七彩灯的程序问题
时间:10-02
整理:3721RD
点击:
我最近在实验七彩灯,但是亮了第十种颜色之后程序就卡死了,剩下的颜色无法出现。我用UV4反汇编窗口,甚至用串口发程序运行的数据到电脑都找不出问题。请大神们帮我看看这是怎么回事。谢谢!
我用的七彩灯是四只脚的,共阳。用了八个灯,占用了32个IO口。芯片是STC89C52RC。我的程序的想法是这样的:比如要亮橙色,找出RGB值“0xff,0x66,0”,然后我用PWN同时实现R,G,B相对应的亮度,就可以亮出漂亮的橙色。
本来我想亮出三十多种颜色的,但亮到第十种颜色后程序就不动了。我程序里有单片机与电脑的串口通信,每隔段时间换一种颜色就发颜色序号给STC串口助手,开始能正常发送,但单片机卡死后就像疯了似的猛发 “0”或“F0”给电脑,让我疑惑不解。下面是我的灯
这是程序
#include <REGX52.H>
#define red P0 //红色
#define green P2 //绿色
#define blue P3 //蓝色
unsigned char jishu=0; //定时器0中断一次加一
unsigned char code shuju[]={
0xff,0,0, 0xff,0x33,0, 0xff,0x66,0, 0xff,0x99,0, 0xff,0xcc,0, 0xff,0xff,0,
0xcc,0xff,0, 0x99,0xff,0, 0x66,0xff,0, 0x33,0xff,0, 0,0xff,0,
0,0xff,0x33, 0,0xff,0x66, 0,0xff,0x99, 0,0xff,0xcc, 0,0xff,0xff,
0,0xcc,0xff, 0,0x99,0xff, 0,0x66,0xff, 0,0x33,0xff, 0,0,0xff,
0x33,0,0xff, 0x66,0,0xff, 0x99,0,0xff, 0xcc,0,0xff, 0xff,0,0xff,
0xff,0,0xcc, 0xff,0,0x99, 0xff,0,0x66, 0xff,0,0x33, 0xff,0,0
}; //每一种颜色的三种RGB值。值越大,对应亮度越大
void main()
{
unsigned char a;
unsigned char color=0;
EA=1;
ET0=1; //开定时器0
TMOD=0X22; //定时器0和1都用模式2,自动填装
SCON=0X50; //串口中断用模式1
TH0=0XD8; //40微妙中断一次
TL0=0XD8;
TH1=0XF3; //2400波特率的初值,板子使用12M晶振,初值=256-12000000/32/12/2400
TL1=0XF3;
TR0=1;
TR1=1;
while(1)
{
for(a=0;a<100;a++) //决定了颜色转换的时间间隔
{
do
{
if(jishu<shuju[color*3])
{
red=0;
}
else red=0xff;
if(jishu<shuju[color*3+1])
{
green=0;
}
else green=0xff;
if(jishu<shuju[color*3+2])
{
blue=0;
}
else blue=0xff;
}while(jishu<255); //用PWN增大或减小相应RGB的亮度,形成色彩
jishu=0;
}
color++; //换下一个颜色
SBUF=color; //把对应颜色通过RS232发送到电脑上
while(TI==0);
TI=1;
if(color>30)color=0;
}
}
void timer0()interrupt 1
{
TR0=0;
jishu++;
TR0=1;
}
来自小组: 朱海生
我用的七彩灯是四只脚的,共阳。用了八个灯,占用了32个IO口。芯片是STC89C52RC。我的程序的想法是这样的:比如要亮橙色,找出RGB值“0xff,0x66,0”,然后我用PWN同时实现R,G,B相对应的亮度,就可以亮出漂亮的橙色。
本来我想亮出三十多种颜色的,但亮到第十种颜色后程序就不动了。我程序里有单片机与电脑的串口通信,每隔段时间换一种颜色就发颜色序号给STC串口助手,开始能正常发送,但单片机卡死后就像疯了似的猛发 “0”或“F0”给电脑,让我疑惑不解。下面是我的灯
这是程序
#include <REGX52.H>
#define red P0 //红色
#define green P2 //绿色
#define blue P3 //蓝色
unsigned char jishu=0; //定时器0中断一次加一
unsigned char code shuju[]={
0xff,0,0, 0xff,0x33,0, 0xff,0x66,0, 0xff,0x99,0, 0xff,0xcc,0, 0xff,0xff,0,
0xcc,0xff,0, 0x99,0xff,0, 0x66,0xff,0, 0x33,0xff,0, 0,0xff,0,
0,0xff,0x33, 0,0xff,0x66, 0,0xff,0x99, 0,0xff,0xcc, 0,0xff,0xff,
0,0xcc,0xff, 0,0x99,0xff, 0,0x66,0xff, 0,0x33,0xff, 0,0,0xff,
0x33,0,0xff, 0x66,0,0xff, 0x99,0,0xff, 0xcc,0,0xff, 0xff,0,0xff,
0xff,0,0xcc, 0xff,0,0x99, 0xff,0,0x66, 0xff,0,0x33, 0xff,0,0
}; //每一种颜色的三种RGB值。值越大,对应亮度越大
void main()
{
unsigned char a;
unsigned char color=0;
EA=1;
ET0=1; //开定时器0
TMOD=0X22; //定时器0和1都用模式2,自动填装
SCON=0X50; //串口中断用模式1
TH0=0XD8; //40微妙中断一次
TL0=0XD8;
TH1=0XF3; //2400波特率的初值,板子使用12M晶振,初值=256-12000000/32/12/2400
TL1=0XF3;
TR0=1;
TR1=1;
while(1)
{
for(a=0;a<100;a++) //决定了颜色转换的时间间隔
{
do
{
if(jishu<shuju[color*3])
{
red=0;
}
else red=0xff;
if(jishu<shuju[color*3+1])
{
green=0;
}
else green=0xff;
if(jishu<shuju[color*3+2])
{
blue=0;
}
else blue=0xff;
}while(jishu<255); //用PWN增大或减小相应RGB的亮度,形成色彩
jishu=0;
}
color++; //换下一个颜色
SBUF=color; //把对应颜色通过RS232发送到电脑上
while(TI==0);
TI=1;
if(color>30)color=0;
}
}
void timer0()interrupt 1
{
TR0=0;
jishu++;
TR0=1;
}
来自小组: 朱海生
虽然不知道,但一看程序,就想,为何定义一个颜色不用结构体呢
typedef struct color
{
unsigned char R;
unsigned char G;
unsigned char B;
}COLOR;
COLOR colorTbl[] ={……};
这样还省去了你那样用乘法算下表耗时……
是不是因为没有在中断里给定时器中断清除标志?
然后是你这中断时间太短了,可不太好,说不定在某一次进入do while()时,刚比较完前面2次,在第三次将要用到jishu这个变量时,中断来了,就修改了jishu的值,使得在这一次do while()循环里,可能本该是三次比较所用到的jishu变量的值是一样的,结果变成了前两次是一样,后一次就跟前2次不一样了……
感谢你的热心!谢谢你为了我费了那么多精力!
你说用结构体这个建议很好,不用浪费那么多时间。而且中断时间也实在不能这么短。我改正了之后彩灯就可以正常转换颜色了!你真是一语中的!但是那个串口通信的的中断标志我的确有清零,但单片机仍旧不断的向电脑串口助手发送“0” 或“0f0”,令人疑惑不解