玩了一天的游戏,太没意思了,无聊下就编了个AVR单片机的程序。还记得上次发表的点阵led交通灯,原来核心是51,这学期学的是AVR,所以就换了,改用ATmega16。
由于是从51上移植过来的,自然思路也差不多。只是这次在中断使用上,做了调整,使之尽可能的短!

核心改变:
下面是在CVAVR下的源程序,有什么不足之处,请指出 :
#include <mega16.h>
#define uchar unsigned char
int time_counter1s,time_counter250ms;
bit diff;
uchar j,n,k,time250ms;
//RSDA PORTC.1;
//CLK PORTC.0;
//RCK PORTC.2;
flash uchar signature[][128]={
.....//00: "walk1",点阵32x32,长度128字节
.....//02: "walk2",点阵32x32,长度128字节
.....//03: "stop",点阵32x32,长度128字节
.....//04: "blank",点阵32x32,长度128字节
};
flash uchar num[][128]={
.....//"39"~"1",点阵32x32,长度128字节
};
void sendbyteR(uchar temp) //发送数据
{
uchar c;
for(c=0;c<8;c++)
{
PORTC.1=(temp)&(0x01);
temp=temp>>1;
PORTC.0=1; //上升沿
PORTC.0=0;
}
}
void display(void) //显示图像
{
for(j=0;j<32;j++)
{
if(diff)
{
if(n>33) //倒计时“5”时,开始闪动
{
if((time250ms%2)==0) k=3;
else{
if((time250ms%4)==1) k=0;
else k=1;
}
}
else k=time250ms%2; //行走
}
else k=2; //停
sendbyteR(num[n][j*4+3]); //显示数字
sendbyteR(num[n][j*4+2]);
sendbyteR(num[n][j*4+1]);
sendbyteR(num[n][j*4]);
sendbyteR(signature[k][j*4+3]); //显示人
sendbyteR(signature[k][j*4+2]);
sendbyteR(signature[k][j*4+1]);
sendbyteR(signature[k][j*4]);
PORTA=j;
PORTC.2=1;
PORTC.2=0;
}
}
// Timer 0 比较匹配中断服务
interrupt [TIM0_COMP] void timer0_comp_isr(void)
{
if(++time_counter1s>=500)
{
time_counter1s=0;
n++; //计时1s
}
if(++time_counter250ms>=125)
{
time_counter250ms=0; //计时0.25s
time250ms++;
}
}
void main(void)
{
PORTA=0x00;
DDRA=0x1F;
PORTC=0x00;
DDRC=0x07; //显示控制I/O口初始化
// Timer/Counter 0 初始化
TCCR0=0x0B; //内部时钟,64分频,CTC模式
TCNT0=0x00;
OCR0=0x7C; //OCR0=2ms
// Timer(s)/Counter(s) Interrupt(s) initialization
TIMSK=0x02;
n=0; //赋初始值
k=0;
diff=0;
#asm("sei") //使能全局中断
while (1)
{
// Place your code here
display(); //显示图像
if(n>=39)
{
diff=!diff; //diff "0":停 ,"1":行走
if(diff) n=10;
else n=0;
}
if(time250ms>=39) time250ms=0;
}
}
|