根据Ai8051U的手册说明,定时器2是可以同时作为串口1、2、3、4的波特率发生器的,
本次实验,就是测试是否可行。预定使用115200波特率。代码如下,通过串口1、2、3、4各自向PC端输出字符串。
//测试工作频率为 11.0592MHz // 测试使用Timer2作为串口1、2、3、4的波特率发生器 // 串口1:P3.6(RXD),P3.7(TXD) // 串口2:P1.2(RXD),P1.3(TXD) // 串口3:P0.0(RXD),P0.1(TXD) // 串口4:P0.2(RXD),P0.3(TXD) #include "Ai8051U.H" #include "intrins.h" #define FOSC 11059200UL //定义为无符号长整型,避免计算溢出 #define BRT (65536 - (FOSC / 115200+2) / 4) //加 2 操作是为了让 Keil 编译器,自动实现四舍五入运算 bit busy1; char wptr1; char rptr1; char buffer1[64]; bit busy2; char wptr2; char rptr2; char buffer2[64]; bit busy3; char wptr3; char rptr3; char buffer3[64]; bit busy4; char wptr4; char rptr4; char buffer4[64]; void Timer2Init(void) { T2L = BRT; T2H = BRT >> 8; S1BRT = 1; // S1BRT:串口 1 波特率发生器选择位, 0:选择定时器 1 作为波特率发生器, 1:选择定时器 2 作为波特率发生器(默认值) T2x12 = 1; T2R = 1; } // 串口1 //--------------------------------------------------------------- void Uart1Isr() interrupt 4 { if (TI) { TI = 0; busy1 = 0; } if (RI) { RI = 0; buffer1[wptr1++] = SBUF; wptr1 &= 0x0f; } } void Uart1Init() { SCON = 0x50; // wptr1 = 0x00; rptr1 = 0x00; busy1 = 0; P_SW1 |= 0x40; // 选择P3.6,P3.7,因为擎天柱开发板上不提供P3.0,P3.1引脚 } void Uart1Send(char dat) { while (busy1); busy1 = 1; SBUF = dat; } void Uart1SendStr(char *p) { while (*p) { Uart1Send(*p++); } } // 串口2 //--------------------------------------------------------------- void Uart2Isr() interrupt 8 { if (S2TI) { S2TI = 0; busy2 = 0; } if (S2RI) { S2RI = 0; buffer2[wptr2++] = S2BUF; wptr2 &= 0x0f; } } void Uart2Init() { S2CFG = 0x01; S2CON = 0x50; wptr2 = 0x00; rptr2 = 0x00; busy2 = 0; } void Uart2Send(char dat) { while (busy2); busy2 = 1; S2BUF = dat; } void Uart2SendStr(char *p) { while (*p) { Uart2Send(*p++); } } // 串口3 //--------------------------------------------------------------- void Uart3Isr() interrupt 17 { if (S3TI) { S3TI = 0; busy3 = 0; } if (S3RI) { S3RI = 0; buffer3[wptr3++] = S3BUF; wptr3 &= 0x0f; } } void Uart3Init() { S3CON = 0x10; wptr3 = 0x00; rptr3 = 0x00; busy3 = 0; } void Uart3Send(char dat) { while (busy3); busy3 = 1; S3BUF = dat; } void Uart3SendStr(char *p) { while (*p) { Uart3Send(*p++); } } // 串口4 //--------------------------------------------------------------- void Uart4Isr() interrupt 18 { if (S4TI) { S4TI = 0; busy4 = 0; } if (S4RI) { S4RI = 0; buffer4[wptr4++] = S4BUF; wptr4 &= 0x0f; } } void Uart4Init() { S4CON = 0x10; wptr4 = 0x00; rptr4 = 0x00; busy4 = 0; } void Uart4Send(char dat) { while (busy4); busy4 = 1; S4BUF = dat; } void Uart4SendStr(char *p) { while (*p) { Uart4Send(*p++); } } void main() { EAXFR = 1; //允许访问扩展的特殊寄存器,XFR //(32 位模式请使用这句,注释下一句) // P_SW2 |= 0x80; //允许访问扩展的特殊寄存器,XFR //(8 位模式请使用这句,注释上一句) WTST = 0; //设置取程序代码等待时间, //赋值为 0 表示不等待,程序以最快速度运行 CKCON = 0; //设置访问片内的 xdata 速度, //赋值为 0 表示用最快速度访问,不增加额外的等待时间 P0M0 = 0x00; P0M1 = 0x00; P1M0 = 0x00; P1M1 = 0x00; P2M0 = 0x00; P2M1 = 0x00; P3M0 = 0x00; P3M1 = 0x00; P4M0 = 0x00; P4M1 = 0x00; P5M0 = 0x00; P5M1 = 0x00; Timer2Init(); Uart1Init(); Uart2Init(); Uart3Init(); Uart4Init(); ES = 1; ES2 = 1; ES3 = 1; ES4 = 1; EA = 1; Uart1SendStr("Uart1 Test !\r\n"); Uart2SendStr("Uart2 Test !\r\n"); Uart3SendStr("Uart3 Test !\r\n"); Uart4SendStr("Uart4 Test !\r\n"); while (1) { } }
实测可行。