STM32-LCD2004驱动

STM32采用3.3V供电,LCD2004大多5v供电,那么STM32能驱动LCD2004吗?

下面来看看LCD2004的电参数

可以看到,LCD2004的输入高电平最小值在2.2V,也就是说只要高于2.2v即可被识别为高电平,STM32完全满足该电平条件,因此理论上STM32可以驱动LCD2004。

以下程序使用STM32F103C8T6单片机验证通过,采用HAL库编写。

LCD.h:该文件列出来可供用户调用的外部函数

#ifndef LCD_H
#define LCD_H 

#include<stdint.h>
#include "gpio.h"


void LCD_Init(void);//LCD初始化
void LCD_Clear(void);//清屏
void LCD_BlinkOn(void);//光标所在位置闪烁开
void LCD_BlinkOff(void);//光标所在位置闪烁关
void LCD_CursorOn(void);//显示光标
void LCD_CursorOff(void);//关闭光标
void LCD_DisplayOn(void);//打开显示
void LCD_DisplayOff(void);//关闭显示
void LCD_ScrollLeft(void);
void LCD_ScrollRight(void);
void LCD_Put(uint8_t Data);
void LCD_CursorSet(uint8_t col, uint8_t row);//设置光标位置
void LCD_Puts(uint8_t x, uint8_t y, char* str);//从指定坐标(x,y)开始打印字符串str
void LCD_CreateChar(uint8_t location, uint8_t* data);//自定义字符
void LCD_PutCustom(uint8_t x, uint8_t y, uint8_t location);//在指定坐标(x,y)显示自定义字符



#endif

gpio.h:

#ifndef __gpio_H
#define __gpio_H
#ifdef __cplusplus
 extern "C" {
#endif

/* Includes ------------------------------------------------------------------*/
#include "LCD_Config.h"

void MX_GPIO_Init(void);

#ifdef __cplusplus
}
#endif
#endif /*__ pinoutConfig_H */

LCD_Config.h:该文件定义了LCD2004与STM32的引脚连接关系,四线模式驱动,使用时需根据自己的硬件修改该头文件


#ifndef LCD_CONFIG_H
#define LCD_CONFIG_H 

#include "stm32f1xx_hal.h"

#define _LCD_COLS         20
#define _LCD_ROWS         4



#define LCD_RS_Pin GPIO_PIN_8
#define LCD_RS_GPIO_Port GPIOA
#define LCD_RW_Pin GPIO_PIN_9
#define LCD_RW_GPIO_Port GPIOB
#define LCD_EN_Pin GPIO_PIN_14
#define LCD_EN_GPIO_Port GPIOB
#define LCD_D4_Pin GPIO_PIN_3
#define LCD_D4_GPIO_Port GPIOB
#define LCD_D5_Pin GPIO_PIN_4
#define LCD_D5_GPIO_Port GPIOB
#define LCD_D6_Pin GPIO_PIN_10
#define LCD_D6_GPIO_Port GPIOB
#define LCD_D7_Pin GPIO_PIN_11
#define LCD_D7_GPIO_Port GPIOB



#define _LCD_RS_PORT      LCD_RS_GPIO_Port
#define _LCD_RS_PIN       LCD_RS_Pin

#define _LCD_E_PORT       LCD_EN_GPIO_Port
#define _LCD_E_PIN        LCD_EN_Pin

#define _LCD_RW_PORT      LCD_RW_GPIO_Port
#define _LCD_RW_PIN       LCD_RW_Pin

#define _LCD_D4_PORT      LCD_D4_GPIO_Port
#define _LCD_D4_PIN				LCD_D4_Pin

#define _LCD_D5_PORT      LCD_D5_GPIO_Port
#define _LCD_D5_PIN       LCD_D5_Pin

#define _LCD_D6_PORT      LCD_D6_GPIO_Port
#define _LCD_D6_PIN       LCD_D6_Pin

#define _LCD_D7_PORT      LCD_D7_GPIO_Port
#define _LCD_D7_PIN       LCD_D7_Pin

#endif

gpio.c:包含引脚初始化相关代码

/* Includes ------------------------------------------------------------------*/
#include "gpio.h"
/*----------------------------------------------------------------------------*/
/* Configure GPIO                                                             */
/*----------------------------------------------------------------------------*/

void MX_GPIO_Init(void)
{
  GPIO_InitTypeDef  gpio;
	
  __HAL_RCC_GPIOC_CLK_ENABLE();
  __HAL_RCC_GPIOD_CLK_ENABLE();
  __HAL_RCC_GPIOA_CLK_ENABLE();
  __HAL_RCC_GPIOB_CLK_ENABLE();
	
  gpio.Mode = GPIO_MODE_OUTPUT_PP;
  gpio.Speed = GPIO_SPEED_FREQ_HIGH;
  gpio.Pull = GPIO_NOPULL;
  
  gpio.Pin = _LCD_RS_PIN;
  HAL_GPIO_Init(_LCD_RS_PORT,&gpio);
  gpio.Pin = _LCD_E_PIN;
  HAL_GPIO_Init(_LCD_E_PORT,&gpio);
  gpio.Pin = _LCD_RW_PIN;
  HAL_GPIO_Init(_LCD_RW_PORT,&gpio);
  gpio.Pin = _LCD_D4_PIN;
  HAL_GPIO_Init(_LCD_D4_PORT,&gpio);
  gpio.Pin = _LCD_D5_PIN;
  HAL_GPIO_Init(_LCD_D5_PORT,&gpio);
  gpio.Pin = _LCD_D6_PIN;
  HAL_GPIO_Init(_LCD_D6_PORT,&gpio);
  gpio.Pin = _LCD_D7_PIN;
  HAL_GPIO_Init(_LCD_D7_PORT,&gpio);
}

