Тема: oled 1.3 sh1106 + Attiny
установить подтягивающие резисторы 4.7 кОм на шину I2C
#include <avr/io.h>
#include <util/delay.h>
#define I2C_SDA PB3
#define I2C_SCL PB4
long ttt;
#define I2C_SDA_HIGH() DDRB &= ~(1<<I2C_SDA)
#define I2C_SDA_LOW() DDRB |= (1<<I2C_SDA)
#define I2C_SCL_HIGH() DDRB &= ~(1<<I2C_SCL)
#define I2C_SCL_LOW() DDRB |= (1<<I2C_SCL)
const char Message1[] PROGMEM = "RCL-RADIO.RU";
const char Message2[] PROGMEM = "ABCDEFGH";
int main(void) {
OLED_init();
OLED_clear();
while(1) {
ttt++;
OLED_cursor(0, 0);
OLED_printP(Message1);
OLED_cursor(0, 2);
OLED_num(ttt/100000);OLED_num(ttt/10000%10);OLED_num(ttt/1000%10);OLED_num(ttt/100%10);OLED_num(ttt/10%10);OLED_num(ttt%10);
OLED_cursor(0, 4);
OLED_printP(Message2);
OLED_cursor(0, 7);
OLED_printP(Message2);
_delay_ms(1000);
// OLED_clear();
}}
///// I2C ///////////////////////////////////////////////////////
void I2C_init(void) {DDRB &= ~((1<<I2C_SDA)|(1<<I2C_SCL)); PORTB &= ~((1<<I2C_SDA)|(1<<I2C_SCL));}
void I2C_write(uint8_t data) {
for(uint8_t i = 8; i; i--) {I2C_SDA_LOW();
if (data & 0x80) I2C_SDA_HIGH();I2C_SCL_HIGH();data<<=1;I2C_SCL_LOW();}
I2C_SDA_HIGH();I2C_SCL_HIGH();asm("nop");I2C_SCL_LOW();
}
void I2C_start(uint8_t addr) {I2C_SDA_LOW();I2C_SCL_LOW();I2C_write(addr);}
void I2C_stop(void) {I2C_SDA_LOW();I2C_SCL_HIGH();I2C_SDA_HIGH();}
///// OLED ///////////////////////////////////
#define OLED_ADDR 0x78
#define OLED_CMD_MODE 0x00
#define OLED_DAT_MODE 0x40
#define OLED_INIT_LEN 13
// OLED init settings
const uint8_t OLED_INIT_CMD[] PROGMEM = {0xA8,0x3F,0x81,0xff,0xA1,0xC0,0xC8,0xDA,0x12,0xD3,0x00,0x40,0xAF};
// Standard ASCII 5x8 font (adapted from Neven Boyanov and Stephen Denne)
const uint8_t OLED_FONT[] PROGMEM = {
0x00, 0x00, 0x00, 0x00, 0x00, // 0
0x00, 0x1c, 0x22, 0x41, 0x00, // ( 8
0x00, 0x41, 0x22, 0x1c, 0x00, // ) 9
0x14, 0x08, 0x3E, 0x08, 0x14, // * 10
0x08, 0x08, 0x3E, 0x08, 0x08, // + 11
0x00, 0x00, 0xA0, 0x60, 0x00, // , 12
0x08, 0x08, 0x08, 0x08, 0x08, // - 13
0x00, 0x60, 0x60, 0x00, 0x00, // . 14
0x20, 0x10, 0x08, 0x04, 0x02, // / 15
0x3E, 0x51, 0x49, 0x45, 0x3E, // 0 16
0x00, 0x42, 0x7F, 0x40, 0x00, // 1 17
0x42, 0x61, 0x51, 0x49, 0x46, // 2 18
0x21, 0x41, 0x45, 0x4B, 0x31, // 3 19
0x18, 0x14, 0x12, 0x7F, 0x10, // 4 20
0x27, 0x45, 0x45, 0x45, 0x39, // 5 21
0x3C, 0x4A, 0x49, 0x49, 0x30, // 6 22
0x01, 0x71, 0x09, 0x05, 0x03, // 7 23
0x36, 0x49, 0x49, 0x49, 0x36, // 8 24
0x06, 0x49, 0x49, 0x29, 0x1E, // 9 25
0x00, 0x36, 0x36, 0x00, 0x00, // : 26
0x00, 0x56, 0x36, 0x00, 0x00, // ; 27
0x08, 0x14, 0x22, 0x41, 0x00, // < 28
0x14, 0x14, 0x14, 0x14, 0x14, // = 29
0x00, 0x41, 0x22, 0x14, 0x08, // > 30
0x02, 0x01, 0x51, 0x09, 0x06, // ? 31
0x32, 0x49, 0x59, 0x51, 0x3E, // @ 32
0x7C, 0x12, 0x11, 0x12, 0x7C, // A 33
0x7F, 0x49, 0x49, 0x49, 0x36, // B 34
0x3E, 0x41, 0x41, 0x41, 0x22, // C 35
0x7F, 0x41, 0x41, 0x22, 0x1C, // D 36
0x7F, 0x49, 0x49, 0x49, 0x41, // E 37
0x7F, 0x09, 0x09, 0x09, 0x01, // F 38
0x3E, 0x41, 0x49, 0x49, 0x7A, // G 39
0x7F, 0x08, 0x08, 0x08, 0x7F, // H 40
0x00, 0x41, 0x7F, 0x41, 0x00, // I 41
0x20, 0x40, 0x41, 0x3F, 0x01, // J 42
0x7F, 0x08, 0x14, 0x22, 0x41, // K 43
0x7F, 0x40, 0x40, 0x40, 0x40, // L 44
0x7F, 0x02, 0x0C, 0x02, 0x7F, // M 45
0x7F, 0x04, 0x08, 0x10, 0x7F, // N 46
0x3E, 0x41, 0x41, 0x41, 0x3E, // O 47
0x7F, 0x09, 0x09, 0x09, 0x06, // P 48
0x3E, 0x41, 0x51, 0x21, 0x5E, // Q 49
0x7F, 0x09, 0x19, 0x29, 0x46, // R 50
0x46, 0x49, 0x49, 0x49, 0x31, // S 51
0x01, 0x01, 0x7F, 0x01, 0x01, // T 52
0x3F, 0x40, 0x40, 0x40, 0x3F, // U 53
0x1F, 0x20, 0x40, 0x20, 0x1F, // V 54
0x3F, 0x40, 0x38, 0x40, 0x3F, // W 55
0x63, 0x14, 0x08, 0x14, 0x63, // X 56
0x07, 0x08, 0x70, 0x08, 0x07, // Y 57
0x61, 0x51, 0x49, 0x45, 0x43, // Z 58
};
void OLED_init(void) {
I2C_init();
I2C_start(OLED_ADDR);
I2C_write(OLED_CMD_MODE);
for (uint8_t i = 0; i < OLED_INIT_LEN; i++) I2C_write(pgm_read_byte(&OLED_INIT_CMD[i]));
I2C_stop();
}
void OLED_printC(char ch) {
uint16_t offset = ch - 32 -7;
offset += offset << 2;
I2C_write(0x00);
for(uint8_t i=5; i; i--) I2C_write(pgm_read_byte(&OLED_FONT[offset++]));
}
void OLED_printP(const char* p) {
I2C_start(OLED_ADDR);
I2C_write(OLED_DAT_MODE);
char ch = pgm_read_byte(p);
while (ch != 0){OLED_printC(ch);ch = pgm_read_byte(++p);}
I2C_stop();
}
void OLED_cursor(uint8_t xpos, uint8_t ypos) {
I2C_start(OLED_ADDR);
I2C_write(OLED_CMD_MODE);
I2C_write(xpos+1 & 0x0F);
I2C_write(0x10 | (xpos >> 4));
I2C_write(0xB0 | (ypos & 0x07));
I2C_stop();
}
void OLED_clear(void) {
for(uint16_t b=0;b<8;b++){
OLED_cursor(0, b);
I2C_start(OLED_ADDR);
I2C_write(OLED_DAT_MODE);
for(uint16_t i=129; i; i--) I2C_write(0x00);
I2C_stop();
}
}
void OLED_num(byte num){
I2C_start(OLED_ADDR);
I2C_write(OLED_DAT_MODE);
OLED_printC(num+48);
I2C_stop();
}