当前位置:首页 > > 21ic电子网
[导读]双十一,看淘宝一直给我发优惠券,就买了一片OLED,0.96寸的,最后花费了4.54元……

出品 21ic论坛 gaoyang9992006

网站:21ic.com


双十一,看淘宝一直给我发优惠券,就买了一片OLED,0.96寸的,最后花费了4.54元。

大神教你如何用ML51单片机点亮



驱动芯片是SSD1315


大神教你如何用ML51单片机点亮

大神教你如何用ML51单片机点亮

第一,驱动不一样,老款是SSD1306,新款的是SSD1315,新款没有并口功能,但是模块是IIC,不影响,程序一样,电路一样。

第二,新款玻璃比老款的小了一圈,没用的玻璃边减去了,省点OLED玻璃,因为玻璃都是日本进口,玻璃省了,价格要便宜一点。

第三,引脚顺序不一样,老款依次是VCC、GND、SCL、SDA,新款则是GND、VCC、SCL、SDA。

所以我为了图便宜,买了新款的。只有4个管脚。

大神教你如何用ML51单片机点亮

第一步,点亮屏幕


得到一块新的屏幕,最重要的就是看能否点亮,点亮了才能使用做各种显示应用。而这个店家没有提供驱动代码,懒得自己写啊,这种通用的肯定有,I2C很容易GPIO模拟,然后搜其他店家,有不少提供驱动代码的,下载了移植到我的ML51开发板上试试。下面链接是厂家提供的驱动程序。


链接: https://pan.baidu.com/s/1jqHcX9fIyKdUirFoZ3qSCA 提取码: mj6e 复制这段内容后打开百度网盘手机App,操作更方便哦为方便下载,提供其中源码与取模软件的本地下载,资料说明看不看无所谓。


考虑到是I2C接口,如果用GPIO模拟,需要先设置为开漏模式,然后找到初始化代码,增加配置开漏模式的四行代码。

//对选用的管脚设置为开漏模式 MFP_P20_GPIO; MFP_P21_GPIO; P20_OPENDRAIN_MODE; P21_OPENDRAIN_MODE;

这里也可以看出我用的是P20与P21.


然后修改头文件中的管脚定义

sbit OLED_SCL=P2^0;//SCLsbit OLED_SDA=P2^1;//SDAsbit OLED_RES =P2^2;//RES

因为使用I2C,按照手册说明可以忽略RES。但是为了少修改一点内容,就先这么随意指定个管脚,不链接就是了。


通过取模软件,可以取出你想要的汉字,放入如下数组。

unsigned char code Hzk[][32]={{0x00,0x00,0xE0,0x40,0x40,0x40,0x40,0xFC,0x40,0x40,0x40,0x40,0x60,0xE0,0x00,0x00,0x00,0x00,0x07,0x02,0x02,0x02,0x02,0x7F,0x02,0x02,0x02,0x02,0x02,0x07,0x00,0x00},/*"中",0*/{0x00,0x00,0xF8,0x08,0x08,0x28,0x28,0x28,0xE8,0x28,0x28,0x38,0x28,0xF8,0x08,0x00,0x00,0x00,0x7F,0x20,0x20,0x29,0x29,0x29,0x2F,0x29,0x2F,0x2D,0x28,0x7F,0x00,0x00},/*"国",1*/{0x00,0x00,0x00,0xF0,0x20,0x20,0x20,0xFC,0x20,0x20,0x20,0xF0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x0F,0x05,0x05,0x05,0x7F,0x45,0x45,0x45,0x4F,0x40,0x60,0x78,0x60},/*"电",2*/{0x00,0x00,0x10,0x10,0x10,0x10,0x10,0xD0,0x30,0x30,0x10,0x08,0x80,0x80,0x00,0x00,0x01,0x01,0x01,0x01,0x21,0x21,0x41,0x7F,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x00},/*"子",3*/{0x00,0x00,0xF8,0x10,0x50,0x90,0x90,0x70,0x70,0x90,0xD0,0x70,0x30,0xF8,0x00,0x00,0x00,0x00,0x7F,0x00,0x08,0x06,0x01,0x1E,0x08,0x06,0x03,0x4E,0x40,0x7F,0x00,0x00},/*"网",4*/};

