STM32 四针OLED屏:实现万年历显示及按键修改时间功能

一、效果展示

      

                启动界面                                 实时时钟界面                                 时间修改界面

二、模块介绍

1.GND电源地

2. VCC电源正(3~5.5V)

3. SCL OLED的D0脚,在IIC通信中为时钟管脚

4. SDA OLED的D1脚,在IIC通信中为数据管脚

本屏所用的驱动IIC为SSD1306; OLED本身是没有显存的,它的显存是依赖于SSD1306提供的(如TFTLCD是本身自带显存,利用FSMC来进行控制)。

SSD1306的显存总共为128*64bit大小,SSD1306将这些显存分为了8页。每页包含了128个字节,总共8页,这样刚好是128*64的点阵大小。

四针的oled屏幕是通过IIC总线驱动,因此,其启动、停止、读、写等程序都是通用的,我会将程序放在下面,大家直接移植即可。

三、文字取模

对于大家使用oled显示,最主要的是“文字取模”、“设置文字显示的位置”

文字取模:就是将自己想显示的文字转换成十六进制数组,如此单片机才能识别从而显示。

取模软件:PCtoLCD2002

步骤:

1、选择文字模式

2、配置取模模式 

 3、输入文字,生成字模

 之后将生成的数组,复制到keil5工程相应的文件中,直接在函数中调用编号即可

注意:粘贴过来的一串十六进制,在数组中的位置应该与你函数中调用的编号一致,如此才能通过函数完成相应的显示(如:第二个大红框代表的是“欢”,在数组的编号为1,函数中输入1即可)

调用OLED_ShowCN(u8 x,u8 y,u8 z)函数显示,修改第三个变量,为想要显示的文字在数组中的编号。

 四、相关程序

main.c

#include "stm32f10x.h"
#include "led.h"
#include "delay.h"
#include "deep.h"
#include "key.h"
#include "sys.h"
#include "oled_i2c.h"
#include "rtc.h"

int main(void)
{	
	u8 Dis_mode;		//显示状态标志 0:显示传感器数据界面  1:显示日期时间界面
    delay_init();	    	                        		//延时函数初始化	  
    NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2); //设置中断优先级分组为组2:2位抢占优先级,2位响应优先级
	LED_Init();
	KEY_Init();
	
	OLED_Init();									 //OLED初始化
	delay_ms(50);
	OLED_CLS();											//清屏
	OLED_ShowCN(16*2,1,1);			 	 	//欢
	OLED_ShowCN(16*3,1,2);       	 	//迎
	OLED_ShowCN(16*4,1,3);        	//使
	OLED_ShowCN(16*5,1,4);     			//用
	OLED_ShowCN(8,4,5);			   			//耀
	OLED_ShowCN(16+8,4,6);        	//鑫
	OLED_ShowCN(16*2+8,4,7);       	//电
	OLED_ShowCN(16*3+8,4,8);     		//子
	OLED_ShowCN(16*4+8,4,9);			  //显
	OLED_ShowCN(16*5+8,4,10);       //示
	OLED_ShowCN(16*6+8,4,11);       //屏
	RTC_Init();
	delay_ms(5000);
	OLED_CLS();										 //清屏
	Dis_mode=1;
	

	while(1)
	{
			
		Key_set();								//按键检测
		switch(Dis_mode)
		{
			case 1:											    					//在显示时间界面
				RTC_Display();													//显示时钟
			break;
		}
		
	}
		
}

oled_iic.c

/************************************************************************************
* Description:128*64点阵的OLED显示屏驱动文件,仅适用于惠特自动化(heltec.taobao.com)的SD1306驱动IIC通信方式显示屏
*
* Others: none;
*
* Function List:
*	1. void I2C_Configuration(void) -- 配置CPU的硬件I2C
* 2. void I2C_WriteByte(uint8_t addr,uint8_t data) -- 向寄存器地址写一个byte的数据
* 3. void WriteCmd(unsigned char I2C_Command) -- 写命令
* 4. void WriteDat(unsigned char I2C_Data) -- 写数据
* 5. void OLED_Init(void) -- OLED屏初始化
* 6. void OLED_SetPos(unsigned char x, unsigned char y) -- 设置起始点坐标
* 7. void OLED_Fill(unsigned char fill_Data) -- 全屏填充
* 8. void OLED_CLS(void) -- 清屏
* 9. void OLED_ON(void) -- 唤醒
* 10. void OLED_OFF(void) -- 睡眠
* 11. void OLED_ShowStr(unsigned char x, unsigned char y, unsigned char ch[], unsigned char TextSize) -- 显示字符串(字体大小有6*8和8*16两种)
* 12. void OLED_ShowCN(unsigned char x, unsigned char y, unsigned char N) -- 显示中文(中文需要先取模,然后放到codetab.h中)
* 13. void OLED_DrawBMP(unsigned char x0,unsigned char y0,unsigned char x1,unsigned char y1,unsigned char BMP[]) -- BMP图片
*
* History: none;
*
*************************************************************************************/

