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

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

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

  • 4
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
好的,基于STM32SPI驱动SSD1309的程序可以分为以下几个步骤: 1. 配置SPI 首先需要配置SPI外设,包括时钟、模式、数据位数、CPOL、CPHA等参数。下面是一个示例代码段: ```c hspi.Instance = SPI1; hspi.Init.Mode = SPI_MODE_MASTER; hspi.Init.Direction = SPI_DIRECTION_2LINES; hspi.Init.DataSize = SPI_DATASIZE_8BIT; hspi.Init.CLKPolarity = SPI_POLARITY_HIGH; hspi.Init.CLKPhase = SPI_PHASE_2EDGE; hspi.Init.NSS = SPI_NSS_SOFT; hspi.Init.BaudRatePrescaler = SPI_BAUDRATEPRESCALER_256; hspi.Init.FirstBit = SPI_FIRSTBIT_MSB; hspi.Init.TIMode = SPI_TIMODE_DISABLE; hspi.Init.CRCCalculation = SPI_CRCCALCULATION_DISABLE; hspi.Init.CRCPolynomial = 10; if (HAL_SPI_Init(&hspi) != HAL_OK) { Error_Handler(); } ``` 2. 配置SSD1309 需要根据SSD1309的规格书,配置SSD1309的各种参数,包括显示模式、扫描方向、显示偏移等。下面是一个示例代码段: ```c SSD1309_Write_Command(0xAE); // 关闭显示 SSD1309_Write_Command(0xD5); // 设置时钟分频因子/振荡器频率 SSD1309_Write_Command(0x80); // 振荡频率 SSD1309_Write_Command(0xA8); // 设置驱动路数 SSD1309_Write_Command(0x3F); // 默认0x3F,1/64 驱动 SSD1309_Write_Command(0xD3); // 设置显示偏移 SSD1309_Write_Command(0x00); // 默认为0 SSD1309_Write_Command(0x40); // 设置显示开始行 [5:0] SSD1309_Write_Command(0x8D); // 电荷泵设置 SSD1309_Write_Command(0x14); // 0x10(关闭);0x14(开启) SSD1309_Write_Command(0x20); // 设置内存地址模式 SSD1309_Write_Command(0x02); // 0x00(水平地址模式);0x01(垂直地址模式);0x02(页地址模式) SSD1309_Write_Command(0xA1); // 段重定向设置 SSD1309_Write_Command(0xC0); // 设置COM扫描方向 SSD1309_Write_Command(0xDA); // 设置COM硬件引脚配置 SSD1309_Write_Command(0x12); SSD1309_Write_Command(0x81); // 对比度设置 SSD1309_Write_Command(0xCF); // 0x00~0xFF SSD1309_Write_Command(0xD9); // 预充电设置 SSD1309_Write_Command(0xF1); // 0x22(默认);0xF1(启动);0x00(关闭) SSD1309_Write_Command(0xDB); // VCOMH设置 SSD1309_Write_Command(0x40); // 0x20,0.77xVcc SSD1309_Write_Command(0xA4); // 全局显示开启 SSD1309_Write_Command(0xA6); // 设置显示方式;bit0:1表示反相,0表示正常;bit1:1表示全局反相,0表示正常 ``` 3. 绘制图像 可以通过向SSD1309的数据缓存中写入数据,来绘制图像。下面是一个示例代码段: ```c // 清除屏幕 SSD1309_Clear(); // 绘制一条直线 SSD1309_Draw_Line(0, 0, 127, 31); // 绘制一个矩形 SSD1309_Draw_Rectangle(10, 10, 50, 20); // 绘制一个圆形 SSD1309_Draw_Circle(64, 16, 10); // 更新屏幕显示 SSD1309_Update_Screen(); ``` 4. 发送数据 最后,将绘制好的图像数据通过SPI发送到SSD1309的数据缓存中,即可实现显示。下面是一个示例代码段: ```c // 将数据写入SSD1309的缓存 SSD1309_Write_Data_Buffer(data_buffer, SSD1309_WIDTH * SSD1309_PAGES); // 更新屏幕显示 SSD1309_Update_Screen(); ``` 以上代码仅供参考,具体实现需要根据自己的具体情况进行调整。
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值