主程序代码如下所示

//#include "ML51.h" #include "oled.h"#include "bmp.h"int main(void){ unsigned char t=' '; OLED_Init();//初始化OLED OLED_ColorTurn(0);//0正常显示,1 反色显示 OLED_DisplayTurn(0);//0正常显示 1 屏幕翻转显示while(1) { // OLED_DrawBMP(0,0,128,64,BMP1);// delay_ms(5);// OLED_Clear();// OLED_ShowChinese(0,0,0,16); OLED_ShowChinese(18,0,0,16);//中 OLED_ShowChinese(36,0,1,16);//国 OLED_ShowChinese(54,0,2,16);//电 OLED_ShowChinese(72,0,3,16);//子 OLED_ShowChinese(90,0,4,16);//网// OLED_ShowChinese(108,0,6,16); OLED_ShowString(8,2,"bbs.21ic.com",16); OLED_ShowString(20,4,"2020/11/17",16); OLED_ShowString(0,6,"ASCII:",16);  OLED_ShowString(63,6,"CODE:",16); OLED_ShowChar(48,6,t,16); t++;if(t>'~')t=' '; OLED_ShowNum(103,6,t,3,16);// delay_ms(5);// OLED_Clear(); } }

接下来连接OLED的I2C接口与开发板,并使用开发板供电。
大神教你如何用ML51单片机点亮


烧录后,效果如下图所示。然后就可以利用这个框架只需要修改简单的几个地方,就能实现OLED点亮了,可以用于其他的各种项目了。


最后献上我修改后的工程。

大神教你如何用ML51单片机点亮

后面我再试试改成用硬件I2C收发器控制。


以上完成第一步点亮屏幕。

第二步,应用到自己的项目中


如果需要显示温湿度的话,就可以利用这些函数组合出你要显示的内容,例如显示“温度:36.5℃”。


则需要先生成所需的汉字与符号字模。


