前几天做了个流水灯,原意是通过单片机的一个引脚加上9013来控制6盏LED灯的亮灭,这一个简单的程序却让我调试了几个小时,先看原先代码
#include "stc12c5a.h"
#define FOSC 2400000L
#define TIME (65536-FOSC/12/1000)
sbit REDLED = P1^1;
sbit GREENLED = P1^2;
sbit YELLOWLED = P1^3;
void main()
{
P1M0 = 0xff;
P1M1 = 0;
REDLED = 1;//初始状态为仅有红灯亮
GREENLED = 0;
YELLOWLED = 0;
TMOD = 0x01; //模式1,16位定时/计数器模式
TL0 = TIME; //赋初值
TH0 = TIME>>8;
TR0 = 1; //启动定时器
ET0=1; //T0中断使能
EA=1; //总中断使能
while(1);
}
void led_isr() interrupt 1
{
unsigned char temp;
count++;
if(count >2000)
{
temp = REDLED;//交换灯亮
REDLED= GREENLED ;
GREENLED = YELLOWLED;
YELLOWLED = temp;
count = 0;
}
/***初始化时间*****/
TH0 = TIME>>8;//设置时间
TL0 = TIME;
}
这是一个极简单的程序,我几乎没有想去调试它,后来也有先在开发板上跑一下发现也是没有问题的,但是到了pcb板上却是另外一回事了,所有的灯全都处于熄灭状态,用万用表量一下单片机的管脚输出全都是0。华仔和我起先都以为是线路出问题了而拼命地在查,但是都毫无结果。最后还是感激小马大神似的出现。原来是单片机管脚由于输出电流太大,已经被拉成低电平了,再次读取的时候就不再是高电平了。矩阵键盘利用的也是这个原理。而在开发板上调试时,因为电流不大,所以没有出现以上错误。修改代码后程序顺利通过。
#include "stc12c5a.h"
#define FOSC 2400000L
#define TIME (65536-FOSC/12/1000)
sbit REDLED = P1^1;
sbit GREENLED = P1^2;
sbit YELLOWLED = P1^3;
unsigned int count = 0;
unsigned char LED0,LED1,LED2;//存储当前灯状态的变量
void main()
{
P1M0 = 0xff;//设置为强推挽
P1M1 = 0;
LED0 = 1;//初始状态
LED1 = 0;
LED2 = 0;
TMOD = 0x01; //模式1,16位定时/计数器模式
TL0 = TIME; //赋初值
TH0 = TIME>>8;
TR0 = 1; //启动定时器
ET0=1; //T0中断使能
EA=1; //总中断使能
REDLED = LED0;
GREENLED = LED1;
YELLOWLED = LED2;
while(1);
}
void led_isr() interrupt 1
{
unsigned char temp;
count++;
if(count >2000)
{
/*先修改变量,再把变量的值赋给管脚,不可以直接读取管脚的值*/
temp = LED0;
LED0 = LED2;
LED2 = LED1;
LED1 = temp;
//赋值给管脚
REDLED = LED0;
GREENLED = LED1;
YELLOWLED = LED2;
count = 0;
}
/***初始化时间*****/
TH0 = TIME>>8;
TL0 = TIME;
}
其实后来感觉如果把单片机管脚设置为开漏输出再加上拉电阻可能就不会有这个问题了。但是这次的错误给我的教训是:不可以用管脚来储存信息!
ps:头次发blog,望请指教