X
首页
技术
模拟电子
单片机
半导体
电源管理
嵌入式
传感器
最能打国产芯
应用
汽车电子
工业控制
家用电子
手机便携
安防电子
医疗电子
网络通信
测试测量
物联网
最能打国产芯
大学堂
首页
直播
专题
TI 培训
论坛
汽车电子
国产芯片
电机驱动控制
电源技术
单片机
模拟电子
PCB设计
电子竞赛
DIY/开源
嵌入式系统
医疗电子
颁奖专区
【厂商专区】
【电子技术】
【创意与实践】
【行业应用】
【休息一下】
最能打国产芯
活动中心
直播
发现活动
颁奖区
电子头条
参考设计
下载中心
分类资源
文集
排行榜
电路图
Datasheet
最能打国产芯
国产芯片交流
[MCU] 上海航芯ACM32G103开发板学习笔记10(OLED显示温湿度信息)
qzc0927
2024-1-22 20:04
楼主
## 12:OLED显示 采用IIC接口的0.96寸OLED来显示信息数据。高分辨率:128x64(和12864同分辨率,高PPI),宽电压供电(3V~5V),兼容3.3V和5V电平逻辑,无需电平转换芯片。 ### 12.1:硬件设计 产品接口定义如下: ![image-20240122111310370](https://boreyun.oss-cn-shanghai.aliyuncs.com/image-20240122111310370.png) 对应主板接口: ![image-20240122200247429](https://boreyun.oss-cn-shanghai.aliyuncs.com/image-20240122200247429.png) 对应SCL引脚为PA5.SDA引脚为PA6。 ### 12.2:软件设计 群里用的是硬件的IIC接口来实现OLED的显示,我这里就采用软件模拟IIC来实现 1:首先定义GPIO引脚的信息 ```C #define DRV_OLED_GPIO GPIOA #define DRV_OLED_SCL_PIN GPIO_PIN_5 #define DRV_OLED_SDA_PIN GPIO_PIN_6 #define DRV_OLED_MODE GPIO_MODE_OUTPUT_PP #define DRV_OLED_PULL GPIO_PULLUP #define DRV_OLED_DRIVE GPIO_DRIVE_LEVEL3 #define DRV_OLED_ALTERNATE GPIO_FUNCTION_0 #define DRV_OLED_CLK_ENABLE() __RCC_GPIOD_CLK_ENABLE() void I2C_Write_SDA(GPIO_PinState H_L) { GPIO_WriteBit(DRV_OLED_GPIO,DRV_OLED_SDA_PIN,H_L); } void I2C_Write_SCL(GPIO_PinState H_L) { GPIO_WriteBit(DRV_OLED_GPIO,DRV_OLED_SCL_PIN,H_L); } #define OLED_READ_SDA GPIO_ReadPin(DRV_OLED_GPIO,DRV_OLED_SDA_PIN) ``` 2:配置OLED引脚输入和输出 ```C //初始化IIC void OLED_IIC_Init(void) { GPIO_InitTypeDefGPIO_InitStruct; /* EnableClock */ DRV_OLED_CLK_ENABLE(); GPIO_InitStruct.Pin = DRV_OLED_SCL_PIN|DRV_OLED_SDA_PIN; GPIO_InitStruct.Mode = DRV_OLED_MODE; GPIO_InitStruct.Pull = DRV_OLED_PULL; GPIO_InitStruct.Drive = DRV_OLED_DRIVE; GPIO_InitStruct.Alternate = DRV_OLED_ALTERNATE; GPIO_Init(DRV_OLED_GPIO, &GPIO_InitStruct); GPIO_WriteBit(DRV_OLED_GPIO, DRV_OLED_SCL_PIN, GPIO_PIN_SET); GPIO_WriteBit(DRV_OLED_GPIO, DRV_OLED_SDA_PIN, GPIO_PIN_SET); } ``` 接着进行模拟IIC时序: ```C //产生IIC起始信号 void OLED_IIC_Start(void) { OLED_SDA_OUT(); //sda线输出 I2C_Write_SDA(GPIO_PIN_SET); I2C_Write_SCL(GPIO_PIN_SET); delay_us(4); I2C_Write_SDA(GPIO_PIN_RESET); delay_us(4); I2C_Write_SCL(GPIO_PIN_RESET); } //产生IIC停止信号 void OLED_IIC_Stop(void) { OLED_SDA_OUT();//sda线输出 I2C_Write_SCL(GPIO_PIN_RESET); I2C_Write_SDA(GPIO_PIN_RESET); delay_us(4); I2C_Write_SCL(GPIO_PIN_SET); I2C_Write_SDA(GPIO_PIN_SET); delay_us(4); } //等待应答信号到来 //返回值:1,接收应答失败 // 0,接收应答成功 u8 OLED_IIC_Wait_Ack(void) { u8 ucErrTime=0; OLED_SDA_IN(); //SDA设置为输入 I2C_Write_SDA(GPIO_PIN_SET); delay_us(1); I2C_Write_SCL(GPIO_PIN_SET); delay_us(1); while(OLED_READ_SDA) { ucErrTime++; if(ucErrTime>250) { OLED_IIC_Stop(); return 1; } } I2C_Write_SCL(GPIO_PIN_RESET); return 0; } //产生ACK应答 void OLED_IIC_Ack(void) { I2C_Write_SCL(GPIO_PIN_RESET); OLED_SDA_OUT(); I2C_Write_SDA(GPIO_PIN_RESET); delay_us(2); I2C_Write_SCL(GPIO_PIN_SET); delay_us(2); I2C_Write_SCL(GPIO_PIN_RESET); } //不产生ACK应答 void OLED_IIC_NAck(void) { I2C_Write_SCL(GPIO_PIN_RESET); OLED_SDA_OUT(); I2C_Write_SDA(GPIO_PIN_SET); delay_us(2); I2C_Write_SCL(GPIO_PIN_SET); delay_us(2); I2C_Write_SCL(GPIO_PIN_RESET); } //IIC发送一个字节 //返回从机有无应答 //1,有应答 //0,无应答 void OLED_IIC_Send_Byte(u8 txd) { u8 t; OLED_SDA_OUT(); I2C_Write_SCL(GPIO_PIN_RESET); for(t=0;t<8;t++) { I2C_Write_SDA((txd&0x80)>>7); txd<<=1; delay_us(2); I2C_Write_SCL(GPIO_PIN_SET); delay_us(2); I2C_Write_SCL(GPIO_PIN_RESET); delay_us(2); } OLED_IIC_Wait_Ack(); } //读1个字节,ack=1时,发送ACK,ack=0,发送nACK u8 OLED_IIC_Read_Byte(unsigned char ack) { unsigned char i,receive=0; OLED_SDA_IN();//SDA设置为输入 for(i=0;i<8;i++ ) { I2C_Write_SCL(GPIO_PIN_RESET); delay_us(2); I2C_Write_SCL(GPIO_PIN_SET); receive<<=1; if(OLED_READ_SDA)receive++; delay_us(1); } if (!ack) OLED_IIC_NAck();//发送nACK else OLED_IIC_Ack(); //发送ACK return receive; } ``` 3:OLED初始化 ```C /*********************OLED初始化************************************/ void OLED_Init(void) { delay_ms (500); //这里的延时很重要 OLED_WrCmd(0xae);//--turn off oled panel OLED_WrCmd(0x00);//---set low column address OLED_WrCmd(0x10);//---set high column address OLED_WrCmd(0x40);//--set start line addressSet Mapping RAM Display Start Line (0x00~0x3F) OLED_WrCmd(0x81);//--set contrast control register OLED_WrCmd(Brightness); // Set SEG Output Current Brightness OLED_WrCmd(0xa1);//--Set SEG/Column Mapping 0xa0左右反置 0xa1正常 OLED_WrCmd(0xc8);//Set COM/Row Scan Direction 0xc0上下反置 0xc8正常 OLED_WrCmd(0xa6);//--set normal display OLED_WrCmd(0xa8);//--set multiplex ratio(1 to 64) OLED_WrCmd(0x3f);//--1/64 duty OLED_WrCmd(0xd3);//-set display offset Shift Mapping RAM Counter (0x00~0x3F) OLED_WrCmd(0x00);//-not offset OLED_WrCmd(0xd5);//--set display clock divide ratio/oscillator frequency OLED_WrCmd(0x80);//--set divide ratio, Set Clock as 100 Frames/Sec OLED_WrCmd(0xd9);//--set pre-charge period OLED_WrCmd(0xf1);//Set Pre-Charge as 15 Clocks & Discharge as 1 Clock OLED_WrCmd(0xda);//--set com pins hardware configuration OLED_WrCmd(0x12); OLED_WrCmd(0xdb);//--set vcomh OLED_WrCmd(0x40);//Set VCOM Deselect Level OLED_WrCmd(0x20);//-Set Page Addressing Mode (0x00/0x01/0x02) OLED_WrCmd(0x02);// OLED_WrCmd(0x8d);//--set Charge Pump enable/disable OLED_WrCmd(0x14);//--set(0x10) disable OLED_WrCmd(0xa4);// Disable Entire Display On (0xa4/0xa5) OLED_WrCmd(0xa6);// Disable Inverse Display On (0xa6/a7) OLED_WrCmd(0xaf);//--turn on oled panel OLED_Fill(0x00); //初始清屏 OLED_Set_Pos(0,0); } ``` 4:汉字显示 使用字符转换工具PCtoLCD2002,将要显示的信息,转换为字符串; ![image-20240122130846726](https://boreyun.oss-cn-shanghai.aliyuncs.com/image-20240122130846726.png) 具体字符如下: ```C typedef struct { unsigned char Index[2]; unsigned char Msk[32]; } typFNT_GB16; static const typFNT_GB16 tfont16[] = { "温",0x10,0x60,0x02,0x8C,0x00,0x00,0xFE,0x92,0x92,0x92,0x92,0x92,0xFE,0x00,0x00,0x00, 0x04,0x04,0x7E,0x01,0x40,0x7E,0x42,0x42,0x7E,0x42,0x7E,0x42,0x42,0x7E,0x40,0x00,/*"温",3*/ "度",0x00,0x00,0xFC,0x24,0x24,0x24,0xFC,0x25,0x26,0x24,0xFC,0x24,0x24,0x24,0x04,0x00, 0x40,0x30,0x8F,0x80,0x84,0x4C,0x55,0x25,0x25,0x25,0x55,0x4C,0x80,0x80,0x80,0x00,/*"度",4*/ "湿",0x10,0x60,0x02,0x8C,0x00,0xFE,0x92,0x92,0x92,0x92,0x92,0x92,0xFE,0x00,0x00,0x00, 0x04,0x04,0x7E,0x01,0x44,0x48,0x50,0x7F,0x40,0x40,0x7F,0x50,0x48,0x44,0x40,0x00,/*"湿",2*/ } ``` 编写字符显示函数: ```C /****************************************************************************** 函数说明:显示单个16x16汉字 入口数据:x,y显示坐标 *s 要显示的汉字 sizey 字号 mode: 字符串S有几个汉字 返回值:无 ******************************************************************************/ void LCD_ShowChinese16x16(uint16_t x, uint16_t y, uint8_t *s, uint8_t sizey) { uint8_t i= 0; uint16_t k; uint16_t HZnum;//汉字数目 HZnum = sizeof(tfont16) / sizeof(typFNT_GB16); //统计汉字数目 for(k = 0; k < HZnum; k++) { if ((tfont16[k].Index[0] == *(s)) && (tfont16[k].Index[1] == *(s + 1))) { OLED_Set_Pos(x,y); for(i = 0; i < sizey; i++) { OLED_WrDat(tfont16[k].Msk[i]); } OLED_Set_Pos(x,y+1); for(i = 0; i < sizey; i++) { OLED_WrDat(tfont16[k].Msk[i+sizey]); } } } } ``` 具体获取温湿度数据就不展开了。 ### 12.3:测试结果输出 将获取到的温湿度信息通过OLED显示出来: ![image-20240122195955748](https://boreyun.oss-cn-shanghai.aliyuncs.com/image-20240122195955748.png)
点赞
回复评论
暂无评论,赶紧抢沙发吧
最新活动
免费申请 | 上百份MPS MIE模块,免费试用还有礼!
TI 有奖直播 | 使用基于 Arm 的 AM6xA 处理器设计智能化楼宇
Follow me第二季第3期来啦!与得捷一起解锁高性能开发板【EK-RA6M5】超能力!
报名直播赢【双肩包、京东卡、水杯】| 高可靠性IGBT的新选择——安世半导体650V IGBT
30套RV1106 Linux开发板(带摄像头),邀您动手挑战边缘AI~
安世半导体理想二极管与负载开关,保障物联网应用的稳健高效运行
随便看看
【X-Nucleo深度评测】——收到板子啦
如何获取存储卡的总容量,可用容量和文件夹的大小
关于登录TI E2E社区的问题
BB方案大结局之上位机软件实现篇——基于BB及FPGA的DAQ及DDS设计与实现
单片机与对讲机无线能通电!!
这个电容起到什么样的作用呢?
STM8S208内部EEProm数据丢失
u-boot 汇编疑问
【CN0209】适合过程控制应用的完全可编程通用模拟前端
关于Wince中SDK的编译问题
运算放大器稳定性
新手请教 - 编译问题
AD19版本如何导入图片 运行脚本 软件闪退
吉时利3700系列主机——目标应用
能不能再开始一次AM33X开发板的团购呀?14:01的时候就全没了,需要的人都没买到。
关于JTAG下载程序问题
基于Proteus的ARM虚拟开发
内核中stuct ieee80211_node这个结构指的是什么
【转帖】贴片电感失效原因分析
学嵌入式 都学什么呀
电子工程世界版权所有
京B2-20211791
京ICP备10001474号-1
京公网安备 11010802033920号
回复
写回复
收藏
回复