一个函数调用USART1、USART2、USART3

2019-07-20 17:27发布

本帖最后由 gjchen 于 2016-4-22 17:13 编辑

正点原子探索者F4板,同一函数调用三个串口,1、2都能正常发,能正常产生接收中断,3能够发数据,但没有接收数据中断,请高手指点一下



/***********************************************************/
//以下是usart.c文件内容
#include "usart.h"
/*串口驱动程序
1.初始化端口
2.设置接收或发送缓冲区
3.开启发送或接收中断
4.中断程序处理数据
*/

struct ZUsart_Buf _Usart1_buf,_Usart2_buf,_Usart3_buf;//,_Usart4_buf,_Usart5_buf;
/*初始化串口
输入:
    UsartNo  串口号 1~5
    Bound 波特率
返回:
    0成功,1失败
*/
void ZUsart_Init(u8 UsartNo,u32 Bound)
{
    GPIO_TypeDef* GpioX;
    uint16_t Gpio_PinSourceTx;
    uint16_t Gpio_PinSourceRx;
    uint8_t Gpio_Af;
    uint16_t Gpio_PinX;
    USART_TypeDef* UsartX;
   
    struct ZUsart_Buf tmp;
   
    GPIO_InitTypeDef GPIO_InitStructure;
    USART_InitTypeDef USART_InitStructure;
   
    tmp.Count =0;
    tmp.DataLen=0;
    tmp.OnData=0;
    tmp.StartRead=0;
    tmp.Status =ENABLE;
    switch (UsartNo)
    {
        case 1:
            RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOA,ENABLE); //使能GPIOA时钟
            RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1,ENABLE);//使能USART1时钟
            GpioX =GPIOA;
            Gpio_PinSourceTx=GPIO_PinSource9;
            Gpio_PinSourceRx=GPIO_PinSource10;
            Gpio_Af=GPIO_AF_USART1;
            Gpio_PinX =GPIO_Pin_9 | GPIO_Pin_10;
            UsartX=USART1;
            _Usart1_buf=tmp;
            break;
        case 2:
            RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOA,ENABLE); //使能GPIOA时钟
            RCC_APB1PeriphClockCmd(RCC_APB1Periph_USART2,ENABLE);//使能USART2时钟
            GpioX =GPIOA;
            Gpio_PinSourceTx=GPIO_PinSource2;
            Gpio_PinSourceRx=GPIO_PinSource3;
            Gpio_Af=GPIO_AF_USART2;
            Gpio_PinX =GPIO_Pin_2 | GPIO_Pin_3;
            UsartX=USART2;
            _Usart2_buf=tmp;
            break;
        case 3:
            //Usart3  PB10(TX)PB11(RX)  P10
            RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOB,ENABLE); //使能GPIOB时钟
            RCC_APB1PeriphClockCmd(RCC_APB1Periph_USART3,ENABLE);//使能USART3时钟
            GpioX =GPIOB;
            Gpio_PinSourceTx=GPIO_PinSource10;
            Gpio_PinSourceRx=GPIO_PinSource11;
            Gpio_Af=GPIO_AF_USART3;
            Gpio_PinX =GPIO_Pin_10 | GPIO_Pin_11;
            UsartX=USART3;
            _Usart2_buf=tmp;
            break;
//        case 4:
//            break;
//        case 5:
//            break;
        default:
            return ;
    }
    //串口1对应引脚复用映射
    GPIO_PinAFConfig(GpioX,Gpio_PinSourceTx,Gpio_Af); //GPIOA9复用为USART1
    GPIO_PinAFConfig(GpioX,Gpio_PinSourceRx,Gpio_Af); //GPIOA10复用为USART1
   
    //USART1端口配置
    GPIO_InitStructure.GPIO_Pin =Gpio_PinX ; //GPIOA9与GPIOA10
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;//复用功能
    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; //速度50MHz
    GPIO_InitStructure.GPIO_OType = GPIO_OType_PP; //推挽复用输出
    GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP; //上拉
    GPIO_Init(GpioX,&GPIO_InitStructure); //初始化PA9,PA10
   //USART1 初始化设置
    USART_InitStructure.USART_BaudRate = Bound;//波特率设置
    USART_InitStructure.USART_WordLength = USART_WordLength_8b;//字长为8位数据格式
    USART_InitStructure.USART_StopBits = USART_StopBits_1;//一个停止位
    USART_InitStructure.USART_Parity = USART_Parity_No;//无奇偶校验位
    USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None;//无硬件数据流控制
    USART_InitStructure.USART_Mode = USART_Mode_Rx | USART_Mode_Tx; //收发模式
    USART_Init(UsartX, &USART_InitStructure); //初始化串口1
    USART_Cmd(UsartX, ENABLE);  //使能串口1
    USART_ClearFlag(UsartX, USART_FLAG_TC);
    //return 0;
}

