玩了一天的游戲,太沒意思了,無聊下就編了個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;
}
}
|