【STM32学习】(18)STM32实现LCD12864显示 - 并行实现8位总线

上一个博客是实现串行显示,现在给大家实现一个并行显示,8位总线的实现,其实四位总线的实现和1602差不多,这里就不去实现了。

先来贴贴1284的一些资料。和1602和相似。

显示屏地址:

具体的资料可以网上查询,资料一大堆。

硬件:STM32L052K8*    这个和其他STM32差不多,只是这款单片机在IO写值时不能一下写两个字节,只能一位一位的写,这个和F系列的单片机不同,但也有解决办法。可以看下面的代码实现。

接线:

PA0-PA7   接     D0-D7

PB1          接     RS

PB2          接     RW

PB3          接     EN

代码如下:

lcd12864.c

#include "lcd12864.h"
#include "stm32l052xx.h"
#include "stm32l0xx_hal_gpio.h" 

uint16_t temp;


//延时
void delay(uint32_t m)
{
	uint32_t i,j;
	for(i=0;i<m;i++)
		for(j=0;j<10;j++);
}
/**
  * @brief GPIO Initialization Function
  * @param None
  * @retval None
  */
void MX_GPIO_Init(void)
{
  GPIO_InitTypeDef GPIO_InitStruct = {0};

  /* GPIO Ports Clock Enable */
  __HAL_RCC_GPIOA_CLK_ENABLE();
  __HAL_RCC_GPIOB_CLK_ENABLE();

  /*Configure GPIO pin Output Level */
  HAL_GPIO_WritePin(GPIOA, GPIO_PIN_0|GPIO_PIN_1|GPIO_PIN_2|GPIO_PIN_3  
                          |GPIO_PIN_4|GPIO_PIN_5|GPIO_PIN_6|GPIO_PIN_7, GPIO_PIN_RESET);

  /*Configure GPIO pin Output Level */
  HAL_GPIO_WritePin(GPIOB, RS_Pin|RW_Pin|EN_Pin, GPIO_PIN_RESET);

  /*Configure GPIO pins : PA0 PA1 PA2 PA3 
                           PA4 PA5 PA6 PA7 */
  GPIO_InitStruct.Pin = GPIO_PIN_0|GPIO_PIN_1|GPIO_PIN_2|GPIO_PIN_3 
                          |GPIO_PIN_4|GPIO_PIN_5|GPIO_PIN_6|GPIO_PIN_7;
  GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
  GPIO_InitStruct.Pull = GPIO_NOPULL;
  GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH;
  HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);

  /*Configure GPIO pins : RS_Pin RW_Pin EN_Pin */
  GPIO_InitStruct.Pin = RS_Pin|RW_Pin|EN_Pin;
  GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
  GPIO_InitStruct.Pull = GPIO_NOPULL;
  GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH;
  HAL_GPIO_Init(GPIOB, &GPIO_InitStruct);

}
//LCD初始化
void LCD_Init(void)
{
	LCD_wcmd(0x30);//功能设定:基本指令集
	HAL_Delay(10);
	//LCD_wcmd(0x08);
	//HAL_Delay(10);
	//LCD_wcmd(0x10);
	//HAL_Delay(10);
	LCD_wcmd(0x0C);//显示开,关光标
	HAL_Delay(10);
	LCD_wcmd(0x01);//清除显示
	HAL_Delay(10);
	//LCD_wcmd(0x06);
	//HAL_Delay(10);
}
//忙判断
void CheckBusy(void)
{
	uint8_t status;
	HAL_GPIO_WritePin(RS_GPIO_Port,RS_Pin,GPIO_PIN_RESET);
	HAL_GPIO_WritePin(RW_GPIO_Port,RW_Pin,GPIO_PIN_SET);	//读出数据,RW=1
	HAL_GPIO_WritePin(GPIOA,GPIO_PIN_0|GPIO_PIN_1|GPIO_PIN_2|GPIO_PIN_3|GPIO_PIN_4|GPIO_PIN_5|GPIO_PIN_6|GPIO_PIN_7,GPIO_PIN_SET);
	do
	{
		HAL_GPIO_WritePin(EN_GPIO_Port,EN_Pin,GPIO_PIN_SET);
		HAL_Delay(5);
		status = HAL_GPIO_ReadPin(GPIOA, GPIO_PIN_7);//接收BF位,判断是否忙
		HAL_GPIO_WritePin(EN_GPIO_Port,EN_Pin,GPIO_PIN_RESET);
	}while(status & 0x80);
	
}
//LCD写命令
void LCD_wcmd(uint8_t cmd)
{
	CheckBusy();
	HAL_GPIO_WritePin(RS_GPIO_Port,RS_Pin,GPIO_PIN_RESET);
	HAL_GPIO_WritePin(RW_GPIO_Port,RW_Pin,GPIO_PIN_RESET);	//读出数据,RW=0
	HAL_Delay(5);
	temp=(temp&0xff00)|cmd;//temp的低八位清零后将cmd放进去
	Write_data(temp);
	//GPIO_Write(GPIOA,temp);//通过GPIO_Write()函数将数据发到A端口(也就是LCD的数据口)
	HAL_GPIO_WritePin(EN_GPIO_Port,EN_Pin,GPIO_PIN_SET);//使能位开启
	HAL_Delay(10);//10ms应该能发送完了
	HAL_GPIO_WritePin(EN_GPIO_Port,EN_Pin,GPIO_PIN_RESET);//使能位关闭
}
//LCD写数据
void LCD_wdat(uint8_t dat)
{
	CheckBusy();
	HAL_GPIO_WritePin(RS_GPIO_Port,RS_Pin,GPIO_PIN_SET);
	HAL_GPIO_WritePin(RW_GPIO_Port,RW_Pin,GPIO_PIN_RESET);
	HAL_Delay(5);
	temp=(temp&0xff00)|dat; //temp的低八位清零后将dat放进去
	Write_data(temp);
	//GPIO_Write(GPIOA,temp);//通过GPIO_Write()函数将数据发到A端口(也就是LCD的数据口)
	HAL_GPIO_WritePin(EN_GPIO_Port,EN_Pin,GPIO_PIN_SET);//使能位开启
	HAL_Delay(10);//10ms应该能发送完了
	HAL_GPIO_WritePin(EN_GPIO_Port,EN_Pin,GPIO_PIN_RESET);//使能位关闭
}
//向LCD12864中写入一行数据(因为你不可能每次只发送一字节数据)
void LCD_Wmessage(uint8_t* message,uint8_t address)
{
	LCD_wcmd(address);//要显示的位置,你想让内容显示在LCD的哪一行,就把该行的起始地址通过写命令的方式发送出去,很神奇,有木有
	while(*message>0)//这个判断很关键,判断你的内容有没有发完
	{
		LCD_wdat(*message); //内核还是发字节函数
		message++; //指针挺好用的。。
	}
}

