STM32驱动lcd1602,并口8位 6800时序

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连接引脚分配如下:

引脚功能初始化
B3RSoutput,pushpull,pullup,high
B4RWoutput,pushpull,pullup,high
B5Eoutput,pushpull,pullup,high
B8-B15D0-D7output,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

/********************************Copyright (c)**********************************\
**
**                   (c) Copyright 2020, Main, China, QD.
**                           All Rights Reserved
**
**                                 By(wo4fisher)
**                           http://www.wo4fisher.com
**
**----------------------------------文件信息------------------------------------
** 文件名称: lcd1602.c
** 创建人员: wht
** 创建日期: 2020-03-13
** 文档描述: 
**
**----------------------------------版本信息------------------------------------
** 版本代号: V0.1
** 版本说明: 初始版本
**
**------------------------------------------------------------------------------
\********************************End of Head************************************/
#include "lcd1602.h"
//############################################################
#define _LCD_COLS         16
#define _LCD_ROWS         2
//############################################################
/*****  GPIOB3  H:data;L:command  ******/
#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)
/*****  GPIOB4  H:read;L:write  ******/
#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)
/*****  GPIOB5    ******/
#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">&lt;</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"

 
 
  • 1

在完成了gpio的初始化之后,初始化lcd。

	LCD_Init();

 
 
  • 1

调用puts函数,在屏幕上显示字符串,加入“\r\n”实现换行。

  LCD_Puts(0,0,"HELLO WORLD!\r\nI'm WHT.");

 
 
  • 1

显示效果:

显示效果

2.5 main.c

/* USER CODE BEGIN Header */
/**
  ******************************************************************************
  * @file           : main.c
  * @brief          : Main program body
  ******************************************************************************
  * @attention
  *
  * <h2><center>&copy; Copyright (c) 2020 STMicroelectronics.
  * All rights reserved.</center></h2>
  *
  * This software component is licensed by ST under BSD 3-Clause license,
  * the "License"; You may not use this file except in compliance with the
  * License. You may obtain a copy of the License at:
  *                        opensource.org/licenses/BSD-3-Clause
  *
  ******************************************************************************
  */
/* USER CODE END Header */

