stm32_ota/SYSTEM/USART/usart.c

575 lines
27 KiB
C
Raw Blame History

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

#include "usart.h"
#include "stm32f10x.h"
#include "sysport.h"
#include "io.h"
/********************************************************************************
* @file usart.c
* @author 晏诚科技 Mr.Wang
* @version V1.1.0
* @date 26-Dec-2018
* @brief 提供串口外设相关驱动
******************************************************************************
* @驱动功能:
* 1、GPIO初始化
* 2、提供串口发送函数
* 3、采用串口DMA进行数据收发
* 4、采用串口接收帧中断配合DMA为上层提供帧数据
* @使用方法:
* 1、先调用UARTx_Init()对UART进行初始化、NVIC、EXTI初始化
* 2、在应用层调用Uart_RegHookCallback()函数注册串口相关回调函数
* @总结
* 采用串口空闲中断配合串口回调函数可以实现,应用层只需要注册回调函数,底层只要
接收到一帧数据就会跳转到回调,应用层只需要在回调中处理帧数据即可。
*******************************************************************************/
/****************************************************************************
* 供外部使用的常变量
****************************************************************************/
/****************************************************************************
* 内部使用的常变量
****************************************************************************/
char uart1_Dma_Rx_Buf[UART1_DMA_RX_MAXLEN] ; //UART1串口DMA接收缓冲区
char uart2_Dma_Rx_Buf[UART2_DMA_RX_MAXLEN] ; //UART2串口DMA接收缓冲区
char uart3_Dma_Rx_Buf[UART3_DMA_RX_MAXLEN] ; //UART3串口DMA接收缓冲区
char uart4_Dma_Rx_Buf[UART4_DMA_RX_MAXLEN] ; //UART4串口DMA接收缓冲区
char uart5_Rx_Buf[UART5_RX_MAXLEN] ; //UART5中断接收数据缓冲区
volatile int uart5_Rx_Index = 0 ; //UART5中断接收数据缓冲区数据指针
/*串口相关参数*/
USART_TypeDef *UARTx_COM[COMSUM] = {USART1, USART2, USART3, UART4, UART5} ; //5个串口的寄存器映射地址
const u8 UARTx_IRQ[COMSUM] = {USART1_IRQn, USART2_IRQn, USART3_IRQn, UART4_IRQn, UART5_IRQn} ; //5个串口TX引脚对应串口中断线
PORT_e UARTx_TX_PORT[COMSUM] = {PA, PA, PB, PC, PC} ; //5个串口TX引脚对应IO端口
PIN_e UARTx_TX_PIN [COMSUM] = {PIN9, PIN2, PIN10, PIN10, PIN12} ; //5个串口TX引脚对应IO引脚
PORT_e UARTx_RX_PORT[COMSUM] = {PA, PA, PB, PC, PD} ; //5个串口RX引脚对应IO端口
PIN_e UARTx_RX_PIN [COMSUM] = {PIN10, PIN3, PIN11, PIN11, PIN2} ; //5个串口RX引脚对应IO引脚
const u32 UARTx_UART_RCC[COMSUM]= {RCC_APB2Periph_USART1, RCC_APB1Periph_USART2, RCC_APB1Periph_USART3,
RCC_APB1Periph_UART4, RCC_APB1Periph_UART5} ;
/*串口DMA相关参数*/
const u8 UARTxDma_Tx_CHx[COMSUM-1] = { DMA1_CH4, DMA1_CH7, DMA1_CH2, DMA2_CH5 } ; //UARTx DMA发送通道UART5没有DMA功能
const u8 UARTxDma_Rx_CHx[COMSUM-1] = { DMA1_CH5, DMA1_CH6, DMA1_CH3, DMA2_CH3 } ; //UARTx DMA接收通道UART5没有DMA功能
const u32 UARTxDMA_RX_BUFADDR[COMSUM-1] = {(u32)uart1_Dma_Rx_Buf, (u32)uart2_Dma_Rx_Buf, (u32)uart3_Dma_Rx_Buf, (u32)uart4_Dma_Rx_Buf} ; //串口DMA接收缓冲区地址
const u16 UARTxDMA_RX_BUFLEN[COMSUM-1] = {UART1_DMA_RX_MAXLEN, UART2_DMA_RX_MAXLEN, UART3_DMA_RX_MAXLEN, UART4_DMA_RX_MAXLEN} ; //串口DMA接收缓冲区字节长度
u32 UARTx_Dma_periAddr[COMSUM-1] = {(u32)&(USART1->DR), (u32)&USART2->DR, (u32)&USART3->DR, (u32)&UART4->DR } ; //串口数据寄存器地址
DMAFP uartTX_dmaTC_Callback[COMSUM-1]= {UART1_DMA_TX_TC_Callback_Functions, UART2_DMA_TX_TC_Callback_Functions,UART3_DMA_TX_TC_Callback_Functions,UART4_DMA_TX_TC_Callback_Functions} ; //DMA发送完成中断回调函数
DMAFP uartTX_dmaTE_Callback[COMSUM-1]= {NULL, NULL, NULL, NULL} ; //DMA串口发送失败中断回调函数
DMAFP uartRX_dmaTC_Callback[COMSUM-1]= {NULL, NULL, NULL, NULL} ; //DMA串口接收完成中断回调函数
DMAFP uartRX_dmaTE_Callback[COMSUM-1]= {NULL, NULL, NULL, NULL} ; //DMA串口接收失败中断回调函数
volatile bool UARTxDma_Tx_TcFlag[COM5] = {false, false, false, false} ; //串口DMA发送完成全局标志
/**************************************************************************************************************/
/*****************************************
*中断事件回调函数相关配置
****************************************/
UARTFP uartFp[COMSUM] = {NULL} ; //定义UART1~UART5共计5个串口回调函数指针
/**************************************************************************************************
* 名 称UARTFP Uart_RegHookCallback(UARTFP pCallback, COM_e eCOMn)
* 功能说明:串口接收超时中断回调函数-注册函数。串口在接收到一帧数据时会触发中断执行回调。数据时通过DMA接收到相应的缓冲区中的
* 入口参数:
* @param1 pCallback UARTFP类型函数指针
* @param2 eCOMn COM_e枚举类型数据
* 出口参数:
* @param1 pCallback UARTFP类型函数指针
*************************************************************************************************/
UARTFP Uart_RegHookCallback(COM_e eCOMn, UARTFP pCallback)
{
if( uartFp[eCOMn] == NULL )
uartFp[eCOMn] = pCallback ;
else
SysErr("Uart Callback repeat reg!") ; //Uart Callback repeat reg!
return pCallback ;
}
/**************************************************************************************************
* 名 称void Uart_Hook(COM_e eCOMn, char *recvBuf)
* 功能说明:串口接收超时中断内调用的钩子函数(执行到中断会把相应的回调函数勾出来运行,嘿嘿嘿。。。
* 当然不同的串口会勾出不同的回调函数uartFp[]
* 入口参数:
* @param1 eCOMn COM_e枚举变量区分UART1~UART5 五个串口
* @param2 *recvBuf 串口在此中断中接收到的数据存放地址
* @param3 recvLen 串口在此中断中接收到的数据长度
*************************************************************************************************/
void Uart_Hook(COM_e eCOMn, char *recvBuf, uint16_t recvLen)
{
if( uartFp[eCOMn] != NULL)
{
uartFp[eCOMn](recvBuf, recvLen) ;
}
}
/*********加入以下代码,支持printf函数,而不需要选择use MicroLIB**************/
#if 1
#pragma import(__use_no_semihosting)
struct __FILE //标准库需要的支持函数
{
int handle;
};
FILE __stdout;
void _sys_exit(int x) //定义_sys_exit()以避免使用半主机模式
{
x = x;
}
void _ttywrch(int ch)
{
ch=ch;
}
int fputc(int ch, FILE *f)//重定义fputc函数
{
// UARTx_COM[UART_DEBUG]->DR = (u8) ch;
// while(( UARTx_COM[UART_DEBUG]->SR & 0X40 ) == 0) ;//循环发送,直到发送完毕 TC
return ch;
}
#endif
/****************************************************************************/
void UARTx_Init(COM_e eCOMn, uint32_t baudrate, uint16_t uartMode, IntPriority_e ePriority)
{
GPIO_InitTypeDef GPIO_InitStructure;
NVIC_InitTypeDef NVIC_InitStructure;
USART_InitTypeDef USART_InitStructure;
/*对串口IO初始化*/
RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO , ENABLE) ; //IO复用时钟开启
Gpio_Init(UARTx_TX_PORT[eCOMn], UARTx_TX_PIN[eCOMn], GPIO_Mode_AF_PP) ;
Gpio_Init(UARTx_RX_PORT[eCOMn], UARTx_RX_PIN[eCOMn], GPIO_Mode_IN_FLOATING) ; //GPIO_Mode_IPU
/*对串口相关参数初始化*/
if( eCOMn == COM1 ) //COM1和COM2、3、4、5所在的APB不同所以要分开开启APB时钟
RCC_APB2PeriphClockCmd(UARTx_UART_RCC[eCOMn] , ENABLE) ;
else
RCC_APB1PeriphClockCmd(UARTx_UART_RCC[eCOMn] , ENABLE) ;
USART_InitStructure.USART_BaudRate = baudrate; //速率baudratebps
USART_InitStructure.USART_WordLength = USART_WordLength_8b; //数据位8位
USART_InitStructure.USART_StopBits = USART_StopBits_1; //停止位1位
USART_InitStructure.USART_Parity = USART_Parity_No; //无校验位
USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None; //无硬件流控
USART_InitStructure.USART_Mode = uartMode ; //USART_Mode_Rx | USART_Mode_Tx; //收发模式
USART_Init(UARTx_COM[eCOMn], &USART_InitStructure); //配置串口参数函数
USART_ClearFlag(UARTx_COM[eCOMn], USART_FLAG_CTS | USART_FLAG_LBD | USART_FLAG_TC | USART_FLAG_RXNE) ; //清标志位
if( ((USART_InitStructure.USART_Mode & USART_Mode_Tx) == USART_Mode_Tx)
&&(eCOMn != COM5)) //当串口UART1~UART4发送功能启用则初始化串口发送DMA
{
//UARTx_DmaTx_Init(eCOMn) ; //串口发送DMA初始化
USART_DMACmd(UARTx_COM[eCOMn], USART_DMAReq_Tx, ENABLE); //使能串口的DMA发送
DMA_Config((DMACH_e)UARTxDma_Tx_CHx[eCOMn], UARTx_Dma_periAddr[eCOMn], 0, DMA_DIR_MTP, NORMAL, TOP_INT_RANK) ; //TX优先级如果设置为OS可屏蔽的话在系统OS启动前无法使用串口输出
Dma_RegHookCallback(UARTxDma_Tx_CHx[eCOMn], DMATC, uartTX_dmaTC_Callback[eCOMn]) ; //注册DMA传输完成回调函数
Dma_RegHookCallback(UARTxDma_Tx_CHx[eCOMn], DMATE, uartTX_dmaTE_Callback[eCOMn]) ; //注册DMA传输失败回调函数
}
if((USART_InitStructure.USART_Mode & USART_Mode_Rx) == USART_Mode_Rx) //当串口接收功能启用,则开启接收中断和接收空闲中断
{
/*对串口NVIC初始化*/
NVIC_InitStructure.NVIC_IRQChannel = UARTx_IRQ[eCOMn]; //设置串口中断
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = ePriority; //抢占优先级
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0 ; //子优先级为0
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; //使能
NVIC_Init(&NVIC_InitStructure);
USART_ITConfig(UARTx_COM[eCOMn], USART_IT_IDLE, ENABLE); //使能串口接收空闲类型 //USART_ITConfig(UARTx_COM[eCOMn], USART_IT_RXNE, ENABLE); //使能串口接收中断
if( eCOMn != COM5 ) //UART1~UART4开启串口DMA接收
{
//UARTx_DmaRx_Init(eCOMn ) ; //串口接收DMA初始化
USART_DMACmd(UARTx_COM[eCOMn], USART_DMAReq_Rx, ENABLE); //使能串口的DMA接收
DMA_Config((DMACH_e)UARTxDma_Rx_CHx[eCOMn], UARTx_Dma_periAddr[eCOMn], UARTxDMA_RX_BUFADDR[eCOMn], DMA_DIR_PTM, NORMAL, ePriority) ;
DMA_SetCurrDataCounter(dmaChx[UARTxDma_Rx_CHx[eCOMn]], UARTxDMA_RX_BUFLEN[eCOMn]); //DMA通道的DMA缓存的大小
Dma_RegHookCallback(UARTxDma_Rx_CHx[eCOMn], DMATC, uartRX_dmaTC_Callback[eCOMn]) ; //注册DMA传输完成回调函数
Dma_RegHookCallback(UARTxDma_Rx_CHx[eCOMn], DMATE, uartRX_dmaTE_Callback[eCOMn]) ; //注册DMA传输失败回调函数
DMA_Cmd(dmaChx[UARTxDma_Rx_CHx[eCOMn]], ENABLE); //使能dmaChx[UARTxDma_Tx_CHx[eCOMn]]所指示的通道
}
else if( eCOMn == COM5) //UART5不具有DMA通道所以开启串口接收中断、串口接收空闲中断来接收数据
{
USART_ITConfig(UARTx_COM[eCOMn], USART_IT_RXNE, ENABLE);
}
}
USART_Cmd(UARTx_COM[eCOMn], ENABLE); //Enable the USART1
}
/****************************************************************************
* 名 称void UARTx_DmaTx_Init(COM_e eCOMn)
* 功 能串口DMA发送初始化
* 入口参数:
* @param1 COMn 端口
* @arg COM_e枚举类型数据
* 说 明默认开启TC中断中断回调函数需要在stm32f10x_it.h文件中注册
* 注 意所有中断优先级需要在stm32f10x_it.h文件中配置
****************************************************************************/
void UARTx_DmaTx_Init(COM_e eCOMn)
{
USART_DMACmd(UARTx_COM[eCOMn], USART_DMAReq_Tx, ENABLE); //使能串口的DMA发送
DMA_Config((DMACH_e)UARTxDma_Tx_CHx[eCOMn], UARTx_Dma_periAddr[eCOMn], 0, DMA_DIR_MTP, NORMAL, INT_RANK_6) ;
}
/****************************************************************************
* 名 称void UARTx_DmaRx_Init(COM_e eCOMn )
* 功 能串口DMA接收初始化
* 入口参数:
* @param1 COMn 端口
* @arg COM_e枚举类型数据
* 说 明默认开启TC中断中断回调函数需要在stm32f10x_it.h文件中注册
* 注 意所有中断优先级需要在stm32f10x_it.h文件中配置
****************************************************************************/
void UARTx_DmaRx_Init(COM_e eCOMn )
{
USART_DMACmd(UARTx_COM[eCOMn], USART_DMAReq_Rx, ENABLE); //使能串口的DMA接收
DMA_Config((DMACH_e)UARTxDma_Rx_CHx[eCOMn], UARTx_Dma_periAddr[eCOMn], UARTxDMA_RX_BUFADDR[eCOMn], DMA_DIR_PTM, NORMAL, INT_RANK_6) ;
DMA_SetCurrDataCounter(dmaChx[UARTxDma_Rx_CHx[eCOMn]], UARTxDMA_RX_BUFLEN[eCOMn]); //DMA通道的DMA缓存的大小
DMA_Cmd(dmaChx[UARTxDma_Rx_CHx[eCOMn]], ENABLE); //使能dmaChx[UARTxDma_Tx_CHx[eCOMn]]所指示的通道
}
/****************************************************************************
* 名 称void UARTx_DmaRx_Restart(COM_e eCOMn)
* 功 能串口DMA接收
* 入口参数:
* @param1 COMn 端口
* @arg COM_e枚举类型数据
* 说 明:清除接收缓冲区
****************************************************************************/
void UARTx_DmaRx_Restart(COM_e eCOMn)
{
DMA_Cmd(dmaChx[UARTxDma_Rx_CHx[eCOMn]], DISABLE); //失能dmaChx[UARTxDma_Tx_CHx[eCOMn]]所指示的通道
// DMA_Config((DMACH_e)UARTxDma_Rx_CHx[eCOMn], UARTx_Dma_periAddr[eCOMn], UARTxDMA_RX_BUFADDR[eCOMn], DMA_DIR_PTM, NORMAL) ;
memset((char*)UARTxDMA_RX_BUFADDR[eCOMn], 0, UARTxDMA_RX_BUFLEN[eCOMn]) ;
DMA_SetCurrDataCounter(dmaChx[UARTxDma_Rx_CHx[eCOMn]], UARTxDMA_RX_BUFLEN[eCOMn]); //DMA通道的DMA缓存的大小
DMA_Cmd(dmaChx[UARTxDma_Rx_CHx[eCOMn]], ENABLE); //使能dmaChx[UARTxDma_Tx_CHx[eCOMn]]所指示的通道
}
/****************************************************************************
* 名 称void UARTx_SendData(COM_e eCOMn, const char *sendData, uint16_t dataLen)
* 功 能通过eCOMn端口输出dataLen长度的数据
* 入口参数:
* @param COMn 端口
* @arg COM_e枚举类型数据
* @param *sendData 输出的数据指针
* @param dataLen 输出数据的长度
* 注 意通过宏定义UARTx_DMATX_EN决定是否启用串口DMA发送数据
* 发送等待DMA TC中断判断串口数据是否发送完成 UARTx_DMA_Tx(UART_DEBUG, (u32)log, LOG_BUF_LEN ) ;
****************************************************************************/
void UARTx_SendData(COM_e eCOMn, const char *sendData, uint16_t dataLen)
{
if( (sendData == NULL) || (dataLen <= 0) )
{
// SysErr("") ;
return ;
}
if(UARTx_DMATX_EN && (eCOMn != COM5)) //使能串口DMA发送,UART5不支持串口DMA发送
{
DMA_Cmd(dmaChx[UARTxDma_Tx_CHx[eCOMn]], DISABLE ); //关闭通道才能对 CMAR值做改写
UARTxDma_Tx_TcFlag[eCOMn] = false ; //串口eCOMn发送完成标志位清除
dmaChx[UARTxDma_Tx_CHx[eCOMn]]->CMAR = (uint32_t)sendData ; //DMA 内存地址
DMA_SetCurrDataCounter(dmaChx[UARTxDma_Tx_CHx[eCOMn]],dataLen); //DMA通道的DMA缓存的大小
//DMA_InitStructure.DMA_MemoryBaseAddr = uartTxBufferAdder; //DMA内存基地址
//DMA_InitStructure.DMA_BufferSize = uartTxDataLen; //DMA通道的DMA缓存的大小
//DMA_Init(DMA_CHx, &DMA_InitStructure);
DMA_Cmd(dmaChx[UARTxDma_Tx_CHx[eCOMn]], ENABLE); //使能dmaChx[UARTxDma_Tx_CHx[eCOMn]]所指示的通道
while( UARTxDma_Tx_TcFlag[eCOMn] == false ) ; //等待串口eCOMn DMA发送完成标志位
}
else //采用查询串口发送完成标志的方法来发送串口数据
{
uint16_t index = 0 ;
const char *pos = sendData ;
USART_GetFlagStatus(UARTx_COM[eCOMn], USART_FLAG_TC); //解决第一个字符发送失败的问题
for(index = 0; index < dataLen; index++)
{
USART_SendData(UARTx_COM[eCOMn], *(pos+index)) ;
while(USART_GetFlagStatus(UARTx_COM[eCOMn], USART_FLAG_TC)==RESET) ;
}
}
}
/****************************************************************************
*单字节发送不支持串口MDA发送尽量不要使用
* 名 称void UARTx_Printf(COM_e eCOMn, uint8_t *Data,...)
* 功 能:格式化串口输出函数
* 入口参数USARTx: 指定串口
Data 发送数组
...: 不定参数
* 出口参数:无
* 说 明:格式化串口输出函数
* "\r" 回车符 UARTx_Printf(USART1, "abcdefg\r")
* "\n" 换行符 UARTx_Printf(USART1, "abcdefg\r\n")
* "%s" 字符串 UARTx_Printf(USART1, "字符串是:%s","abcdefg")
* "%d" 十进制 UARTx_Printf(USART1, "a=%d",10)
****************************************************************************/
void UARTx_SendString(COM_e eCOMn, uint8_t *Data,...)
{
const char *s;
int d;
char buf[16];
va_list ap;
va_start(ap, Data);
while(*Data!=0)
{ //判断是否到达字符串结束符
if(*Data == 0x5c)
{ //'\'
switch (*++Data)
{
case 'r': //回车符
USART_SendData(UARTx_COM[eCOMn], 0x0D);
Data++;
break;
case 'n': //换行符
USART_SendData(UARTx_COM[eCOMn], 0x0A);
Data++;
break;
default:
Data++;
break;
}
}
else if(*Data=='%')
{ //
switch (*++Data)
{
case 's': //字符串
s = va_arg(ap, const char *);
for ( ; *s; s++)
{
USART_SendData(UARTx_COM[eCOMn],*s);
while(USART_GetFlagStatus(UARTx_COM[eCOMn], USART_FLAG_TC)==RESET);
}
Data++;
break;
case 'd': //十进制
d = va_arg(ap, int);
itoa(d, buf, 10);
for (s = buf; *s; s++)
{
USART_SendData(UARTx_COM[eCOMn],*s);
while(USART_GetFlagStatus(UARTx_COM[eCOMn], USART_FLAG_TC)==RESET);
}
Data++;
break;
default:
Data++;
break;
}
}
else
USART_SendData(UARTx_COM[eCOMn], *Data++);
while(USART_GetFlagStatus(UARTx_COM[eCOMn], USART_FLAG_TC)==RESET) ;
}
}
/****************************************************************************
* 名 称void USART1_IRQHandler(void)
* 功 能USART1中断服务程序
****************************************************************************/
void USART1_IRQHandler(void)
{
/* 串口1接收空闲中断 */
if( USART_GetITStatus(USART1, USART_IT_IDLE) != RESET )
{
DMA_Cmd(dmaChx[UARTxDma_Rx_CHx[COM1]], DISABLE); //失能dmaChx[UARTxDma_Tx_CHx[eCOMn]]所指示的通道
uint8_t clearFlag = USART1->SR ; //清除空闲中断标志USART_ClearITPendingBit(USART1, USART_IT_IDLE) ;
clearFlag = USART1->DR ;
uint16_t len = UARTxDMA_RX_BUFLEN[COM1] - DMA_GetCurrDataCounter(dmaChx[UARTxDma_Rx_CHx[COM1]]) ;
//SysLog("COM1 RxLen:%d; RxBuf:%s,", len, uart1_Dma_Rx_Buf);
Uart_Hook(COM1, uart1_Dma_Rx_Buf, len) ; //跳转到回调函数
UARTx_DmaRx_Restart(COM1) ;
}
if(USART_GetITStatus(USART1, USART_IT_RXNE) != RESET) //判断读寄存器是否非空
{
USART_ClearITPendingBit(USART1, USART_IT_RXNE) ;
}
if(USART_GetITStatus(USART1, USART_IT_TXE) != RESET) //这段是为了避免STM32 USART 第一个字节发不出去的BUG
{
USART_ITConfig(USART1, USART_IT_TXE, DISABLE); //禁止发缓冲器空中断,
}
}
/****************************************************************************
* 名 称void USART2_IRQHandler(void)
* 功 能USART2中断服务程序
****************************************************************************/
void USART2_IRQHandler(void)
{
if( USART_GetITStatus(USART2, USART_IT_IDLE) != RESET )
{
DMA_Cmd(dmaChx[UARTxDma_Rx_CHx[COM2]], DISABLE); //失能dmaChx[UARTxDma_Tx_CHx[eCOMn]]所指示的通道
uint8_t clearFlag = USART2->SR ; //清除空闲中断标志位 无法通过USART_ClearITPendingBit(UART4, USART_IT_IDLE)清楚标志位
clearFlag = USART2->DR ;
uint16_t len = UARTxDMA_RX_BUFLEN[COM2] - DMA_GetCurrDataCounter(dmaChx[UARTxDma_Rx_CHx[COM2]]) ;
//SysLog("COM2 RxLen:%d; RxBuf:%s", len, uart2_Dma_Rx_Buf);
Uart_Hook(COM2, uart2_Dma_Rx_Buf, len) ; //跳转到回调函数
UARTx_DmaRx_Restart(COM2) ;
}
if(USART_GetITStatus(USART2, USART_IT_RXNE) != RESET) //判断读寄存器是否非空
{
USART_ClearITPendingBit(USART2, USART_IT_RXNE) ; //清除接收中断标志位
}
if(USART_GetITStatus(USART2, USART_IT_TXE) != RESET) //这段是为了避免STM32 USART 第一个字节发不出去的BUG
{
USART_ITConfig(USART2, USART_IT_TXE, DISABLE); //禁止发缓冲器空中断,
}
}
/****************************************************************************
* 名 称void USART3_IRQHandler(void)
* 功 能USART3中断服务程序
****************************************************************************/
void USART3_IRQHandler(void)
{
if( USART_GetITStatus(USART3, USART_IT_IDLE) != RESET ) /* 串口3接收空闲中断 */
{
DMA_Cmd(dmaChx[UARTxDma_Rx_CHx[COM3]], DISABLE); //失能dmaChx[UARTxDma_Tx_CHx[eCOMn]]所指示的通道
uint8_t clearFlag = USART3->SR ; //需要测试中断标志是否真的清零、、、、、、、、、、、、、、、、、、、、、
clearFlag = USART3->DR ;
uint16_t len =UARTxDMA_RX_BUFLEN[COM3] - DMA_GetCurrDataCounter(dmaChx[UARTxDma_Rx_CHx[COM3]]) ; //DMAy_Channelx->CNDTR
/*****下行代码需要屏蔽,在中段中耗时太长,影响帧接收,会导致丢失帧数据******/
//SysLog("COM3 RxLen:%d; RxBuf:%s", len, uart3_Dma_Rx_Buf);
Uart_Hook(COM3, uart3_Dma_Rx_Buf, len) ; //跳转到回调函数
UARTx_DmaRx_Restart(COM3) ;
}
if(USART_GetITStatus(USART3, USART_IT_RXNE) != RESET) /* 串口3接收中断 */
{
USART_ClearITPendingBit(USART3, USART_IT_RXNE) ; //清除接收中断标志位
}
if(USART_GetITStatus(USART3, USART_IT_TXE) != RESET) //这段是为了避免STM32 USART 第一个字节发不出去的BUG
{
USART_ITConfig(USART3, USART_IT_TXE, DISABLE); //禁止发缓冲器空中断,
}
}
/****************************************************************************
* 名 称void UART4_IRQHandler(void)
* 功 能UART4中断服务程序
****************************************************************************/
void UART4_IRQHandler(void)
{
/* 串口4接收空闲中断 */
if( USART_GetITStatus(UART4, USART_IT_IDLE) != RESET )
{
DMA_Cmd(dmaChx[UARTxDma_Rx_CHx[COM4]], DISABLE); //失能dmaChx[UARTxDma_Tx_CHx[eCOMn]]所指示的通道
uint8_t clearFlag = UART4->SR ; //清楚空闲中断标志位 无法通过USART_ClearITPendingBit(UART4, USART_IT_IDLE)清楚标志位
clearFlag = UART4->DR ;
uint16_t len = UARTxDMA_RX_BUFLEN[COM4] - DMA_GetCurrDataCounter(dmaChx[UARTxDma_Rx_CHx[COM4]]) ;
//SysLog("COM4 RxLen:%d; RxBuf:%s", len, uart4_Dma_Rx_Buf);
Uart_Hook(COM4, uart4_Dma_Rx_Buf, len) ; //跳转到回调函数
UARTx_DmaRx_Restart(COM4) ;
}
if(USART_GetITStatus(UART4, USART_IT_RXNE) != RESET) //判断读寄存器是否非空
{
USART_ClearITPendingBit(UART4, USART_IT_RXNE) ; //清除中断标志
}
if(USART_GetITStatus(UART4, USART_IT_TXE) != RESET) //这段是为了避免STM32 USART 第一个字节发不出去的BUG
{
USART_ITConfig(UART4, USART_IT_TXE, DISABLE); //禁止发缓冲器空中断,
}
USART_ClearFlag(UART4, USART_FLAG_TC ); //清除TC中断标志
}
/****************************************************************************
* 名 称void UART5_IRQHandler(void)
* 功 能UART5中断服务程序
****************************************************************************/
void UART5_IRQHandler(void)
{
if(USART_GetITStatus(UART5, USART_IT_RXNE) != RESET) //判断读寄存器是否非空
{
uart5_Rx_Buf[uart5_Rx_Index++] = UART5->DR ;
uart5_Rx_Buf[uart5_Rx_Index] = 0x00 ; //保证uart5_Rx_Buf中有正确的字符串小尾巴在数据处理时不会越界处理
if( uart5_Rx_Index >= (UART5_RX_MAXLEN-1) ) //接收溢出则从uart5_Rx_Buf[0]开始再接收
{
uart5_Rx_Index = 0 ;
}
}
if( USART_GetITStatus(UART5, USART_IT_IDLE) != RESET )
{
uint8_t clearFlag = UART5->SR ; //需要测试中断标志是否真的清零、、、、、、、、、、、、、、、、、、、、、
clearFlag = UART5->DR ;
//SysLog("COM5 RxLen:%d; RxBuf:%s", uart5_Rx_Index, uart5_Rx_Buf);
Uart_Hook(COM5, (char*)uart5_Rx_Buf, uart5_Rx_Index) ; //跳转到回调函数运行
memset((char*)uart5_Rx_Buf, 0, UART5_RX_MAXLEN) ; //清空uart5_Rx_Buf
uart5_Rx_Index = 0 ; //uart5_Rx_Buf 指针uart5_Rx_Index清零
USART_ClearITPendingBit(UART5, USART_IT_IDLE) ; //清除接收中断标志位
}
if(USART_GetITStatus(UART5, USART_IT_TXE) != RESET) //这段是为了避免STM32 USART 第一个字节发不出去的BUG
{
USART_ITConfig(UART5, USART_IT_TXE, DISABLE); //禁止发缓冲器空中断,
}
}
/****************************************************************************
* 名 称void UART1_DMA_TX_TC_Callback_Functions(void))
* 功 能USART1 DMA发送完成中断回调函数
****************************************************************************/
void UART1_DMA_TX_TC_Callback_Functions(void)
{
UARTxDma_Tx_TcFlag[COM1] = true ;
}
/****************************************************************************
* 名 称void UART2_DMA_TX_TC_Callback_Functions(void))
* 功 能USART2 DMA发送完成中断回调函数
****************************************************************************/
void UART2_DMA_TX_TC_Callback_Functions(void)
{
UARTxDma_Tx_TcFlag[COM2] = true ;
}
/****************************************************************************
* 名 称void UART3_DMA_TX_TC_Callback_Functions(void))
* 功 能USART3 DMA发送完成中断回调函数
****************************************************************************/
void UART3_DMA_TX_TC_Callback_Functions(void)
{
UARTxDma_Tx_TcFlag[COM3] = true ;
}
/****************************************************************************
* 名 称void UART4_DMA_TX_TC_Callback_Functions(void))
* 功 能USART4 DMA发送完成中断回调函数
****************************************************************************/
void UART4_DMA_TX_TC_Callback_Functions(void)
{
UARTxDma_Tx_TcFlag[COM4] = true ;
}
/****************************************************************************
* 名 称void UART1_DMA_RX_TC_Callback_Functions(void))
* 功 能USART1 DMA接收完成中断回调函数
****************************************************************************/
void UART1_DMA_RX_TC_Callback_Functions(void)
{
//SysLog("\r\nUart1Dma Rx TC!") ;
}
/****************************************************************************
* 名 称void UART2_DMA_RX_TC_Callback_Functions(void))
* 功 能USART2 DMA接收完成中断回调函数
****************************************************************************/
void UART2_DMA_RX_TC_Callback_Functions(void)
{
}
/****************************************************************************
* 名 称void UART3_DMA_RX_TC_Callback_Functions(void))
* 功 能USART3 DMA接收完成中断回调函数
****************************************************************************/
void UART3_DMA_RX_TC_Callback_Functions(void)
{}
/****************************************************************************
* 名 称void UART4_DMA_RX_TC_Callback_Functions(void))
* 功 能USART4 DMA接收完成中断回调函数
****************************************************************************/
void UART4_DMA_RX_TC_Callback_Functions(void)
{}