找回密码
 立即注册
查看: 2069|回复: 17

串口波特率问题

[复制链接]

12

主题

15

回帖

174

积分

注册会员

积分
174
发表于 2023-4-27 01:05:57 | 显示全部楼层 |阅读模式
串口波特率问题
波特率问题.png
回复

使用道具 举报 送花

  • 打卡等级:常住居民III
  • 打卡总天数:135
  • 最近打卡:2024-12-25 10:15:05

47

主题

1350

回帖

8058

积分

荣誉版主

冲哥视频教程和各种开源资料QQ交流群884047237,可群

积分
8058
QQ
发表于 2023-4-27 09:36:36 | 显示全部楼层
为了适应几个常见的波特率,提前预分频了呗,使用的时候只要带入公式计算就好了。
回复 支持 反对

使用道具 举报 送花

  • 打卡等级:偶尔看看I
  • 打卡总天数:14
  • 最近打卡:2025-04-28 14:10:14

19

主题

385

回帖

2508

积分

版主

积分
2508
QQ
发表于 2023-4-27 09:38:01 | 显示全部楼层
计算公式就是这样,需要采样4次
QQ:1463035472,微信:19952583954
回复 支持 反对

使用道具 举报 送花

12

主题

15

回帖

174

积分

注册会员

积分
174
发表于 2023-4-27 16:15:30 | 显示全部楼层
32位8051-STCAI 发表于 2023-4-27 09:38
计算公式就是这样,需要采用4次

公式也不能凭空舔加4,得有根有据,其实这个公式是根据定时器2的工作原理图推导出来的,但不知道这4是怎么来的,
回复 支持 反对

使用道具 举报 送花

  • 打卡等级:偶尔看看III
  • 打卡总天数:55
  • 最近打卡:2025-05-02 08:32:59

718

主题

1万

回帖

1万

积分

管理员

积分
15630
发表于 2023-4-27 18:41:02 | 显示全部楼层
忘了,可能是4倍的采样速度
回复 支持 反对

使用道具 举报 送花

12

主题

15

回帖

174

积分

注册会员

积分
174
发表于 2023-4-27 23:13:17 | 显示全部楼层
神*** 发表于 2023-4-27 18:41
忘了,可能是4倍的采样速度

波特率也就是定时器2的溢出率,定时器的计数也不需要采样,来一个脉冲就计一个数,与采样无关
回复 支持 反对

使用道具 举报 送花

  • 打卡等级:偶尔看看III
  • 打卡总天数:55
  • 最近打卡:2025-05-02 08:32:59

718

主题

1万

回帖

1万

积分

管理员

积分
15630
发表于 2023-4-27 23:27:58 | 显示全部楼层
那你说凭啥来个波特率的4倍,我虽然忘了,我好像懂原理啊,这个4,是我要求的以波特率的4倍采样 !
我讲我忘了,好像是,那是我老了,我有了谦虚的风格
回复 支持 反对

使用道具 举报 送花

12

主题

15

回帖

174

积分

注册会员

积分
174
发表于 2023-4-28 11:47:22 | 显示全部楼层
神*** 发表于 2023-4-27 23:27
那你说凭啥来个波特率的4倍,我虽然忘了,我好像懂原理啊,这个4,是我要求的以波特率的4倍采样 !
我讲我 ...

我没有别的意思,我是真心请教的,我之所以对这个问题刨根究底,是因我的电路中用到了WIFI模组,WIFI模组的通信波特率是115200,所以要求串口要能精准产生115200的波特率,为了稳妥起见,我根据T2的原理图对波特率的计算进行了推导,从T2原理图中看不出这"4"的来历,所以才请教你的。你所说的波特率的4倍采样,是不是指串口在传输数据时,对每位数据位的采样速率是按波特率4倍的速率来采样的,如果是这样,好像也
回复 支持 反对

使用道具 举报 送花

  • 打卡等级:偶尔看看III
  • 打卡总天数:55
  • 最近打卡:2025-05-02 08:32:59

718

主题

1万

回帖

1万

积分

管理员

积分
15630
发表于 2023-4-28 13:03:20 | 显示全部楼层
为准确的采样到每个BIT, INTEL 好像是16倍的采样速度,我们为了加速串口速度/[如40M/4 = 10M bps, 0误差],
减少波特率计算误差,我当时建议4倍采样就可以了 !
这样广泛的宽范围波特率误差也小了,/16那是历史的局限,这个【理论+实践】 是有充分的实践的
1.png

这就是我们的实践
2.png


//本示例在Keil开发环境下请选择Intel的8058芯片型号进行编译
//若无特别说明,工作频率一般为11.0592MHz


#include "reg51.h"

//-----------------------------------------
//define baudrate const
//BAUD = 65536 - FOSC/3/BAUDRATE/M (1T:M=1; 12T:M=12)
//NOTE: (FOSC/3/BAUDRATE) must be greater then 98, (RECOMMEND GREATER THEN 110)

