stm32cubeide驱动LCD1602显示屏
STM32驱动LCD1602
- 硬件连接关系
- STM32CUBEIDE设置
- 代码
- 项目设置
- 最后运行
硬件连接关系
LCD1602 | STM32 |
---|---|
VCC | VCC |
GND | GND |
VO | VCC-滑动变阻 |
RS | PB1 |
RW | PB2(BOOT1) |
E | PB0 |
D0 ~ D7 | PB8 ~ PB15 |
A | PA8 |
K | PA11 |
这是普中科技的C51开发板,送了一个stm32f103c6的小核心板,C51开发板上有个LCD1602的接口就直接使用了。
STM32CUBEIDE设置
- System Core -> RCC -> HSE -> Crystal/Ceramic Resonator
- System Core -> RCC -> LSE -> Crystal/Ceramic Resonator
- System Core -> SYS -> Debug -> Serial Wire
- Connectivity -> USART1 -> Mode -> Asynchronous(Baud Rate: 115200Bits/S, Word Length: 8Bits)
- PA8:
GPIO_Output, GPIO output level: High, GPIO Mode: Output Push Pull
- PA11:
GPIO_Output, GPIO output level: Low, GPIO Mode: Output Push Pull
- PB0:
GPIO_Output, GPIO output level: Low, GPIO Mode: Output Push Pull, User Label: LCD_EN
- PB1:
GPIO_Output, GPIO output level: Low, GPIO Mode: Output Push Pull, User Label: LCD_RS
- PB2:
GPIO_Output, GPIO output level: Low, GPIO Mode: Output Push Pull, User Label: LCD_RW
- PB8:
GPIO_Output, GPIO output level: Low, GPIO Mode: Output Open Drain
- PB9:
GPIO_Output, GPIO output level: Low, GPIO Mode: Output Open Drain
- PB10:
GPIO_Output, GPIO output level: Low, GPIO Mode: Output Open Drain
- PB11:
GPIO_Output, GPIO output level: Low, GPIO Mode: Output Open Drain
- PB12:
GPIO_Output, GPIO output level: Low, GPIO Mode: Output Open Drain
- PB13:
GPIO_Output, GPIO output level: Low, GPIO Mode: Output Open Drain
- PB14:
GPIO_Output, GPIO output level: Low, GPIO Mode: Output Open Drain
- PB15:
GPIO_Output, GPIO output level: Low, GPIO Mode: Output Open Drain
- 设置时钟并保存
前面4行是设置晶振、JWD口、和UART调试信息。PA8,PA11是背光的控制口,设置推挽输出。PB0,PB1,PB2分别是LCD使能、LCD RS、LCD RW口,设置推挽输出。P8 ~ P15是数据输出和输入,因为输出同时要检测LCD是否忙,所以要读状态,需要设置为开漏输出。这里用的是8线输出方式。
代码
- Core->Inc文件夹下建立新的头文件"lcd1602.h"
#ifndef INC_LCD1602_H_
#define INC_LCD1602_H_#include "main.h"// 片选、读/写、数据/命令
#define LCD_CMD HAL_GPIO_WritePin(LCD_RS_GPIO_Port, LCD_RS_Pin, GPIO_PIN_RESET)
#define LCD_DATA HAL_GPIO_WritePin(LCD_RS_GPIO_Port, LCD_RS_Pin, GPIO_PIN_SET)
#define LCD_EN_HIGH HAL_GPIO_WritePin(LCD_EN_GPIO_Port, LCD_EN_Pin, GPIO_PIN_SET)
#define LCD_EN_LOWER HAL_GPIO_WritePin(LCD_EN_GPIO_Port, LCD_EN_Pin, GPIO_PIN_RESET)
#define LCD_WRITE HAL_GPIO_WritePin(LCD_RW_GPIO_Port, LCD_RW_Pin, GPIO_PIN_RESET)
#define LCD_READ HAL_GPIO_WritePin(LCD_RW_GPIO_Port, LCD_RW_Pin, GPIO_PIN_SET)void lcd_init(void);
void lcd_wait_ready(void);
void lcd_write_cmd(unsigned char cmd);
void lcd_write_data(unsigned char data);
void lcd_set_cursor(unsigned char x, unsigned char y);
void lcd_area_clear(unsigned char x, unsigned char y, unsigned char len);
void lcd_full_clear(void);
void lcd_show_string(unsigned char x, unsigned char y, unsigned char *data);
void write_data(unsigned char data);#endif /* INC_LCD1602_H_ */
- Core/Src下面建立"lcd1602.c"
#include "main.h"
#include "stdio.h"
#include "lcd1602.h"void lcd_init(void){lcd_write_cmd(0x38); // 16 * 2 显示 , 5 * 7 点阵, 8位接口lcd_wait_ready();lcd_write_cmd(0X0c); // 显示器开,光标关闭lcd_wait_ready();lcd_write_cmd(0x06); // 文字不动,地址自动加lcd_wait_ready();lcd_write_cmd(0x01); // 清屏lcd_wait_ready();printf("Init OK \r\n");
}void lcd_wait_ready(void){unsigned char status;write_data(0xff);LCD_CMD; // CMDLCD_READ; // Readdo{LCD_EN_HIGH; // 下降沿status = HAL_GPIO_ReadPin(GPIOB, GPIO_PIN_15);LCD_EN_LOWER;}while(status == 1);
}void lcd_write_cmd(unsigned char cmd){lcd_wait_ready();LCD_CMD;LCD_WRITE;write_data(cmd);LCD_EN_HIGH;LCD_EN_LOWER;lcd_wait_ready();
}void lcd_write_data(unsigned char data){lcd_wait_ready();LCD_DATA;LCD_WRITE;write_data(data);LCD_EN_HIGH;LCD_EN_LOWER;lcd_wait_ready();
}void lcd_set_cursor(unsigned char x, unsigned char y){unsigned char addr = 0;// Row : y , Col : xlcd_wait_ready();// 从输入的屏幕计算显示RAMif(y == 0){addr = 0x00 + x;}else{addr = 0x40 + x;}lcd_write_cmd(addr | 0x80);
}void lcd_area_clear(unsigned char x, unsigned char y, unsigned char len){lcd_set_cursor(x, y);while(len--){lcd_wait_ready();lcd_write_data(' ');}
}void lcd_full_clear(void){lcd_write_cmd(0x01);
}void lcd_show_string(unsigned char x, unsigned char y, unsigned char *data){lcd_set_cursor(x, y);while(*data != '\0'){lcd_wait_ready();lcd_write_data(*data++);}
}void write_data(unsigned char data){
// 这里直接控制的ODR寄存器,更方便。第一行清除原来的PB高8位,第二行写新数据GPIOB->ODR &= 0x00FF;GPIOB->ODR |= (data << 8);
}
- main.c中加入代码
#include "stdio.h"
#include "lcd1602.h"// 只是为了printf显示到串口信息中
#ifdef __GNUC__#define PUTCHAR_PROTOTYPE int __io_putchar(int ch)
#else#define PUTCHAR_PROTOTYPE int fputc(int ch, FILE *stream)
#endif
PUTCHAR_PROTOTYPE
{HAL_UART_Transmit(&huart1, (uint8_t *)&ch, 1, 0xffff);return ch;
}
//// 以下代码加入main函数中unsigned char *str = (unsigned char *)"Hello everyone";unsigned char *welcome = (unsigned char *)"Welcome to my world";// 开背光HAL_GPIO_WritePin(GPIOA, GPIO_PIN_8, GPIO_PIN_SET);HAL_GPIO_WritePin(GPIOA, GPIO_PIN_11, GPIO_PIN_RESET);lcd_init();HAL_Delay(10);//尝试读LCD状态。status1要显示非0才是闲状态。如果一直读到1,可能是BOOT1接地了write_data(0xff);LCD_CMD;LCD_READ;LCD_EN_HIGH;printf("Get status1: %d \r\n", HAL_GPIO_ReadPin(GPIOB, GPIO_PIN_15));printf("Get status2: 0x%04X \r\n", (uint16_t)GPIOB->ODR);printf("Get status2: 0x%04X \r\n", (uint16_t)GPIOB->IDR);LCD_EN_LOWER;lcd_show_string(0, 0, str);lcd_show_string(0, 1, welcome);HAL_Delay(5);while (1){HAL_Delay(1000);lcd_write_cmd(0x18); //屏幕右移//
项目设置
Project -> Properties -> C/C++ Build -> Setting -> MCU Setting -> Runtime Libray :Standard C。这个是用于printf显示用的。后面的两个也可以选上,用于显示小数
Project -> Properties -> C/C++ Build -> Setting -> MCU Post Build outputs -> Convert to intel Hex file 选中可以编译生成.HEX文件
最后的运行
- 因为我使用的是普中的板子,普中给的资料里面有一个UART烧写工具"普中ISP",这个工具烧写还是比较好用的,但烧写要BOOT0,BOOT1都接GND。而且只能烧写.HEX文件,所以我才会生成HEX文件
- 烧写完成后一定要记得拔下BOOT1的短接帽,因为工程中使用到PB2接口,默认这个PB2和BOOT1是同一个接口,我程序写好后怎么都不能读取到LCD状态
lcd_wait_ready()
死循环。花了一天时间才找到原因。 - CSDN上很多程序都没有
lcd_wait_ready()
,直接使用自己写的延迟代替。自己写来玩是可以用,但毕竟不是完美方法,要想lcd_wait_ready()
正常必须要记得BOOT1不能接地,PB8 ~ PB15要设置为开漏输出。 - 如果有问题可以使用Printf()显示变量信息,也可以使用Jlink调试。printf()要想能换行只用在字符串结束时加上’\r\n’就可以了。只加’\n’是不能换行的。
stm32cubeide驱动LCD1602显示屏相关推荐
- 树莓派通过I2C驱动LCD1602显示屏
问题来源 在此之前学习了Arduino驱动LCD1602(Arduino通过I2C控制1602LCD显示屏),其过程比较简单,现在想通过树莓派实现控制功能,提升树莓派编程控制能力,在此过程中虽然能正常 ...
- 物联网开发笔记(25)- 使用Micropython开发ESP32开发板之控制LCD1602显示屏
这一节我们讲解了如何控制LCD1602显示屏,显示两行字. 一.目的 使用MicroPython开发ESP32开发板控制LCD1602显示屏 二.环境 ESP32 + LCD1602显示屏 + Tho ...
- lcd1602显示屏显示“welcome to 207”
基础知识: lcd1602显示屏可以显示两行,一行可以显示16个字符 显示原理:(简单了解) 一般的液晶显示器(Liquid Crystal Display, LCD) 的主要原理是以电流刺激液晶分子 ...
- 【mcuclub】LCD1602显示屏
1.实物图 2.原理图 3.原理介绍 LCD1602:LCD1602液晶显示器是一种广泛使用的字符型液晶显示模块.它是由字符型液晶显示屏(LCD).控制驱动主电路及其扩展驱动电路,以及少量电阻.电容元 ...
- Arduino 和LCD1602显示屏
LCD1602显示屏 带I2C接口 引脚说明 GND ------ 地线 VCC ------ 电源(5V or 3.3v 电源不同显示效果有点差别) SDA ------ I2C 数据线 SCL - ...
- 物联网开发笔记(26)- 使用Micropython开发ESP32开发板之控制LCD1602显示屏(续)
上一节介绍了使用i2c来控制LCD1602显示屏,那么使用GPIO怎么控制LCD1602显示屏呢?使用GPIO又分为8bit和4bit两种模式,比较常用的4bit模式,因为它占用GPIO口比较少. ...
- 使用8080并口协议驱动NT35510LCD显示屏
使用8080并口协议驱动NT35510LCD显示屏 本文记录如何使用8080协议驱动LCD显示屏,其中LCD显示屏驱动为NT35510芯片,正点原子的4.3寸显示屏,像素480X800,基于正点原 ...
- 4.11 51单片机-LCD1602显示屏
4.11 LCD1602显示屏 4.11.1 原理图介绍 图4-11-1 图4-11-2 根据原理图得知: LCD1602的数据脚接P0口. RD(RS)引脚接P2.6 WR(RW)引脚接P2.5 L ...
- Arduino和C51开发LCD1602显示屏
技术:51单片机.Arduino.LCD1602 概述 本文介绍了LCD1602显示屏,并在LCD1602上显示字符串,对LCD1602常见的问题的解决和开发方法也做了简单介绍. 详细 代码下载:ht ...
最新文章
- python下载大文件-使用python通过FTP下载大文件
- 通过CSS让html网页中的内容不可选
- HDU4546(优先队列)
- apache.camel_在即将发布的Camel 2.21版本中改进了使用Apache Camel和ActiveMQ Artemis处理大型消息的功能...
- web标准三个要素 此标准的好处
- 共同努力做好NBear!
- Q144:FS,求解流体方程(逻辑总结)
- Spring AOP(六)之访问目标方法的参数
- C#程序加密工具.Net Reactor教程
- 上传文件与下载文件不一致的怪事
- 2018-2019-1 20165301 《信息安全系统设计基础》第六周学习总结
- linux脚本显示时间戳,shell下获取时间戳
- word排版案例报告_Word分节符的一些常见问题及解决办法
- matlab正序零序负序,史上最完美的图形和公式带你搞懂正序负序零序!
- PostgreSQL 分区表一点也不差
- 【THUSC2017】座位
- 服务器图片显示小方块,高手帮忙了!!验证码跟着敲好之后 服务器打开一个小方块里面空的!在线等!!!...
- 描写火车站场景_作文素材 描写火车站的句子-精品
- pt mysql_pt(Percona Toolkit)工具介绍
- NFC学习笔记(2)——NFC基础知识
热门文章
- 基于stm32C8T6的红外遥控器制作 stm做遥控器
- Jenkins教程(4)使用PyInstaller构建Python应用
- 【MATLAB教程案例13】基于SA模拟退火优化算法的函数极值计算matlab仿真及其他应用
- Linux如何给服务器增加白名单
- 广点通,网盟广告Sdk 一键集成!Android
- message函数php,ReplyMessage()函数
- 英语四级+六级词汇大全(全部带“音标”)
- docker国内镜像拉取和镜像加速registry-mirrors配置修改
- Zoom Meeting App操作说明
- win10+tensorflow环境搭建