返回

(STM32 A串口2)接收(STM32 B数据printf2),同时STM32 A使用串口1printf给电脑

发布时间:2023-10-29 06:07:02 145


一.遇到的问题:
1. 首先是想使用第二个串口,查了一下中文手册,但是好像并没有关于第二个串口配置的,于是就自己写了一个
2. 在写串口2的时候遇到的问题是如何使用printf()函数,才能不与第一个串口向冲突,找了一下百度,通过一个函数就可以搞定了,下文配上
3. 当深入研究串口的时候发现很多问题,一个是数据接收保存问题,虽然是利用串口中断,但是数据在中断中无法读取(添加了定时器定时读取数据,从而使大数据不在堵塞)
4. 就上述三个问题处理,深入处理串口问题
二.针对于串口2配置问题,手册使用IO TX->A2 RX->A3
1.在初始化的时候还是老样子
void usart2_init(u32 bound)
2.串口2中断也是直接改过来的(正点原子例程)

void USART2_IRQHandler(void)                    //串口2中断服务程序
{
u8 Res,t;
if(USART_GetITStatus(USART2, USART_IT_RXNE) != RESET) //接收中断(接收到的数据必须是0x0d 0x0a结尾)
{
Res =USART_ReceiveData(USART2); //读取接收到的数据
if((USART2_RX_STA&0x8000)==0)//接收未完成
{
if(USART2_RX_STA&0x4000)//接收到了0x0d
{
if(Res!=0x0a)USART2_RX_STA=0;//接收错误,重新开始
else USART2_RX_STA|=0x8000; //接收完成了
}
else //还没收到0X0D
{
if(Res==0x0d)USART2_RX_STA|=0x4000;
else
{
USART2_RX_BUF[USART2_RX_STA&0X3FFF]=Res ;
USART2_RX_STA++;
if(USART2_RX_STA>(USART2_REC_LEN-1))USART2_RX_STA=0;//接收数据错误,重新开始接收
}
}
}
}
}

3.以下为实现printf()函数,想要使用在那个串口,直接修改一下USARTX就行了
/串口2的printf/
// CMD_BUFFER_LEN长度自己定义吧

void printf2(char *fmt, ...) 
{
char buffer[CMD_BUFFER_LEN+1];
u8 i = 0;
va_list arg_ptr;
va_start(arg_ptr, fmt);
vsnprintf(buffer, CMD_BUFFER_LEN+1, fmt, arg_ptr);
while ((i < CMD_BUFFER_LEN) && buffer[i])
{
USART_SendData(USART2, (u8) buffer[i++]);
while (USART_GetFlagStatus(USART2, USART_FLAG_TC) == RESET);
}
va_end(arg_ptr);
}

5. 在上面那个中断中测试接收到的数据时候出现了些问题,总是卡死或者显示两次不完整的数据,于是便自己写了一个串口显示函数如下

void receive_usart2_handle()
{
if(USART2_RX_STA&0x8000)
{
// len=USART2_RX_STA&0x3fff;//得到此次接收到的数据长度
printf("\r\n您发送串口2的消息为:\r\n");
printf("%s\r\n",USART2_RX_BUF);
memset(USART2_RX_BUF,0,sizeof(USART2_RX_BUF));//清除buffer
USART2_RX_STA=0;
}
}

6. 下面是定时器2的定时器中断,因为主函数有延时,不能及时显示接收数据,从而使定时器不断扫描,及时传递数据,使得数据不再卡顿堵塞

void TIM2_IRQHandler(void)   //TIM2中断
{
if (TIM_GetITStatus(TIM2, TIM_IT_Update) != RESET) //检查TIM2更新中断发生与否
{
TIM_ClearITPendingBit(TIM2, TIM_IT_Update ); //清除TIMx更新中断标志
receive_usart1_handle();
receive_usart2_handle();
}
}
  1. 以下是定时器2的中断配置
void TIM2_Int_Init(u16 arr,u16 psc)
{
TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure;
NVIC_InitTypeDef NVIC_InitStructure;

RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2, ENABLE); //时钟使能

//定时器TIM2初始化
TIM_TimeBaseStructure.TIM_Period = arr; //设置在下一个更新事件装入活动的自动重装载寄存器周期的值
TIM_TimeBaseStructure.TIM_Prescaler =psc; //设置用来作为TIMx时钟频率除数的预分频值
TIM_TimeBaseStructure.TIM_ClockDivision = TIM_CKD_DIV1; //设置时钟分割:TDTS = Tck_tim
TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up; //TIM向上计数模式
TIM_TimeBaseInit(TIM2, &TIM_TimeBaseStructure); //根据指定的参数初始化TIMx的时间基数单位
TIM_ITConfig(TIM2,TIM_IT_Update,ENABLE ); //使能指定的TIM2中断,允许更新中断

// //中断优先级NVIC设置
NVIC_InitStructure.NVIC_IRQChannel = TIM2_IRQn; //TIM2中断
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0; //先占优先级0级
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 3; //从优先级3级
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; //IRQ通道被使能
NVIC_Init(&NVIC_InitStructure); //初始化NVIC寄存器
TIM_Cmd(TIM2, ENABLE); //使能TIMx
}

8.从而主函数初始化就能够进行通信了

加例程吧,下面这个是完整版两个串口一个定时器中断
​​​http://pan.baidu.com/s/1o8gEJ8I​​


特别声明:以上内容(图片及文字)均为互联网收集或者用户上传发布,本站仅提供信息存储服务!如有侵权或有涉及法律问题请联系我们。
举报
评论区(0)
按点赞数排序
用户头像
精选文章
thumb 中国研究员首次曝光美国国安局顶级后门—“方程式组织”
thumb 俄乌线上战争,网络攻击弥漫着数字硝烟
thumb 从网络安全角度了解俄罗斯入侵乌克兰的相关事件时间线