STM32F103——0.96寸OLED的软件模拟SPI通讯

这篇博客主要记录了STM32F103C8单片机如何通过软件模拟SPI通信来驱动0.96英寸的OLED显示器。博主详细介绍了引脚定义、端口配置,并提供了显示图片和文字的代码资源,如BMP.H、OLEDFONT.H等头文件和主函数代码。
摘要由CSDN通过智能技术生成

目的:仅做个人学习总结备忘

所用单片机型号为:STM32F103C8

引脚定义及端口配置见 OLED.H、OLED.C
显示的图片代码见BMP.H
显示的文字代码见OLEDFONT.H

  • OLED.h
#ifndef __OLED_H
#define __OLED_H


#include "sys.h"
#include "stdlib.h"

/**************OLED_VDD引脚定义****************/
#define PORT_OLED_VDD               GPIOA
#define PIN_OLED_VDD                GPIO_PIN_15

/**************OLED其他引脚定义****************/
#define PORT_OLED_CS				GPIOB
#define PORT_OLED_SCK				GPIOB
#define PORT_OLED_MOSI				GPIOB
#define PORT_OLED_RES				GPIOB
#define PORT_OLED_DC				GPIOB

#define PORT_OLED_ALL				PORT_OLED_CS|PORT_OLED_SCK|PORT_OLED_MOSI|PORT_OLED_RES|PORT_OLED_RES|PORT_OLED_DC


#define PIN_OLED_SCK				GPIO_PIN_1
#define PIN_OLED_MOSI				GPIO_PIN_2
#define PIN_OLED_CS					GPIO_PIN_3
#define PIN_OLED_DC					GPIO_PIN_4
#define PIN_OLED_RES				GPIO_PIN_5

#define PIN_OLED_ALL                PIN_OLED_SCK|PIN_OLED_MOSI|PIN_OLED_CS|PIN_OLED_DC|PIN_OLED_RES

/**************OLED_VDD开、关****************/
#define		OLED_POWER_ON()		HAL_GPIO_WritePin(PORT_OLED_VDD, PIN_OLED_VDD, GPIO_PIN_SET)
#define		OLED_POWER_OFF()	HAL_GPIO_WritePin(PORT_OLED_VDD, PIN_OLED_VDD, GPIO_PIN_RESET)  



//OLED模式设置
//0:4线串行模式
//1:并行8080模式
#define OLED_MODE 0
#define SIZE 16
#define XLevelL		0x00    //0x02
#define XLevelH		0x10
#define Max_Column	128
#define Max_Row		64
#define	Brightness	0xFF 
#define X_WIDTH 	128
#define Y_WIDTH 	64	    

-----------------测试LED端口定义---------------- 
//#define PORT_LED    GPIOA
//#define PIN_LED     GPIO_PIN_7


#define LED_ON GPIO_ResetBits(PORT_LED,PIN_LED)//DC
#define LED_OFF GPIO_SetBits(PORT_LED,PIN_LED)

///* 定义控制IO的宏 */
//#define LED_TOGGLE		    digitalToggle(PORT_LED,PIN_LED)
//#define LED_OFF		        digitalHi(PORT_LED,PIN_LED)
//#define LED_ON			    digitalLo(PORT_LED,PIN_LED)

///* 直接操作寄存器的方法控制IO */
//#define	digitalHi(p,i)		 {p->BSRR=i;}	 //输出为高电平		
//#define digitalLo(p,i)		 {p->BRR=i;}	 //输出低电平
//#define digitalToggle(p,i)   {p->ODR ^=i;} //输出反转状态


//-----------------OLED端口复位置位----------------  					   

#define OLED_SCLK_Clr() HAL_GPIO_WritePin(PORT_OLED_SCK,PIN_OLED_SCK,GPIO_PIN_RESET)//CLK
#define OLED_SCLK_Set() HAL_GPIO_WritePin(PORT_OLED_SCK,PIN_OLED_SCK,GPIO_PIN_SET)