#include "oled_i2c.h"
#include "delay.h"
#include "codetab.h"

//extern 	 u8 display_1[4];                   //当前状态(oled显示的汉字在数组中的索引)
extern u8 display_time_flag;

//初始化IIC
void IIC_Init2(void)
{					     
	GPIO_InitTypeDef GPIO_InitStructure;
	RCC_APB2PeriphClockCmd(	RCC_APB2Periph_GPIOB, ENABLE );	//使能GPIOB时钟
	   
	GPIO_InitStructure.GPIO_Pin = GPIO_Pin_6|GPIO_Pin_7;
	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP ;   //推挽输出
	GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
	GPIO_Init(GPIOB, &GPIO_InitStructure);
	GPIO_SetBits(GPIOB,GPIO_Pin_6|GPIO_Pin_7); 	//PB6,PB7 输出高
	
}
//产生IIC起始信号
void IIC_Start(void)
{
	SDA_OUT();     //sda线输出
	IIC_SDA=1;	  	  
	IIC_SCL=1;
	//delay_us(4);
 	IIC_SDA=0;//START:when CLK is high,DATA change form high to low 
	//delay_us(4);
	IIC_SCL=0;//钳住I2C总线,准备发送或接收数据 
}	 

//产生IIC停止信号
void IIC_Stop(void)
{
	SDA_OUT();//sda线输出
	IIC_SCL=0;
	IIC_SDA=0;//STOP:when CLK is high DATA change form low to high
 	//delay_us(4);
	IIC_SCL=1; 
	IIC_SDA=1;//发送I2C总线结束信号
	//delay_us(4);							   	
}

//等待应答信号到来
//返回值:1,接收应答失败
//        0,接收应答成功
u8 IIC_Wait_Ack(void)
{
	u8 ucErrTime=0;
	SDA_IN();      //SDA设置为输入  
	IIC_SDA=1;/*delay_us(1)*/;	   
	IIC_SCL=1;/*delay_us(1)*/;	 
	while(READ_SDA)
	{
		ucErrTime++;
		if(ucErrTime>250)
		{
			IIC_Stop();
			return 1;
		}
	}
	IIC_SCL=0;//时钟输出0 	   
	return 0;  
} 

//产生ACK应答
void IIC_Ack(void)
{
	IIC_SCL=0;
	SDA_OUT();
	IIC_SDA=0;
	//delay_us(2);
	IIC_SCL=1;
	//delay_us(2);
	IIC_SCL=0;
}

//不产生ACK应答		    
void IIC_NAck(void)
{
	IIC_SCL=0;
	SDA_OUT();
	IIC_SDA=1;
	//delay_us(2);
	IIC_SCL=1;
	//delay_us(2);
	IIC_SCL=0;
}	

//IIC发送一个字节
//返回从机有无应答
//1,有应答
//0,无应答			  
void IIC_Send_Byte(u8 txd)
{                        
    u8 t;   
	  SDA_OUT(); 	    
    IIC_SCL=0;//拉低时钟开始数据传输
    for(t=0;t<8;t++)
    {              
        //IIC_SDA=(txd&0x80)>>7;
		if((txd&0x80)>>7)
			IIC_SDA=1;
		else
			IIC_SDA=0;
		txd<<=1; 	  
		//delay_us(2);   //对TEA5767这三个延时都是必须的
		IIC_SCL=1;
		//delay_us(2); 
		IIC_SCL=0;	
		//delay_us(2);
    }	 
} 

//读1个字节,ack=1时,发送ACK,ack=0,发送nACK   
u8 IIC_Read_Byte(unsigned char ack)
{
	unsigned char i,receive=0;
	SDA_IN();//SDA设置为输入
    for(i=0;i<8;i++ )
	{
        //IIC_SCL=0; 
        delay_us(2);
		//IIC_SCL=1;
        receive<<=1;
        if(READ_SDA)receive++;   
		//delay_us(1); 
    }					 
    if (!ack)
        IIC_NAck();//发送nACK
    else
        IIC_Ack(); //发送ACK   
    return receive;
}

