3086 views|10 replies

565

Posts

0

Resources
The OP
 

【GD32L233C-START Review】6. Hardware I2C drive 0.96-inch OLED [Copy link]

Related articles:

[GD32L233C-START Review] 1. GD32L233C-START with obvious advantages and disadvantages (unboxing)

[GD32L233C-START Review] 2. Non-blocking way to light up, blink, blink, blink...

[GD32L233C-START Review] 3. PWM to achieve breathing light

[GD32L233C-START Review] 4. Serial port variable length data reception

[GD32L233C-START Review] 5. Flash Read and Write - Using Internal Flash to Store Data

1. About the I2C interface of GD32L233CCT6

It can be seen that there are two I2Cs , I2C0 and I2C1.

2. I2C pins on the development board

It can be seen that the pins of I2C1 are PB10 and PB11.

3. General pin multiplexing as I2C

It can be seen that it is multiplexing function 4.

4. Code Implementation

(1) Initialize i2c

void I2cInit(void)
{
	rcu_periph_clock_enable(RCU_I2C1);
	rcu_periph_clock_enable(RCU_GPIOB);

	gpio_af_set(GPIOB, GPIO_AF_4, GPIO_PIN_10);
    gpio_af_set(GPIOB, GPIO_AF_4, GPIO_PIN_11);

    gpio_mode_set(GPIOB, GPIO_MODE_AF, GPIO_PUPD_PULLUP, GPIO_PIN_10);
    gpio_output_options_set(GPIOB, GPIO_OTYPE_OD, GPIO_OSPEED_50MHZ, GPIO_PIN_10);
    gpio_mode_set(GPIOB, GPIO_MODE_AF, GPIO_PUPD_PULLUP, GPIO_PIN_11);
    gpio_output_options_set(GPIOB, GPIO_OTYPE_OD, GPIO_OSPEED_50MHZ, GPIO_PIN_11);
	
    /* configure I2C timing */
	i2c_timing_config(I2C1, 0, 0x3, 0);
    i2c_master_clock_config(I2C1, 0x13, 0x36);
	
    /* configure I2C address */
    i2c_address_config(I2C1, I2C_OWN_ADDRESS7, I2C_ADDFORMAT_7BITS);
    /* configure slave address */
    i2c_master_addressing(I2C1, I2C_SLAVE_ADDRESS7, I2C_MASTER_TRANSMIT);
    /* configure number of bytes to be transferred */
    i2c_transfer_byte_number_config(I2C1, 2);
    /* enable I2C1 */
    i2c_enable(I2C1);	
}

(2) Writing OLED

The commands and data are written separately below.

void SSD1306_WriteCmd(uint8_t var)
{
	/* wait until I2C bus is idle */
    while(i2c_flag_get(I2C1, I2C_FLAG_I2CBSY));
    /* send a start condition to I2C bus */
    i2c_start_on_bus(I2C1);
	
    /* wait until the transmit data buffer is empty */
    I2C_STAT(I2C1) |= I2C_STAT_TBE;
    while(!i2c_flag_get(I2C1, I2C_FLAG_TBE));

	/* data transmission */
	i2c_data_transmit(I2C1, 0x00);
    /* wait until the TI bit is set */
    while(!i2c_flag_get(I2C1, I2C_FLAG_TBE));
	
	i2c_data_transmit(I2C1, var);
    /* wait until the TI bit is set */
    while(!i2c_flag_get(I2C1, I2C_FLAG_TBE));
	
    /* wait for transfer complete flag */
    while(!i2c_flag_get(I2C1, I2C_FLAG_TC));
    /* send a stop condition to I2C bus */
    i2c_stop_on_bus(I2C1);
    /* wait until stop condition generate */
    while(!i2c_flag_get(I2C1, I2C_FLAG_STPDET));
    /* clear the STPDET bit */
    i2c_flag_clear(I2C1, I2C_FLAG_STPDET);
}

void SSD1306_WriteData(uint8_t var)
{
	/* wait until I2C bus is idle */
    while(i2c_flag_get(I2C1, I2C_FLAG_I2CBSY));
    /* send a start condition to I2C bus */
    i2c_start_on_bus(I2C1);
    /* wait until the transmit data buffer is empty */
    I2C_STAT(I2C1) |= I2C_STAT_TBE;
    while(!i2c_flag_get(I2C1, I2C_FLAG_TBE));

	/* data transmission */
	i2c_data_transmit(I2C1, 0x40);
    /* wait until the TI bit is set */
    while(!i2c_flag_get(I2C1, I2C_FLAG_TBE));
	
	i2c_data_transmit(I2C1, var);
    /* wait until the TI bit is set */
    while(!i2c_flag_get(I2C1, I2C_FLAG_TBE));
	
    /* wait for transfer complete flag */
    while(!i2c_flag_get(I2C1, I2C_FLAG_TC));
    /* send a stop condition to I2C bus */
    i2c_stop_on_bus(I2C1);
    /* wait until stop condition generate */
    while(!i2c_flag_get(I2C1, I2C_FLAG_STPDET));
    /* clear the STPDET bit */
    i2c_flag_clear(I2C1, I2C_FLAG_STPDET);
}

