/*** ************************************************************************************ * @file usart.c * @brief usart 接口相关函数 ************************************************************************************ * @description * * 初始化USART1的引脚 PA9/PA10, * 配置USART1工作在收发模式、数位8位、停止位1位、无校验、不使用硬件控制流控制, * 串口的波特率设置为115200,若需要更改波特率直接修改usart.h里的宏定义USART1_BaudRate。 * 重定义fputc函数,用以支持使用printf函数打印数据 * ************************************************************************************ ***/ #include "usart.h" #include "buff.h" #include "libc.h" #include "stm32f4xx.h" #define MUTEX_INIT() #define MUTEX_DELETE() #define MUTEX_TAKE() #define MUTEX_RELEASE() // 函数:usart IO口初始化 // void USART_GPIO_Config(void) { GPIO_InitTypeDef GPIO_InitStructure; // IO口时钟配置 RCC_AHB1PeriphClockCmd(USART1_TX_CLK | USART1_RX_CLK, ENABLE); // 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; // 数据位8位 USART_InitStructure.USART_WordLength = USART_WordLength_8b; // 停止位1位 USART_InitStructure.USART_StopBits = USART_StopBits_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; // 初始化串口1 USART_Init(USART1, &USART_InitStructure); // 使能串口1 USART_Cmd(USART1, ENABLE); } // 函数:重定义fputc函数 // static int usart_putc(int c) { // 发送单字节数据 USART_SendData(USART1, (uint8_t)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, ((uint8_t *)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; // 抢占优先级1 NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0x00; // 子优先级3 NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0x01; 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; NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0x01; 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; // 数据位8位 USART_InitStructure.USART_WordLength = USART_WordLength_8b; // 停止位1位 USART_InitStructure.USART_StopBits = USART_StopBits_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); // 配置中断 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 uint8_t g_key = 0; static uint8_t g_keyPress = 0; static uint8_t g_keyPressed = 0; void USART3_IRQHandler(void) { uint8_t 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; } } uint8_t USART3_GetKey(void) { uint8_t ret = g_key; // g_key=0; return ret; } uint8_t USART3_GetKeyPressed(void) { uint8_t ret = g_keyPressed; g_keyPressed = 0; return ret; }