单片机作业1_为OLED制作汉字字库_第2部分

第2部分,

  • 实现proteus中 i2c 接口的 OLED12864 的驱动,后面将为其制作汉字字库!
  • SSD1306是如何驱动OLED12864的?需要做哪些初始化工作?
  • 由于OLED是显示缓存是列行式扫描,HZK16x16是逐行式扫描,需要将“逐行式”转化为列行式!

Proteus中OLED12864(i2c)使用的是 SSD1306 驱动芯片!我们可以从网上下载 SSD1306 的datasheet,进一步地学习研究!

1 i2c时序图

1.1 SSD1306的 i2c 器件地址

在这里插入图片描述

在这里插入图片描述

1.1.1 测试OLED12864的i2c器件地址

在这里插入图片描述

在这里插入图片描述

1.2 i2c的起始与终止信号

在这里插入图片描述

1.3 i2c的应答信号

在这里插入图片描述

1.4 i2c的传输数据位

在这里插入图片描述

2 i2c底层实现

2.1 延时函数

static void i2c_delay(){
    // 24MHz, 12T, delay 1.5us
    _nop_();
    _nop_();
}

2.2 起始信号

void i2c_start(void){
   
    I2C_SDA = 1;
    I2C_SCL = 1;
    I2C_SDA = 0; // Falling edge
    i2c_delay(); // 1us
    I2C_SCL = 0; // Releasing the clock
}

2.2 终止信号

void i2c_stop(void){
   
    I2C_SDA = 0;
    I2C_SCL = 1;
    i2c_delay(); // 1us
    I2C_SDA = 1; // Rising edge
    i2c_delay(); // 1us
    I2C_SCL = 0; // Releasing the clock
}

2.3 发送数据字节

void i2c_send_byte(uint8_t dat){
   
    uint8_t tmp = 0x80;
    I2C_SCL = 0;
    for(tmp = 0x80; tmp; tmp >>= 1){
   
        if(dat & tmp){
   
            I2C_SDA = 1;
        }else{
   
            I2C_SDA = 0;
        }
        I2C_SCL = 1;
        i2c_delay(); // 1us
        I2C_SCL = 0;
    }
}

2.4 发送器接收应答信号

bit i2c_recv_ack(void){
   
    bit ack = 0;
    I2C_SDA = 1;
    I2C_SCL = 1;
    ack = !I2C_SDA;
    i2c_delay();
    I2C_SCL = 0; // Releasing the clock
    return ack;
}

3 OLED12864 驱动实现

3.1 数据手册阅读

3.1.1 SSD1306 硬件框图

在这里插入图片描述

3.1.2 SSD1306 的 GDDRAM 结构

图形显示数据RAM,Graphic Display Data RAM (GDDRAM)
在这里插入图片描述

在这里插入图片描述

3.1.3 向OLED12864写入数据

在这里插入图片描述
控制字:用来识别发送的数据是“命令”还是“数据”!
在这里插入图片描述

3.2 代码实现

3.2.1 器件寻址

bit oled12864_addressing(uint8_t dev_addr){
   
    bit ack = 0;
    i2c_start();
    i2c_send_byte((dev_addr << 1) | 0x00);
    ack = i2c_recv_ack();
    i2c_stop();
    return ack;
}

3.2.2 向OLED写入命令或数据

// mode = 1 dat mode = 0 command
static bit oled_write(uint8_t dev_addr, uint8_t dat, bit mode){
   ;
    i2c_start();
    i2c_send_byte((dev_addr << 1) | 0x00);
    if(!i2c_recv_ack()){
   
        return 0;
    }
    if(mode){
   
        i2c_send_byte(0x40);
    }else{
   
        i2c_send_byte(0x00);
    }
    if(!i2c_recv_ack()){
   
        return 0;
    }
    i2c_send_byte(dat);
    if(!i2c_recv_ack()){
   
        return 0;
    }
    i2c_stop();
    return 1;
}
3.2.2.1 写命令
static bit oled_write_cmd(uint8_t cmd){
   
    return oled_write(OLED12864_I2C_ADDR, cmd, 0);
}
3.2.2.2 写数据
static bit oled_write_dat(uint8_t dat){
   
    return oled_write(OLED12864_I2C_ADDR, dat, 1);
}

3.2.3 OLED显示开关

