123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449 |
- #include "usart.h"
- #include "task.h"
- #include "sim7600.h"
- #include "delay.h"
- #include "malloc.h"
- #include "dma.h"
- #include <string.h>
- //////////////////////////////////////////////////////////////////////////////////
- //如果使用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;
- // 串口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,USART3_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("recive:%s\r\n", USART2_RX_BUF);
- 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);
- memset(USART2_RX_BUF,0,uart2RxCounter);
- uart2RxCounter = 0;
- }
- void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart)
- {
- if(huart->Instance==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_DMAStop(huart);
- temp=huart->Instance->SR;
- temp=huart->Instance->DR;
- temp = __HAL_DMA_GET_COUNTER(&hdma_usart2_rx);
- uart2RxCounter = USART2_REC_LEN-temp;
- Usart2_Data_Handler();
- __HAL_UART_CLEAR_IDLEFLAG(huart);
- HAL_UART_Receive_DMA(huart,USART2_RX_BUF,USART3_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 MYDMA_USART_Transmit(UART_HandleTypeDef *huart, uint8_t *pData, uint16_t Size)
- {
- HAL_DMA_Start(huart->hdmatx, (u32)pData, (uint32_t)&huart->Instance->DR, Size);
- huart->Instance->CR3 |= USART_CR3_DMAT;
- }
- void Usart2_Send_Data(u8 *buffer,u8 len)
- {
- MYDMA_USART_Transmit(&UART2_Handler, buffer, len);
- //HAL_UART_Transmit(&UART2_Handler,buffer,len,1000);
- delay_ms(500);
- }
|