你的浏览器版本过低,可能导致网站不能正常访问!
为了你能正常使用网站功能,请使用这些浏览器。

如何用ML51单片机点亮

[复制链接]
gaosmile 发布时间:2020-12-20 22:53
双十一,看淘宝一直给我发优惠券,就买了一片OLED,0.96寸的,最后花费了4.54元。
微信图片_20201220224738.png


驱动芯片是SSD1315

微信图片_20201220224742.png
微信图片_20201220224746.png
第一,驱动不一样,老款是SSD1306,新款的是SSD1315,新款没有并口功能,但是模块是IIC,不影响,程序一样,电路一样。
第二,新款玻璃比老款的小了一圈,没用的玻璃边减去了,省点OLED玻璃,因为玻璃都是日本进口,玻璃省了,价格要便宜一点。
第三,引脚顺序不一样,老款依次是VCC、GND、SCL、SDA,新款则是GND、VCC、SCL、SDA。
所以我为了图便宜,买了新款的。只有4个管脚。
微信图片_20201220224748.png
第一步,点亮屏幕

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

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

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

  1. //对选用的管脚设置为开漏模式
  2.         MFP_P20_GPIO;
  3.         MFP_P21_GPIO;
  4.         P20_OPENDRAIN_MODE;
  5.         P21_OPENDRAIN_MODE;
复制代码

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

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

  1. sbit OLED_SCL=P2^0;//SCL
  2. sbit OLED_SDA=P2^1;//SDA
  3. sbit OLED_RES =P2^2;//RES