#define OLED_SDIN_Clr() HAL_GPIO_WritePin(PORT_OLED_MOSI,PIN_OLED_MOSI,GPIO_PIN_RESET)//DIN
#define OLED_SDIN_Set() HAL_GPIO_WritePin(PORT_OLED_MOSI,PIN_OLED_MOSI,GPIO_PIN_SET)

#define OLED_RST_Clr() HAL_GPIO_WritePin(PORT_OLED_RES,PIN_OLED_RES,GPIO_PIN_RESET)//RES
#define OLED_RST_Set() HAL_GPIO_WritePin(PORT_OLED_RES,PIN_OLED_RES,GPIO_PIN_SET)

#define OLED_DC_Clr() HAL_GPIO_WritePin(PORT_OLED_DC,PIN_OLED_DC,GPIO_PIN_RESET)//DC
#define OLED_DC_Set() HAL_GPIO_WritePin(PORT_OLED_DC,PIN_OLED_DC,GPIO_PIN_SET)

#define OLED_CS_Clr()   HAL_GPIO_WritePin(PORT_OLED_CS,PIN_OLED_CS,GPIO_PIN_RESET)//CS
#define OLED_CS_Set()   HAL_GPIO_WritePin(PORT_OLED_CS,PIN_OLED_CS,GPIO_PIN_SET)

#define OLED_CMD  0	//写命令
#define OLED_DATA 1	//写数据





//OLED控制用函数
void OLED_WR_Byte(uint8_t dat,uint8_t cmd);	    
void OLED_Display_On(void);
void OLED_Display_Off(void);	   							   		    
void OLED_Init(void);
void OLED_Clear(void);
void OLED_DrawPoint(uint8_t x,uint8_t y,uint8_t t);
void OLED_Fill(uint8_t x1,uint8_t y1,uint8_t x2,uint8_t y2,uint8_t dot);
void OLED_ShowChar(uint8_t x,uint8_t y,uint8_t chr);
void OLED_ShowNum(uint8_t x,uint8_t y,uint32_t num,uint8_t len,uint8_t size);
void OLED_ShowString(uint8_t x,uint8_t y, uint8_t *p);	 
void OLED_Set_Pos(unsigned char x, unsigned char y);
void OLED_ShowCHinese(uint8_t x,uint8_t y,uint8_t no);
void OLED_DrawBMP(unsigned char x0, unsigned char y0,unsigned char x1, unsigned char y1,unsigned char BMP[]);





#endif


  • OLED.c
#include "oled.h"
#include "oledfont.h" 

//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 			   

#if OLED_MODE==1
//向SSD1106写入一个字节。
//dat:要写入的数据/命令
//cmd:数据/命令标志 0,表示命令;1,表示数据;
void OLED_WR_Byte(uint8_t dat,uint8_t cmd)
{
	DATAOUT(dat);	    
	if(cmd)
	  OLED_DC_Set();
	else 
	  OLED_DC_Clr();		   
	OLED_CS_Clr();
	OLED_WR_Clr();	 
	OLED_WR_Set();
	OLED_CS_Set();	  
	OLED_DC_Set();	 
} 	    	    
#else
//向SSD1106写入一个字节。
//dat:要写入的数据/命令
//cmd:数据/命令标志 0,表示命令;1,表示数据;
void OLED_WR_Byte(uint8_t dat,uint8_t cmd)
{	
	uint8_t i;			  
	if(cmd)
	  OLED_DC_Set();
	else 
	  OLED_DC_Clr();		  
	OLED_CS_Clr();
	for(i=0;i<8;i++)
	{			  
		OLED_SCLK_Clr();
		if(dat&0x80)
		   OLED_SDIN_Set();
		else 
		   OLED_SDIN_Clr();
		OLED_SCLK_Set();
		dat<<=1;   
	}				 		  
	OLED_CS_Set();
	OLED_DC_Set();   	  
} 
#endif
	void OLED_Set_Pos(unsigned char x, unsigned char 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); 
}    	  
//开启OLED显示    
void OLED_Display_On(void)
{
	OLED_WR_Byte(0X8D,OLED_CMD);  //SET DCDC命令
	OLED_WR_Byte(0X14,OLED_CMD);  //DCDC ON
	OLED_WR_Byte(0XAF,OLED_CMD);  //DISPLAY ON
}
//关闭OLED显示     
void OLED_Display_Off(void)
{
	OLED_WR_Byte(0X8D,OLED_CMD);  //SET DCDC命令
	OLED_WR_Byte(0X10,OLED_CMD);  //DCDC OFF
	OLED_WR_Byte(0XAE,OLED_CMD);  //DISPLAY OFF
}		   			 
//清屏函数,清完屏,整个屏幕是黑色的!和没点亮一样!!!	  
void OLED_Clear(void)  
{  
	uint8_t i,n;		    
	for(i=0;i<8;i++)  
	{  
		OLED_WR_Byte (0xb0+i,OLED_CMD);    //设置页地址(0~7)
		OLED_WR_Byte (0x02,OLED_CMD);      //设置显示位置—列低地址
		OLED_WR_Byte (0x10,OLED_CMD);      //设置显示位置—列高地址   
		for(n=0;n<128;n++)OLED_WR_Byte(0,OLED_DATA); 
	} //更新显示
}


