511 views|0 replies

118

Posts

1

Resources
The OP
 

[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


This post is from RF/Wirelessly
 

Guess Your Favourite
Just looking around
Find a datasheet?

EEWorld Datasheet Technical Support

Featured Posts
Studying Things to Gain Knowledge 05: Dimensions and Elementary Functions

What is dimension? It is usually taught in middle school physics courses and again in university physics courses. Howev ...

EBAZ4205 mining board transformation based on Z7010

This post was last edited by chenzhufly on 2019-6-11 00:32 The main changes were to the power supply, adding a serial ...

Domestic MCU replacement: a pitfall

  As a fan of Butterfly, I feel sorry for the shortage and price increase of STM32. But whether you are making product ...

AD5933 can measure impedance accurately, but cannot measure phase angle accurately

I am a newbie. I want to ask why the real and imaginary parts of the AD5933 are constantly changing when I use a single- ...

[Flower carving DIY] Interesting and fun music visualization series of small projects (07) --- large square spectrum light

I had the urge to do a series of topics on sound visualization. This topic is a bit difficult and covers a wide range of ...

When studying the working principle of RCD circuit, what is the energy accumulated in the parasitic inductance?

Is it the parasitic inductance of the switch? 626540 Then I saw a circuit similar to RCD function in the PFC circuit. Is ...

Electric vehicle drive system motor controller vehicle communication network

Electric vehicle drive system motor controller vehicle communication network The vehicle CAN communication network has m ...

【ACM32G103RCT6] + UART function evaluation

The ACM32G103RCT6 development board has three UARTs on board, namely UART1, UART2, UART3 and UART4. UART2 is used as deb ...

Read the check-in terminal: Security vulnerability analysis - "Run Linux Kernel 2: Debugging and Case Analysis"

Members of the Linux reading group: @iysheng, @maskmoo, @ oxlm_1, @ jobszheng5 , @ y909334873 , @hardcorekingclassmate , ...

【FireBeetle 2 ESP32 C6】espnow test 2

Modify the program so that a signal is sent when the button is pressed and the LED flashes when the signal is received. ...

快速回复 返回顶部 Return list