历史上的今天
今天是:2024年10月16日(星期三)
2019年10月16日 | avr单片机atmega16自动浇花器Proteus仿真+源程序
2019-10-16 来源:eefocus
单片机源程序如下:
#include #include #define key_bz 0b00000111 #define uchar unsigned char #define uint_16 unsigned short char smg_zx[]={0x3f,0x06,0x5b,0x4f,0x66,0x6d, 0x7d,0x07,0x7f,0x6f,0x37};// 全局变量 char smg_wx[]={0B00000001,0B00000010,0B00000100,0b00001000}; char smg_oFF[]={0x3f,0X71,0X71}; unsigned int flag_10ms=0,flag_1s=0,on=0,buff[]={0,0,0},mode=0; unsigned int jh_hour1=2,u=0,count=0,count1=2,on_sec=0; unsigned int jh_sec1=5,jh_hour=0,jh_sec=0,flag=0; unsigned long int jishi_sec=0; void delay_ms(unsigned int k) { unsigned int i,j; for(i=0;i for(j=0;j<570;j++); } } // 用定时器实现定时 void T0_init(void)// 端口初始化函数 { TIFR=0XFF; TCCR0=0X0B; //64FENPIN, CTC MODE TCNT0=0; OCR0=250; TIMSK=0X02; } void port_init(void)// 端口初始化函数 { DDRC|=0b10001111; // PC4 5 OUT PUT PORTC=0b11110000; //m103 output only PORTD= 0xFF; DDRD= 0xff; DDRB&= 0b11111000; PORTB|=0B00000111; } void init_devices(void) { CLI(); //disable all interrupts port_init();//smg_zx[0]=1; T0_init(); SEI(); //re-enable interrupts } ////多位数拆分函数///////*/ void xs_buff(uchar va1, uchar va2) { buff[0]=va1/10; buff[1]=va1%10; buff[2]=va2/10; buff[3]=va2%10; } void xs_buff_on( uchar va2) { buff[0]=0; buff[1]=10; buff[2]=va2/10; buff[3]=va2%10; } void xs_smg() {//char smg_zx[]={0x3f,0x06,0x5b,0x4f,0x66,0x6d, // 0x7d,0x07,0x7f,0x6f};// 局部变量 static unsigned char posit=0; PORTC&=0X80; // turn off PORTC|=smg_wx[posit];//selecting led 7-segment PORTD=~smg_zx[buff[posit]]; // if(posit++>=3)posit=0; } //////////////////////////////////////////////////////////// void smg_xs(void) { if((count<=20)||(flag==1)) { if((on!=1)&&(on!=2)) { xs_buff(jh_hour,jh_sec); xs_smg(); } else { if((on==1)) { xs_buff_on(on_sec); xs_smg(); } else if(on==2) {PORTC&=0X80;on_sec=0; PORTD=~smg_oFF[u]; PORTC|=smg_wx[u];if(u++>=2)u=0; } } } else {PORTC&=0X80;count1=0;} } //////////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////////// void motor(void) { if(on==1) {PORTC|=0X80;flag=1; } else { on_sec=0; if(on==2){PORTC&=0X7F;flag=0;}//off状态下关闭电机 else if((jishi_sec>jh_hour1*3600)&&(jishi_sec<=jh_hour1*3600+jh_sec1))//大于设定的时间间隔和浇花时长 {PORTC|=0X80;//开电机 flag=1;} else { PORTC&=0X7F;flag=0; if(jishi_sec>jh_hour1*3600+jh_sec1) jishi_sec=0; } } } /////////////////////////////////////////////////////////////////////////////////// /// 按键子程序,实现按键值返回 uchar key(void) { static uchar key_zt=1, key_value; uchar returnvalue=100; // 100表示无按键对应的一个数值 switch(key_zt) // 0b00000111 /0b00000110 //0b00000110 { case 1:if((PINB&key_bz)!=key_bz) {key_value=PINB&key_bz; key_zt=2;} break; case 2: if((PINB&key_bz)==key_value) {key_zt=3; switch(key_value) { case 0b00000110: returnvalue=1; //切换模式 break; case 0b00000101: returnvalue=2;//在时分之间切换 break; case 0b00000011: returnvalue=3;//在时分之间切换 break; } }else key_zt=1; break; case 3: if((PINB&key_bz)==key_bz) key_zt=1; break; } return returnvalue; } // 根据按键子程序返回的按键值去执行相应的功能 void key_process(void) { switch(key()) { case 1:count=0;count1++;if(count1>1){count1=2;if(on==0)/*只有on=0,回归正常显示界面才能加*/{if(jh_hour++>=99)jh_hour=0;}}break; //mode:0-计时,1,校准,2闹钟 // 模式切换 case 2:count=0;count1++;if(count1>1){count1=2;if(on++>=2){on=0;jishi_sec=0;}}break;//每手动开启电机,jishi_sec就赋零 case 3:count=0;count1++;if(count1>1){count1=2;if(on==0)/*只有on=0,回归正常显示界面才能加*/{if(jh_sec++>=99)jh_sec=0;}}break; } } /////////////////////////////////////////////////////////////////////////////////////////////////// void sj_lj(void) { jishi_sec++; if(jishi_sec%3600==0&&jishi_sec!=0)jh_hour--; if(jh_hour==0){if(jh_sec--<=0){jh_hour=jh_hour1;jh_sec=jh_sec1;}} } //主函数//////////////////////////////////////////////////////////////////////////////////// void main(void) { jh_hour=jh_hour1; jh_sec=jh_sec1; init_devices(); while(1) { motor(); smg_xs(); if(flag_1s==1) {flag_1s=0; sj_lj();} if(flag_10ms==1) {flag_10ms=0; key_process();} } } ///////////////// ////////////// //T0中断服务程序 // 2ms 进入中断 #pragma interrupt_handler timer0_ocf_isr:20 void timer0_ocf_isr(void) {static uint_16 count_1s=0,count_10ms=0,count_5s=0; if(++count_10ms>=5) { count_10ms=0; flag_10ms=1; if(++count_1s>=100) {count_1s=0; flag_1s=1; count++; if(on==1) on_sec++; } } }
史海拾趣