//在指定位置显示一个字符,包括部分字符
//x:0~127
//y:0~63
//mode:0,反白显示;1,正常显示				 
//size:选择字体 16/12 
void OLED_ShowChar(uint8_t x,uint8_t y,uint8_t chr)
{      	
	unsigned char c=0,i=0;	
		c=chr-' ';//得到偏移后的值			
		if(x>Max_Column-1){x=0;y=y+2;}
		if(SIZE ==16)
			{
			OLED_Set_Pos(x,y);	
			for(i=0;i<8;i++)
			OLED_WR_Byte(F8X16[c*16+i],OLED_DATA);
			OLED_Set_Pos(x,y+1);
			for(i=0;i<8;i++)
			OLED_WR_Byte(F8X16[c*16+i+8],OLED_DATA);
			}
			else {	
				OLED_Set_Pos(x,y+1);
				for(i=0;i<6;i++)
				OLED_WR_Byte(F6x8[c][i],OLED_DATA);
				
			}
}
//m^n函数
uint32_t oled_pow(uint8_t m,uint8_t n)
{
	uint32_t result=1;	 
	while(n--)result*=m;    
	return result;
}				  
//显示2个数字
//x,y :起点坐标	 
//len :数字的位数
//size:字体大小
//mode:模式	0,填充模式;1,叠加模式
//num:数值(0~4294967295);	 		  
void OLED_ShowNum(uint8_t x,uint8_t y,uint32_t num,uint8_t len,uint8_t size)
{         	
	uint8_t t,temp;
	uint8_t enshow=0;						   
	for(t=0;t<len;t++)
	{
		temp=(num/oled_pow(10,len-t-1))%10;
		if(enshow==0&&t<(len-1))
		{
			if(temp==0)
			{
				OLED_ShowChar(x+(size/2)*t,y,' ');
				continue;
			}else enshow=1; 
		 	 
		}
	 	OLED_ShowChar(x+(size/2)*t,y,temp+'0'); 
	}
} 
//显示一个字符号串
void OLED_ShowString(uint8_t x,uint8_t y,uint8_t *chr)
{
	unsigned char j=0;
	while (chr[j]!='\0')
	{		OLED_ShowChar(x,y,chr[j]);
			x+=8;
		if(x>120){x=0;y+=2;}
			j++;
	}
}
//显示汉字
void OLED_ShowCHinese(uint8_t x,uint8_t y,uint8_t no)
{      			    
	uint8_t t,adder=0;
	OLED_Set_Pos(x,y);	
    for(t=0;t<16;t++)
		{
				OLED_WR_Byte(Hzk[2*no][t],OLED_DATA);
				adder+=1;
     }	
		OLED_Set_Pos(x,y+1);	
    for(t=0;t<16;t++)
			{	
				OLED_WR_Byte(Hzk[2*no+1][t],OLED_DATA);
				adder+=1;
      }					
}
/***********功能描述:显示显示BMP图片128×64起始点坐标(x,y),x的范围0~127,y为页的范围0~7*****************/
void OLED_DrawBMP(unsigned ch
  • 3
    点赞
  • 11
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值