(3) OLED related drivers

//坐标设置:也就是在哪里显示
void OledSetPos(uint8_t x, uint8_t y) 
{ 
  //以下3个寄存器只在页寻址的模式下有效	
  SSD1306_WriteCmd(0xb0+y);             //页地址设置     0xb0~0xb7
  SSD1306_WriteCmd(((x&0xf0)>>4)|0x10); //列高位地址设置
  SSD1306_WriteCmd((x&0x0f));           //列低位地址设置
} 
 
//开启Oled显示
void OledDisplayOn(void)
{
  SSD1306_WriteCmd(0X8D);  //SET DCDC命令
  SSD1306_WriteCmd(0X14);  //DCDC ON
  SSD1306_WriteCmd(0XAF);  //DISPLAY ON
}
 
//关闭Oled显示   
void OledDisplayOff(void)
{
  SSD1306_WriteCmd(0X8D);  //SET DCDC命令
  SSD1306_WriteCmd(0X10);  //DCDC OFF
  SSD1306_WriteCmd(0XAE);  //DISPLAY OFF
}
 
//清屏函数,清完屏,整个屏幕是黑色的!和没点亮一样  
void OledClear(void)  
{  
  uint8_t i,n;	
  
  for(i=0;i<8;i++)  
  {  
    SSD1306_WriteCmd (0xb0+i);    //设置页地址(0~7)
    SSD1306_WriteCmd (0x00);      //设置显示位置—列低地址
    SSD1306_WriteCmd (0x10);      //设置显示位置—列高地址   
    for(n=0;n<128;n++)
      SSD1306_WriteData(0); 
  } //更新显示
}
 
//在指定位置显示一个字符,包括部分字符
//x:0~127,y:0~7
//Char_Size:选择字体 16/12 
void OledShowChar(uint8_t x,uint8_t y,uint8_t chr,uint8_t Char_Size)
{      	
  uint8_t c=0,i=0;	
  
  c=chr-' ';//得到偏移后的值			
  if(x>MAX_COLUMN-1)
  {
    x=0;
    y=y+2;
  }
  if(Char_Size ==16)
  {
    OledSetPos(x,y);	
    for(i=0;i<8;i++)
    {
      SSD1306_WriteData(F8X16[c*16+i]);//先写上半部分
    }
    
    OledSetPos(x,y+1);
    for(i=0;i<8;i++)
    {
      SSD1306_WriteData(F8X16[c*16+i+8]);//后写下半部分
    }
  }
  else
  {	
    OledSetPos(x,y);
    for(i=0;i<6;i++)
    {
      SSD1306_WriteData(F6x8[c][i]);
    }
  }
}
 
//显示一个字符串
void OledShowString(uint8_t x,uint8_t y,char *str,uint8_t Char_Size)
{
  unsigned char j=0;
  
  while (str[j]!='\0')
  {
    OledShowChar(x,y,str[j],Char_Size);
    x+=8;
    if(x>120)
    {
      x=0;
      y+=2;
    }
    j++;//移动一次就是一个page,取值0-7
  }
}
 
//显示汉字
//由于汉字是16*16大小的,所以最多显示4行汉字
//index:在汉字取模中的索引
void OledShowCN(uint8_t x,uint8_t y,uint8_t index)
{      			    
  uint8_t t;
	
  OledSetPos(x,y);	
  for(t=0;t<16;t++)
  {
    SSD1306_WriteData(Hzk[index][t]);
  }	
  
  OledSetPos(x,y+1);	
  for(t=0;t<16;t++)
  {	
    SSD1306_WriteData(Hzk[index][t+16]);
  }					
}

(4) OLED initialization

void OledInit(void)
{
  DelayMs(300);
  DelayMs(300);

  //SSD1306复位之后,默认的是页寻址方式
  
  SSD1306_WriteCmd(0xAE);//--display off
  
  SSD1306_WriteCmd(0x00);//--set low column address
  SSD1306_WriteCmd(0x10);//--set high column address
  SSD1306_WriteCmd(0x40);//--set start line address  
  
  SSD1306_WriteCmd(0xB0);//--set page address
  
  SSD1306_WriteCmd(0x81);// contract control
  SSD1306_WriteCmd(0xFF);//--128   
  SSD1306_WriteCmd(0xA1);//set segment re-map  0 to 127 
  SSD1306_WriteCmd(0xA6);//set normal  display  
  SSD1306_WriteCmd(0xA8);//set multiplex ratio(1 to 64)
  SSD1306_WriteCmd(0x3F);//--1/32 duty
  
  SSD1306_WriteCmd(0xC8);//Com scan direction
  SSD1306_WriteCmd(0xD3);//set display offset
  SSD1306_WriteCmd(0x00);//no offset
	
  SSD1306_WriteCmd(0xD5);//set display clock divide ratio/oscillator frequency  
  SSD1306_WriteCmd(0x80);//
	
  SSD1306_WriteCmd(0xD8);//set area color mode off
  SSD1306_WriteCmd(0x05);//
	
  SSD1306_WriteCmd(0xD9);//Set Pre-Charge Period
  SSD1306_WriteCmd(0xF1);//
	
  SSD1306_WriteCmd(0xDA);//set com pin  hardware configuartion
  SSD1306_WriteCmd(0x12);//
	
  SSD1306_WriteCmd(0xDB);//set Vcomh
  SSD1306_WriteCmd(0x30);//0x20,0.77xVcc
	
  SSD1306_WriteCmd(0x8D);//set charge pump enable
  SSD1306_WriteCmd(0x14);//
	
  SSD1306_WriteCmd(0xAF);//--turn on Oled panel
}

