Files
player/Project/Src/Drive/Source/usart.c
2025-07-05 19:47:28 +08:00

278 lines
7.0 KiB
C
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

/***
************************************************************************************
* @file usart.c
* @brief usart 接口相关函数
************************************************************************************
* @description
*
* 初始化USART1的引脚 PA9/PA10
* 配置USART1工作在收发模式、数位8位、停止位1位、无校验、不使用硬件控制流控制
* 串口的波特率设置为115200若需要更改波特率直接修改usart.h里的宏定义USART1_BaudRate。
* 重定义fputc函数,用以支持使用printf函数打印数据
*
************************************************************************************
***/
#include "usart.h"
#include "libc.h"
#include "buff.h"
#ifndef BOOTLOADER
#include "rtthread.h"
#define MUTEX_INIT() g_mutex=rt_mutex_create("usart1_mutex",RT_IPC_FLAG_FIFO);
#define MUTEX_DELETE() if(g_mutex) {rt_mutex_delete(g_mutex);g_mutex=0;}
#define MUTEX_TAKE() if(g_mutex) rt_mutex_take(g_mutex,RT_WAITING_FOREVER);
#define MUTEX_RELEASE() if(g_mutex) rt_mutex_release(g_mutex);
void *g_mutex;
#else
#define MUTEX_INIT()
#define MUTEX_DELETE()
#define MUTEX_TAKE()
#define MUTEX_RELEASE()
#endif
// 函数usart IO口初始化
//
void USART_GPIO_Config (void)
{
GPIO_InitTypeDef GPIO_InitStructure;
RCC_AHB1PeriphClockCmd ( USART1_TX_CLK|USART1_RX_CLK, ENABLE); //IO口时钟配置
//IO配置
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF; //复用模式
GPIO_InitStructure.GPIO_OType = GPIO_OType_PP; //推挽
GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP; //上拉
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_2MHz; //速度等级
//初始化 TX 引脚
GPIO_InitStructure.GPIO_Pin = USART1_TX_PIN;
GPIO_Init(USART1_TX_PORT, &GPIO_InitStructure);
//初始化 RX 引脚
GPIO_InitStructure.GPIO_Pin = USART1_RX_PIN;
GPIO_Init(USART1_RX_PORT, &GPIO_InitStructure);
//IO复用复用到USART1
GPIO_PinAFConfig(USART1_TX_PORT,USART1_TX_PinSource,GPIO_AF_USART1);
GPIO_PinAFConfig(USART1_RX_PORT,USART1_RX_PinSource,GPIO_AF_USART1);
}
// 函数USART 口初始化
//
void Usart_Config(void)
{
USART_InitTypeDef USART_InitStructure;
RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1, ENABLE);
// IO口初始化
USART_GPIO_Config();
// 配置串口各项参数
USART_InitStructure.USART_BaudRate = USART1_BaudRate; //波特率
USART_InitStructure.USART_WordLength = USART_WordLength_8b; //数据位8位
USART_InitStructure.USART_StopBits = USART_StopBits_1; //停止位1位
USART_InitStructure.USART_Parity = USART_Parity_No ; //无校验
USART_InitStructure.USART_Mode = USART_Mode_Rx | USART_Mode_Tx; //发送和接收模式
USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None; // 不使用硬件流控制
USART_Init(USART1,&USART_InitStructure); //初始化串口1
USART_Cmd(USART1,ENABLE); //使能串口1
}
// 函数重定义fputc函数
//
static int usart_putc(int c)
{
USART_SendData( USART1,(u8)c ); // 发送单字节数据
while (USART_GetFlagStatus(USART1, USART_FLAG_TXE) == RESET); //等待发送完毕
return (c); //返回字符
}
static int usart_puts(const void *data,int size)
{
MUTEX_TAKE();
for(int i=0;i<size;i++)
{
USART_SendData( USART1,((u8 *)data)[i] ); // 发送单字节数据
while (USART_GetFlagStatus(USART1, USART_FLAG_TXE) == RESET); //等待发送完毕
}
MUTEX_RELEASE();
return size;
}
static data_buff g_recv;
static int usart_getc(void)
{
uint8_t data;
if(buff_read_byte(&g_recv,&data)==0)
return data;
else return EOF;
}
static int usart_open(void)
{
MUTEX_INIT();
buff_init(&g_recv,1024,0,0,0);
/* 打开接收中断 */
USART_ITConfig(USART1,USART_IT_RXNE,ENABLE);
NVIC_InitTypeDef NVIC_InitStructure;
NVIC_InitStructure.NVIC_IRQChannel=USART1_IRQn; //定时器中断
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority=0x00; //抢占优先级1
NVIC_InitStructure.NVIC_IRQChannelSubPriority=0x01; //子优先级3
NVIC_InitStructure.NVIC_IRQChannelCmd=ENABLE;
NVIC_Init(&NVIC_InitStructure);
return 0;
}
static int usart_close(void)
{
MUTEX_DELETE();
NVIC_InitTypeDef NVIC_InitStructure;
NVIC_InitStructure.NVIC_IRQChannel=USART1_IRQn; //定时器中断
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority=0x00; //抢占优先级1
NVIC_InitStructure.NVIC_IRQChannelSubPriority=0x01; //子优先级3
NVIC_InitStructure.NVIC_IRQChannelCmd=DISABLE;
NVIC_Init(&NVIC_InitStructure);
USART_ITConfig(USART1,USART_IT_RXNE,DISABLE);
buff_deinit(&g_recv);
return 0;
}
extern_device2(usart,usart_open,usart_close,usart_putc,usart_getc,usart_puts,NULL);
void USART1_IRQHandler (void)
{
uint8_t t=0;
if(USART1->SR&USART_FLAG_RXNE)
{
t=USART1->DR;
buff_save_byte(&g_recv,t);
//if(g_recv_cb) g_recv_cb(t);
}
else
{
t=USART1->SR;
t=USART1->DR;
}
}
void USART3_Init (void)
{
GPIO_InitTypeDef GPIO_InitStructure;
RCC_AHB1PeriphClockCmd ( RCC_AHB1Periph_GPIOB, ENABLE); //IO口时钟配置
//IO配置
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF; //复用模式
GPIO_InitStructure.GPIO_OType = GPIO_OType_PP; //推挽
GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP; //上拉
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_2MHz; //速度等级
//初始化 TX 引脚
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10;
GPIO_Init(GPIOB, &GPIO_InitStructure);
//初始化 RX 引脚
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_11;
GPIO_Init(GPIOB, &GPIO_InitStructure);
//IO复用复用到USART1
GPIO_PinAFConfig(GPIOB,GPIO_PinSource10,GPIO_AF_USART3);
GPIO_PinAFConfig(GPIOB,GPIO_PinSource11,GPIO_AF_USART3);
USART_InitTypeDef USART_InitStructure;
RCC_APB1PeriphClockCmd(RCC_APB1Periph_USART3, ENABLE);
// 配置串口各项参数
USART_InitStructure.USART_BaudRate = 115200; //波特率
USART_InitStructure.USART_WordLength = USART_WordLength_8b; //数据位8位
USART_InitStructure.USART_StopBits = USART_StopBits_1; //停止位1位
USART_InitStructure.USART_Parity = USART_Parity_No ; //无校验
USART_InitStructure.USART_Mode = USART_Mode_Rx | USART_Mode_Tx; //发送和接收模式
USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None; // 不使用硬件流控制
USART_Init(USART3,&USART_InitStructure); //初始化串口1
//配置中断
NVIC_InitTypeDef NVIC_InitStructure;
NVIC_InitStructure.NVIC_IRQChannel = USART3_IRQn; //串口中断通道
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority=3; //抢占优先级3
NVIC_InitStructure.NVIC_IRQChannelSubPriority =3; //子优先级3
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; //IRQ通道使能
NVIC_Init(&NVIC_InitStructure); //根据指定的参数初始化VIC寄存器、
USART_Cmd(USART3,ENABLE); //使能串口1
USART_ITConfig(USART3, USART_IT_RXNE, ENABLE);
}
//串口3接收手柄数据
static u8 g_key=0;
static u8 g_keyPress=0;
static u8 g_keyPressed=0;
void USART3_IRQHandler (void)
{
u8 res=0;
if(USART_GetITStatus(USART3, USART_IT_RXNE) != RESET)
{
g_key=USART_ReceiveData(USART3);
if ((g_keyPress^g_key)&g_keyPress)
{
//检测按键弹起
g_keyPressed=g_keyPress^g_key;
}
g_keyPress=g_key;
}
}
u8 USART3_GetKey(void)
{
u8 ret=g_key;
//g_key=0;
return ret;
}
u8 USART3_GetKeyPressed (void)
{
u8 ret=g_keyPressed;
g_keyPressed=0;
return ret;
}