XWF1890 发表于 2023-4-27 01:05:57

串口波特率问题

串口波特率问题

电子DIY小家 发表于 2023-4-27 09:36:36

为了适应几个常见的波特率,提前预分频了呗,使用的时候只要带入公式计算就好了。

32位8051-AI 发表于 2023-4-27 09:38:01

计算公式就是这样,需要采样4次

XWF1890 发表于 2023-4-27 16:15:30

32位8051-STCAI 发表于 2023-4-27 09:38
计算公式就是这样,需要采用4次

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

神农鼎 发表于 2023-4-27 18:41:02

忘了,可能是4倍的采样速度

XWF1890 发表于 2023-4-27 23:13:17

神农鼎 发表于 2023-4-27 18:41
忘了,可能是4倍的采样速度

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

神农鼎 发表于 2023-4-27 23:27:58

那你说凭啥来个波特率的4倍,我虽然忘了,我好像懂原理啊,这个4,是我要求的以波特率的4倍采样 !
我讲我忘了,好像是,那是我老了,我有了谦虚的风格

XWF1890 发表于 2023-4-28 11:47:22

神农鼎 发表于 2023-4-27 23:27
那你说凭啥来个波特率的4倍,我虽然忘了,我好像懂原理啊,这个4,是我要求的以波特率的4倍采样 !
我讲我 ...

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

神农鼎 发表于 2023-4-28 13:03:20

为准确的采样到每个BIT, INTEL 好像是16倍的采样速度,我们为了加速串口速度/[如40M/4 = 10M bps, 0误差],
减少波特率计算误差,我当时建议4倍采样就可以了 !
这样广泛的宽范围波特率误差也小了,/16那是历史的局限,这个【理论+实践】 是有充分的实践的


这就是我们的实践



//本示例在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 BAUD0xF400                  // 1200bps @ 11.0592MHz
//#define BAUD0xFA00                  // 2400bps @ 11.0592MHz
//#define BAUD0xFD00                  // 4800bps @ 11.0592MHz
//#define BAUD0xFE80                  // 9600bps @ 11.0592MHz
//#define BAUD0xFF40                  //19200bps @ 11.0592MHz
#define BAUD0xFFA0                  //38400bps @ 11.0592MHz

//#define BAUD0xEC00                  // 1200bps @ 18.432MHz
//#define BAUD0xF600                  // 2400bps @ 18.432MHz
//#define BAUD0xFB00                  // 4800bps @ 18.432MHz
//#define BAUD0xFD80                  // 9600bps @ 18.432MHz
//#define BAUD0xFEC0                  //19200bps @ 18.432MHz
//#define BAUD    0xFF60                //38400bps @ 18.432MHz

//#define BAUD0xE800                  // 1200bps @ 22.1184MHz
//#define BAUD0xF400                  // 2400bps @ 22.1184MHz
//#define BAUD0xFA00                  // 4800bps @ 22.1184MHz
//#define BAUD0xFD00                  // 9600bps @ 22.1184MHz
//#define BAUD0xFE80                  //19200bps @ 22.1184MHz
//#define BAUD0xFF40                  //38400bps @ 22.1184MHz
//#define BAUD0xFF80                  //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;

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 = RBUF;
      }
      if (TEND)
      {
            if (t != r)
            {
                TEND = 0;
                TBUF = buf;
                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;
}


神农鼎 发表于 2023-4-28 13:04:16

用心良苦,曲高朋友多{:4_196:}








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

页: [1] 2
查看完整版本: 串口波特率问题