#include "usart.h" #include "task.h" #include "sim7600.h" #include "delay.h" #include "malloc.h" #include "dma.h" #include ////////////////////////////////////////////////////////////////////////////////// //如果使用os,则包括下面的头文件即可. #if SYSTEM_SUPPORT_OS #include "includes.h" //os 使用 #endif ////////////////////////////////////////////////////////////////////////////////// //本程序只供学习使用,未经作者许可,不得用于其它任何用途 //ALIENTEK STM32F407开发板 //串口3初始化 //正点原子@ALIENTEK //技术论坛:www.openedv.com //修改日期:2017/4/6 //版本:V1.5 //版权所有,盗版必究。 //Copyright(C) 广州市星翼电子科技有限公司 2009-2019 //All rights reserved //******************************************************************************** //V1.0修改说明 ////////////////////////////////////////////////////////////////////////////////// //加入以下代码,支持printf函数,而不需要选择use MicroLIB //#define PUTCHAR_PROTOTYPE int fputc(int ch, FILE *f) #if 1 #pragma import(__use_no_semihosting) //标准库需要的支持函数 struct __FILE { int handle; }; FILE __stdout; //定义_sys_exit()以避免使用半主机模式 void _sys_exit(int x) { x = x; } //重定义fputc函数 int fputc(int ch, FILE *f) { while((USART3->SR&0X40)==0);//循环发送,直到发送完毕 USART3->DR = (u8) ch; return ch; } #endif u8 USART2_RX_BUF[USART2_REC_LEN]; //接收缓冲,最大USART_REC_LEN个字节. u16 uart2RxCounter; #if EN_USART3_RX //如果使能了接收 //串口3中断服务程序 //注意,读取USARTx->SR能避免莫名其妙的错误 u8 USART3_RX_BUF[USART3_REC_LEN]; //接收缓冲,最大USART_REC_LEN个字节. u16 USART3_RX_STA=0; //接收状态标记 u8 usart3_aRxBuffer[RXBUFFERSIZE];//HAL库使用的串口接收缓冲 UART_HandleTypeDef UART2_Handler; //UART句柄 UART_HandleTypeDef UART3_Handler; //UART句柄 DMA_HandleTypeDef hdma_usart2_tx; //DMA句柄 DMA_HandleTypeDef hdma_usart2_rx; // SIM7600初始化状态 BOOL isInitDone = 0; // 串口2接收的数据 typedef struct { u8 *buf; u16 length; } usart_buffer; usart_buffer *us2_buf; //****************************************** //初始化IO 串口2 //bound:波特率 //****************************************** void uart2_init(u32 bound) { MX_DMA_Init(); UART2_Handler.Instance = USART2; UART2_Handler.Init.BaudRate = bound; UART2_Handler.Init.WordLength = UART_WORDLENGTH_8B; UART2_Handler.Init.StopBits = UART_STOPBITS_1; UART2_Handler.Init.Parity = UART_PARITY_NONE; UART2_Handler.Init.Mode = UART_MODE_TX_RX; UART2_Handler.Init.HwFlowCtl = UART_HWCONTROL_NONE; if (HAL_UART_Init(&UART2_Handler) != HAL_OK) { _Error_Handler(__FILE__, __LINE__); } __HAL_UART_ENABLE_IT(&UART2_Handler, UART_IT_IDLE); HAL_UART_Receive_DMA(&UART2_Handler,USART2_RX_BUF,USART2_REC_LEN); } //****************************************** //初始化IO 串口3 //bound:波特率 //****************************************** void uart3_init(u32 bound) { //UART 初始化设置 UART3_Handler.Instance=USART3; //USART1 UART3_Handler.Init.BaudRate=bound; //波特率 UART3_Handler.Init.WordLength=UART_WORDLENGTH_8B; //字长为8位数据格式 UART3_Handler.Init.StopBits=UART_STOPBITS_1; //一个停止位 UART3_Handler.Init.Parity=UART_PARITY_NONE; //无奇偶校验位 UART3_Handler.Init.HwFlowCtl=UART_HWCONTROL_NONE; //无硬件流控 UART3_Handler.Init.Mode=UART_MODE_TX_RX; //收发模式 HAL_UART_Init(&UART3_Handler); //HAL_UART_Init()会使能UART3 HAL_UART_Receive_IT(&UART3_Handler, (u8 *)usart3_aRxBuffer, RXBUFFERSIZE);//该函数会开启接收中断:标志位UART_IT_RXNE,并且设置接收缓冲以及接收缓冲接收最大数据量 } //UART底层初始化,时钟使能,引脚配置,中断配置 //此函数会被HAL_UART_Init()调用 //huart:串口句柄 void HAL_UART_MspInit(UART_HandleTypeDef *huart) { //GPIO端口设置 GPIO_InitTypeDef GPIO_InitStruct; if(huart->Instance==USART2)//如果是串口2,进行串口2 MSP初始化 { __HAL_RCC_GPIOA_CLK_ENABLE(); __HAL_RCC_USART2_CLK_ENABLE(); /**USART2 GPIO Configuration PA2 ------> USART2_TX PA3 ------> USART2_RX */ GPIO_InitStruct.Pin=GPIO_PIN_2; //PA2 usart2_tx GPIO_InitStruct.Mode=GPIO_MODE_AF_PP; GPIO_InitStruct.Speed=GPIO_SPEED_FREQ_HIGH; GPIO_InitStruct.Pull=GPIO_PULLUP; HAL_GPIO_Init(GPIOA,&GPIO_InitStruct); GPIO_InitStruct.Pin=GPIO_PIN_3; //PA3 GPIO_InitStruct.Mode=GPIO_MODE_AF_INPUT; HAL_GPIO_Init(GPIOA,&GPIO_InitStruct); HAL_NVIC_EnableIRQ(USART2_IRQn); HAL_NVIC_SetPriority(USART2_IRQn,3,3); /* USART2 DMA Init */ /* USART2_RX Init */ hdma_usart2_rx.Instance = DMA1_Channel6; hdma_usart2_rx.Init.Direction = DMA_PERIPH_TO_MEMORY; hdma_usart2_rx.Init.PeriphInc = DMA_PINC_DISABLE; hdma_usart2_rx.Init.MemInc = DMA_MINC_ENABLE; hdma_usart2_rx.Init.PeriphDataAlignment = DMA_PDATAALIGN_BYTE; hdma_usart2_rx.Init.MemDataAlignment = DMA_MDATAALIGN_BYTE; hdma_usart2_rx.Init.Mode = DMA_NORMAL; hdma_usart2_rx.Init.Priority = DMA_PRIORITY_HIGH; if (HAL_DMA_Init(&hdma_usart2_rx) != HAL_OK) { _Error_Handler(__FILE__, __LINE__); } __HAL_LINKDMA(huart,hdmarx,hdma_usart2_rx); /* USART2_TX Init */ hdma_usart2_tx.Instance = DMA1_Channel7; hdma_usart2_tx.Init.Direction = DMA_MEMORY_TO_PERIPH; hdma_usart2_tx.Init.PeriphInc = DMA_PINC_DISABLE; hdma_usart2_tx.Init.MemInc = DMA_MINC_ENABLE; hdma_usart2_tx.Init.PeriphDataAlignment = DMA_PDATAALIGN_BYTE; hdma_usart2_tx.Init.MemDataAlignment = DMA_MDATAALIGN_BYTE; hdma_usart2_tx.Init.Mode = DMA_NORMAL; hdma_usart2_tx.Init.Priority = DMA_PRIORITY_LOW; if (HAL_DMA_Init(&hdma_usart2_tx) != HAL_OK) { _Error_Handler(__FILE__, __LINE__); } __HAL_LINKDMA(huart,hdmatx,hdma_usart2_tx); /* USART2 interrupt Init */ HAL_NVIC_SetPriority(USART2_IRQn, 3, 3); HAL_NVIC_EnableIRQ(USART2_IRQn); /* USER CODE BEGIN USART2_MspInit 1 */ /* USER CODE END USART2_MspInit 1 */ } if(huart->Instance==USART3)//如果是串口3,进行串口3 MSP初始化 { __HAL_RCC_GPIOB_CLK_ENABLE(); //使能GPIOB时钟 __HAL_RCC_GPIOC_CLK_ENABLE(); //使能GPIOC时钟 __HAL_RCC_USART3_CLK_ENABLE(); //使能USART3时钟 GPIO_InitStruct.Pin=GPIO_PIN_10; //PB10 usart3_tx GPIO_InitStruct.Mode=GPIO_MODE_AF_PP; //复用推挽输出 GPIO_InitStruct.Pull=GPIO_PULLUP; //上拉 GPIO_InitStruct.Speed=GPIO_SPEED_FREQ_HIGH;//高速 HAL_GPIO_Init(GPIOB,&GPIO_InitStruct); //初始化PB10 GPIO_InitStruct.Pin=GPIO_PIN_11; //PB11 GPIO_InitStruct.Mode=GPIO_MODE_AF_INPUT; //模式要设置为复用输入模式! HAL_GPIO_Init(GPIOB,&GPIO_InitStruct); //初始化PB11 GPIO_InitStruct.Pin = GPIO_PIN_13; //485 发送接收 GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP; GPIO_InitStruct.Pull = GPIO_NOPULL; GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH; HAL_GPIO_Init(GPIOC, &GPIO_InitStruct); #if EN_USART3_RX __HAL_UART_ENABLE_IT(&UART3_Handler,UART_IT_RXNE);//开启接收中断 HAL_NVIC_EnableIRQ(USART3_IRQn); //使能USART3中断通道 HAL_NVIC_SetPriority(USART3_IRQn,2,2); //抢占优先级3,子优先级3 #endif Usart_TX_Set(0); //设置为接收模式 } } void HAL_UART_MspDeInit(UART_HandleTypeDef* uartHandle) { if(uartHandle->Instance==USART2) { /* USER CODE BEGIN USART2_MspDeInit 0 */ /* USER CODE END USART2_MspDeInit 0 */ /* Peripheral clock disable */ __HAL_RCC_USART2_CLK_DISABLE(); /**USART2 GPIO Configuration PA2 ------> USART2_TX PA3 ------> USART2_RX */ HAL_GPIO_DeInit(GPIOA, GPIO_PIN_2|GPIO_PIN_3); /* USART2 DMA DeInit */ HAL_DMA_DeInit(uartHandle->hdmarx); HAL_DMA_DeInit(uartHandle->hdmatx); /* USART2 interrupt Deinit */ HAL_NVIC_DisableIRQ(USART2_IRQn); /* USER CODE BEGIN USART2_MspDeInit 1 */ /* USER CODE END USART2_MspDeInit 1 */ } else if(uartHandle->Instance==USART3) { /* USER CODE BEGIN USART3_MspDeInit 0 */ /* USER CODE END USART3_MspDeInit 0 */ /* Peripheral clock disable */ __HAL_RCC_USART3_CLK_DISABLE(); /**USART3 GPIO Configuration PB10 ------> USART3_TX PB11 ------> USART3_RX */ HAL_GPIO_DeInit(GPIOB, GPIO_PIN_10|GPIO_PIN_11); /* USART3 interrupt Deinit */ HAL_NVIC_DisableIRQ(USART3_IRQn); /* USER CODE BEGIN USART3_MspDeInit 1 */ /* USER CODE END USART3_MspDeInit 1 */ } } static void Usart2_Data_Handler(void) { PRINTF("SIM7600====>MCU:%s, len:%d\r\n", USART2_RX_BUF, uart2RxCounter); task *task = new_task(); memcpy(us2_buf->buf, USART2_RX_BUF,uart2RxCounter + 1); us2_buf->buf[uart2RxCounter] = '\0'; us2_buf->length=uart2RxCounter+1; task->handler = module_data_handler; task->pdata=us2_buf; add_task(task); uart2RxCounter = 0; for(int i=0;iInstance==USART2)//如果是串口2 { PRINTF("inter"); } if(huart->Instance==USART3)//如果是串口3 { if((USART3_RX_STA&0x8000)==0)//接收未完成 { if(USART3_RX_STA&0x4000)//接收到了0x0d { if(usart3_aRxBuffer[0]!=0x0a)USART3_RX_STA=0;//接收错误,重新开始 else USART3_RX_STA|=0x8000; //接收完成了 } else //还没收到0X0D { if(usart3_aRxBuffer[0]==0x0d)USART3_RX_STA|=0x4000; else { USART3_RX_BUF[USART3_RX_STA&0X3FFF]=usart3_aRxBuffer[0] ; USART3_RX_STA++; if(USART3_RX_STA>(USART3_REC_LEN-1))USART3_RX_STA=0;//接收数据错误,重新开始接收 } } } } } void UART_IDLE_Callback(UART_HandleTypeDef *huart) { u32 temp; if(__HAL_UART_GET_FLAG(huart,UART_FLAG_IDLE)) { __HAL_UART_CLEAR_IDLEFLAG(huart); HAL_UART_DMAStop(huart); temp=huart->Instance->SR; temp=huart->Instance->DR; temp = __HAL_DMA_GET_COUNTER(&hdma_usart2_rx); uart2RxCounter = USART2_REC_LEN-temp; char * p = strstr((char *)USART2_RX_BUF, "DONE"); if(p != NULL) { isInitDone = 1; } else { Usart2_Data_Handler(); } HAL_UART_Receive_DMA(huart,USART2_RX_BUF,USART2_REC_LEN); } } //串口2中断服务程序 void USART2_IRQHandler(void) { UART_IDLE_Callback(&UART2_Handler); HAL_UART_IRQHandler(&UART2_Handler); } //串口3中断服务程序 void USART3_IRQHandler(void) { u32 timeout=0; #if SYSTEM_SUPPORT_OS //使用OS OSIntEnter(); #endif HAL_UART_IRQHandler(&UART3_Handler); //调用HAL库中断处理公用函数 timeout=0; while (HAL_UART_GetState(&UART3_Handler) != HAL_UART_STATE_READY)//等待就绪 { timeout++;////超时处理 if(timeout>HAL_MAX_DELAY) break; } timeout=0; while(HAL_UART_Receive_IT(&UART3_Handler, (u8 *)usart3_aRxBuffer, RXBUFFERSIZE) != HAL_OK)//一次处理完成之后,重新开启中断并设置RxXferCount为1 { timeout++; //超时处理 if(timeout>HAL_MAX_DELAY) break; } #if SYSTEM_SUPPORT_OS //使用OS OSIntExit(); #endif } #endif //****************************************** //RS485模式控制. //Ren:1,接收;0,发送. //****************************************** void Usart_TX_Set(uint8_t Ren) { uint8_t i; i=Ren; if(i==0) { PCout(13)=0; } else { PCout(13)=1; } } //****************************************** //RS485发送字符串. //****************************************** void Usart_Send_Str_Data(char *str) { Usart_TX_Set(1); //设置为发送模式 delay_us(1000); printf(str); delay_us(150); Usart_TX_Set(0); } //****************************************** //RS485发送len个字节. //buf:发送区首地址 //len:发送的字节数(为了和本代码的接收匹配,这里建议不要超过64个字节) //****************************************** void Usart_Send_Data(uint8_t *buf,uint8_t len) { Usart_TX_Set(1); //设置为发送模式 delay_ms(100); // HAL_UART_Transmit(&huart3,buf,len,1000);//串口3发送数据 Usart_TX_Set(0); //设置为接收模式 delay_ms(50); } void Usart2_Send_Data(u8 *buffer,u16 len) { if(HAL_OK !=HAL_UART_Transmit(&UART2_Handler, buffer,len, 10000)) { } }