重构过的51版简易IIC通信SSD1306驱动库

/**********************************************************************************
 * 程序名:    SSD1306_IIC驱动程序	
 * 作者:      DaveoCKII			
 * 日期:      2020.7.21			
 * 版本:      STC12C5A60S2 		
 **********************************************************************************/

#ifndef _SSD1306_IIC_H_
#define _SSD1306_IIC_H_

#include <STC12C5A60S2.H>

typedef unsigned char u8;
//------------------------------------定义列表------------------------------------//
sbit SCL = P3^4;	// 时钟线
sbit SDA = P3^3;	// 数据线
//------------------------------------函数列表------------------------------------//

void OLED_Init(void);			// OLED 初始化

void OLED_Clear(void);			// OLED 清屏

void OLED_WriteCMD(u8 cmd);		// OLED 单次写命令

void OLED_WriteDAT(u8 dat);		// OLED 单次写数据

void OLED_WriteMultiByte(u8 *dat, u8 len, u8 cmd);	// OLED连续写入

void OLED_Frame(u8 P[8][128]);		// OLED 一帧图像写入

void OLED_Frame32(u8 P[4][128]);	// OLED 32行写入(为128X32规格设计)

//------------------------------------内部函数------------------------------------//
static void IIC_START(void);		// IIC_开始信号	(重开始信号用此替代)
static void IIC_STOP(void); 		// IIC_结束信号
static void IIC_Write(u8 dat);		// IIC_写数据函数	参数:要写入的数据
//------------------------------------函数内容------------------------------------//

void OLED_WriteCMD(u8 cmd)
{
	IIC_START();		// 通信开始
	IIC_Write(0X78);	// 写从机地址'0111 100' 读写符号'0'
	IIC_Write(0X00);	// 写命令  Co='0' C/D='000 0000'
	IIC_Write(cmd);		// 写入命令
	IIC_STOP();			// 通信结束
}

void OLED_WriteDAT(u8 dat)
{
	IIC_START();		// 通信开始
	IIC_Write(0X78);	// 写从机地址'0111 100' 读写符号'0'
	IIC_Write(0X40);	// 写数据  Co='0' C/D='100 0000'
	IIC_Write(dat);		// 写入数据
	IIC_STOP();			// 通信结束
}

// 参数说明: cmd: 0X00,写命令  0X40,写数据
void OLED_WriteMultiByte(u8 *dat, u8 len, u8 cmd)
{
	u8 i,j;
	IIC_START();		// 通信开始
	IIC_Write(0X78);	// 写从机地址'0111 100' 读写符号'0'
	IIC_Write(cmd);		// 根据参数选择写命令还是数据
	for(i=0; i<len; i++)
		IIC_Write(dat[i]);
	//通信结束
	IIC_STOP();
}

void OLED_Init(void)
{	
	IIC_START();			// 通信开始
	IIC_Write(0X78);		// 写从机地址'0111 100' 读写符号'0'
	IIC_Write(0x00);		// 写命令 Co='0' C/D='000 0000'
	IIC_Write(0XAE);		// 关OLED显示
	// 基础设置
	IIC_Write(0XA4);		// 输出GDDRAM内容
	IIC_Write(0XA6);		// 正常显示(1亮0灭)
	IIC_Write(0X81);		// 设置对比度
	IIC_Write(0X7F);		// 第127级对比度
	// COM和SEG输出设置
	IIC_Write(0XD3);		// 设置垂直显示偏移(向上)
	IIC_Write(0X00);		// 偏移0行
	IIC_Write(0X40);		// 设置GDDRAM起始行 0
	IIC_Write(0XA8);		// 设置MUX数 (显示行数)
	IIC_Write(0X3F);		//  MUX=63	 (显示63行)
	IIC_Write(0XA1);		// 左右反置关(段重映射)
	IIC_Write(0XC8);		// 上下反置关(行重映射)
	IIC_Write(0XDA);		// 设置COM引脚配置
	IIC_Write(0X12);		// 序列COM配置,禁用左右反置
	// 时钟设置
	IIC_Write(0XD5);		// 设置DCLK分频和OSC频率
	IIC_Write(0X80);		// 无分频,第8级OSC频率	
	// 开OLED
	IIC_Write(0X8D);		// 启用电荷泵
	IIC_Write(0X14);		// 启用电荷泵
	IIC_Write(0XAF);		// 开OLED显示
	// 通信结束
	IIC_STOP();
}

