找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 8851|回复: 4
打印 上一主题 下一主题
收起左侧

STM32最小系统+面包板控制1602液晶显示

[复制链接]
跳转到指定楼层
楼主
ID:313060 发表于 2019-1-21 15:36 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
最近老师布置一个小任务用STM32控制1602,本来觉得应该很简单,但是在学习过程中也出现很多问题,很多疑问。

1、TFTLCD可以被当做SRAM使用,LCD1602可以当做什么使用吗?
2、可以通过FSMC想TFT一样吗?
3、对于5V的LCD1602,3.3VSTM32引脚应该怎么设置?

因为担心不小心就烧坏芯片,所以我用最小系统来做,用面包板来搭1602的电路。
我发现大家都是直接用51上使用的方法直接在STM32上用,自己也没有继续在想其他办法。
程序基本是:1、利用位带操作设置好1602三只控制脚和指示灯(八个数据脚用数据寄存器来完成)
                   2、LCD1602写入8位命令子函数和LCD1602写入8位数据子函数、LCD1602初始化子程序
                   3、GPIO初始化
最后的效果是1602显示正常,LED闪烁。
值得留意的是:八个数据脚用数据寄存器来完成
                      GPIO初始化的时候,数据的引脚GPIOE(2-9)用开漏输出,控制引脚用推挽输出GPIOF(0-3)(其实我是想全部设置成开漏输出的,因为网上大家都是找到FT(可以承受5V的引脚),然后设置开漏输出,但是控制引脚用开漏输出无法正常显示,不知道什么原因)
                     除了标有ADC其他引脚都是可以承受5V的,芯片数据手册和原理图可以查阅。
                     STM32连接LCD1602要接保护电阻,偷懒就没有加上了 。
                     不懂寄存器可以查参考手册。
                     GPIO输出方式可以看固件库使用手册。

制作出来的实物图如下:


电路原理图如下:


