#include "../i2c/ad0x0_i2c1.h" #include "../i2c/ad0x0_i2c2.h" #include "../i2c/ad0x0_i2c_ext.h" #include #include "ssd1306.h" //unsigned char vbuf[100]; #include "font.h" void OLED_Init(oled_desc_s *p_desc); void OLED_test(oled_desc_s *p_desc); void OLED_Printf(oled_desc_s *p_desc,unsigned char* buf, unsigned char size); /* печатает строку с размерами - 0 самый мелкий 2 - увеличиный - 3 самый большой(только для цифр) */ void OLED_DrawImage(unsigned char num_image); /* выводит картинку из флеш */ void OLED_Bat(unsigned char y,unsigned char x, unsigned char z); /* рисует батарейку по координатам z - от 0 до 10 делений */ void OLED_Mode(oled_desc_s *p_desc, char set_mode); /* 1 - inverted / 0 - normal */ void OLED_Sleep(oled_desc_s *p_desc, char set); /* 1 - on sleep / 0 - off sleep */ void OLED_Command(oled_desc_s *p_desc, unsigned char ControByte, unsigned char DataByte); void OLED_Commmand(oled_desc_s *p_desc,unsigned char ControByte, unsigned char DataByte); /* eiiaiau aeniea? eee aaiiua */ void OLED_Commmand2(oled_desc_s *p_desc,unsigned char ControByte, unsigned char DataByte); /* eiiaiau aeniea? eee aaiiua */ void OLED_PrintAt(oled_desc_s *p_desc, unsigned char x, unsigned char y,unsigned char* buf, unsigned char size); void OLED_Char2x(oled_desc_s *p_desc, unsigned int c); /* auaia neiaiea ia 2 no?iee*/ void OLED_GotoXY(oled_desc_s *p_desc, unsigned char x, unsigned char y); void OLED_GotoXYWH(oled_desc_s *p_desc, unsigned char x, unsigned char y,unsigned char w, unsigned char h); void OLED_Clear(oled_desc_s *p_desc); /* i?enoea anaai aenieay */ // void OLED_BigNum(unsigned char num); /* auaia aieuoeo oeo? */ void OLED_Char(oled_desc_s *p_desc, unsigned int c); /* auaia neiaiea */ oled_desc_s *p_desc_i2c1=NULL,*p_desc_i2c2=NULL;//жопой чую, что пожалею, что сунул все в один си файл // void commmand_i2c1(unsigned char ControByte, unsigned char DataByte){ OLED_Command(p_desc_i2c1,ControByte,DataByte); } void commmand_i2c2(unsigned char ControByte, unsigned char DataByte){ OLED_Command(p_desc_i2c2,ControByte,DataByte); } void OLED_PrintAt_i2c1(unsigned char x, unsigned char y,unsigned char* buf, unsigned char size){ OLED_PrintAt(p_desc_i2c1,x,y,buf,size); } void OLED_PrintAt_i2c2(unsigned char x, unsigned char y,unsigned char* buf, unsigned char size){ OLED_PrintAt(p_desc_i2c2,x,y,buf,size); } void OLED_test_i2c1(void){ OLED_test(p_desc_i2c1); } void OLED_test_i2c2(void){ OLED_test(p_desc_i2c2); } void OLED_clear_i2c1(void){ OLED_Clear(p_desc_i2c1); } void OLED_clear_i2c2(void){ OLED_Clear(p_desc_i2c2); } void OLED_Init2(I2C_TypeDef * _I2C_BASE, oled_desc_s *p_desc){ memset(p_desc,0,sizeof(oled_desc_s)); if(_I2C_BASE == (I2C_TypeDef *)I2C1_BASE){ p_desc_i2c1=p_desc; p_desc->ad0x0_i2c_get_ext_async2=ad0x0_i2c1_get_ext_async2; p_desc->ad0x0_i2c_push=ad0x0_i2c1_push; p_desc->commmand=commmand_i2c1; p_desc->print_at=OLED_PrintAt_i2c1; p_desc->OLED_test=OLED_test_i2c1; p_desc->clear=OLED_clear_i2c1; OLED_Init(p_desc_i2c1); }else if(_I2C_BASE == (I2C_TypeDef *)I2C2_BASE){ p_desc_i2c2=p_desc; p_desc->ad0x0_i2c_get_ext_async2=ad0x0_i2c2_get_ext_async2; p_desc->ad0x0_i2c_push=ad0x0_i2c2_push; p_desc->commmand=commmand_i2c2; p_desc->print_at=OLED_PrintAt_i2c2; p_desc->OLED_test=OLED_test_i2c2; p_desc->clear=OLED_clear_i2c2; OLED_Init(p_desc_i2c2); }else{ ad0x0_err(); } } /* --------------------------------------------------------- * OLED_init * --------------------------------------------------------- */ void OLED_Init(oled_desc_s *p_desc) { //OLED_Sleep(0); p_desc->commmand(COMAND, SSD1306_DISPLAYOFF); //HAL_Delay(10); ad0x0_i2c1_push(ADQ_DELAY_MS,100); p_desc->commmand(COMAND, SSD1306_DISPLAYON); ad0x0_i2c1_push(ADQ_DELAY_MS,100); p_desc->commmand(COMAND, SSD1306_SETCONTRAST); p_desc->commmand(COMAND, 0x7f); p_desc->commmand(COMAND, SSD1306_SETDISPLAYCLOCKDIV); p_desc->commmand(COMAND, 0x80); p_desc->commmand(COMAND, SSD1306_SETMULTIPLEX); p_desc->commmand(COMAND, 0x3F); p_desc->commmand(COMAND, SSD1306_SETDISPLAYOFFSET); p_desc->commmand(COMAND, 0x00); p_desc->commmand(COMAND, SSD1306_SETSTARTLINE | 0x00); /* We use internal charge pump */ p_desc->commmand(COMAND, SSD1306_CHARGEPUMP); p_desc->commmand(COMAND, 0x14); /* Horizontal memory mode */ p_desc->commmand(COMAND, SSD1306_MEMORYMODE); p_desc->commmand(COMAND, 0x00); //p_desc->commmand(COMAND, SSD1306_SEGREMAP | 0x1);//ad0x0 p_desc->commmand(COMAND, SSD1306_SEGREMAP | 0x0);//ad0x0 //p_desc->commmand(COMAND, SSD1306_COMSCANDEC);//ad0x0 p_desc->commmand(COMAND, SSD1306_COMSCANINC); p_desc->commmand(COMAND, SSD1306_SETCOMPINS); //p_desc->commmand(COMAND, 0x12); p_desc->commmand(COMAND, 0x2);//ad0x0 /* Max contrast */ p_desc->commmand(COMAND, SSD1306_SETCONTRAST); p_desc->commmand(COMAND, 0xCF); p_desc->commmand(COMAND, SSD1306_SETPRECHARGE); p_desc->commmand(COMAND, 0xF1); p_desc->commmand(COMAND, SSD1306_SETVCOMDETECT); //p_desc->commmand(COMAND, 0x40); p_desc->commmand(COMAND, 0x20); p_desc->commmand(COMAND, SSD1306_DISPLAYALLON_RESUME); /* Non-inverted display */ OLED_Mode(p_desc, 0); /* Turn display back on */ OLED_Sleep(p_desc, 1); OLED_Clear(p_desc); OLED_GotoXY(p_desc, 0,0); } /* --------------------------------------------------------- * OLED_Mode * --------------------------------------------------------- */ void OLED_Mode(oled_desc_s *p_desc, char set_mode) { if(set_mode==0) { p_desc->commmand(COMAND, SSD1306_NORMALDISPLAY); } if(set_mode==1) { p_desc->commmand(COMAND, SSD1306_INVERTDISPLAY); } } /* --------------------------------------------------------- * OLED_Sleep * --------------------------------------------------------- */ void OLED_Sleep(oled_desc_s *p_desc, char set) { if(set==0) { p_desc->commmand(COMAND,SSD1306_DISPLAYOFF); } if(set==1) { p_desc->commmand(COMAND,SSD1306_DISPLAYON); } } void OLED_GotoXY(oled_desc_s *p_desc, unsigned char x, unsigned char y) { p_desc->OLED_X = x; p_desc->OLED_Y = y; p_desc->commmand(COMAND, SSD1306_COLUMNADDR); p_desc->commmand(COMAND, x); p_desc->commmand(COMAND, 127); p_desc->commmand(COMAND, SSD1306_PAGEADDR); p_desc->commmand(COMAND, y); p_desc->commmand(COMAND, 0x3); } void OLED_GotoXYWH(oled_desc_s *p_desc, unsigned char x, unsigned char y,unsigned char w, unsigned char h){ p_desc->OLED_X = x; p_desc->OLED_Y = y; p_desc->commmand(COMAND, SSD1306_COLUMNADDR); p_desc->commmand(COMAND, x); //начало строки p_desc->commmand(COMAND, x+w); //конец (после переполенения след.столб.+начало строки) p_desc->commmand(COMAND, SSD1306_PAGEADDR); p_desc->commmand(COMAND, y);//столбец старт p_desc->commmand(COMAND, 0x3);//4й столбец последний } void OLED_Char2x(oled_desc_s *p_desc, unsigned int c) { unsigned char x = 0; uint8_t suka=4,v,nv; //вызов OLED_GotoXYWH(x,y,10,2) должен установить окно размером 10пикс х 2строки //типа было 10110111 => 1100111100111111 for (x=0; x<5; x++) { v=OLED_Buffer[c*5+x]; nv=0; suka=4; while(suka--){ if(v & 0x8){nv|=0x3;} if(suka)nv<<=2; v<<=1; } p_desc->commmand(DATA, nv); p_desc->commmand(DATA, nv); //p_desc->commmand(DATA, 0x0); } for (x=0; x<5; x++) { v=OLED_Buffer[c*5+x]; nv=0; suka=4; while(suka--){ if(v & 0x80){nv|=0x3;} if(suka)nv<<=2; v<<=1; } p_desc->commmand(DATA, nv); p_desc->commmand(DATA, nv); //p_desc->commmand(DATA, 0x0); } p_desc->OLED_X += 11; if(p_desc->OLED_X>SSD1306_LCDWIDTH) { p_desc->OLED_X = SSD1306_DEFAULT_SPACE; } } /* --------------------------------------------------------- * OLED_Clear * --------------------------------------------------------- */ void OLED_Clear(oled_desc_s *p_desc) { unsigned short i; unsigned short x = 0; unsigned short y = 0; OLED_GotoXY(p_desc, 0,0); for (i=0; i<(SSD1306_LCDWIDTH*SSD1306_LCDHEIGHT/8); i++) /* (SSD1306_LCDWIDTH*SSD1306_LCDHEIGHT/8) */ { OLED_Char(p_desc, ' '); x ++; if(x>SSD1306_LCDWIDTH) { x = 0; y++; OLED_GotoXY(p_desc, 0,y); } } p_desc->OLED_X = SSD1306_DEFAULT_SPACE; p_desc->OLED_Y = 0; } /* --------------------------------------------------------- * OLED_Char * --------------------------------------------------------- */ void OLED_Char(oled_desc_s *p_desc, unsigned int c) { unsigned char x = 0; for (x=0; x<5; x++) { p_desc->commmand(DATA, OLED_Buffer[c*5+x]); } p_desc->OLED_X += 8; if(p_desc->OLED_X>SSD1306_LCDWIDTH) { p_desc->OLED_X = SSD1306_DEFAULT_SPACE; } } /* --------------------------------------------------------- * OLED_CharBig * --------------------------------------------------------- */ void OLED_CharBig(oled_desc_s *p_desc, unsigned int c) { unsigned char x = 0; unsigned int m = 0; for (x=0; x<5; x++) { m = OLED_Buffer[c*5+x]; p_desc->commmand(DATA, m); p_desc->commmand(DATA, m); } p_desc->commmand(DATA,0x00); /* пробео в одну точку между символами */ p_desc->OLED_X += 11; if(p_desc->OLED_X>SSD1306_LCDWIDTH) { p_desc->OLED_X = SSD1306_DEFAULT_SPACE; } } /* --------------------------------------------------------- * OLED_Printf * --------------------------------------------------------- */ void OLED_Printf(oled_desc_s *p_desc, unsigned char* buf, unsigned char size) /* выводим строку из буфера */ { while (*buf!=0) { if(size==0) { if((p_desc->OLED_X>SSD1306_LCDWIDTH)||(p_desc->OLED_X<5)) { p_desc->OLED_X=SSD1306_DEFAULT_SPACE; } OLED_Char(p_desc, *buf++); } if(size==1) { if((p_desc->OLED_X>SSD1306_LCDWIDTH)||(p_desc->OLED_X<5)) { p_desc->OLED_X=SSD1306_DEFAULT_SPACE; } OLED_CharBig(p_desc, *buf++); } } } void OLED_PrintAt(oled_desc_s *p_desc, unsigned char x, unsigned char y,unsigned char* buf, unsigned char size){ if(size==0)OLED_GotoXY(p_desc, x,y);else if(size==1)OLED_GotoXY(p_desc, x,y); while (*buf!=0) { if(size==0) { if((p_desc->OLED_X>SSD1306_LCDWIDTH)||(p_desc->OLED_X<5)) { p_desc->OLED_X=SSD1306_DEFAULT_SPACE; } OLED_Char(p_desc, *buf++); } if(size==1) { if((p_desc->OLED_X>SSD1306_LCDWIDTH)||(p_desc->OLED_X<5)) { p_desc->OLED_X=SSD1306_DEFAULT_SPACE; } OLED_CharBig(p_desc, *buf++); } if(size==2) { if((p_desc->OLED_X>SSD1306_LCDWIDTH)) { p_desc->OLED_X=SSD1306_DEFAULT_SPACE; } OLED_GotoXYWH(p_desc, x,y,9,2); OLED_Char2x(p_desc, *buf++); x+=11; } } } void OLED_Command(oled_desc_s *p_desc, unsigned char ControByte, unsigned char DataByte){ /*if(ad0x0_i2c_isovrflow()){ asm("nop"); }else { asm("nop"); }*/ //ad0x0_i2c1_push(0x1,0); //ad0x0_i2c1_push(0x3,SSD1306_I2C_ADDRESS & 0xFE); /*ad0x0_i2c1_push(ADQ_START_ADDR,SSD1306_I2C_ADDRESS & 0xFE);//v2 start+addr ad0x0_i2c1_push(ADQ_TX,ControByte); ad0x0_i2c1_push(ADQ_TX_STOP,DataByte); ad0x0_i2c2_push(ADQ_START_ADDR,SSD1306_I2C_ADDRESS & 0xFE);//v2 start+addr ad0x0_i2c2_push(ADQ_TX,ControByte); ad0x0_i2c2_push(ADQ_TX_STOP,DataByte);*/ uint8_t h_ext; ad0x0_i2c_ext_t *p_ext_t=NULL; p_desc->ad0x0_i2c_get_ext_async2(&h_ext,(void**)&p_ext_t); p_ext_t->addr_w=SSD1306_I2C_ADDRESS; p_ext_t->user_data0=ControByte | (uint32_t)(DataByte<<8); p_ext_t->pbuf_count=2; p_ext_t->pbuf_tx=(uint8_t*)&p_ext_t->user_data0;//TX!!!!!!! p_ext_t->p_pre_SetTXRXBuf=EXT_SetTXRXBuf_i2c; p_desc->ad0x0_i2c_push(ADQ_HAL_ADDR_TX_BUF_STOP_EXT,h_ext); } /* --------------------------------------------------------- * OLED_test * --------------------------------------------------------- */ void OLED_test(oled_desc_s *p_desc) { OLED_Clear(p_desc); OLED_PrintAt(p_desc, 0,0,(unsigned char*)"Шрифт размер = 0",0); HAL_Delay(500); OLED_PrintAt(p_desc, 0,1,(unsigned char*)"Шрифт s = 1",1); HAL_Delay(500); OLED_PrintAt(p_desc, 0,2,(unsigned char*)"Шрифт s = 2",2); HAL_Delay(500); OLED_Clear(p_desc); } unsigned char * i16_2s(int16_t value, unsigned char *buffer) { memset(buffer,' ',6); buffer += 7; char m=(value<0)?'-':' '; if(value<0)value=-value; // 11 байт достаточно для десятичного представления 32-х байтного числа // и завершающего нуля *--buffer = 0; do { *--buffer = value % 10 + '0'; value /= 10; } while (value != 0); *--buffer=m; return buffer; } unsigned char * i32_2s(int32_t value, unsigned char *buffer) { memset(buffer,' ',8); buffer += 7; char m=(value<0)?'-':' '; if(value<0)value=-value; // 11 байт достаточно для десятичного представления 32-х байтного числа // и завершающего нуля *--buffer = 0; do { *--buffer = value % 10 + '0'; value /= 10; } while (value != 0); *--buffer=m; return buffer; } /* EOF "ssd1306.c" */