uart.c 17 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406
  1. #include "uart.h"
  2. #include "stdio.h"
  3. #include "uart.h"
  4. #include <string.h>
  5. static INT8U uart1_tx_buf[UART1_TX_LEN] = {0};
  6. static INT8U uart1_rx_buf[UART1_REC_LEN] = {0};
  7. static INT8U uart3_tx_buf[UART3_TX_LEN] = {0};
  8. static INT8U uart3_rx_buf[UART3_REC_LEN] = {0};
  9. UartFrame_TypeDef Uart1FrameStruct[MAX_MSG_NUM];
  10. UartFrame_TypeDef Uart3FrameStruct[MAX_MSG_NUM];
  11. extern OS_EVENT *uart1_mbox;
  12. extern OS_EVENT *uart3_mbox;
  13. void uart1_nvic_config(void)
  14. {
  15. NVIC_InitTypeDef NVIC_InitStructure;
  16. // Usart1 NVIC 配置
  17. NVIC_InitStructure.NVIC_IRQChannel = USART1_IRQn; //串口1中断通道
  18. NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0; //抢占优先级
  19. NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0; //子优先级
  20. NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; // IRQ通道使能
  21. NVIC_Init(&NVIC_InitStructure); //根据指定的参数初始化VIC寄存器
  22. }
  23. void uart1_dma_init(void)
  24. {
  25. DMA_InitTypeDef DMA_InitStructure;
  26. if ((u32)UART1_DMA_TXCH > (u32)DMA2) //得到当前stream是属于DMA2还是DMA1
  27. {
  28. RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_DMA2, ENABLE); // DMA2时钟使能
  29. }
  30. else
  31. {
  32. RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_DMA1, ENABLE); // DMA1时钟使能
  33. }
  34. DMA_DeInit(UART1_DMA_TXCH);
  35. /* 配置 DMA Stream */
  36. DMA_InitStructure.DMA_PeripheralBaseAddr = (u32)(&(USART1->DR)); // DMA外设地址
  37. DMA_InitStructure.DMA_BufferSize = UART1_TX_LEN; //数据传输量
  38. DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable; //外设非增量模式
  39. DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable; //存储器增量模式
  40. DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_Byte; //外设数据长度:8位
  41. DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_Byte; //存储器数据长度:8位
  42. DMA_InitStructure.DMA_Mode = DMA_Mode_Normal; // 使用普通模式
  43. DMA_InitStructure.DMA_Priority = DMA_Priority_Medium; //中等优先级
  44. DMA_InitStructure.DMA_FIFOMode = DMA_FIFOMode_Disable;
  45. DMA_InitStructure.DMA_FIFOThreshold = DMA_FIFOThreshold_Full;
  46. DMA_InitStructure.DMA_MemoryBurst = DMA_MemoryBurst_Single; //存储器突发单次传输
  47. DMA_InitStructure.DMA_PeripheralBurst = DMA_PeripheralBurst_Single; //外设突发单次传输
  48. DMA_InitStructure.DMA_Channel = UART1_DMA; //通道选择
  49. DMA_InitStructure.DMA_DIR = DMA_DIR_MemoryToPeripheral; //存储器到外设模式
  50. DMA_InitStructure.DMA_Memory0BaseAddr = (u32)uart1_tx_buf; // DMA 存储器0地址
  51. DMA_Init(UART1_DMA_TXCH, &DMA_InitStructure); //初始化DMA Stream
  52. if ((u32)UART1_DMA_RXCH > (u32)DMA2) //得到当前stream是属于DMA2还是DMA1
  53. {
  54. RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_DMA2, ENABLE); // DMA2时钟使能
  55. }
  56. else
  57. {
  58. RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_DMA1, ENABLE); // DMA1时钟使能
  59. }
  60. DMA_DeInit(UART1_DMA_RXCH);
  61. /* 配置 DMA Stream */
  62. DMA_InitStructure.DMA_PeripheralBaseAddr = (u32)(&(USART1->DR)); // DMA外设地址
  63. DMA_InitStructure.DMA_BufferSize = UART1_REC_LEN; //数据传输量
  64. DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable; //外设非增量模式
  65. DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable; //存储器增量模式
  66. DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_Byte; //外设数据长度:8位
  67. DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_Byte; //存储器数据长度:8位
  68. DMA_InitStructure.DMA_Mode = DMA_Mode_Circular; // 使用循环模式
  69. DMA_InitStructure.DMA_Priority = DMA_Priority_Medium; //中等优先级
  70. DMA_InitStructure.DMA_FIFOMode = DMA_FIFOMode_Disable;
  71. DMA_InitStructure.DMA_FIFOThreshold = DMA_FIFOThreshold_Full;
  72. DMA_InitStructure.DMA_MemoryBurst = DMA_MemoryBurst_Single; //存储器突发单次传输
  73. DMA_InitStructure.DMA_PeripheralBurst = DMA_PeripheralBurst_Single; //外设突发单次传输
  74. /* 配置 RX DMA */
  75. DMA_InitStructure.DMA_Channel = UART1_DMA; /* 配置接收通道 */
  76. DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralToMemory; /* 设置从外设到内存 */
  77. DMA_InitStructure.DMA_Memory0BaseAddr = (u32)uart1_rx_buf; /* 设置内存地址 */
  78. DMA_Init(UART1_DMA_RXCH, &DMA_InitStructure);
  79. }
  80. void uart1_config(void)
  81. {
  82. USART_InitTypeDef USART_InitStructure;
  83. // USART1 初始化设置
  84. USART_InitStructure.USART_BaudRate = 9600; //波特率设置
  85. USART_InitStructure.USART_WordLength = USART_WordLength_8b; //字长为8位数据格式
  86. USART_InitStructure.USART_StopBits = USART_StopBits_1; //一个停止位
  87. USART_InitStructure.USART_Parity = USART_Parity_No; //无奇偶校验位
  88. USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None; //无硬件数据流控制
  89. USART_InitStructure.USART_Mode = USART_Mode_Rx | USART_Mode_Tx; //收发模式
  90. USART_Init(USART1, &USART_InitStructure); //初始化串口1
  91. USART_Cmd(USART1, ENABLE); //使能串口1
  92. }
  93. void Uart1DMA_Enable(DMA_Stream_TypeDef *DMA_Streamx, u16 count)
  94. {
  95. DMA_Cmd(DMA_Streamx, DISABLE); //关闭DMA传输
  96. while (DMA_GetCmdStatus(DMA_Streamx) != DISABLE)
  97. {
  98. } //确保DMA可以被设置
  99. DMA_SetCurrDataCounter(DMA_Streamx, count); //数据传输量
  100. DMA_Cmd(DMA_Streamx, ENABLE); //开启DMA传输
  101. }
  102. void uart1_init(void)
  103. {
  104. uart1_config();
  105. uart1_dma_init();
  106. uart1_nvic_config();
  107. // /* USART DMA enable*/
  108. USART_DMACmd(USART1, USART_DMAReq_Rx, ENABLE); // 使能串口DMA接收数据
  109. Uart1DMA_Enable(UART1_DMA_RXCH, UART3_REC_LEN);
  110. /*configure DMA0 interrupt*/
  111. USART_ITConfig(USART1, USART_IT_IDLE, ENABLE); //开启空闲中断
  112. USART_ITConfig(USART1, USART_IT_TC, ENABLE);
  113. UART1_RX_ENABLE;
  114. }
  115. /****************************************************
  116. * 函 数 名:Uart1_Send_Data
  117. * 函数功能:串口1发送数据
  118. * 入口参数:buf 待发送数据 len 数据长度
  119. * 说 明:
  120. *****************************************************/
  121. void Uart1_Send_Data(const u8 *buf, u16 len)
  122. {
  123. u8 i;
  124. UART1_TX_ENABLE; // 485 发送使能
  125. for (i = 0; i < len; i++) //循环发送数据
  126. {
  127. while (USART_GetFlagStatus(USART1, USART_FLAG_TC) == RESET)
  128. ;
  129. USART_SendData(USART1, buf[i]);
  130. }
  131. while (USART_GetFlagStatus(USART1, USART_FLAG_TC) == RESET)
  132. ;
  133. UART1_RX_ENABLE; // 接收使能
  134. }
  135. void Uart1_dma_Send_Data(const INT8U *buf, INT16U len)
  136. {
  137. // INT16U cnt = 0;
  138. if (RESET != DMA_GetFlagStatus(UART1_DMA_TXCH, DMA_FLAG_TCIF7))
  139. {
  140. DMA_ClearFlag(UART1_DMA_TXCH, DMA_FLAG_TCIF7);
  141. }
  142. UART1_TX_ENABLE;
  143. if (len > UART1_TX_LEN)
  144. {
  145. len = UART1_TX_LEN;
  146. }
  147. memcpy(uart1_tx_buf, buf, len);
  148. USART_DMACmd(USART1, USART_DMAReq_Tx, ENABLE); // 使能DMA串口发送数据
  149. Uart1DMA_Enable(UART1_DMA_TXCH, len);
  150. }
  151. void USART1_IRQHandler(void)
  152. {
  153. static INT8U u0_index = 0;
  154. volatile INT8U clear = 0;
  155. INT8U rec_cnt = 0;
  156. if (RESET != USART_GetITStatus(USART1, USART_IT_IDLE))
  157. {
  158. clear = USART1->SR;
  159. clear = USART1->DR; // 先读SR, 再读DR, 就是为了消除IDLE中断
  160. DMA_Cmd(UART1_DMA_RXCH, DISABLE);
  161. DMA_ClearFlag(UART1_DMA_RXCH, DMA_FLAG_TCIF5);
  162. rec_cnt = UART1_REC_LEN - DMA_GetCurrDataCounter(UART1_DMA_RXCH); // 获得接收帧帧长 特别注意: 帧长不是DMA_GetCurrDataCounter(DMA2_Stream5)
  163. memcpy(Uart1FrameStruct[u0_index].buf, uart1_rx_buf, rec_cnt);
  164. Uart1FrameStruct[u0_index].len = rec_cnt;
  165. OSMboxPost(uart1_mbox, &Uart1FrameStruct[u0_index]);
  166. if (u0_index < MAX_MSG_NUM - 1)
  167. {
  168. u0_index++;
  169. }
  170. else
  171. {
  172. u0_index = 0;
  173. }
  174. DMA_SetCurrDataCounter(UART1_DMA_RXCH, UART1_REC_LEN);
  175. DMA_Cmd(UART1_DMA_RXCH, ENABLE);
  176. }
  177. else if (RESET != USART_GetITStatus(USART1, USART_IT_TC))
  178. {
  179. USART_ClearITPendingBit(USART1, USART_IT_TC); // 清除发送完成标标志位
  180. UART1_RX_ENABLE; // 485接收使能
  181. Uart1DMA_Enable(UART1_DMA_RXCH, UART1_REC_LEN); // DMA接收使能
  182. DMA_Cmd(UART1_DMA_TXCH, DISABLE); // 关闭发送DMA
  183. DMA_SetCurrDataCounter(UART1_DMA_TXCH, 0); // 清除发送数据长度
  184. }
  185. }
  186. void uart3_nvic_config(void)
  187. {
  188. NVIC_InitTypeDef NVIC_InitStructure;
  189. // Usart3 NVIC 配置
  190. NVIC_InitStructure.NVIC_IRQChannel = USART3_IRQn; //串口3中断通道
  191. NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0; //抢占优先级
  192. NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0; //子优先级
  193. NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; // IRQ通道使能
  194. NVIC_Init(&NVIC_InitStructure);
  195. }
  196. void uart3_dma_init(void)
  197. {
  198. DMA_InitTypeDef DMA_InitStructure;
  199. if ((u32)UART3_DMA_TXCH > (u32)DMA2)
  200. {
  201. RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_DMA2, ENABLE); // DMA2时钟使能
  202. }
  203. else
  204. {
  205. RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_DMA1, ENABLE); // DMA1时钟使能
  206. }
  207. DMA_DeInit(UART3_DMA_TXCH);
  208. while (DMA_GetCmdStatus(UART3_DMA_TXCH) != DISABLE)
  209. {
  210. } //等待DMA可配置
  211. /* 配置 DMA Stream */
  212. DMA_InitStructure.DMA_Channel = UART3_DMA; //通道选择
  213. DMA_InitStructure.DMA_PeripheralBaseAddr = (u32)&USART3->DR; // DMA外设地址
  214. DMA_InitStructure.DMA_Memory0BaseAddr = (u32)uart3_tx_buf; // DMA 存储器0地址
  215. DMA_InitStructure.DMA_DIR = DMA_DIR_MemoryToPeripheral; //存储器到外设模式
  216. DMA_InitStructure.DMA_BufferSize = UART3_TX_LEN; //数据传输量
  217. DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable; //外设非增量模式
  218. DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable; //存储器增量模式
  219. DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_Byte; //外设数据长度:8位
  220. DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_Byte; //存储器数据长度:8位
  221. DMA_InitStructure.DMA_Mode = DMA_Mode_Normal; // 使用普通模式
  222. DMA_InitStructure.DMA_Priority = DMA_Priority_Medium; //中等优先级6
  223. DMA_InitStructure.DMA_FIFOMode = DMA_FIFOMode_Disable;
  224. DMA_InitStructure.DMA_FIFOThreshold = DMA_FIFOThreshold_Full;
  225. DMA_InitStructure.DMA_MemoryBurst = DMA_MemoryBurst_Single; //存储器突发单次传输
  226. DMA_InitStructure.DMA_PeripheralBurst = DMA_PeripheralBurst_Single; //外设突发单次传输
  227. DMA_Init(UART3_DMA_TXCH, &DMA_InitStructure); //初始化DMA Stream
  228. if ((u32)UART3_DMA_RXCH > (u32)DMA2) //得到当前stream是属于DMA2还是DMA1
  229. {
  230. RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_DMA2, ENABLE); // DMA2时钟使能
  231. }
  232. else
  233. {
  234. RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_DMA1, ENABLE); // DMA1时钟使能
  235. }
  236. DMA_DeInit(UART3_DMA_RXCH);
  237. while (DMA_GetCmdStatus(UART3_DMA_RXCH) != DISABLE)
  238. {
  239. } //等待DMA可配置
  240. /* 配置 DMA Stream */
  241. DMA_InitStructure.DMA_Channel = UART3_DMA; //通道选择
  242. DMA_InitStructure.DMA_PeripheralBaseAddr = (u32)&USART3->DR; // DMA外设地址
  243. DMA_InitStructure.DMA_Memory0BaseAddr = (u32)uart3_rx_buf; // DMA 存储器0地址
  244. DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralToMemory; //外设到存储器模式
  245. DMA_InitStructure.DMA_BufferSize = UART3_REC_LEN; //数据传输量
  246. DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable; //外设非增量模式
  247. DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable; //存储器增量模式
  248. DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_Byte; //外设数据长度:8位
  249. DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_Byte; //存储器数据长度:8位
  250. DMA_InitStructure.DMA_Mode = DMA_Mode_Circular; // 使用循环模式
  251. DMA_InitStructure.DMA_Priority = DMA_Priority_Medium; //中等优先级
  252. DMA_InitStructure.DMA_FIFOMode = DMA_FIFOMode_Disable;
  253. DMA_InitStructure.DMA_FIFOThreshold = DMA_FIFOThreshold_Full;
  254. DMA_InitStructure.DMA_MemoryBurst = DMA_MemoryBurst_Single; //存储器突发单次传输
  255. DMA_InitStructure.DMA_PeripheralBurst = DMA_PeripheralBurst_Single; //外设突发单次传输
  256. DMA_Init(UART3_DMA_RXCH, &DMA_InitStructure);
  257. }
  258. void uart3_config(void)
  259. {
  260. /* USART3 configure */
  261. USART_InitTypeDef USART_InitStructure;
  262. // USART3 初始化设置
  263. USART_InitStructure.USART_BaudRate = 9600; //波特率设置
  264. USART_InitStructure.USART_WordLength = USART_WordLength_8b; //字长为8位数据格式
  265. USART_InitStructure.USART_StopBits = USART_StopBits_1; //一个停止位
  266. USART_InitStructure.USART_Parity = USART_Parity_No; //无奇偶校验位
  267. USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None; //无硬件数据流控制
  268. USART_InitStructure.USART_Mode = USART_Mode_Rx | USART_Mode_Tx; //收发模式
  269. USART_Init(USART3, &USART_InitStructure); //初始化串口1
  270. USART_Cmd(USART3, ENABLE); //使能串口3
  271. }
  272. void Uart3DMA_Enable(DMA_Stream_TypeDef *DMA_Streamx, u16 count)
  273. {
  274. DMA_Cmd(DMA_Streamx, DISABLE); //关闭DMA传输
  275. while (DMA_GetCmdStatus(DMA_Streamx) != DISABLE)
  276. {
  277. } //确保DMA可以被设置
  278. DMA_SetCurrDataCounter(DMA_Streamx, count); //数据传输量
  279. DMA_Cmd(DMA_Streamx, ENABLE); //开启DMA传输
  280. }
  281. void uart3_init(void)
  282. {
  283. uart3_config();
  284. uart3_dma_init();
  285. uart3_nvic_config();
  286. /* USART DMA enable*/
  287. USART_DMACmd(USART3, USART_DMAReq_Rx, ENABLE); // 使能串口DMA接收数据
  288. Uart3DMA_Enable(UART3_DMA_RXCH, UART3_REC_LEN);
  289. /*configure DMA interrupt*/
  290. USART_ITConfig(USART3, USART_IT_IDLE, ENABLE); //开启空闲中断
  291. USART_ITConfig(USART3, USART_IT_TC, ENABLE);
  292. UART3_RX_ENABLE;
  293. }
  294. /****************************************************
  295. * 函 数 名:Uart3_Send_Data
  296. * 函数功能:串口1发送数据
  297. * 入口参数:buf 待发送数据 len 数据长度
  298. * 说 明:
  299. *****************************************************/
  300. void Uart3_Send_Data(const INT8U *buf, INT16U len)
  301. {
  302. INT8U i;
  303. UART3_TX_ENABLE; // 485 发送使能
  304. for (i = 0; i < len; i++) //循环发送数据
  305. {
  306. while (USART_GetFlagStatus(USART3, USART_FLAG_TC) == RESET)
  307. ;
  308. USART_SendData(USART3, buf[i]);
  309. }
  310. while (USART_GetFlagStatus(USART3, USART_FLAG_TC) == RESET)
  311. ;
  312. UART3_RX_ENABLE; // 接收使能
  313. }
  314. void Uart3_dma_Send_Data(const INT8U *buf, INT16U len)
  315. {
  316. if (DMA_GetFlagStatus(UART3_DMA_TXCH, DMA_FLAG_TCIF3) != RESET)
  317. {
  318. DMA_ClearFlag(UART3_DMA_TXCH, DMA_FLAG_TCIF3);
  319. }
  320. UART3_TX_ENABLE; // 485 发送使能
  321. if (len > UART3_TX_LEN)
  322. {
  323. len = UART3_TX_LEN;
  324. }
  325. memcpy(uart3_tx_buf, buf, len);
  326. USART_DMACmd(USART3, USART_DMAReq_Tx, len);
  327. Uart3DMA_Enable(UART3_DMA_TXCH, len);
  328. }
  329. void USART3_IRQHandler(void)
  330. {
  331. static INT8U u3_index = 0;
  332. volatile INT8U clear = 0;
  333. INT8U rec_cnt = 0;
  334. if (RESET != USART_GetITStatus(USART3, USART_IT_IDLE))
  335. {
  336. clear = USART3->SR;
  337. clear = USART3->DR; // 先读SR, 再读DR, 就是为了消除IDLE中断
  338. DMA_Cmd(UART3_DMA_RXCH, DISABLE);
  339. DMA_ClearFlag(UART3_DMA_RXCH, DMA_FLAG_TCIF1);
  340. rec_cnt = UART3_REC_LEN - DMA_GetCurrDataCounter(UART3_DMA_RXCH);
  341. memcpy(Uart3FrameStruct[u3_index].buf, uart3_rx_buf, rec_cnt);
  342. Uart3FrameStruct[u3_index].len = rec_cnt;
  343. OSMboxPost(uart3_mbox, &Uart3FrameStruct[u3_index]);
  344. if (u3_index < MAX_MSG_NUM - 1)
  345. {
  346. u3_index++;
  347. }
  348. else
  349. {
  350. u3_index = 0;
  351. }
  352. DMA_SetCurrDataCounter(UART3_DMA_RXCH, UART3_REC_LEN);
  353. DMA_Cmd(UART3_DMA_RXCH, ENABLE);
  354. }
  355. else if (RESET != USART_GetITStatus(USART3, USART_IT_TC))
  356. {
  357. USART_ClearITPendingBit(USART3, USART_IT_TC);
  358. UART3_RX_ENABLE;
  359. Uart3DMA_Enable(UART3_DMA_RXCH, UART3_REC_LEN); // DMA接收使能
  360. DMA_Cmd(UART3_DMA_TXCH, DISABLE); // 关闭发送DMA
  361. DMA_SetCurrDataCounter(UART3_DMA_TXCH, 0); // 清除发送数据长度
  362. }
  363. }