Update lcd.c
adds graphic procedures
Dieser Commit ist enthalten in:
		
							Ursprung
							
								
									743d5ade88
								
							
						
					
					
						Commit
						77ee1b280c
					
				
							
								
								
									
										314
									
								
								lcd.c
									
									
									
									
									
								
							
							
						
						
									
										314
									
								
								lcd.c
									
									
									
									
									
								
							| @ -37,13 +37,20 @@ | |||||||
|  *  first dev-version only for I2C-Connection |  *  first dev-version only for I2C-Connection | ||||||
|  *  at ATMega328P like Arduino Uno |  *  at ATMega328P like Arduino Uno | ||||||
|  * |  * | ||||||
|  |  *  at GRAPHICMODE lib needs SRAM for display | ||||||
|  |  *  DISPLAY-WIDTH * DISPLAY-HEIGHT + 2 bytes | ||||||
|  */ |  */ | ||||||
| /* Standard ASCII 6x8 font */ |  | ||||||
| 
 | 
 | ||||||
| #include "lcd.h" | #include "lcd.h" | ||||||
| #include <avr/interrupt.h> |  | ||||||
| #include <string.h> | #include <string.h> | ||||||
| 
 | 
 | ||||||
|  | #if defined GRAPHICMODE | ||||||
|  | #include <stdlib.h> | ||||||
|  | static uint8_t displayBuffer[DISPLAYSIZE]; | ||||||
|  | uint16_t actualIndex = 0; | ||||||
|  | #endif | ||||||
|  | 
 | ||||||
