uart1.c 9.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218
  1. /**
  2. ************************************************************************************************
  3. * @文件 : uart1.c
  4. * @作者 : 樊春春
  5. * @版本 : V1.0
  6. * @时间 : 2022/05/31 20:20:39
  7. * @邮箱 : [email protected]
  8. * @说明 : uart1底层驱动,待修复
  9. ************************************************************************************************
  10. **/
  11. #include "uart1.h"
  12. #include "queue.h"
  13. // 重定义fputc函数
  14. #ifdef __GNUC__
  15. int _write(int fd, char *pBuffer, int size)
  16. {
  17. while (RESET != USART_GetITStatus(USART1, USART_IT_TC))
  18. ;
  19. uart1_dma_send((INT8U *)pBuffer, size);
  20. return size;
  21. }
  22. #endif
  23. static INT8U uart1_tx_buf[UART1_TX_LEN] = {0};
  24. static INT8U uart1_rx_buf[UART1_REC_LEN] = {0};
  25. UartFrame_TypeDef Uart1FrameStruct[UART1_MAX_MSG_NUM];
  26. extern OS_EVENT *uart1_mbox;
  27. void uart1_nvic_config(void)
  28. {
  29. NVIC_InitTypeDef NVIC_InitStructure;
  30. // Usart1 NVIC 配置
  31. NVIC_InitStructure.NVIC_IRQChannel = USART1_IRQn; //串口1中断通道
  32. NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0; //抢占优先级
  33. NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0; //子优先级
  34. NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; // IRQ通道使能
  35. NVIC_Init(&NVIC_InitStructure); //根据指定的参数初始化VIC寄存器
  36. }
  37. void uart1_dma_init(void)
  38. {
  39. DMA_InitTypeDef DMA_InitStructure;
  40. if ((u32)UART1_DMA_TXCH > (u32)DMA2) //得到当前stream是属于DMA2还是DMA1
  41. {
  42. RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_DMA2, ENABLE); // DMA2时钟使能
  43. }
  44. else
  45. {
  46. RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_DMA1, ENABLE); // DMA1时钟使能
  47. }
  48. DMA_DeInit(UART1_DMA_TXCH);
  49. while (DMA_GetCmdStatus(UART1_DMA_TXCH) != DISABLE)
  50. {
  51. } //等待DMA可配置
  52. /* 配置 DMA Stream */
  53. DMA_InitStructure.DMA_Channel = UART1_DMA; //通道选择
  54. DMA_InitStructure.DMA_PeripheralBaseAddr = (u32)&USART1->DR; // DMA外设地址
  55. DMA_InitStructure.DMA_Memory0BaseAddr = (u32)uart1_tx_buf; // DMA 存储器0地址
  56. DMA_InitStructure.DMA_DIR = DMA_DIR_MemoryToPeripheral; //存储器到外设模式
  57. DMA_InitStructure.DMA_BufferSize = UART1_TX_LEN; //数据传输量
  58. DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable; //外设非增量模式
  59. DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable; //存储器增量模式
  60. DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_Byte; //外设数据长度:8位
  61. DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_Byte; //存储器数据长度:8位
  62. DMA_InitStructure.DMA_Mode = DMA_Mode_Normal; // 使用普通模式
  63. DMA_InitStructure.DMA_Priority = DMA_Priority_Medium; //中等优先级6
  64. DMA_InitStructure.DMA_FIFOMode = DMA_FIFOMode_Disable;
  65. DMA_InitStructure.DMA_FIFOThreshold = DMA_FIFOThreshold_Full;
  66. DMA_InitStructure.DMA_MemoryBurst = DMA_MemoryBurst_Single; //存储器突发单次传输
  67. DMA_InitStructure.DMA_PeripheralBurst = DMA_PeripheralBurst_Single; //外设突发单次传输 // DMA 存储器0地址
  68. DMA_Init(UART1_DMA_TXCH, &DMA_InitStructure); //初始化DMA Stream
  69. if ((u32)UART1_DMA_RXCH > (u32)DMA2) //得到当前stream是属于DMA2还是DMA1
  70. {
  71. RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_DMA2, ENABLE); // DMA2时钟使能
  72. }
  73. else
  74. {
  75. RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_DMA1, ENABLE); // DMA1时钟使能
  76. }
  77. DMA_DeInit(UART1_DMA_RXCH);
  78. while (DMA_GetCmdStatus(UART1_DMA_RXCH) != DISABLE)
  79. {
  80. }
  81. DMA_InitStructure.DMA_Channel = UART1_DMA; //通道选择
  82. DMA_InitStructure.DMA_PeripheralBaseAddr = (u32)&USART1->DR; // DMA外设地址
  83. DMA_InitStructure.DMA_Memory0BaseAddr = (u32)uart1_rx_buf; // DMA 存储器0地址
  84. DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralToMemory; //外设到存储器模式
  85. DMA_InitStructure.DMA_BufferSize = UART1_REC_LEN; //数据传输量
  86. DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable; //外设非增量模式
  87. DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable; //存储器增量模式
  88. DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_Byte; //外设数据长度:8位
  89. DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_Byte; //存储器数据长度:8位
  90. DMA_InitStructure.DMA_Mode = DMA_Mode_Circular; // 使用循环模式
  91. DMA_InitStructure.DMA_Priority = DMA_Priority_Medium; //中等优先级
  92. DMA_InitStructure.DMA_FIFOMode = DMA_FIFOMode_Disable;
  93. DMA_InitStructure.DMA_FIFOThreshold = DMA_FIFOThreshold_Full;
  94. DMA_InitStructure.DMA_MemoryBurst = DMA_MemoryBurst_Single; //存储器突发单次传输
  95. DMA_InitStructure.DMA_PeripheralBurst = DMA_PeripheralBurst_Single; //外设突发单次传输
  96. DMA_Init(UART1_DMA_RXCH, &DMA_InitStructure);
  97. }
  98. void uart1_config(void)
  99. {
  100. USART_InitTypeDef USART_InitStructure;
  101. USART_InitStructure.USART_BaudRate = 9600; //波特率设置
  102. USART_InitStructure.USART_WordLength = USART_WordLength_8b; //字长为8位数据格式
  103. USART_InitStructure.USART_StopBits = USART_StopBits_1; //一个停止位
  104. USART_InitStructure.USART_Parity = USART_Parity_No; //无奇偶校验位
  105. USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None; //无硬件数据流控制
  106. USART_InitStructure.USART_Mode = USART_Mode_Rx | USART_Mode_Tx; //收发模式
  107. USART_Init(USART1, &USART_InitStructure); //初始化串口1
  108. USART_Cmd(USART1, ENABLE); //使能串口1
  109. }
  110. void Uart1DMA_Enable(DMA_Stream_TypeDef *DMA_Streamx, u16 count)
  111. {
  112. DMA_Cmd(DMA_Streamx, DISABLE); //关闭DMA传输
  113. while (DMA_GetCmdStatus(DMA_Streamx) != DISABLE)
  114. {
  115. } //确保DMA可以被设置
  116. DMA_SetCurrDataCounter(DMA_Streamx, count); //数据传输量
  117. DMA_Cmd(DMA_Streamx, ENABLE); //开启DMA传输
  118. }
  119. void uart1_init(void)
  120. {
  121. uart1_config();
  122. uart1_dma_init();
  123. uart1_nvic_config();
  124. /* USART DMA enable*/
  125. USART_DMACmd(USART1, USART_DMAReq_Rx, ENABLE); // 使能串口DMA接收数据
  126. Uart1DMA_Enable(UART1_DMA_RXCH, UART1_REC_LEN);
  127. /*configure DMA interrupt*/
  128. USART_ITConfig(USART1, USART_IT_IDLE, ENABLE); //开启空闲中断
  129. USART_ITConfig(USART1, USART_IT_TC, ENABLE);
  130. }
  131. /****************************************************
  132. * 函 数 名:Uart1_Send_Data
  133. * 函数功能:串口1发送数据
  134. * 入口参数:buf 待发送数据 len 数据长度
  135. * 说 明:
  136. *****************************************************/
  137. void Uart1_Send_Data(const u8 *buf, u16 len)
  138. {
  139. u8 i;
  140. for (i = 0; i < len; i++) //循环发送数据
  141. {
  142. while (USART_GetFlagStatus(USART1, USART_FLAG_TC) == RESET)
  143. ;
  144. USART_SendData(USART1, buf[i]);
  145. }
  146. while (USART_GetFlagStatus(USART1, USART_FLAG_TC) == RESET)
  147. ;
  148. }
  149. void uart1_dma_send(const INT8U *buf, INT16U len)
  150. {
  151. if (RESET != DMA_GetFlagStatus(UART1_DMA_TXCH, DMA_FLAG_TCIF7))
  152. {
  153. DMA_ClearFlag(UART1_DMA_TXCH, DMA_FLAG_TCIF7);
  154. }
  155. if (len > UART1_TX_LEN)
  156. {
  157. len = UART1_TX_LEN;
  158. }
  159. memcpy(uart1_tx_buf, buf, len);
  160. USART_DMACmd(USART1, USART_DMAReq_Tx, ENABLE); // 使能DMA串口发送数据
  161. Uart1DMA_Enable(UART1_DMA_TXCH, len);
  162. }
  163. void USART1_IRQHandler(void)
  164. {
  165. static INT8U u1_index = 0;
  166. volatile INT8U clear = 0;
  167. INT8U rec_cnt = 0;
  168. if (RESET != USART_GetITStatus(USART1, USART_IT_IDLE))
  169. {
  170. clear = USART1->SR;
  171. clear = USART1->DR; // 先读SR, 再读DR, 就是为了消除IDLE中断
  172. DMA_Cmd(UART1_DMA_RXCH, DISABLE);
  173. DMA_ClearFlag(UART1_DMA_RXCH, DMA_FLAG_TCIF5);
  174. rec_cnt = UART1_REC_LEN - DMA_GetCurrDataCounter(UART1_DMA_RXCH); // 获得接收帧帧长 特别注意: 帧长不是DMA_GetCurrDataCounter(DMA2_Stream5)
  175. memcpy(Uart1FrameStruct[u1_index].buf, uart1_rx_buf, rec_cnt);
  176. Uart1FrameStruct[u1_index].len = rec_cnt;
  177. OSMboxPost(uart1_mbox, &Uart1FrameStruct[u1_index]);
  178. if (u1_index < UART1_MAX_MSG_NUM - 1)
  179. {
  180. u1_index++;
  181. }
  182. else
  183. {
  184. u1_index = 0;
  185. }
  186. DMA_SetCurrDataCounter(UART1_DMA_RXCH, UART1_REC_LEN);
  187. DMA_Cmd(UART1_DMA_RXCH, ENABLE);
  188. }
  189. else if (RESET != USART_GetITStatus(USART1, USART_IT_TC))
  190. {
  191. USART_ClearITPendingBit(USART1, USART_IT_TC); // 清除发送完成标标志位
  192. Uart1DMA_Enable(UART1_DMA_RXCH, UART1_REC_LEN); // DMA接收使能
  193. DMA_Cmd(UART1_DMA_TXCH, DISABLE); // 关闭发送DMA
  194. DMA_SetCurrDataCounter(UART1_DMA_TXCH, 0); // 清除发送数据长度
  195. }
  196. }