//在AT24CXX指定地址写入一个数据
//WriteAddr  :写入数据的目的地址    
//DataToWrite:要写入的数据
void WriteCmd(unsigned char I2C_Command)
{				   	  	    																 
    IIC_Start();  
	IIC_Send_Byte(0X78);   //
	IIC_Wait_Ack();	 										  		   
	IIC_Send_Byte(0X00);    	 //发送字节							   
	IIC_Wait_Ack();  		  
	IIC_Send_Byte(I2C_Command);    	 //发送字节							   
	IIC_Wait_Ack();
    IIC_Stop();//产生一个停止条件  
}

void WriteDat(unsigned char I2C_Data)//写数据
{
	//I2C_WriteByte(0x40, I2C_Data);
	IIC_Start();  
	IIC_Send_Byte(OLED_ADDRESS);   //
	IIC_Wait_Ack();	 										  		   
	IIC_Send_Byte(0x40);    	 //发送字节							   
	IIC_Wait_Ack();  		  
	IIC_Send_Byte(I2C_Data);    	 //发送字节							   
	IIC_Wait_Ack();
    IIC_Stop();//产生一个停止条件 
	 
}
//void WriteCmd(unsigned char I2C_Command)//写命令
//{
//	I2C_WriteByte(0x00, I2C_Command);
//}

//void WriteDat(unsigned char I2C_Data)//写数据
//{
//	I2C_WriteByte(0x40, I2C_Data);
//}

void OLED_Init(void)
{
	IIC_Init2();
	//I2C_Configuration();		//IIC接口配置
	delay_ms(100); //这里的延时很重要
	
	WriteCmd(0xAE); //display off
	WriteCmd(0x20);	//Set Memory Addressing Mode	
	WriteCmd(0x10);	//00,Horizontal Addressing Mode;01,Vertical Addressing Mode;10,Page Addressing Mode (RESET);11,Invalid
	WriteCmd(0xb0);	//Set Page Start Address for Page Addressing Mode,0-7
	WriteCmd(0xc8);	//Set COM Output Scan Direction
	WriteCmd(0x00); //---set low column address
	WriteCmd(0x10); //---set high column address
	WriteCmd(0x40); //--set start line address
	WriteCmd(0x81); //--set contrast control register
	WriteCmd(0xff); //亮度调节 0x00~0xff
	WriteCmd(0xa1); //--set segment re-map 0 to 127
	WriteCmd(0xa6); //--set normal display
	WriteCmd(0xa8); //--set multiplex ratio(1 to 64)
	WriteCmd(0x3F); //
	WriteCmd(0xa4); //0xa4,Output follows RAM content;0xa5,Output ignores RAM content
	WriteCmd(0xd3); //-set display offset
	WriteCmd(0x00); //-not offset
	WriteCmd(0xd5); //--set display clock divide ratio/oscillator frequency
	WriteCmd(0xf0); //--set divide ratio
	WriteCmd(0xd9); //--set pre-charge period
	WriteCmd(0x22); //
	WriteCmd(0xda); //--set com pins hardware configuration
	WriteCmd(0x12);
	WriteCmd(0xdb); //--set vcomh
	WriteCmd(0x20); //0x20,0.77xVcc
	WriteCmd(0x8d); //--set DC-DC enable
	WriteCmd(0x14); //
	WriteCmd(0xaf); //--turn on oled panel
}

void OLED_SetPos(unsigned char x, unsigned char y) //设置起始点坐标
{ 
	WriteCmd(0xb0+y);
	WriteCmd(((x&0xf0)>>4)|0x10);
	WriteCmd((x&0x0f)|0x01);
}

void OLED_Fill(unsigned char fill_Data)//全屏填充
{
	unsigned char m,n;
	for(m=0;m<8;m++)
	{
		WriteCmd(0xb0+m);		//page0-page1
		WriteCmd(0x00);		//low column start address
		WriteCmd(0x10);		//high column start address
		for(n=0;n<128;n++)
			{
				WriteDat(fill_Data);
			}
	}
}

void OLED_CLS(void)//清屏
{
	OLED_Fill(0x00);
}