unsigned char code Hzk[][32]={ {0x00,0x00,0xE0,0x40,0x40,0x40,0x40,0xFC,0x40,0x40,0x40,0x40,0x60,0xE0,0x00,0x00,0x00,0x00,0x07,0x02,0x02,0x02,0x02,0x7F,0x02,0x02,0x02,0x02,0x02,0x07,0x00,0x00},/*"中",0*/{0x00,0x00,0xF8,0x08,0x08,0x28,0x28,0x28,0xE8,0x28,0x28,0x38,0x28,0xF8,0x08,0x00,0x00,0x00,0x7F,0x20,0x20,0x29,0x29,0x29,0x2F,0x29,0x2F,0x2D,0x28,0x7F,0x00,0x00},/*"国",1*/{0x00,0x00,0x00,0xF0,0x20,0x20,0x20,0xFC,0x20,0x20,0x20,0xF0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x0F,0x05,0x05,0x05,0x7F,0x45,0x45,0x45,0x4F,0x40,0x60,0x78,0x60},/*"电",2*/{0x00,0x00,0x10,0x10,0x10,0x10,0x10,0xD0,0x30,0x30,0x10,0x08,0x80,0x80,0x00,0x00,0x01,0x01,0x01,0x01,0x21,0x21,0x41,0x7F,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x00},/*"子",3*/{0x00,0x00,0xF8,0x10,0x50,0x90,0x90,0x70,0x70,0x90,0xD0,0x70,0x30,0xF8,0x00,0x00,0x00,0x00,0x7F,0x00,0x08,0x06,0x01,0x1E,0x08,0x06,0x03,0x4E,0x40,0x7F,0x00,0x00},/*"网",4*/{0x00,0x80,0x80,0xC8,0x30,0x00,0x80,0x40,0x30,0x18,0x10,0x60,0xC0,0x80,0x80,0x80,0x00,0x00,0x00,0x3F,0x12,0x09,0x04,0x7F,0x44,0x44,0x42,0x43,0x42,0x78,0x60,0x00},/*"论",5*/{0x40,0x40,0x40,0xF8,0x40,0x60,0xC0,0x90,0x90,0x90,0x90,0x90,0x90,0x98,0xD0,0x80,0x00,0x10,0x10,0x1F,0x08,0x08,0x60,0x30,0x2C,0x27,0x23,0x25,0x28,0x30,0x60,0x00},/*"坛",6*/{0x00,0x00,0x00,0x18,0xF8,0x18,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x18,0x1B,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00},/*"!",7*/ {0x00,0x40,0xC0,0x18,0x90,0x60,0xF8,0xA8,0xA8,0xA8,0xA8,0xA8,0xF8,0x08,0x00,0x00,0x00,0x04,0x7C,0x7E,0x01,0x00,0x21,0x3E,0x22,0x3E,0x22,0x3E,0x23,0x3E,0x22,0x20},/*"温",8*/{0x00,0x00,0x00,0xF0,0x90,0x90,0x90,0xF4,0x98,0x90,0x90,0xF0,0x90,0xD8,0x90,0x00,0x00,0x40,0x30,0x0F,0x40,0x44,0x44,0x4F,0x35,0x25,0x35,0x6F,0x64,0x40,0x40,0x00},/*"度",9*/
{0x00,0x40,0xC0,0x98,0x60,0x00,0xF8,0xA8,0xA8,0xA8,0xA8,0xA8,0xA8,0xF8,0x08,0x00,0x04,0x04,0x7E,0x01,0x20,0x24,0x3D,0x20,0x3F,0x20,0x20,0x3F,0x24,0x27,0x33,0x20},/*"湿",10*/{0x00,0x00,0x00,0xF0,0x90,0x90,0x90,0xF4,0x98,0x90,0x90,0xF0,0x90,0xD8,0x90,0x00,0x00,0x40,0x30,0x0F,0x40,0x44,0x44,0x4F,0x35,0x25,0x35,0x6F,0x64,0x40,0x40,0x00},/*"度",11*/
{0x00,0x00,0x00,0x80,0x80,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x11,0x19,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00},/*":",12*/ {0x00,0x00,0x78,0x48,0x78,0xC0,0xE0,0x10,0x08,0x08,0x08,0x08,0x10,0x38,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x03,0x0F,0x08,0x10,0x10,0x10,0x10,0x08,0x08,0x04,0x00},/*"℃",13*/
};


最后显示的效果如下图所示,如果将温度的数字通过读取传感器继续更新,就可以看到实时的温度了。


然后合理的利OLED厂家提供的库函数组合。