/*禁止串口功能
输入:
    UsartNo  串口号 1~5
返回:
    0成功,1失败
*/
u8 ZUsart_Disable(u8 UsartNo)
{
    USART_TypeDef* UsartX;
    switch(UsartNo)
    {
        case 1:
            UsartX=USART1;
            _Usart1_buf.Status = DISABLE;
            break;
        case 2:
            UsartX=USART2;
            _Usart2_buf.Status = DISABLE;
            break;
        case 3:
            //Usart3  PB10(TX)PB11(RX)  P10
            UsartX=USART3;
            _Usart2_buf.Status = DISABLE;
            break;
        default:
            return 1;
    }
    USART_Cmd(UsartX, DISABLE);  //使能串口
   
    return 0;
}
/*使能串口功能
输入:
    UsartNo  串口号 1~5
返回:
    0成功,1失败
*/
u8 ZUsart_Enable(u8 UsartNo)
{
    USART_TypeDef* UsartX;
    switch(UsartNo)
    {
        case 1:
            UsartX=USART1;
            _Usart1_buf.Status = ENABLE;
            break;
        case 2:
            UsartX=USART2;
            _Usart2_buf.Status = ENABLE;
            break;
        case 3:
            //Usart3  PB10(TX)PB11(RX)  P10
            UsartX=USART3;
            _Usart2_buf.Status = ENABLE;
            break;
        default:
            return 1;
    }
    USART_Cmd(UsartX, ENABLE);  //使能串口
   
    return 0;
}
/*设置发送信息缓冲区
输入:
    ZUsart_Buf  串口结构信息
    Buf     缓冲区地址
    Buf_Len     缓冲区长度
返回:
    0成功,1失败
*/
u8 ZUsart_SetTxBuf(struct ZUsart_Buf *Usart_Buf,u16 * Buf,u16 Buf_Len)
{
    if (Usart_Buf->Status == ENABLE)
    {
        Usart_Buf->TX_BUF=Buf;
        Usart_Buf->TX_LEN=Buf_Len;
        return 0;
    }
    else
    {
        return 1;
    }
}
/*设置接收信息缓冲区
输入:
    ZUsart_Buf  串口结构信息
    Buf     缓冲区地址
    Buf_Len     缓冲区长度
返回:
    0成功,1失败
*/
u8 ZUsart_SetRxBuf(struct ZUsart_Buf *Usart_Buf,u16 * Buf,u16 Buf_Len)
{
    if (Usart_Buf->Status == ENABLE)
    {
        Usart_Buf->RX_BUF=Buf;
        Usart_Buf->RX_LEN=Buf_Len;
        return 0;
    }
    else
    {
        return 1;
    }
}
/*开启或关闭串口中断
输入:
    usartno  串口号 1~5
    usart_it 中断类型  USART_IT_RXNE,接收中断     USART_IT_TXE,发送中断
    value 设置值   ENABLE,开启中断   DISABLE,禁止中断
返回:
    0成功,1失败
*/
u8 ZUsart_SetInit(u8 UsartNo ,uint16_t Usart_It,FunctionalState Value)
{
    uint8_t Usart_Irqn;
    USART_TypeDef* UsartX;
    NVIC_InitTypeDef NVIC_InitStructure;
   
    switch(UsartNo)
    {
        case 1:
            if (_Usart1_buf.Status == DISABLE)
                return 1;
            UsartX=USART1;
            Usart_Irqn= USART1_IRQn;
            break;
        case 2:
            if (_Usart2_buf.Status == DISABLE)
                return 1;
            UsartX=USART2;
            Usart_Irqn= USART2_IRQn;
            break;
        case 3:
            if (_Usart3_buf.Status == DISABLE)
                return 1;
            UsartX=USART3;
            Usart_Irqn= USART3_IRQn;
            break;
        default:
            return 1;
    }
    USART_ITConfig(UsartX, Usart_It, Value);//开启相关中断
    //Usart1 NVIC 配置
//    NVIC_PriorityGroupConfig(NVIC_PriorityGroup_0);
    NVIC_InitStructure.NVIC_IRQChannel = Usart_Irqn;//串口1中断通道
    NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority=3;//抢占优先级3
    NVIC_InitStructure.NVIC_IRQChannelSubPriority =UsartNo;  //子优先级3
    NVIC_InitStructure.NVIC_IRQChannelCmd = Value;   //IRQ通道使能
    NVIC_Init(&NVIC_InitStructure); //根据指定的参数初始化VIC寄存器、
    return 0;
   
}  
/*串口发送数据
输入:
    UsartNo 串口号
    DataBuf 数据缓冲区首地址
    DataLen 数据缓冲区长度
返回:
    0成功,1失败
*/
u8 ZUsart_SendData(u8 UsartNo,u16* DataBuf,u16 DataLen)
{
    USART_TypeDef* UsartX;
    u16 i;
    switch(UsartNo)
    {
        case 1:
            if (_Usart1_buf.Status == DISABLE)
                return 1;
            UsartX=USART1;
            break;
        case 2:
            if (_Usart2_buf.Status == DISABLE)
                return 1;
            UsartX=USART2;
            break;
        case 3:
            if (_Usart3_buf.Status == DISABLE)
                return 1;
            UsartX=USART3;
            break;
        default:
            return 1;
    }
    for (i=0;i<DataLen;i++)
    {
        USART_SendData(UsartX,*DataBuf);
        while(USART_GetFlagStatus(UsartX,USART_FLAG_TC)!=SET);//等待发送结束
        DataBuf++;
    }
    return 0;
}
//发送默认缓冲区数据
//UsartNo:串口号1,2,3
//返回:0成功,1失败
u8 ZUsart_SendDefault(u8 UsartNo)
{
    u8 i;
    switch(UsartNo)
    {
        case 1:
            if (_Usart1_buf.Status == DISABLE)
                return 1;
            i= ZUsart_SendData(UsartNo,_Usart1_buf.TX_BUF,_Usart1_buf.TX_LEN);
            break;
        case 2:
            if (_Usart2_buf.Status == DISABLE)
                return 1;
            i= ZUsart_SendData(UsartNo,_Usart2_buf.TX_BUF,_Usart2_buf.TX_LEN);
            break;
        case 3:
            if (_Usart3_buf.Status == DISABLE)
                return 1;
            i= ZUsart_SendData(UsartNo,_Usart3_buf.TX_BUF,_Usart3_buf.TX_LEN);
            break;
        default:
            return 1;
    }
    return i;
}