//--------------------------------------------------------------
// Prototype      : void OLED_ON(void)
// Calls          : 
// Parameters     : none
// Description    : 将OLED从休眠中唤醒
//--------------------------------------------------------------
void OLED_ON(void)
{
	WriteCmd(0X8D);  //设置电荷泵
	WriteCmd(0X14);  //开启电荷泵
	WriteCmd(0XAF);  //OLED唤醒
}

//--------------------------------------------------------------
// Prototype      : void OLED_OFF(void)
// Calls          : 
// Parameters     : none
// Description    : 让OLED休眠 -- 休眠模式下,OLED功耗不到10uA
//--------------------------------------------------------------
void OLED_OFF(void)
{
	WriteCmd(0X8D);  //设置电荷泵
	WriteCmd(0X10);  //关闭电荷泵
	WriteCmd(0XAE);  //OLED休眠
}

//--------------------------------------------------------------
// Prototype      : void OLED_ShowChar(unsigned char x, unsigned char y, unsigned char ch[], unsigned char TextSize)
// Calls          : 
// Parameters     : x,y -- 起始点坐标(x:0~127, y:0~7); ch[] -- 要显示的字符串; TextSize -- 字符大小(1:6*8 ; 2:8*16)
// Description    : 显示codetab.h中的ASCII字符,有6*8和8*16可选择
//--------------------------------------------------------------
void OLED_ShowStr(unsigned char x, unsigned char y, unsigned char ch[], unsigned char TextSize)
{
	unsigned char c = 0,i = 0,j = 0;
	switch(TextSize)  
	{
		case 1:
		{
			while(ch[j] != '\0')
			{
				c = ch[j] - 32;
				if(x > 126)         //写满一行换行
				{
					x = 0;
					y++;
				}
				OLED_SetPos(x,y);
				for(i=0;i<6;i++)
					WriteDat(F6x8[c][i]);  //写入第一个字符
				x += 6;           //一个字符写完,横向+6个单位
				j++;  //下一个字符
			}
		}break;
		case 2:
		{
			while(ch[j] != '\0')
			{
				c = ch[j] - 32;
				if(x > 120)
				{
					x = 0;
					y++;
				}
				OLED_SetPos(x,y);
				for(i=0;i<8;i++)
					WriteDat(F8X16[c*16+i]);  //一维数组,c*16定位在第几行
				OLED_SetPos(x,y+1);//加了一页(按页存储,共8页)
				for(i=0;i<8;i++)
					WriteDat(F8X16[c*16+i+8]);
				x += 8;
				j++;
			}
		}break;
	}
}

//--------------------------------------------------------------
// Prototype      : void OLED_ShowCN(unsigned char x, unsigned char y, unsigned char N)
// Calls          : 
// Parameters     : x,y -- 起始点坐标(x:0~127, y:0~7); N:汉字在codetab.h中的索引
// Description    : 显示codetab.h中的汉字,16*16点阵
//--------------------------------------------------------------
void OLED_ShowCN(unsigned char x, unsigned char y, unsigned char N)
{
	unsigned char wm=0;
	unsigned int  adder=32*N;
	OLED_SetPos(x , y);
	for(wm = 0;wm < 16;wm++)
	{
		WriteDat(F16x16[adder]);
		adder += 1;
	}
	OLED_SetPos(x,y + 1);
	for(wm = 0;wm < 16;wm++)
	{
		WriteDat(F16x16[adder]);
		adder += 1;
	}
}

//--------------------------------------------------------------
// Prototype      : void OLED_DrawBMP(unsigned char x0,unsigned char y0,unsigned char x1,unsigned char y1,unsigned char BMP[]);
// Calls          : 
// Parameters     : x0,y0 -- 起始点坐标(x0:0~127, y0:0~7); x1,y1 -- 起点对角线(结束点)的坐标(x1:1~128,y1:1~8)
// Description    : 显示BMP位图
//--------------------------------------------------------------
void OLED_DrawBMP(unsigned char x0,unsigned char y0,unsigned char x1,unsigned char y1,unsigned char BMP[])
{
	unsigned int j=0;
	unsigned char x,y;

  if(y1%8==0)
		y = y1/8;
  else
		y = y1/8 + 1;
	for(y=y0;y<y1;y++)
	{
		OLED_SetPos(x0,y);
    for(x=x0;x<x1;x++)
		{
			WriteDat(BMP[j++]);
		}
	}
}

