HAL库使用I2C控制OLED屏

HAL_StatusTypeDef HAL_I2C_Mem_Write(I2C_HandleTypeDef *hi2c, uint16_t DevAddress, uint16_t MemAddress, uint16_t MemAddSize, uint8_t *pData, uint16_t Size, uint32_t Timeout)

首先介绍下这个函数,官方的I2C写函数(注意这个没有用到中断,DMA,属于阻塞类发送的)

  • *hi2c: I2C设备号指针,设置使用的是那个IIC 例:&hi2c2
  • DevAddress: 从设备地址 从设备的IIC地址 例E2PROM的设备地址 0xA0
  • MemAddress: 从机寄存器地址 ,每写入一个字节数据,地址就会自动+1
  • MemAddSize: 从机寄存器地址字节长度 8位或16位
  • *pData: 需要写入的的数据的起始地址
  • Size: 传输数据的大小 多少个字节
  • Timeout: 最大读取时间,超过时间将自动退出函数

void OLED_WR_CMD(uint8_t cmd)//向OLED写命令
{
    HAL_I2C_Mem_Write(&hi2c1 ,0x78,0x00,I2C_MEMADD_SIZE_8BIT,&cmd,1,0x100);
}
void OLED_WR_DATA(uint8_t data)//向OLED写数据
{
    HAL_I2C_Mem_Write(&hi2c1 ,0x78,0x40,I2C_MEMADD_SIZE_8BIT,&data,1,0x100);
}
我这里是一个字节一个字节的传送,所有字节大小填1

void OLED_DISPLAY_CLEAR(void){//清屏操作
    uint8_t j,t;
    for(t=0xB0;t<0xB8;t++){    //设置起始页地址为0xB0
        //I2C_SAND_BYTE(OLED0561_ADD,COM,t);     //页地址(从0xB0到0xB7)
        //I2C_SAND_BYTE(OLED0561_ADD,COM,0x10); //起始列地址的高4位
        //I2C_SAND_BYTE(OLED0561_ADD,COM,0x00);    //起始列地址的低4位
        OLED_WR_CMD(t);
        OLED_WR_CMD(0x10);
        OLED_WR_CMD(0x00);
        for(j=0;j<132;j++){    //整页内容填充
             //I2C_SAND_BYTE(OLED0561_ADD,DAT,0x00);
            OLED_WR_DATA(0);
         }
    }
}

上面注释掉的代码是使用标准库的函数,无视了

void OLED_DISPLAY_8x16(uint8_t x, //显示汉字的页坐标(从0到7)(此处不可修改)
                        uint8_t y, //显示汉字的列坐标(从0到63)
                        uint16_t w){ //要显示汉字的编号
    uint8_t j,t,c=0;
    uint8_t a,b,d,e;
    y=y+2; //因OLED屏的内置驱动芯片是从0x02列作为屏上最左一列,所以要加上偏移量
    for(t=0;t<2;t++){
        //I2C_SAND_BYTE(OLED0561_ADD,COM,0xb0+x); //页地址(从0xB0到0xB7)
        //I2C_SAND_BYTE(OLED0561_ADD,COM,y/16+0x10); //起始列地址的高4位
        //I2C_SAND_BYTE(OLED0561_ADD,COM,y%16);    //起始列地址的低4位
        OLED_WR_CMD(0xb0+x);
        OLED_WR_CMD(y/16+0x10);
        OLED_WR_CMD(y%16);
        for(j=0;j<8;j++){ //整页内容填充
             //I2C_SAND_BYTE(OLED0561_ADD,DAT,ASCII_8x16[(w*16)+c-512]);//为了和ASII表对应要减512
            OLED_WR_DATA(ASCII_8x16[(w*16)+c-512]);
            c++;}x++; //页地址加1
    }
}
//向LCM发送一个字符串,长度64字符之内。
//应用:OLED_DISPLAY_8_16_BUFFER(0," KingZhan"); 
void OLED_DISPLAY_8x16_BUFFER(uint8_t row,uint8_t *str){
    uint8_t r=0;
    while(*str != '\0'){
        OLED_DISPLAY_8x16(row,r*8,*str++);
        r++;
    }    
}

完成

posted @ 2021-09-25 21:20  kingzhan  阅读(1434)  评论(0编辑  收藏  举报