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++; } }
完成