oled_iic.h

#ifndef __OLED_I2C_H
#define	__OLED_I2C_H

#include "stm32f10x.h"

#define OLED_ADDRESS	0x78 //通过调整0R电阻,屏可以0x78和0x7A两个地址 -- 默认0x78


#define SDA_IN()  {GPIOB->CRL&=0X0FFFFFFF;GPIOB->CRL|=(u32)8<<28;}
#define SDA_OUT() {GPIOB->CRL&=0X0FFFFFFF;GPIOB->CRL|=(u32)3<<28;}

//IO操作函数	 
#define IIC_SCL    PBout(6) //SCL
#define IIC_SDA    PBout(7) //SDA	 
#define READ_SDA   PBin(7)  //输入SDA 



void I2C_Configuration(void);
void I2C_WriteByte(uint8_t addr,uint8_t data);
void WriteCmd(unsigned char I2C_Command);
void WriteDat(unsigned char I2C_Data);
void OLED_Init(void);
void OLED_SetPos(unsigned char x, unsigned char y);
void OLED_Fill(unsigned char fill_Data);
void OLED_CLS(void);
void OLED_ON(void);
void OLED_OFF(void);
void OLED_ShowStr(unsigned char x, unsigned char y, unsigned char ch[], unsigned char TextSize);
void OLED_ShowCN(unsigned char x, unsigned char y, unsigned char N);
void OLED_DrawBMP(unsigned char x0,unsigned char y0,unsigned char x1,unsigned char y1,unsigned char BMP[]);

#endif

key.c

#include "key.h"
#include "sys.h" 
#include "delay.h"
#include "oled_i2c.h"
#include "rtc.h"
#include "string.h"
#include "stdio.h"

/*************************************************************************
按键功能:
KEY0:屏幕切换按键(用于切换家具状态 和 时钟显示)
KEY1:时钟界面调整时间(每次按下可设置不同位置的时间,按满五次后退出设置)
KEY2:时间设置时+
KEY3:时间设置时-

*************************************************************************/

u8 Dis_mode=1;		//显示状态标志 0:显示传感器数据  1:显示日期时间


//按键初始化函数
void KEY_Init(void) //IO初始化
{ 
 	GPIO_InitTypeDef GPIO_InitStructure;
 
 	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA|RCC_APB2Periph_GPIOE,ENABLE);//使能PORTA,PORTE时钟

	GPIO_InitStructure.GPIO_Pin  = GPIO_Pin_4|GPIO_Pin_3;//KEY0-KEY1
	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU; //设置成上拉输入
 	GPIO_Init(GPIOE, &GPIO_InitStructure);//初始化GPIOE4,3

	//初始化 WK_UP-->GPIOA.0	  下拉输入
	GPIO_InitStructure.GPIO_Pin  = GPIO_Pin_0;
	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPD; //PA0设置成输入,默认下拉	  
	GPIO_Init(GPIOA, &GPIO_InitStructure);//初始化GPIOA.0

}


