在学习Ai8051U的PCA测量外部脉冲宽度时,按照以下设想编写代码:
1、使用定时器2作为串口1 的波特率发生器
2、使用定时器0在P20上输出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的设置?
我要赚赏金
