stm32硬件spi来驱动2.42英寸oled12864(ssd1309芯片)

文章详细描述了如何在STM32平台使用SSD1309OLED显示器,包括初始化过程、控制命令、功能函数如清屏、画点和读取像素等,以及Cubemx的设置。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

1.cubemx设置

2.驱动代码

  1. oled.c
#include "oled.h"

#include <string.h>

#include "spi.h"
#include "gpio.h"
#include "Delay.h"


#define SCREEN_WIDTH 128
#define SCREEN_HEIGHT 64

#define OLED_RES_Clr() HAL_GPIO_WritePin(OLED_RES_GPIO_Port,OLED_RES_Pin,GPIO_PIN_RESET)//RES
#define OLED_RES_Set() HAL_GPIO_WritePin(OLED_RES_GPIO_Port,OLED_RES_Pin,GPIO_PIN_SET)

#define OLED_DC_Clr()  HAL_GPIO_WritePin(OLED_DC_GPIO_Port,OLED_DC_Pin,GPIO_PIN_RESET)//DC
#define OLED_DC_Set()  HAL_GPIO_WritePin(OLED_DC_GPIO_Port,OLED_DC_Pin,GPIO_PIN_SET)
 		     
#define OLED_CS_Clr()  HAL_GPIO_WritePin(OLED_CS_GPIO_Port,OLED_CS_Pin,GPIO_PIN_RESET)//CS
#define OLED_CS_Set()  HAL_GPIO_WritePin(OLED_CS_GPIO_Port,OLED_CS_Pin,GPIO_PIN_SET)

#define SSD1309_COMMAND   0x00
#define SSD1309_DATA      0x01


uint8_t screenBuffer[128][8] ;

static void SSD1309_Reset(void)
{
    OLED_RES_Set();
    rt_hw_us_delay(100);
    OLED_RES_Clr();
    rt_hw_us_delay(100);
    OLED_RES_Set();
    rt_hw_us_delay(100);
}

void SSD1309_SendByte(uint8_t byte, uint8_t dc)
{
    OLED_CS_Clr();

    if (dc == SSD1309_COMMAND)
    {
       OLED_DC_Clr();
    }
    else
    {
        OLED_DC_Set();
    }

    //HAL_SPI_Transmit(&hspi2, &byte, 1, HAL_MAX_DELAY);
	HAL_SPI_Transmit_IT(&hspi2,&byte, 1);
//	for(uint8_t i=0;i<8;i++)
//	{
//		HAL_GPIO_WritePin(OLED_SCL_GPIO_Port, OLED_SCL_Pin, GPIO_PIN_RESET);
//		
//		/*先传高位*/
//		if (byte & 0x80) 
//		{
//			HAL_GPIO_WritePin(OLED_SDA_GPIO_Port, OLED_SDA_Pin, GPIO_PIN_SET);
//		}
//		else 
//		{
//			HAL_GPIO_WritePin(OLED_SDA_GPIO_Port, OLED_SDA_Pin, GPIO_PIN_RESET);
//		}
//		
//		HAL_GPIO_WritePin(OLED_SCL_GPIO_Port, OLED_SCL_Pin, GPIO_PIN_SET);

//		byte <<= 1;
//	}

    OLED_CS_Set();
}


//更新显存到OLED	
void OLED_Update(void)
{
	uint8_t i,n;
	for(i=0;i<8;i++)
	{
	   SSD1309_SendByte(0xb0+i,SSD1309_COMMAND); //设置行起始地址
	   SSD1309_SendByte(0x00,SSD1309_COMMAND);   //设置低列起始地址
	   SSD1309_SendByte(0x10,SSD1309_COMMAND);   //设置高列起始地址
	   for(n=0;n<128;n++)
	   {
		 SSD1309_SendByte(screenBuffer[n][i],SSD1309_DATA);			   
	   }
  }
}
//清屏函数
void OLED_ClearScreen(void)
{
   	uint8_t i,n; 
	
	for(i=0;i<8;i++)
	{
		for(n=0;n<128;n++)
		{
			screenBuffer[n][i]=0x00;  
		}
	}
	OLED_Update();//更新显示
}

//画点 
//x:0~127
//y:0~63
//t:1 填充 0,清空	
void OLED_DrawPixel(int x, int y, unsigned int t)
{
	uint8_t i,m,n;
	i=y/8;
	m=y%8;
	n=(uint8_t)1<<m;
	if(t)
	{
		screenBuffer[x][i]|=n;
	}
	else
	{
		screenBuffer[x][i]=~screenBuffer[x][i];
		screenBuffer[x][i]|=n;
		screenBuffer[x][i]=~screenBuffer[x][i];
//		screenBuffer[x][i] &= ~n;
	}
}
int OLED_ReadPixel(int x, int y)
{
	uint8_t i,m,n;
	i=x/8;
	m=x%8;
	n=(uint8_t)1<<m;
	if(screenBuffer[y][i]&&n)
		return 1;
	else
		return 0;
}

