N76E003使用双串口,波特率异常(115200 bps)

发布时间 2023-08-12 08:35:45作者: lazy12138

1、如下图通过数据手册可以看出在16Mhz的时钟下115200会有较大误差,故须将时钟配置为16.6Mhz

2、使用双串口的情况下串口0使用timer1作为时钟,串口1使用timer3作为时钟,在这种情况下,实际上timer1的时钟是16.588Mhz,需要按16.588Mhz来计算波特率,否则波特率有较大误差。(即便如此,在某些芯片上,波特率仍有固定误差,应和物料有关)
系统时钟16.6Mhz设置代码如下:

sfr RCTRIM0 = 0x84;
sfr RCTRIM1 = 0x85;
void MODIFY_HIRC_166(void)
{
    unsigned char hircmap0,hircmap1;
    unsigned int trimvalue16bit;
    /* 因为只有开机才能重新加载RCTRIM0和RCTRIM1的值,所以检查开机标志*/
    if ((PCON&SET_BIT4)==SET_BIT4)
    {
        hircmap0 = RCTRIM0;
        hircmap1 = RCTRIM1;
        trimvalue16bit = ((hircmap0<<1)+(hircmap1&0x01));
        trimvalue16bit = trimvalue16bit - 15;
        hircmap1 = trimvalue16bit&0x01;
        hircmap0 = trimvalue16bit>>1;
        TA=0XAA;
        TA=0X55;
        RCTRIM0 = hircmap0;
        TA=0XAA;
        TA=0X55;
        RCTRIM1 = hircmap1;
        /* 修改HIRC值后,清除上电标志 */
        PCON &= CLR_BIT4;
    }
}

波特率设置示例代码如下:

void InitialUART0_Timer1(UINT32 u32Baudrate)    //T1M = 1, SMOD = 1
{
    SCON = 0x52;     //UART0 Mode1,REN=1,TI=1
    TMOD |= 0x20;    //Timer1 Mode1

    set_SMOD;        //UART0 Double Rate Enable
    set_T1M;
    clr_BRCK;        //Serial port 0 baud rate clock source = Timer1

#ifdef FOSC_160000
    //TH1 = 256 - (1000000/u32Baudrate+1);          /*16 MHz */
    TH1 = 256 - (1036750/u32Baudrate+1);         /*16.588 MHz */
    //TH1 = 256 - (1037500/u32Baudrate+1);         /*16.6 MHz */
#endif       

#ifdef FOSC_221184
    TH1 = 256 - (1382400/u32Baudrate);               /*22.1184 MHz */
#endif
    set_TR1;
}

void InitialUART1_Timer3(UINT32 u32Baudrate) //use timer3 as Baudrate generator
{
    P02_Quasi_Mode;        //Setting UART pin as Quasi mode for transmit
    P16_Quasi_Mode;        //Setting UART pin as Quasi mode for transmit

    SCON_1 = 0x50;        //UART1 Mode1,REN_1=1,TI_1=1
    T3CON = 0x08;          //T3PS2=0,T3PS1=0,T3PS0=0(Prescale=1), UART1 in MODE 1

    clr_BRCK;

#ifdef FOSC_160000

    //RH3    = HIBYTE(65536 - (1000000/u32Baudrate)-1);      /*16 MHz */
    //RL3    = LOBYTE(65536 - (1000000/u32Baudrate)-1);      /*16 MHz */

    RH3    = HIBYTE(65536 - (1037500/u32Baudrate));          /*16.6 MHz */
    RL3    = LOBYTE(65536 - (1037500/u32Baudrate));          /*16.6 MHz */
#endif

#ifdef FOSC_166000
    RH3    = HIBYTE(65536 - (1037500/u32Baudrate));           /*16.6 MHz */
    RL3    = LOBYTE(65536 - (1037500/u32Baudrate));           /*16.6 MHz */
#endif
    
    set_TR3;         //Trigger Timer3  
}

但是,在实测的情况下,发现在超频的状态下,仍然会有误差,会出现接收的字节错误的情况。