/* 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
/**

  • @brief Reports the name of the source file and the source line number
  •     where the assert_param error has occurred.
    
  • @param file: pointer to the source file name
  • @param line: assert_param error line source number
  • @retval None
    /
    void assert_failed(uint8_t
    file, uint32_t line)
    {
    /* USER CODE BEGIN 6 /
    / User can add his own implementation to report the file name and line number,
    tex: printf(“Wrong parameters value: file %s on line %d\r\n”, file, line) /

    / USER CODE END 6 /
    }
    #endif / 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
  • 1
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
以下是一个简单的STM32F407并口驱动LCD1602的代码示例: ```c #include "stm32f4xx.h" #define LCD_RS_PIN GPIO_Pin_0 #define LCD_RW_PIN GPIO_Pin_1 #define LCD_EN_PIN GPIO_Pin_2 #define LCD_DB4_PIN GPIO_Pin_4 #define LCD_DB5_PIN GPIO_Pin_5 #define LCD_DB6_PIN GPIO_Pin_6 #define LCD_DB7_PIN GPIO_Pin_7 void LCD_Init(void); void LCD_SendCommand(uint8_t command); void LCD_SendData(uint8_t data); void LCD_SendString(char *str); int main(void) { LCD_Init(); LCD_SendString("Hello, world!"); while(1); } void LCD_Init(void) { RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOA, ENABLE); GPIO_InitTypeDef GPIO_InitStruct; GPIO_InitStruct.GPIO_Pin = LCD_RS_PIN | LCD_RW_PIN | LCD_EN_PIN | LCD_DB4_PIN | LCD_DB5_PIN | LCD_DB6_PIN | LCD_DB7_PIN; GPIO_InitStruct.GPIO_Mode = GPIO_Mode_OUT; GPIO_InitStruct.GPIO_OType = GPIO_OType_PP; GPIO_InitStruct.GPIO_Speed = GPIO_Speed_50MHz; GPIO_InitStruct.GPIO_PuPd = GPIO_PuPd_NOPULL; GPIO_Init(GPIOA, &GPIO_InitStruct); GPIO_WriteBit(GPIOA, LCD_RS_PIN, Bit_RESET); GPIO_WriteBit(GPIOA, LCD_RW_PIN, Bit_RESET); GPIO_WriteBit(GPIOA, LCD_EN_PIN, Bit_RESET); LCD_SendCommand(0x33); LCD_SendCommand(0x32); LCD_SendCommand(0x28); LCD_SendCommand(0x0C); LCD_SendCommand(0x06); LCD_SendCommand(0x01); LCD_SendCommand(0x02); } void LCD_SendCommand(uint8_t command) { GPIO_WriteBit(GPIOA, LCD_RS_PIN, Bit_RESET); GPIO_WriteBit(GPIOA, LCD_RW_PIN, Bit_RESET); GPIO_WriteBit(GPIOA, LCD_DB4_PIN, (command & 0x10) ? Bit_SET : Bit_RESET); GPIO_WriteBit(GPIOA, LCD_DB5_PIN, (command & 0x20) ? Bit_SET : Bit_RESET); GPIO_WriteBit(GPIOA, LCD_DB6_PIN, (command & 0x40) ? Bit_SET : Bit_RESET); GPIO_WriteBit(GPIOA, LCD_DB7_PIN, (command & 0x80) ? Bit_SET : Bit_RESET); GPIO_WriteBit(GPIOA, LCD_EN_PIN, Bit_SET); GPIO_WriteBit(GPIOA, LCD_EN_PIN, Bit_RESET); GPIO_WriteBit(GPIOA, LCD_DB4_PIN, (command & 0x01) ? Bit_SET : Bit_RESET); GPIO_WriteBit(GPIOA, LCD_DB5_PIN, (command & 0x02) ? Bit_SET : Bit_RESET); GPIO_WriteBit(GPIOA, LCD_DB6_PIN, (command & 0x04) ? Bit_SET : Bit_RESET); GPIO_WriteBit(GPIOA, LCD_DB7_PIN, (command & 0x08) ? Bit_SET : Bit_RESET); GPIO_WriteBit(GPIOA, LCD_EN_PIN, Bit_SET); GPIO_WriteBit(GPIOA, LCD_EN_PIN, Bit_RESET); // Wait for command to be processed for (volatile uint32_t i = 0; i < 1000; i++); } void LCD_SendData(uint8_t data) { GPIO_WriteBit(GPIOA, LCD_RS_PIN, Bit_SET); GPIO_WriteBit(GPIOA, LCD_RW_PIN, Bit_RESET); GPIO_WriteBit(GPIOA, LCD_DB4_PIN, (data & 0x10) ? Bit_SET : Bit_RESET); GPIO_WriteBit(GPIOA, LCD_DB5_PIN, (data & 0x20) ? Bit_SET : Bit_RESET); GPIO_WriteBit(GPIOA, LCD_DB6_PIN, (data & 0x40) ? Bit_SET : Bit_RESET); GPIO_WriteBit(GPIOA, LCD_DB7_PIN, (data & 0x80) ? Bit_SET : Bit_RESET); GPIO_WriteBit(GPIOA, LCD_EN_PIN, Bit_SET); GPIO_WriteBit(GPIOA, LCD_EN_PIN, Bit_RESET); GPIO_WriteBit(GPIOA, LCD_DB4_PIN, (data & 0x01) ? Bit_SET : Bit_RESET); GPIO_WriteBit(GPIOA, LCD_DB5_PIN, (data & 0x02) ? Bit_SET : Bit_RESET); GPIO_WriteBit(GPIOA, LCD_DB6_PIN, (data & 0x04) ? Bit_SET : Bit_RESET); GPIO_WriteBit(GPIOA, LCD_DB7_PIN, (data & 0x08) ? Bit_SET : Bit_RESET); GPIO_WriteBit(GPIOA, LCD_EN_PIN, Bit_SET); GPIO_WriteBit(GPIOA, LCD_EN_PIN, Bit_RESET); // Wait for data to be processed for (volatile uint32_t i = 0; i < 1000; i++); } void LCD_SendString(char *str) { while (*str) { LCD_SendData(*str++); } } ``` 这个代码使用了GPIOA作为LCD1602并口,其他GPIO也可以使用,只需要修改代码中的相应定义。在`main`函数中,我们初始化LCD并发送一串字符串。`LCD_Init`函数初始化GPIO并发送LCD的初始化命令,`LCD_SendCommand`函数发送LCD命令,`LCD_SendData`函数发送LCD数据,`LCD_SendString`函数发送一个字符串(通过调用`LCD_SendData`函数)。在发送命令和数据时,我们需要按照LCD的时序要求进行操作,并且需要适当的延时来确保命令和数据被正确处理。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值