// Copyright 2006 Yamane Akira //ICC-AVR application builder : 2005/09/23 14:30:07 // Target : M48 // Crystal: 1.0000Mhz #include #include unsigned char row_data, col_data, stage; void port_init(void) { PORTB = 0x0F; DDRB = 0xF0; PORTC = 0x7F; DDRC = 0x7F; PORTD = 0xFF; DDRD = 0xFF; } //TIMER0 initialize - prescale:256 // WGM: Normal // desired value: 10mSec // actual value: 9.984mSec (0.2%) void timer0_init(void) { TCCR0B = 0x00; //stop TCNT0 = 0xD9; //set count TCCR0A = 0x00; TCCR0B = 0x00; //stop timer } #pragma interrupt_handler timer0_ovf_isr:17 void timer0_ovf_isr(void) { TCNT0 = 0xD9; //set count TCCR0B = 0x04; //start timer if (stage == 0x00) row_data_r(); else if (stage == 0x01) col_data_r(); else if (stage == 0x02) sw_off_chk(); else stage = 0xFF; } unsigned char swin2hex(unsigned char indata) { unsigned char value; switch (indata) { case 0b11101110: value = 0x00; break; case 0b11101101: value = 0x01; break; case 0b11101011: value = 0x02; break; case 0b11100111: value = 0x03; break; case 0b11011110: value = 0x04; break; case 0b11011101: value = 0x05; break; case 0b11011011: value = 0x06; break; case 0b11010111: value = 0x07; break; case 0b10111110: value = 0x08; break; case 0b10111101: value = 0x09; break; case 0b10111011: value = 0x0A; break; case 0b10110111: value = 0x0B; break; case 0b01111110: value = 0x0C; break; case 0b01111101: value = 0x0D; break; case 0b01111011: value = 0x0E; break; case 0b01110111: value = 0x0F; break; } return value; } void row_data_r(void) { row_data = PINB | 0xF0; PORTB = row_data; DDRB = ~row_data; stage = 0x01; } void col_data_r(void) { col_data = PINB; PORTB = 0x0F; DDRB = 0xF0; stage = 0x02; PORTD = ~swin2hex(col_data); } void sw_off_chk(void) { if (PINB != 0x0F) stage = 0x02; else stage = 0xFF; } #pragma interrupt_handler pcint0_isr:4 void pcint0_isr(void) { PCMSK0 = 0x00; TCNT0 = 0xD9; TCCR0B = 0x04; //start timer PORTB = 0x0F; DDRB = 0xF0; stage = 0x00; } //call this routine to initialize all peripherals void init_devices(void) { //stop errant interrupts until set up CLI(); //disable all interrupts port_init(); timer0_init(); MCUCR = 0x00; EICRA = 0x00; //extended ext ints EIMSK = 0x00; TIMSK0 = 0x01; //timer 0 interrupt sources TIMSK1 = 0x00; //timer 1 interrupt sources TIMSK2 = 0x00; //timer 2 interrupt sources PCMSK0 = 0x0F; //pin change mask PCNT0..3 Enabled PCMSK1 = 0x00; //pin change mask 1 PCMSK2 = 0x00; //pin change mask 2 PCICR = 0x01; //pin change enable PRR = 0x00; //power controller SEI(); //re-enable interrupts //all peripherals are now initialized } // void main(void) { init_devices(); stage = 0xFF; while(1) { SMCR =0x01; asm("sleep\n"); if (stage ==0xFF) { PCMSK0 = 0x0F; TCCR0B = 0x00; //stop timer } } }