Ai8051U的串口1全双工中断方式收发通讯程序代码如下:
/************* 功能说明 ************** 本例程基于AI8051U为主控芯片的实验箱进行编写测试。 使用Keil C251编译器,Memory Model推荐设置XSmall模式,默认定义变量在edata,单时钟存取访问速度快。 edata建议保留1K给堆栈使用,空间不够时可将大数组、不常用变量加xdata关键字定义到xdata空间。 串口1全双工中断方式收发通讯程序。 通过PC向MCU发送数据, MCU收到后通过串口1把收到的数据原样返回. 用定时器做波特率发生器,建议使用1T模式(除非低波特率用12T),并选择可被波特率整除的时钟频率,以提高精度。 下载时, 选择时钟 22.1184MHz (用户可自行修改频率). ******************************************/ #include "..\..\comm\AI8051U.h" #include "stdio.h" #include "intrins.h" typedef unsigned charu8; typedef unsigned intu16; typedef unsigned longu32; #define MAIN_Fosc 22118400L //定义主时钟(精确计算115200波特率) //========================================================================== #define Baudrate1 (65536 - MAIN_Fosc / 115200 / 4) #define UART1_BUF_LENGTH 128 //========================================================================== /************* IO口定义 **************/ /************* 本地常量声明 **************/ /************* 本地变量声明 **************/ u8 TX1_Cnt; //发送计数 u8 RX1_Cnt; //接收计数 bit B_TX1_Busy; //发送忙标志 u8 RX1_Buffer[UART1_BUF_LENGTH]; //接收缓冲 /************* 本地函数声明 **************/ void UART1_config(u8 brt); // 选择波特率, 2: 使用Timer2做波特率, 其它值: 使用Timer1做波特率. void PrintString1(u8 *puts); /**************** 外部函数声明和外部变量声明 *****************/ //======================================================================== // 函数: void PrintString1(u8 *puts) // 描述: 串口1发送字符串函数。 // 参数: puts: 字符串指针. // 返回: none. // 备注: //======================================================================== void PrintString1(u8 *puts) { //遇到停止符0结束 for (; *puts != 0; puts++) { SBUF = *puts; B_TX1_Busy = 1; while(B_TX1_Busy); } } //======================================================================== // 函数: SetTimer2Baudraye(u32 dat) // 描述: 设置Timer2做波特率发生器。 // 参数: dat: Timer2的重装值. // 返回: none. // 备注: //======================================================================== void SetTimer2Baudraye(u32 dat) { T2R = 0;//Timer stop T2_CT = 0;//Timer2 set As Timer T2x12 = 1;//Timer2 set as 1T mode T2H = (u8)(dat / 256); T2L = (u8)(dat % 256); ET2 = 0; //禁止中断 T2R = 1;//Timer run enable } //======================================================================== // 函数: void UART1_config(u8 brt) // 描述: UART1初始化函数。 // 参数: brt: 选择波特率, 2: 使用Timer2做波特率, 其它值: 使用Timer1做波特率. // 返回: none. // 备注: //======================================================================== void UART1_config(u8 brt) { /*********** 波特率使用定时器2 *****************/ if(brt == 2) { S1BRT = 1;//S1 BRT Use Timer2; SetTimer2Baudraye(Baudrate1); } else { /*********** 波特率使用定时器1 *****************/ TR1 = 0; S1BRT = 0;//S1 BRT Use Timer1; T1_CT = 0;//Timer1 set As Timer T1x12 = 1;//Timer1 set as 1T mode TMOD &= ~0x30;//Timer1_16bitAutoReload; TH1 = (u8)(Baudrate1 / 256); TL1 = (u8)(Baudrate1 % 256); ET1 = 0; //禁止中断 TR1 = 1; } /*************************************************/ SCON = (SCON & 0x3f) | 0x40; //UART1模式, 0x00: 同步移位输出, 0x40: 8位数据,可变波特率, 0x80: 9位数据,固定波特率, 0xc0: 9位数据,可变波特率 // PS = 1; //高优先级中断 ES = 1; //允许中断 REN = 1; //允许接收 // 串口功能脚选择:0x00: P3.0 P3.1 // 0x40: P3.6 P3.7 // 0x80: P1.6 P1.7 // 0xC0: P4.3 P4.4 P_SW1 &= 0x3f; //P_SW1 |= 0x00; P_SW1 |= 0x40; B_TX1_Busy = 0; TX1_Cnt = 0; RX1_Cnt = 0; } //======================================================================== // 函数: void UART1_int (void) interrupt UART1_VECTOR // 描述: UART1中断函数。 // 参数: nine. // 返回: none. // 备注: //======================================================================== void UART1_int (void) interrupt 4 { // 接收数据中断 if(RI) { RI = 0; RX1_Buffer[RX1_Cnt] = SBUF; if(++RX1_Cnt >= UART1_BUF_LENGTH) RX1_Cnt = 0; } // 发送数据中断 if(TI) { TI = 0; B_TX1_Busy = 0; } } void UartPutc(unsigned char dat) { SBUF = dat; while(TI == 0); TI = 0; //Clear Tx flag B_TX1_Busy = 0; } char putchar(char c) { UartPutc(c); return c; } //======================================================================== // 函数: void delay_ms(u8 ms) // 描述: 延时函数。 // 参数: ms,要延时的ms数, 这里只支持1~255ms. 自动适应主时钟. // 返回: none. // 备注: //======================================================================== void delay_ms(u8 ms) { u16 i; do { i = MAIN_Fosc / 6000; while(--i); }while(--ms); } /******************** 主函数 **************************/ void main(void) { WTST = 0; //设置程序指令延时参数,赋值为0可将CPU执行指令的速度设置为最快 EAXFR = 1; //扩展寄存器(XFR)访问使能 CKCON = 0; //提高访问XRAM速度 P0M1 = 0x00; P0M0 = 0x00; //设置为准双向口 P1M1 = 0x00; P1M0 = 0x00; //设置为准双向口 P2M1 = 0x00; P2M0 = 0x00; //设置为准双向口 P3M1 = 0x00; P3M0 = 0x00; //设置为准双向口 P4M1 = 0x00; P4M0 = 0x00; //设置为准双向口 P5M1 = 0x00; P5M0 = 0x00; //设置为准双向口 P6M1 = 0x00; P6M0 = 0x00; //设置为准双向口 P7M1 = 0x00; P7M0 = 0x00; //设置为准双向口 UART1_config(2); // 选择波特率, 2: 使用Timer2做波特率, 其它值: 使用Timer1做波特率. EA = 1; //允许全局中断 PrintString1("AI8051U UART1 Test Programme! P3.6-Rxd & P3.7-Txd \r\n"); //UART1发送一个字符串 while (1) { //收到数据, 发送空闲 if((TX1_Cnt != RX1_Cnt) && (!B_TX1_Busy)) { SBUF = RX1_Buffer[TX1_Cnt]; B_TX1_Busy = 1; if(++TX1_Cnt >= UART1_BUF_LENGTH) TX1_Cnt = 0; } } }
根据设置,切断到P3.6和P3.7引脚。程序通过擎天柱评估板完成测试。修改P_SW1的设置,可以改变功能引脚。