voltmeter
changeset 1:40b150fedb0e tip
foo
author | John Tsiombikas <nuclear@member.fsf.org> |
---|---|
date | Mon, 28 Jan 2013 09:52:15 +0200 |
parents | d26d73ef2db7 |
children | |
files | voltmeter.c |
diffstat | 1 files changed, 77 insertions(+), 22 deletions(-) [+] |
line diff
1.1 --- a/voltmeter.c Sun Jan 27 10:11:40 2013 +0200 1.2 +++ b/voltmeter.c Mon Jan 28 09:52:15 2013 +0200 1.3 @@ -3,6 +3,7 @@ 1.4 1.5 #include <stdio.h> 1.6 #include <avr/io.h> 1.7 +#include <avr/interrupt.h> 1.8 #include <util/delay.h> 1.9 1.10 /* hardware setup 1.11 @@ -12,6 +13,7 @@ 1.12 * bit 1: R/W 1.13 * bit 2: E 1.14 */ 1.15 +#define LCD_BUS_WIDTH 8 1.16 1.17 #define BIT_RS 3 1.18 #define BIT_RW 4 1.19 @@ -57,10 +59,23 @@ 1.20 1.21 FILE stream_lcd = FDEV_SETUP_STREAM(lcd_stream_write, NULL, _FDEV_SETUP_WRITE); 1.22 1.23 +int bn_pressed; 1.24 +unsigned char foo; 1.25 + 1.26 int main(void) 1.27 { 1.28 stdout = stderr = &stream_lcd; 1.29 1.30 + /* port B[0] out -> backlight 1.31 + * port B[1] in <- backlight switch 1.32 + */ 1.33 + DDRB = 1; 1.34 + PORTB = 0xfe; /* enable all pullups, leave bit0 -> 0 (backlight) */ 1.35 + /* enable PIN B1 interrupt */ 1.36 + PCMSK0 = 2; 1.37 + PCICR = 1; 1.38 + sei(); /* enable interrupts */ 1.39 + 1.40 DDRC = 0xfe; 1.41 PORTC = 0; /* disable pullups */ 1.42 1.43 @@ -74,18 +89,36 @@ 1.44 long val = read_adc(); 1.45 double ref = 1.08 * 1.47 / 0.47; 1.46 double voltage = ref * (double)val / (double)1024; 1.47 + 1.48 lcd_clear(); 1.49 1.50 if(val == 1023) { 1.51 - printf("*** RANGE *** "); 1.52 + printf("*** RANGE ***"); 1.53 } else { 1.54 - printf("%.2f volts ", voltage); 1.55 + printf("%.2f volts", voltage); 1.56 + } 1.57 + 1.58 + /* check if the backlight button was pressed */ 1.59 + if(bn_pressed & 1) { 1.60 + if(PORTB & 1) { 1.61 + PORTB &= 0xfe; 1.62 + } else { 1.63 + PORTB |= 1; 1.64 + } 1.65 + bn_pressed = 0; 1.66 } 1.67 _delay_ms(500); 1.68 } 1.69 return 0; 1.70 } 1.71 1.72 + 1.73 +ISR(PCINT0_vect) { 1.74 + if((PINB & 2) == 0) { 1.75 + bn_pressed = 1; 1.76 + } 1.77 +} 1.78 + 1.79 void setup_adc(void) 1.80 { 1.81 /* disable digital input buffer on ADC0 pin */ 1.82 @@ -114,10 +147,39 @@ 1.83 return low | ((long)ADCH << 8); 1.84 } 1.85 1.86 +void lcd_write_byte(unsigned char byte) 1.87 +{ 1.88 +#if LCD_BUS_WIDTH == 8 1.89 + DDRD = 0xff; 1.90 + PORTD = byte; 1.91 +#else 1.92 + DDRD = (DDRD & 0xf0) | 0xf; 1.93 + 1.94 + PORTD = (PORTD & 0xf0) | ((byte >> 4) & 0xf); 1.95 + PORTD = (PORTD & 0xf0) | (byte & 0xf); 1.96 +#endif 1.97 +} 1.98 + 1.99 +unsigned char lcd_read_byte(void) 1.100 +{ 1.101 +#if LCD_BUS_WIDTH == 8 1.102 + DDRD = 0; 1.103 + PORTD = 0; /* disable pull-ups */ 1.104 + 1.105 + return PIND; 1.106 +#else 1.107 + unsigned char byte; 1.108 + 1.109 + DDRD = DDRD & 0xf0; 1.110 + PORTD &= 0xf0; /* disable pull-ups */ 1.111 + 1.112 + byte = (PIND & 0xf) << 4; 1.113 + return byte | (PIND & 0xf); 1.114 +#endif 1.115 +} 1.116 + 1.117 void lcd_init(void) 1.118 { 1.119 - DDRD = 0x0f; /* port d[0, 3] -> output */ 1.120 - 1.121 /* make sure the display has time to boot up */ 1.122 _delay_ms(20); 1.123 1.124 @@ -125,55 +187,53 @@ 1.125 1.126 clear_bit(BIT_E); 1.127 clear_bit(BIT_RS); 1.128 - PORTD = CMD_FUNC | FUNC_BUS_8BIT | FUNC_LINES_2 | FUNC_FONT_5x8; 1.129 +#if LCD_BUS_WIDTH == 8 1.130 + lcd_write_byte(CMD_FUNC | FUNC_BUS_8BIT | FUNC_LINES_2 | FUNC_FONT_5x8); 1.131 +#else 1.132 + lcd_write_byte(CMD_FUNC | FUNC_BUS_4BIT | FUNC_LINES_2 | FUNC_FONT_5x8); 1.133 +#endif 1.134 enable(); 1.135 lcd_wait_busy(); 1.136 1.137 clear_bit(BIT_RS); 1.138 - PORTD = CMD_ONOFF | ONOFF_DISP | ONOFF_CURSOR; 1.139 + lcd_write_byte(CMD_ONOFF | ONOFF_DISP); 1.140 enable(); 1.141 lcd_wait_busy(); 1.142 1.143 clear_bit(BIT_RS); 1.144 - PORTD = CMD_ENTRY_MODE | (1 << 1); 1.145 + lcd_write_byte(CMD_ENTRY_MODE | (1 << 1)); 1.146 enable(); 1.147 lcd_wait_busy(); 1.148 } 1.149 1.150 void lcd_clear(void) 1.151 { 1.152 - DDRD = 0xff; /* port d -> output */ 1.153 - 1.154 clear_bit(BIT_RW); 1.155 1.156 clear_bit(BIT_E); 1.157 clear_bit(BIT_RS); 1.158 - PORTD = CMD_CLEAR; 1.159 + lcd_write_byte(CMD_CLEAR); 1.160 enable(); 1.161 lcd_wait_busy(); 1.162 } 1.163 1.164 void lcd_set_cursor_addr(unsigned int addr) 1.165 { 1.166 - DDRD = 0xff; /* port d -> output */ 1.167 - 1.168 clear_bit(BIT_RW); 1.169 1.170 clear_bit(BIT_E); 1.171 clear_bit(BIT_RS); 1.172 - PORTD = CMD_DDRAM_ADDR | addr; 1.173 + lcd_write_byte(CMD_DDRAM_ADDR | addr); 1.174 enable(); 1.175 lcd_wait_busy(); 1.176 } 1.177 1.178 void lcd_putchar(char c) 1.179 { 1.180 - DDRD = 0xff; /* port d -> output */ 1.181 - 1.182 clear_bit(BIT_RW); 1.183 1.184 set_bit(BIT_RS); 1.185 - PORTD = c; 1.186 + lcd_write_byte(c); 1.187 enable(); 1.188 lcd_wait_busy(); 1.189 } 1.190 @@ -196,9 +256,6 @@ 1.191 { 1.192 unsigned char data; 1.193 1.194 - DDRD = 0; /* port d -> input */ 1.195 - PORTD = 0; /* disable pull-ups */ 1.196 - 1.197 do { 1.198 NSDELAY(); 1.199 clear_bit(BIT_E); 1.200 @@ -209,13 +266,11 @@ 1.201 NSDELAY(); 1.202 set_bit(BIT_E); 1.203 NSDELAY(); 1.204 - data = PIND; 1.205 + data = lcd_read_byte(); 1.206 clear_bit(BIT_E); 1.207 clear_bit(BIT_RW); 1.208 1.209 } while(data & (1 << 7)); 1.210 - 1.211 - DDRD = 0xff; /* port d -> output */ 1.212 } 1.213 1.214 static void enable(void)