usart.c 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459
  1. #include "usart.h"
  2. #include "task.h"
  3. #include "sim7600.h"
  4. #include "delay.h"
  5. #include "malloc.h"
  6. #include "dma.h"
  7. #include <string.h>
  8. //////////////////////////////////////////////////////////////////////////////////
  9. //如果使用os,则包括下面的头文件即可.
  10. #if SYSTEM_SUPPORT_OS
  11. #include "includes.h" //os 使用
  12. #endif
  13. //////////////////////////////////////////////////////////////////////////////////
  14. //本程序只供学习使用,未经作者许可,不得用于其它任何用途
  15. //ALIENTEK STM32F407开发板
  16. //串口3初始化
  17. //正点原子@ALIENTEK
  18. //技术论坛:www.openedv.com
  19. //修改日期:2017/4/6
  20. //版本:V1.5
  21. //版权所有,盗版必究。
  22. //Copyright(C) 广州市星翼电子科技有限公司 2009-2019
  23. //All rights reserved
  24. //********************************************************************************
  25. //V1.0修改说明
  26. //////////////////////////////////////////////////////////////////////////////////
  27. //加入以下代码,支持printf函数,而不需要选择use MicroLIB
  28. //#define PUTCHAR_PROTOTYPE int fputc(int ch, FILE *f)
  29. #if 1
  30. #pragma import(__use_no_semihosting)
  31. //标准库需要的支持函数
  32. struct __FILE
  33. {
  34. int handle;
  35. };
  36. FILE __stdout;
  37. //定义_sys_exit()以避免使用半主机模式
  38. void _sys_exit(int x)
  39. {
  40. x = x;
  41. }
  42. //重定义fputc函数
  43. int fputc(int ch, FILE *f)
  44. {
  45. while((USART3->SR&0X40)==0);//循环发送,直到发送完毕
  46. USART3->DR = (u8) ch;
  47. return ch;
  48. }
  49. #endif
  50. u8 USART2_RX_BUF[USART2_REC_LEN]; //接收缓冲,最大USART_REC_LEN个字节.
  51. u16 uart2RxCounter;
  52. #if EN_USART3_RX //如果使能了接收
  53. //串口3中断服务程序
  54. //注意,读取USARTx->SR能避免莫名其妙的错误
  55. u8 USART3_RX_BUF[USART3_REC_LEN]; //接收缓冲,最大USART_REC_LEN个字节.
  56. u16 USART3_RX_STA=0; //接收状态标记
  57. u8 usart3_aRxBuffer[RXBUFFERSIZE];//HAL库使用的串口接收缓冲
  58. UART_HandleTypeDef UART2_Handler; //UART句柄
  59. UART_HandleTypeDef UART3_Handler; //UART句柄
  60. DMA_HandleTypeDef hdma_usart2_tx; //DMA句柄
  61. DMA_HandleTypeDef hdma_usart2_rx;
  62. // SIM7600初始化状态
  63. BOOL isInitDone = 0;
  64. // 串口2接收的数据
  65. typedef struct {
  66. u8 *buf;
  67. u16 length;
  68. } usart_buffer;
  69. usart_buffer *us2_buf;
  70. //******************************************
  71. //初始化IO 串口2
  72. //bound:波特率
  73. //******************************************
  74. void uart2_init(u32 bound)
  75. {
  76. MX_DMA_Init();
  77. UART2_Handler.Instance = USART2;
  78. UART2_Handler.Init.BaudRate = bound;
  79. UART2_Handler.Init.WordLength = UART_WORDLENGTH_8B;
  80. UART2_Handler.Init.StopBits = UART_STOPBITS_1;
  81. UART2_Handler.Init.Parity = UART_PARITY_NONE;
  82. UART2_Handler.Init.Mode = UART_MODE_TX_RX;
  83. UART2_Handler.Init.HwFlowCtl = UART_HWCONTROL_NONE;
  84. if (HAL_UART_Init(&UART2_Handler) != HAL_OK)
  85. {
  86. _Error_Handler(__FILE__, __LINE__);
  87. }
  88. __HAL_UART_ENABLE_IT(&UART2_Handler, UART_IT_IDLE);
  89. HAL_UART_Receive_DMA(&UART2_Handler,USART2_RX_BUF,USART2_REC_LEN);
  90. }
  91. //******************************************
  92. //初始化IO 串口3
  93. //bound:波特率
  94. //******************************************
  95. void uart3_init(u32 bound)
  96. {
  97. //UART 初始化设置
  98. UART3_Handler.Instance=USART3; //USART1
  99. UART3_Handler.Init.BaudRate=bound; //波特率
  100. UART3_Handler.Init.WordLength=UART_WORDLENGTH_8B; //字长为8位数据格式
  101. UART3_Handler.Init.StopBits=UART_STOPBITS_1; //一个停止位
  102. UART3_Handler.Init.Parity=UART_PARITY_NONE; //无奇偶校验位
  103. UART3_Handler.Init.HwFlowCtl=UART_HWCONTROL_NONE; //无硬件流控
  104. UART3_Handler.Init.Mode=UART_MODE_TX_RX; //收发模式
  105. HAL_UART_Init(&UART3_Handler); //HAL_UART_Init()会使能UART3
  106. HAL_UART_Receive_IT(&UART3_Handler, (u8 *)usart3_aRxBuffer, RXBUFFERSIZE);//该函数会开启接收中断:标志位UART_IT_RXNE,并且设置接收缓冲以及接收缓冲接收最大数据量
  107. }
  108. //UART底层初始化,时钟使能,引脚配置,中断配置
  109. //此函数会被HAL_UART_Init()调用
  110. //huart:串口句柄
  111. void HAL_UART_MspInit(UART_HandleTypeDef *huart)
  112. {
  113. //GPIO端口设置
  114. GPIO_InitTypeDef GPIO_InitStruct;
  115. if(huart->Instance==USART2)//如果是串口2,进行串口2 MSP初始化
  116. {
  117. __HAL_RCC_GPIOA_CLK_ENABLE();
  118. __HAL_RCC_USART2_CLK_ENABLE();
  119. /**USART2 GPIO Configuration
  120. PA2 ------> USART2_TX
  121. PA3 ------> USART2_RX
  122. */
  123. GPIO_InitStruct.Pin=GPIO_PIN_2; //PA2 usart2_tx
  124. GPIO_InitStruct.Mode=GPIO_MODE_AF_PP;
  125. GPIO_InitStruct.Speed=GPIO_SPEED_FREQ_HIGH;
  126. GPIO_InitStruct.Pull=GPIO_PULLUP;
  127. HAL_GPIO_Init(GPIOA,&GPIO_InitStruct);
  128. GPIO_InitStruct.Pin=GPIO_PIN_3; //PA3
  129. GPIO_InitStruct.Mode=GPIO_MODE_AF_INPUT;
  130. HAL_GPIO_Init(GPIOA,&GPIO_InitStruct);
  131. HAL_NVIC_EnableIRQ(USART2_IRQn);
  132. HAL_NVIC_SetPriority(USART2_IRQn,3,3);
  133. /* USART2 DMA Init */
  134. /* USART2_RX Init */
  135. hdma_usart2_rx.Instance = DMA1_Channel6;
  136. hdma_usart2_rx.Init.Direction = DMA_PERIPH_TO_MEMORY;
  137. hdma_usart2_rx.Init.PeriphInc = DMA_PINC_DISABLE;
  138. hdma_usart2_rx.Init.MemInc = DMA_MINC_ENABLE;
  139. hdma_usart2_rx.Init.PeriphDataAlignment = DMA_PDATAALIGN_BYTE;
  140. hdma_usart2_rx.Init.MemDataAlignment = DMA_MDATAALIGN_BYTE;
  141. hdma_usart2_rx.Init.Mode = DMA_NORMAL;
  142. hdma_usart2_rx.Init.Priority = DMA_PRIORITY_HIGH;
  143. if (HAL_DMA_Init(&hdma_usart2_rx) != HAL_OK)
  144. {
  145. _Error_Handler(__FILE__, __LINE__);
  146. }
  147. __HAL_LINKDMA(huart,hdmarx,hdma_usart2_rx);
  148. /* USART2_TX Init */
  149. hdma_usart2_tx.Instance = DMA1_Channel7;
  150. hdma_usart2_tx.Init.Direction = DMA_MEMORY_TO_PERIPH;
  151. hdma_usart2_tx.Init.PeriphInc = DMA_PINC_DISABLE;
  152. hdma_usart2_tx.Init.MemInc = DMA_MINC_ENABLE;
  153. hdma_usart2_tx.Init.PeriphDataAlignment = DMA_PDATAALIGN_BYTE;
  154. hdma_usart2_tx.Init.MemDataAlignment = DMA_MDATAALIGN_BYTE;
  155. hdma_usart2_tx.Init.Mode = DMA_NORMAL;
  156. hdma_usart2_tx.Init.Priority = DMA_PRIORITY_LOW;
  157. if (HAL_DMA_Init(&hdma_usart2_tx) != HAL_OK)
  158. {
  159. _Error_Handler(__FILE__, __LINE__);
  160. }
  161. __HAL_LINKDMA(huart,hdmatx,hdma_usart2_tx);
  162. /* USART2 interrupt Init */
  163. HAL_NVIC_SetPriority(USART2_IRQn, 3, 3);
  164. HAL_NVIC_EnableIRQ(USART2_IRQn);
  165. /* USER CODE BEGIN USART2_MspInit 1 */
  166. /* USER CODE END USART2_MspInit 1 */
  167. }
  168. if(huart->Instance==USART3)//如果是串口3,进行串口3 MSP初始化
  169. {
  170. __HAL_RCC_GPIOB_CLK_ENABLE(); //使能GPIOB时钟
  171. __HAL_RCC_GPIOC_CLK_ENABLE(); //使能GPIOC时钟
  172. __HAL_RCC_USART3_CLK_ENABLE(); //使能USART3时钟
  173. GPIO_InitStruct.Pin=GPIO_PIN_10; //PB10 usart3_tx
  174. GPIO_InitStruct.Mode=GPIO_MODE_AF_PP; //复用推挽输出
  175. GPIO_InitStruct.Pull=GPIO_PULLUP; //上拉
  176. GPIO_InitStruct.Speed=GPIO_SPEED_FREQ_HIGH;//高速
  177. HAL_GPIO_Init(GPIOB,&GPIO_InitStruct); //初始化PB10
  178. GPIO_InitStruct.Pin=GPIO_PIN_11; //PB11
  179. GPIO_InitStruct.Mode=GPIO_MODE_AF_INPUT; //模式要设置为复用输入模式!
  180. HAL_GPIO_Init(GPIOB,&GPIO_InitStruct); //初始化PB11
  181. GPIO_InitStruct.Pin = GPIO_PIN_13; //485 发送接收
  182. GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
  183. GPIO_InitStruct.Pull = GPIO_NOPULL;
  184. GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH;
  185. HAL_GPIO_Init(GPIOC, &GPIO_InitStruct);
  186. #if EN_USART3_RX
  187. __HAL_UART_ENABLE_IT(&UART3_Handler,UART_IT_RXNE);//开启接收中断
  188. HAL_NVIC_EnableIRQ(USART3_IRQn); //使能USART3中断通道
  189. HAL_NVIC_SetPriority(USART3_IRQn,2,2); //抢占优先级3,子优先级3
  190. #endif
  191. Usart_TX_Set(0); //设置为接收模式
  192. }
  193. }
  194. void HAL_UART_MspDeInit(UART_HandleTypeDef* uartHandle)
  195. {
  196. if(uartHandle->Instance==USART2)
  197. {
  198. /* USER CODE BEGIN USART2_MspDeInit 0 */
  199. /* USER CODE END USART2_MspDeInit 0 */
  200. /* Peripheral clock disable */
  201. __HAL_RCC_USART2_CLK_DISABLE();
  202. /**USART2 GPIO Configuration
  203. PA2 ------> USART2_TX
  204. PA3 ------> USART2_RX
  205. */
  206. HAL_GPIO_DeInit(GPIOA, GPIO_PIN_2|GPIO_PIN_3);
  207. /* USART2 DMA DeInit */
  208. HAL_DMA_DeInit(uartHandle->hdmarx);
  209. HAL_DMA_DeInit(uartHandle->hdmatx);
  210. /* USART2 interrupt Deinit */
  211. HAL_NVIC_DisableIRQ(USART2_IRQn);
  212. /* USER CODE BEGIN USART2_MspDeInit 1 */
  213. /* USER CODE END USART2_MspDeInit 1 */
  214. }
  215. else if(uartHandle->Instance==USART3)
  216. {
  217. /* USER CODE BEGIN USART3_MspDeInit 0 */
  218. /* USER CODE END USART3_MspDeInit 0 */
  219. /* Peripheral clock disable */
  220. __HAL_RCC_USART3_CLK_DISABLE();
  221. /**USART3 GPIO Configuration
  222. PB10 ------> USART3_TX
  223. PB11 ------> USART3_RX
  224. */
  225. HAL_GPIO_DeInit(GPIOB, GPIO_PIN_10|GPIO_PIN_11);
  226. /* USART3 interrupt Deinit */
  227. HAL_NVIC_DisableIRQ(USART3_IRQn);
  228. /* USER CODE BEGIN USART3_MspDeInit 1 */
  229. /* USER CODE END USART3_MspDeInit 1 */
  230. }
  231. }
  232. static void Usart2_Data_Handler(void) {
  233. PRINTF("SIM7600====>MCU:%s, len:%d\r\n", USART2_RX_BUF, uart2RxCounter);
  234. task *task = new_task();
  235. memcpy(us2_buf->buf, USART2_RX_BUF,uart2RxCounter + 1);
  236. us2_buf->buf[uart2RxCounter] = '\0';
  237. us2_buf->length=uart2RxCounter+1;
  238. task->handler = module_data_handler;
  239. task->pdata=us2_buf;
  240. add_task(task);
  241. uart2RxCounter = 0;
  242. for(int i=0;i<USART2_REC_LEN;i++)
  243. {
  244. USART2_RX_BUF[i]=0;
  245. }
  246. }
  247. void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart)
  248. {
  249. if(huart->Instance==USART2)//如果是串口2
  250. {
  251. PRINTF("inter");
  252. }
  253. if(huart->Instance==USART3)//如果是串口3
  254. {
  255. if((USART3_RX_STA&0x8000)==0)//接收未完成
  256. {
  257. if(USART3_RX_STA&0x4000)//接收到了0x0d
  258. {
  259. if(usart3_aRxBuffer[0]!=0x0a)USART3_RX_STA=0;//接收错误,重新开始
  260. else USART3_RX_STA|=0x8000; //接收完成了
  261. }
  262. else //还没收到0X0D
  263. {
  264. if(usart3_aRxBuffer[0]==0x0d)USART3_RX_STA|=0x4000;
  265. else
  266. {
  267. USART3_RX_BUF[USART3_RX_STA&0X3FFF]=usart3_aRxBuffer[0] ;
  268. USART3_RX_STA++;
  269. if(USART3_RX_STA>(USART3_REC_LEN-1))USART3_RX_STA=0;//接收数据错误,重新开始接收
  270. }
  271. }
  272. }
  273. }
  274. }
  275. void UART_IDLE_Callback(UART_HandleTypeDef *huart)
  276. {
  277. u32 temp;
  278. if(__HAL_UART_GET_FLAG(huart,UART_FLAG_IDLE)) {
  279. __HAL_UART_CLEAR_IDLEFLAG(huart);
  280. HAL_UART_DMAStop(huart);
  281. temp=huart->Instance->SR;
  282. temp=huart->Instance->DR;
  283. temp = __HAL_DMA_GET_COUNTER(&hdma_usart2_rx);
  284. uart2RxCounter = USART2_REC_LEN-temp;
  285. char * p = strstr((char *)USART2_RX_BUF, "DONE");
  286. if(p != NULL)
  287. {
  288. isInitDone = 1;
  289. }
  290. else
  291. {
  292. Usart2_Data_Handler();
  293. }
  294. HAL_UART_Receive_DMA(huart,USART2_RX_BUF,USART2_REC_LEN);
  295. }
  296. }
  297. //串口2中断服务程序
  298. void USART2_IRQHandler(void)
  299. {
  300. UART_IDLE_Callback(&UART2_Handler);
  301. HAL_UART_IRQHandler(&UART2_Handler);
  302. }
  303. //串口3中断服务程序
  304. void USART3_IRQHandler(void)
  305. {
  306. u32 timeout=0;
  307. #if SYSTEM_SUPPORT_OS //使用OS
  308. OSIntEnter();
  309. #endif
  310. HAL_UART_IRQHandler(&UART3_Handler); //调用HAL库中断处理公用函数
  311. timeout=0;
  312. while (HAL_UART_GetState(&UART3_Handler) != HAL_UART_STATE_READY)//等待就绪
  313. {
  314. timeout++;////超时处理
  315. if(timeout>HAL_MAX_DELAY) break;
  316. }
  317. timeout=0;
  318. while(HAL_UART_Receive_IT(&UART3_Handler, (u8 *)usart3_aRxBuffer, RXBUFFERSIZE) != HAL_OK)//一次处理完成之后,重新开启中断并设置RxXferCount为1
  319. {
  320. timeout++; //超时处理
  321. if(timeout>HAL_MAX_DELAY) break;
  322. }
  323. #if SYSTEM_SUPPORT_OS //使用OS
  324. OSIntExit();
  325. #endif
  326. }
  327. #endif
  328. //******************************************
  329. //RS485模式控制.
  330. //Ren:1,接收;0,发送.
  331. //******************************************
  332. void Usart_TX_Set(uint8_t Ren)
  333. {
  334. uint8_t i;
  335. i=Ren;
  336. if(i==0)
  337. {
  338. PCout(13)=0;
  339. }
  340. else
  341. {
  342. PCout(13)=1;
  343. }
  344. }
  345. //******************************************
  346. //RS485发送字符串.
  347. //******************************************
  348. void Usart_Send_Str_Data(char *str)
  349. {
  350. Usart_TX_Set(1); //设置为发送模式
  351. delay_us(1000);
  352. printf(str);
  353. delay_us(150);
  354. Usart_TX_Set(0);
  355. }
  356. //******************************************
  357. //RS485发送len个字节.
  358. //buf:发送区首地址
  359. //len:发送的字节数(为了和本代码的接收匹配,这里建议不要超过64个字节)
  360. //******************************************
  361. void Usart_Send_Data(uint8_t *buf,uint8_t len)
  362. {
  363. Usart_TX_Set(1); //设置为发送模式
  364. delay_ms(100);
  365. // HAL_UART_Transmit(&huart3,buf,len,1000);//串口3发送数据
  366. Usart_TX_Set(0); //设置为接收模式
  367. delay_ms(50);
  368. }
  369. void Usart2_Send_Data(u8 *buffer,u16 len)
  370. {
  371. if(HAL_OK !=HAL_UART_Transmit(&UART2_Handler, buffer,len, 10000))
  372. {
  373. }
  374. }