void SSD1309_SetBrightness(uint8_t brightness)
{
	SSD1309_SendByte(0x81,SSD1309_COMMAND);//命令字节:0x81
	SSD1309_SendByte(brightness,SSD1309_COMMAND);//数据字节:0x7F (对比度值,可以根据需要进行调整)
}

//OLED的初始化
void OLED_Init(void)
{	
	SSD1309_Reset();
	
    //设置解除lock状态
	SSD1309_SendByte(0xFD,SSD1309_COMMAND);//命令字节:0xFD
	SSD1309_SendByte(0x12,SSD1309_COMMAND);//数据字节1:0x12
	//关闭显示:
	SSD1309_SendByte(0xAE,SSD1309_COMMAND);//命令字节:0xAE
	//设置列地址范围(Column Address Range):
	SSD1309_SendByte(0x21,SSD1309_COMMAND);//命令字节:0x21
	SSD1309_SendByte(0x00,SSD1309_COMMAND);//(起始列地址)
	SSD1309_SendByte(0x7F,SSD1309_COMMAND);//数据字节2:0x7F (结束列地址,对应127列)
	//设置页地址范围(Page Address Range):
	SSD1309_SendByte(0x22,SSD1309_COMMAND);//命令字节:0x22
	SSD1309_SendByte(0x00,SSD1309_COMMAND);//数据字节1:0x00 (起始页地址)
	SSD1309_SendByte(0x07,SSD1309_COMMAND);//数据字节2:0x07 (结束页地址,对应7页)
	//设置显示模式:
	SSD1309_SendByte(0xA0,SSD1309_COMMAND);//命令字节:0xA0 (设置段重定向模式,正常模式)
	SSD1309_SendByte(0xC0,SSD1309_COMMAND);//命令字节:0xC0 (设置COM扫描方向,从COM0到COM[N-1])
	//设置对比度控制:
	SSD1309_SendByte(0x81,SSD1309_COMMAND);//命令字节:0x81
	SSD1309_SendByte(0x7F,SSD1309_COMMAND);//数据字节:0x7F (对比度值,可以根据需要进行调整)
	//设置内存地址模式:
	SSD1309_SendByte(0x20,SSD1309_COMMAND);//命令字节:0x20
	SSD1309_SendByte(0x02,SSD1309_COMMAND);//数据字节:0x02 (设置为页寻址模式);00,列地址模式;01,行地址模式;10,页地址模式;默认10;
	//设置显示偏移量(Display Offset):
	SSD1309_SendByte(0xD3,SSD1309_COMMAND);//命令字节:0xD3
	SSD1309_SendByte(0x00,SSD1309_COMMAND);//数据字节:0x00 (偏移量为0)
	//设置SEG/Column 的Mapping
	SSD1309_SendByte(0xA1,SSD1309_COMMAND);// 0xa0左右反置 0xa1正常
	//设置COM/Row的显示方向
	SSD1309_SendByte(0xC8,SSD1309_COMMAND);//0xc0上下反置 0xc8正常	
	//设置显示时钟分频器(Display Clock Divider):
	SSD1309_SendByte(0xD5,SSD1309_COMMAND);//命令字节:0xD5
	SSD1309_SendByte(0xA0,SSD1309_COMMAND);//数据字节:0xF0 (默认分频器值)
	//设置多路复用比率
	SSD1309_SendByte(0xA8,SSD1309_COMMAND);	//Set Multiplex Ratio 	   
	SSD1309_SendByte(0x3F,SSD1309_COMMAND);	//
	//设置预充电周期(Pre-charge Period):
	SSD1309_SendByte(0xD9,SSD1309_COMMAND);//命令字节:0xD9
	SSD1309_SendByte(0x22,SSD1309_COMMAND);//数据字节:0x22 (默认预充电周期值)
	//设置COM引脚配置:
	SSD1309_SendByte(0xDA,SSD1309_COMMAND);//命令字节:0xDA
	SSD1309_SendByte(0x12,SSD1309_COMMAND);//数据字节:0x12 (默认COM引脚配置值)
	//设置VCOMH电压倍数:
	SSD1309_SendByte(0xDB,SSD1309_COMMAND);//命令字节:0xDB
	SSD1309_SendByte(0x20,SSD1309_COMMAND);//数据字节:0x20 (默认VCOMH电压倍数值)
	//设置电源控制:
	SSD1309_SendByte(0x8D,SSD1309_COMMAND);//命令字节:0x8D
	SSD1309_SendByte(0x14,SSD1309_COMMAND);//数据字节:0x14 (开启电源)
	//清屏
	OLED_ClearScreen();
	//开启显示:
	SSD1309_SendByte(0xAF,SSD1309_COMMAND);//命令字节:0xAF

}

 

#ifndef __OLED_H
#define __OLED_H 

