usart.c 9.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332
  1. #include "usart.h"
  2. /* \arg COM_EC800: EC800
  3. \arg COM_485: 485
  4. \arg COM_232: 232
  5. */
  6. static rcu_periph_enum COM_CLK[COMn] = {COM_EC800_CLK, COM_485_CLK, COM_232_CLK};
  7. static uint32_t COM_TX_PIN[COMn] = {COM_EC800_TX_PIN, COM_485_TX_PIN, COM_232_TX_PIN};
  8. static uint32_t COM_RX_PIN[COMn] = {COM_EC800_RX_PIN, COM_485_RX_PIN, COM_232_RX_PIN};
  9. static uint32_t COM_GPIO_PORT[COMn] = {COM_EC800_GPIO_PORT, COM_485_GPIO_PORT, COM_232_GPIO_PORT};
  10. static rcu_periph_enum COM_GPIO_CLK[COMn] = {COM_EC800_GPIO_CLK, COM_485_GPIO_CLK, COM_232_GPIO_CLK};
  11. static uint32_t COM_IT_HANDLER[COMn] = {COM_EC800_IT_HANDLER, COM_485_IT_HANDLER, COM_232_IT_HANDLER};
  12. static uint32_t COM_BAUDTATE[COMn]={COM_EC800_BAUDRATE,COM_485_BAUDRATE,COM_232_BAUDRATE};
  13. uint8_t UART0_RX_BUF[UART0_RX_LEN];
  14. uint8_t UART0_RX_STAT = 0;
  15. uint8_t UART0_RX_MQTT_SUB_STAT=0; //mqttt订阅信息标志位
  16. uint32_t UART0_RX_NUM = 0;
  17. usart_data_buf_t usart1_rx_buf;
  18. //清除dma buffer内数据
  19. void Clear_DMA_Buffer(void)
  20. {
  21. UART0_RX_NUM=0;
  22. memset(UART0_RX_BUF,0,UART0_RX_LEN);
  23. }
  24. /*!
  25. \brief configure 485 DE gpio
  26. \param[out] none
  27. \retval none
  28. */
  29. void gd_485_DE_pin_init(void)
  30. {
  31. /* enable the 485 DE pin clock */
  32. rcu_periph_clock_enable(RCU_GPIOA);
  33. /* configure 485 DE GPIO port */
  34. gpio_init(GPIOA, GPIO_MODE_OUT_PP, GPIO_OSPEED_50MHZ, GPIO_PIN_8);
  35. GPIO_BC(GPIOA) = GPIO_PIN_8;
  36. }
  37. /*!
  38. \brief turn 485 to tx
  39. \param[out] none
  40. \retval none
  41. */
  42. void gd_485_DE_tx(void)
  43. {
  44. GPIO_BOP(GPIOA) = GPIO_PIN_8;
  45. }
  46. /*!
  47. \brief turn 485 to rx
  48. \param[out] none
  49. \retval none
  50. */
  51. void gd_485_DE_rx(void)
  52. {
  53. GPIO_BC(GPIOA) = GPIO_PIN_8;
  54. }
  55. /*!
  56. \brief configure COM port
  57. \param[in] com: COM on the board
  58. \arg COM_EC800: EC800
  59. \arg COM_485: 485
  60. \arg COM_232: 232
  61. \param[out] none
  62. \retval none
  63. */
  64. void gd_com_init(uint32_t com)
  65. {
  66. uint32_t com_id = 0U;
  67. if(COM_EC800 == com)
  68. {
  69. com_id = 0U;
  70. }
  71. else if(COM_485 == com)
  72. {
  73. com_id=1U;
  74. }
  75. else if(COM_232 == com)
  76. {
  77. com_id = 2U;
  78. //重映射usart2端口
  79. rcu_periph_clock_enable(RCU_AF);
  80. gpio_pin_remap_config(GPIO_USART2_FULL_REMAP, ENABLE);
  81. }
  82. //nvic_irq_enable(COM_IT_HANDLER[com_id], 0, 0);
  83. /* enable GPIO clock */
  84. rcu_periph_clock_enable(COM_GPIO_CLK[com_id]);
  85. /* enable USART clock */
  86. rcu_periph_clock_enable(COM_CLK[com_id]);
  87. /* connect port to USARTx_Tx */
  88. gpio_init(COM_GPIO_PORT[com_id], GPIO_MODE_AF_PP, GPIO_OSPEED_50MHZ, COM_TX_PIN[com_id]);
  89. /* connect port to USARTx_Rx */
  90. gpio_init(COM_GPIO_PORT[com_id], GPIO_MODE_IN_FLOATING, GPIO_OSPEED_50MHZ, COM_RX_PIN[com_id]);
  91. /* USART configure */
  92. usart_deinit(com);
  93. usart_baudrate_set(com, COM_BAUDTATE[com_id]);
  94. usart_word_length_set(com, USART_WL_8BIT);
  95. usart_stop_bit_set(com, USART_STB_1BIT);
  96. usart_parity_config(com, USART_PM_NONE);
  97. usart_hardware_flow_rts_config(com, USART_RTS_DISABLE);
  98. usart_hardware_flow_cts_config(com, USART_CTS_DISABLE);
  99. usart_receive_config(com, USART_RECEIVE_ENABLE);
  100. usart_transmit_config(com, USART_TRANSMIT_ENABLE);
  101. usart_enable(com);
  102. // usart_interrupt_enable(com, USART_INT_TBE);
  103. usart_interrupt_enable(com, USART_INT_RBNE); //开启接受终端
  104. usart_interrupt_enable(com, USART_INT_IDLE); //开启空闲终端,也叫帧终端
  105. }
  106. /*!
  107. \brief COM port to send buff
  108. \param[in] com: COM on the board
  109. \arg COM_485
  110. \param[out] none
  111. \retval none
  112. */
  113. void gd_com_485_send(uint8_t *message,uint16_t size){
  114. uint16_t i=0;
  115. gd_485_DE_tx();
  116. uint8_t data;
  117. for (i = 0; i < size; i++)
  118. {
  119. data = message[i];
  120. usart_data_transmit(COM_485, data);
  121. while (RESET == usart_flag_get(COM_485, USART_FLAG_TC));
  122. }
  123. gd_485_DE_rx();
  124. }
  125. void gd_com_232_send(uint8_t *message,uint16_t size){
  126. uint16_t i=0;
  127. for (i = 0; i < size; i++){
  128. usart_data_transmit(COM_232, *(message + i));
  129. while (RESET == usart_flag_get(COM_232, USART_FLAG_TC));
  130. }
  131. }
  132. void gd_com_232_Receive(void)
  133. {
  134. uint8_t value;
  135. if(RESET != usart_interrupt_flag_get(COM_232, USART_INT_FLAG_RBNE))
  136. {
  137. /* receive data */
  138. value = (uint8_t)usart_data_receive(COM_232);
  139. usart_interrupt_flag_clear(COM_232,USART_INT_FLAG_ERR_FERR);
  140. }
  141. }
  142. /*!
  143. \brief configure EC800M pin
  144. \param[out] none
  145. \retval none
  146. */
  147. void gd_EC800M_pin_init(void)
  148. {
  149. /* enable the EC800M power pin clock */
  150. rcu_periph_clock_enable(EC800M_PER_GPIO_CLK);
  151. /* configure EC800M GPIO port */
  152. gpio_init(EC800M_PER_GPIO_PORT, GPIO_MODE_OUT_PP, GPIO_OSPEED_50MHZ, EC800M_PER_PIN);
  153. GPIO_BC(EC800M_PER_GPIO_PORT) = EC800M_PER_PIN;
  154. /* enable the EC800M reset pin clock */
  155. rcu_periph_clock_enable(EC800M_RST_GPIO_CLK);
  156. /* configure EC800M GPIO port */
  157. gpio_init(EC800M_RST_GPIO_PORT, GPIO_MODE_OUT_PP, GPIO_OSPEED_50MHZ, EC800M_RST_PIN);
  158. GPIO_BC(EC800M_RST_GPIO_PORT) = EC800M_RST_PIN;
  159. }
  160. void gd_pull_EC800M_pwr_up(void)
  161. {
  162. GPIO_BOP(EC800M_PER_GPIO_PORT) = EC800M_PER_PIN;
  163. }
  164. void gd_pull_EC800M_pwr_down(void)
  165. {
  166. GPIO_BC(EC800M_PER_GPIO_PORT) = EC800M_PER_PIN;
  167. }
  168. void gd_pull_EC800M_rst_up(void)
  169. {
  170. GPIO_BOP(EC800M_RST_GPIO_PORT) = EC800M_RST_PIN;
  171. }
  172. void gd_pull_EC800M_rst_down(void)
  173. {
  174. GPIO_BC(EC800M_RST_GPIO_PORT) = EC800M_RST_PIN;
  175. }
  176. ////////////////////////////////////////////////////////////////////
  177. void dma_config(void)
  178. {
  179. dma_parameter_struct dma_init_struct;
  180. rcu_periph_clock_enable(RCU_DMA0);
  181. dma_deinit(DMA0, DMA_CH4);
  182. dma_init_struct.direction = DMA_PERIPHERAL_TO_MEMORY;
  183. dma_init_struct.memory_addr = (uint32_t)UART0_RX_BUF;
  184. dma_init_struct.memory_inc = DMA_MEMORY_INCREASE_ENABLE;
  185. dma_init_struct.memory_width = DMA_MEMORY_WIDTH_8BIT;
  186. dma_init_struct.number = UART0_RX_LEN;
  187. dma_init_struct.periph_addr = (uint32_t)(&USART_DATA(USART0));// ((uint32_t)0x40013804);
  188. dma_init_struct.periph_inc = DMA_PERIPH_INCREASE_DISABLE;
  189. dma_init_struct.periph_width = DMA_PERIPHERAL_WIDTH_8BIT;
  190. dma_init_struct.priority = DMA_PRIORITY_ULTRA_HIGH;
  191. dma_init(DMA0, DMA_CH4, &dma_init_struct);
  192. dma_circulation_disable(DMA0, DMA_CH4);
  193. dma_memory_to_memory_disable(DMA0, DMA_CH4);
  194. usart_dma_transmit_config(USART0, USART_DENT_ENABLE|USART_DENR_ENABLE);
  195. //nvic_irq_enable(DMA0_Channel4_IRQn, 2, 2);
  196. dma_interrupt_enable(DMA0, DMA_CH4, DMA_INT_FTF|DMA_INT_HTF|DMA_INT_ERR);
  197. dma_channel_enable(DMA0, DMA_CH4);
  198. }
  199. //手动控制dma搬运的数据地址和大小,在使用完成后需要恢复到默认的dma配置
  200. void dma_config_change(char *dmaBuffer,uint32_t bufferSize)
  201. {
  202. dma_parameter_struct dma_init_struct;
  203. rcu_periph_clock_enable(RCU_DMA0);
  204. dma_deinit(DMA0, DMA_CH4);
  205. dma_init_struct.direction = DMA_PERIPHERAL_TO_MEMORY;
  206. dma_init_struct.memory_addr = (uint32_t)dmaBuffer;
  207. dma_init_struct.memory_inc = DMA_MEMORY_INCREASE_ENABLE;
  208. dma_init_struct.memory_width = DMA_MEMORY_WIDTH_8BIT;
  209. dma_init_struct.number = bufferSize;
  210. dma_init_struct.periph_addr = (uint32_t)(&USART_DATA(USART0));// ((uint32_t)0x40013804);
  211. dma_init_struct.periph_inc = DMA_PERIPH_INCREASE_DISABLE;
  212. dma_init_struct.periph_width = DMA_PERIPHERAL_WIDTH_8BIT;
  213. dma_init_struct.priority = DMA_PRIORITY_ULTRA_HIGH;
  214. dma_init(DMA0, DMA_CH4, &dma_init_struct);
  215. dma_circulation_disable(DMA0, DMA_CH4);
  216. dma_memory_to_memory_disable(DMA0, DMA_CH4);
  217. usart_dma_transmit_config(USART0, USART_DENT_ENABLE|USART_DENR_ENABLE);
  218. //nvic_irq_enable(DMA0_Channel4_IRQn, 2, 2);
  219. dma_interrupt_enable(DMA0, DMA_CH4, DMA_INT_FTF|DMA_INT_ERR);
  220. dma_channel_enable(DMA0, DMA_CH4);
  221. }
  222. /*
  223. * 函数名:void config_485_port(uint32_t com,uint32_t baudrate, uint8_t databits, uint8_t stopbits, uint8_t parity, uint8_t flowcontrol)
  224. * 输入参数:com 串口,baudrate,databits,stopbits,parity,flowcontol 串口的配置参数
  225. * 输出参数:无
  226. * 返回值:无
  227. * 函数作用:配置485串口参数
  228. */
  229. void config_485_port(uint32_t com,uint32_t baudrate, uint8_t databits, uint8_t stopbits, uint8_t parity)
  230. {
  231. uint32_t com_id = 0U;
  232. uint8_t wordLength;
  233. if(parity!=0)
  234. {
  235. wordLength=databits+1;
  236. }else wordLength=databits;
  237. if(COM_485 == com){
  238. com_id=1U;
  239. // nvic_irq_enable(COM_IT_HANDLER[com_id], 0, 0);
  240. /* enable GPIO clock */
  241. rcu_periph_clock_enable(COM_GPIO_CLK[com_id]);
  242. /* enable USART clock */
  243. rcu_periph_clock_enable(COM_CLK[com_id]);
  244. /* connect port to USARTx_Tx */
  245. gpio_init(COM_GPIO_PORT[com_id], GPIO_MODE_AF_PP, GPIO_OSPEED_50MHZ, COM_TX_PIN[com_id]);
  246. /* connect port to USARTx_Rx */
  247. gpio_init(COM_GPIO_PORT[com_id], GPIO_MODE_IN_FLOATING, GPIO_OSPEED_50MHZ, COM_RX_PIN[com_id]);
  248. //usart_deinit(com);
  249. usart_baudrate_set(com, baudrate);
  250. usart_word_length_set(com, (wordLength == 9) ? USART_WL_9BIT : USART_WL_8BIT);
  251. usart_stop_bit_set(com, (stopbits == 2) ? USART_STB_2BIT : USART_STB_1BIT);
  252. usart_parity_config(com, parity == 1 ? (USART_PM_ODD) : (parity == 2 ? USART_PM_EVEN : USART_PM_NONE));
  253. usart_hardware_flow_rts_config(com, USART_RTS_DISABLE);
  254. usart_hardware_flow_cts_config(com, USART_CTS_DISABLE);
  255. usart_receive_config(com, USART_RECEIVE_ENABLE);
  256. usart_transmit_config(com, USART_TRANSMIT_ENABLE);
  257. /* 使能串口 */
  258. usart_enable(com);
  259. usart_interrupt_enable(com, USART_INT_RBNE);
  260. usart_interrupt_enable(com, USART_INT_IDLE);
  261. //nvic_irq_enable(USART1_IRQn, 1, 0);
  262. //解决485第一个帧数据第一个字节丢失问题
  263. usart_flag_clear(COM_485,USART_FLAG_TC);
  264. }
  265. }
  266. void nvic_config(void)
  267. {
  268. nvic_priority_group_set(NVIC_PRIGROUP_PRE2_SUB2); // 设置抢占优先级和子优先级的位数为 2
  269. nvic_irq_enable(USART0_IRQn, 0, 0);
  270. nvic_irq_enable(USART1_IRQn, 1, 0);
  271. nvic_irq_enable(USART2_IRQn, 2, 0);
  272. nvic_irq_enable(DMA0_Channel4_IRQn, 2, 1);
  273. }