LCD1602模块-带IIC转接板

LCD1602模块-带IIC转接板

LCD1602简介

写时序

在这里插入图片描述

读时序

在这里插入图片描述

指令表

在这里插入图片描述

字符表

在这里插入图片描述

IIC转接板-PCF8574、PCF8574T

IIC地址

在这里插入图片描述

IIC写时序

在这里插入图片描述

IIC读时序

在这里插入图片描述

PCF8574手册

示例代码

iic.c

#include "iic.h"


// IIC总线的延时函数,根据实际情况调整时间
void IIC_Delay()
{
	uint8_t i;

	/* 
	 	下面的时间是通过逻辑分析仪测试得到的。
    工作条件:CPU主频72MHz ,MDK编译环境,1级优化
  
		循环次数为10时,SCL频率 = 205KHz 
		循环次数为7时,SCL频率 = 347KHz, SCL高电平时间1.5us,SCL低电平时间2.87us 
	 	循环次数为5时,SCL频率 = 421KHz, SCL高电平时间1.25us,SCL低电平时间2.375us 
	*/
	for (i = 0; i < 10; i++);
}


// IIC总线的初始化函数
void IIC_Init(void)
{
  GPIO_InitTypeDef GPIO_InitStruct = {0};

	//开启时钟
  IIC_SDA_GPIO_CLK_ENABLE();
	IIC_SCL_GPIO_CLK_ENABLE();

  // 配置SDA、SCL引脚为开漏输出
  GPIO_InitStruct.Pin = SDA_GPIO_PIN | SCL_GPIO_PIN;
  GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_OD;
	GPIO_InitStruct.Pull = GPIO_NOPULL;
  GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH;
	
	//注意:如果不在同个port,需要初始化两次
  HAL_GPIO_Init(SDA_GPIO_PORT, &GPIO_InitStruct);

  // 初始化时将SDA、SCL置高
  IIC_SDA_1();
  IIC_SCL_1();
	
}

// IIC总线的起始信号函数
void IIC_Start(void)
{
  // 先将SDA、SCL置高
  IIC_SDA_1();
  IIC_SCL_1();
  IIC_Delay();

  // 拉低SDA,开始起始信号
  IIC_SDA_0();
  IIC_Delay();

  // 拉低SCL,开始传输数据
  IIC_SCL_0();
  IIC_Delay();
}

// IIC总线的停止信号函数
void IIC_Stop(void)
{
  // 先将SDA、SCL置低
  IIC_SDA_0();
  IIC_SCL_1();
  IIC_Delay();
  // 拉高SCL,传输结束
  IIC_SDA_1();
}

//发送数据
void IIC_SendByte(uint8_t _ucByte)
{
	uint8_t i;

 /* 先发送字节的高位 bit7 */
	for (i = 0; i < 8; i++) {
		if (_ucByte & 0x80) {
			IIC_SDA_1();
		}else{
			IIC_SDA_0();
		}
		IIC_Delay();
		IIC_SCL_1();
		IIC_Delay();
		IIC_SCL_0();
		if (i == 7) {
			IIC_SDA_1(); // 释放总线
		}
		_ucByte <<= 1; /* 左移一个 bit */
		IIC_Delay();
	}
}
//接收数据
uint8_t IIC_ReadByte(void)
{
	uint8_t i;
	uint8_t value;

	/* 读到第 1 个 bit 为数据的 bit7 */
	value = 0;
	for (i = 0; i < 8; i++) {
		value <<= 1;
		IIC_SCL_1();
		IIC_Delay();
		if (IIC_SDA_READ()) {
			value++;
		}
		IIC_SCL_0();
		IIC_Delay();
	}
	return value;
}

//等待从设备响应
uint8_t IIC_WaitAck(void)
{
	uint8_t re;

	IIC_SDA_1();	/* CPU释放SDA总线 */
	IIC_Delay();
	IIC_SCL_1();	/* CPU驱动SCL = 1, 此时器件会返回ACK应答 */
	IIC_Delay();
	if (IIC_SDA_READ())	/* CPU读取SDA口线状态 */
	{
		re = 1;
	}
	else
	{
		re = 0;
	}
	IIC_SCL_0();
	IIC_Delay();
	return re;
}

/*
*********************************************************************************************************
*	函 数 名: i2c_Ack
*	功能说明: CPU产生一个ACK信号
*	形    参:无
*	返 回 值: 无
*********************************************************************************************************
*/
void IIC_Ack(void)
{
	IIC_SDA_0();	/* CPU驱动SDA = 0 */
	IIC_Delay();
	IIC_SCL_1();	/* CPU产生1个时钟 */
	IIC_Delay();
	IIC_SCL_0();
	IIC_Delay();
	IIC_SDA_1();	/* CPU释放SDA总线 */
}

/*
*********************************************************************************************************
*	函 数 名: i2c_NAck
*	功能说明: CPU产生1个NACK信号
*	形    参:无
*	返 回 值: 无
*********************************************************************************************************
*/
void IIC_NAck(void)
{
	IIC_SDA_1();	/* CPU驱动SDA = 1 */
	IIC_Delay();
	IIC_SCL_1();	/* CPU产生1个时钟 */
	IIC_Delay();
	IIC_SCL_0();
	IIC_Delay();	
}

iic.h

#ifndef __IIC_H
#define __IIC_H
#include "stm32f1xx_hal.h"

