/* inv.c Programa que emula uma calculadora Atividae 2 MC 404 1º Sem 2011 Prof Célio G Atualizado em: 16 Maio 2011 ***************************************************************************************************/ #include #include #include // biblioteca para tratar dados na area de programa //#define _BV(bit) (1<< (bit)) unsigned char temp; //unsigned char lcdinput; int strlen(char *); // somente para o compilador não emitir warnings! char message1[] PROGMEM= "Press any key(1-16)"; // define uma cadeia C na área de programa char message2[] PROGMEM = "You pressed key:"; char message3[] PROGMEM = "Comando recebido:"; char message4[] PROGMEM = "Caracteres demais"; char buf[20] __attribute__((section("*.noinit"))); // __attribute__((section("*.noinit"))); // qdo não queremos inicializar variavel global; char * p=buf; #define TDELAY 1 // Obs: _delay_loop_2(1000) delays 4ms on a 1 MHz CPU #define ENABLE 0 #define RS 1 #define RW 2 void lcd_busy(){ PORTC |= _BV(RW); PORTC &= ~_BV(RS); DDRD= 0xff; DDRD= 0x00; PORTD= 0x00; while (1){ PORTC |= _BV(ENABLE); temp= PORTC; PORTC &= ~_BV(ENABLE); if (bit_is_clear(temp,7)) break; } DDRD= 0xff; } void lcd_cmd(char lcdinput){ PORTC &= ~(_BV(RS) | _BV(RW)); //PORTC &= ~(_BV(RW)); PORTC |= _BV(ENABLE); PORTD= lcdinput; PORTC &= ~(_BV(ENABLE)); } void lcd_write(char lcdinput){ //PORTC |= _BV(RS); PORTC &= ~(_BV(RW)); PORTC |= (_BV(ENABLE) | _BV(RS)); PORTD= lcdinput; PORTC &= ~_BV(ENABLE); } void writemsg(char * msg){ char * getbyte= msg; while(1){ temp= pgm_read_byte(getbyte++); if (!temp) break; lcd_write(temp); lcd_busy(); } } void writemsgram(char * msg){ char * p= msg; while(*p !=0){ lcd_write(*p++); lcd_busy(); } } void lcdinit(){ DDRD= 0xff; DDRC=0xff; lcd_cmd(0x38); // 8 bit mode 2 line LCD, blink cursor default lcd_busy(); lcd_cmd(1); // clear screen lcd_busy(); lcd_cmd(2); // cursor home command lcd_busy(); } void delay(int val){ //_delay_ms(20); _delay_loop_2(val); } unsigned char check_keys(){ while (1){ PINB= 0xff; delay(TDELAY); PORTB= 0b11101111; //col1 delay(TDELAY*1500); // para contotnar bug de seleção na col 3 if (bit_is_clear(PINB,PB0)) return ('1'); else if (bit_is_clear(PINB,PB1)) return ('4'); else if (bit_is_clear(PINB,PB2)) return ('7'); else if (bit_is_clear(PINB,PB3)) return ('C'); PORTB= 0b11011111; //col2 delay(TDELAY); if (bit_is_clear(PINB,PB0)) return ('2'); else if (bit_is_clear(PINB,PB1)) return ('5'); else if (bit_is_clear(PINB,PB2)) return ('8'); else if (bit_is_clear(PINB,PB3)) return ('0'); PORTB= 0b10111111; //col3 delay(TDELAY); if (bit_is_clear(PINB,PB0)) return ('3'); else if (bit_is_clear(PINB,PB1)) return ('6'); else if (bit_is_clear(PINB,PB2)) return ('9'); else if (bit_is_clear(PINB,PB3)) return ('E'); PORTB= 0b01111111; //col4 delay(TDELAY); if (bit_is_clear(PINB,PB0)) return ('A'); else if (bit_is_clear(PINB,PB1)) return ('S'); else if (bit_is_clear(PINB,PB2)) return ('M'); else if (bit_is_clear(PINB,PB3)) return ('D'); } } int store (char key){ //armazena caracter no buffer buf if (p==buf+20) return 0; if (key== 'E'){ *p=0; //insira terminador de cadeia return 2; } *p++= key; // armazena caracter digitado return 1; } int main(){ unsigned char key, res; p=buf; lcdinit(); DDRB= 0b11110000; PORTB= 0b00001111; writemsg(message1); while(1){ lcd_cmd(0xc0); // go to beginning of 2nd line lcd_busy(); key= check_keys(); writemsg(message2); lcd_write (key); res= store(key); if (res==1) continue; lcd_cmd(1); // clear screen, go to beginning of 1st line lcd_busy(); if (res==2) { writemsg(message3); lcd_cmd(0xc0); lcd_busy(); writemsgram(buf); } else if (res == 0){ writemsg(message4); } p=buf; } }