1. 程式人生 > >AVRmega16 LED 例程

AVRmega16 LED 例程

ext code clas 產生 init ims ini tcc 也好

AVRmega16 LED 例程 例程1:點亮一個燈
#include<mega16.h>
#include<delay.h>
void main(void)
{
DDRA=0xff;
while(1)
{
PORTA=0x01;
};
}
例程2:運用8個LED顯示出流水燈的效果(運用for語句)
#include<mega16.h>
#include<delay.h>
void
main(void) { unsignedchar i; PORTA=0x00; DDRA=0xFF; while(1) { for(i=0;i<8;i++) { PORTA=1<<i ; delay_ms(200); } } }

或者(運用if語句,用位移 << 操作實現) 例程
#include<mega16.h>
#include<delay.h>
void main(void)
{
unsignedchar a;
PORTA=0x00;
DDRA=0xFF;
a=0b00000001;
while(1)
{
if(a==0b00000000)
a=0b00000001;
PORTA=a;
a
=a<<1; delay_ms(200); } }
或者用一維數組
#include<mega161.h>
#include<delay.h>
void main()
{
unsignedchar display1[]={0x01,0x02,0x04,0x08,0x10,0x20,0x40,0x80};
unsignedchar display2[]={0x80,0x40,0x20,0x10,0x08,0x04,0x02,0x01};
unsignedchar k,b;
DDRA=0xff;
while(1)
{
for(k=0;k<8;k++)
{
PORTA=display1[k];
delay_ms(
150); } for(b=0;b<8;b++) { PORTA=display2[b]; delay_ms(150); } } }

例程3:用獨立按鍵控制一個燈(運用if與else語句)
#include<mega16.h>
#include<delay.h>
void main(void)
{
DDRA=0xff;
DDRB=0x00;
PORTB=0xff;
while(1)
{
if(PINB.0==0)
{
PORTA=0x01;
//delay_ms(1000);
}
else
{
PORTA=0x00;
// delay_ms(1000);
}
};
}

例程4:用獨立按鍵控制8個燈(運用switch語句) 牛刀小試:自己用switch編寫:
#include<mega16.h>
#include<delay.h>
void main(void)
{
DDRA=0xff;
DDRB=0x00;
while(1)
{
switch(PINB)
{
case(0xfe):
PORTA=0x01;break;
case(0xfd):
PORTA=0x02;break;
case(0xfb):
PORTA=0x04;break;
case(0xf7):
PORTA=0x08;break;
case(0xef):
PORTA=0x10;break;
case(0xdf):
PORTA=0x20;break;
case(0xbf):
PORTA=0x40;break;
case(0x7f):
PORTA=0x80;break;
}
};
}

1位8段數碼管

例程1:使數碼管從0-F跳動(運用一維數組)
#include<mega16.h>
#include<delay.h>
void main(void)
{
//unsigned char display[16]={0x3F, 0x06, 0x5B, 0x4F,0x66, 0x6D, 0x7D, 0x07,0x7F, 0x6F,0x77, 0x7C, 0x39, 0x5E, 0x79, 0x71}; //共陰極
unsignedchar display[16]={0xc0,0xf9,0xA4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x98,0x88,0x83,0xc6,0xa1,0x86,0x8e};//共陽極
unsignedchar i =0;
PORTA=0x00;
DDRA=0xff;
while(1)
{
PORTA= display[i];
i++;
if(i ==16)
i =0;
delay_ms(1000);
//PORTA= ~display[i] ; //共陰極 (取反)
PORTA= display[i];//共陽極
};
}

8位8段數碼管 例程1:利用8位8段數碼管顯示自己的學號(1理解數碼管工作原理)
#include<mega16.h>
#include<delay.h>
void main(void)
{
// unsigned char i;
PORTA=0x00;//段選初始化
PORTB=0x00;
DDRA=0xff;//
DDRB=0xff;//
while(1)
{
PORTB=0x00;
PORTA=0x06;//1
PORTB=0xfe;
delay_ms(1);
PORTB=0x00;
PORTA=0x66;//4
PORTB=0xfd;
delay_ms(1);
PORTB=0x00;
PORTA=0x3f;//0
PORTB=0xfb;
delay_ms(1);
PORTB=0x00;
PORTA=0x06;//1
PORTB=0xf7;
delay_ms(1);
PORTB=0x00;
PORTA=0x3f;//0
PORTB=0xef;
delay_ms(1);
PORTB=0x00;
PORTA=0x7d;//6
PORTB=0xdf;
delay_ms(1);
PORTB=0x00;
PORTA=0x66;//4
PORTB=0xbf;
delay_ms(1);
PORTB=0x00;
PORTA=0x07;//7
PORTB=0x7f;
delay_ms(1);
};
}