void  Write_data(uint16_t temp)
{
	/* 高8位值判断 */
	if((temp&0X0080) == 0X0080)			//	**** **** 1000 0000
	{
		HAL_GPIO_WritePin(GPIOA,GPIO_PIN_7,GPIO_PIN_SET);
	}
	else
	{
		HAL_GPIO_WritePin(GPIOA,GPIO_PIN_7,GPIO_PIN_RESET);
	}
	/* 高7位值判断 */
	if((temp&0X0040) == 0X0040)			//	**** **** 1000 0000
	{
		HAL_GPIO_WritePin(GPIOA,GPIO_PIN_6,GPIO_PIN_SET);
	}
	else
	{
		HAL_GPIO_WritePin(GPIOA,GPIO_PIN_6,GPIO_PIN_RESET);
	}
	/* 高6位值判断 */
	if((temp&0X0020) == 0X0020)			//	**** **** 1000 0000
	{
		HAL_GPIO_WritePin(GPIOA,GPIO_PIN_5,GPIO_PIN_SET);
	}
	else
	{
		HAL_GPIO_WritePin(GPIOA,GPIO_PIN_5,GPIO_PIN_RESET);
	}
	/* 高5位值判断 */
	if((temp&0X0010) == 0X0010)			//	**** **** 1000 0000
	{
		HAL_GPIO_WritePin(GPIOA,GPIO_PIN_4,GPIO_PIN_SET);
	}
	else
	{
		HAL_GPIO_WritePin(GPIOA,GPIO_PIN_4,GPIO_PIN_RESET);
	}
	/* 高4位值判断 */
	if((temp&0X0008) == 0X0008)			//	**** **** 1000 0000
	{
		HAL_GPIO_WritePin(GPIOA,GPIO_PIN_3,GPIO_PIN_SET);
	}
	else
	{
		HAL_GPIO_WritePin(GPIOA,GPIO_PIN_3,GPIO_PIN_RESET);
	}
	/* 高3位值判断 */
	if((temp&0X0004) == 0X0004)			//	**** **** 1000 0000
	{
		HAL_GPIO_WritePin(GPIOA,GPIO_PIN_2,GPIO_PIN_SET);
	}
	else
	{
		HAL_GPIO_WritePin(GPIOA,GPIO_PIN_2,GPIO_PIN_RESET);
	}
	/* 高2位值判断 */
	if((temp&0X0002) == 0X0002)			//	**** **** 1000 0000
	{
		HAL_GPIO_WritePin(GPIOA,GPIO_PIN_1,GPIO_PIN_SET);
	}
	else
	{
		HAL_GPIO_WritePin(GPIOA,GPIO_PIN_1,GPIO_PIN_RESET);
	}
	/* 高1位值判断 */
	if((temp&0X0001) == 0X0001)			//	**** **** 1000 0000
	{
		HAL_GPIO_WritePin(GPIOA,GPIO_PIN_0,GPIO_PIN_SET);
	}
	else
	{
		HAL_GPIO_WritePin(GPIOA,GPIO_PIN_0,GPIO_PIN_RESET);
	}
	
	
}