单片机源程序如下:
  1. #include "stm32f10x.h"
  2. //位带操作,实现51类似的GPIO控制功能
  3. //具体实现思想,参考<<CM3权威指南>>第五章(87页~92页).
  4. //IO口操作宏定义
  5. #define BITBAND(addr, bitnum) ((addr & 0xF0000000)+0x2000000+((addr &0xFFFFF)<<5)+(bitnum<<2))
  6. #define MEM_ADDR(addr)  *((volatile unsigned long  *)(addr))
  7. #define BIT_ADDR(addr, bitnum)   MEM_ADDR(BITBAND(addr, bitnum))
  8. //IO口地址映射
  9. #define GPIOA_ODR_Addr    (GPIOA_BASE+12) //0x4001080C
  10. #define GPIOB_ODR_Addr    (GPIOB_BASE+12) //0x40010C0C
  11. #define GPIOC_ODR_Addr    (GPIOC_BASE+12) //0x4001100C
  12. #define GPIOD_ODR_Addr    (GPIOD_BASE+12) //0x4001140C
  13. #define GPIOE_ODR_Addr    (GPIOE_BASE+12) //0x4001180C
  14. #define GPIOF_ODR_Addr    (GPIOF_BASE+12) //0x40011A0C   
  15. #define GPIOG_ODR_Addr    (GPIOG_BASE+12) //0x40011E0C   

  16. #define GPIOA_IDR_Addr    (GPIOA_BASE+8) //0x40010808
  17. #define GPIOB_IDR_Addr    (GPIOB_BASE+8) //0x40010C08
  18. #define GPIOC_IDR_Addr    (GPIOC_BASE+8) //0x40011008
  19. #define GPIOD_IDR_Addr    (GPIOD_BASE+8) //0x40011408
  20. #define GPIOE_IDR_Addr    (GPIOE_BASE+8) //0x40011808
  21. #define GPIOF_IDR_Addr    (GPIOF_BASE+8) //0x40011A08
  22. #define GPIOG_IDR_Addr    (GPIOG_BASE+8) //0x40011E08

  23. //IO口操作,只对单一的IO口!
  24. //确保n的值小于16!
  25. #define PAout(n)   BIT_ADDR(GPIOA_ODR_Addr,n)  //输出
  26. #define PAin(n)    BIT_ADDR(GPIOA_IDR_Addr,n)  //输入

  27. #define PBout(n)   BIT_ADDR(GPIOB_ODR_Addr,n)  //输出
  28. #define PBin(n)    BIT_ADDR(GPIOB_IDR_Addr,n)  //输入

  29. #define PCout(n)   BIT_ADDR(GPIOC_ODR_Addr,n)  //输出
  30. #define PCin(n)    BIT_ADDR(GPIOC_IDR_Addr,n)  //输入

  31. #define PDout(n)   BIT_ADDR(GPIOD_ODR_Addr,n)  //输出
  32. #define PDin(n)    BIT_ADDR(GPIOD_IDR_Addr,n)  //输入

  33. #define PEout(n)   BIT_ADDR(GPIOE_ODR_Addr,n)  //输出
  34. #define PEin(n)    BIT_ADDR(GPIOE_IDR_Addr,n)  //输入

  35. #define PFout(n)   BIT_ADDR(GPIOF_ODR_Addr,n)  //输出
  36. #define PFin(n)    BIT_ADDR(GPIOF_IDR_Addr,n)  //输入

  37. #define PGout(n)   BIT_ADDR(GPIOG_ODR_Addr,n)  //输出
  38. #define PGin(n)    BIT_ADDR(GPIOG_IDR_Addr,n)  //输入


  39. #define LCD1602_E PFout(0)          //LCD1602_E连接的是PC2管脚
  40. #define LCD1602_RS PFout(1)          //LCD1602_RS连接的是PC3管脚
  41. #define LCD1602_RW PFout(2)        //LCD1602_RW连接的是PC4管脚
  42. #define Led PFout(3)

  43. /*??????*/
  44. #define TIME_MS 12000                        //@72M
  45. #define TIME_US 10                                //@72M


  46. /*************************
  47. 函数声明
  48. *************************/
  49. /*延时函数*/
  50. void Delay_ms(u16 n);
  51. /*LCD1602写入8位命令子函数*/
  52. void LcdWriteCom(u16 com);
  53. /*LCD1602写入8位数据子函数*/
  54. void LcdWriteData(u16 dat);
  55. /*LCD1602初始化子程序*/
  56. void LcdInit(void);
  57. /*GPIO初始化*/
  58. void LCD_1602GPIO_Init(void);

  59. u8 Disp[] = " Pechin Science ";
  60. u8 dat[]="0123456789ABCDEF";

  61. /*?????*/
  62. void Delay_ms(u16 n)
  63. {
  64.         u16 i,j;
  65.        
  66.         for(i=n;i>0;i--)
  67.                 for(j=TIME_MS;j>0;j--);
  68. }

  69. /*?????*/
  70. void Delay_us(u16 n)
  71. {
  72.         u16 i,j;
  73.        
  74.         for(i=n;i>0;i--)
  75.                 for(j=TIME_US;j>0;j--);
  76. }
  77. /*GPIO初始化函数*/
  78. void LCD_1602GPIO_Init(void)
  79. {
  80.         GPIO_InitTypeDef        GPIO_InitStructure;//定义结构体变量
  81.        
  82.         RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOE,ENABLE);//使能GPIOE时钟
  83.        
  84.         GPIO_InitStructure.GPIO_Pin=GPIO_Pin_2|GPIO_Pin_3|GPIO_Pin_4|GPIO_Pin_5|GPIO_Pin_6|GPIO_Pin_7|GPIO_Pin_8|GPIO_Pin_9;//选择你要设置的IO口
  85.         GPIO_InitStructure.GPIO_Mode=GPIO_Mode_Out_OD;        //设置开漏输出模式
  86.         GPIO_InitStructure.GPIO_Speed=GPIO_Speed_50MHz;//设置传输速率
  87.         GPIO_Init(GPIOE,&GPIO_InitStructure);        //初始化GPIO
  88.                
  89.         GPIO_SetBits(GPIOE,GPIO_Pin_2|GPIO_Pin_3|GPIO_Pin_4|GPIO_Pin_5|GPIO_Pin_6|GPIO_Pin_7|GPIO_Pin_8|GPIO_Pin_9);        //将GPIOE端口拉高,熄灭所有LED


  90.         RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOF,ENABLE);//使能GPIOF时钟
  91.        
  92.         GPIO_InitStructure.GPIO_Pin=GPIO_Pin_0|GPIO_Pin_1|GPIO_Pin_2|GPIO_Pin_3;//选择你要设置的IO口
  93.         GPIO_InitStructure.GPIO_Mode=GPIO_Mode_Out_PP;        //设置推挽输出模式
  94.         GPIO_InitStructure.GPIO_Speed=GPIO_Speed_50MHz;//设置传输速率
  95.         GPIO_Init(GPIOF,&GPIO_InitStructure);        //初始化GPIO
  96.                
  97.         GPIO_SetBits(GPIOF,GPIO_Pin_0|GPIO_Pin_1|GPIO_Pin_2|GPIO_Pin_3);        //将GPIOE端口拉高,熄灭所有LED       
  98. }
  99. /*******************************************************************************
  100. * 函 数 名         : LcdWriteCom
  101. * 函数功能                   : 向LCD写入一个字节的命令
  102. * 输    入         : com
  103. * 输    出         : 无
  104. *******************************************************************************/
  105. void LcdWriteCom(u16 com)
  106. {
  107.         LCD1602_E = 0;        //使能
  108.         LCD1602_RS = 0;        //选择发送命令
  109.         LCD1602_RW = 0;        //选择写入
  110.        
  111.         GPIOE->ODR = com<<2;        //放入命令
  112.         Delay_ms(1);        //等待数据稳定
  113.        
  114.         LCD1602_E = 1;                                //写入时序
  115.         Delay_ms(5);        //保持时间
  116.         LCD1602_E = 0;
  117. }
  118. /*******************************************************************************
  119. * 函 数 名         : LcdWriteData
  120. * 函数功能                   : 向LCD写入一个字节的数据
  121. * 输    入         : dat
  122. * 输    出         : 无
  123. *******************************************************************************/
  124. void LcdWriteData(u16 dat)        //写入数据
  125. {
  126.         LCD1602_E = 0;        //使能清零
  127.         LCD1602_RS = 1;        //选择输入数据
  128.         LCD1602_RW = 0;        //选择写入
  129.        
  130.         GPIOE->ODR = dat<<2;        //写入数据
  131.         Delay_ms(1);
  132.        
  133.         LCD1602_E = 1;        //写入时序
  134.         Delay_ms(5);        //保持时间
  135.         LCD1602_E = 0;
  136.        
  137. }
  138. /*******************************************************************************
  139. * 函 数 名       : LcdInit()
  140. * 函数功能                 : 初始化LCD屏
  141. * 输    入       : 无
  142. * 输    出       : 无
  143. *******************************************************************************/       
  144. void LcdInit(void)                                //LCD初始化程序
  145. {
  146.         LcdWriteCom(0x38);        //开显示
  147.         LcdWriteCom(0x0c);        //开显示不显示光标
  148.         LcdWriteCom(0x06);        //写一个指针加1       
  149.         LcdWriteCom(0x01);        //清屏
  150.         LcdWriteCom(0x80);        //设置数据指针起点
  151.        
  152. }


  153. int main(void)
  154. {
  155.         u8 i;
  156.         LCD_1602GPIO_Init();
  157.         LcdInit();
  158.         LcdWriteCom(0x80);
  159.         for(i=0;i<16;i++)
  160.         {
  161.                 LcdWriteData('A');                       
  162.         }
  163.         while(1)
  164.         {
  165.                 Led = 1;
  166.                 Delay_ms(1000);
  167.                 Led = 0;
  168.                 Delay_ms(1000);
  169.         }
  170. }