例程:數碼管顯示時鐘(設置定時器)
#include<mega16.h>
#include<delay.h>
#defineuintunsignedint
#define uchar unsignedchar
uchar duan[]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f};
uchar shi,fen,miao;
uint time;//註意char 與int的取值?
void display(uchar shi,uchar fen,uchar miao)
{
PORTB=0Xfe;//位碼
PORTA=(duan[shi/10]);//段碼
delay_ms(2);
PORTB=0xfd;
PORTA=(duan[shi%10]);
delay_ms(2);
PORTB=0xfb;//位碼
PORTA=0x40;//段碼
delay_ms(2);
PORTB=0xf7;//位碼
PORTA=(duan[fen/10]);//段碼
delay_ms(2);
PORTB=0xef;
PORTA=(duan[fen%10]);
delay_ms(2);
PORTB=0xdf;//位碼
PORTA=0x40;//段碼
delay_ms(2);
PORTB=0xbf;//位碼
PORTA=(duan[miao/10]);//段碼
delay_ms(2);
PORTB=0x7f;
PORTA=(duan[miao%10]);
delay_ms(2);
}
void init()//程序初始化
{
TCCR0=0x02;
TCNT0=0x06;
TIMSK=0x01;
ACSR=0x80;
#asm("sei")
PORTA=0x00;
PORTB=0x00;
DDRA=0xff;
DDRB=0xff;
time=0;
}
interrupt [TIM0_OVF]void timer0_ovf_isr(void)  /*打開定時器0 */
{
TCNT0=0x06;//設置初值 (0-ff之間)
time++;
if(time==400)//計算,結合初值算出精確時間
{
miao++;
if(miao>59)
{
miao=0;
fen++;
};
if(fen>59)
{
fen=0;
shi++;
};
if(shi>23)
shi=0;
time=0;//歸零
}
}
void main()
{
init();
while(1)
{
display(shi,fen,miao);
}
}

例程:獨立鍵盤與數碼管顯示數字
#include<mega16.h>
#include<delay.h>
unsignedchar display[16]={0xc0,0xf9,0xA4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x98,0x88,0x83,0xc6,0xa1,0x86,0x8e};//共陽極
unsignedchar temp;
void main(void)
{
DDRA=0xff;
DDRB=0x00;
while(1)
{
temp=PINB;//將值給tem
switch(PINB)
{
case(0xfe):
PORTA=display[0];break;
case(0xfd):
PORTA=display[1];break;
case(0xfb):
PORTA=display[2];break;
case(0xf7):
PORTA=display[3];break;
case(0xef):
PORTA=display[4];break;
case(0xdf):
PORTA=display[5];break;
case(0xbf):
PORTA=display[6];break;
case(0x7f):
PORTA=display[7];break;
}
};
}
例程:矩陣鍵盤與數碼管顯示數值
#include<mega16.h>
#include<delay.h>
//#define uchar unsigned char
//#define uint unsigned int
unsignedchar display[16]={0xc0,0xf9,0xA4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x98,0x88,0x83,0xc6,0xa1,0x86,0x8e};//共陽極
unsignedchar yin,temp;
void init()
{
PORTA=0x00;
DDRA=0Xff;
DDRB=0x00;
PORTB=0x00;
}
void keyscan()
{
for(yin=0;yin<2;yin++)
{
PORTB=0xfe;//將第一行置0,即檢測第一行
temp=PIND;//將值給tem
temp=temp&0xf0;//與0xf0與門一下,
while(temp!=0xf0)//判斷是否為0xf0
{
delay_ms(10);//延時
temp=PINB;//將P1值再給tem
temp=temp&0xf0;//將值再與門
while(temp!=0xf0)//再次判斷是否為0xf0
{
temp=PINB;//確實按下了,將tem值裝回,以便下次判斷開關語句,否則沒有它對應的值,如原來是ee,如果再按下是第二個鍵就不是de了
switch(temp)
{
case0xee:
PORTA=display[0];break;
case0xde:
PORTA=display[1];break;
case0xbe:
PORTA=display[2];break;
case0x7e:
PORTA=display[3];break;
}
while(temp!=0xf0)//松手判斷,以便退出以上兩個while
{
temp=PINB;//給temp賦值
temp=temp&0xf0;//與門一下
}
}
}
}
for(yin=0;yin<2;yin++)
{
PORTB=0xfd;//將第2行置0,即檢測第2行?
temp=PIND;//將值給tem
temp=temp&0xf0;//與0xf0與門一下,
while(temp!=0xf0)//判斷是否為0xf0
{
delay_ms(10);//延時
temp=PINB;//將P1值再給tem
temp=temp&0xf0;//將值再與門
while(temp!=0xf0)//再次判斷是否為0xf0
{
temp=PINB;//確實按下了,將tem值裝回,以便下次判斷開關語句,否則沒有它對應的值,如原來是ee,如果再按下是第二個鍵就不是de了
switch(temp)
{
case0xed:
PORTA=display[4];break;
case0xdd:
PORTA=display[5];break;
case0xbd:
PORTA=display[6];break;
case0x7d:
PORTA=display[7];break;
}
while(temp!=0xf0)//松手判斷,以便退出以上兩個while
{
temp=PINB;//給temp賦值
temp=temp&0xf0;//與門一下
}
}
}
}
for(yin=0;yin<2;yin++)
{
PORTB=0xfb;//將第3行置0,即檢測第3
temp=PIND;//將值給tem
temp=temp&0xf0;//與0xf0與門一下,
while(temp!=0xf0)//判斷是否為0xf0
{
delay_ms(10);//延時
temp=PINB;//將P1值再給tem
temp=temp&0xf0;//將值再與門
while(temp!=0xf0)//再次判斷是否為0xf0
{
temp=PINB;//確實按下了,將tem值裝回,以便下次判斷開關語句,否則沒有它對應的值,如原來是ee,如果再按下是第二個鍵就不是de了
switch(temp)
{
case0xeb:
PORTA=display[8];break;
case0xdb:
PORTA=display[9];break;
case0xbb:
PORTA=display[10];break;
case0x7b:
PORTA=display[11];break;
}
while(temp!=0xf0)//松手判斷,以便退出以上兩個while
{
temp=PINB;//給temp賦值
temp=temp&0xf0;//與門一下
}
}
}
}
for(yin=0;yin<2;yin++)
{
PORTB=0xf7;//將第4兄?,即檢測第4行
temp=PIND;//將值給tem
temp=temp&0xf0;//與0xf0與門一下,
while(temp!=0xf0)//判斷是否為0xf0
{
delay_ms(10);//延時
temp=PINB;//將P1值再給tem
temp=temp&0xf0;//將值再與門
while(temp!=0xf0)//再次判斷是否為0xf0
{
temp=PINB;//確實按下了,將tem值裝回,以便下次判斷開關語句,否則沒有它對應的值,如原來是ee,如果再按下是第二個鍵就不是de了
switch(temp)
{
case0xe7:
PORTA=display[12];break;
case0xd7:
PORTA=display[13];break;
case0xb7:
PORTA=display[14];break;
case0x77:
PORTA=display[15];break;
}
while(temp!=0xf0)//松手判斷,以便退出以上兩個while
{
temp=PINB;//給temp賦值
temp=temp&0xf0;//與門一下
}
}
}
}
}
void main()
{
init();
PORTB=0xff;//PB輸出為高電位
DDRB=0x0f;//設置高
while(1)
{
keyscan();
}
}

