STM32驱动lcd1602,并口8位 6800时序
一、LCD1602(3.3V硬件版本)简介
1.1 引脚
引脚,lcd1602采用标准接口,6800时序8位并行数据传输。 第 1 脚:VSS 为地电源。 第 2 脚:VDD 接 3.3V 正电源。 第 3 脚:VL 为液晶显示器对比度调整端,接正电源时对比度最弱,接地时对比度最高,对 比度过高时会产生“鬼影”,使用时可以通过一个 10K 的电位器调整对比度。 第 4 脚:RS 为寄存器选择,高电平时选择数据寄存器、低电平时选择指令寄存器。 第 5 脚:R/W 为读写信号线,高电平时进行读操作,低电平时进行写操作。当 RS 和 R/W 共同为低电平时可以写入指令或者显示地址,当 RS 为低电平 R/W 为高电平时可以读忙信 号,当 RS 为高电平 R/W 为低电平时可以写入数据。 第 6 脚:E 端为使能端,当 E 端由高电平跳变成低电平时,液晶模块执行命令。 第 7~14 脚:D0~D7 为 8 位双向数据线。 第 15 脚:背光源正极。 第 16 脚:背光源负极。
1.2写数据/命令时序
1.3 命令集
1602 液晶模块的读写操作、屏幕和光标的操作都是通过指令编程来实现的。(说明:1 为高电平、0 为低电平)。 指令 1:清显示,指令码 01H,光标复位到地址 00H 位置。 指令 2:光标复位,光标返回到地址 00H。 指令 3:光标和显示模式设置 I/D:光标移动方向,高电平右移,低电平左移 S:屏幕上所有文字是否左移或者右移。高电平表示有效,低电平则无效。 指令 4:显示开关控制。 D:控制整体显示的开与关,高电平表示开显示,低电平表示关显示 C:控制光标的开与关,高电平表示有光标,低电平表示无光标 B:控制光标是否闪烁,高电平闪烁,低电平不闪烁。 指令 5:光标或显示移位 S/C:高电平时移动显示的文字,低电平时移动光标。 指令 6:功能设置命令 DL:高电平时为 4 位总线,低电平时为 8 位总线 N:低电平时为单行显示,高电平时双行显示 F: 低电平时显示 5x7 的点阵字符,高电平时显示 5x10 的点阵字符。 指令 7:字符发生器 RAM 地址设置。 指令 8:DDRAM 地址设置。 指令 9:读忙信号和光标地址 BF:为忙标志位,高电平表示忙,此时模块不能接收命令或者数据,如果为低电平表示不忙。 指令 10:写数据。 指令 11:读数据。
1.4 存储映射
注意:写地址时格式:写地址命令0x80 | 地址
1.5 基本初始化步骤
1.6 复位
二、程序实现
2.1 stm32初始化
在cubemx中进行gpio、rcc、sys、uart等必要的初始化。其中,lcd1602连接引脚分配如下:
引脚 功能 初始化 B3 RS output,pushpull,pullup,high B4 RW output,pushpull,pullup,high B5 E output,pushpull,pullup,high B8-B15 D0-D7 output,pushpull,pullup,high
2.2 LCD.H
```c
/********************************Copyright (c)**********************************\
**
** (c) Copyright 2020, Main, China, QD.
** All Rights Reserved
**
** By(wo4fisher)
** http://www.wo4fisher.com
**
**----------------------------------文件信息------------------------------------
** 文件名称: lcd1602.h
** 创建人员: wht
** 创建日期: 2020-03-13
** 文档描述:
**
**----------------------------------版本信息------------------------------------
** 版本代号: V0.1
** 版本说明: 初始版本
**
**------------------------------------------------------------------------------
\********************************End of Head************************************/
#ifndef _LCD1602_H #define _LCD1602_H #include “main.h” #include “usart.h” #include “gpio.h”
/* +++ Nima Askari +++ www.github.com/NimaLTD +++ www.instagram.com/github.NimaLTD +++ Version: 1.1.0 */
void LCD_Init(void); void LCD_DisplayOn(void); void LCD_DisplayOff(void); void LCD_Clear(void); void LCD_Puts(uint8_t x, uint8_t y, char* str); void LCD_BlinkOn(void); void LCD_BlinkOff(void); void LCD_CursorOn(void); void LCD_CursorOff(void); void LCD_ScrollLeft(void); void LCD_ScrollRight(void); void LCD_CreateChar(uint8_t location, uint8_t* data); void LCD_PutCustom(uint8_t x, uint8_t y, uint8_t location); void LCD_Put(uint8_t Data);
#endif /End of File ****/
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55
程序参考了github里Nima Askari的代码
2.3 lcd.c
# include "lcd1602.h"
# define _LCD_COLS 16
# define _LCD_ROWS 2
# define LCD1602_RS_DATA HAL_GPIO_WritePin ( GPIOB, GPIO_PIN_3, GPIO_PIN_SET)
# define LCD1602_RS_CMD HAL_GPIO_WritePin ( GPIOB, GPIO_PIN_3, GPIO_PIN_RESET)
# define LCD1602_RW_READ HAL_GPIO_WritePin ( GPIOB, GPIO_PIN_4, GPIO_PIN_SET)
# define LCD1602_RW_WRITE HAL_GPIO_WritePin ( GPIOB, GPIO_PIN_4, GPIO_PIN_RESET)
# define LCD1602_E_HIGH HAL_GPIO_WritePin ( GPIOB, GPIO_PIN_5, GPIO_PIN_SET)
# define LCD1602_E_LOW HAL_GPIO_WritePin ( GPIOB, GPIO_PIN_5, GPIO_PIN_RESET)
#define LCD1602_DATA(x) GPIOB->ODR=(GPIOB->ODR & 0x00ff) | (x<<8) //############################################################ /* Commands*/ #define LCD_CLEARDISPLAY 0x01 #define LCD_RETURNHOME 0x02 #define LCD_ENTRYMODESET 0x04 #define LCD_DISPLAYCONTROL 0x08 #define LCD_CURSORSHIFT 0x10 #define LCD_FUNCTIONSET 0x20 #define LCD_SETCGRAMADDR 0x40 #define LCD_SETDDRAMADDR 0x80 /* Flags for display entry mode / #define LCD_ENTRYRIGHT 0x00 #define LCD_ENTRYLEFT 0x02 #define LCD_ENTRYSHIFTINCREMENT 0x01 #define LCD_ENTRYSHIFTDECREMENT 0x00 / Flags for display on/off control / #define LCD_DISPLAYON 0x04 #define LCD_CURSORON 0x02 #define LCD_BLINKON 0x01 / Flags for display/cursor shift / #define LCD_DISPLAYMOVE 0x08 #define LCD_CURSORMOVE 0x00 #define LCD_MOVERIGHT 0x04 #define LCD_MOVELEFT 0x00 / Flags for function set / #define LCD_8BITMODE 0x10 #define LCD_4BITMODE 0x00 #define LCD_2LINE 0x08 #define LCD_1LINE 0x00 #define LCD_5x10DOTS 0x04 #define LCD_5x8DOTS 0x00 //############################################################ //############################################################ typedef struct {
uint8_t DisplayControl; uint8_t DisplayFunction; uint8_t DisplayMode; uint8_t currentX; uint8_t currentY; } LCD_Options_t; //############################################################ / Private functions / static void LCD_Cmd ( uint8_t cmd) ; static void LCD_Data ( uint8_t data) ; static void LCD_CursorSet ( uint8_t col, uint8_t row) ; static void LCD_EnBlink ( void ) ; //############################################################ / Private variable / static LCD_Options_t LCD_Opts; //############################################################ void LCD_Delay_us ( uint16_t us) {
uint32_t Div = ( SysTick-> LOAD+ 1 ) / 1000 ; uint32_t StartMicros = HAL_GetTick ( ) 1000 + ( 1000 - SysTick-> VAL/ Div) ; while ( ( HAL_GetTick ( ) 1000 + ( 1000 - SysTick-> VAL/ Div) - StartMicros < us) ) ; } //############################################################ void LCD_Delay_ms ( uint8_t ms) {
HAL_Delay ( ms) ; } //############################################################ void LCD_Init ( void ) {
/ Set cursor pointer to beginning for LCD / LCD_Opts. currentX = 0 ; LCD_Opts. currentY = 0 ; LCD_Opts. DisplayFunction = LCD_8BITMODE | LCD_5x8DOTS | LCD_1LINE; if ( _LCD_ROWS > 1 ) LCD_Opts. DisplayFunction | = LCD_2LINE; / Set # lines, font size,8BITMODE,etc. / LCD_Cmd ( LCD_FUNCTIONSET | LCD_Opts. DisplayFunction) ; / Turn the display on with no cursor or blinking default / LCD_Opts. DisplayControl = LCD_DISPLAYON; LCD_DisplayOn ( ) ; / Default font directions 文字不动,地址自动+1*/ LCD_Opts. DisplayMode = LCD_ENTRYLEFT | LCD_ENTRYSHIFTDECREMENT; LCD_Cmd ( LCD_ENTRYMODESET | LCD_Opts. DisplayMode) ; LCD_Clear ( ) ; LCD_Delay_ms ( 5 ) ; } //############################################################ void LCD_Clear ( void ) {
LCD_Cmd ( LCD_CLEARDISPLAY) ; LCD_Delay_ms ( 5 ) ; } //############################################################ void LCD_Puts ( uint8_t x, uint8_t y, char str) {
LCD_CursorSet ( x, y) ; while ( str) {
if ( LCD_Opts. currentX >= _LCD_COLS) /移动到下一行 / {
LCD_Opts. currentX = 0 ; LCD_Opts. currentY++ ; LCD_CursorSet ( LCD_Opts. currentX, LCD_Opts. currentY) ; } if ( str == ‘\n’ ) /换行,列对其 / {
LCD_Opts. currentY++ ; LCD_CursorSet ( LCD_Opts. currentX, LCD_Opts. currentY) ; } else if ( str == ‘\r’ ) /回车,换行回行首 / {
LCD_CursorSet ( 0 , LCD_Opts. currentY) ; } else {
LCD_Data ( str) ; LCD_Opts. currentX++ ; } str++ ; } } //############################################################ void LCD_DisplayOn ( void ) {
LCD_Opts. DisplayControl | = LCD_DISPLAYON; LCD_Cmd ( LCD_DISPLAYCONTROL | LCD_Opts. DisplayControl) ; } //############################################################ void LCD_DisplayOff ( void ) {
LCD_Opts. DisplayControl & = ~ LCD_DISPLAYON; LCD_Cmd ( LCD_DISPLAYCONTROL | LCD_Opts. DisplayControl) ; } //############################################################ void LCD_BlinkOn ( void ) {
LCD_Opts. DisplayControl | = LCD_BLINKON; LCD_Cmd ( LCD_DISPLAYCONTROL | LCD_Opts. DisplayControl) ; } //############################################################ void LCD_BlinkOff ( void ) {
LCD_Opts. DisplayControl & = ~ LCD_BLINKON; LCD_Cmd ( LCD_DISPLAYCONTROL | LCD_Opts. DisplayControl) ; } //############################################################ void LCD_CursorOn ( void ) {
LCD_Opts. DisplayControl | = LCD_CURSORON; LCD_Cmd ( LCD_DISPLAYCONTROL | LCD_Opts. DisplayControl) ; } //############################################################ void LCD_CursorOff ( void ) {
LCD_Opts. DisplayControl & = ~ LCD_CURSORON; LCD_Cmd ( LCD_DISPLAYCONTROL | LCD_Opts. DisplayControl) ; } //############################################################ void LCD_ScrollLeft ( void ) {
LCD_Cmd ( LCD_CURSORSHIFT | LCD_DISPLAYMOVE | LCD_MOVELEFT) ; } //############################################################ void LCD_ScrollRight ( void ) {
LCD_Cmd ( LCD_CURSORSHIFT | LCD_DISPLAYMOVE | LCD_MOVERIGHT) ; } //############################################################ void LCD_CreateChar ( uint8_t location, uint8_t data) {
uint8_t i; /* We have 8 locations available for custom characters */ location & = 0x07 ; LCD_Cmd ( LCD_SETCGRAMADDR | ( location << 3 ) ) ;
<span class="token keyword">for</span> <span class="token punctuation">(</span>i <span class="token operator">=</span> <span class="token number">0</span><span class="token punctuation">;</span> i <span class="token operator"><</span> <span class="token number">8</span><span class="token punctuation">;</span> i<span class="token operator">++</span><span class="token punctuation">)</span> <span class="token punctuation">{<!-- --></span>
<span class="token function">LCD_Data</span><span class="token punctuation">(</span>data<span class="token punctuation">[</span>i<span class="token punctuation">]</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token punctuation">}</span>
} //############################################################ void LCD_PutCustom ( uint8_t x, uint8_t y, uint8_t location) {
LCD_CursorSet ( x, y) ; LCD_Data ( location) ; } //############################################################ static void LCD_EnBlink ( void ) {
LCD1602_E_HIGH; LCD_Delay_us ( 50 ) ; LCD1602_E_LOW; LCD_Delay_us ( 50 ) ; } //############################################################ static void LCD_Cmd ( uint8_t cmd) {
LCD1602_RS_CMD; LCD1602_RW_WRITE; LCD1602_DATA ( cmd) ; LCD_EnBlink ( ) ; } //############################################################ static void LCD_Data ( uint8_t data) {
LCD1602_RS_DATA; LCD1602_RW_WRITE; LCD1602_DATA ( data) ; LCD_EnBlink ( ) ; } //############################################################ static void LCD_CursorSet ( uint8_t col, uint8_t row) {
uint8_t row_offsets[ ] = {
0x00 , 0x40 , 0x14 , 0x54 } ; if ( row >= _LCD_ROWS) row = 0 ; LCD_Opts. currentX = col; LCD_Opts. currentY = row; LCD_Cmd ( LCD_SETDDRAMADDR | ( col + row_offsets[ row] ) ) ; } //############################################################ void LCD_Put ( uint8_t Data) {
LCD_Data ( Data) ; } //############################################################ /End of File ****/
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250
2.4 使用
在main.c中添加头文件
# include "lcd1602.h"
在完成了gpio的初始化之后,初始化lcd。
LCD_Init ( ) ;
调用puts函数,在屏幕上显示字符串,加入“\r\n”实现换行。
LCD_Puts ( 0 , 0 , "HELLO WORLD!\r\nI'm WHT." ) ;
显示效果:
2.5 main.c
/* Includes ------------------------------------------------------------------*/ #include “main.h” #include “usart.h” #include “gpio.h”
/* Private includes ----------------------------------------------------------/ / USER CODE BEGIN Includes / #include “lcd1602.h” / USER CODE END Includes */
/* Private typedef -----------------------------------------------------------/ / USER CODE BEGIN PTD */
/* USER CODE END PTD */
/* Private define ------------------------------------------------------------/ / USER CODE BEGIN PD / / USER CODE END PD */
/* Private macro -------------------------------------------------------------/ / USER CODE BEGIN PM */
/* USER CODE END PM */
/* Private variables ---------------------------------------------------------*/
/* USER CODE BEGIN PV */
/* USER CODE END PV */
/* Private function prototypes -----------------------------------------------/ void SystemClock_Config ( void ) ; / USER CODE BEGIN PFP */
/* USER CODE END PFP */
/* Private user code ---------------------------------------------------------/ / USER CODE BEGIN 0 */ uint8_t msg[ ] = “hello world…\n” ;
/* USER CODE END 0 */
/**
@brief The application entry point. @retval int / int main ( void ) {
/ USER CODE BEGIN 1 */
/* USER CODE END 1 */
/* MCU Configuration--------------------------------------------------------*/
/* Reset of all peripherals, Initializes the Flash interface and the Systick. */ HAL_Init ( ) ;
/* USER CODE BEGIN Init */
/* USER CODE END Init */
/* Configure the system clock */ SystemClock_Config ( ) ;
/* USER CODE BEGIN SysInit */
/* USER CODE END SysInit */
/* Initialize all configured peripherals / MX_GPIO_Init ( ) ; MX_USART1_UART_Init ( ) ; / USER CODE BEGIN 2 / printf ( "%s" , msg) ; LCD_Init ( ) ; LCD_Puts ( 0 , 0 , “HELLO WORLD!\r\nI’m WHT.” ) ; / USER CODE END 2 */
/* Infinite loop / / USER CODE BEGIN WHILE / while ( 1 ) {
/ USER CODE END WHILE / HAL_GPIO_TogglePin ( GPIOC, GPIO_PIN_2) ; HAL_Delay ( 1000 ) ; / USER CODE BEGIN 3 / } / USER CODE END 3 */ }
/**
@brief System Clock Configuration @retval None */ void SystemClock_Config ( void ) {
RCC_OscInitTypeDef RCC_OscInitStruct = {
0 } ; RCC_ClkInitTypeDef RCC_ClkInitStruct = {
0 } ;
/** Initializes the CPU, AHB and APB busses clocks / RCC_OscInitStruct. OscillatorType = RCC_OSCILLATORTYPE_HSE; RCC_OscInitStruct. HSEState = RCC_HSE_ON; RCC_OscInitStruct. HSEPredivValue = RCC_HSE_PREDIV_DIV1; RCC_OscInitStruct. HSIState = RCC_HSI_ON; RCC_OscInitStruct. PLL. PLLState = RCC_PLL_ON; RCC_OscInitStruct. PLL. PLLSource = RCC_PLLSOURCE_HSE; RCC_OscInitStruct. PLL. PLLMUL = RCC_PLL_MUL6; if ( HAL_RCC_OscConfig ( & RCC_OscInitStruct) != HAL_OK) {
Error_Handler ( ) ; } /* Initializes the CPU, AHB and APB busses clocks */ RCC_ClkInitStruct. ClockType = RCC_CLOCKTYPE_HCLK| RCC_CLOCKTYPE_SYSCLK | RCC_CLOCKTYPE_PCLK1| RCC_CLOCKTYPE_PCLK2; RCC_ClkInitStruct. SYSCLKSource = RCC_SYSCLKSOURCE_PLLCLK; RCC_ClkInitStruct. AHBCLKDivider = RCC_SYSCLK_DIV1; RCC_ClkInitStruct. APB1CLKDivider = RCC_HCLK_DIV2; RCC_ClkInitStruct. APB2CLKDivider = RCC_HCLK_DIV1;
if ( HAL_RCC_ClockConfig ( & RCC_ClkInitStruct, FLASH_LATENCY_2) != HAL_OK) {
Error_Handler ( ) ; } }
/* USER CODE BEGIN 4 */
/* USER CODE END 4 */
/**
@brief This function is executed in case of error occurrence. @retval None / void Error_Handler ( void ) {
/ USER CODE BEGIN Error_Handler_Debug / / User can add his own implementation to report the HAL error return state */
/* USER CODE END Error_Handler_Debug */ }
#ifdef USE_FULL_ASSERT /**
/************************ © COPYRIGHT STMicroelectronics *END OF FILE /
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)