1

Тема: 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();    
  }