#include "uart.h" #include "systick.h" #include #include static uint8_t usart1_tx_buf[256]; static uint8_t usart1_rx_buf[256]; static uint8_t usart2_tx_buf[256]; static uint8_t usart2_rx_buf[256]; static uint8_t usart3_tx_buf[256]; static uint8_t usart3_rx_buf[256]; #define UART1_TX_PORT GPIOA #define UART1_TX_PIN GPIO_Pin_9 #define UART1_TX_SOURCE GPIO_PinSource9 #define UART1_RX_PORT GPIOA #define UART1_RX_PIN GPIO_Pin_10 #define UART1_RX_SOURCE GPIO_PinSource10 #define UART2_TX_PORT GPIOA #define UART2_TX_PIN GPIO_Pin_2 #define UART2_TX_SOURCE GPIO_PinSource2 #define UART2_RX_PORT GPIOA #define UART2_RX_PIN GPIO_Pin_3 #define UART2_RX_SOURCE GPIO_PinSource3 #define UART3_TX_PORT GPIOB #define UART3_TX_PIN GPIO_Pin_10 #define UART3_TX_SOURCE GPIO_PinSource2 #define UART3_RX_PORT GPIOB #define UART3_RX_PIN GPIO_Pin_11 #define UART3_RX_SOURCE GPIO_PinSource3 int usart1_snd_tx_cnt = 0; // 加入以下代码,支持printf函数,而不需要选择use MicroLIB // 确保没有从 C 库链接使用半主机的函数 #pragma import(__use_no_semihosting) #pragma import(__use_no_semihosting_swi) // 定义_sys_exit() 以避免使用半主机模式 void _sys_exit(int x) { x = x; } // 加入以下代码,支持printf函数,而不需要选择use MicroLIB // 标准库需要的支持函数 struct __FILE { int handle; }; /* FILE is typedef ’ d in stdio.h. */ FILE __stdout; FILE __stdin; int _ttywrch(int ch) { ch = ch; return ch; } // && !defined(__clang__) #if defined(__GNUC__) #define PUTCHAR_PROTOTYPE int __io_putchar(int ch) #define GETCHAR_PROTOTYPE int __io_getchar(void) #else #define PUTCHAR_PROTOTYPE int fputc(int ch, FILE *f) #define GETCHAR_PROTOTYPE int fgetc(FILE *f) #endif PUTCHAR_PROTOTYPE { uint32_t tick; usart1_snd_tx_cnt++; usart_send_it(&usart1_context, &ch, 1); tick = get_systick_ms(); while (RESET == USART_GetFlagStatus(USART1, USART_FLAG_TXE)) { if (get_systick_ms() - tick > 10) break; } return ch; } GETCHAR_PROTOTYPE { uint8_t ch; if (0 != usart_receive_read(&usart1_context, &ch, 1)) { return ch; } return -1; } // &&!defined(__clang__) #if defined(__GNUC__) __attribute__((weak)) int _write(int file, char *ptr, int len) { (void)file; if ((file != STDOUT_FILENO) && (file != STDERR_FILENO)) { return -1; } for (int index = 0; index < len; index++) __io_putchar(*ptr++); return len; } __attribute__((weak)) int _read(int file, char *ptr, int len) { (void)file; if (file != STDIN_FILENO) { return -1; } uint8_t ch; for (int index = 0; index < len; index++) { // *ptr++ = __io_getchar(); if (0 != usart_receive_read(&usart1_context, &ch, 1)) { return ch; } return -1; } return len; } #endif #if 0 int getchar(void) { char c = 0; // ssize_t int bytes_read = read(STDIN_FILENO, &c, sizeof(char)); if (bytes_read == -1) { // 读取错误 return EOF; } else if (bytes_read == 0) { // 读取结束 return EOF; } else { // 返回读取的字符 return (int)c; } } #else int getchar(void) { uint8_t ch; if (0 != usart_receive_read(&usart1_context, &ch, 1)) { return ch; } return -1; } #endif static void usart1_config(void) { GPIO_InitTypeDef GPIO_StructInit; NVIC_InitTypeDef NVIC_InitStructure; RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOA, ENABLE); RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1, ENABLE); GPIO_StructInit.GPIO_Mode = GPIO_Mode_AF; GPIO_StructInit.GPIO_OType = GPIO_OType_PP; GPIO_StructInit.GPIO_Speed = GPIO_Speed_100MHz; GPIO_StructInit.GPIO_PuPd = GPIO_PuPd_UP; GPIO_StructInit.GPIO_Pin = UART1_TX_PIN; GPIO_PinAFConfig(UART1_TX_PORT, UART1_TX_SOURCE, GPIO_AF_USART1); GPIO_Init(UART1_TX_PORT, &GPIO_StructInit); GPIO_StructInit.GPIO_Pin = UART1_RX_PIN; GPIO_PinAFConfig(UART1_RX_PORT, UART1_RX_SOURCE, GPIO_AF_USART1); GPIO_Init(UART1_RX_PORT, &GPIO_StructInit); // Usart1 NVIC 配置 NVIC_InitStructure.NVIC_IRQChannel = USART1_IRQn; // 串口1中断通道 NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1; // 抢占优先级 NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0; // 子优先级 NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; // IRQ通道使能 NVIC_Init(&NVIC_InitStructure); } static void usart1_deconfig(void) { } static void usart2_config(void) { GPIO_InitTypeDef GPIO_StructInit; NVIC_InitTypeDef NVIC_InitStructure; RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOA, ENABLE); RCC_APB1PeriphClockCmd(RCC_APB1Periph_USART2, ENABLE); GPIO_StructInit.GPIO_Mode = GPIO_Mode_AF; GPIO_StructInit.GPIO_OType = GPIO_OType_PP; GPIO_StructInit.GPIO_Speed = GPIO_Speed_100MHz; GPIO_StructInit.GPIO_PuPd = GPIO_PuPd_UP; GPIO_StructInit.GPIO_Pin = UART2_TX_PIN; GPIO_PinAFConfig(UART2_TX_PORT, UART2_TX_SOURCE, GPIO_AF_USART2); GPIO_Init(UART2_TX_PORT, &GPIO_StructInit); GPIO_StructInit.GPIO_Pin = UART2_RX_PIN; GPIO_PinAFConfig(UART2_RX_PORT, UART2_RX_SOURCE, GPIO_AF_USART2); GPIO_Init(UART2_RX_PORT, &GPIO_StructInit); // Usart1 NVIC 配置 NVIC_InitStructure.NVIC_IRQChannel = USART2_IRQn; // 串口1中断通道 NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1; // 抢占优先级 NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0; // 子优先级 NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; // IRQ通道使能 NVIC_Init(&NVIC_InitStructure); } static void usart2_deconfig(void) { } static void usart3_config(void) { GPIO_InitTypeDef GPIO_StructInit; NVIC_InitTypeDef NVIC_InitStructure; RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOB, ENABLE); RCC_APB1PeriphClockCmd(RCC_APB1Periph_USART3, ENABLE); GPIO_StructInit.GPIO_Mode = GPIO_Mode_AF; GPIO_StructInit.GPIO_OType = GPIO_OType_PP; GPIO_StructInit.GPIO_Speed = GPIO_Speed_100MHz; GPIO_StructInit.GPIO_PuPd = GPIO_PuPd_UP; GPIO_StructInit.GPIO_Pin = UART3_TX_PIN; GPIO_PinAFConfig(UART3_TX_PORT, UART3_TX_SOURCE, GPIO_AF_USART3); GPIO_Init(UART3_TX_PORT, &GPIO_StructInit); GPIO_StructInit.GPIO_Pin = UART3_RX_PIN; GPIO_PinAFConfig(UART3_RX_PORT, UART3_RX_SOURCE, GPIO_AF_USART3); GPIO_Init(UART3_RX_PORT, &GPIO_StructInit); // Usart1 NVIC 配置 NVIC_InitStructure.NVIC_IRQChannel = USART3_IRQn; // 串口1中断通道 NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1; // 抢占优先级 NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0; // 子优先级 NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; // IRQ通道使能 NVIC_Init(&NVIC_InitStructure); } static void usart3_deconfig(void) { } usart_context_t usart1_context = { USART1, usart1_tx_buf, sizeof(usart1_tx_buf), 0, 0, 0, usart1_rx_buf, sizeof(usart1_rx_buf), 0, 0, 0, usart1_config, usart1_deconfig}; usart_context_t usart2_context = { USART2, usart2_tx_buf, sizeof(usart2_tx_buf), 0, 0, 0, usart2_rx_buf, sizeof(usart2_rx_buf), 0, 0, 0, usart2_config, usart2_deconfig}; usart_context_t usart3_context = { USART3, usart3_tx_buf, sizeof(usart3_tx_buf), 0, 0, 0, usart3_rx_buf, sizeof(usart3_rx_buf), 0, 0, 0, usart3_config, usart3_deconfig}; void usart_config_init(usart_context_t *p_usart_content, uint32_t band_rate) { p_usart_content->config(); USART_InitTypeDef USART_InitStructure; USART_InitStructure.USART_BaudRate = band_rate; USART_InitStructure.USART_WordLength = USART_WordLength_8b; USART_InitStructure.USART_StopBits = USART_StopBits_1; USART_InitStructure.USART_Parity = USART_Parity_No; USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None; USART_InitStructure.USART_Mode = USART_Mode_Rx | USART_Mode_Tx; USART_Init(p_usart_content->usart_periph, &USART_InitStructure); // 初始化串口 USART_ITConfig(p_usart_content->usart_periph, USART_IT_RXNE, ENABLE); USART_Cmd(p_usart_content->usart_periph, ENABLE); // 使能串口 } void usart_config_deinit(usart_context_t *p_usart_content) { USART_DeInit(p_usart_content->usart_periph); p_usart_content->deconfig(); } void usart_send(usart_context_t *p_usart_content, const void *_send_buf, const uint16_t send_count) { const uint8_t *send_buf = (const uint8_t *)_send_buf; uint16_t i; for (i = 0; i < send_count; i++) { while (RESET == USART_GetFlagStatus(p_usart_content->usart_periph, USART_FLAG_TXE)) ; USART_SendData(p_usart_content->usart_periph, (uint8_t)send_buf[i]); } while (RESET == USART_GetFlagStatus(p_usart_content->usart_periph, USART_FLAG_TC)) ; } int32_t usart_read_until_char(usart_context_t *p_usart_content, char c) { uint32_t i; for (i = p_usart_content->rx_rd; i < p_usart_content->rx_wr; i++) { if (p_usart_content->rx_buf[i % p_usart_content->rx_buf_size] == c) { return i; } } return -1; } // read until memory // return:第一次出现mem位置, -1 没找到 int32_t usart_read_until_mem(usart_context_t *p_usart_content, char *mem, int len) { int32_t i, j, pos; for (i = p_usart_content->rx_rd; i < p_usart_content->rx_wr; i++) { // overflow for (j = 0; j < len; j++) { pos = i + j; if (p_usart_content->rx_buf[pos % p_usart_content->rx_buf_size] != mem[j]) { break; } } // 找到内存快 if (j == len) { return i; } } return -1; } // read ble format 04 FC code len data // return 满足format条件结束位置, -1 没找到 int32_t usart_read_ble_format(usart_context_t *p_usart_content) { uint16_t rx_wr = p_usart_content->rx_wr; uint16_t rx_rd = p_usart_content->rx_rd; if (rx_wr < rx_rd) { rx_wr += p_usart_content->rx_buf_size; } if (rx_wr - rx_rd < 4) { return -1; } // 第一次开机跳过特殊桢处理 00 04,跳过00 if (p_usart_content->rx_buf[rx_rd % p_usart_content->rx_buf_size] == 0x00 || p_usart_content->rx_buf[(rx_rd + 1) % p_usart_content->rx_buf_size] == 0x04) { p_usart_content->rx_rd++; p_usart_content->rx_rd %= p_usart_content->rx_buf_size; return -4; } if (p_usart_content->rx_buf[rx_rd % p_usart_content->rx_buf_size] != 0x04 || p_usart_content->rx_buf[(rx_rd + 1) % p_usart_content->rx_buf_size] != 0xFC) { return -2; } // 蓝牙长度不够 if (rx_wr - rx_rd < p_usart_content->rx_buf[(rx_rd + 3) % p_usart_content->rx_buf_size] + 4) { return -3; } return p_usart_content->rx_buf[(rx_rd + 3) % p_usart_content->rx_buf_size] + 4; } int32_t usart_copy_data(usart_context_t *p_usart_content, int rlen, char *data) { int32_t i, p; // 拷贝rlen + 1个数据 for (i = 0; i < rlen; i++) { p = (p_usart_content->rx_rd + i) % p_usart_content->rx_buf_size; data[i] = p_usart_content->rx_buf[p]; } return 0; } int32_t usart_read_update(usart_context_t *p_usart_content, int rlen, char *data) { int32_t i, p; // 拷贝rlen + 1个数据 for (i = 0; i < rlen; i++) { p = (p_usart_content->rx_rd + i) % p_usart_content->rx_buf_size; data[i] = p_usart_content->rx_buf[p]; } // 指定pos下一个位置 // return p_usart_content->rx_rd = (p_usart_content->rx_rd + rlen) % p_usart_content->rx_buf_size; p = p_usart_content->rx_rd = (p_usart_content->rx_rd + rlen) % p_usart_content->rx_buf_size; return p; } void usart_send_it(usart_context_t *p_usart_content, const void *_send_buf, const uint16_t send_count) { const uint8_t *send_buf = (const uint8_t *)_send_buf; uint16_t i; uint16_t left; // 空间不够直接返回 if (p_usart_content->tx_wr >= p_usart_content->tx_rd) { left = p_usart_content->tx_buf_size - (p_usart_content->tx_wr - p_usart_content->tx_rd); } else { left = p_usart_content->tx_rd - p_usart_content->tx_wr; if (send_count > left) { p_usart_content->tx_err++; return; } } // 内存拷贝 for (i = 0; i < send_count; i++) { // send buffer overflow just wait p_usart_content->tx_buf[p_usart_content->tx_wr++] = send_buf[i]; p_usart_content->tx_wr %= p_usart_content->tx_buf_size; } // 使能发送缓存空中断 USART_ITConfig(p_usart_content->usart_periph, USART_IT_TXE, ENABLE); } void usart_wait_send_finished(usart_context_t *p_usart_content) { while (p_usart_content->tx_wr != p_usart_content->tx_rd) ; while (RESET == USART_GetFlagStatus(p_usart_content->usart_periph, USART_FLAG_TC)) ; } int usart_receive_read(usart_context_t *p_usart_context, void *_receive_buf, const int receive_count) { uint8_t *receive_buf = (uint8_t *)_receive_buf; int i, receive_count_real; /* Read data from receive buffer. *The buffer have data that received from usart. */ for (i = 0, receive_count_real = 0; i < receive_count; i++) { if (p_usart_context->rx_rd == p_usart_context->rx_wr) { return receive_count_real; } else { receive_buf[i] = p_usart_context->rx_buf[p_usart_context->rx_rd++]; p_usart_context->rx_rd %= p_usart_context->rx_buf_size; receive_count_real++; } } return receive_count_real; } static void usart_rxne_it(usart_context_t *p_usart_content) { p_usart_content->rx_buf[p_usart_content->rx_wr++] = USART_ReceiveData(p_usart_content->usart_periph); p_usart_content->rx_wr %= p_usart_content->rx_buf_size; // overflow handle if (p_usart_content->rx_wr == p_usart_content->rx_rd) { p_usart_content->rx_rd++; p_usart_content->rx_rd %= p_usart_content->rx_buf_size; } } static void usart_txe_it(usart_context_t *p_usart_content) { if (p_usart_content->tx_rd != p_usart_content->tx_wr) { USART_SendData(p_usart_content->usart_periph, p_usart_content->tx_buf[p_usart_content->tx_rd++]); p_usart_content->tx_rd %= p_usart_content->tx_buf_size; } else { USART_ITConfig(p_usart_content->usart_periph, USART_IT_TXE, DISABLE); } } void usart_it(usart_context_t *p_usart_content) { // 读取缓沖区非空中断 if (SET == USART_GetFlagStatus(p_usart_content->usart_periph, USART_FLAG_RXNE)) { USART_ClearFlag(p_usart_content->usart_periph, USART_FLAG_RXNE); usart_rxne_it(p_usart_content); } // 发送缓沖区空中断 if (SET == USART_GetFlagStatus(p_usart_content->usart_periph, USART_FLAG_TXE)) { USART_ClearFlag(p_usart_content->usart_periph, USART_FLAG_TXE); usart_txe_it(p_usart_content); } // // 发送完成中断 // if (RESET != USART_GetFlagStatus(p_usart_content->usart_periph, USART_FLAG_TC)) // { // USART_ITConfig(p_usart_content->usart_periph, USART_FLAG_TC, DISABLE); // USART_ITConfig(p_usart_content->usart_periph, USART_FLAG_RXNE, ENABLE); // } // 发送错误 if (RESET != USART_GetFlagStatus(p_usart_content->usart_periph, USART_FLAG_ORE)) USART_ClearFlag(p_usart_content->usart_periph, USART_FLAG_ORE); } void USART1_IRQHandler(void) { usart_it(&usart1_context); } void USART2_IRQHandler(void) { usart_it(&usart2_context); } void USART3_IRQHandler(void) { usart_it(&usart3_context); }