/******************************* project :A/D转换数码管显示 chip type : atmega8 clock frequency:内部RC(INT) 8MHz Author :周远峰 ********************************/ #include "iom8v.h" #include "macros.h" #define osccal 0x7d unsigned long adc_rel; //处理后世界转换结果 unsigned long adc_rl; //A/D转换结 unsigned int tmp; //设置的温度参数 unsigned char adc_mux; //A/D通道 unsigned int ww; //闪时间 unsigned int kk; unsigned char k1; //显示 unsigned int k; unsigned char key1; //按键标志 unsigned char led_buff[3]={0,0,0}; //显示缓存 signed int error0; //当前偏差 signed int error1; //上次偏差 signed int error2; //上上次偏差 signed char Kp; //比例常数 signed char Ki; //积分常数 signed char Kd; //微分常数 signed int kk1; //当前控制输出 signed int kk2; //上次控制输出 #define NB -3 #define NM -2 #define NS -1 #define ZO 0 #define PS 1 #define PM 2 #define PB 3 #pragma data:code //设置数据区位程序储存器 const unsigned char seg_table[17]={0x40,0x79,0x24,0x30,0x19,0x90,0x80,0x78,0x00,0x10,0x08,0x81,0x44,0x21,0x04,0x8c,0xff}; const unsigned char KP_table[49]={PB,PB,PM,PM,PS,ZO,ZO,PB,PB,PM,PS,PS,ZO,NS,PM,PM,PM,PS,ZO,NS,NS,PM,PM,PS,ZO,NS,NM,NM,PS,PS,ZO,NS,NS,NM,NM,PS,ZO,NS,NM,NM,NM,NB,ZO,ZO,NM,NM,NM,NB,NB}; const unsigned char KI_table[49]={NB,NB,NM,NM,NS,ZO,ZO,NB,NB,NM,NS,NS,ZO,ZO,NB,NM,NS,NS,ZO,PS,PS,NM,NM,NS,ZO,PS,PM,PM,NM,NS,ZO,PS,PS,PM,PB,ZO,ZO,PS,PS,PM,PB,PB,ZO,ZO,PS,PM,PM,PB,PB}; const unsigned char KD_table[49]={PS,NS,NB,NB,NB,NM,NS,PS,NS,NB,NM,NM,NS,ZO,ZO,NS,NM,NM,NS,NS,ZO,ZO,NS,NS,NS,NS,NS,ZO,ZO,ZO,ZO,ZO,ZO,ZO,ZO,PB,NS,PS,PS,PS,PS,PB,PB,PM,PM,PM,PS,PS,PB}; #pragma data:data //设置数据区回到数据储存器 /********************************************************* 延时函数 *********************************************************/ void delay_us(int time) //微秒级延时 { do time--; while (time>1); } void delay_ms(unsigned int time) //毫秒级延时 { while (time!=0) { delay_us(1000); time--; } } /************************************************************ 中断显示初始化 TIMER2 initialize - prescale:1024 WGM: Normal desired value: 10mSec actual value: 9.984mSec (0.2%) *************************************************************/ void timer2_init(void) { TCCR2 = 0x00; //stop ASSR = 0x00; //set async mode TCNT2 = 0xB2; //setup OCR2 = 0x4E; TCCR2 = 0x07; //start DDRB=0xff; //PC口为推挽1输出 PORTB=0xff; //PC口内部上拉 DDRD|=0xf0; PORTD&=0x1f; //关闭LED } /*********************************************** 中断显示 *************************************************/ #pragma interrupt_handler timer2_ovf_isr:5 void timer2_ovf_isr(void) { unsigned char i; static unsigned k; SEI(); TCNT2 = 0xB2; //reload counter value if (k1==0) { for(i=0;i<3;i++) { PORTB=led_buff[i]; PORTD|=(1<<(i+5));//待显示的位置1 delay_ms(1); PORTD&=0x1f; //关闭LED k=0; } } } void shanshuo(void) { if(kadc_rel) { if (kk2<500) kk2+=3; else kk2=500; } if ((tmp-1)>adc_rel) { if (kk2<500) kk2+=3; else kk2=500; } /*if ((tmp-2)>adc_rel) { if (kk2<600) kk2+=3; else kk2=600; }*/ if (tmp10) kk2-=3; else kk2=10; } if ((tmp+1)10) kk2-=3; else kk2=10; } /*if ((tmp+2)10) kk2-=3; else kk2=10; } /*if (tmp>adc_rel) { if (Ki<200) Ki+=4; else Ki=400; } if (tmp0) Ki-=4; else Ki=0; } */ } /******************************************************* PID函数 ********************************************************/ void pidcalc(void) { signed long KPP; signed long KII; signed long KDD; signed int i; signed char j; if(key1==0) { error0=tmp-adc_rel; j=error0-error1; i=7*(3+error0)+(3+j); if(i<49) { if (i>0) { Kp=KP_table[i]; Ki=KI_table[i]; Kd=KD_table[i]; } } //输出 if ((tmp-15)adc_rel) //比设定高时关PID { KPP=Kp*(error0-error1); //比例 KII=error0*Ki; //积分 KDD=Kd*(error0-(2*error1)+error2); //微分 kk1=(KPP+KII+KDD)*4+kk2; if(kk1<0x3ef) { if (kk1>=10) OCR1A=kk1; else OCR1A=0; } else { OCR1A=0x3ff; } /*if((tmp-2)>adc_rel) { if(OCR1A<500) OCR1A+=20; else OCR1A=500; }*/ } else { //if (tmp50) OCR1A-=20; // else OCR1A=50; OCR1A=0; // } } } else { OCR1A=0x3ff; } error2=error1; error1=error0; } } /*********************************************** ADC初始化 ************************************************/ void adc_init(void) { DDRC=0x00; PORTC=0X00; ADCSRA=0X00; ADMUX=(1<