void OLED_Clear(void)
{
	u8 i,j;
	// 地址设置
	IIC_START();		// 通信开始
	IIC_Write(0X78);	// 写从机地址'0111 100' 读写符号'0'
	IIC_Write(0x00);	// 写命令 Co='0' C/D='000 0000'
	IIC_Write(0X20);	// 设置GDDRAM模式
	IIC_Write(0X00);	// 水平寻址模式 
	IIC_Write(0X21);	// 设置列起始和结束地址
	IIC_Write(0X00);	// 列起始地址 0
	IIC_Write(0X7F);	// 列终止地址 127
	IIC_Write(0X22);	// 设置页起始和结束地址
	IIC_Write(0X00);	// 页起始地址 0
	IIC_Write(0X07);	// 页终止地址 7
	// 写入一帧'0'
	IIC_START();		// 通信重开始
	IIC_Write(0X78);	// 写从机地址'0111 100' 读写符号'0'
	IIC_Write(0X40);	// 写数据  Co='0' C/D='100 0000'
	for(i=0; i<8; i++){
		for(j=0; j<128; j++){
			IIC_Write(0X00);
		}
	}
	
	IIC_STOP();
}

void OLED_Frame(u8 P[8][128])
{
	u8 i,j;
	// 地址设置
	IIC_START();		// 通信开始
	IIC_Write(0X78);	// 写从机地址'0111 100' 读写符号'0'
	IIC_Write(0x00);	// 写命令 Co='0' C/D='000 0000'
	IIC_Write(0X20);	// 设置GDDRAM模式
	IIC_Write(0X00);	// 水平寻址模式 
	IIC_Write(0X21);	// 设置列起始和结束地址
	IIC_Write(0X00);	// 列起始地址 0
	IIC_Write(0X7F);	// 列终止地址 127
	IIC_Write(0X22);	// 设置页起始和结束地址
	IIC_Write(0X00);	// 页起始地址 0
	IIC_Write(0X07);	// 页终止地址 7
	// 写入一帧数据
	IIC_START();		// 通信重开始
	IIC_Write(0X78);	// 写从机地址'0111 100' 读写符号'0'
	IIC_Write(0X40);	// 写数据  Co='0' C/D='100 0000'
	for(i=0; i<8; i++)
		for(j=0; j<128; j++)
			IIC_Write(P[i][j]);
	// 结束IIC通信
	IIC_STOP();
}

void OLED_Frame32(u8 P[4][128])
{
	u8 i,j;
	// 地址设置
	IIC_START();		// 通信开始
	IIC_Write(0X78);	// 写从机地址'0111 100' 读写符号'0'
	IIC_Write(0x00);	// 写命令 Co='0' C/D='000 0000'
	IIC_Write(0X20);	// 设置GDDRAM模式
	IIC_Write(0X00);	// 水平寻址模式 
	IIC_Write(0X21);	// 设置列起始和结束地址
	IIC_Write(0X00);	// 列起始地址 0
	IIC_Write(0X7F);	// 列终止地址 127
	IIC_Write(0X22);	// 设置页起始和结束地址
	IIC_Write(0X00);	// 页起始地址 0
	IIC_Write(0X07);	// 页终止地址 7
	// 写入32行数据
	IIC_START();		// 通信重开始
	IIC_Write(0X78);	// 写从机地址'0111 100' 读写符号'0'
	IIC_Write(0X40);	// 写数据  Co='0' C/D='100 0000'
	for(i=0; i<4; i++)		
		for(j=0; j<128; j++)
			IIC_Write(P[i][j]);
	// 结束IIC通信
	IIC_STOP();
}

//----------------------------------内部函数内容-----------------------------------//

static void IIC_START(void)
{
	SDA = 1;		// SDA拉高 
	SCL = 1;		// SCL拉高 准备发出起始信号
	SDA = 0;		// SDA拉低 发出起始信号
	SCL = 0;		// SCL拉低 开始传输
}

static void IIC_STOP(void)
{
	SCL = 0;		// SCL拉低 防止可能出现的各种误动作
	SDA = 0;		// SDA拉低
	SCL = 1;		// SCL拉高 准备发出结束信号	
	SDA = 1;		// SDA拉高 发出结束信号
}

static void IIC_Write(u8 dat)
{
	u8 i;
	for(i=0; i<8; i++) 
	{
		SCL = 0; 			// 拉低SCL 准备写数据
		SDA = dat & 0X80;	// 写数据
		dat <<= 1;			// 数据格式:高位在前
		SCL = 1;			// 拉高SCL 发送数据
		SCL = 0;			// 拉低SCL 结束发送
	}
	// 快速跳过ACK
	SCL = 1;		// SCL拉高告诉从机响应
	SCL = 0;		// SCL拉低结束询问ACK
}

//---------------------------------------------------------------------------------//
//------------------------------------定义结束-------------------------------------//
//---------------------------------------------------------------------------------//

#endif

//---------------------------------------------------------------------------------//
//------------------------------------定义结束-------------------------------------//
//---------------------------------------------------------------------------------//

#endif
  • 13
    点赞
  • 77
    收藏
    觉得还不错? 一键收藏
  • 3
    评论