/*串口接收数据
输入:
    UsartNo 串口号
    DataBuf 数据缓冲区首地址
    DataLen 数据缓冲区长度
返回:
    0成功,1失败
*/
u8 ZUsart_ReceiveData(u8 UsartNo,u16* DataBuf,u16 DataLen)
{
    USART_TypeDef* UsartX;
    u16 i;
    switch(UsartNo)
    {
        case 1:
            if (_Usart1_buf.Status == DISABLE)
                return 1;
            UsartX=USART1;
            break;
        case 2:
            if (_Usart2_buf.Status == DISABLE)
                return 1;
            UsartX=USART2;
            break;
        case 3:
            if (_Usart3_buf.Status == DISABLE)
                return 1;
            UsartX=USART3;
            break;
        default:
            return 1;
    }
    for (i=0;i<DataLen;i++)
    {
        *DataBuf = USART_ReceiveData(UsartX);
        while(USART_GetFlagStatus(UsartX,USART_FLAG_RXNE)==SET);//等待发送结束
        DataBuf++;
//        xData[2*i]=xChar[ USART_RX_BUF>>4];
//        xData[2*i+1]=xChar[USART_RX_BUF&0x0F];
    }
    return 0;
}

//串口命令模式接收数据
void ZUsart_Order(u8 UsartNo)
{
    USART_TypeDef* UsartX;
    struct ZUsart_Buf *Usart_Buf;
    u8 res=0;
   
    switch(UsartNo)
    {
        case 1:
            if (_Usart1_buf.Status == DISABLE)
                return ;
            UsartX=USART1;
            Usart_Buf=&_Usart1_buf;
            break;
        case 2:
            if (_Usart2_buf.Status == DISABLE)
                return ;
            UsartX=USART2;
            Usart_Buf=&_Usart2_buf;
            break;
        case 3:
            if (_Usart3_buf.Status == DISABLE)
                return ;
            UsartX=USART3;
            Usart_Buf=&_Usart3_buf;
            break;
        default:
            return ;
    }
   
    if (USART_GetITStatus(UsartX,USART_IT_RXNE)!=RESET)
    {
        res = USART_ReceiveData(UsartX);//读串口值
        if (Usart_Buf->OnData ==0)                     //缓冲区没有数量才能读数据,否则不读数据
        {
            if (Usart_Buf->StartRead==0)               //首次读数据
            {
                //buf = Usart_Buf->RX_BUF;
                if ((res<4)||(res==55))         //如果是命令 01、02、03、04或55各参数取默认值
                {
                    Usart_Buf->StartRead=1;
                    Usart_Buf->Count=1;
                    Usart_Buf->DataLen=8;      //接收的数据最少是8位才有效
                    *Usart_Buf->RX_BUF=res;    //给指定地址的变量赋值
                    USART_ITConfig(UsartX, USART_IT_IDLE, ENABLE);//开启空闲中断
                }
            }
            else                                        //连续接收数据
            {
                if (Usart_Buf->Count==1)               //如果是第二个数据,则表示接收的是数据长度
                {
                    if (res <=Usart_Buf->RX_LEN)       //如果接收数据长度在接收空间大小内
                    {
                        Usart_Buf->DataLen=res;
                        Usart_Buf->RX_BUF++;
                        *Usart_Buf->RX_BUF=res;
                        Usart_Buf->Count=2;
                    }
                    else                                //接收数据长度超过接收空间大小
                    {
                        USART_ITConfig(UsartX, USART_IT_IDLE, DISABLE);//关闭空闲中断
                        Usart_Buf->Count = 0;
                        Usart_Buf->StartRead=0;
                        Usart_Buf->OnData=0;
                        Usart_Buf->DataLen=0;
                    }
                }
                else                                    //其它有效数据
                {
                    if (Usart_Buf->Count<Usart_Buf->DataLen)  //在数据长度内的有效数据
                    {
                        Usart_Buf->RX_BUF++;
                        *Usart_Buf->RX_BUF=res;
                        Usart_Buf->Count++;
                        if (Usart_Buf->Count == Usart_Buf->DataLen)   //表示一组数据接收完毕
                        {
                            USART_ITConfig(UsartX, USART_IT_IDLE, DISABLE);//关闭空闲中断
                            Usart_Buf->Count=0;
                            Usart_Buf->StartRead=0;
                            //Usart_Buf->OnData=1;                     //致收据接收完毕标志
                            ZUsart_SendData(1,Usart_Buf->RX_BUF-Usart_Buf->DataLen+1,Usart_Buf->DataLen);            //回传收到的数据
                        }
                    }
                }               
            }
        }
    }
   
    if (USART_GetITStatus(UsartX,USART_IT_IDLE)!=RESET)
    {
        if (Usart_Buf->StartRead ==1)
        {
            USART_ITConfig(UsartX, USART_IT_IDLE, DISABLE);//关闭空闲中断
            Usart_Buf->Count = 0;
            Usart_Buf->StartRead=0;
            Usart_Buf->OnData=0;
            Usart_Buf->DataLen=0;
        }
    }
}
//串口接收直接发送模式接收
void ZRecAndSend(u8 UsartNo)
{
    USART_TypeDef* UsartX;
    u8 res=0;
   
    switch(UsartNo)
    {
        case 1:
            if (_Usart1_buf.Status == DISABLE)
                return ;
            UsartX=USART1;
            break;
        case 2:
            if (_Usart2_buf.Status == DISABLE)
                return ;
            UsartX=USART2;
            break;
        case 3:
            if (_Usart3_buf.Status == DISABLE)
                return ;
            UsartX=USART3;
            break;
        default:
            return ;
    }
    if (USART_GetITStatus(UsartX,USART_IT_RXNE)!=RESET)
    {
        res = USART_ReceiveData(UsartX);//读串口值
        USART_SendData(UsartX, (uint16_t)res);         //向串口1发送数据
        while(USART_GetFlagStatus(UsartX,USART_FLAG_TC)!=SET);//等待发送结束
    }
}
void USART1_IRQHandler(void)                 //串口1中断服务程序
{
    //ZUsart_Order(1);
    ZRecAndSend(1);
}

