Block diagram ของฝั่งควบคุมอุณหภูมิ
Code Microcontroller (Temperature)
#include #include #include
#define NTIMER 4
//loop1:SW reading //loop2:adc from sensors // feedback //loop3:7segment //loop4:stepping motor condition
volatile char TmrEnb[NTIMER] = {1, 1, 1, 1}; volatile char TmrMod[NTIMER] = {1, 1, 1, 1}; volatile int TmrRel[NTIMER] = {100, 50, 4, 150}; //0.5 ms volatile int TmrCnt[NTIMER] = {100, 50, 4, 150}; volatile char TmrRdy[NTIMER] = {0, 0, 0, 0}; volatile char TmrErr[NTIMER] = {0, 0, 0, 0};
void Hardware_init(void); void ADC_init(void); void Timer1_init(void);
int main() { unsigned char segment_ndot[10] = {0x00,0x10,0x20,0x30,0x40,0x50,0x60,0x70,0x80,0x90}; //unsigned char step[4] = {0x03,0x18,0xC0,0x81}; unsigned char step[4] = {0x01,0x02,0x40,0x80}; unsigned char ch_adc=0,finish=0x00; unsigned int temp=0,sumadc=0,avradc=0; unsigned int adc[3];int nadc1 =0; unsigned char bcd[3]; float real_temp=0; float set_temp=0; float dif_temp=0; float cmp_temp=0; int flag = 0x00; int i=0;int j=0;int s=0; int z=1;int y=7;int x=5; int stepenable =0; float adcback=0; Hardware_init(); ADC_init(); Timer1_init();
sei(); while(1) { ADMUX = (0< ADCSRA = (1 << ADEN); ADCSRA |= (0 << ADPS2)|(1 << ADPS1)|(1 << ADPS0); cli();// disable interrupt if(TmrRdy[0] == 1) { TmrRdy[0] = 0; sei();
if(stepenable==0) { if(((PINA&0x08)==0x08)&&(flag == 0x00)) { flag = 0x01; } else if(((PINA&0x08)==0x00)&&(flag == 0x01)) { flag = 0x00; x++; if(x>9) { x = 0;y++; if(y>9) { y=0;z++; } } else if(set_temp>244) { z=1;y=7;x=5; } } else if(((PINA&0x10)==0x10)&&(flag == 0x00)) { flag = 0x02; } else if(((PINA&0x10)==0x00)&&(flag == 0x02)) { flag = 0x00; y++; if(y>9) { y = 0;z++;if(z>2){z=1;} } else if(set_temp>235) { z=1;y=7;x=5; } } else if((PINA&0x20)==0x20) { stepenable=1; } else{ } } else if((PINA&0x80)==0x80) { stepenable =0; } else{ }
set_temp = ((z*100)+(y*10)+x); } else if(TmrRdy[1] == 1) { TmrRdy[1]=0; sei(); for(ch_adc=1;ch_adc<3;ch_adc++) {
ADMUX = (0< ADCSRA |= (1< while((ADCSRA&0x10)!=0x10);
adc[ch_adc] = ADCW; } sumadc = sumadc + adc[1]; nadc1++; if(nadc1==15) { nadc1=0; } else{ } if(nadc1==0) { avradc = sumadc/15; sumadc=0; } else{ }
if(avradc>=204) { real_temp = (float)((float)(0.0609*avradc) - 12.439); } else { real_temp = 0; } } else if(TmrRdy[2] == 1) { TmrRdy[2] = 0; sei(); temp=(unsigned int)(real_temp*10); for(i = 0; i < 3; i++) { bcd[i] = temp%10; temp = temp/10; } if(j == 0) { PORTB = 0b00000100|finish; PORTB |= segment_ndot[bcd[0]]; PORTD = 0b00000100; PORTD |= segment_ndot[x]; j++; } else if(j == 1) { PORTB = 0b00000010|finish; PORTB |= segment_ndot[bcd[1]]; PORTD = 0b00001010; PORTD |= segment_ndot[y]; j++; } else if(j == 2) { PORTB = 0b00000001|finish; PORTB |= segment_ndot[bcd[2]]; PORTD = 0b00000001; PORTD |= segment_ndot[z]; j=0; } else{}
PORTC = sbi(PORTC,3); } else if(TmrRdy[3] == 1) { TmrRdy[3] = 0; sei(); dif_temp = (float)(real_temp - (float)(set_temp/10)); if(stepenable==1) { if((dif_temp>2.5)&&(dif_temp<=12.5)) { cmp_temp = (float)(dif_temp*22.9376); } else if((dif_temp<=2.5)&&(dif_temp>0)) { cmp_temp = 57.344; } else if(dif_temp<=0) { cmp_temp = 0; stepenable =2; } else if(dif_temp>12.5) { cmp_temp = 286.72; } else{} } else if(stepenable==0) { cmp_temp = 0; finish = 0x00; } else if(stepenable==2) { cmp_temp =0; finish = 0x08; } adcback = adc[2];
if(cmp_temp-5>adcback) { PORTC = step[s]|0x08; s++; if(s>3) { s=0; } } else if(cmp_temp+5 { PORTC = step[s]|0x08; s--; if(s<0) { s=3; } } else if((cmp_temp+5>=adcback)&&(cmp_temp-5<=adcback)) { PORTC = 0x00; } else{} } else { sei(); } } return 0; }
void Hardware_init(void) { //PORTA is input //PORTB PORTC PORTD is output DDRA = 0x00; DDRB = 0xFF; DDRC = 0xFF; DDRD = 0xFF;
//clear PORT PORTB = 0x00; PORTC = 0x00; PORTD = 0x00; }
void ADC_init(void) { ADMUX = (0< ADCSRA = (1 << ADEN); ADCSRA |= (0 << ADPS2)|(1 << ADPS1)|(1 << ADPS0); }
void Timer1_init(void) { //Mode : CTC //TOP : OCR1A TCCR1A = (0 << WGM11)|(0 << WGM10); TCCR1B = (0 << WGM13)|(1 << WGM12);
//prescaler 8 010 001 = no prescaler TCCR1B |= (0 << CS12)|(1 << CS11)|(0 << CS10);
//8 MHz / 8 = 1 MHz //output compare interrupt is interval every 1 ms //1 MHz /500 = 2kHz ==>> 0.5ms /// 1000= 0x03E8 (in hex) OCR1AH = 0x01; OCR1AL = 0xF4; //Timer/Counter1 Output Compare A Match Interrupt Enable TIMSK = (1 << OCIE1A); }
ISR (TIMER1_COMPA_vect) { int k; for(k=0; k { if(TmrEnb[k] == 1) { TmrCnt[k]--; if(TmrCnt[k] == 0) { if(TmrRdy[k] == 1) { TmrErr[k] = 0; } else { TmrRdy[k] = 1; TmrCnt[k] = TmrRel[k]; if(TmrMod[k] == 0) { TmrEnb[k]=0; } } } } } }
back to circuit & code
|