这些小活动你都参加了吗?快来围观一下吧!>>
电子产品世界 » 论坛首页 » 嵌入式开发 » 国产MCU » 【STCAi8051U】Ai8051U的串口1全双工中断方式收发通讯程序

共3条 1/1 1 跳转至

【STCAi8051U】Ai8051U的串口1全双工中断方式收发通讯程序

专家
2025-08-05 15:07:45     打赏

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的设置,可以改变功能引脚。




关键词: 菜鸟学单片机     Ai8051U     串口测试    

院士
2025-08-05 18:15:56     打赏
2楼

这么看下来,ARM的架构确实还是先进了一些。



院士
2025-08-08 10:20:20     打赏
3楼

确实。

越简单,越不容易出错。

越简单,越可靠

功能越多,坏得越快


共3条 1/1 1 跳转至

回复

匿名不能发帖!请先 [ 登陆 注册 ]