HAL库模拟IIC写四针OLED

OLED.C

#include "driver_oled.h"`
`#include "oledfont.h"` 
`#include "math.h"` 
`uint8_t OLED_GRAM[128][8];`
`//OLED的显存`
`//存放格式如下.`
`//[0]0 1 2 3 ... 127`	
`//[1]0 1 2 3 ... 127`	
`//[2]0 1 2 3 ... 127`	
`//[3]0 1 2 3 ... 127`	
`//[4]0 1 2 3 ... 127`	
`//[5]0 1 2 3 ... 127`	
`//[6]0 1 2 3 ... 127`	
`//[7]0 1 2 3 ... 127 			   
/**********************************************`
`//IIC Start`
`**********************************************/`
`/**********************************************`
`//IIC Start`
`**********************************************/`
`void IIC_Start()`
`{`
		`OLED_SCLK_Set();`
		`OLED_SDIN_Set();`
		`OLED_SDIN_Clr();`
		`OLED_SCLK_Clr();`
`}`

`/**********************************************`
`//IIC Stop`
`**********************************************/`
`void IIC_Stop()`
`{`
    `OLED_SCLK_Set();`
		`OLED_SDIN_Clr();`
		`OLED_SDIN_Set();`
``	
`}`

`void IIC_Wait_Ack()`
`{`
		`OLED_SCLK_Set();`
		`OLED_SCLK_Clr();`
`}`
`/**********************************************`
`// IIC Write byte`
`**********************************************/`

`void Write_IIC_Byte(uint8_t IIC_Byte)`
`{`
		`uint8_t i;`
		`uint8_t m,da;`
		`da=IIC_Byte;`
		`OLED_SCLK_Clr();`
		`for(i=0;i<8;i++)`		
		`{`
			`m=da;`
			`m=m&0x80;`
			`if(m==0x80)`
					`OLED_SDIN_Set();`
			`else` 
					`OLED_SDIN_Clr();`
			`da=da<<1;`
			`OLED_SCLK_Set();`
			`OLED_SCLK_Clr();`
		`}`
`}`
`/**********************************************`
`// IIC Write Command`
`**********************************************/`
`void Write_IIC_Command(uint8_t IIC_Command)`
`{`
		 `IIC_Start();`
		 `Write_IIC_Byte(0x78);            //Slave address,SA0=0`
		 `IIC_Wait_Ack();`	
		 `Write_IIC_Byte(0x00);			//write command`
		 `IIC_Wait_Ack();`	
		 `Write_IIC_Byte(IIC_Command);` 
		 `IIC_Wait_Ack();`	
		 `IIC_Stop();`
`}`
`/**********************************************`
`// IIC Write Data`
`**********************************************/`
`void Write_IIC_Data(uint8_t IIC_Data)`
`{`
		 `IIC_Start();`
		 `Write_IIC_Byte(0x78);			//D/C#=0; R/W#=0`
		 `IIC_Wait_Ack();`	
		 `Write_IIC_Byte(0x40);			//write data`
		 `IIC_Wait_Ack();`	
		 `Write_IIC_Byte(IIC_Data);`
		 `IIC_Wait_Ack();`	
		 `IIC_Stop();`
`}`
`void OLED_WR_Byte(unsigned dat,unsigned cmd)`
`{`
		`if(cmd)`
		`{`
				`Write_IIC_Data(dat);  
		}`
		`else` 
		`{`
				`Write_IIC_Command(dat);`		
		`}`
`}`


`/********************************************`
`// fill_Picture`
`********************************************/`
`void fill_picture(uint8_t fill_Data)`
`{`
		`uint8_t m,n;`
		`for(m=0;m<8;m++)`
		`{`
			`OLED_WR_Byte(0xb0+m,0);		//page0-page1`
			`OLED_WR_Byte(0x02,0);		//low column start address`
			`OLED_WR_Byte(0x10,0);		//high column start address`
			`for(n=0;n<128;n++)`
			`{`
					`OLED_WR_Byte(fill_Data,1);`
			`}`
		`}`
`}`

`` 

`//坐标设置` 
`void OLED_Set_Pos(uint8_t x, uint8_t y)` 
`{` 
		`OLED_WR_Byte(0xb0+y,OLED_CMD);`
		`OLED_WR_Byte((((x+2)&0xf0)>>4)|0x10,OLED_CMD);`
		`OLED_WR_Byte(((x+2)&0x0f),OLED_CMD);` 
