OpenEdv-开源电子网

 找回密码
 立即注册
正点原子全套STM32/Linux/FPGA开发资料,上千讲STM32视频教程免费下载...
查看: 3735|回复: 4

STM32的USART1把接收到的内容返回问题

[复制链接]

14

主题

72

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
268
金钱
268
注册时间
2021-10-7
在线时间
44 小时
发表于 2021-10-26 15:20:34 | 显示全部楼层 |阅读模式
1金钱
本帖最后由 cyradg 于 2021-10-26 15:36 编辑

正在学习STM32的USART,在做一个例子测试单片机接收到什么就发送什么回去,在单位上,开发板不在身边,所以是Proteus仿真的,发送端是用串口调试助手,接收端就是Proteus仿真,仿真时,调试助手发送一个字符,比如‘A’,STM32会正确将‘A’发送回来,但是连续接收到两个及以上的字符时,Proteus仿真STM32接收到的从第2个字符开始就错了,具体是什么原因?代码如下,所有代码都是在main函数所在C文件里面:
#include <stm32f10x.h>
#include "delay.h"
/*************************************************
*clk:单片机工作时钟。默认最高频率72MHz
*bound:波特率,例如9600,115200等
**************************************************/
void USART_Init(u32 clk,u32 bound)
{
        float temp;
        u16 mantissa;
        u16 fraction;           
        temp=(float)(clk*1000000)/(bound*16);//得到USARTDIV
        mantissa=temp;                                 //得到整数部分
        fraction=(temp-mantissa)*16; //得到小数部分         
    mantissa<<=4;
        mantissa+=fraction;
        RCC->APB2ENR|=1<<2;   //使能PORTA口时钟  
        RCC->APB2ENR|=1<<14;  //使能串口时钟
        GPIOA->CRH&=0XFFFFF00F;//IO状态设置
        GPIOA->CRH|=0X000008B4;//IO状态设置
        GPIOA->BSRR=1<<10;
        RCC->APB2RSTR|=1<<14;   //复位串口1
        RCC->APB2RSTR&=~(1<<14);//停止复位                     
        //波特率设置
         USART1->BRR=mantissa; // 波特率设置         
        USART1->CR1|=0X200C;  //1位停止,无校验位.
}

int main(void)
{
        delay_init(72);//初始化延迟功能时钟,默认为72MHz
        RCC->APB2ENR |=1<<3;
        GPIOB->CRL=0x33333333;
        GPIOB->CRH=0x33333333;
        USART_Init(72,9600);//初始化串口。
        u8 rec;
        u16 cnt=0;
        u16 v=0;
        while(1)
        {
                if(USART1->SR&(1<<5))        //接收到数据
                {
                        rec=USART1->DR; //保存接收数据
                        if (0==cnt)v=rec;//将接收到的第1个内容传给PB口的低8位
                        else if (1==cnt)v=(v<<8)+rec;//将接收到的第2个内容传给PB口的低8位
                        else v=0;
                        GPIOB->ODR=v;
                        cnt++;
                        USART1->DR=rec; //将接收到的数据返回发送端
                        while((USART1->SR&0X40)==0);//等待发送结束
                }
        }
}1、发送一个‘A’,正确
A.jpg
2、发送两个,即‘AA’,第二个返回的内容就错了(STM32接收就错了,但是串口那是正确的)。
B.jpg


正点原子逻辑分析仪DL16劲爆上市
回复

使用道具 举报

14

主题

72

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
268
金钱
268
注册时间
2021-10-7
在线时间
44 小时
 楼主| 发表于 2021-10-26 19:26:32 | 显示全部楼层
本帖最后由 cyradg 于 2021-10-26 19:31 编辑

上开发板测试还是会乱码,继续求解。
A.jpg

回复

使用道具 举报

14

主题

72

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
268
金钱
268
注册时间
2021-10-7
在线时间
44 小时
 楼主| 发表于 2021-10-26 20:07:43 | 显示全部楼层
注释掉正点原子的“while((USART1->SR&0X40)==0);//等待发送结束”,网上抄了一句“while((USART1->SR&(1<<7))==0);”,可以了,不知道为什么。
A.jpg
B.jpg
回复

使用道具 举报

3

主题

117

帖子

0

精华

高级会员

Rank: 4

积分
559
金钱
559
注册时间
2018-10-3
在线时间
107 小时
发表于 2021-10-26 21:34:02 | 显示全部楼层
查看手册USART 的SR寄存器就知道了。1<<7  就是寄存器第八位。 0x40,也就是1<<6 ,寄存器第七位。
回复

使用道具 举报

14

主题

72

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
268
金钱
268
注册时间
2021-10-7
在线时间
44 小时
 楼主| 发表于 2021-10-27 12:11:33 | 显示全部楼层
wklhwkl 发表于 2021-10-26 21:34
查看手册USART 的SR寄存器就知道了。1

这个知道,我是不太明白为什么检测第7位就可以,检测第6位为什么不正常。另外Proteus仿真STM32时,时钟好像不正常,或者说有特定的设置,Proteus仿真时,异步串口,SysTick时钟做延迟,我测试了Proteus仿真都是不正常的,上开发板就正常。至于SPI、I2C,因为有CLCK信号Proteus仿真估计没问题。
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则



关闭

原子哥极力推荐上一条 /2 下一条

正点原子公众号

QQ|手机版|OpenEdv-开源电子网 ( 粤ICP备12000418号-1 )

GMT+8, 2025-6-10 18:36

Powered by OpenEdv-开源电子网

© 2001-2030 OpenEdv-开源电子网

快速回复 返回顶部 返回列表