原创 Nucleo_G070RB 评测之驱动LCD1602液晶显示

2019-6-6 17:03 4524 34 31 分类: MCU/ 嵌入式 文集: MCU
一、写在前面
5月份收到板子到现在,已经过去一个月了。到手时简单写了一个开箱评测,感觉确实太简单了,不过也得没办法,因为当时在ST官网找板子资料时,就将原理图找错了,那时候想做个按键控制LED都没办法。就这个原理图我都是前两个周才找到正确的,还不是在ST官网上找的。可能是因为这块板子刚出来不久吧,资料都要找好半天,真是醉了。
想当时还想着好好做个完整的显示系统,可是显示部分的内容直接把我就给搞崩溃了,好不容易搭建好电路,结果程序死活调试不出来,没办法,改电路结构,重新修改程序,直到今天早上才将程序调试OK,瞬间感觉自己好菜。
言归正传哦,这篇文章应该是评测文章的,想了解一块PCBA,那么原理图是必不可少的对吧,在我历尽千辛万苦将这个板子的原理图找到后,不得不感叹这个图画的不错,最少挺好看的,呵呵。算了不吐槽他的设计了,直接来看吧

三张图,第一个是原理图的目录,基本上没什么用,第二张图就是整个板子电路的顶层图(不知道这么说对不对),可以了解下他的电路连接结构,第三张就是扩展连接了,我一直将其理解为外设接口。这也是用户(我)最关心的部分,其他的就不贴了,文末看看附上附件给大家,大神请忽略(不过想来大佬也不会看我这种垃圾博文吧)。我用过几天后,确实不是很理解板子的扩展接口为什么是这样子排列的,为啥不能是一些常用的外接部件的接口呢?欢迎大家来讨论一波。

二、LCD1602驱动的内容

LCD602的一些介绍

LCD1602是一种工业字符型液晶,能够同时显示16x02即32个字符。LCD1602液晶显示的原理是利用液晶的物理特性,通过电压对其显示区域进行控制,即可以显示出图形。(来自度娘)

LCD1602引脚功能:

第 脚:VSS 为地电源。
第 脚:VDD 接 5V 正电源。
第 脚:VL 为液晶显示器对比度调整端,接正电源时对比度最弱,接地时对比度最高,对
比度过高时会产生鬼影,使用时可以通过一个 10K 的电位器调整对比度。
第 脚:RS 为寄存器选择,高电平时选择数据寄存器、低电平时选择指令寄存器。
第 脚:R/W 为读写信号线,高电平时进行读操作,低电平时进行写操作。当 RS 和 R/W
共同为低电平时可以写入指令或者显示地址,当 RS 为低电平 R/W 为高电平时可以读忙信
号,当 RS 为高电平 R/W 为低电平时可以写入数据。
第 脚:端为使能端,当 端由高电平跳变成低电平时,液晶模块执行命令。
第 714 脚:D0D7 为 位双向数据线。
第 15 脚:背光源正极。
第 16 脚:背光源负极

在STM32CubeMX中新建项目,选择正确的MCU型号(我直接选了Nucleo-g070rb板子),

然后根据板子实际情况设置时钟,这块板子最高主频可以设64MHz,但是我选了36MHz,

接下来配置至于IO口,如下面的图片

最后配置定时器TIM1,用来产生一毫秒延时,