void USART2_IRQHandler(void)
{
    ZRecAndSend(2);
//    u8 res = USART_ReceiveData(USART2);//读串口值
//            USART_SendData(USART2, (uint16_t)res);         //向串口1发送数据
//        while(USART_GetFlagStatus(USART2,USART_FLAG_TC)!=SET);//等待发送结束
}
void USART3_IRQHandler(void)
{
    ZRecAndSend(3);
//        u8 res = USART_ReceiveData(USART3);//读串口值
//            USART_SendData(USART3, (uint16_t)res);         //向串口1发送数据
//        while(USART_GetFlagStatus(USART3,USART_FLAG_TC)!=SET);//等待发送结束
}




/***********************************************************/
//以下是usart.h文件内容
#include "stm32f4xx.h"
/*
1.初始化端口
2.设置接收或发送缓冲区
3.开启发送或接收中断
4.中断程序处理数据
*/
struct ZUsart_Buf
{
    FunctionalState Status; //ENABLE,开启   DISABLE,禁止
    u16 RX_LEN;     //需接收字节数,当值为0时表示收到数据值为''时停止接收
    u16* RX_BUF;    //数据接收区域首地址
    u16 TX_LEN;     //需发送字节数,当值为0时表示发送数据值为''时停止发送
    u16* TX_BUF;    //数据发送区域首地址
    u8 Count;         //当前接收数据总数
    u8 DataLen;       //当前包数据长度
    u8 OnData;        //缓冲中是否有数据 0 表示无数据或者正在生成缓存数据包,1 表示有缓存数据包
    u8 StartRead;     //是否开始生成缓存数据包 0 表示未开始生成缓存数据包 1 表示正在接收数据生成缓存数据包
};
/*初始化串口
输入:
    UsartNo  串口号 1~5
    Bound 波特率
返回:
    0成功,1失败
*/
void ZUsart_Init(u8 UsartNo,u32 Bound);