//#define BAUD  0xF400                  // 1200bps @ 11.0592MHz
//#define BAUD  0xFA00                  // 2400bps @ 11.0592MHz
//#define BAUD  0xFD00                  // 4800bps @ 11.0592MHz
//#define BAUD  0xFE80                  // 9600bps @ 11.0592MHz
//#define BAUD  0xFF40                  //19200bps @ 11.0592MHz
#define BAUD  0xFFA0                    //38400bps @ 11.0592MHz

//#define BAUD  0xEC00                  // 1200bps @ 18.432MHz
//#define BAUD  0xF600                  // 2400bps @ 18.432MHz
//#define BAUD  0xFB00                  // 4800bps @ 18.432MHz
//#define BAUD  0xFD80                  // 9600bps @ 18.432MHz
//#define BAUD  0xFEC0                  //19200bps @ 18.432MHz
//#define BAUD    0xFF60                //38400bps @ 18.432MHz

//#define BAUD  0xE800                  // 1200bps @ 22.1184MHz
//#define BAUD  0xF400                  // 2400bps @ 22.1184MHz
//#define BAUD  0xFA00                  // 4800bps @ 22.1184MHz
//#define BAUD  0xFD00                  // 9600bps @ 22.1184MHz
//#define BAUD  0xFE80                  //19200bps @ 22.1184MHz
//#define BAUD  0xFF40                  //38400bps @ 22.1184MHz
//#define BAUD  0xFF80                  //57600bps @ 22.1184MHz

sfr AUXR = 0x8E;
sbit RXB = P3^0;                        //define UART TX/RX port
sbit TXB = P3^1;

typedef bit BOOL;
typedef unsigned char BYTE;
typedef unsigned int WORD;

BYTE TBUF,RBUF;
BYTE TDAT,RDAT;
BYTE TCNT,RCNT;
BYTE TBIT,RBIT;
BOOL TING,RING;
BOOL TEND,REND;

void UART_INIT();

BYTE t, r;
BYTE buf[16];

void main()
{
    TMOD = 0x00;                        //timer0 in 16-bit auto reload mode
    AUXR = 0x80;                        //timer0 working at 1T mode
    TL0 = BAUD;
    TH0 = BAUD>>8;                      //initial timer0 and set reload value
    TR0 = 1;                            //tiemr0 start running
    ET0 = 1;                            //enable timer0 interrupt
    PT0 = 1;                            //improve timer0 interrupt priority
    EA = 1;                             //open global interrupt switch

    UART_INIT();

    while (1)
    {                                   //user's function
        if (REND)
        {
            REND = 0;
            buf[r++ & 0x0f] = RBUF;
        }
        if (TEND)
        {
            if (t != r)
            {
                TEND = 0;
                TBUF = buf[t++ & 0x0f];
                TING = 1;
            }
        }
    }
}

//-----------------------------------------
//Timer interrupt routine for UART

void tm0() interrupt 1
{
    if (RING)
    {
        if (--RCNT == 0)
        {
            RCNT = 3;                   //reset send baudrate counter
            if (--RBIT == 0)
            {
                RBUF = RDAT;            //save the data to RBUF
                RING = 0;               //stop receive
                REND = 1;               //set receive completed flag
            }
            else
            {
                RDAT >>= 1;
                if (RXB) RDAT |= 0x80;  //shift RX data to RX buffer
            }
        }
    }
    else if (!RXB)
    {
        RING = 1;                       //set start receive flag
        RCNT = 4;                       //initial receive baudrate counter
        RBIT = 9;                       //initial receive bit number (8 data bits + 1 stop bit)
    }

    if (--TCNT == 0)
    {
        TCNT = 3;                       //reset send baudrate counter
        if (TING)                       //judge whether sending
        {
            if (TBIT == 0)
            {
                TXB = 0;                //send start bit
                TDAT = TBUF;            //load data from TBUF to TDAT
                TBIT = 9;               //initial send bit number (8 data bits + 1 stop bit)
            }
            else
            {
                TDAT >>= 1;             //shift data to CY
                if (--TBIT == 0)
                {
                    TXB = 1;
                    TING = 0;           //stop send
                    TEND = 1;           //set send completed flag
                }
                else
                {
                    TXB = CY;           //write CY to TX port
                }
            }
        }
    }
}

//-----------------------------------------
//initial UART module variable

void UART_INIT()
{
    TING = 0;
    RING = 0;
    TEND = 1;
    REND = 0;
    TCNT = 0;
    RCNT = 0;
}


回复 支持 反对

使用道具 举报 送花

  • 打卡等级:偶尔看看III
  • 打卡总天数:55
  • 最近打卡:2025-05-02 08:32:59

718

主题

1万

回帖

1万

积分

管理员

积分
15630
发表于 2023-4-28 13:04:16 | 显示全部楼层
用心良苦,曲高朋友多
1.png

2.png

3.png

4.png

比INTEL 大哥的/16 好太多了,看我们的 3倍波特率采样,软件模拟串口,
就知到我们的实力了,4倍采样可以了

回复 支持 反对

使用道具 举报 送花

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

本版积分规则

QQ|手机版|小黑屋|深圳国芯人工智能有限公司 ( 粤ICP备2022108929号-2 )

GMT+8, 2025-5-2 20:45 , Processed in 0.151523 second(s), 106 queries .

Powered by Discuz! X3.5

© 2001-2025 Discuz! Team.

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