#include "main.h"
#include "stdlib.h"	




void OLED_Update(void);
void OLED_ClearScreen(void);
void OLED_DrawPixel(int x, int y, unsigned int color);
int OLED_ReadPixel(int x, int y);
//void SSD1309_SetBrightness(uint8_t brightness);
void OLED_Init(void);





#endif

<think>好的,我现在需要帮助用户寻找SSD1309驱动2.42寸显示屏的示例代码或驱动程序。首先,我需要确认用户的需求。用户提到了SSD13092.42寸的显示屏,并且参考了站内的一个关于PCA9632的引用,可能用户是在某个嵌入式开发项目中工作,比如使用Arduino或者类似的平台。 首先,我应该回忆一下SSD1309SSD1306之间的关系。通常,SSD1309SSD1306都是OLED显示屏的驱动芯片,它们的指令集和通信协议可能相似,甚至兼容。因此,用户可能可以使用现有的SSD1306库,并稍作修改来适配SSD1309。但需要确认这一点是否正确。 接下来,我需要考虑常见的开发平台,比如Arduino、STM32、Raspberry Pi等,用户可能在这些平台上使用SSD1309。不同的平台有不同的库和驱动程序,因此需要提供针对不同平台的示例。 对于Arduino,常用的库是Adafruit SSD1306库,但默认可能不支持SSD1309。不过,用户可以通过修改库中的初始化代码来适配,比如调整地址或初始化命令。另外,可能需要检查I2C或SPI接口的设置是否正确,因为不同的显示屏可能使用不同的通信协议。 对于STM32,可能需要使用HAL库或者CubeMX配置,结合现有的SSD1306驱动代码,同样进行初始化命令的调整。对于Raspberry Pi,使用Python的情况下,可能需要使用luma.oled库,并指定正确的驱动型号。 另外,用户提到的是2.42寸的显示屏,这可能意味着分辨率较高,比如128x64或者更大的分辨率。需要确保示例代码中的分辨率设置正确,否则显示可能会有问题。 还需要考虑用户是否已经正确连接了硬件,比如I2C的地址是否正确(通常SSD1309的I2C地址是0x3C或0x3D),以及电源和接线的正确性。如果用户遇到问题,可能需要检查这些硬件连接。 最后,应该提醒用户如果在现有库中遇到问题,可以尝试联系显示屏的供应商获取具体的驱动代码,或者查找专门为SSD1309编写的库。同时,社区资源如GitHub、Arduino论坛可能已经有相关的解决方案,用户可以进行搜索。</think>针对SSD1309驱动2.42寸显示屏开发,以下是基于不同平台的实现方案和注意事项: ### 1. Arduino平台实现 ```cpp #include <Wire.h> #include <Adafruit_GFX.h> #include <Adafruit_SSD1306.h> #define SCREEN_WIDTH 128 // 根据实际分辨率修改 #define SCREEN_HEIGHT 64 // 根据实际分辨率修改 #define OLED_RESET -1 Adafruit_SSD1306 display(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire, OLED_RESET); void setup() { Wire.begin(); display.begin(SSD1309_SWITCHCAPVCC, 0x3C); // 地址可能为0x3C或0x3D display.display(); delay(2000); display.clearDisplay(); display.setTextSize(1); display.setTextColor(SSD1306_WHITE); } void loop() { display.setCursor(0,0); display.println("Hello SSD1309!"); display.display(); } ``` *注意:需手动修改Adafruit_SSD1306库的SSD1306_128_64.h文件,添加SSD1309的初始化命令序列[^1]* ### 2. STM32 HAL实现 ```c // 硬件I2C初始化代码省略 #define SSD1309_ADDRESS 0x3C void SSD1309_Init(void) { uint8_t init_cmd[] = { 0xAE, // 关闭显示 0xD5, 0x80, // 设置时钟分频 0xA8, 0x3F, // 复用率 0xD3, 0x00, // 显示偏移 0x40, // 起始行 0x8D, 0x14, // 电荷泵 0x20, 0x00, // 内存模式 0xA1, // 段重映射 0xC8, // COM扫描方向 0xDA, 0x12, // COM硬件配置 0x81, 0xCF, // 对比度 0xD9, 0xF1, // 预充电 0xDB, 0x40, // VCOMH 0xA4, // 显示恢复 0xA6, // 正常显示 0xAF // 开启显示 }; HAL_I2C_Mem_Write(&hi2c1, SSD1309_ADDRESS, 0x00, 1, init_cmd, sizeof(init_cmd), 100); } ``` ### 3. Raspberry Pi Python实现 ```python from luma.core.interface.serial import i2c from luma.oled.device import ssd1309 from luma.core.render import canvas serial = i2c(port=1, address=0x3C) device = ssd1309(serial, width=128, height=64) with canvas(device) as draw: draw.rectangle(device.bounding_box, outline="white") draw.text((30, 20), "SSD1309", fill="white") ```
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值