void Key_set(void)
{
	unsigned char ic = 0;
	unsigned char disp[20];
	unsigned int syear = 0;
	
	unsigned char smonth,sday,shour,smin;		//临时变量
	syear = calendar.w_year;
	smonth = calendar.w_month;
	sday = calendar.w_date;
	shour = calendar.hour;
	smin = calendar.min;
	if((KEY1==0) && (Dis_mode==1))  						//时间显示界面
	{
		while(KEY1==0);				//等待释放
		OLED_CLS();						//清屏
		OLED_ShowCN(16*3,0,24);		//设置
		OLED_ShowCN(16*4,0,25);
		
		OLED_ShowCN(0,2,12);			//日期
		OLED_ShowCN(16,2,13);
		
		OLED_ShowCN(0,4,14);			//时间
		OLED_ShowCN(16,4,15);


		while((KEY0==0) || (ic<5))   //按下五次KEY1设置时间后,跳出循环,返回时间显示界面。
		{
			if(KEY1==0)         //通过重复按下KEY1,设置不同的时间参数 年、月、日、时、分
			{
				while(KEY1==0);		//等待释放	
				ic++;
				if(ic>9)
					ic= 0;
			}

			if(ic==0)				//年设置
			{
				if(KEY2==1)
				{
					while(KEY2==1);
					syear++;
				}
				//if(KEY3==0)
				//{
				//	while(KEY3==0);
				//	syear--;
				//}

				
				sprintf((char*)disp,">%d-%02d-%02d",syear,smonth,sday);			//将数据以什么样的字符串格式存到disp数组中
				OLED_ShowStr(32,2,disp,2);

				sprintf((char*)disp,":%02d:%02d:%02d",shour,smin,0);
				OLED_ShowStr(32,4,disp,2);

			}
			if(ic==1)				//月设置
			{
				if(KEY2==1)
				{
					while(KEY2==1);				
					smonth++;
					if(smonth>12)
						smonth = 1;
				}
//				if(KEY3==0)
//				{
//					while(KEY3==0);
//					if(smonth>1)
//						smonth--;
//				}

				
				sprintf((char*)disp,":%d>%02d-%02d",syear,smonth,sday);			
				OLED_ShowStr(32,2,disp,2);

				sprintf((char*)disp,":%02d:%02d:%02d",shour,smin,0);
				OLED_ShowStr(32,4,disp,2);

							
			}
			if(ic==2)				//日设置
			{
				if(KEY2==1)
				{
					while(KEY2==1);				
					sday++;
					if(sday>31)
						sday = 1;
				}
//				if(KEY3==0)
//				{
//					while(KEY3==0);
//					if(sday>1)
//						sday--;
//				}
			
				
				sprintf((char*)disp,":%d-%02d>%02d",syear,smonth,sday);			
				OLED_ShowStr(32,2,disp,2);

				sprintf((char*)disp,":%02d:%02d:%02d",shour,smin,0);
				OLED_ShowStr(32,4,(u8 *)disp,2);	
				
			}
			if(ic==3)				//时设置
			{
				if(KEY2==1)
				{
					while(KEY2==1);				
					shour++;
					if(shour>23)
						shour = 0;
				}
//				if(KEY3==0)
//				{
//					while(KEY3==0);
//					if(shour>0)
//						shour--;
//				}
			
				
				sprintf((char*)disp,":%d-%02d-%02d",syear,smonth,sday);			
				OLED_ShowStr(32,2,(u8 *)disp,2);

				sprintf((char*)disp,">%02d:%02d:%02d",shour,smin,0);
				OLED_ShowStr(32,4,(u8 *)disp,2);

				
			}
			if(ic==4)				//分设置
			{
				if(KEY2==1)
				{
					while(KEY2==1);				
					smin++;
					if(smin>59)
						smin = 0;
				}
//				if(KEY3==0)
//				{
//					while(KEY3==0);
//					if(smin>0)
//						smin--;
//				}
				
				
				sprintf((char*)disp,":%d-%02d-%02d",syear,smonth,sday);			
				OLED_ShowStr(32,2,(u8 *)disp,2);

				sprintf((char*)disp,":%02d>%02d:%02d",shour,smin,0);
				OLED_ShowStr(32,4,(u8 *)disp,2);	
				
			}
			
			if(ic==5)				//退出设置  返回到时间显示界面
			{
				RTC_Set(syear,smonth,sday,shour,smin,0);  //设置时间
				Dis_mode = 1;					//显示状态标志 0:显示传感器数据  1:显示日期时间
				OLED_CLS();						//清屏
				ic =0;
				break;
			}
		}
	}
}
	

key.h

#ifndef __KEY_H
#define __KEY_H	 
#include "sys.h"



//#define KEY0 PEin(4)   	//PE4
//#define KEY1 PEin(3)	//PE3 
//#define WK_UP PAin(0)	//PA0  WK_UP

#define KEY0    GPIO_ReadInputDataBit(GPIOE,GPIO_Pin_4)//读取按键0
#define KEY1    GPIO_ReadInputDataBit(GPIOE,GPIO_Pin_3)//读取按键1
#define KEY2    GPIO_ReadInputDataBit(GPIOA,GPIO_Pin_0)//读取按键3(WK_UP) 

 

#define KEY0_PRES 	1	//KEY0按下
#define KEY1_PRES	  2	//KEY1按下
#define WKUP_PRES   3	//KEY_UP按下(即WK_UP/KEY_UP)


void KEY_Init(void);//IO初始化		
void Key_set(void);			    
#endif

完整工程链接:https://item.taobao.com/item.htm?spm=a1z10.3-c.w4002-24450682685.9.14cc609dJigFZh&id=692552845345

物联沃分享整理
物联沃-IOTWORD物联网 » STM32 四针OLED屏:实现万年历显示及按键修改时间功能

发表评论