本帖最后由 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);
一周热门 更多>