以下是使用STM32HAL驱动SSD1306 OLED显示屏的IIC接口的示例代码: ```c #include "stm32f4xx_hal.h" #include "ssd1306.h" I2C_HandleTypeDef hi2c1; #define SSD1306_I2C_ADDR 0x78 // SSD1306 I2C地址 void SystemClock_Config(void); static void MX_GPIO_Init(void); static void MX_I2C1_Init(void); int main(void) { HAL_Init(); SystemClock_Config(); MX_GPIO_Init(); MX_I2C1_Init(); ssd1306_Init(&hi2c1); ssd1306_Fill(White); // 填充白色 ssd1306_UpdateScreen(&hi2c1); // 更新屏幕 HAL_Delay(1000); ssd1306_Fill(Black); // 填充黑色 ssd1306_UpdateScreen(&hi2c1); // 更新屏幕 while (1) { } } void SystemClock_Config(void) { RCC_OscInitTypeDef RCC_OscInitStruct = {0}; RCC_ClkInitTypeDef RCC_ClkInitStruct = {0}; __HAL_RCC_PWR_CLK_ENABLE(); __HAL_PWR_VOLTAGESCALING_CONFIG(PWR_REGULATOR_VOLTAGE_SCALE1); RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSI; RCC_OscInitStruct.HSIState = RCC_HSI_ON; RCC_OscInitStruct.HSICalibrationValue = RCC_HSICALIBRATION_DEFAULT; RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON; RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_HSI; RCC_OscInitStruct.PLL.PLLM = 8; RCC_OscInitStruct.PLL.PLLN = 336; RCC_OscInitStruct.PLL.PLLP = RCC_PLLP_DIV2; RCC_OscInitStruct.PLL.PLLQ = 7; if (HAL_RCC_OscConfig(&RCC_OscInitStruct) != HAL_OK) { Error_Handler(); } 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_DIV4; RCC_ClkInitStruct.APB2CLKDivider = RCC_HCLK_DIV2; if (HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_5) != HAL_OK) { Error_Handler(); } } static void MX_I2C1_Init(void) { hi2c1.Instance = I2C1; hi2c1.Init.ClockSpeed = 400000; hi2c1.Init.DutyCycle = I2C_DUTYCYCLE_2; hi2c1.Init.OwnAddress1 = 0; hi2c1.Init.AddressingMode = I2C_ADDRESSINGMODE_7BIT; hi2c1.Init.DualAddressMode = I2C_DUALADDRESS_DISABLE; hi2c1.Init.OwnAddress2 = 0; hi2c1.Init.GeneralCallMode = I2C_GENERALCALL_DISABLE; hi2c1.Init.NoStretchMode = I2C_NOSTRETCH_DISABLE; if (HAL_I2C_Init(&hi2c1) != HAL_OK) { Error_Handler(); } } static void MX_GPIO_Init(void) { __HAL_RCC_GPIOC_CLK_ENABLE(); GPIO_InitTypeDef GPIO_InitStruct = {0}; GPIO_InitStruct.Pin = GPIO_PIN_9 | GPIO_PIN_8; GPIO_InitStruct.Mode = GPIO_MODE_AF_OD; GPIO_InitStruct.Pull = GPIO_PULLUP; GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH; GPIO_InitStruct.Alternate = GPIO_AF4_I2C1; HAL_GPIO_Init(GPIOC, &GPIO_InitStruct); } void HAL_I2C_MspInit(I2C_HandleTypeDef* i2cHandle) { GPIO_InitTypeDef GPIO_InitStruct = {0}; if(i2cHandle->Instance==I2C1) { __HAL_RCC_GPIOB_CLK_ENABLE(); __HAL_RCC_I2C1_CLK_ENABLE(); GPIO_InitStruct.Pin = GPIO_PIN_6 | GPIO_PIN_7; GPIO_InitStruct.Mode = GPIO_MODE_AF_OD; GPIO_InitStruct.Pull = GPIO_PULLUP; GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH; GPIO_InitStruct.Alternate = GPIO_AF4_I2C1; HAL_GPIO_Init(GPIOB, &GPIO_InitStruct); } } void HAL_I2C_MspDeInit(I2C_HandleTypeDef* i2cHandle) { if(i2cHandle->Instance==I2C1) { __HAL_RCC_I2C1_CLK_DISABLE(); HAL_GPIO_DeInit(GPIOB, GPIO_PIN_6 | GPIO_PIN_7); } } ``` 上述代码中,我们通过HAL初始化了I2C1接口,并在SSD1306 OLED显示屏上绘制了白色和黑色的屏幕。在使用此代码时,需要包含ssd1306.h和ssd1306.c文件,这些文件包含了SSD1306 OLED显示屏的驱动程序。同时需要注意的是,需要根据实际的硬件连接情况修改I2C引脚的定义。
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值