打印

单片机波特率可以微调吗?

[复制链接]
2116|15
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
dmcz|  楼主 | 2014-7-30 16:45 | 只看该作者 |只看大图 回帖奖励 |倒序浏览 |阅读模式
最近在调试一块板子,STM32和SIM模块通信
现象:当波特率设置为9600单片机收到32个字节后面的数据就会不正确,当设为19200可以收到64个字节

经过反复调试排除软件和硬件问题,查找到原因是SIM模块发送出来的波形比正常波特率空闲间隔小,正常是70-75us左右,而SIM模块的空闲间隔只有52us,这也就是说SIM模块的波特率偏高一点点,请问在这种情况下该如何微调单片机的波特率呢?



        USART_InitStructure.USART_BaudRate = 19200;
        USART_InitStructure.USART_WordLength = USART_WordLength_8b;
        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);
        USART_ITConfig(USART1, USART_IT_RXNE, ENABLE);
        USART_Cmd(USART1, ENABLE);
        USART_ClearFlag(USART1,USART_FLAG_TC);





相关帖子

沙发
ayb_ice| | 2014-7-30 17:15 | 只看该作者
误差小于5%是可以的

只要能正确接收一个字节(任意数值),后面应该也是可以的,因为每个字节有同步信号

使用特权

评论回复
板凳
dmcz|  楼主 | 2014-7-30 17:32 | 只看该作者
ayb_ice 发表于 2014-7-30 17:15
误差小于5%是可以的

只要能正确接收一个字节(任意数值),后面应该也是可以的,因为每个字节有同步信号 ...

你好朋友,事实上我用PL2303给单片机发相同的数据接收是正常的,我只能比较两组信号的区别,唯一的区别就是SIM模块数据线空闲间隔比PL2303间隔时间短,我也觉得您所讲的字节同步是对的,可单片机出来的数据又为何不同呢

使用特权

评论回复
地板
chunyang| | 2014-7-30 17:40 | 只看该作者
楼主的概念错误,空闲时间跟波特率无关,波特率误差由任何一帧的长度本身决定,测试从起始位的前沿到结束位的后沿间的时间即可获知。楼主的问题跟数据处理部分的代码有关,跟波特率无关。

使用特权

评论回复
5
lanmp| | 2014-7-30 17:40 | 只看该作者
空闲是什么意思?起始位和结束位之间的高电平么?串口定义里面有这部分么?

使用特权

评论回复
6
chunyang| | 2014-7-30 17:41 | 只看该作者
如果你想微调MCU的串口波特率,改变波特率发生器的配置即可。

使用特权

评论回复
7
焊出个未来| | 2014-7-30 17:50 | 只看该作者
chunyang 发表于 2014-7-30 17:40
楼主的概念错误,空闲时间跟波特率无关,波特率误差由任何一帧的长度本身决定,测试从起始位的前沿到结束位 ...

您好大哥,如果说我的数据处理有问题,那我用PL2303发相同的数据,单片机可以正确接收,我觉得通过这点应该可以排除是软件问题

为了验证代码,软件也比较简单,只是设了断点观察接收到的数据,没做其他处理

char *pbuff;
char buff[256];
void USART1_IRQHandler(void)
{
        u8 c;
        if(USART_GetITStatus(USART1, USART_IT_RXNE) != RESET)
        {
                //USART_ClearITPendingBit(USART1, USART_IT_RXNE);
                c = USART_ReceiveData(USART1);
                *pbuff++ = c;
        }
}

int main(void){
        pbuff=buff;
        serial1_init("19200");
        while(1){
                if(*(pbuff-1)=='\n'){
                        memset(buff,0,sizeof(buff));//
                        pbuff = buff;
                }
        }
        return 0;
}

使用特权

评论回复
8
lanmp| | 2014-7-30 18:07 | 只看该作者
焊出个未来 发表于 2014-7-30 17:50
您好大哥,如果说我的数据处理有问题,那我用PL2303发相同的数据,单片机可以正确接收,我觉得通过这点应 ...

if(*(pbuff-1)=='\n')
这么写程序真的没问题么?

使用特权

评论回复
9
chunyang| | 2014-7-30 18:17 | 只看该作者
焊出个未来 发表于 2014-7-30 17:50
您好大哥,如果说我的数据处理有问题,那我用PL2303发相同的数据,单片机可以正确接收,我觉得通过这点应 ...

问题是二者的信号并非完全相同。你都说了,SIM900的空闲期时间较短,这对你的程序处理能力的要求更高,必须在下一帧来临前,把前面的数据处理完。

使用特权

评论回复
10
ZG11211| | 2014-7-30 21:17 | 只看该作者
我所知道的,PIC单片机时钟频率可以微调(寄存器设定),STM的不了解。

使用特权

评论回复
11
dmcz|  楼主 | 2014-7-30 23:26 | 只看该作者
lanmp 发表于 2014-7-30 18:07
if(*(pbuff-1)=='\n')
这么写程序真的没问题么?

你好,在中断里先赋过值才加的指针,所以这里需要读前一个数据才是最后接收到的

使用特权

评论回复
12
lanmp| | 2014-7-31 14:07 | 只看该作者
dmcz 发表于 2014-7-30 23:26
你好,在中断里先赋过值才加的指针,所以这里需要读前一个数据才是最后接收到的 ...

看不出如何保证这句在中断后面执行。

使用特权

评论回复
13
rszhao| | 2014-7-31 16:10 | 只看该作者
跟波特率无关 如果波特率不正确 你前面的数据就会不对 应该是你程序在处理数据的问题 好好看看程序 算算 一帧数据处理的时间 和下帧数据的间隔是否满足要求

使用特权

评论回复
14
joyme| | 2014-7-31 16:38 | 只看该作者
pbuff = buff;

使用特权

评论回复
15
joyme| | 2014-7-31 16:42 | 只看该作者
pbuff = buff; 之后执行 *(pbuff-1),取到的数据是乱的,不是数组里的数据
还有你说的32字节之后是乱和64字节之后是乱的,发送的内容是什么,是否刚好是碰到了'\n',就乱了
9600的32字节和19200的64字节时间是一样的,也有可能是时间上的一个bug

使用特权

评论回复
16
mcu5i51| | 2014-7-31 17:33 | 只看该作者
9600速率时间大约104uS,停止位你测量为52uS,就是0.5位了,一般停止位1,1.5,2 可见这个波形不是很标准;

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

22

主题

66

帖子

0

粉丝