LCD12864在STM32F103上的实现

最近在项目上用到LCD屏,屏幕大小为128*64,芯片为ST7565不带字库的

STM32F103代码实现,用的是ST的LL库



#define CS_Pin LL_GPIO_PIN_5
#define CS_GPIO_Port GPIOB
#define RST_Pin LL_GPIO_PIN_6
#define RST_GPIO_Port GPIOB
#define A0_Pin LL_GPIO_PIN_8
#define A0_GPIO_Port GPIOB

#define  OLED_CS_HIGH()		LL_GPIO_SetOutputPin(CS_GPIO_Port,CS_Pin)
#define  OLED_CS_LOW()		LL_GPIO_ResetOutputPin(CS_GPIO_Port,CS_Pin)
#define  OLED_WDATA()		LL_GPIO_SetOutputPin(A1_GPIO_Port,A1_Pin)
#define  OLED_WCMD()		LL_GPIO_ResetOutputPin(A1_GPIO_Port,A1_Pin)

//IO口初始化
static void MX_GPIO_Init(void)
{
  LL_GPIO_InitTypeDef GPIO_InitStruct = {0};

  /* GPIO Ports Clock Enable */
  LL_APB2_GRP1_EnableClock(LL_APB2_GRP1_PERIPH_GPIOC);
  LL_APB2_GRP1_EnableClock(LL_APB2_GRP1_PERIPH_GPIOD);
  LL_APB2_GRP1_EnableClock(LL_APB2_GRP1_PERIPH_GPIOB);

  /**/
  LL_GPIO_ResetOutputPin(GPIOB, CS_Pin|RST_Pin|A0_Pin); 

  /**/
  GPIO_InitStruct.Pin = CS_Pin|RST_Pin|A0_Pin;
  GPIO_InitStruct.Mode = LL_GPIO_MODE_OUTPUT;
  GPIO_InitStruct.Speed = LL_GPIO_SPEED_FREQ_LOW;
  GPIO_InitStruct.OutputType = LL_GPIO_OUTPUT_PUSHPULL;
  LL_GPIO_Init(GPIOB, &GPIO_InitStruct);

}


//spi2初始化
static void MX_SPI2_Init(void)
{

  /* USER CODE BEGIN SPI2_Init 0 */

  /* USER CODE END SPI2_Init 0 */

  LL_SPI_InitTypeDef SPI_InitStruct = {0};

  LL_GPIO_InitTypeDef GPIO_InitStruct = {0};

  /* Peripheral clock enable */
  LL_APB1_GRP1_EnableClock(LL_APB1_GRP1_PERIPH_SPI2);

  LL_APB2_GRP1_EnableClock(LL_APB2_GRP1_PERIPH_GPIOB);
  /**SPI2 GPIO Configuration
  PB13   ------> SPI2_SCK
  PB15   ------> SPI2_MOSI
  */
  GPIO_InitStruct.Pin = LL_GPIO_PIN_13|LL_GPIO_PIN_15;
  GPIO_InitStruct.Mode = LL_GPIO_MODE_ALTERNATE;
  GPIO_InitStruct.Speed = LL_GPIO_SPEED_FREQ_HIGH;
  GPIO_InitStruct.OutputType = LL_GPIO_OUTPUT_PUSHPULL;
  LL_GPIO_Init(GPIOB, &GPIO_InitStruct);

  /* SPI2 interrupt Init */
  NVIC_SetPriority(SPI2_IRQn, NVIC_EncodePriority(NVIC_GetPriorityGrouping(),0, 0));
  NVIC_DisableIRQ(SPI2_IRQn);

  /* USER CODE BEGIN SPI2_Init 1 */

  /* USER CODE END SPI2_Init 1 */
  /* SPI2 parameter configuration*/
  SPI_InitStruct.TransferDirection = LL_SPI_FULL_DUPLEX;
  SPI_InitStruct.Mode = LL_SPI_MODE_MASTER;
  SPI_InitStruct.DataWidth = LL_SPI_DATAWIDTH_8BIT;
  SPI_InitStruct.ClockPolarity = LL_SPI_POLARITY_LOW;
  SPI_InitStruct.ClockPhase = LL_SPI_PHASE_1EDGE;
  SPI_InitStruct.NSS = LL_SPI_NSS_SOFT;
  SPI_InitStruct.BaudRate = LL_SPI_BAUDRATEPRESCALER_DIV64;
  SPI_InitStruct.BitOrder = LL_SPI_MSB_FIRST;
  SPI_InitStruct.CRCCalculation = LL_SPI_CRCCALCULATION_DISABLE;
  SPI_InitStruct.CRCPoly = 10;
  LL_SPI_Init(SPI2, &SPI_InitStruct);
  /* USER CODE BEGIN SPI2_Init 2 */
  LL_SPI_EnableIT_TXE(SPI2);
  LL_SPI_Enable(SPI2);
  /* USER CODE END SPI2_Init 2 */

}