(5) Display test

void OledDisplayTest(void)
{
	I2cInit();
	OledInit();
	
	OledClear(); 

	OledShowString(28,0,(char *)("EEWORLD"),16);
	OledShowString(40,2,(char *)("GD32"),16);
	OledShowString(40,4,(char *)("2022"),16);

	OledShowCN(24,6,0);
	OledShowCN(40,6,1);
	OledShowCN(56,6,2);
	OledShowCN(72,6,3);
}

5. Phenomenon

I wish EEWORLD and GD32 official a prosperous 2022.

This post is from GD32 MCU

Latest reply

I2C_STAT(I2C1) |= I2C_STAT_TBE; Hi, can you elaborate on this? I am stuck in the while loop.   Details Published on 2022-5-2 18:05
Personal signaturestm32/LoRa物联网:304350312
 

565

Posts

0

Resources
2
 

Font library modeling method: negative code, reverse, column and row

This post is from GD32 MCU
 
Personal signaturestm32/LoRa物联网:304350312
 
 

6552

Posts

0

Resources
3
 

A series of summaries, like

The final display is interesting and powerful.

This post is from GD32 MCU
 
 
 

6818

Posts

11

Resources
4
 
Can I borrow your font library? I am evaluating the National Technology N32G457 development board and want to make an LCD display. Thank you!
This post is from GD32 MCU

Comments

Font library: Contains 6*8 dot matrix, 8*16 dot matrix and 4 Chinese character dot matrix  Details Published on 2022-1-24 09:01
 
 
 

565

Posts

0

Resources
5
 
lugl4313820 posted on 2022-1-23 22:41 Can I borrow your font library? I am doing a review of the National Technology N32G457 development board and also want to make an LCD display. Thank you!

Font: fontlib.h (12.82 KB, downloads: 1)

Contains 6*8 dot matrix, 8*16 dot matrix and 4 Chinese character dot matrix

This post is from GD32 MCU

Comments

Thank you very much! Please take care of me and learn from me in the future!  Details Published on 2022-1-24 13:32
 
Personal signaturestm32/LoRa物联网:304350312
 
 

565

Posts

0

Resources
6
 
Jacktang posted on 2022-1-23 22:23 A series of summaries, I like the last display, it is interesting and powerful

This post is from GD32 MCU
 
Personal signaturestm32/LoRa物联网:304350312
 
 

6818

Posts

11

Resources
7
 
freeelectron published on 2022-1-24 09:01 Font library: Contains 6*8 dot matrix, 8*16 dot matrix and 4 Chinese character dot matrix

Thank you very much! Please take care of me and learn from me in the future!

This post is from GD32 MCU

Comments

Mutual exchanges and common progress  Details Published on 2022-1-24 15:01
 
 
 

565

Posts

0

Resources
8
 
lugl4313820 posted on 2022-1-24 13:32 Thank you very much! Please take care of me in the future and learn from the teacher!

Mutual exchanges and common progress

This post is from GD32 MCU
 
Personal signaturestm32/LoRa物联网:304350312
 
 

16

Posts

0

Resources
9
 

Studying

This post is from GD32 MCU
 
 
 

1

Posts

0

Resources
10
 

I2C_STAT(I2C1) |= I2C_STAT_TBE; Hi, can you elaborate on this? I am stuck in the while loop.

This post is from GD32 MCU

Comments

Waiting for sending to be empty. There is something wrong. Take a look at the waveform.  Details Published on 2022-5-5 08:28
 
 
 

565

Posts

0

Resources
11
 
xiaoyiaixuexi posted on 2022-5-2 18:05 I2C_STAT(I2C1) |= I2C_STAT_TBE; Hi, can you elaborate on this? I'm always stuck in the while loop

Waiting for sending to be empty. There is something wrong. Take a look at the waveform.

This post is from GD32 MCU
 
Personal signaturestm32/LoRa物联网:304350312
 
 

Guess Your Favourite
Just looking around
Find a datasheet?

EEWorld Datasheet Technical Support

EEWorld
subscription
account

EEWorld
service
account

Automotive
development
circle

Copyright © 2005-2024 EEWORLD.com.cn, Inc. All rights reserved 京B2-20211791 京ICP备10001474号-1 电信业务审批[2006]字第258号函 京公网安备 11010802033920号
快速回复 返回顶部 Return list