LCD.c:LCD2004驱动相关代码,一般无需修改

#include "LCD.h"
//############################################################################################
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_Cmd4bit(uint8_t cmd);
static void LCD_Data(uint8_t data);
//############################################################################################
/* Private variable */
static LCD_Options_t LCD_Opts;
//############################################################################################
/* Pin definitions */
#define LCD_RS_LOW              HAL_GPIO_WritePin(_LCD_RS_PORT, _LCD_RS_PIN,GPIO_PIN_RESET)
#define LCD_RS_HIGH             HAL_GPIO_WritePin(_LCD_RS_PORT, _LCD_RS_PIN,GPIO_PIN_SET)
#define LCD_E_LOW               HAL_GPIO_WritePin(_LCD_E_PORT,  _LCD_E_PIN,GPIO_PIN_RESET)
#define LCD_E_HIGH              HAL_GPIO_WritePin(_LCD_E_PORT,  _LCD_E_PIN,GPIO_PIN_SET)
#define LCD_E_BLINK             LCD_E_HIGH; LCD_Delay_us(50); LCD_E_LOW; LCD_Delay_us(50)
//############################################################################################
/* 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
//############################################################################################
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)
{	
	while(HAL_GetTick()<200)
    LCD_Delay_ms(1);
	/* Set cursor pointer to beginning for LCD */
	LCD_Opts.currentX = 0;
	LCD_Opts.currentY = 0;
	LCD_Opts.DisplayFunction = LCD_4BITMODE | LCD_5x8DOTS | LCD_1LINE;
	if (_LCD_ROWS > 1)
		LCD_Opts.DisplayFunction |= LCD_2LINE;
	/* Try to set 4bit mode */
	LCD_Cmd4bit(0x03);
	LCD_Delay_ms(5);
	/* Second try */
	LCD_Cmd4bit(0x03);
	LCD_Delay_ms(5);
	/* Third goo! */
	LCD_Cmd4bit(0x03);
	LCD_Delay_ms(5);
	/* Set 4-bit interface */
	LCD_Cmd4bit(0x02);
	LCD_Delay_ms(5);
	/* Set # lines, font size, 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();
	LCD_Clear();
	/* Default font directions */
	LCD_Opts.DisplayMode = LCD_ENTRYLEFT | LCD_ENTRYSHIFTDECREMENT;
	LCD_Cmd(LCD_ENTRYMODESET | LCD_Opts.DisplayMode);
	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));
	
	for (i = 0; i < 8; i++) {
		LCD_Data(data[i]);
	}
}
//############################################################################################
void LCD_PutCustom(uint8_t x, uint8_t y, uint8_t location)
{
	LCD_CursorSet(x, y);
	LCD_Data(location);
}
//############################################################################################
static void LCD_Cmd(uint8_t cmd)
{
	LCD_RS_LOW;
	LCD_Cmd4bit(cmd >> 4);
	LCD_Cmd4bit(cmd & 0x0F);
}
//############################################################################################
static void LCD_Data(uint8_t data)
{
	LCD_RS_HIGH;
	LCD_Cmd4bit(data >> 4);
	LCD_Cmd4bit(data & 0x0F);
}
//############################################################################################
static void LCD_Cmd4bit(uint8_t cmd)
{
	HAL_GPIO_WritePin(_LCD_D7_PORT, _LCD_D7_PIN, (GPIO_PinState)(cmd & 0x08));
	HAL_GPIO_WritePin(_LCD_D6_PORT, _LCD_D6_PIN, (GPIO_PinState)(cmd & 0x04));
	HAL_GPIO_WritePin(_LCD_D5_PORT, _LCD_D5_PIN, (GPIO_PinState)(cmd & 0x02));
	HAL_GPIO_WritePin(_LCD_D4_PORT, _LCD_D4_PIN, (GPIO_PinState)(cmd & 0x01));
	LCD_E_BLINK;
}
//############################################################################################
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);	
}
//############################################################################################

main.c:包含main主函数,测试显示效果

/* Includes ------------------------------------------------------------------*/
#include "main.h"
#include "LCD.h"

void SystemClock_Config(void);

/**
  * @brief  The application entry point.
  * @retval int
*/

int main(void)
{

    HAL_Init();

    SystemClock_Config();

    MX_GPIO_Init();
	
	LCD_Init();
    LCD_Puts(0,0,"!@#$%^&*()-+=_[]<>?/");
	LCD_Puts(0,1,"0123456789ABCDEFGHIJ");
    LCD_Puts(0,2,"22222222222222222222");
	LCD_Puts(0,3,"33333333333333333333");

  while (1)
  {
		LCD_BlinkOn();
		HAL_Delay(5000);
		LCD_BlinkOff();
		HAL_Delay(5000);
  }
}

/**
  * @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_MUL9;
  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  Period elapsed callback in non blocking mode
  * @note   This function is called  when TIM4 interrupt took place, inside
  * HAL_TIM_IRQHandler(). It makes a direct call to HAL_IncTick() to increment
  * a global variable "uwTick" used as application time base.
  * @param  htim : TIM handle
  * @retval None
  */
void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim)
{
  /* USER CODE BEGIN Callback 0 */

  /* USER CODE END Callback 0 */
  if (htim->Instance == TIM4) {
    HAL_IncTick();
  }
  /* USER CODE BEGIN Callback 1 */

  /* USER CODE END Callback 1 */
}

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

/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/

显示效果:

 

  • 5
    点赞
  • 17
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值