|  | /* Standard ASCII 6x8 font */ | ||||||
| static const uint8_t ssd1306oled_font6x8 [] PROGMEM = { | static const uint8_t ssd1306oled_font6x8 [] PROGMEM = { | ||||||
|     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // sp
 |     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // sp
 | ||||||
|     0x00, 0x00, 0x00, 0x2f, 0x00, 0x00, // !
 |     0x00, 0x00, 0x00, 0x2f, 0x00, 0x00, // !
 | ||||||
| @ -177,7 +184,22 @@ const uint8_t init_sequence [] PROGMEM = {	// Initialization Sequence | |||||||
|      |      | ||||||
|      |      | ||||||
| }; | }; | ||||||
| 
 | void lcd_command(uint8_t cmd[], uint8_t size) { | ||||||
|  |     i2c_start(LCD_I2C_ADDR); | ||||||
|  |     i2c_byte(0x00);	// 0x00 for command, 0x40 for data
 | ||||||
|  |     for (uint8_t i=0; i<size; i++) { | ||||||
|  |         i2c_byte(cmd[i]); | ||||||
|  |     } | ||||||
|  |     i2c_stop(); | ||||||
|  | } | ||||||
|  | void lcd_data(uint8_t data[], uint16_t size) { | ||||||
|  |     i2c_start(LCD_I2C_ADDR); | ||||||
|  |     i2c_byte(0x40);	// 0x00 for command, 0x40 for data
 | ||||||
|  |     for (uint16_t i = 0; i<size; i++) { | ||||||
|  |         i2c_byte(data[i]); | ||||||
|  |     } | ||||||
|  |     i2c_stop(); | ||||||
|  | } | ||||||
| void lcd_init(uint8_t dispAttr){ | void lcd_init(uint8_t dispAttr){ | ||||||
|     i2c_init(); |     i2c_init(); | ||||||
|     uint8_t commandSequence[sizeof(init_sequence)+1]; |     uint8_t commandSequence[sizeof(init_sequence)+1]; | ||||||
| @ -191,22 +213,41 @@ void lcd_init(uint8_t dispAttr){ | |||||||
| void lcd_home(void){ | void lcd_home(void){ | ||||||
|     lcd_gotoxy(0, 0); |     lcd_gotoxy(0, 0); | ||||||
| } | } | ||||||
|  | void lcd_invert(uint8_t invert){ | ||||||
|  |     i2c_start(LCD_I2C_ADDR); | ||||||
|  |     uint8_t commandSequence[1]; | ||||||
|  |     if (invert == YES) { | ||||||
|  |         commandSequence[0] = 0xA7; | ||||||
|  |     } else { | ||||||
|  |         commandSequence[0] = 0xA7; | ||||||
|  |     } | ||||||
|  |     lcd_command(commandSequence, 1); | ||||||
|  | } | ||||||
|  | void lcd_set_contrast(uint8_t contrast){ | ||||||
|  |     uint8_t commandSequence[2] = {0x81, contrast}; | ||||||
|  |     lcd_command(commandSequence, sizeof(commandSequence)); | ||||||
|  | } | ||||||
|  | void lcd_puts(const char* s){ | ||||||
|  |     while (*s) { | ||||||
|  |         lcd_putc(*s++); | ||||||
|  |     } | ||||||
|  | } | ||||||
|  | void lcd_puts_p(const char* progmem_s){ | ||||||
|  |     register uint8_t c; | ||||||
|  |     while ((c = pgm_read_byte(progmem_s++))) { | ||||||
|  |         lcd_putc(c); | ||||||
|  |     } | ||||||
|  | } | ||||||
|  | #if defined TEXTMODE | ||||||
|  | void lcd_clrscr(void){ | ||||||
|  |     uint8_t clearLine[DISPLAY_WIDTH]; | ||||||
|  |     memset(clearLine, 0x00, DISPLAY_WIDTH); | ||||||
|  |     for (uint8_t j = 0; j < DISPLAY_HEIGHT/8; j++){ | ||||||
|  |         lcd_gotoxy(0,j); | ||||||
|  |         lcd_data(clearLine, sizeof(clearLine)); | ||||||
|          |          | ||||||
| void lcd_command(uint8_t cmd[], uint8_t size) { |  | ||||||
|     i2c_start(LCD_I2C_ADDR); |  | ||||||
|     i2c_byte(0x00);	// 0x00 for command, 0x40 for data
 |  | ||||||
|     for (uint8_t i=0; i<size; i++) { |  | ||||||
|         i2c_byte(cmd[i]); |  | ||||||
|     } |     } | ||||||
|     i2c_stop(); |     lcd_home(); | ||||||
| } |  | ||||||
| void lcd_data(uint8_t data[], uint16_t size) { |  | ||||||
|     i2c_start(LCD_I2C_ADDR); |  | ||||||
|     i2c_byte(0x40);	// 0x00 for command, 0x40 for data
 |  | ||||||
|     for (uint8_t i = 0; i<size; i++) { |  | ||||||
|         i2c_byte(data[i]); |  | ||||||
|     } |  | ||||||
|     i2c_stop(); |  | ||||||
| } | } | ||||||
| void lcd_gotoxy(uint8_t x, uint8_t y) { | void lcd_gotoxy(uint8_t x, uint8_t y) { | ||||||
|     if( x > (DISPLAY_WIDTH/6) || y > (DISPLAY_HEIGHT/8-1)) return;// out of display
 |     if( x > (DISPLAY_WIDTH/6) || y > (DISPLAY_HEIGHT/8-1)) return;// out of display
 | ||||||
| @ -218,17 +259,6 @@ void lcd_gotoxy(uint8_t x, uint8_t y){ | |||||||
| #endif | #endif | ||||||
|     lcd_command(commandSequence, sizeof(commandSequence)); |     lcd_command(commandSequence, sizeof(commandSequence)); | ||||||
| } | } | ||||||
| void lcd_clrscr(void){ |  | ||||||
|     uint8_t clearLine[DISPLAY_WIDTH]; |  | ||||||
|     memset(clearLine, 0x00, DISPLAY_WIDTH); |  | ||||||
|     for (uint8_t j = 0; j <= DISPLAY_HEIGHT/8-1; j++){ |  | ||||||
|         lcd_gotoxy(0,j); |  | ||||||
|         lcd_data(clearLine, sizeof(clearLine)); |  | ||||||
|          |  | ||||||
|     } |  | ||||||
|     lcd_home(); |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| void lcd_putc(char c){ | void lcd_putc(char c){ | ||||||
|     if((c > 127 || |     if((c > 127 || | ||||||
|         c < 32) && |         c < 32) && | ||||||
| @ -313,28 +343,216 @@ void lcd_putc(char c){ | |||||||
|     } |     } | ||||||
|     i2c_stop(); |     i2c_stop(); | ||||||
| } | } | ||||||
| void lcd_puts(const char* s){ | #elif defined GRAPHICMODE | ||||||
|     while (*s) { | void lcd_clrscr(void){ | ||||||
|         lcd_putc(*s++); |     memset(displayBuffer, 0x00, sizeof(displayBuffer)); | ||||||
|  | #if defined SSD1306 | ||||||
|  |     lcd_data(displayBuffer, sizeof(displayBuffer)); | ||||||
|  | #elif defined SH1106 | ||||||
|  |     for (uint8_t i=0; i <= DISPLAY_HEIGHT/8; i++) { | ||||||
|  |         uint8_t actualLine[DISPLAY_WIDTH]; | ||||||
|  |         for (uint8_t j=0; j< DISPLAY_WIDTH; j++) { | ||||||
|  |             actualLine[j]=displayBuffer[i*DISPLAY_WIDTH+j]; | ||||||
|         } |         } | ||||||
|  |         lcd_data(actualLine, sizeof(actualLine)); | ||||||
|  |         lcd_gotoxy(0, i); | ||||||
|     } |     } | ||||||
| void lcd_puts_p(const char* progmem_s){ | #endif | ||||||
|     register uint8_t c; |     lcd_home(); | ||||||
|     while ((c = pgm_read_byte(progmem_s++))) { |  | ||||||
|         lcd_putc(c); |  | ||||||
| } | } | ||||||
| } | void lcd_gotoxy(uint8_t x, uint8_t y){ | ||||||
| void lcd_invert(uint8_t invert){ |     if( x > (DISPLAY_WIDTH/6) || y > (DISPLAY_HEIGHT/8-1)) return;// out of display
 | ||||||
|     i2c_start(LCD_I2C_ADDR); |     x = x * 6;					// one char: 6 pixel width
 | ||||||
|     uint8_t commandSequence[1]; |     actualIndex = (x)+(y*DISPLAY_WIDTH); | ||||||
|     if (invert == YES) { | #if defined SSD1306 | ||||||
|         commandSequence[0] = 0xA7; |     uint8_t commandSequence[] = {0xb0+y, 0x21, x, 0x7f}; | ||||||
|     } else { | #elif defined SH1106 | ||||||
|         commandSequence[0] = 0xA7; |     uint8_t commandSequence[] = {0xb0+y, 0x21, 0x00+((2+x) & (0x0f)), 0x10+( ((2+x) & (0xf0)) >> 4 ), 0x7f}; | ||||||
|     } | #endif | ||||||
|     lcd_command(commandSequence, 1); |  | ||||||
| } |  | ||||||
| void lcd_set_contrast(uint8_t contrast){ |  | ||||||
|     uint8_t commandSequence[2] = {0x81, contrast}; |  | ||||||
|     lcd_command(commandSequence, sizeof(commandSequence)); |     lcd_command(commandSequence, sizeof(commandSequence)); | ||||||
| } | } | ||||||
|  | void lcd_putc(char c){ | ||||||
|  |     if((actualIndex+1)%127 != 0){ | ||||||
|  |         if((c > 127 || | ||||||
|  |             c < 32) && | ||||||
|  |            (c != 'ü' && | ||||||
|  |             c != 'ö' && | ||||||
|  |             c != '°' && | ||||||
|  |             c != 'ä' && | ||||||
|  |             c != 'ß' && | ||||||
|  |             c != 'Ü' && | ||||||
|  |             c != 'Ö' && | ||||||
|  |             c != 'Ä' ) ) return; | ||||||
|  |         switch (c) { | ||||||
|  |             case 'ü': | ||||||
|  |                 c = 95; // ü - 188
 | ||||||
|  |                 for (uint8_t i = 0; i < 6; i++) | ||||||
|  |                 { | ||||||
|  |                     displayBuffer[actualIndex+i] = pgm_read_byte(&ssd1306oled_font6x8[c * 6 + i]);	// print font to ram, print 6 columns
 | ||||||
|  |                 } | ||||||
|  |                 break; | ||||||
|  |             case 'ö': | ||||||
|  |                 c = 99; // ö
 | ||||||
|  |                 for (uint8_t i = 0; i < 6; i++) | ||||||
|  |                 { | ||||||
|  |                     displayBuffer[actualIndex+i] = pgm_read_byte(&ssd1306oled_font6x8[c * 6 + i]);	// print font to ram, print 6 columns
 | ||||||
|  |                 } | ||||||
|  |                 break; | ||||||
|  |             case '°': | ||||||
|  |                 c = 101; // °
 | ||||||
|  |                 for (uint8_t i = 0; i < 6; i++) | ||||||
|  |                 { | ||||||
|  |                     displayBuffer[actualIndex+i] = pgm_read_byte(&ssd1306oled_font6x8[c * 6 + i]);	// print font to ram, print 6 columns
 | ||||||
|  |                 } | ||||||
|  |                 break; | ||||||
|  |             case 'ä': | ||||||
|  |                 c = 97; // ä
 | ||||||
|  |                 for (uint8_t i = 0; i < 6; i++) | ||||||
|  |                 { | ||||||
|  |                     displayBuffer[actualIndex+i] = pgm_read_byte(&ssd1306oled_font6x8[c * 6 + i]);	// print font to ram, print 6 columns
 | ||||||
|  |                 } | ||||||
|  |                 break; | ||||||
|  |             case 'ß': | ||||||
|  |                 c = 102; // ß
 | ||||||
|  |                 for (uint8_t i = 0; i < 6; i++) | ||||||
|  |                 { | ||||||
|  |                     displayBuffer[actualIndex+i] = pgm_read_byte(&ssd1306oled_font6x8[c * 6 + i]);	// print font to ram, print 6 columns
 | ||||||
|  |                 } | ||||||
|  |                 break; | ||||||
|  |             case 'Ü': | ||||||
|  |                 c = 96; // Ü
 | ||||||
|  |                 for (uint8_t i = 0; i < 6; i++) | ||||||
|  |                 { | ||||||
|  |                     displayBuffer[actualIndex+i] = pgm_read_byte(&ssd1306oled_font6x8[c * 6 + i]);	// print font to ram, print 6 columns
 | ||||||
|  |                 } | ||||||
|  |                 break; | ||||||
|  |             case 'Ö': | ||||||
|  |                 c = 100; // Ö
 | ||||||
|  |                 for (uint8_t i = 0; i < 6; i++) | ||||||
|  |                 { | ||||||
|  |                     displayBuffer[actualIndex+i] = pgm_read_byte(&ssd1306oled_font6x8[c * 6 + i]);	// print font to ram, print 6 columns
 | ||||||
|  |                 } | ||||||
|  |                 break; | ||||||
|  |             case 'Ä': | ||||||
|  |                 c = 98; // Ä
 | ||||||
|  |                 for (uint8_t i = 0; i < 6; i++) | ||||||
|  |                 { | ||||||
|  |                     displayBuffer[actualIndex+i] = pgm_read_byte(&ssd1306oled_font6x8[c * 6 + i]);	// print font to ram, print 6 columns
 | ||||||
|  |                 } | ||||||
|  |                 break; | ||||||
|  |             default: | ||||||
|  |                 c -= 32; | ||||||
|  |                 for (uint8_t i = 0; i < 6; i++) | ||||||
|  |                 { | ||||||
|  |                     displayBuffer[actualIndex+i] = pgm_read_byte(&ssd1306oled_font6x8[c * 6 + i]); | ||||||
|  |                 } | ||||||
|  |                 break; | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  |     actualIndex += 6; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | void lcd_drawPixel(uint8_t x, uint8_t y, uint8_t color){ | ||||||
|  |     if( x > DISPLAY_WIDTH-1 || y > (DISPLAY_HEIGHT-1)) return; // out of Display
 | ||||||
|  |     if( color == WHITE){ | ||||||
|  |         displayBuffer[(uint8_t)(y / (DISPLAY_HEIGHT/8)) * DISPLAY_WIDTH +x] |= (1 << (y % (DISPLAY_HEIGHT/8))); | ||||||
|  |     } else { | ||||||
|  |         displayBuffer[(uint8_t)(y / (DISPLAY_HEIGHT/8)) * DISPLAY_WIDTH +x] &= ~(1 << (y % (DISPLAY_HEIGHT/8))); | ||||||
|  |     } | ||||||
|  | } | ||||||
|  | void lcd_drawLine(uint8_t x1, uint8_t y1, uint8_t x2, uint8_t y2, uint8_t color){ | ||||||
|  |     if( x1 > DISPLAY_WIDTH-1 || | ||||||
|  |        x2 > DISPLAY_WIDTH-1 || | ||||||
|  |        y1 > DISPLAY_HEIGHT-1 || | ||||||
|  |        y2 > DISPLAY_HEIGHT-1) return; | ||||||
|  |     int dx =  abs(x2-x1), sx = x1<x2 ? 1 : -1; | ||||||
|  |     int dy = -abs(y2-y1), sy = y1<y2 ? 1 : -1; | ||||||
|  |     int err = dx+dy, e2; /* error value e_xy */ | ||||||
|  |      | ||||||
|  |     while(1){ | ||||||
|  |         lcd_drawPixel(x1, y1, color); | ||||||
|  |         if (x1==x2 && y1==y2) break; | ||||||
|  |         e2 = 2*err; | ||||||
|  |         if (e2 > dy) { err += dy; x1 += sx; } /* e_xy+e_x > 0 */ | ||||||
|  |         if (e2 < dx) { err += dx; y1 += sy; } /* e_xy+e_y < 0 */ | ||||||
|  |     } | ||||||
|  | } | ||||||
|  | void lcd_drawRect(uint8_t px1, uint8_t py1, uint8_t px2, uint8_t py2, uint8_t color){ | ||||||
|  |     if( px1 > DISPLAY_WIDTH-1 || | ||||||
|  |        px2 > DISPLAY_WIDTH-1 || | ||||||
|  |        py1 > DISPLAY_HEIGHT-1 || | ||||||
|  |        py2 > DISPLAY_HEIGHT-1) return; | ||||||
|  |     lcd_drawLine(px1, py1, px2, py1, color); | ||||||
|  |     lcd_drawLine(px2, py1, px2, py2, color); | ||||||
|  |     lcd_drawLine(px2, py2, px1, py2, color); | ||||||
|  |     lcd_drawLine(px1, py2, px1, py1, color); | ||||||
|  | } | ||||||
|  | void lcd_fillRect(uint8_t px1, uint8_t py1, uint8_t px2, uint8_t py2, uint8_t color){ | ||||||
|  |     if( px1 > px2){ | ||||||
|  |         uint8_t temp = px1; | ||||||
|  |         px1 = px2; | ||||||
|  |         px2 = temp; | ||||||
|  |         temp = py1; | ||||||
|  |         py1 = py2; | ||||||
|  |         py2 = temp; | ||||||
|  |     } | ||||||
|  |     for (uint8_t i=0; i<=(py2-py1); i++){ | ||||||
|  |         lcd_drawLine(px1, py1+i, px2, py1+i, color); | ||||||
|  |     } | ||||||
|  | } | ||||||
|  | void lcd_drawCircle(uint8_t center_x, uint8_t center_y, uint8_t radius, uint8_t color){ | ||||||
|  |     if( ((center_x + radius) > DISPLAY_WIDTH-1) || | ||||||
|  |        ((center_y + radius) > DISPLAY_HEIGHT-1) || | ||||||
|  |        center_x < radius || | ||||||
|  |        center_y < radius) return; | ||||||
|  |     int16_t f = 1 - radius; | ||||||
|  |     int16_t ddF_x = 1; | ||||||
|  |     int16_t ddF_y = -2 * radius; | ||||||
|  |     int16_t x = 0; | ||||||
|  |     int16_t y = radius; | ||||||
|  |      | ||||||
|  |     lcd_drawPixel(center_x  , center_y+radius, color); | ||||||
|  |     lcd_drawPixel(center_x  , center_y-radius, color); | ||||||
|  |     lcd_drawPixel(center_x+radius, center_y  , color); | ||||||
|  |     lcd_drawPixel(center_x-radius, center_y  , color); | ||||||
|  |      | ||||||
|  |     while (x<y) { | ||||||
|  |         if (f >= 0) { | ||||||
|  |             y--; | ||||||
|  |             ddF_y += 2; | ||||||
|  |             f += ddF_y; | ||||||
|  |         } | ||||||
|  |         x++; | ||||||
|  |         ddF_x += 2; | ||||||
|  |         f += ddF_x; | ||||||
|  |          | ||||||
|  |         lcd_drawPixel(center_x + x, center_y + y, color); | ||||||
|  |         lcd_drawPixel(center_x - x, center_y + y, color); | ||||||
|  |         lcd_drawPixel(center_x + x, center_y - y, color); | ||||||
|  |         lcd_drawPixel(center_x - x, center_y - y, color); | ||||||
|  |         lcd_drawPixel(center_x + y, center_y + x, color); | ||||||
|  |         lcd_drawPixel(center_x - y, center_y + x, color); | ||||||
|  |         lcd_drawPixel(center_x + y, center_y - x, color); | ||||||
|  |         lcd_drawPixel(center_x - y, center_y - x, color); | ||||||
|  |     } | ||||||
|  | } | ||||||
|  | void lcd_fillCircle(uint8_t center_x, uint8_t center_y, uint8_t radius, uint8_t color) { | ||||||
|  |     for(uint8_t i=0; i<= radius;i++){ | ||||||
|  |         lcd_drawCircle(center_x, center_y, i, color); | ||||||
|  |     } | ||||||
|  | } | ||||||
|  | void lcd_display() { | ||||||
|  | #if defined SSD1306 | ||||||
|  |     lcd_data(displayBuffer, sizeof(displayBuffer)); | ||||||
|  | #elif defined SH1106 | ||||||
|  |     for (uint8_t i=0; i < DISPLAY_HEIGHT/8; i++) { | ||||||
|  |         lcd_gotoxy(0, i); | ||||||
|  |         uint8_t actualLine[DISPLAY_WIDTH]; | ||||||
|  |         for (uint8_t j=0; j < DISPLAY_WIDTH; j++) { | ||||||
|  |             actualLine[j]=displayBuffer[i*DISPLAY_WIDTH+j]; | ||||||
|  |         } | ||||||
|  |         lcd_data(actualLine, sizeof(actualLine)); | ||||||
|  |     } | ||||||
|  | #endif | ||||||
|  | } | ||||||
|  | #endif | ||||||
|  | |||||||
		Laden…
	
	
			
			x
			
			
		
	
		In neuem Issue referenzieren
	
	Einen Benutzer sperren
	 Sylaina
						Sylaina