1474|7

6960

帖子

11

TA的资源

版主

楼主
 

【CW32L052测评】硬件I2C驱动OLED屏 [复制链接]

 

一直以来,大家对硬件I2C的驱动与使用有点不大支持,因为I2C硬件驱动,相比模拟的时序掌握比较难入手,移植也不是很方便,所以I2C模拟时序大行其道。

经过几天的学习CW32L052的用户手册,我发现其硬件的I2C的驱动的掌握难点在于,对其过 I2C 状态寄存器 I2Cx_STAT的掌握是一个难点,在其用户手册中,他的状态达28个之多,其中的26个为正常接收或发送状态,2个特殊状态(0xF8:I2C总线无可用信息;0x00: 总线错误)。其I2C状态码如下表所示:

 

经过学习官方的cw32l052_i2c.c中的函数,结合我以住驱动SSD1306的经验,成细的驱动了OLED屏,现在驱动方法分享如下:

1、选取合适的硬件I2C驱动管脚, 由于我原来在L083开发板上面使用了与LCD段码屏的管脚导致不起时序,所以这次我避免用到有可能起冲突的管脚。经查看原理图,开发板上的PB8,PB9是接到的开发板的EEPROM上的,原理图如下:

 于是,我选取PB8为SCL,PB9为SDA,经查看用户手册,这两个管脚为I2C1,复用管脚代码如下:

  PB08_AFx_I2C1SCL();
  PB09_AFx_I2C1SDA();

初始化的次序为:使能GPIOB的时钟——使能I2C1时钟——复用GPIO为I2C1——配置GPIO为GPIO_MODE_OUTPUT_OD模式——配置I2C的波特率——配置I2C1总线——使用能I2C1,具体代码如下:

void OLED_I2C_Init(void)
{
	GPIO_InitTypeDef GPIO_InitStructure = {0};
	I2C_InitTypeDef I2C_InitStruct = {0};
	
//	__RCC_GPIOB_CLK_ENABLE();
//	__RCC_I2C1_CLK_ENABLE();
	CW_SYSCTRL->AHBEN_f.GPIOB  = 1;
	CW_SYSCTRL->APBEN1_f.I2C1 = 1U;    //
	
	PB08_AFx_I2C1SCL();
  PB09_AFx_I2C1SDA();
	GPIO_InitStructure.Pins = I2C1_SCL_GPIO_PIN | I2C1_SDA_GPIO_PIN;
	GPIO_InitStructure.Mode = GPIO_MODE_OUTPUT_OD;
	GPIO_Init(I2C1_SCL_GPIO_PORT, &GPIO_InitStructure);
	
	I2C_InitStruct.I2C_Baud = 0x1; // 48000 000/(8*(1+11) = 500k
	I2C_InitStruct.I2C_BaudEn = ENABLE;
  I2C_InitStruct.I2C_FLT = DISABLE;
  I2C_InitStruct.I2C_AA =  DISABLE;
	
	I2C1_DeInit();
  I2C_Master_Init(CW_I2C1,&I2C_InitStruct);//初始化模块

	I2C_Cmd(CW_OLED_I2C, ENABLE);
}

此次I2C不起用中断,采取循环获取I2C状态来决定下一步数据写入的方法。

需要驱动OLED,首先发出起始信号,然后判断STA状态寄存器的状态来做下一步的动作。而驱动SSD1306最基本的函数为向其写入一个byte的数据,其他的都是可以通用的,具体实现的代码如下:

//向OLED寄存器地址写一个byte的数据
int I2C_WriteByte(uint8_t addr,uint8_t data)
{
	uint8_t u8i = 0, u8State;
  uint16_t timeout = 0xffff;
	I2C_GenerateSTART(CW_OLED_I2C, ENABLE);
	//获取状态
	while(1)
	{
		
		while((0 == I2C_GetIrq(CW_OLED_I2C)) && timeout--);
		if(timeout == 0) return 1;
		u8State = I2C_GetState(CW_OLED_I2C);
		switch(u8State) 
		{
			case 0x08:  //发送完START信号
				I2C_GenerateSTART(CW_OLED_I2C, DISABLE);
				I2C_Send7bitAddress(CW_OLED_I2C, OLED_ADDR, 0x00);
				break;
			case 0x18:  //发送完SLA+W信号,ACK已收到
				I2C_SendData(CW_OLED_I2C, addr);
				break;
			case 0x28:
				I2C_SendData(CW_OLED_I2C, data);
				u8i ++;
				break;
			case 0x20: //发送完SLA+W后从机返回NACK
				break;
			case 0x38: //主机在发送 SLA+W 阶段或者发送数据阶段丢失仲载  或者  主机在发送 SLA+R 阶段或者回应 NACK 阶段丢失仲裁
				I2C_GenerateSTART(CW_OLED_I2C, ENABLE);
        break;
			case 0x30:
				I2C_GenerateSTOP(CW_OLED_I2C, ENABLE);
				break;
			default:
				break;		
		}
		if(u8i>1)
		{
			I2C_GenerateSTOP(CW_OLED_I2C, ENABLE);
			I2C_ClearIrq(CW_OLED_I2C);
			break;
		}
		I2C_ClearIrq(CW_OLED_I2C);
		
	}
	return 0;
}

实现好这个函数后,我们使用以住的驱动库,就可以顺利的点亮OLED屏了,在主函数中我们写入测试函数:

	OLED_Init();
	SysTickDelay(500);
	OLED_Fill(0xff);
	SysTickDelay(500);
	OLED_Fill(0x00);
	SysTickDelay(500);
	OLED_ShowStr(31,2,"Hello World",1);
	OLED_ShowStr(10,5,"Hello CW32L052",2);