/*禁止串口功能
输入:
    UsartNo  串口号 1~5
返回:
    0成功,1失败
*/
u8 ZUsart_Disable(u8 UsartNo);
/*使能串口功能
输入:
    UsartNo  串口号 1~5
返回:
    0成功,1失败
*/
u8 ZUsart_Enable(u8 UsartNo);
/*设置发送信息缓冲区
输入:
    ZUsart_Buf  串口结构信息
    Buf     缓冲区地址
    Buf_Len     缓冲区长度
返回:
    0成功,1失败
*/
u8 ZUsart_SetTxBuf(struct ZUsart_Buf *Usart_Buf,u16 * Buf,u16 Buf_Len);
/*设置接收信息缓冲区
输入:
    ZUsart_Buf  串口结构信息
    Buf     缓冲区地址
    Buf_Len     缓冲区长度
返回:
    0成功,1失败
*/
u8 ZUsart_SetRxBuf(struct ZUsart_Buf *Usart_Buf,u16 * Buf,u16 Buf_Len);
/*开启或关闭串口中断
输入:
    usartno  串口号 1~5
    usart_it 中断类型  USART_IT_RXNE,接收中断     USART_IT_TXE,发送中断
    value 设置值   ENABLE,开启中断   DISABLE,禁止中断
返回:
    0成功,1失败
*/
u8 ZUsart_SetInit(u8 UsartNo ,uint16_t Usart_It,FunctionalState Value);
/*串口发送数据
输入:
    UsartNo 串口号
    DataBuf 数据缓冲区首地址
    DataLen 数据缓冲区长度
返回:
    0成功,1失败
*/
u8 ZUsart_SendData(u8 UsartNo,u16* DataBuf,u16 DataLen);
//发送默认缓冲区数据
//UsartNo:串口号1,2,3
//返回:0成功,1失败
u8 ZUsart_SendDefault(u8 UsartNo);
/*串口接收数据
输入:
    UsartNo 串口号
    DataBuf 数据缓冲区首地址
    DataLen 数据缓冲区长度
返回:
    0成功,1失败
*/
u8 ZUsart_ReceiveData(u8 UsartNo,u16* DataBuf,u16 DataLen);
//串口命令模式接收数据
void ZUsart_Order(u8 UsartNo);
//串口接收直接发送模式接收
void ZRecAndSend(u8 UsartNo);

友情提示: 此问题已得到解决,问题已经关闭,关闭后问题禁止继续编辑,回答。