lcd12864.h

#include "main.h"

#define			LINE1		0x80 //第一行起始地址,下同
#define			LINE2 		0x90
#define			LINE3 		0x88
#define			LINE4 		0x98

#define RS_Pin GPIO_PIN_1
#define RS_GPIO_Port GPIOB
#define RW_Pin GPIO_PIN_3
#define RW_GPIO_Port GPIOB
#define EN_Pin GPIO_PIN_5
#define EN_GPIO_Port GPIOB

void MX_GPIO_Init(void);
void LCD_Init(void);
void CheckBusy(void);
void LCD_wcmd(uint8_t cmd);
void LCD_wdat(uint8_t dat);
void LCD_Wmessage(uint8_t* message,uint8_t address);
void  Write_data(uint16_t temp);

main.c

int main(void)
{
  /* USER CODE BEGIN 1 */
	uint8_t dis3[]={"床前明月光,"};
	uint8_t dis4[]={"疑是地上霜,"};
	uint8_t dis5[]={"举头望明月,"};
	uint8_t dis6[]={"低头思故乡。"};
  /* 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();
  LCD_Init();
  /* USER CODE BEGIN 2 */
	//LCD_Wmessage(dis3,LINE1);
  /* USER CODE END 2 */

  /* Infinite loop */
  /* USER CODE BEGIN WHILE */
  while (1)
  {
    /* USER CODE END WHILE */

    /* USER CODE BEGIN 3 */
		LCD_Wmessage(dis3,LINE1); 
		LCD_Wmessage(dis4,LINE2);
		LCD_Wmessage(dis5,LINE3);
		LCD_Wmessage(dis6,LINE4);
  }
  /* USER CODE END 3 */
}

显示效果如下:

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

小材大用

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值