`}`  

`//画点` 
`//x:0~127`
`//y:0~63`
`//t:1 填充 0,清空				   
void OLED_DrawPoint(uint8_t x,uint8_t y,uint8_t t)     //用此函数后需要将点更新到LCD,,即OLED_Refresh_Gram();`
`{`
		`uint8_t pos,bx,temp=0;`
		`if(x>127||y>63)`
			`return;//超出范围了.`
		`pos = 7-y/8;            //第几页  其实是反过来,然后       然后会翻转`
		`bx = y%8;`
		`temp = 1<<(7-bx);       //这里使这个 1 与具体的y相匹配`
		`if(t)`
			`OLED_GRAM[x][pos] |= temp;`
		`else` 
			`OLED_GRAM[x][pos] &= ~temp;`	
`}`

`//更新显存到LCD`		 
`void OLED_Refresh_Gram(void)`
`{`
		`uint8_t i,n;		    
		for(i=0;i<8;i++)  
		{  
				OLED_WR_Byte (0xb0+i,OLED_CMD);    //设置页地址(0~7)`
				`OLED_WR_Byte (0x00,OLED_CMD);      //设置显示位置—列低地址`
				`OLED_WR_Byte (0x10,OLED_CMD);      //设置显示位置—列高地址   
				for(n=0;n<128;n++)`
					`OLED_WR_Byte(OLED_GRAM[n][i],OLED_DATA); //将数据写入O_LED的GRAM中`
		`}   
}`

`//画线`
`void LCD_DrawLine(uint16_t x1, uint16_t y1, uint16_t x2,uint16_t y2)//用此函数后需要将点更新到LCD,,即OLED_Refresh_Gram();`
`{`
		`uint16_t t;` 
		`int xerr=0,yerr=0,delta_x,delta_y,distance;` 
		`int incx,incy,uRow,uCol;` 
		`delta_x=x2-x1; //计算坐标增量` 
		`delta_y=y2-y1;` 
		`uRow=x1;` 
		`uCol=y1;` 
		`if(delta_x>0)`
			`incx=1; //设置单步方向` 
		`else if(delta_x==0)`
			`incx=0;//垂直线` 
		`else` 
		`{`
			`incx=-1;`
			`delta_x=-delta_x;`
		`}` 
		`if(delta_y>0)`
			`incy=1;` 
		`else if(delta_y==0)`
			`incy=0;//水平线` 
		`else`
		`{`
				`incy=-1;`
				`delta_y=-delta_y;`
		`}` 
		`if(delta_x>delta_y)`
				`distance=delta_x; //选取基本增量坐标轴` 
		`else` 
				`distance=delta_y;` 
		`for(t=0;t<=distance+1;t++ )//画线输出` 
		`{  
				OLED_DrawPoint(uRow,uCol,1);//画点` 
				`xerr+=delta_x ;` 
				`yerr+=delta_y ;` 
				`if(xerr>distance)` 
				`{` 
						`xerr-=distance;` 
						`uRow+=incx;` 
				`}` 
				`if(yerr>distance)` 
				`{` 
						`yerr-=distance;` 
						`uCol+=incy;` 
				`}` 
		`}  
}` 

`//画圆`
`void draw_circle(uint8_t x0,uint8_t y0,uint8_t r) //圆心(x0,y0),半径r`
`{`
		`uint8_t x,y;`
		`for(x=x0-r;x<=x0+r;x++)`
		`{`
				`uint8_t y_old;`
				`y_old=sqrt(pow(r,2)-pow(x-x0,2));  
			    OLED_DrawPoint(x,y_old+y0,1);    //上圆`
				`OLED_DrawPoint(x,y0-y_old,1);  //下圆`
		`}`
`}`

`//写画实心圆心(x0,y0),半径r`
`void draw_fill_circle(uint8_t x0,uint8_t y0,uint8_t r,uint8_t dot)`
`{`	
		`uint8_t x = 0,y = 0,R = 0;`
		`for(x = x0-r;x <= x0+r;x++)`
	  `{`
				`for(y = y0-r; y <= y0+r ;y++ )`
				`{`
						`R = sqrt(pow(r,2)-pow(x-x0,2))+y0; //圆方程  x,y反置`		
						`if( (y >= y0 && y <= R) || (y < y0 && y >= 2*y0-R )|| dot == 0 ) //点限制在 圆方程内`	
						`{  
								OLED_DrawPoint(y,x,dot);`
						`}`	
				`}`
		`}`