//#include "ML51.h" #include "oled.h"#include "bmp.h"
int main(void){ char i=0; unsigned char t=' '; OLED_Init();//初始化OLED OLED_ColorTurn(0);//0正常显示,1 反色显示 OLED_DisplayTurn(0);//0正常显示 1 屏幕翻转显示 while(1) {

//第一行显示8个字符16*8==128for(i=0;i<8;i++)OLED_ShowChinese(i*16,0,i,16);//第二行显示 温度:OLED_ShowChinese(0,2,8,16);//温OLED_ShowChinese(16,2,9,16);//度OLED_ShowChinese(32,2,12,16);//://在第二行,第四个字符位置显示36OLED_ShowNum(48,2,36,2,16);OLED_ShowChar(66,2,'.',16);OLED_ShowNum(74,2,5,1,16);OLED_ShowChinese(90,2,13,16);//℃//在第三行显示字符串OLED_ShowString(8,4,"bbs.21ic.com",16);//delay_ms(5); } }


大神教你如何用ML51单片机点亮


在使用中遇到了一个问题,我在main.c和oled.h都引用了头文件#include "ML51.h"        


导致编译后报错重复定义。然后我删除了main.c中的,重新设置了引用头文件路径,完美解决。


另外如果你修改了目录,或者重建了目录结构,需要在这里也修改一下,不然工程无法找到对应的exe。


大神教你如何用ML51单片机点亮


..\Library\Startup\exe\hex2bin.exe  .\output\@L.hex


运行该命令可以生成所需的hex文件。


第三步,添加其他的外设驱动,实现显示检测数据显示功能


这里我使用的是ADC检测温度,然后通过该屏幕显示。



已经添加了NTC传感器。效果非常好



大神教你如何用ML51单片机点亮

还有就是使用的GPIO,一定要初始化为GPIO模式的开漏模式,不然无法驱动屏幕。


//***********************************************************************************************************// File Function: 通过ML51的GPIO P20、P21驱动I2C显示屏,通过P24_ADC_CH1测量NTC传感器阻抗,然后换算成温度显示在I2C屏幕上//***********************************************************************************************************//#include "ML51.h"#include "oled.h"#include "NTC.h"

/*P20,P21接I2C的OLED屏幕SCL与SDA接口,P24接NTC传感器接口,读取温度,并显示在OLED上*/
void main (void){ unsigned int ADCRESULT; float Rval; float temp; // 定义温度整数部分与小数部分 unsigned int temp_H,temp_L; char i=0;
ADC_Open(ADC_SINGLE,1); //Enable P24_ADC_CH1 ADC_ConvertTime(3,7);
//对选用的管脚设置为开漏模式 MFP_P20_GPIO; MFP_P21_GPIO; P20_OPENDRAIN_MODE; P21_OPENDRAIN_MODE;
OLED_Init();//初始化OLED OLED_ColorTurn(0);//0正常显示,1 反色显示 OLED_DisplayTurn(0);//0正常显示 1 屏幕翻转显示
while(1) { set_ADCCON0_ADCS; // Software trig adc start while((ADCCON0|CLR_BIT7)==CLR_BIT7); // wait ADCF = 1; ADCRESULT = (ADCRH<<4)+ADCRL; Rval=1000*((ADCRESULT*6.2)/(4095-ADCRESULT)); temp=Res_to_Tem(Rval); temp_H=((unsigned int)(temp*10.0))/10; temp_L=((unsigned int)(temp*10.0))%10;
for(i=0;i<8;i++) OLED_ShowChinese(i*16,0,i,16); //第二行显示 温度: OLED_ShowChinese(0,2,8,16);//温 OLED_ShowChinese(16,2,9,16);//度 OLED_ShowChinese(32,2,12,16);//:
//在第二行,第四个字符位置显示36 OLED_ShowNum(48,2,temp_H,2,16); OLED_ShowChar(64,2,'.',16); OLED_ShowNum(72,2,temp_L,1,16);
OLED_ShowChinese(82,2,13,16);//℃ //在第三行显示字符串 OLED_ShowString(8,4,"bbs.21ic.com",16); //在第4行显示字符串// OLED_ShowString(8,6,"gaoyang9992006",16); OLED_ShowString(0,6,"0123456789123456",16); Timer2_Delay(24000000,128,5,100000); }
}


另外对于字符是使用的8*16的字模,所以每行可以显示16个字符,共计可以显示4行。

大神教你如何用ML51单片机点亮

这样既可以驱动屏幕,又可以通过ADC读取分压,换算成温度,显示到屏幕的预定位置了。


注意事项:需要注意的是,如果多文件使用到同一个头文件,应避免重复引用,以免报错重定向,而将其中放到一处引用即可。通过该实例,大家可以学习到驱动程序的移植方法,同时也可以让大家注意到,可移植能力的重要性,以避免面对不同MCu时候重复工作,本项目中使用到的厂家的驱动程序,即充分考虑了可移植性,只需要做最简单的底层映射即可正常使用。

大神教你如何用ML51单片机点亮

本文系21ic论坛网友gaoyang9992006原创



大神教你如何用ML51单片机点亮

免责声明:本文内容由21ic获得授权后发布,版权归原作者所有,本平台仅提供信息存储服务。文章仅代表作者个人观点,不代表本平台立场,如有问题,请联系我们,谢谢!

21ic电子网

扫描二维码,关注更多精彩内容

本站声明: 本文章由作者或相关机构授权发布,目的在于传递更多信息,并不代表本站赞同其观点,本站亦不保证或承诺内容真实性等。需要转载请联系该专栏作者,如若文章内容侵犯您的权益,请及时联系本站删除。
换一批
延伸阅读

随着现代家庭生活方式不断升级,厨房已不再只是功能空间,而逐渐成为融合审美表达、健康管理与智能体验的重要场域。消费者在关注空间整体性的同时,也对食材储存的安全性、洁净度以及使用便利性提出了更高要求。基于对中国家庭真实使用场...

关键字: 冰箱 嵌入式

在嵌入式系统、工业物联网等各类电子设备中,UART与网口是两种应用广泛的通信接口,前者作为经典的串行通信接口,承担着简单设备互联、调试日志传输等基础任务,后者则专注于高速、远距离的数据交互,是设备接入网络、实现大数据量传...

关键字: 嵌入式 通信接口 网口通讯

在单片机的世界里,“字节”(Byte)是一个贯穿始终的核心概念。从存储数据到执行指令,从变量定义到外设通信,字节无处不在。很多初学者在学习单片机时,往往更关注复杂的程序逻辑和外设驱动,却忽略了字节这个基础知识点,导致在后...

关键字: 单片机 字节

在单片机的数字逻辑中,我们通常最关注的是高电平和低电平两种状态,它们构成了二进制数字世界的基础。然而,除了这两种状态之外,还有一种至关重要但常常被忽视的状态——高阻态(High Impedance State)。高阻态就...

关键字: 单片机 高阻态

在软件开发领域,设计模式被誉为“解决特定问题的最佳实践”,但在嵌入式开发中,它却常常处于“边缘地带”。许多嵌入式工程师职业生涯中可能从未刻意使用过设计模式,甚至认为这些“软件工程理论”与单片机、传感器、实时系统等硬件紧密...

关键字: 嵌入式 设计模式

对于PIC入门者来说,不需要盲目追求高端开发板,一块功能均衡、资料丰富的入门款就能满足需求。比如Microchip官方推出的PIC16F84A开发板,它搭载经典的8位PIC内核,引脚布局清晰,自带LED、按键等基础外设,...

关键字: PIC 单片机

在居住结构持续演进与消费需求不断升级的背景下,中国家庭厨房正经历从“功能集合”向“系统空间”的深层转变。厨房不再只是烹饪的场所,而逐渐成为融合效率、健康、美学与家庭互动的重要生活空间。基于对这一趋势的长期洞察,西门子家电...

关键字: 嵌入式 蒸玲珑

该低功耗器件支持5V运行,在实现高性能的同时,能有效保障系统简洁性与成本效益

关键字: MCU 单片机 工业自动化

在物联网设备、工业控制系统和智能家居等嵌入式场景中,轻量级WEB服务器扮演着核心角色。它们不仅需要满足资源受限环境下的性能需求,还需兼顾安全性、可扩展性和开发效率。本文从资源占用、功能特性、适用场景三个维度,对比分析六大...

关键字: 嵌入式 WEB服务器

在嵌入式软件开发工具领域,一场悄然的变革正在发生。随着全球软件行业向订阅制转型,嵌入式软件开发工具的授权模式也迎来了重要调整。市场上的嵌入式软件开发工具基本可以分为三类:商用开发工具,开源开发工具和厂商私有开发工具,其中...

关键字: 嵌入式 MCU RISC-V
关闭