复制代码

所有资料51hei提供下载:
嵌入式.7z (237.08 KB, 下载次数: 79)

评分

参与人数 1黑币 +8 收起 理由
菜鸡一只314159 + 8 共享资料的黑币奖励!

查看全部评分

分享到:  QQ好友和群QQ好友和群 QQ空间QQ空间 腾讯微博腾讯微博 腾讯朋友腾讯朋友
收藏收藏3 分享淘帖 顶 踩
回复

使用道具 举报

沙发
ID:110502 发表于 2019-1-22 08:31 | 只看该作者
正需要呢!好资料,51黑有你更精彩!!!
回复

使用道具 举报

板凳
ID:813062 发表于 2020-8-10 22:35 | 只看该作者

好资料 正需要呢!!谢谢楼主分享!!!
回复

使用道具 举报

地板
ID:591382 发表于 2020-8-11 09:23 | 只看该作者
我有一个STM32F407最小系统,我用该最小系统驱动了1602和12864显示屏。今天看了你的代码,我获益匪浅,感谢分享,一起学习,一起创造新天地。
回复

使用道具 举报

5#
ID:904320 发表于 2021-4-12 10:35 | 只看该作者
你好!我是一个初学者,现在急需stm32f407的1602的代码,学习你的源代码给一下吗
回复

使用道具 举报

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

本版积分规则

手机版|小黑屋|51黑电子论坛 |51黑电子论坛6群 QQ 管理员QQ:125739409;技术交流QQ群281945664

Powered by 单片机教程网

快速回复 返回顶部 返回列表