AVRmega16 LED 例程
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); } } }
例程
#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); } } }
#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;">
每个人都可以站在大地上,分享这个世界,并触摸天空;