这些小活动你都参加了吗?快来围观一下吧!>>
电子产品世界 » 论坛首页 » 嵌入式开发 » 国产MCU » 【STCAi8051U】定时器0和定时器2之间的干扰?

共2条 1/1 1 跳转至

【STCAi8051U】定时器0和定时器2之间的干扰?

专家
2026-03-02 13:58:09     打赏

在学习Ai8051UPCA测量外部脉冲宽度时,按照以下设想编写代码:

 

1、使用定时器2作为串口1 的波特率发生器

2、使用定时器0P20上输出1KH方波

3、使用 PCA 测量P20上的方波,测出脉冲宽度数据

 

定时器的代码:

//========================================================================
// 函数: void Timer0_init(void)
// 描述: timer0初始化函数.
//========================================================================
void Timer0_init(void) {
    TR0 = 0;    //停止计数
 
    ET0 = 1;    //允许中断
  
    //PT0 = 1;    //高优先级中断
    TMOD &= ~0x03;
    TMOD |= 0;  //工作模式, 0: 16位自动重装, 1: 16位定时/计数, 2: 8位自动重装, 3: 16位自动重装, 不可屏蔽中断
    //TMOD |= T0_CT;  //计数
    TMOD &= ~T0_CT;  //定时
  
    //INTCLKO |= T0CLKO; //输出时钟
    INTCLKO &= ~T0CLKO; //不输出时钟
 
    AUXR |= T0x12;  //1T mode
    TH0 = (u8)((65536UL - Timer0_Reload) / 256);
    TL0 = (u8)((65536UL - Timer0_Reload) % 256);
 
    TR0 = 1;    //开始运行
}
 
// 测试使用Timer2作为串口的波特率发生器
void Timer2Init(void) {
 //    T2L = BRT;
//    T2H = BRT >> 8;
////    S1BRT = 1;  // S1BRT:串口1的波特率发生器选择位: 0-选择定时器1作为波特率发生器;1-选择定时器2作为波特率发生器(默认) 
////    T2x12 = 1;
////    T2R = 1;    
//    AUXR |= S1BRT | T2x12;
    
}
 
//========================================================================
// 函数: void timer0_int (void) interrupt TIMER0_VECTOR
// 描述:  timer0中断函数.
//========================================================================
void timer0_int (void) interrupt 1 {
    P20 = ~P20;
}
 
主程序代码:
void main(void) {
    WTST = 0;  //设置程序指令延时参数,赋值为0可将CPU执行指令的速度设置为最快
    P_SW2 |= EAXFR; //扩展寄存器(XFR)访问使能
    CKCON = 0; //提高访问XRAM速度
 
    RSTFLAG |= 0x04;   //设置硬件复位后需要检测P3.2的状态选择运行区域,否则硬件复位后进入USB下载模式
 
    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;   //设置为准双向口
 
    usb_init();
    Timer0_init();
//===============================================================================
//  // 初始化定时器2,给串口1做波特率发生器用
//    Timer2Init();
//  
//    // 初始化串口1
//    Uart1Init(); 
    IE2 |= EUSB;   //IE2相关的中断位操作使能后,需要重新设置EUSB
    EA = 1;     //打开总中断
 
    while (1) {
        // USB调试及复位所需代码
if (bUsbOutReady)  {
            //USB_SendData(UsbOutBuffer,64);    //发送数据缓冲区,长度
            usb_OUT_done();
        }
 
        KeyResetScan();   //P3.2口按键触发软件复位,进入USB下载模式,不需要此功能可删除本行代码
        delay_ms(1);
    }
}


 

这个代码下,编译程序、上传给单片机,运行时在P20口可以检测到1KHz的方波。

接下来如果此时将Timer2Init()函数中的代码前两行取消注释,形如下面:

// 测试使用Timer2作为串口的波特率发生器
void Timer2Init(void) {
    T2L = BRT;
    T2H = BRT >> 8;
////  S1BRT = 1;  // S1BRT:串口1的波特率发生器选择位: 0-选择定时器1作为波特率发生器;1-选择定时器2作为波特率发生器(默认) 
////    T2x12 = 1;
////    T2R = 1;    
//  AUXR |= S1BRT | T2x12;
}


其实及时修改了,也不应该有效,因为主程序代码中并没有调用Timer2Init()这个函数。也就是说,这个修改应该对整个程序的运行不应该有任何影响。

然而奇怪的现象出来了,在此修改基础上,编译、上传、运行,再用示波器检测P20口的输出,方波没了,就好像Timer0中断处理没有发生一样。

 

搞不动为什么会发生这样的事情,难道对T2L T2H 的赋值,影响了Timer0的设置?





关键词: 懒猫的学习笔记     Ai8051U    

专家
2026-03-02 14:54:56     打赏
2楼

经过检查,修改代码测试,发现是引用了错误的头文件《Ai8051U.h》而导致的异常。唉、浪费了大量时间,还以为代码本身有逻辑错误。


共2条 1/1 1 跳转至

回复

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