// IIC总线的SDA、SCL引脚定义
#define SDA_GPIO_PORT GPIOB
#define SDA_GPIO_PIN GPIO_PIN_7
#define SCL_GPIO_PORT GPIOB
#define SCL_GPIO_PIN GPIO_PIN_6

// 定义IIC总线时钟
#define IIC_SDA_GPIO_CLK_ENABLE() __HAL_RCC_GPIOB_CLK_ENABLE()
#define IIC_SCL_GPIO_CLK_ENABLE() __HAL_RCC_GPIOB_CLK_ENABLE()


// 定义IIC总线的高、低电平信号
#define IIC_SDA_1() HAL_GPIO_WritePin(SDA_GPIO_PORT, SDA_GPIO_PIN, GPIO_PIN_SET)
#define IIC_SDA_0() HAL_GPIO_WritePin(SDA_GPIO_PORT, SDA_GPIO_PIN, GPIO_PIN_RESET)
#define IIC_SCL_1() HAL_GPIO_WritePin(SCL_GPIO_PORT, SCL_GPIO_PIN, GPIO_PIN_SET)
#define IIC_SCL_0() HAL_GPIO_WritePin(SCL_GPIO_PORT, SCL_GPIO_PIN, GPIO_PIN_RESET)

// IIC总线的SDA、SCL信号读写操作函数
#define IIC_SDA_READ() HAL_GPIO_ReadPin(SDA_GPIO_PORT, SDA_GPIO_PIN)
#define IIC_SCL_READ() HAL_GPIO_ReadPin(SCL_GPIO_PORT, SCL_GPIO_PIN)


void IIC_Init(void);
void IIC_Start(void);
void IIC_Stop(void);
void IIC_SendByte(uint8_t _ucByte);
uint8_t IIC_ReadByte(void);
uint8_t IIC_WaitAck(void);
void IIC_Ack(void);
void IIC_NAck(void);


#endif  /** __IIC_H */


lcd1602-iic.c

#include "iic.h"
//发送数据
void sendData(uint8_t data)
{
	uint8_t x = 0;
	IIC_Init();
	IIC_Start();
	IIC_SendByte(0x4e); //写地址
  IIC_WaitAck();
	IIC_SendByte(data); //数据
	IIC_WaitAck();
	IIC_Stop();
}

//设置高为|=

#define LCD1602_E_1 0x04
#define LCD1602_RW_1 0x02
#define LCD1602_RS_1 0x01
#define LCD1602_P3_1 0x08



//设置低为&=
#define LCD1602_P3_0 0xf7
#define LCD1602_E_0 0xfb
#define LCD1602_RW_0 0xfd
#define LCD1602_RS_0 0xfe


// 通过IIC发送两个8bit数据
void IIC_SendTwoData(uint8_t data1,uint8_t data2)
{
	IIC_Start(); //发送起始信号
	IIC_SendByte(0x4e); //写设备地址
  IIC_WaitAck(); //等待响应
	IIC_SendByte(data1); //发送数据1
	IIC_WaitAck();//等待响应
	IIC_SendByte(data2); //发送数据2
	IIC_WaitAck();//等待响应
	IIC_Stop();//发送结束信号
}


//发送4字节命令,高位为数据,低四位为控制
void WriteHalfCommand(uint8_t command)
{
	uint8_t tempCommand = command; 
	tempCommand &= LCD1602_RS_0; //模式为指令模式
	tempCommand &= LCD1602_RW_0; //模式为写模式
	tempCommand |= LCD1602_E_1; //设置时钟为高
	tempCommand |= LCD1602_P3_1; //设置背景灯亮
	IIC_SendTwoData(tempCommand,tempCommand&LCD1602_E_0);
	HAL_Delay(1);
}

//发送8字节命令
void WriteFullCommand(uint8_t command)
{
	WriteHalfCommand((command&0xf0));
	WriteHalfCommand((command&0x0f)<<4);
}

//发送4字节数据
void WriteHalfData(uint8_t data)
{
	uint8_t tempData = data; 
	tempData |= LCD1602_RS_1; //模式为数据模式
	tempData &= LCD1602_RW_0; //模式为写模式
	tempData |= LCD1602_E_1; //设置时钟为高
	tempData |= LCD1602_P3_1; //设置背景灯亮
	IIC_SendTwoData(tempData,tempData&LCD1602_E_0);
}

//发送8字节数据
void WriteFullData(uint8_t data)
{
	WriteHalfData((data&0xf0));
	WriteHalfData((data&0x0f)<<4);
}

//发送8字节数据
void ClearScreen(uint8_t data)
{
		//清屏
	WriteFullCommand(0x01);
}


void showChar(uint8_t row,uint8_t col,char ch)
{
		WriteFullCommand(0x80+(0x40*row)+col);
		WriteFullData(ch);
}



void showLine(uint8_t row,uint8_t col,char *string)
{
		WriteFullCommand(0x80+(0x40*row)+col);
		while(*string){
		WriteFullData(*string);
			string++;
		}
}








void initLCD1602(void)
{

	IIC_Init();
	//设置4bit模式
	WriteHalfCommand(0x20);
	WriteFullCommand(0x28);
	WriteFullCommand(0x08);
	WriteFullCommand(0x01);
	WriteFullCommand(0x06);
	//开启显示、不显示光标、不闪烁光标
  WriteFullCommand(0x0c);
	
	
}

…后续更新详细(TODO)

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值