uart3.c 8.8 KB

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