AVRmega16 LED 例程
阿新 • • 發佈:2018-09-09
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> voidmain(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;">
AVRmega16 LED 例程