usart.c.orig 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449
  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. // 串口2接收的数据
  63. typedef struct {
  64. u8 *buf;
  65. u16 length;
  66. } usart_buffer;
  67. usart_buffer *us2_buf;
  68. //******************************************
  69. //初始化IO 串口2
  70. //bound:波特率
  71. //******************************************
  72. void uart2_init(u32 bound)
  73. {
  74. MX_DMA_Init();
  75. UART2_Handler.Instance = USART2;
  76. UART2_Handler.Init.BaudRate = bound;
  77. UART2_Handler.Init.WordLength = UART_WORDLENGTH_8B;
  78. UART2_Handler.Init.StopBits = UART_STOPBITS_1;
  79. UART2_Handler.Init.Parity = UART_PARITY_NONE;
  80. UART2_Handler.Init.Mode = UART_MODE_TX_RX;
  81. UART2_Handler.Init.HwFlowCtl = UART_HWCONTROL_NONE;
  82. if (HAL_UART_Init(&UART2_Handler) != HAL_OK)
  83. {
  84. _Error_Handler(__FILE__, __LINE__);
  85. }
  86. __HAL_UART_ENABLE_IT(&UART2_Handler, UART_IT_IDLE);
  87. HAL_UART_Receive_DMA(&UART2_Handler,USART2_RX_BUF,USART3_REC_LEN);
  88. }
  89. //******************************************
  90. //初始化IO 串口3
  91. //bound:波特率
  92. //******************************************
  93. void uart3_init(u32 bound)
  94. {
  95. //UART 初始化设置
  96. UART3_Handler.Instance=USART3; //USART1
  97. UART3_Handler.Init.BaudRate=bound; //波特率
  98. UART3_Handler.Init.WordLength=UART_WORDLENGTH_8B; //字长为8位数据格式
  99. UART3_Handler.Init.StopBits=UART_STOPBITS_1; //一个停止位
  100. UART3_Handler.Init.Parity=UART_PARITY_NONE; //无奇偶校验位
  101. UART3_Handler.Init.HwFlowCtl=UART_HWCONTROL_NONE; //无硬件流控
  102. UART3_Handler.Init.Mode=UART_MODE_TX_RX; //收发模式
  103. HAL_UART_Init(&UART3_Handler); //HAL_UART_Init()会使能UART3
  104. HAL_UART_Receive_IT(&UART3_Handler, (u8 *)usart3_aRxBuffer, RXBUFFERSIZE);//该函数会开启接收中断:标志位UART_IT_RXNE,并且设置接收缓冲以及接收缓冲接收最大数据量
  105. }
  106. //UART底层初始化,时钟使能,引脚配置,中断配置
  107. //此函数会被HAL_UART_Init()调用
  108. //huart:串口句柄
  109. void HAL_UART_MspInit(UART_HandleTypeDef *huart)
  110. {
  111. //GPIO端口设置
  112. GPIO_InitTypeDef GPIO_InitStruct;
  113. if(huart->Instance==USART2)//如果是串口2,进行串口2 MSP初始化
  114. {
  115. __HAL_RCC_GPIOA_CLK_ENABLE();
  116. __HAL_RCC_USART2_CLK_ENABLE();
  117. /**USART2 GPIO Configuration
  118. PA2 ------> USART2_TX
  119. PA3 ------> USART2_RX
  120. */
  121. GPIO_InitStruct.Pin=GPIO_PIN_2; //PA2 usart2_tx
  122. GPIO_InitStruct.Mode=GPIO_MODE_AF_PP;
  123. GPIO_InitStruct.Speed=GPIO_SPEED_FREQ_HIGH;
  124. GPIO_InitStruct.Pull=GPIO_PULLUP;
  125. HAL_GPIO_Init(GPIOA,&GPIO_InitStruct);
  126. GPIO_InitStruct.Pin=GPIO_PIN_3; //PA3
  127. GPIO_InitStruct.Mode=GPIO_MODE_AF_INPUT;
  128. HAL_GPIO_Init(GPIOA,&GPIO_InitStruct);
  129. HAL_NVIC_EnableIRQ(USART2_IRQn);
  130. HAL_NVIC_SetPriority(USART2_IRQn,3,3);
  131. /* USART2 DMA Init */
  132. /* USART2_RX Init */
  133. hdma_usart2_rx.Instance = DMA1_Channel6;
  134. hdma_usart2_rx.Init.Direction = DMA_PERIPH_TO_MEMORY;
  135. hdma_usart2_rx.Init.PeriphInc = DMA_PINC_DISABLE;
  136. hdma_usart2_rx.Init.MemInc = DMA_MINC_ENABLE;
  137. hdma_usart2_rx.Init.PeriphDataAlignment = DMA_PDATAALIGN_BYTE;
  138. hdma_usart2_rx.Init.MemDataAlignment = DMA_MDATAALIGN_BYTE;
  139. hdma_usart2_rx.Init.Mode = DMA_NORMAL;
  140. hdma_usart2_rx.Init.Priority = DMA_PRIORITY_HIGH;
  141. if (HAL_DMA_Init(&hdma_usart2_rx) != HAL_OK)
  142. {
  143. _Error_Handler(__FILE__, __LINE__);
  144. }
  145. __HAL_LINKDMA(huart,hdmarx,hdma_usart2_rx);
  146. /* USART2_TX Init */
  147. hdma_usart2_tx.Instance = DMA1_Channel7;
  148. hdma_usart2_tx.Init.Direction = DMA_MEMORY_TO_PERIPH;
  149. hdma_usart2_tx.Init.PeriphInc = DMA_PINC_DISABLE;
  150. hdma_usart2_tx.Init.MemInc = DMA_MINC_ENABLE;
  151. hdma_usart2_tx.Init.PeriphDataAlignment = DMA_PDATAALIGN_BYTE;
  152. hdma_usart2_tx.Init.MemDataAlignment = DMA_MDATAALIGN_BYTE;
  153. hdma_usart2_tx.Init.Mode = DMA_NORMAL;
  154. hdma_usart2_tx.Init.Priority = DMA_PRIORITY_LOW;
  155. if (HAL_DMA_Init(&hdma_usart2_tx) != HAL_OK)
  156. {
  157. _Error_Handler(__FILE__, __LINE__);
  158. }
  159. __HAL_LINKDMA(huart,hdmatx,hdma_usart2_tx);
  160. /* USART2 interrupt Init */
  161. HAL_NVIC_SetPriority(USART2_IRQn, 3, 3);
  162. HAL_NVIC_EnableIRQ(USART2_IRQn);
  163. /* USER CODE BEGIN USART2_MspInit 1 */
  164. /* USER CODE END USART2_MspInit 1 */
  165. }
  166. if(huart->Instance==USART3)//如果是串口3,进行串口3 MSP初始化
  167. {
  168. __HAL_RCC_GPIOB_CLK_ENABLE(); //使能GPIOB时钟
  169. __HAL_RCC_GPIOC_CLK_ENABLE(); //使能GPIOC时钟
  170. __HAL_RCC_USART3_CLK_ENABLE(); //使能USART3时钟
  171. GPIO_InitStruct.Pin=GPIO_PIN_10; //PB10 usart3_tx
  172. GPIO_InitStruct.Mode=GPIO_MODE_AF_PP; //复用推挽输出
  173. GPIO_InitStruct.Pull=GPIO_PULLUP; //上拉
  174. GPIO_InitStruct.Speed=GPIO_SPEED_FREQ_HIGH;//高速
  175. HAL_GPIO_Init(GPIOB,&GPIO_InitStruct); //初始化PB10
  176. GPIO_InitStruct.Pin=GPIO_PIN_11; //PB11
  177. GPIO_InitStruct.Mode=GPIO_MODE_AF_INPUT; //模式要设置为复用输入模式!
  178. HAL_GPIO_Init(GPIOB,&GPIO_InitStruct); //初始化PB11
  179. GPIO_InitStruct.Pin = GPIO_PIN_13; //485 发送接收
  180. GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
  181. GPIO_InitStruct.Pull = GPIO_NOPULL;
  182. GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH;
  183. HAL_GPIO_Init(GPIOC, &GPIO_InitStruct);
  184. #if EN_USART3_RX
  185. __HAL_UART_ENABLE_IT(&UART3_Handler,UART_IT_RXNE);//开启接收中断
  186. HAL_NVIC_EnableIRQ(USART3_IRQn); //使能USART3中断通道
  187. HAL_NVIC_SetPriority(USART3_IRQn,2,2); //抢占优先级3,子优先级3
  188. #endif
  189. Usart_TX_Set(0); //设置为接收模式
  190. }
  191. }
  192. void HAL_UART_MspDeInit(UART_HandleTypeDef* uartHandle)
  193. {
  194. if(uartHandle->Instance==USART2)
  195. {
  196. /* USER CODE BEGIN USART2_MspDeInit 0 */
  197. /* USER CODE END USART2_MspDeInit 0 */
  198. /* Peripheral clock disable */
  199. __HAL_RCC_USART2_CLK_DISABLE();
  200. /**USART2 GPIO Configuration
  201. PA2 ------> USART2_TX
  202. PA3 ------> USART2_RX
  203. */
  204. HAL_GPIO_DeInit(GPIOA, GPIO_PIN_2|GPIO_PIN_3);
  205. /* USART2 DMA DeInit */
  206. HAL_DMA_DeInit(uartHandle->hdmarx);
  207. HAL_DMA_DeInit(uartHandle->hdmatx);
  208. /* USART2 interrupt Deinit */
  209. HAL_NVIC_DisableIRQ(USART2_IRQn);
  210. /* USER CODE BEGIN USART2_MspDeInit 1 */
  211. /* USER CODE END USART2_MspDeInit 1 */
  212. }
  213. else if(uartHandle->Instance==USART3)
  214. {
  215. /* USER CODE BEGIN USART3_MspDeInit 0 */
  216. /* USER CODE END USART3_MspDeInit 0 */
  217. /* Peripheral clock disable */
  218. __HAL_RCC_USART3_CLK_DISABLE();
  219. /**USART3 GPIO Configuration
  220. PB10 ------> USART3_TX
  221. PB11 ------> USART3_RX
  222. */
  223. HAL_GPIO_DeInit(GPIOB, GPIO_PIN_10|GPIO_PIN_11);
  224. /* USART3 interrupt Deinit */
  225. HAL_NVIC_DisableIRQ(USART3_IRQn);
  226. /* USER CODE BEGIN USART3_MspDeInit 1 */
  227. /* USER CODE END USART3_MspDeInit 1 */
  228. }
  229. }
  230. static void Usart2_Data_Handler(void) {
  231. PRINTF("recive:%s\r\n", USART2_RX_BUF);
  232. task *task = new_task();
  233. memcpy(us2_buf->buf, USART2_RX_BUF,uart2RxCounter + 1);
  234. us2_buf->buf[uart2RxCounter] = 0;
  235. us2_buf->length=uart2RxCounter+1;
  236. task->handler = module_data_handler;
  237. task->pdata=us2_buf;
  238. add_task(task);
  239. memset(USART2_RX_BUF,0,uart2RxCounter);
  240. uart2RxCounter = 0;
  241. }
  242. void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart)
  243. {
  244. if(huart->Instance==USART2)//如果是串口2
  245. {
  246. PRINTF("inter");
  247. }
  248. if(huart->Instance==USART3)//如果是串口3
  249. {
  250. if((USART3_RX_STA&0x8000)==0)//接收未完成
  251. {
  252. if(USART3_RX_STA&0x4000)//接收到了0x0d
  253. {
  254. if(usart3_aRxBuffer[0]!=0x0a)USART3_RX_STA=0;//接收错误,重新开始
  255. else USART3_RX_STA|=0x8000; //接收完成了
  256. }
  257. else //还没收到0X0D
  258. {
  259. if(usart3_aRxBuffer[0]==0x0d)USART3_RX_STA|=0x4000;
  260. else
  261. {
  262. USART3_RX_BUF[USART3_RX_STA&0X3FFF]=usart3_aRxBuffer[0] ;
  263. USART3_RX_STA++;
  264. if(USART3_RX_STA>(USART3_REC_LEN-1))USART3_RX_STA=0;//接收数据错误,重新开始接收
  265. }
  266. }
  267. }
  268. }
  269. }
  270. void UART_IDLE_Callback(UART_HandleTypeDef *huart)
  271. {
  272. u32 temp;
  273. if(__HAL_UART_GET_FLAG(huart,UART_FLAG_IDLE)) {
  274. HAL_UART_DMAStop(huart);
  275. temp=huart->Instance->SR;
  276. temp=huart->Instance->DR;
  277. temp = __HAL_DMA_GET_COUNTER(&hdma_usart2_rx);
  278. uart2RxCounter = USART2_REC_LEN-temp;
  279. Usart2_Data_Handler();
  280. __HAL_UART_CLEAR_IDLEFLAG(huart);
  281. HAL_UART_Receive_DMA(huart,USART2_RX_BUF,USART3_REC_LEN);
  282. }
  283. }
  284. //串口2中断服务程序
  285. void USART2_IRQHandler(void)
  286. {
  287. UART_IDLE_Callback(&UART2_Handler);
  288. HAL_UART_IRQHandler(&UART2_Handler);
  289. }
  290. //串口3中断服务程序
  291. void USART3_IRQHandler(void)
  292. {
  293. u32 timeout=0;
  294. #if SYSTEM_SUPPORT_OS //使用OS
  295. OSIntEnter();
  296. #endif
  297. HAL_UART_IRQHandler(&UART3_Handler); //调用HAL库中断处理公用函数
  298. timeout=0;
  299. while (HAL_UART_GetState(&UART3_Handler) != HAL_UART_STATE_READY)//等待就绪
  300. {
  301. timeout++;////超时处理
  302. if(timeout>HAL_MAX_DELAY) break;
  303. }
  304. timeout=0;
  305. while(HAL_UART_Receive_IT(&UART3_Handler, (u8 *)usart3_aRxBuffer, RXBUFFERSIZE) != HAL_OK)//一次处理完成之后,重新开启中断并设置RxXferCount为1
  306. {
  307. timeout++; //超时处理
  308. if(timeout>HAL_MAX_DELAY) break;
  309. }
  310. #if SYSTEM_SUPPORT_OS //使用OS
  311. OSIntExit();
  312. #endif
  313. }
  314. #endif
  315. //******************************************
  316. //RS485模式控制.
  317. //Ren:1,接收;0,发送.
  318. //******************************************
  319. void Usart_TX_Set(uint8_t Ren)
  320. {
  321. uint8_t i;
  322. i=Ren;
  323. if(i==0)
  324. {
  325. PCout(13)=0;
  326. }
  327. else
  328. {
  329. PCout(13)=1;
  330. }
  331. }
  332. //******************************************
  333. //RS485发送字符串.
  334. //******************************************
  335. void Usart_Send_Str_Data(char *str)
  336. {
  337. Usart_TX_Set(1); //设置为发送模式
  338. delay_us(1000);
  339. printf(str);
  340. delay_us(150);
  341. Usart_TX_Set(0);
  342. }
  343. //******************************************
  344. //RS485发送len个字节.
  345. //buf:发送区首地址
  346. //len:发送的字节数(为了和本代码的接收匹配,这里建议不要超过64个字节)
  347. //******************************************
  348. void Usart_Send_Data(uint8_t *buf,uint8_t len)
  349. {
  350. Usart_TX_Set(1); //设置为发送模式
  351. delay_ms(100);
  352. // HAL_UART_Transmit(&huart3,buf,len,1000);//串口3发送数据
  353. Usart_TX_Set(0); //设置为接收模式
  354. delay_ms(50);
  355. }
  356. void MYDMA_USART_Transmit(UART_HandleTypeDef *huart, uint8_t *pData, uint16_t Size)
  357. {
  358. HAL_DMA_Start(huart->hdmatx, (u32)pData, (uint32_t)&huart->Instance->DR, Size);
  359. huart->Instance->CR3 |= USART_CR3_DMAT;
  360. }
  361. void Usart2_Send_Data(u8 *buffer,u8 len)
  362. {
  363. MYDMA_USART_Transmit(&UART2_Handler, buffer, len);
  364. //HAL_UART_Transmit(&UART2_Handler,buffer,len,1000);
  365. delay_ms(500);
  366. }