生成工程文件,打开后,在工程中添加如下文件 LCD1602.c内容如下:

  • /*********************************************************************
    1. * 文件名称:LCD1602.C
    2. *********************************************************************/
    3. #include "stm32g070xx.h"
    4. #include "LCD1602.h"
    5. #include "gpio.h"

    6. /*******************************************************************************
    7. * 函 数 名         : LcdWriteCom
    8. * 函数功能    : 向LCD写入一个字节的命令
    9. * 输    入         : com
    10. * 输    出         : 无
    11. *******************************************************************************/
    12. void LcdWriteCom(uchar com)   //写入命令
    13. {
    14. delay_nms(10);
    15. LCD_EN_0;     //使能
    16. LCD_RS_0;    //选择发送命令
    17. LCD_RW_0;    //选择写入
    18. DATAOUT = com;     //放入命令
    19. delay_nus(1); //等待数据稳定

    20. LCD_EN_1;           //写入时序
    21. delay_nus(5);   //保持时间
    22. LCD_EN_0;
    23. //delay_nms(1);
    24. }

    25. /*******************************************************************************
    26. * 函 数 名         : LcdWriteData
    27. * 函数功能    : 向LCD写入一个字节的数据
    28. * 输    入         : dat
    29. * 输    出         : 无
    30. *******************************************************************************/        
    31. void LCD_Writedata(uchar dat) //写入数据
    32. {
    33. delay_nms(10);
    34. LCD_EN_0; //使能清零
    35. LCD_RS_1; //选择输入数据
    36. LCD_RW_0; //选择写入

    37. DATAOUT = dat; //写入数据
    38. delay_nus(1);

    39. LCD_EN_1;   //写入时序
    40. delay_nus(5);   //保持时间
    41. LCD_EN_0;
    42. //delay_nms(1);
    43. }
    44. /*******************************************************************************
    45. * 函 数 名         : LCD_Setpos
    46. * 函数功能      : 设定显示位置
    47. * 输    入         :row:行,row=1表示第一行,row=2表示第二行
    48. *                    col:列,0~15,用于指定显示的列,范围可以是0~40
    49. * 输    出         : 无
    50. *******************************************************************************/
    51. void LCD_Setpos(uchar row,uchar col)
    52. {
    53. if(row==1) 
    54. LcdWriteCom(col | 0x80);
    55. else 
    56. LcdWriteCom(col | 0xC0);
    57. }

    58. /*********************************************************************
    59. * 函 数 名         : LCD_DispChar
    60. * 函数功能      : 显示一个字符
    61. * 输    入         : ch:待显示的字符
    62. * 输    出         : 无
    63. *********************************************************************/
    64. void LCD_DispChar(char ch)
    65. {
    66. LCD_Writedata(ch);
    67. }
    68. /*********************************************************************
    69. * 函 数 名         : LCD_DispChar
    70. * 函数功能      : 在指定位置显示一个字符   
    71. * 输    入         : row:行 1或2        col:列,0~15
    72. *        ch:待显示的字符
    73. * 输    出         : 无
    74. *********************************************************************/
    75. void LCD_Setpos_DispChar(uchar row,uchar col,char ch)
    76. {
    77. LCD_Setpos(row,col);
    78. LCD_Writedata(ch);
    79. }
    80. /*********************************************************************
    81. * 函 数 名         :LCD_DispString()
    82. * 函数功能         : 使LCD1602显示一个字符串,显示位置需提前设定
    83. * 输    入         : str[]:待显示的字符串
    84. * 输    出         : 无
    85. *********************************************************************/
    86. void LCD_DispString(unsigned char str[])
    87. {
    88.     uchar i=0;
    89. while(str != '\0')
    90. {
    91. LCD_Writedata(str);
    92. ++i;
    93. }
    94. }
    95. /*********************************************************************
    96. * 函 数 名         : LCD_DispChar
    97. * 函数功能      : 在指定位置显示一个字符   
    98. * 输    入         : row:行 1或2        col:列,0~15
    99. *        str[]:待显示的字符串
    100. * 输    出         : 无
    101. * 说    明         :指定位置是显示的初始位置,第一个字符显示的位置
    102. *********************************************************************/
    103. void LCD_Setpos_DispString(uchar row,uchar col,unsigned char str[])
    104. {
    105. LCD_Setpos(row,col);
    106. LCD_DispString(str);
    107. }

    108. /*******************************************************************************
    109. * 函 数 名       : LcdInit()
    110. * 函数功能    : 初始化LCD屏
    111. * 输    入       : 无
    112. * 输    出       : 无
    113. *******************************************************************************/    

    114. void LCD_Init()   //LCD初始化子程序
    115. {
    116.   LcdWriteCom(0x38);  //开显示
    117. delay_nms(10);
    118. LcdWriteCom(0x38);  //开显示
    119. delay_nms(10);
    120. LcdWriteCom(0x0e);  //开显示不显示光标
    121. delay_nms(10);
    122. LcdWriteCom(0x06);  //写一个指针加1
    123. delay_nms(10);
    124. LcdWriteCom(0x01);  //清屏
    125. //delay_nms(10);
    126. LcdWriteCom(0x80);  //设置数据指针起点
    127. //delay_nms(10);
    128. }

    之后就是man.c里面修修补补了

    首先是在主函数里面加上LCD调用函数和预先写入的字符,如下面所示

     /* USER CODE BEGIN 2 */

    /*************************************************************

    *                      LCD1602驱动显示

    *************************************************************/

    unsigned char str[]={"Happy Dragon "};  //Nucleo_G070RB

    unsigned char str1[]={"Boat Festival !"};  //mianbaoban.cn

    LCD_Init();

    LCD_Setpos_DispString(1,2,str);

    LCD_Setpos_DispString(2,0,str1);

      /* USER CODE END 2 */

    其次是在while循环里面加入如下语句,这个是将程序进入主循环后给LED4一个取反信号,便于调试

    HAL_GPIO_TogglePin(GPIOA,GPIO_PIN_5);

    delay_ms(10);

    显示效果如下面所示

    由于是刚开始接触STM32,所以很多问题都不太懂,欢迎大家批评指正,

    文章基本上到这里也就结束了,本来说上传原理图附件的,可是博文好像不行,或是我不知到,所以想要要的可以留个邮箱什么的,就这样把,谢谢大家翻阅,

    祝大家端午节快乐!

    注:本文程序部分参考http://www.51hei.com/mcu/2696.html文中程序





    作者: 江湖独行, 来源:面包板社区

    链接: https://mbb.eet-china.com/blog/uid-me-3882390.html

    版权声明:本文为博主原创,未经本人允许,禁止转载!

    文章评论0条评论)

    登录后参与讨论
    我要评论
    0
    34
    关闭 站长推荐上一条 /2 下一条