顺利的点亮OLED屏,效果如下:

 其余的代码我附上工程源码,有不足之处,请大家多多指教:

oled.zip (5.74 KB, 下载次数: 8)

 

最新回复

谢谢分享,期待后续!   详情 回复 发表于 2023-7-21 15:30
点赞(2) 关注
 
 

回复
举报

1700

帖子

0

TA的资源

五彩晶圆(初级)

沙发
 

初始化的次序总结的不错,谢谢分享

点评

感谢大佬的关注与肯定,我会继续努力学习,并把学习的分享给大家!  详情 回复 发表于 2023-7-21 08:43
 
 
 

回复

6960

帖子

11

TA的资源

版主

板凳
 
火辣西米秀 发表于 2023-7-21 08:40 初始化的次序总结的不错,谢谢分享

感谢大佬的关注与肯定,我会继续努力学习,并把学习的分享给大家!

 
 
 

回复

1469

帖子

0

TA的资源

五彩晶圆(初级)

4
 
不错的资料分享,初始化的次序总结的不错,谢谢分享

点评

谢谢大佬关注与肯定,学习使我快乐,生命不此,学习不断!  详情 回复 发表于 2023-7-21 11:57
 
 
 

回复

6960

帖子

11

TA的资源

版主

5
 
lkh747566933 发表于 2023-7-21 11:28 不错的资料分享,初始化的次序总结的不错,谢谢分享

谢谢大佬关注与肯定,学习使我快乐,生命不此,学习不断!

 
 
 

回复

6105

帖子

4

TA的资源

版主

6
 

Hello eeworld!

 
 
 

回复

7608

帖子

18

TA的资源

五彩晶圆(高级)

7
 

谢谢分享,期待后续!

点评

多谢大佬关注,一定加油继续写好帖子!  详情 回复 发表于 2023-7-21 15:52
个人签名

默认摸鱼,再摸鱼。2022、9、28

 
 
 

回复

6960

帖子

11

TA的资源

版主

8
 
freebsder 发表于 2023-7-21 15:30 谢谢分享,期待后续!

多谢大佬关注,一定加油继续写好帖子!

 
 
 

回复
您需要登录后才可以回帖 登录 | 注册

随便看看
查找数据手册?

EEWorld Datasheet 技术支持

相关文章 更多>>
推荐帖子
单片机、DSP、PLD/EDA的介绍、比较和分析

摘 要:当今,数字时代的核心动力便是单片机,DSP ,PLD/ EDA ,以其各自的特点满足了各种需要,推动着信息技术的快速发展。这里将对 ...

VxWorks操作系统及实时多任务程序设计

非常不错的资料,与大家分享 欢迎下载:)

全国大学生电子设计竞赛相关帖子汇总

由于帖子的不断更新以及论坛的现实篇幅有限,故难免会有一些好贴沉下去而不能发挥余热~~~ 在此特整理汇总全国大学生电子设计竞赛 ...

超级电容器贴近我们生活吗?

随着社会的快速发展,我们的生活也越来越方便快捷,它的功劳归功于智能家居。让我们一起来看看我们的生活智能到哪了? 智能家 ...

【基于NUCLEO-F746ZG电机开发应用】12.参数配置-定时器TIM1配置

在伺服电机的控制过程中,使电机能够按照自己的想法转起来,一定要用到PWM输出控制,但是PWM该如何产生,频率如何控制,占空比 ...

[HPM-DIY]hpm6750 openmv移植成功,使用cherryusb作为repl交互

使用官方板子hpm6750evkmini,移植成功openmv,全新的Board支持,移植过程中学到不少东西,新鲜玩意就是好。 使用ses工程进 ...

ZigBee无线传感器网络设计与实现

本书面向立志于进行ZigBee无线传感器网络开发的初学者以及向无线网络开发转型的工程师,按照理论实践相结合的思想,介绍了ZigBee ...

回顾2022展望2023+时间过的真快呀

时间过得真是快,转眼娃娃会走路讲话了 ●你的2022年是如何度过的 出差60天,游了西湖,桂林,夫子庙,完美躲避了疫情; ...

PWM整流电路的网侧滤波?

本帖最后由 乱世煮酒论天下 于 2024-5-16 22:45 编辑 PWM整流滤波单元的参数该怎么选择,网侧滤波器一般是LCL结构,有时还会 ...

IEC61850转Modbus RTU解决案例

IEC61850定义 IEC61850标准是电力系统自动化领域的全球通用标准。它通过标准的实现,实现了智能变电站的工程运作标准化。使得 ...

关闭
站长推荐上一条 1/9 下一条

 
EEWorld订阅号

 
EEWorld服务号

 
汽车开发圈

About Us 关于我们 客户服务 联系方式 器件索引 网站地图 最新更新 手机版

站点相关: 国产芯 安防电子 汽车电子 手机便携 工业控制 家用电子 医疗电子 测试测量 网络通信 物联网

北京市海淀区中关村大街18号B座15层1530室 电话:(010)82350740 邮编:100190

电子工程世界版权所有 京B2-20211791 京ICP备10001474号-1 电信业务审批[2006]字第258号函 京公网安备 11010802033920号 Copyright © 2005-2025 EEWORLD.com.cn, Inc. All rights reserved
快速回复 返回顶部 返回列表