复制代码

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

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

  1. unsigned char code Hzk[][32]={
  2. {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*/
  3. {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*/
  4. {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*/
  5. {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*/
  6. {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*/
  7. };
复制代码

主程序代码如下所示

  1. //#include "ML51.h"        
  2. #include "oled.h"
  3. #include "bmp.h"
  4. int main(void)
  5. {        
  6. unsigned char t=' ';
  7.         OLED_Init();//初始化OLED
  8.         OLED_ColorTurn(0);//0正常显示,1 反色显示
  9.   OLED_DisplayTurn(0);//0正常显示 1 屏幕翻转显示
  10. while(1)
  11.         {               
  12. //                OLED_DrawBMP(0,0,128,64,BMP1);
  13. //                delay_ms(5);
  14. //                OLED_Clear();
  15. //                OLED_ShowChinese(0,0,0,16);
  16.                 OLED_ShowChinese(18,0,0,16);//中
  17.                 OLED_ShowChinese(36,0,1,16);//国
  18.                 OLED_ShowChinese(54,0,2,16);//电
  19.                 OLED_ShowChinese(72,0,3,16);//子
  20.                 OLED_ShowChinese(90,0,4,16);//网
  21. //        OLED_ShowChinese(108,0,6,16);
  22.                 OLED_ShowString(8,2,"bbs.21ic.com",16);
  23.                 OLED_ShowString(20,4,"2020/11/17",16);
  24.                 OLED_ShowString(0,6,"ASCII:",16);  
  25.                 OLED_ShowString(63,6,"CODE:",16);
  26.                 OLED_ShowChar(48,6,t,16);
  27.                 t++;
  28. if(t>'~')t=' ';
  29.                 OLED_ShowNum(103,6,t,3,16);
  30. //                delay_ms(5);
  31. //                OLED_Clear();
  32.         }         
  33. }
复制代码

接下来连接OLED的I2C接口与开发板,并使用开发板供电。
微信图片_20201220224751.png

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

最后献上我修改后的工程。
微信图片_20201220224754.png
后面我再试试改成用硬件I2C收发器控制。

以上完成第一步点亮屏幕。
第二步,应用到自己的项目中

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

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

  1. unsigned char code Hzk[][32]={
  2.         
  3. {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*/
  4. {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*/
  5. {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*/
  6. {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*/
  7. {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*/
  8. {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*/
  9. {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*/
  10. {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*/
  11.         
  12. {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*/
  13. {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*/

  14. {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*/
  15. {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*/

  16. {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*/
  17.         
  18. {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*/        

  19. };
复制代码


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

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

  1. //#include "ML51.h"        
  2. #include "oled.h"
  3. #include "bmp.h"

  4. int main(void)
  5. {        
  6.         char i=0;
  7.         
  8.         unsigned char t=' ';
  9.         OLED_Init();//初始化OLED
  10.         OLED_ColorTurn(0);//0正常显示,1 反色显示
  11.   OLED_DisplayTurn(0);//0正常显示 1 屏幕翻转显示
  12.         while(1)
  13.         {               


  14. //第一行显示8个字符16*8==128
  15. for(i=0;i<8;i++)
  16. OLED_ShowChinese(i*16,0,i,16);
  17. //第二行显示  温度:
  18. OLED_ShowChinese(0,2,8,16);//温
  19. OLED_ShowChinese(16,2,9,16);//度
  20. OLED_ShowChinese(32,2,12,16);//:
  21. //在第二行,第四个字符位置显示36
  22. OLED_ShowNum(48,2,36,2,16);
  23. OLED_ShowChar(66,2,'.',16);
  24. OLED_ShowNum(74,2,5,1,16);
  25. OLED_ShowChinese(90,2,13,16);//℃
  26. //在第三行显示字符串
  27. OLED_ShowString(8,4,"bbs.21ic.com",16);
  28. //delay_ms(5);
  29.         }         
  30.         
  31. }
复制代码

微信图片_20201220224757.png

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

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

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

微信图片_20201220224800.png

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

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

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

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


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




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

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


  7. /*
  8. P20,P21接I2C的OLED屏幕SCL与SDA接口,
  9. P24接NTC传感器接口,读取温度,并显示在OLED上
  10. */

  11. void main (void)
  12. {
  13.         unsigned int ADCRESULT;
  14.         float Rval;
  15.         float temp;
  16.         //        定义温度整数部分与小数部分
  17.         unsigned int temp_H,temp_L;
  18.         char i=0;

  19.         ADC_Open(ADC_SINGLE,1);                                        //Enable P24_ADC_CH1
  20.         ADC_ConvertTime(3,7);

  21.         //对选用的管脚设置为开漏模式
  22.         MFP_P20_GPIO;
  23.         MFP_P21_GPIO;
  24.         P20_OPENDRAIN_MODE;
  25.         P21_OPENDRAIN_MODE;

  26.         OLED_Init();//初始化OLED
  27.         OLED_ColorTurn(0);//0正常显示,1 反色显示
  28.         OLED_DisplayTurn(0);//0正常显示 1 屏幕翻转显示

  29.         while(1)
  30.         {
  31.                 set_ADCCON0_ADCS;                           // Software trig adc start
  32.                 while((ADCCON0|CLR_BIT7)==CLR_BIT7);         // wait ADCF = 1;
  33.                 ADCRESULT = (ADCRH<<4)+ADCRL;
  34.                 Rval=1000*((ADCRESULT*6.2)/(4095-ADCRESULT));
  35.                 temp=Res_to_Tem(Rval);
  36.                 temp_H=((unsigned int)(temp*10.0))/10;
  37.                 temp_L=((unsigned int)(temp*10.0))%10;

  38.                 for(i=0;i<8;i++)
  39.                 OLED_ShowChinese(i*16,0,i,16);
  40.                 //第二行显示  温度:
  41.                 OLED_ShowChinese(0,2,8,16);//温
  42.                 OLED_ShowChinese(16,2,9,16);//度
  43.                 OLED_ShowChinese(32,2,12,16);//:

  44.                 //在第二行,第四个字符位置显示36
  45.                 OLED_ShowNum(48,2,temp_H,2,16);
  46.                 OLED_ShowChar(64,2,'.',16);
  47.                 OLED_ShowNum(72,2,temp_L,1,16);

  48.                 OLED_ShowChinese(82,2,13,16);//℃
  49.                 //在第三行显示字符串
  50.                 OLED_ShowString(8,4,"bbs.21ic.com",16);
  51.                 //在第4行显示字符串
  52. //        OLED_ShowString(8,6,"gaoyang9992006",16);
  53.                 OLED_ShowString(0,6,"0123456789123456",16);               
  54.                 Timer2_Delay(24000000,128,5,100000);
  55.         }

  56. }
复制代码


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

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

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

微信图片_20201220224810.png

微信图片_20201220224804.png
收藏 1 评论1 发布时间:2020-12-20 22:53

举报

1个回答
Kevin_G 回答时间:2020-12-21 11:02:55
干货

所属标签

关于
我们是谁
投资者关系
意法半导体可持续发展举措
创新与技术
意法半导体官网
联系我们
联系ST分支机构
寻找销售人员和分销渠道
社区
媒体中心
活动与培训
隐私策略
隐私策略
Cookies管理
行使您的权利
官方最新发布
STM32N6 AI生态系统
STM32MCU,MPU高性能GUI
ST ACEPACK电源模块
意法半导体生物传感器
STM32Cube扩展软件包
关注我们
st-img 微信公众号
st-img 手机版