各位大虾:
本人刚接触STM32,菜鸟一个。 我最近遇到一个关于STM32中5个串口同时工作的问题,自己忙了一个多月,也查了不少资料,但问题依旧没有解决,所以当自己努力后还没解决问题就要向吧里的各位兄弟姐妹求教了,废话不多说,直奔主题
任务要求是,4路串口分别接收各路数据,然后由一个串口发给上位机;每路数据一共5个字节 {FF 81 数据位 数据位 校验和 } 前两个是帧头和状态位,当中是两个数据位 ,最后是校验和
我的设计思路是: 让串口2~5这四个串口分时接收数据,然后通过串口1发送给电脑; 即先让串口2工作,把串口3、4、5关掉,只有当串口2收到中断里面的正确的状态位并通过串口1发送出去之后关掉串口2,然后使能串口3,当串口3工作完后关掉串口3,如此以往
在中断里面所做的工作就是判断帧头、状态位、校验和正确则置标志位,总的来讲程序设计思路简单;
我所碰到的问题:只让串口2和3接收,串口1发出,即在代码中注释掉串口4和5工作的部分,工作非常正常,一点问题也没有;
但是当加入串口4让串口2、3、4同时工作,偶尔这3个串口能正确收几次程序就死掉,运气不好的时候,刚轮到串口4工作就死掉了,但是我把其它串口工作部分注释掉只让串口4收串口1发又是正常的,我现在很纠结,不知道问题出在哪?也不知道该怎么解决?自己调了一个多月,没什么进展,前来向各位兄弟姐妹求教,望指点一二,谢谢!(我用的是战舰板调的,有没有战舰板上短路帽插错导致这种现象的可能?)
附上源码
这是USART.C
[mw_shl_code=c,true]#include "sys.h"
#include "usart.h"
u8 USART2_RX_BUF[USART_REC_LEN]; //接收缓冲,最大USART_REC_LEN个字节.
u8 USART3_RX_BUF[USART_REC_LEN];
u8 UART4_RX_BUF[USART_REC_LEN];
u8 UART5_RX_BUF[USART_REC_LEN];
u8 m=0;
u8 n=0;
u8 p=0;
u8 q=0;
u8 i=0;
u16 USART2_RX_STA=0; //接收状态标记//接收状态标记
u16 USART3_RX_STA=0;
u16 UART4_RX_STA=0; //接收状态标记
u16 UART5_RX_STA=0;
//初始化串口1`5
//bound:波特率
void uart_init(u32 bound){
//GPIO端口设置
GPIO_InitTypeDef GPIO_InitStructure;
USART_InitTypeDef USART_InitStructure;
NVIC_InitTypeDef NVIC_InitStructure;
RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1|RCC_APB2Periph_GPIOA|RCC_APB2Periph_GPIOB, ENABLE); //使能USART1,GPIOA时钟
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOC|RCC_APB2Periph_GPIOD, ENABLE);
RCC_APB1PeriphClockCmd(RCC_APB1Periph_USART2|RCC_APB1Periph_USART3, ENABLE);
RCC_APB1PeriphClockCmd(RCC_APB1Periph_UART4|RCC_APB1Periph_UART5, ENABLE);
USART_DeInit(USART1); //复位串口1`5
USART_DeInit(USART2);
USART_DeInit(USART3);
USART_DeInit(UART4);
USART_DeInit(UART5);
//USART1_TX USART2_TX PA.9 PA.2
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_2|GPIO_Pin_9; //PA.9与PA.2
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP; //复用推挽输出
GPIO_Init(GPIOA, &GPIO_InitStructure); //初始化PA9
//USART1_RX USART2_RX PA.10 PA.3
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_3|GPIO_Pin_10;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;//浮空输入
GPIO_Init(GPIOA, &GPIO_InitStructure); //初始化PA10
//USART3_TX PB.10
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10; //PB.10
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP; //复用推挽输出
GPIO_Init(GPIOB, &GPIO_InitStructure); //初始化PA9
//USART3_RX PB.11
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_11;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;//浮空输入
GPIO_Init(GPIOB, &GPIO_InitStructure); //初始化PA10
//UART4_TX UART5_TX PC10 PC12
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10|GPIO_Pin_12; //PC10 PC12
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP; //复用推挽输出
GPIO_Init(GPIOC, &GPIO_InitStructure); //初始化PC10 PC12
//UART4_RX PC11
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_11;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;//浮空输入
GPIO_Init(GPIOC, &GPIO_InitStructure); //初始化PC11
//UART5_RX PD2
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_2;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;//浮空输入
GPIO_Init(GPIOD, &GPIO_InitStructure); //初始化 PD2
//USART1 初始化设置
USART_InitStructure.USART_BaudRate = bound;//一般设置为9600;
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(USART1, &USART_InitStructure); //初始化串口
//USART2 初始化设置
USART_InitStructure.USART_BaudRate = bound;//一般设置为9600;
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(USART2, &USART_InitStructure); //初始化串口
//USART3 初始化设置
USART_InitStructure.USART_BaudRate = bound;//一般设置为9600;
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(USART3, &USART_InitStructure); //初始化串口
//UART4 初始化设置
USART_InitStructure.USART_BaudRate = bound;//一般设置为9600;
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(UART4, &USART_InitStructure); //初始化串口
//UART5 初始化设置
USART_InitStructure.USART_BaudRate = bound;//一般设置为9600;
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(UART5, &USART_InitStructure); //初始化串口
//Usart1 NVIC 配置
NVIC_InitStructure.NVIC_IRQChannel = USART2_IRQn;
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority=3;//抢占优先级3
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 3; //子优先级3
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; //IRQ通道使能
NVIC_Init(&NVIC_InitStructure); //根据指定的参数初始化VIC寄存器
USART_ITConfig(USART2, USART_IT_RXNE, ENABLE);//开启中断
NVIC_InitStructure.NVIC_IRQChannel = USART3_IRQn;
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority=3 ;//抢占优先级3
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 3; //子优先级3
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; //IRQ通道使能
NVIC_Init(&NVIC_InitStructure); //根据指定的参数初始化VIC寄存器
USART_ITConfig(USART3, USART_IT_RXNE, ENABLE);//开启中断
NVIC_InitStructure.NVIC_IRQChannel = UART4_IRQn;
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority=3 ;//抢占优先级3
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 3; //子优先级3
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; //IRQ通道使能
NVIC_Init(&NVIC_InitStructure); //根据指定的参数初始化VIC寄存器
USART_ITConfig(UART4, USART_IT_RXNE, ENABLE);//开启中断
NVIC_InitStructure.NVIC_IRQChannel = UART5_IRQn;
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority=3 ;//抢占优先级3
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 3; //子优先级3
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; //IRQ通道使能
NVIC_Init(&NVIC_InitStructure); //根据指定的参数初始化VIC寄存器
USART_ITConfig(UART5, USART_IT_RXNE, ENABLE);//开启中断
USART_Cmd(USART1, ENABLE); //使能串口
/* USART_Cmd(USART2, ENABLE);
USART_Cmd(USART3, ENABLE);
USART_Cmd(UART4, ENABLE);
USART_Cmd(UART5, ENABLE); */
}
void USART2_IRQHandler(void) //串口2中断服务程序
{
u8 Res2;
if(USART_GetITStatus(USART2, USART_IT_RXNE) != RESET) //
{
Res2=USART_ReceiveData(USART2);//(USART2->DR); //读取接收到的数据
USART2_RX_BUF[USART2_RX_STA]=Res2;
USART2_RX_STA++;
if(USART2_RX_STA==5)
{
USART2_RX_STA=0;
i=USART2_RX_BUF[0]+USART2_RX_BUF[1]+USART2_RX_BUF[2]+USART2_RX_BUF[3];
if(USART2_RX_BUF[0]==0XFF&&USART2_RX_BUF[1]==0X81&&i==USART2_RX_BUF[4])
{
m=0x01;
}
else {m=0;}
}
}
}
void USART3_IRQHandler(void) //串口3中断服务程序
{
u8 Res3;
if(USART_GetITStatus(USART3, USART_IT_RXNE) != RESET) //
{
Res3=USART_ReceiveData(USART3);//(USART2->DR); //读取接收到的数据
USART3_RX_BUF[USART3_RX_STA]=Res3;
USART3_RX_STA++;
if(USART3_RX_STA==5)
{
USART3_RX_STA=0;
i=USART3_RX_BUF[0]+USART3_RX_BUF[1]+USART3_RX_BUF[2]+USART3_RX_BUF[3];
if(USART3_RX_BUF[0]==0XFF&&USART3_RX_BUF[1]==0X81&&i==USART3_RX_BUF[4])
{
n=0x01;
}
else {n=0;}
}
}
}
void UART4_IRQHandler(void) //串口4中断服务程序
{
u8 Res4;
if(USART_GetITStatus(UART4, USART_IT_RXNE) != RESET) //
{
Res4=USART_ReceiveData(UART4);//读取接收到的数据
UART4_RX_BUF[UART4_RX_STA]=Res4;
UART4_RX_STA++;
if(UART4_RX_STA==5)
{
UART4_RX_STA=0;
i=UART4_RX_BUF[0]+UART4_RX_BUF[1]+UART4_RX_BUF[2]+UART4_RX_BUF[3];
if(UART4_RX_BUF[0]==0XFF&&UART4_RX_BUF[1]==0X81&&i==UART4_RX_BUF[4])
{
p=0x01;
}
else {p=0;}
}
}
}
void UART5_IRQHandler(void) //串口5中断服务程序
{
u8 Res5;
if(USART_GetITStatus(UART5, USART_IT_RXNE) != RESET)
{
Res5=USART_ReceiveData(UART5);//读取接收到的数据
UART5_RX_BUF[UART5_RX_STA]=Res5;
UART5_RX_STA++;
if(UART5_RX_STA==5)
{
UART5_RX_STA=0;
i=UART5_RX_BUF[0]+UART5_RX_BUF[1]+UART5_RX_BUF[2]+UART5_RX_BUF[3];
if(UART5_RX_BUF[0]==0XFF&&UART5_RX_BUF[1]==0X81&&i==UART5_RX_BUF[4])
{
q=0x01;
}
else {q=0;}
}
}
}
USART.H部分的源码[/mw_shl_code]
[mw_shl_code=c,true]#ifndef __USART_H
#define __USART_H
#include "stdio.h"
#include "sys.h"
#define USART_REC_LEN 5 //定义最大接收字节数 200
extern u8 USART2_RX_BUF[USART_REC_LEN]; //接收缓冲,最大USART_REC_LEN个字节.末字节为换行符
extern u8 USART3_RX_BUF[USART_REC_LEN];
extern u8 UART4_RX_BUF[USART_REC_LEN]; //接收缓冲,最大USART_REC_LEN个字节.末字节为换行符
extern u8 UART5_RX_BUF[USART_REC_LEN];
extern u8 m;
extern u8 n;
extern u8 p;
extern u8 q;
extern u16 USART2_RX_STA; //接收状态标记
extern u16 USART3_RX_STA;
extern u16 UART4_RX_STA; //接收状态标记
extern u16 UART5_RX_STA;
//如果想串口中断接收,请不要注释以下宏定义
void uart_init(u32 bound);
#endif
[/mw_shl_code]
main.c部分源码
[mw_shl_code=c,true]#include "sys.h"
#include "usart.h"
int main(void)
{
u8 t=0;
NVIC_Configuration(); //设置NVIC中断分组2:2位抢占优先级,2位响应优先级
uart_init(9600); //串口初始化为9600
while(1)
{
//串口2
USART_Cmd(USART2, ENABLE); //使能串口2
while(m!=0X01);
{
USART_ITConfig(USART2, USART_IT_RXNE, DISABLE);//在此处要关闭中断
m=0;
for(t=0;t<5;t++)
{
USART_SendData(USART1, USART2_RX_BUF[t]);//向串口1发送数据
while(USART_GetFlagStatus(USART1,USART_FLAG_TC)!=SET);//等待发送结束
}
USART_ITConfig(USART2, USART_IT_RXNE, ENABLE); //开启串口中断
}
USART_Cmd(USART2, DISABLE); //失能串口2
//串口3
USART_Cmd(USART3, ENABLE);
while(n!=0X01);
{
USART_ITConfig(USART3, USART_IT_RXNE, DISABLE);//在此处要关闭中断
n=0;
for(t=0;t<5;t++)
{
USART_SendData(USART1, USART3_RX_BUF[t]);//向串口1发送数据
while(USART_GetFlagStatus(USART1,USART_FLAG_TC)!=SET);//等待发送结束
}
USART_ITConfig(USART3, USART_IT_RXNE, ENABLE); //开启串口中断
}
USART_Cmd(USART3, DISABLE);
//串口4
USART_Cmd(UART4, ENABLE);
while(p!=0X01);
{
USART_ITConfig(UART4, USART_IT_RXNE, DISABLE);//在此处要关闭中断
p=0;
for(t=0;t<5;t++)
{
USART_SendData(USART1, UART4_RX_BUF[t]);//向串口1发送数据
while(USART_GetFlagStatus(USART1,USART_FLAG_TC)!=SET);//等待发送结束
}
USART_ITConfig(UART4, USART_IT_RXNE, ENABLE); //开启串口中断
}
USART_Cmd(UART4, DISABLE);
// 串口5
USART_Cmd(UART5, ENABLE);
while(q!=0X01);
{
USART_ITConfig(UART5, USART_IT_RXNE, DISABLE);//在此处要关闭中断
q=0;
for(t=0;t<5;t++)
{
USART_SendData(USART1, UART5_RX_BUF[t]);//向串口1发送数据
while(USART_GetFlagStatus(USART1,USART_FLAG_TC)!=SET);//等待发送结束
}
USART_ITConfig(UART5, USART_IT_RXNE, ENABLE); //开启串口中断
}
USART_Cmd(UART5, DISABLE);
}
}
[/mw_shl_code]
仿真跟踪看过没有?
还是要debug调试具体到底是在哪里出问题
一周热门 更多>