[N32L43X评测] 2.模拟I2C驱动OLED
[复制链接]
I2C总线是我们开发过程中经常使用的一种串行总线。
I2C主要功能特点包括:
1、只需要两条总线;
2、所有组件之间都存在简单的主/从关系,连接到总线的每个设备均可通过唯一地址进行软件寻址;
3、是真正的多主设备总线,可提供仲裁和冲突检测;
4、最大从机数:理论上是127;
5、传输速度:
标准模式:Standard Mode = 100 Kbps
快速模式:Fast Mode = 400 Kbps
高速模式:High speed mode = 3.4 Mbps
超快速模式:Ultra fast mode = 5 Mbps
I2C总线协议详解可参考以下资料:
UM10204_I2C-bus specification and user manual-Rev.7.0.pdf
(733.36 KB, 下载次数: 2)
I2C总线规范.pdf
(918.13 KB, 下载次数: 3)
此篇主要介绍GPIO软件模拟实现I2C来驱动0.96寸OLED显示屏,OLED显示屏资料:
0.96寸OLED使用文档V3.0.pdf
(1.68 MB, 下载次数: 3)
硬件连接
GND —— GND
VCC —— 3.3V
SCL —— PB8
SDA —— PB9
软件代码
I2C代码:
-
- void SDA_IN(void)
- {
- GPIO_InitType GPIO_InitStructure;
-
- RCC_EnableAPB2PeriphClk( SDA_GPIO_CRM_CLK, ENABLE);
-
- GPIO_InitStruct(&GPIO_InitStructure);
- GPIO_InitStructure.Pin = SDA_PIN;
- GPIO_InitStructure.GPIO_Slew_Rate = GPIO_Slew_Rate_High;
- GPIO_InitStructure.GPIO_Current = GPIO_DC_4mA;
- GPIO_InitStructure.GPIO_Pull = GPIO_Pull_Up;
- GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Input;
- GPIO_InitPeripheral(SDA_GPIO, &GPIO_InitStructure);
- }
-
-
- void SDA_OUT(void)
- {
- GPIO_InitType GPIO_InitStructure;
-
- RCC_EnableAPB2PeriphClk( SDA_GPIO_CRM_CLK, ENABLE);
-
- GPIO_InitStruct(&GPIO_InitStructure);
- GPIO_InitStructure.Pin = SDA_PIN;
- GPIO_InitStructure.GPIO_Slew_Rate = GPIO_Slew_Rate_High;
- GPIO_InitStructure.GPIO_Current = GPIO_DC_4mA;
- GPIO_InitStructure.GPIO_Pull = GPIO_Pull_Up;
- GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
- GPIO_InitPeripheral(SDA_GPIO, &GPIO_InitStructure);
- }
-
-
- void I2C_SCL(int n)
- {
- if(n == 1)
- {
- GPIO_WriteBit(SCL_GPIO, SCL_PIN, Bit_SET);
- }
- else
- {
- GPIO_WriteBit(SCL_GPIO, SCL_PIN, Bit_RESET);
- }
- }
-
-
- void I2C_SDA(int n)
- {
- if(n == 1)
- {
- GPIO_WriteBit(SDA_GPIO, SDA_PIN, Bit_SET);
- }
- else
- {
- GPIO_WriteBit(SDA_GPIO, SDA_PIN, Bit_RESET);
- }
- }
-
-
- unsigned char READ_SDA(void)
- {
- return GPIO_ReadInputDataBit(SDA_GPIO, SDA_PIN);
- }
-
-
- void I2C_Initial(void)
- {
- GPIO_InitType GPIO_InitStructure;
-
-
- RCC_EnableAPB2PeriphClk( SCL_GPIO_CRM_CLK, ENABLE);
- RCC_EnableAPB2PeriphClk( SDA_GPIO_CRM_CLK, ENABLE);
-
-
- GPIO_InitStruct(&GPIO_InitStructure);
- GPIO_InitStructure.Pin = SCL_PIN;
- GPIO_InitStructure.GPIO_Slew_Rate = GPIO_Slew_Rate_High;
- GPIO_InitStructure.GPIO_Current = GPIO_DC_4mA;
- GPIO_InitStructure.GPIO_Pull = GPIO_Pull_Up;
- GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
- GPIO_InitPeripheral(SCL_GPIO, &GPIO_InitStructure);
-
-
- GPIO_InitStruct(&GPIO_InitStructure);
- GPIO_InitStructure.Pin = SDA_PIN;
- GPIO_InitStructure.GPIO_Slew_Rate = GPIO_Slew_Rate_High;
- GPIO_InitStructure.GPIO_Current = GPIO_DC_4mA;
- GPIO_InitStructure.GPIO_Pull = GPIO_Pull_Up;
- GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
- GPIO_InitPeripheral(SDA_GPIO, &GPIO_InitStructure);
-
- I2C_SCL(1);
- I2C_SDA(1);
- }
-
-
- void I2C_Start(void)
- {
- SDA_OUT();
- I2C_SDA(1);
- I2C_SCL(1);
- Delay_Us(4);
- I2C_SDA(0);
- Delay_Us(4);
- I2C_SCL(0);
- }
-
-
- void I2C_Stop(void)
- {
- SDA_OUT();
- I2C_SCL(0);
- I2C_SDA(0);
- Delay_Us(4);
- I2C_SCL(1);
- I2C_SDA(1);
- Delay_Us(4);
- }
-
-
- unsigned char I2C_Wait_Ack(void)
- {
- unsigned char ucErrTime = 0;
-
- SDA_IN();
- I2C_SDA(1);
- Delay_Us(1);
- I2C_SCL(1);
- Delay_Us(1);
-
- while(READ_SDA())
- {
- ucErrTime++;
-
- if(ucErrTime > 250)
- {
- I2C_Stop();
- return HAL_ERROR;
- }
- }
-
- I2C_SCL(0);
- return HAL_OK;
- }
-
-
- void I2C_Ack(void)
- {
- I2C_SCL(0);
- SDA_OUT();
- I2C_SDA(0);
- Delay_Us(2);
- I2C_SCL(1);
- Delay_Us(2);
- I2C_SCL(0);
- }
-
-
- void I2C_NAck(void)
- {
- I2C_SCL(0);
- SDA_OUT();
- I2C_SDA(1);
- Delay_Us(2);
- I2C_SCL(1);
- Delay_Us(2);
- I2C_SCL(0);
- }
-
-
- void I2C_Send_Byte(unsigned char txd)
- {
- unsigned char cnt = 0;
-
- SDA_OUT();
- I2C_SCL(0);
-
- for(cnt = 0; cnt < 8; cnt++)
- {
- I2C_SDA((txd & 0x80) >> 7);
- txd <<= 1;
- Delay_Us(2);
- I2C_SCL(1);
- Delay_Us(2);
- I2C_SCL(0);
- Delay_Us(2);
- }
- }
-
-
- unsigned char I2C_Read_Byte(unsigned char ack)
- {
- unsigned char cnt, rec = 0;
-
- SDA_IN();
-
- for(cnt = 0; cnt < 8; cnt++)
- {
- I2C_SCL(0);
- Delay_Us(2);
- I2C_SCL(1);
- rec <<= 1;
-
- if(READ_SDA())
- {
- rec++;
- }
-
- Delay_Us(1);
- }
-
- if(!ack)
- {
- I2C_NAck();
- }
- else
- {
- I2C_Ack();
- }
-
- return rec;
- }
OLED代码:
-
- static void OLED_Write_CMD(unsigned char cmd)
- {
- I2C_Start();
- I2C_Send_Byte(0x78);
- I2C_Wait_Ack();
- I2C_Send_Byte(0x00);
- I2C_Wait_Ack();
- I2C_Send_Byte(cmd);
- I2C_Wait_Ack();
- I2C_Stop();
- }
-
-
- static void OLED_Write_Date(unsigned char date)
- {
- I2C_Start();
- I2C_Send_Byte(0x78);
- I2C_Wait_Ack();
- I2C_Send_Byte(0x40);
- I2C_Wait_Ack();
- I2C_Send_Byte(date);
- I2C_Wait_Ack();
- I2C_Stop();
- }
-
-
- static void OLED_Set_Pos(unsigned char x, unsigned char y)
- {
- OLED_Write_CMD(0xB0 + y);
- OLED_Write_CMD(((x & 0xF0) >> 4) | 0x10);
- OLED_Write_CMD(x & 0x0F);
- }
-
-
- static void OLED_Display_On(void)
- {
- OLED_Write_CMD(0x8D);
- OLED_Write_CMD(0x14);
- OLED_Write_CMD(0xAF);
- }
-
-
- static void OLED_Display_Off(void)
- {
- OLED_Write_CMD(0x8D);
- OLED_Write_CMD(0x10);
- OLED_Write_CMD(0xAE);
- }
-
-
- void OLED_Clear(void)
- {
- unsigned char cnt, count;
-
- for(cnt = 0; cnt < 8; cnt++)
- {
- OLED_Write_CMD(0xB0 + cnt);
- OLED_Write_CMD(0x00);
- OLED_Write_CMD(0x10);
-
- for(count = 0; count < 128; count++)
- {
- OLED_Write_Date(0x00);
- }
- }
- }
-
-
- void OLED_Clear_Row(unsigned char n)
- {
- unsigned char count;
-
- OLED_Write_CMD(0xB0 + n);
- OLED_Write_CMD(0x00);
- OLED_Write_CMD(0x10);
-
- for(count = 0; count < 128; count++)
- {
- OLED_Write_Date(0x00);
- }
- }
-
-
- void OLED_Fill(void)
- {
- unsigned char cnt, count;
-
- for(cnt = 0; cnt < 8; cnt++)
- {
- OLED_Write_CMD(0xB0 + cnt);
- OLED_Write_CMD(0x00);
- OLED_Write_CMD(0x10);
-
- for(count = 0; count < 128; count++)
- {
- OLED_Write_Date(0x01);
- }
- }
- }
-
-
-
-
-
-
- void OLED_ShowChar(unsigned char x, unsigned char y, unsigned char chr, unsigned char size)
- {
- unsigned char offset = 0, cnt = 0;
-
- offset = chr - ' ';
-
- if(x > 128 - 1)
- {
- x = 0;
- y = y + 2;
- }
-
- if(size == 16)
- {
- OLED_Set_Pos(x, y);
-
- for(cnt = 0; cnt < 8; cnt++)
- {
- OLED_Write_Date(F8x16[offset * 16 + cnt]);
- }
-
- OLED_Set_Pos(x, y + 1);
-
- for(cnt = 0; cnt < 8; cnt++)
- {
- OLED_Write_Date(F8x16[offset * 16 + cnt + 8]);
- }
- }
- else
- {
- OLED_Set_Pos(x, y);
-
- for(cnt = 0; cnt < 6; cnt++)
- {
- OLED_Write_Date(F6x8[offset][cnt]);
- }
- }
- }
-
- unsigned int oled_pow(unsigned char m, unsigned char n)
- {
- unsigned int result = 1;
-
- while(n--)
- {
- result *= m;
- }
-
- return result;
- }
-
-
-
-
-
-
- void OLED_ShowNum(unsigned char x, unsigned char y, unsigned int num, unsigned char len, unsigned char size)
- {
- unsigned char cnt, temp;
- unsigned char show = 0;
-
- for(cnt = 0; cnt < len; cnt++)
- {
- temp = (num / oled_pow(10, len - cnt - 1)) % 10;
-
- if(show == 0 && cnt < (len - 1))
- {
- if(temp == 0)
- {
- OLED_ShowChar(x + (size / 2) * cnt, y, ' ', size);
- continue;
- }
- else
- {
- show = 1;
- }
- }
-
- OLED_ShowChar(x + (size / 2) * cnt, y, temp + '0', size);
- }
- }
-
-
- void OLED_ShowString(unsigned char x, unsigned char y, unsigned char *chr, unsigned char size)
- {
- unsigned char cnt = 0;
-
- while(chr[cnt] != '\0')
- {
- OLED_ShowChar(x, y, chr[cnt], size);
- x += 8;
-
- if(x > 120)
- {
- x = 0;
- y += 2;
- }
-
- cnt++;
- }
- }
-
-
- void OLED_ShowCHinese(unsigned char x, unsigned char y, unsigned char no)
- {
- unsigned char cnt, addr = 0;
-
- OLED_Set_Pos(x, y);
-
- for(cnt = 0; cnt < 16; cnt++)
- {
- OLED_Write_Date(Hzk[2 * no][cnt]);
- addr++;
- }
-
- OLED_Set_Pos(x, y + 1);
-
- for(cnt = 0; cnt < 16; cnt++)
- {
- OLED_Write_Date(Hzk[2 * no + 1][cnt]);
- addr++;
- }
- }
-
-
-
- void OLED_DrawBMP(unsigned char x0, unsigned char y0, unsigned char x1, unsigned char y1, const unsigned char BMP[])
- {
- unsigned int j = 0;
- unsigned char x, y;
-
- if(y1 % 8 == 0)
- {
- y = y1 / 8;
- }
- else
- {
- y = y1 / 8 + 1;
- }
-
- for(y = y0; y < y1; y++)
- {
- OLED_Set_Pos(x0, y);
-
- for(x = x0; x < x1; x++)
- {
- OLED_Write_Date(BMP[j++]);
- }
- }
- }
-
-
-
- void OLED_DrawGIF(unsigned char x0, unsigned char y0, unsigned char x1, unsigned char y1, unsigned char k, int m, const unsigned char GIF[][m])
- {
- unsigned int j = 0;
- unsigned char x, y, i;
-
- if(y1 % 8 == 0)
- {
- y = y1 / 8;
- }
- else
- {
- y = y1 / 8 + 1;
- }
-
- for (i = 0; i < k; i++)
- {
- j = 0;
-
- for(y = y0; y < y1; y++)
- {
- OLED_Set_Pos(x0, y);
-
- for(x = x0; x < x1; x++)
- {
- OLED_Write_Date(GIF[i][j++]);
- }
- }
-
-
- }
- }
-
-
- void OLED_Init(void)
- {
- I2C_Initial();
- Delay_Ms(200);
- OLED_Write_CMD(0xAE);
- OLED_Write_CMD(0x00);
- OLED_Write_CMD(0x10);
- OLED_Write_CMD(0x40);
- OLED_Write_CMD(0xB0);
- OLED_Write_CMD(0x81);
- OLED_Write_CMD(0xFF);
- OLED_Write_CMD(0xA1);
- OLED_Write_CMD(0xA6);
- OLED_Write_CMD(0xA8);
- OLED_Write_CMD(0x3F);
- OLED_Write_CMD(0xC8);
- OLED_Write_CMD(0xD3);
- OLED_Write_CMD(0x00);
- OLED_Write_CMD(0xD5);
- OLED_Write_CMD(0x80);
- OLED_Write_CMD(0xD8);
- OLED_Write_CMD(0x05);
- OLED_Write_CMD(0xD9);
- OLED_Write_CMD(0xF1);
- OLED_Write_CMD(0xDA);
- OLED_Write_CMD(0x12);
- OLED_Write_CMD(0xDB);
- OLED_Write_CMD(0x30);
- OLED_Write_CMD(0x8D);
- OLED_Write_CMD(0x14);
- OLED_Write_CMD(0xAF);
- }
运行测试
鎾斁鍣ㄥ姞杞藉け璐�: 鏈娴嬪埌Flash Player锛岃鍒� 瀹夎
SW_I2C_OLED
测试代码
N32L43x_SW_I2C_OLED.zip
(516.95 KB, 下载次数: 31)
|