lcd.c (7915B)
1 #include <avr/io.h> //standard AVR header 2 #define F_CPU 16000000UL // THE CPU FREQUENCY 3 #include <util/delay.h> //delay header 4 #include <avr/interrupt.h> //interrupt header 5 #include <stdlib.h> 6 7 #define LCD_DPRT PORTD //LCD DATA PORT 8 #define LCD_DDDR DDRD //LCD DATA DDR 9 #define LCD_DPIN PIND //LCD DATA PIN 10 #define LCD_CPRT PORTB //LCD COMMANDS PORT 11 #define LCD_CDDR DDRB //LCD COMMANDS DDR 12 #define LCD_CPIN PINB //LCD COMMANDS PIN 13 #define LCD_RS 0 //LCD RS 14 #define LCD_EN 1 //LCD EN 15 16 // Define your buffer sizes 17 #define SERIAL_BUFFER_SIZE 20 18 #define NOTES_BUFFER_SIZE 20 19 20 // Global variables 21 char serialBuffer[SERIAL_BUFFER_SIZE]; 22 char notesBuffer[NOTES_BUFFER_SIZE]; 23 int serialIndex = 0; 24 int notesIndex = 0; 25 volatile int buttonState = 0; // Holds the state of all buttons 26 unsigned char songBuffer[1024]; 27 int count = 0; 28 29 void 30 usart_init(void) 31 { 32 // 9600 bps, RX enabled 33 UBRR0 = 103; 34 UCSR0B = 1 << RXEN0; 35 UCSR0C = (1 << UCSZ01) | (1 << UCSZ00); 36 } 37 38 char 39 getNote(void) 40 { 41 while (!(UCSR0A & (1 << RXC0))); 42 43 unsigned char c = UDR0; 44 45 // convert 0-9 to ascii character 46 if (c <= 9) 47 c += '0'; 48 // convert to capital hex 49 else if (c >= 0xa && c <= 0xf) 50 c = c - 0xa + 'A'; 51 52 return c; 53 } 54 // 55 void lcd_putValue(unsigned char val) 56 { 57 LCD_DPRT &= 0x0F; 58 LCD_DPRT |= (val & 0xF0); //send cmnd to data port 59 LCD_CPRT |= (1 << LCD_EN); //EN = 1 for H-to-L pulse 60 _delay_us(1); //wait to make enable wide 61 LCD_CPRT &= ~(1 << LCD_EN); //EN = 0 for H-to-L pulse 62 _delay_us(100); //wait to make enable wide 63 LCD_DPRT &= 0x0F; 64 LCD_DPRT |= val << 4; //send cmnd to data port 65 LCD_CPRT |= (1 << LCD_EN); //EN = 1 for H-to-L pulse 66 _delay_us(1); //wait to make enable wide 67 LCD_CPRT &= ~(1 << LCD_EN); //EN = 0 for H-to-L pulse 68 _delay_us(100); //wait to make enable wide 69 } 70 71 //******************************************************* 72 void lcdCommand(unsigned char cmnd) 73 { 74 LCD_CPRT &= ~(1 << LCD_RS); //RS = 0 for command 75 lcd_putValue(cmnd); 76 } 77 78 //******************************************************* 79 void lcdData(unsigned char data) 80 { 81 LCD_CPRT |= (1 << LCD_RS); //RS = 1 for data 82 lcd_putValue(data); 83 } 84 85 void lcd_clear() 86 { 87 lcdCommand(0x01); 88 _delay_us(1700); 89 } 90 91 void lcd_showCursor() 92 { 93 lcdCommand(0x0E); 94 _delay_us(50); 95 } 96 97 void lcd_hideCursor() 98 { 99 lcdCommand(0x0C); 100 _delay_us(50); 101 } 102 103 //******************************************************* 104 void lcd_init() 105 { 106 LCD_DDDR |= 0xF0; 107 LCD_CDDR |= (1 << LCD_RS) | (1 << LCD_EN); 108 LCD_CPRT &= ~(1 << LCD_EN); //LCD_EN = 0 109 _delay_us(2000); //wait for init. 110 lcdCommand(0x33); //send $33 for init. 111 lcdCommand(0x32); //send $32 for init 112 lcdCommand(0x28); //init. LCD 2 line,5*7 matrix 113 lcdCommand(0x0e); //display on, cursor on 114 lcdCommand(0x06); //shift cursor right 115 lcd_clear(); 116 } 117 118 //******************************************************* 119 void lcd_gotoxy(unsigned char x, unsigned char y) 120 { 121 unsigned char firstCharAdr[] = { 0x80, 0xC0, 0x94, 0xD4 }; //Table 12-4 122 lcdCommand(firstCharAdr[y - 1] + x - 1); 123 _delay_us(100); 124 } 125 126 //******************************************************* 127 void lcd_print(char *str) 128 { 129 unsigned char i = 0; 130 while (str[i] != 0) //while it is not end of string 131 { 132 lcdData(str[i]); 133 i++; 134 } 135 } 136 137 char getSerialData() { 138 // Read serial data and return it 139 return ' '; 140 } 141 142 void setup() { 143 // Initialize Serial communication 144 // Initialize LCD 145 // Initialize buttons as inputs 146 // Set pins A4 and A5 as inputs with pull-up resistors enabled 147 DDRC &= ~((1 << DDC4) | (1 << DDC5)); 148 PORTC |= (1 << PORTC4) | (1 << PORTC5); 149 150 // Enable Pin Change Interrupt on pins PC4 and PC5 151 PCMSK1 |= (1 << PCINT12) | (1 << PCINT13); // Enable PCINT for pins PC4 and PC5 152 PCICR |= (1 << PCIE1); // Enable Pin Change Interrupt 1 153 sei(); // Enable global interrupts 154 } 155 156 ISR(PCINT1_vect) { 157 // Update button state when any pin changes state 158 for (unsigned char i = 4; i <= 5; i++) { 159 if (PINC & (1 << i)) { 160 if(buttonState == 0) 161 buttonState = i; 162 else 163 buttonState = 0; 164 break; 165 } 166 } 167 } 168 169 void displayNotes() { 170 char circularBuffer[16]; 171 static int bufferIndex = 0; 172 173 lcd_clear(); 174 lcd_gotoxy(6, 2); 175 lcd_print("PLAYING"); 176 _delay_ms(1000); 177 lcd_clear(); 178 _delay_ms(1000); 179 for(int k = 0; k < count) { 180 unsigned char randomValue = songBuffer[k]; 181 182 if (bufferIndex == 16) { 183 184 // Remove the first value and shift other values down 185 for (int i = 0; i < 16 - 1; i++) { 186 circularBuffer[i] = circularBuffer[i + 1]; 187 } 188 // Add the new value at the end 189 circularBuffer[16 - 1] = randomValue; 190 } else { 191 // Add the new value to the buffer 192 circularBuffer[bufferIndex] = randomValue; 193 bufferIndex++; 194 } 195 196 lcd_clear(); 197 for (int i = 0; i <= bufferIndex - 1; i++) { 198 char singleChar[2] = {circularBuffer[i], '\0'}; 199 lcd_gotoxy(17-bufferIndex+i ,1); 200 lcd_print(singleChar); // Print the single character 201 lcd_gotoxy(6,2); 202 lcd_print("PLAYING"); 203 } 204 205 _delay_ms(500); 206 } 207 buttonState = 0; 208 bufferIndex = 0; 209 lcd_clear(); 210 } 211 212 213 void displaySerialData() { 214 char circularBuffer[16]; 215 static int bufferIndex = 0; 216 lcd_clear(); 217 lcd_gotoxy(3, 2); 218 lcd_print("RECORDING"); 219 _delay_ms(1000); 220 lcd_clear(); 221 _delay_ms(1000); 222 while (buttonState == 5) { 223 unsigned char randomValue = getNote(); 224 count = 0; 225 songBuffer[count] = randomValue; 226 count++; 227 228 if (bufferIndex == 16) { 229 // Remove the first value and shift other values down 230 for (int i = 0; i < 16 - 1; i++) { 231 circularBuffer[i] = circularBuffer[i + 1]; 232 } 233 // Add the new value at the end 234 circularBuffer[16 - 1] = randomValue; 235 } else { 236 // Add the new value to the buffer 237 circularBuffer[bufferIndex] = randomValue; 238 bufferIndex++; 239 } 240 241 lcd_clear(); 242 lcd_gotoxy(1,1); 243 for (int i = 0; i <= bufferIndex-1; i++) { 244 char singleChar[2] = {circularBuffer[bufferIndex- 1 - i], '\0'}; 245 lcd_gotoxy(i+1,1); 246 lcd_print(singleChar); // Print the single character 247 lcd_gotoxy(3,2); 248 lcd_print("RECORDING"); 249 } 250 251 //_delay_ms(1000); 252 } 253 bufferIndex = 0; 254 lcd_clear(); 255 } 256 257 void displayPiano() { 258 char circularBuffer[16]; 259 static int bufferIndex = 0; 260 lcd_clear(); 261 lcd_gotoxy(6, 2); 262 lcd_print("PIANO"); 263 _delay_ms(1000); 264 lcd_clear(); 265 _delay_ms(1000); 266 while (buttonState == 0) { 267 unsigned char randomValue = getNote(); 268 269 if (bufferIndex == 16) { 270 // Remove the first value and shift other values down 271 for (int i = 0; i < 16 - 1; i++) { 272 circularBuffer[i] = circularBuffer[i + 1]; 273 } 274 // Add the new value at the end 275 circularBuffer[16 - 1] = randomValue; 276 } else { 277 // Add the new value to the buffer 278 circularBuffer[bufferIndex] = randomValue; 279 bufferIndex++; 280 } 281 282 lcd_clear(); 283 lcd_gotoxy(1,1); 284 for (int i = 0; i <= bufferIndex-1; i++) { 285 char singleChar[2] = {circularBuffer[bufferIndex- 1 - i], '\0'}; 286 lcd_gotoxy(i+1,1); 287 lcd_print(singleChar); // Print the single character 288 lcd_gotoxy(6, 2); 289 lcd_print("PIANO"); 290 } 291 292 //_delay_ms(1000); 293 } 294 bufferIndex = 0; 295 lcd_clear(); 296 } 297 298 //******************************************************* 299 int main(void) { 300 lcd_init(); 301 lcd_hideCursor(); 302 usart_init(); 303 setup(); 304 lcd_clear(); 305 while (1) { 306 // Check button state and perform actions accordingly 307 if (buttonState == 5) { 308 displaySerialData(); 309 310 } else if (buttonState == 4) { 311 displayNotes(); 312 } 313 else { 314 displayPiano(); 315 } 316 } 317 return 0; 318 }