LCD延時的時鐘代碼
#include<lcd.h>
#include<delay.h>
#asm
.equ __lcd_port =0x18
#endasm
int sec =50,min=59,hour=23;
void display_time(void){
lcd_gotoxy(0,0);
lcd_putchar(0+hour/10);
lcd_putchar(0+hour%10);
lcd_putchar(:);
lcd_putchar(0+min/10);
lcd_putchar(0+min%10);
lcd_putchar(:);
lcd_putchar(0+sec/10);
lcd_putchar(0+sec%10);
}
void time_tick(void){
sec++;
if(sec ==60){
sec =0;
min++;
if(min ==60){
min =0;
hour++;
if(hour ==24){
hour =0;
}
}
}
}
void main(void){
lcd_init(16);
while(1){
time_tick();
display_time();
delay_ms(1000);
}
}
直流電機調速
#include<mega16.h>
#include<delay.h>
#define uchar unsignedchar
uchar a;
#define key_up PINA.5
#define key_dowm PINA.6
interrupt [EXT_INT0]void INT0_mode(void)//中斷選擇電機正反轉
{ TCCR1A=0x00;// PD4,PD5都不產生PWM
PORTD=0x00;//初始化PD4,PD5電平相等
a++;
delay_ms(10);
if(a>1)
a=0;
}
void main(void)
{
DDRA.4=0;
DDRA.5=0;
PORTA=0xf0;
DDRD=0xf0;//PD4,5做輸出
GICR=0x40;//外部中斷0
MCUCR=0x00;//低電平觸發INT0
MCUCSR=0x00;
GIFR=0x40;
TCCR1B=0x19;//工作模式14 快速PWM
TCNT1H=0x00;//計數器從0開始
TCNT1L=0x00;
ICR1H=5000/256;//計數上限植高8位
ICR1L=5000%256;// 計數上限植低8位
#asm("sei")
while(1)
{
if(a==0)
{
if(key_up==0)
{ PORTD.5=0;
TCCR1A=0x22;// 只開PD4
OCR1B=1500;//比較數值(快速)
}
if(key_dowm==0)
{ PORTD.5=0;
TCCR1A=0x22;// 只開PD4
OCR1B=3000;//慢速
}

最後小結,其實不論是什麽代碼也好,最終代碼的調用都應該是使用各種模塊分類的形式去調用,而不會是零散的。c是最接近底層硬件的代碼,是有非常好的機器親和性,可以通過單片機通過現象去學好c語言。

<wiz_tmp_tag id="wiz-table-range-border" contenteditable="false" style="display: none;">



來自為知筆記(Wiz)



AVRmega16 LED 例程