//写命令
void SpiWriteComd(uint8_t val)
{
	OLED_WCMD();
    OLED_CS_LOW();
    LL_SPI_TransmitData8(SPI2, val);
    while(LL_SPI_IsActiveFlag_TXE(SPI2) == 0);
    while(LL_SPI_IsActiveFlag_BSY(SPI2) == 1);  //等待发送完成后,置高CS,不能早不能晚

    OLED_CS_HIGH();
}
//写数据
void SpiWriteData(uint8_t val)
{
	OLED_WDATA();
    OLED_CS_LOW();
    LL_SPI_TransmitData8(SPI2, val);
	while(LL_SPI_IsActiveFlag_TXE(SPI2) == 0);
	while(LL_SPI_IsActiveFlag_BSY(SPI2) == 1);  //等待发送完成后,置高CS,不能早不能晚
    OLED_CS_HIGH();
}

//延时
void Lcd_DelayUs(uint32_t us)
{
	uint8_t i;
	while(--us>0){
		for(i=0; i<10; ++i){
			//asm("NOP");
			LL_IWDG_ReloadCounter(IWDG);
		}
	}
}

//复位
void Lcd_Reset(void)
{
	LL_GPIO_ResetOutputPin(RST_GPIO_Port, RST_Pin);
	Lcd_DelayUs(1000);
	LL_GPIO_SetOutputPin(RST_GPIO_Port, RST_Pin);
}

//清屏
void Clear(void)
{
	uint8_t i,j;

	for(i=0;i<8;i++)
	{
		SpiWriteComd(0xb0 + i);
		SpiWriteComd(0x10);
		SpiWriteComd(0);

		for(j=0;j<128;j++)
		{
			SpiWriteData(0x00);
		}
	}
}
//设置行
void SetLine(uint8_t line)
{
	line = line & 0x07;
	line = line | 0xB0;
	SpiWriteComd(line);
}

//设置列
void SetColumn(uint8_t col)
{
	uint8_t col_h,col_l;

	col = col & 0x7F;

	col_h = col & 0xF0;
	col_h >>= 4;
	col_h |= 0x10;

	col_l = col & 0x0F;
	col_l |= 0x00;

	SpiWriteComd(col_h);
	SpiWriteComd(col_l);
}

//写汉字
void PutChinese(uint8_t line,uint8_t column,const uint8_t * data)
{
	uint32_t j;

	SetLine(line);
	SetColumn(column);
	for(j=0;j<16;j++)
	{
		SpiWriteData(*data++);
	}

	SetLine(line + 1);
	SetColumn(column);
	for(j=0;j<16;j++)
	{
		SpiWriteData(*data++);
	}
}

//写字符
void PutAscii(uint8_t line,uint8_t column,const uint8_t * data)
{
	uint32_t j;

	SetLine(line);
	SetColumn(column);
	for(j=0;j<8;j++)
	{
		SpiWriteData(*data++);
	}

	SetLine(line + 1);
	SetColumn(column);
	for(j=0;j<8;j++)
	{
		SpiWriteData(*data++);
	}
}

//初始化
void InitDisplay(void)
{
	uint32_t i;

	Lcd_Reset();
	Clear();

	SpiWriteComd(0xAE);
	SpiWriteComd(0xA2);
	SpiWriteComd(0xA0);
	SpiWriteComd(0xC8);

	SpiWriteComd(0xF8);
	SpiWriteComd(0x00);

	SpiWriteComd(0x25);

	SpiWriteComd(0x81);
	SpiWriteComd(0x28);

	SpiWriteComd(0x2C);
	SpiWriteComd(0x2E);
	SpiWriteComd(0x2F);
	SpiWriteComd(0xAF); //Set Display ON


	PutChinese(0,0,&CH_DOT[0][0]);
	PutChinese(0,16,&CH_DOT[1][0]);

	PutAscii(4,32,&ASCII_DOT['1' - 0x20][0]);
	PutAscii(4,32+8,&ASCII_DOT['2' - 0x20][0]);
	PutAscii(4,32+16,&ASCII_DOT['3' - 0x20][0]);
	PutAscii(4,32+24,&ASCII_DOT['A' - 0x20][0]);
	PutAscii(4,32+32,&ASCII_DOT['B' - 0x20][0]);
	PutAscii(4,32+40,&ASCII_DOT['C' - 0x20][0]);
}

由于网上找的字模提取工具都不能满足自己的应用,所以就自己写了一个:

https://download.csdn.net/download/amw2738/15452725

  • 1
    点赞
  • 12
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
### 回答1: 要将LCD12864STM32F103C8T6连接,需要进行以下步骤: 1. 确定LCD12864的引脚定义,包括VCC、GND、RS、RW、E、D0-D7等。 2. 确定STM32F103C8T6的引脚定义,包括VCC、GND、PA0-PA15、PB0-PB15等。 3. 将LCD12864的VCC引脚连接到STM32F103C8T6的VCC引脚,将GND引脚连接到STM32F103C8T6的GND引脚。 4. 将LCD12864的RS引脚连接到STM32F103C8T6的任意一个GPIO引脚,将RW引脚连接到STM32F103C8T6的GND引脚,将E引脚连接到STM32F103C8T6的任意一个GPIO引脚。 5. 将LCD12864的D0-D7引脚分别连接到STM32F103C8T6的任意一个GPIO引脚。 6. 在STM32F103C8T6的程序中,使用GPIO控制LCD12864的RS、RW、E、D0-D7引脚,实现LCD12864的控制。 以上是连接LCD12864STM32F103C8T6的基本步骤,具体实现还需要根据具体情况进行调整。 ### 回答2: LCD12864是一种常见的字符液晶屏,它可以与STM32F103C8T6单片机进行连接,实现显示字符、图形、动画等多种功能。 首先需要准备好如下硬件器件:LCD12864液晶屏、STM32F103C8T6单片机、杜邦线、电源线。 接线步骤如下: 1.将LCD12864的VSS和VDD分别连接到单片机的GND和5V电源; 2.将LCD12864的V0接到单片机的PWM输出引脚,在程序中可以通过调整PWM的占空比控制屏幕亮度; 3.将LCD12864的RS、RW、E分别连接到单片机的GPIO引脚,用来控制读写信号和使能信号; 4.将LCD12864的DB0-DB7分别连接到单片机的GPIO引脚,用来传输数据; 5.如果需要读取液晶屏的状态,需要将LCD12864的CS1和CS2分别连接到单片机的GPIO引脚。 连接完成后,需要编写程序实现LCD12864的控制。常用的液晶屏控制方法有基于并行接口和串行接口两种方式。在STM32F103C8T6单片机中,可以通过SPI接口或者GPIO口实现液晶屏的控制。 其中,基于并行接口的控制方法较为复杂,需要使用到单片机的多个GPIO口同时进行控制。而基于SPI接口的控制方法相对简单,只需要使用到SPI模块和片选引脚即可。 在使用SPI接口进行液晶屏控制时,需要进行如下设置: 1.初始化SPI模块,包括时钟分频、数据位长度、工作模式等参数的设置; 2.初始化液晶屏的控制引脚,包括RS、RW、E、CS1、CS2等引脚的设置; 3.发送控制命令或数据到液晶屏,包括字符显示、清屏、设置光标位置等操作。 相比较而言,基于SPI接口的控制方法更为简单直观,适合于初学者进行液晶屏的学习和应用。在实际应用中,需要根据具体的需求和硬件环境选择合适的液晶屏控制方法和参数设置,以达到最佳的显示效果。 ### 回答3: LCD12864是一种常用的液晶显示器,常见于各种电子设备中。而STM32F103C8T6是一种嵌入式微控制器,广泛应用于各种控制应用中。将它们连接起来可以实现各种各样的控制应用,下面简单介绍一下如何连接。 首先,需要准备一些基础硬件设备,包括STM32F103C8T6开发板、LCD12864液晶显示器、杜邦线和面包板。在连接之前,需要了解LCD12864的接口和引脚定义。一般来说,LCD12864的引脚包括Vss、Vcc、Vo、RS、RW、E、D0~D7和LED,其中Vss和Vcc为电源引脚,Vo为液晶偏压引脚,RS、RW和E为控制引脚,D0~D7为数据引脚,LED为背光引脚。 接下来,需要将LCD12864液晶显示器和STM32F103C8T6开发板连接起来。在连接之前,需要将LCD12864液晶显示器的引脚与杜邦线连接起来,然后用面包板连接到STM32F103C8T6开发板。具体连接方式如下: 1.将LCD12864的Vss引脚与STM32F103C8T6的GND引脚相连,Vcc引脚与5V引脚相连。 2.将LCD12864的Vo引脚连接到开发板上的模拟输入引脚(如PA4)。 3.将LCD12864的RS引脚连接到开发板上的数字输出引脚(如PA0)。 4.将LCD12864的RW引脚连接到开发板上的数字输出引脚(如PA1)。 5.将LCD12864的E引脚连接到开发板上的数字输出引脚(如PA2)。 6.将LCD12864的D0~D7引脚连接到开发板相应的数字输出引脚(如PA8~PA15)。 7.将LCD12864的LED引脚连接到开发板上的数字输出引脚(如PB5),然后再通过一个电阻连接到5V。 完成连接后,还需要编写相应的程序代码来控制LCD12864显示器。可以采用Keil或者STM32CubeMX编写程序,具体方式可以参考相关的开发资料。在编写程序时,需要掌握LCD12864相应的控制命令和数据格式,以便正确地控制LCD12864显示器。一般来说,需要涉及到初始化、清屏、显示字符串、移动光标等操作。 综上所述,将LCD12864STM32F103C8T6连接需要涉及一定的硬件和软件知识,需要仔细阅读相关的文档和资料,并根据具体应用场景进行相应的开发。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值