[ST NUCLEO-WB09KE Review] -4-I2C interface driving OLED test
[Copy link]
This post was last edited by Murong Xuehua on 2024-9-11 21:33
The Morpho interface CN4 and the Arduino interface CN6 on the development board both lead out the I2C bus interface.
The order from top to bottom is: SCL, SDA, VCC, GND. The order of the OLED pins on hand is: SDA, SCL, VCC, GND.
1. GND Power ground
2. VCC Power positive (3~5.5V)
3. SCL OLED D0 pin, the clock pin in IIC communication
4. SDA OLED D1 pin, the data pin in IIC communication
There is a little difference. It is possible to directly connect the DuPont cable, but I have suffered from cable problems before. I happened to make a small adapter board some time ago, and I used it this time.
I am not good at soldering, but this simple interface conversion can still be used as a makeshift. The actual picture of the stacked objects:
Next, configure I2C:
Click Save to automatically generate code:
static void MX_I2C1_Init(void)
{
/* USER CODE BEGIN I2C1_Init 0 */
/* USER CODE END I2C1_Init 0 */
/* USER CODE BEGIN I2C1_Init 1 */
/* USER CODE END I2C1_Init 1 */
hi2c1.Instance = I2C1;
hi2c1.Init.Timing = 0x00303D5B;
hi2c1.Init.OwnAddress1 = 0;
hi2c1.Init.AddressingMode = I2C_ADDRESSINGMODE_7BIT;
hi2c1.Init.DualAddressMode = I2C_DUALADDRESS_DISABLE;
hi2c1.Init.OwnAddress2 = 0;
hi2c1.Init.OwnAddress2Masks = I2C_OA2_NOMASK;
hi2c1.Init.GeneralCallMode = I2C_GENERALCALL_DISABLE;
hi2c1.Init.NoStretchMode = I2C_NOSTRETCH_DISABLE;
if (HAL_I2C_Init(&hi2c1) != HAL_OK)
{
Error_Handler();
}
/** Configure Analogue filter
*/
if (HAL_I2CEx_ConfigAnalogFilter(&hi2c1, I2C_ANALOGFILTER_ENABLE) != HAL_OK)
{
Error_Handler();
}
/** Configure Digital filter
*/
if (HAL_I2CEx_ConfigDigitalFilter(&hi2c1, 0) != HAL_OK)
{
Error_Handler();
}
/* USER CODE BEGIN I2C1_Init 2 */
/* USER CODE END I2C1_Init 2 */
}
iic driver oled complete code sharing:
/*Reference: https://blog.csdn.net/Reasally/article/details/126789505*/
#include "oled.h"
#include "stdlib.h"
#include "oledfont.h"
#include "main.h"
extern I2C_HandleTypeDef hi2c1;
uint8_t OLED_GRAM[144][8];
//
void OLED_ColorTurn(uint8_t i)
{
if(i==0)
{
WriteCmd(0xA6);
}
if(i==1)
{
WriteCmd(0xA7);
}
}
//180
void OLED_DisplayTurn(uint8_t i)
{
if(i==0)
{
WriteCmd(0xC8);
WriteCmd(0xA1);
}
if(i==1)
{
WriteCmd(0xC0);
WriteCmd(0xA0);
}
}
//
void IIC_delay(void)
{
uint16_t t=300;
while(t--);
}
/***************************************************
I2C总线传出数据函数:
addr : 要写入的地址(OLED的地址一般为0x40;指令地址为0x00)
data : 要写入的数据
***************************************************/
void HAL_I2C_WriteByte(uint8_t addr,uint8_t data)
{
uint8_t TxData[2] = {addr,data};
HAL_I2C_Master_Transmit(&hi2c1,0X78,(uint8_t*)TxData,2,10);
}
/**************************************************************
Prototype : void WriteCmd(uint8_t IIC_Command)
Parameters : IIC_Command
return : none
Description : 写命令(通过HAL_I2C_WriteByte中的HAL_I2C_Master_Transmit
向0x00写入命令)
***************************************************************/
void WriteCmd(uint8_t IIC_Command)
{
HAL_I2C_WriteByte(0x00, IIC_Command);
}
/**************************************************************
Prototype : void WriteDat(uint8_t IIC_Data)
Parameters : IIC_Data
return : none
Description : 写数据(通过HAL_I2C_WriteByte中的HAL_I2C_Master_Transmit
向0x40写入数据)
***************************************************************/
void WriteDat(uint8_t IIC_Data)
{
HAL_I2C_WriteByte(0x40, IIC_Data);
}
//д
void Send_Byte(uint8_t dat){
//I2C_SendData(I2C1, dat);
//while (RESET == I2C_GetFlagStatus(I2C1, I2C_STATUS_FLAG_TFE));
HAL_I2C_Master_Transmit(&hi2c1, 0x78, &dat, 1, 0xffffffff);
}
//
//mode:/ 0,;1,;
void OLED_WR_Byte(uint8_t dat,uint8_t mode)
{
if(mode){
//Send_Byte(0x40);
WriteDat(dat);
}
else{
//Send_Byte(0x00);
WriteCmd(dat);
}
//Send_Byte(dat);
//I2C_Stop();
}
//OLED
void OLED_DisPlay_On(void)
{
WriteCmd(0x8D);
WriteCmd(0x14);
WriteCmd(0xAF);
}
//OLED
void OLED_DisPlay_Off(void)
{
WriteCmd(0x8D);
WriteCmd(0x10);
WriteCmd(0xAE);
}
//浽OLED
void OLED_Refresh(void)
{
uint8_t i,n;
for(i=0;i<8;i++)
{
WriteCmd(0xb0+i);
WriteCmd(0x00);
WriteCmd(0x10);
for(n=0;n<128;n++)
{
WriteDat(OLED_GRAM[n][i]);
}
}
}
//
void OLED_Clear(void)
{
uint8_t i,n;
for(i=0;i<8;i++)
{
for(n=0;n<128;n++)
{
OLED_GRAM[n][i]=0;//
}
}
}
//
//x:0~127
//y:0~63
//t:1 0,
void OLED_DrawPoint(uint8_t x,uint8_t y,uint8_t t)
{
uint8_t i,m,n;
i=y/8;
m=y%8;
n=1<<m;
if(t){OLED_GRAM[x][i]|=n;}
else
{
OLED_GRAM[x][i]=~OLED_GRAM[x][i];
OLED_GRAM[x][i]|=n;
OLED_GRAM[x][i]=~OLED_GRAM[x][i];
}
}
//
//x1,y1:
//x2,y2:
void OLED_DrawLine(uint8_t x1,uint8_t y1,uint8_t x2,uint8_t y2,uint8_t mode)
{
uint16_t t;
int xerr=0,yerr=0,delta_x,delta_y,distance;
int incx,incy,uRow,uCol;
delta_x=x2-x1; //
delta_y=y2-y1;
uRow=x1;//
uCol=y1;
if(delta_x>0)incx=1; //
else if (delta_x==0)incx=0;//
else {incx=-1;delta_x=-delta_x;}
if(delta_y>0)incy=1;
else if (delta_y==0)incy=0;//
else {incy=-1;delta_y=-delta_x;}
if(delta_x>delta_y)distance=delta_x; //
else distance=delta_y;
for(t=0;t<distance+1;t++)
{
OLED_DrawPoint(uRow,uCol,mode);//
xerr+=delta_x;
yerr+=delta_y;
if(xerr>distance)
{
xerr-=distance;
uRow+=incx;
}
if(yerr>distance)
{
yerr-=distance;
uCol+=incy;
}
}
}
//x,y:
//r:
void OLED_DrawCircle(uint8_t x,uint8_t y,uint8_t r)
{
int a, b,num;
a = 0;
b = r;
while(2 * b * b >= r * r)
{
OLED_DrawPoint(x + a, y - b,1);
OLED_DrawPoint(x - a, y - b,1);
OLED_DrawPoint(x - a, y + b,1);
OLED_DrawPoint(x + a, y + b,1);
OLED_DrawPoint(x + b, y + a,1);
OLED_DrawPoint(x + b, y - a,1);
OLED_DrawPoint(x - b, y - a,1);
OLED_DrawPoint(x - b, y + a,1);
a++;
num = (a * a + b * b) - r*r;//
if(num > 0)
{
b--;
a--;
}
}
}
//λ,
//x:0~127
//y:0~63
//size1: 6x8/6x12/8x16/12x24
//mode:0,;1,
void OLED_ShowChar(uint8_t x,uint8_t y,uint8_t chr,uint8_t size1,uint8_t mode)
{
uint8_t i,m,temp,size2,chr1;
uint8_t x0=x,y0=y;
if(size1==8)size2=6;
else size2=(size1/8+((size1%8)?1:0))*(size1/2); //
chr1=chr-' '; //
for(i=0;i<size2;i++)
{
if(size1==8)
{temp=asc2_0806[chr1][i];} //0806
else if(size1==12)
{temp=asc2_1206[chr1][i];} //1206
else if(size1==16)
{temp=asc2_1608[chr1][i];} //1608
else if(size1==24)
{temp=asc2_2412[chr1][i];} //2412
else return;
for(m=0;m<8;m++)
{
if(temp&0x01)OLED_DrawPoint(x,y,mode);
else OLED_DrawPoint(x,y,!mode);
temp>>=1;
y++;
}
x++;
if((size1!=8)&&((x-x0)==size1/2))
{x=x0;y0=y0+8;}
y=y0;
}
}
//
//x,y:
//size1:С
//*chr:
//mode:0,;1,
void OLED_ShowString(uint8_t x,uint8_t y,uint8_t *chr,uint8_t size1,uint8_t mode)
{
while((*chr>=' ')&&(*chr<='~'))//ж!
{
OLED_ShowChar(x,y,*chr,size1,mode);
if(size1==8)x+=6;
else x+=size1/2;
chr++;
}
}
//m^n
uint32_t OLED_Pow(uint8_t m,uint8_t n)
{
uint32_t result=1;
while(n--)
{
result*=m;
}
return result;
}
//
//x,y :
//num :
//len :λ
//size:С
//mode:0,;1,
void OLED_ShowNum(uint8_t x,uint8_t y,uint32_t num,uint8_t len,uint8_t size1,uint8_t mode)
{
uint8_t t,temp,m=0;
if(size1==8)m=2;
for(t=0;t<len;t++)
{
temp=(num/OLED_Pow(10,len-t-1))%10;
if(temp==0)
{
OLED_ShowChar(x+(size1/2+m)*t,y,'0',size1,mode);
}
else
{
OLED_ShowChar(x+(size1/2+m)*t,y,temp+'0',size1,mode);
}
}
}
//
//x,y:
//num:
//mode:0,;1,
void OLED_ShowChinese(uint8_t x,uint8_t y,uint8_t num,uint8_t size1,uint8_t mode)
{
uint8_t m,temp;
uint8_t x0=x,y0=y;
uint16_t i,size3=(size1/8+((size1%8)?1:0))*size1; //
for(i=0;i<size3;i++)
{
if(size1==16)
{temp=Hzk1[num][i];}//16*16
else if(size1==24)
{temp=Hzk2[num][i];}//24*24
else if(size1==32)
{temp=Hzk3[num][i];}//32*32
else if(size1==64)
{temp=Hzk4[num][i];}//64*64
else return;
for(m=0;m<8;m++)
{
if(temp&0x01)OLED_DrawPoint(x,y,mode);
else OLED_DrawPoint(x,y,!mode);
temp>>=1;
y++;
}
x++;
if((x-x0)==size1)
{x=x0;y0=y0+8;}
y=y0;
}
}
//num
//space
//mode:0,;1,
void OLED_ScrollDisplay(uint8_t num,uint8_t space,uint8_t mode)
{
uint8_t i,n,t=0,m=0,r;
while(1)
{
if(m==0)
{
OLED_ShowChinese(128,24,t,16,mode); //дOLED_GRAM[][]
t++;
}
if(t==num)
{
for(r=0;r<16*space;r++) //
{
for(i=1;i<144;i++)
{
for(n=0;n<8;n++)
{
OLED_GRAM[i-1][n]=OLED_GRAM[i][n];
}
}
OLED_Refresh();
}
t=0;
}
m++;
if(m==16){m=0;}
for(i=1;i<144;i++) //
{
for(n=0;n<8;n++)
{
OLED_GRAM[i-1][n]=OLED_GRAM[i][n];
}
}
OLED_Refresh();
}
}
//x,y
//sizex,sizey,
//BMP[]д
//mode:0,;1,
void OLED_ShowPicture(uint8_t x,uint8_t y,uint8_t sizex,uint8_t sizey,uint8_t BMP[],uint8_t mode)
{
uint16_t j=0;
uint8_t i,n,temp,m;
uint8_t x0=x,y0=y;
sizey=sizey/8+((sizey%8)?1:0);
for(n=0;n<sizey;n++)
{
for(i=0;i<sizex;i++)
{
temp=BMP[j];
j++;
for(m=0;m<8;m++)
{
if(temp&0x01)OLED_DrawPoint(x,y,mode);
else OLED_DrawPoint(x,y,!mode);
temp>>=1;
y++;
}
x++;
if((x-x0)==sizex)
{
x=x0;
y0=y0+8;
}
y=y0;
}
}
}
//OLED
void OLED_Init(void)
{
HAL_Delay(1000);
WriteCmd(0xAE);//--turn off oled panel
WriteCmd(0x00);//---set low column address
WriteCmd(0x10);//---set high column address
WriteCmd(0x40);//--set start line address Set Mapping RAM Display Start Line (0x00~0x3F)
WriteCmd(0x81);//--set contrast control register
WriteCmd(0xCF);// Set SEG Output Current Brightness
WriteCmd(0xA1);//--Set SEG/Column Mapping 0xa0 0xa1
WriteCmd(0xC8);//Set COM/Row Scan Direction 0xc0· 0xc8
WriteCmd(0xA6);//--set normal display
WriteCmd(0xA8);//--set multiplex ratio(1 to 64)
WriteCmd(0x3f);//--1/64 duty
WriteCmd(0xD3);//-set display offset Shift Mapping RAM Counter (0x00~0x3F)
WriteCmd(0x00);//-not offset
WriteCmd(0xd5);//--set display clock divide ratio/oscillator frequency
WriteCmd(0x80);//--set divide ratio, Set Clock as 100 Frames/Sec
WriteCmd(0xD9);//--set pre-charge period
WriteCmd(0xF1);//Set Pre-Charge as 15 Clocks & Discharge as 1 Clock
WriteCmd(0xDA);//--set com pins hardware configuration
WriteCmd(0x12);
WriteCmd(0xDB);//--set vcomh
WriteCmd(0x40);//Set VCOM Deselect Level
WriteCmd(0x20);//-Set Page Addressing Mode (0x00/0x01/0x02)
WriteCmd(0x02);//
WriteCmd(0x8D);//--set Charge Pump enable/disable
WriteCmd(0x14);//--set(0x10) disable
WriteCmd(0xA4);// Disable Entire Display On (0xa4/0xa5)
WriteCmd(0xA6);// Disable Inverse Display On (0xa6/a7)
OLED_Clear();
WriteCmd(0xAF); //Set display on added by sensoryoung
HAL_Delay(200);
}
Physical display:
413275085
|