3.2.3.1 打开显示
void oled_on(void){
   
    oled_write_cmd(0xAF); // display on
}
3.2.3.2 关闭显示
void oled_off(void){
   
    oled_write_cmd(0xAE); // display off
}

3.2.4 初始化OLED

void oled_init(void){
   
    oled_off();
    /**** (1) OLED12864 or OLED12832 ****/
#if (RESOLUTION == 12864) // 0.96"
    /** Set Multiplex Ratio(1 to 64) (Resolution Col * Row)
    Setting Row from 16MUX(0x10) to 64MUX(0x3F)**/
    oled_write_cmd(0xA8); 
    oled_write_cmd(0x3F); // 0x00|X[5:0] 64MUX
    /**Set COM Pins Hardware Configuration
        - X[4]=0b, Sequential COM pin configuration
        - X[4]=1b(RESET), Alternative COM pin configuration
        - X[5]=0b(RESET), Disable COM Left/Right remap
        - X[5]=1b, Enable COM Left/Right remap  **/
    oled_write_cmd(0xDA);
    oled_write_cmd(0x12); // 0x02|X[5]|X[4]
#elif (RESOLUTION == 12832) // 0.91"
    /** Set Multiplex Ratio(1 to 64) (Resolution Col * Row)
    Setting Row from 16MUX(0x10) to 64MUX(0x3F)**/
    oled_write_cmd(0xA8); 
    oled_write_cmd(0x1F); // 0x00|X[5:0] 16MUX
    /**Set COM Pins Hardware Configuration
        - X[4]=0b, Sequential COM pin configuration
        - X[4]=1b(RESET), Alternative COM pin configuration
        - X[5]=0b(RESET), Disable COM Left/Right remap
        - X[5]=1b, Enable COM Left/Right remap  **/
    oled_write_cmd(0xDA);
    oled_write_cmd(0x02); // 0x02|X[5]|X[4]
#endif
    /**** (2) Charge Pump Command Table ****/
    oled_write_cmd(0x8D); // Charge Pump Setting
    oled_write_cmd(0x10); // 0x10 dsiabled, 0x14 enabled
    /**** (3) Fundamental Command ****/
    oled_write_cmd(0xA5); // Entire display ON
    oled_write_cmd(0xA4); // Display outputs according to the GDDRAM contents
    oled_write_cmd(0xA6); // 0xA6 Normal display(default, 1 - 'ON'); 0xA7 Inverse display(0 - 'ON')
    /** Contrast Control
    The chip has 256 contrast steps from 00h to FFh. 
    The segment output current increases as the contrast step value increases. **/
    oled_write_cmd(0x81);
    oled_write_cmd(0x7F); // 0x7F
    /**** (4) Addressing Setting Command Table ****/
    /**Set Memory Addressing Mode
        - X[1:0] = 00b, Horizontal Addressing Mode
        - X[1:0] = 01b, Vertical Addressing Mode
        - X[1:0] = 10b, Page Addressing Mode (RESET)
        - X[1:0] = 11b, Invalid  **/
    oled_write_cmd(0x20);
    oled_write_cmd(0x00); // 0x00|X[1:0] Vertical
    /**** (5) Hardware Configuration (Panel resolution & layout related) Command Table ****/
    /**Set Segment Re-map
        - 0xA0 column address 0 is mapped to SEG0 (RESET)
        - 0xA1 column address 127 is mapped to SEG0  **/
    oled_write_cmd(0xA1);
    /**Set COM Re-map
        - 0xC0 normal mode (RESET) Scan from COM0 to COM[N-1]
        - 0xC8 remapped mode. Scan from COM[N-1] to COM0  **/
    oled_write_cmd(0xC8); // 0xC0|X[3], remapped mode
    // Set Display Start Line. 0x40 ~ 0x7F(RESET = 0x40)
    oled_write_cmd(0x40); // 0x40|X[5:0], from row 0 to 63
    /**Set Display Offset 
        Set vertical shift by COM from 0~63(0x00~0z3F) **/
    oled_write_cmd(0xD3); 
    oled_write_cmd(0x00); // Set vertical shift by COM from 0x00~0x3F(RESET=0x00)
    /**Set Display Clock Divide Ratio/Oscillator Frequency
        - X[7:4] : Set the Oscillator Frequency, Oscillator Frequency increases with the value of X[7:4] and vice versa.
  
  • 0
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值