/***************************************************** Chip type : ATmega16 Program type : Application Clock frequency : 8.000000 MHz Memory model : Small External SRAM size : 0 Data Stack size : 256 *****************************************************/ #include #include #define ADC_VREF_TYPE 0xC0 // Declare your global variables here flash unsigned char LedCode[10]={0xC0,0xF9,0xA4,0xB0,0x99,0x92,0x82,0xF8,0x80,0x90}; flash unsigned char LedPos[3]={0xFE,0xFD,0xFB}; unsigned char i,tmp,disbuf[4],mode,key,dismod,keyval; unsigned int mask,alltmp,adtmp[8],keycnt; void display(unsigned char data,unsigned char pos) { PORTB=PORTB&(LedPos[pos]); if (pos==2){ PORTD=LedCode[data]&0x7F; } else PORTD=LedCode[data]; } // Read the AD conversion result unsigned int read_adc(unsigned char adc_input) { ADMUX=adc_input | (ADC_VREF_TYPE & 0xff); // Delay needed for the stabilization of the ADC input voltage delay_us(10); // Start the AD conversion ADCSRA|=0x40; // Wait for the AD conversion to complete while ((ADCSRA & 0x10)==0); ADCSRA|=0x10; return ADCW; } void adcon() { read_adc(2); read_adc(2); for (i=0;i<8;i++) { //因为采用内部参考,为了测到5V左右,用了两个560K电阻分压 //虽然两电阻已经精选过了,但是还是有误差,所以乘了5220(本来选用内部参考应该乘5120的) adtmp[i]=(unsigned long)read_adc(2)*5220/1024; alltmp+=adtmp[i]; } alltmp/=8; tmp=alltmp%10; if (tmp>4) alltmp=alltmp/10+1; else alltmp/=10; } void keyscan() { switch(mode) { case 0: key=PINB&0x38; if (key!=0x38) mode=1; break; case 1: key=PINB&0x38; if (key!=0x38) { mode=2; keycnt=0; if (PINB.5==0) keyval=0; else if ((PINB.4==0)&&(dismod==1)) keyval=1; else if ((PINB.3==0)&&(dismod==1)) keyval=2; } break; case 2: key=PINB&0x38; if (key==0x38) { mode=0; if (keyval==0) dismod^=0x01; if (keyval==1) mask+=1; if (keyval==2) mask-=1; keyval=0x0f; } else if (++keycnt>=100) { mode=3; if (keyval==0) dismod^=0x01; keycnt=0; if (keyval==1) mask+=10; if (keyval==2) mask-=10; } break; case 3: key=PINB&0x38; if (key==0x38) { mode=0; keyval=0x0f; } else if (++keycnt>=50) { keycnt=0; if (keyval==0) dismod^=0x01; if (keyval==1) mask+=10; if (keyval==2) mask-=10; } break; } } void main(void) { // Declare your local variables here PORTB=0xFF; DDRB=0xC7; PORTC=0x00; DDRC=0x00; PORTD=0xFF; DDRD=0xFF; // ADC initialization // ADC Clock frequency: 691.200 kHz // ADC Voltage Reference: Int., cap. on AREF // ADC Auto Trigger Source: None ADMUX=0xC2; ADCSRA=0x86; mask=375; alltmp=0; mode=0; dismod=0; keycnt=0; while (1) { // Place your code here //进行温度转换,结果保存于alltmp中 adcon(); //读取键值 keyscan(); //mask为无符号型,故只需判断上限 if (mask>499) mask=0; //判断测得电压是否达到规定电压? if (dismod==0) { if (alltmp>=mask) PORTB&=~(1<<7); //达到规定电压,蜂鸣器鸣叫 else PORTB|=(1<<7); //否则,关蜂鸣器 } if (dismod==0) //当前是不是显示电池电压状态 { PORTB|=(1<<6); //设置指示灯灭 for (i=0;i<3;i++) //显示缓存为电压值 { disbuf[i]=alltmp%10; alltmp/=10; } } else //不是,当前为设定电压状态 { alltmp=mask; PORTB|=(1<<7); //关蜂鸣器 PORTB&=~(1<<6); //亮设置指示灯 for (i=0;i<3;i++) //显示缓存为设定值 { disbuf[i]=mask%10; mask/=10; } mask=alltmp; } for (i=0;i<3;i++) //显示数据 { PORTB|=0x07; display(disbuf[i],i); delay_ms(4); } }; }