`}`


`//开启OLED显示    
void OLED_Displa
<think>好的,我需要帮用户找到适用于0.96寸OLED显示屏的驱动程序。首先,用户提到的接口应该是IIC协议,因为通常包括VCC、GND、SCL和SDA,而SPI接口一般需要更多引脚。根据提供的引用内容,引用[1]和[2]都提到了STM32的IIC驱动代码,尤其是引用[2]中的主函数示例,说明有现成的初始化函数和显示函数。 接下来,我需要确定用户可能的开发环境。用户引用的是STM32的代码,所以假设他们使用的是STM32系列单片机。驱动程序需要适配STM32的IIC接口,这可能涉及到硬件IIC或软件模拟IIC。引用[2]中的代码包含了iic.h和oled_iic.h,可能使用的是软件模拟IIC,这在STM32中更常见,因为硬件IIC有时会有兼容性问题。 然后,驱动程序的结构应包括IIC通信的基本函数,如起始信号、停止信号、发送字节等,以及OLED的初始化、清屏、入数据等函数。引用[2]中的OLED_Init()和OLED_Menu_Display()函数可能是关键部分。用户可能需要下载这些头文件和源文件,并正确配置到他们的项目中。 另外,用户可能需要字或图形显示的支持,如引用[1]提到的显示汉字和图案。驱动程序里可能包含字数组,如引用[2]中的word.h,这需要包含在项目中以确保正确显示。 最后,需要指导用户如何获取这些驱动代码。可能直接提供代码链接,或者建议在GitHub、论坛或相关技术社区搜索特定关键词,如“STM32 OLED IIC驱动”。同时提醒用户注意引脚配置是否正确,以及根据具体型号调整参数,比如屏幕地址可能默认是0x78或0x7A,需要根据数据手册确认。</think>关于0.96寸OLED显示屏的驱动程序获取,以下是分步骤说明: ### 一、驱动代码获取渠道 1. **官方资源** STM32CubeMX软件包中内置了OLED驱动模板,路径:`STM32Cube_FW_F1_V1.8.4/Drivers/BSP/Components/ssd1306`(版本号可能变化),包含I²C接口的初始化与显示函数[^2]。 2. **开源平台** 在GitHub搜索关键词`STM32 SSD1306 I2C Driver`,可找到如`afiskon/stm32-ssd1306`等开源项目,包含完整的`.c/.h`文件和接线示例。 3. **开发板配套资料** 若使用正点原子/野火等开发板,配套资料包的`HAL_Libraries/OLED`目录下通常包含已验证的驱动代码,支持ASCII码和16x16汉字显示。 ### 二、驱动程序核心组成 ```c // I²C基础通信函数(软件模拟实现) void I2C_Start(void); void I2C_Stop(void); void I2C_WriteByte(uint8_t byte); // OLED专用指令 void OLED_WriteCmd(uint8_t cmd); // 发送控制命令 void OLED_WriteData(uint8_t dat); // 发送显示数据 void OLED_Init(void); // 初始化序列 void OLED_Clear(void); // 清屏函数 ``` ### 三、硬件连接确认 OLED引脚定义一般为: | OLED引脚 | STM32连接目标 | |----------|---------------| | VCC | 3.3V电源 | | GND | 地线 | | SCL | PB6/PB8等GPIO | | SDA | PB7/PB9等GPIO | 需在`oled_iic.h`中修改宏定义匹配实际接线: ```c #define OLED_SCL_PIN GPIO_Pin_6 #define OLED_SDA_PIN GPIO_Pin_7 #define OLED_PORT GPIOB ``` ### 、典型应用代码 ```c // 显示ASCII字符示例 OLED_ShowChar(0, 0, 'A', 16); // 在(0,0)坐标显示16像素高度的字母 // 显示中文需预存字 const uint8_t HZ_测试[] = { 0x00,0x40,0x20,0x50,0x0F,0xE0,... // 16x16点阵数据 }; OLED_ShowCHinese(32, 2, 0); // 调用字数组索引 ``` ### 五、调试注意事项 1. 若屏幕无反应,先用逻辑分析仪检测I²C信号波形,确认时钟频率≤400kHz 2. 检查设备地址是否正确(SSD1306默认地址0x3C,7位格式) 3. 供电不足会导致显示残影,建议单独供电并增加10μF滤波电容 相关问题
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值