STM32多功能小灯

项目描述:

基于STM32控制的多功能小灯,有红外遥控、光敏自动调节亮度、以及超声波检测人是否在位功能。然后用OLED实现人机交互,多级菜单,功能选择。

硬件:

STM32C8T6

红外接收器HS0038

光敏传感器

0.96 4引脚OLED屏幕

HCSR04超声波测距

若干杜邦线以及按键

LED灯

模块IO 
红外控制A1TIM2CH2
按键控制B12/13/14
超声波控制A9\A10Trig\Echo
光敏控制B1ADC12IN9
LEDPB0TIM3CH3 PWM

项目步骤以及功能实现

一.编写各模块驱动

1.PWM

2.红外接受模块

3.ADC光敏传感器

4.超声波模块

5.移植U8g2图象图

6.编写多级菜单

二.代码编写

PWM

void PWM_Init()
{
	/*启动时钟*/
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB,ENABLE);
	RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM3,ENABLE);
	
	/*初始化引脚*/
	GPIO_InitTypeDef GPIO_InitStructure;
	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
	GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0;
	GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
	GPIO_Init(GPIOB,&GPIO_InitStructure);
	
	/*TIM3选择内部时钟*/
	TIM_InternalClockConfig(TIM3);
	
	/*时基配置*/
	TIM_TimeBaseInitTypeDef TIM_TimeBaseInitStruct;
	TIM_TimeBaseInitStruct.TIM_ClockDivision = TIM_CKD_DIV1 ;
	TIM_TimeBaseInitStruct.TIM_CounterMode = TIM_CounterMode_Up;
	TIM_TimeBaseInitStruct.TIM_Period = 10-1;
	TIM_TimeBaseInitStruct.TIM_Prescaler = 72-1;
	TIM_TimeBaseInitStruct.TIM_RepetitionCounter = 0;
	TIM_TimeBaseInit(TIM3,&TIM_TimeBaseInitStruct);
	
	/********中断用在超声波模块用了计算返回时间********/
	TIM_ClearFlag(TIM3, TIM_FLAG_Update);			//清除更新中断标志位
	TIM_ITConfig(TIM3, TIM_IT_Update, ENABLE);		//开启更新中断
	
	NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);				//设置中断优先级分组
	
	/*中断配置*/
	NVIC_InitTypeDef NVIC_InitStructure;						//定义结构体,配置中断优先级
	NVIC_InitStructure.NVIC_IRQChannel = TIM3_IRQn;				//指定中断通道
	NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;				//中断使能
	NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 2;	//设置抢占优先级
	NVIC_InitStructure.NVIC_IRQChannelSubPriority = 2;			//设置响应优先级
	NVIC_Init(&NVIC_InitStructure);								// https://blog.zeruns.tech
	/************************************************/
	
	/*OC输出比较通道初始化化*/
	TIM_OCInitTypeDef TIM_OCInitStruct;
	TIM_OCStructInit(&TIM_OCInitStruct);
	TIM_OCInitStruct.TIM_OCMode = TIM_OCMode_PWM1;
	TIM_OCInitStruct.TIM_OCPolarity = TIM_OCPolarity_High;
	TIM_OCInitStruct.TIM_OutputState = TIM_OutputState_Enable ;
	TIM_OCInitStruct.TIM_Pulse = 0;
	TIM_OC3Init(TIM3,&TIM_OCInitStruct);
	
	TIM_Cmd(TIM3,ENABLE);
}

/**
  * @brief  设置PWM的比较值
  * @param  
  * @param  
  * @retval None
  */
void PWM_SetCompare(uint16_t Compare)
{
    TIM_SetCompare3(TIM3, Compare);
}

红外接受

#include "Remote.h"
#include "stm32f10x.h"                  // Device header
#include "OLED.h"
 
void Remote_Init(void)
{
	RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2,ENABLE);
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA,ENABLE);
	
		
	GPIO_InitTypeDef GPIO_InitStructure;
	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU;
	GPIO_InitStructure.GPIO_Pin = GPIO_Pin_1;
	GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
	GPIO_Init(GPIOA,&GPIO_InitStructure);
	
	TIM_InternalClockConfig(TIM2);//将时钟源选择内部时钟
	
	TIM_TimeBaseInitTypeDef TIM_TimeBaseInitStructure;
	TIM_TimeBaseInitStructure.TIM_ClockDivision = TIM_CKD_DIV1;
	TIM_TimeBaseInitStructure.TIM_CounterMode = TIM_CounterMode_Up;
	TIM_TimeBaseInitStructure.TIM_Period = 20000-1;
	TIM_TimeBaseInitStructure.TIM_Prescaler = 72-1;
	TIM_TimeBaseInitStructure.TIM_RepetitionCounter  = 0;
	TIM_TimeBaseInit(TIM2,&TIM_TimeBaseInitStructure);
	
	TIM_ICInitTypeDef TIM_ICInitStructure;
	TIM_ICInitStructure.TIM_Channel = TIM_Channel_2;
	TIM_ICInitStructure.TIM_ICFilter  = 0x03;
	TIM_ICInitStructure.TIM_ICPolarity =  TIM_ICPolarity_Falling;
	TIM_ICInitStructure.TIM_ICPrescaler  = TIM_ICPSC_DIV1;
	TIM_ICInitStructure.TIM_ICSelection = TIM_ICSelection_DirectTI;
	TIM_ICInit(TIM2,&TIM_ICInitStructure);
	
	NVIC_InitTypeDef NVIC_InitStruct;
	NVIC_InitStruct.NVIC_IRQChannel = TIM2_IRQn;
	NVIC_InitStruct.NVIC_IRQChannelCmd = ENABLE;
	NVIC_InitStruct.NVIC_IRQChannelPreemptionPriority  = 1;
	NVIC_InitStruct.NVIC_IRQChannelSubPriority = 1;
	NVIC_Init(&NVIC_InitStruct);
	
	
	TIM_ITConfig(TIM2, TIM_IT_CC2, ENABLE);
}
/**********************************红外遥控***********************************/
/*
通过检测下捕捉下降沿进入中断间隔时间来判断红外接收数据
*/
unsigned int IR_Time;//进中断的间隔时间
unsigned char IR_State;//当前状态

unsigned char IR_Data[4];//读取到的数据分别是地址码 反码 数据码 反码
unsigned char IR_pData;//当前读取到的数据位

unsigned char IR_DataFlag;//数据读取完毕标志
unsigned char IR_RepeatFlag;//重复按键标志
unsigned char IR_Address;//地址码
unsigned char IR_Command;//数据之类码

void TIM2_IRQHandler()
{
	 if(TIM_GetITStatus(TIM2,TIM_IT_CC2)==SET)
	 {
		 if(IR_State==0)//红外产生下降沿第一次进出中断
		 {
			 TIM_SetCounter(TIM2,0);//清楚计时器
			 TIM_Cmd(TIM2,ENABLE);//启动计时器
			 IR_State=1;
		 }
			else if(IR_State==1)
			{
				IR_Time = TIM_GetCounter(TIM2);//获取计时器的值
				TIM_SetCounter(TIM2,0);//计时器清零
			  if(IR_Time>13500-500 && IR_Time<13500+500)//
				{ 
					 IR_State=2;
				}
			 else if(IR_Time>11370-500 && IR_Time<11370+500)
			 {
				 IR_RepeatFlag = 1;
				 TIM_Cmd(TIM2,DISABLE);
				 IR_State=0;
			 }
			 else
			 {
				 IR_State = 1;
			 }
			}
			else if(IR_State == 2)
			{
			 IR_Time = TIM_GetCounter(TIM2);
			 TIM_SetCounter(TIM2,0);
			 if(IR_Time>1120-500 && IR_Time<1120+500)
			 {
					IR_Data[IR_pData/8]&=~(0x01<<(IR_pData%8));	//数据对应位清0
					IR_pData++;			//数据位置指针自增
			 }
			 else if(IR_Time>2250-500 && IR_Time<2250+500)
			 {
					IR_Data[IR_pData/8]|=(0x01<<(IR_pData%8));	//数据对应位置1
					IR_pData++;			//数据位置指针自增
			 }
			 else
			 {
				 IR_pData = 0;
				 IR_State = 1;
			 }
			 if(IR_pData==32)
			 {
				 IR_pData = 0;
				 
					 IR_Address=IR_Data[0];	//转存数据
					 IR_Command=IR_Data[2];
					 IR_DataFlag=1;	//置收到连发帧标志位为1
				
				 TIM_SetCounter(TIM2,0);
				 IR_State = 0;
			 }
			}
		 TIM_ClearITPendingBit(TIM2,  TIM_IT_CC2);
	 }
}

/**
  * @brief  红外遥控获取收到数据帧标志位
  * @param  无
  * @retval 是否收到数据帧,1为收到,0为未收到
  */
unsigned char IR_GetDataFlag(void)
{
	if(IR_DataFlag)
	{
		IR_DataFlag=0;
		return 1;
	}
	return 0;
}

/**
  * @brief  红外遥控获取收到连发帧标志位
  * @param  无
  * @retval 是否收到连发帧,1为收到,0为未收到
  */
unsigned char IR_GetRepeatFlag(void)
{
	if(IR_RepeatFlag)
	{
		IR_RepeatFlag=0;
		return 1;
	}
	return 0;
}

/**
  * @brief  红外遥控获取收到的地址数据
  * @param  无
  * @retval 收到的地址数据
  */
unsigned char IR_GetAddress(void)
{
	return IR_Address;
}

/**
  * @brief  红外遥控获取收到的命令数据
  * @param  无
  * @retval 收到的命令数据
  */
unsigned char IR_GetCommand(void)
{
	return IR_Command;
}


/**
  * @brief  放回按键功能,有增加,减少,开关
  * @param  
  * @retval None
  */
uint8_t IR_Num;
uint8_t IR_GetNum()
{
	static uint8_t Mode;
			if(IR_GetDataFlag())
		{
			if(IR_GetCommand()==IR_VOL_ADD)
			{
				IR_Num += 20;
				if(IR_Num>=100) IR_Num=100;
			}
			if(IR_GetCommand()==IR_VOL_MINUS)
			{
				IR_Num -= 20;
				if(IR_Num>100||IR_Num==0) IR_Num=0;
			}
			if(IR_GetCommand()==IR_POWER)
			{
				if(Mode==0)
				{
					Mode=1;
					IR_Num = 50;
				}
				else if(Mode==1)
				{
					Mode = 0;
					IR_Num = 0;
				}	
			}
		}
	return IR_Num/10;
}

光敏

#include "stm32f10x.h"                  // Device header

void AD_Init(void)
{
	/*启动时钟*/
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB,ENABLE);//配置时钟总线使能
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_ADC1,ENABLE);
	
	/*初始化引脚*/
	GPIO_InitTypeDef GPIO_InitStructure;
	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AIN;//引脚配置成模拟输入模式
	GPIO_InitStructure.GPIO_Pin = GPIO_Pin_1;
	GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
	GPIO_Init(GPIOB,&GPIO_InitStructure);
	
	RCC_ADCCLKConfig(RCC_PCLK2_Div6);//配置ADC时钟
	ADC_RegularChannelConfig(ADC1, ADC_Channel_9, 1, ADC_SampleTime_55Cycles5);//配置ADC通道采样排名
	
	/*ADC初始化*/
	ADC_InitTypeDef ADC_InitStructure;
	ADC_InitStructure.ADC_ContinuousConvMode = DISABLE;											                                       
	ADC_InitStructure.ADC_DataAlign = ADC_DataAlign_Right;                                                         
	ADC_InitStructure.ADC_ExternalTrigConv  =ADC_ExternalTrigConv_None ;                                           
	ADC_InitStructure.ADC_Mode = ADC_Mode_Independent;                                                             
	ADC_InitStructure.ADC_NbrOfChannel  = 1;                                                                       
	ADC_InitStructure.ADC_ScanConvMode = DISABLE;                                                                  
	ADC_Init(ADC1,&ADC_InitStructure);
	
	ADC_Cmd(ADC1,ENABLE);
	
	/*ADC校准*/
	ADC_ResetCalibration(ADC1);//复位校准寄存器
  while (ADC_GetResetCalibrationStatus(ADC1) == SET);//在复位校准过程中Status一直被置Set
  ADC_StartCalibration(ADC1);//启动校准寄存器
  while (ADC_GetCalibrationStatus(ADC1) == SET);//在启动校准过程中Status一直被置Set
}

uint16_t ADC_GetValue()
{
    ADC_SoftwareStartConvCmd(ADC1, ENABLE);//软件触发开始转变
    while (ADC_GetFlagStatus(ADC1, ADC_FLAG_EOC) == RESET);//如果转变成功了就为Set,RESET说明还在转变过程中
    return ADC_GetConversionValue(ADC1);//转变成功后放回
}

uint16_t ADC_GetCompare()
{
	uint16_t Value;
	Value = ADC_GetValue();
	if(Value<3500&&Value>2000) return 10;
	if(Value<2000&&Value>1000) return 5;
	if(Value<1000&&Value>0)    return 0;
	return Value;
}

超声波

#include "stm32f10x.h"                  // Device header
#include "Delay.h"
#include "OLED.h"
#define Trig GPIO_Pin_9
#define Echo GPIO_Pin_10

uint64_t time=0;			//声明变量,用来计时
uint64_t time_end=0;		//声明变量,存储回波信号时间
/**
  * @brief  HCSR04初始化 
  * @param  
  * @param  
  * @retval None
  */
void HCSRO4_Init()
{
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA,ENABLE);
	
	GPIO_InitTypeDef GPIO_InitStructure;
	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
	GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9;
	GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
	GPIO_Init(GPIOA,&GPIO_InitStructure);
	
	GPIO_InitTypeDef GPIO_InitStructure2;
	GPIO_InitStructure2.GPIO_Mode = GPIO_Mode_IPD;			//设置GPIO口为下拉输入模式
	GPIO_InitStructure2.GPIO_Pin = GPIO_Pin_10;	
	GPIO_InitStructure2.GPIO_Speed = GPIO_Speed_50MHz;	//设置GPIO口10
	GPIO_Init(GPIOA,&GPIO_InitStructure2);					//初始化GPIOA
	
	GPIO_WriteBit(GPIOA,Trig,0);
	Delay_us(15);
}
/**
  * @brief  返回测试的距离mm为单位
  * @param  无
  * @param  无
  * @retval Distance_mm:返回测距结果
  */
uint16_t Get_sonar_mm()
{
	uint32_t Distance,Distance_mm = 0;
	GPIO_WriteBit(GPIOA,Trig,1);						//输出高电平
	Delay_us(15);										//延时15微秒
	GPIO_WriteBit(GPIOA,Trig,0);						//输出低电平
	while(GPIO_ReadInputDataBit(GPIOA,GPIO_Pin_10)==0);		//等待低电平结束
	time=0;												//计时清零
	while(GPIO_ReadInputDataBit(GPIOA,Echo)==1);		//等待高电平结束
	time_end=time;										//记录结束时的时间
	if(time_end/100<38)									//判断是否小于38毫秒,大于38毫秒的就是超时,直接调到下面返回0
	{
		Distance=(time_end*346)/2;						//计算距离,25°C空气中的音速为346m/s
		Distance_mm=Distance/100;						//因为上面的time_end的单位是10微秒,所以要得出单位为毫米的距离结果,还得除以100
	}
	return Distance_mm;									//返回测距结果
}
/**
  * @brief  返回PWM的比较器的值
  * @param  
  * @param  
  * @retval 0 or 5
  */
uint8_t Get_Sonar_Num()
{
	int Sonar_Num=Get_sonar_mm();
	if(Sonar_Num <= 300)
	{
		return 5;
	}
	else
	{
		return 0;
	}
}
void TIM3_IRQHandler(void)			//更新中断函数,用来计时,每10微秒变量time加1
{
	if (TIM_GetITStatus(TIM3, TIM_IT_Update) == SET)		//获取TIM3定时器的更新中断标志位
	{
		time++;
		TIM_ClearITPendingBit(TIM3, TIM_IT_Update);			//清除更新中断标志位
	}
}

多级菜单

多级菜单主要是使用数组索引的方法来实现

#include "stm32f10x.h"                  // Device header
#include "menu.h"
#include "Key.h"
#include "OLED.h"
#include "Remote.h"
#include "PWM.h"
#include "ADC.h"
#include "HCSR04.h"
#include "u8g2.h"
#include "U8G2_int.h"
#include <Stdio.h>

#define KEY_UP  	1 //向上
#define KEY_DOWN	2	//向下
#define KEY_ENTER 3	//确定
uint8_t fresh_flag; //进入第2层函数标志位

/*********************************第0层************************************/
void Main_UI(u8g2_t *u8g2)
{
	draw(u8g2);
}
/**************************************************************************/

/*********************************第1层************************************/
/*******************************************************************************
* 函数名   	: fun1
* 功能			: 主要在第一层显示列表,每个函数只是>的位置指向该选项而已
* 输入			: 无 
* 输出			: 无
*******************************************************************************/
void Main_Remote_fun1(u8g2_t *u8g2)//红外选项
{
		u8g2_SetFontMode(u8g2, 1);//
		u8g2_SetFont(u8g2, u8g2_font_unifont_t_symbols);//字库选择
		u8g2_ClearBuffer(u8g2);
    u8g2_DrawStr(u8g2,0,16,">");
    u8g2_DrawStr(u8g2,16,16,"[1]Remote");
    u8g2_DrawStr(u8g2,16,32,"[2]Photosen");
    u8g2_DrawStr(u8g2,16,48,"[3]Hcsr04");
    u8g2_DrawStr(u8g2,16,64,"<--");
		u8g2_SendBuffer(u8g2);
}

void Main_Photosen_fun1(u8g2_t *u8g2)//光敏电阻选项
{
		u8g2_SetFontMode(u8g2, 1);//字体模式
    u8g2_SetFont(u8g2, u8g2_font_unifont_t_symbols);//字库选择
		u8g2_ClearBuffer(u8g2);
		/*************写显示数据进缓存区中***************/
		u8g2_DrawStr(u8g2,0,32,">");
    u8g2_DrawStr(u8g2,16,16,"[1]Remote");
    u8g2_DrawStr(u8g2,16,32,"[2]Photosen");
    u8g2_DrawStr(u8g2,16,48,"[3]Hcsr04");
    u8g2_DrawStr(u8g2,16,64,"<--");   
		/*************发送缓存区中的数据到显示屏幕***************/
		u8g2_SendBuffer(u8g2);
}
void Main_Hcsr04_fun1(u8g2_t *u8g2)//超声波选项
{
		u8g2_SetFontMode(u8g2, 1);
    u8g2_SetFont(u8g2, u8g2_font_unifont_t_symbols);//字库选择
		u8g2_ClearBuffer(u8g2);
		u8g2_DrawStr(u8g2,0,48,">");
    u8g2_DrawStr(u8g2,16,16,"[1]Remote");
    u8g2_DrawStr(u8g2,16,32,"[2]Photosen");
    u8g2_DrawStr(u8g2,16,48,"[3]Hcsr04");
    u8g2_DrawStr(u8g2,16,64,"<--");
		u8g2_SendBuffer(u8g2);
}
void Main_Return_fun1(u8g2_t *u8g2)//放回上一层
{
		u8g2_SetFontMode(u8g2, 1);
    u8g2_SetFont(u8g2, u8g2_font_unifont_t_symbols);//字库选择
		u8g2_ClearBuffer(u8g2);
		u8g2_DrawStr(u8g2,0,64,">");
    u8g2_DrawStr(u8g2,16,16,"[1]Remote");
    u8g2_DrawStr(u8g2,16,32,"[2]Photosen");
    u8g2_DrawStr(u8g2,16,48,"[3]Hcsr04");
    u8g2_DrawStr(u8g2,16,64,"<--"); 
		u8g2_SendBuffer(u8g2);
}
/**************************************************************************/

/*********************************第2层************************************/
/*******************************************************************************
* 函数名   	: fun2
* 功能			: 执行改功能函数
* 输入			: 无 
* 输出			: 无
*******************************************************************************/
void Main_Remote_fun2(u8g2_t *u8g2)
{
		Remote_Init();
		uint8_t Value;
		Value = IR_GetNum();
		PWM_SetCompare(Value);
		char str[20];
		sprintf(str,"%d",Value);//将整型初始化为字符串类型
		u8g2_SetFontMode(u8g2, 1);
		u8g2_SetFont(u8g2, u8g2_font_unifont_t_symbols);
		u8g2_ClearBuffer(u8g2);
		u8g2_DrawStr(u8g2,0,48,"Value:");
		u8g2_DrawStr(u8g2,48,48,str);
    u8g2_SetFont(u8g2, u8g2_font_crox4tb_tf);//字库选择
		u8g2_DrawStr(u8g2,30,13,"Remote");
		u8g2_SendBuffer(u8g2);
		fresh_flag = 1;
}

void Main_Photosen_fun2(u8g2_t *u8g2)
{
		AD_Init();
		uint8_t Value = ADC_GetCompare();
		char str[20];
		sprintf(str,"%d",Value);
		u8g2_SetFontMode(u8g2, 1);
		u8g2_SetFont(u8g2, u8g2_font_unifont_t_symbols);
		u8g2_ClearBuffer(u8g2);
		u8g2_DrawStr(u8g2,0,48,"Value:");
		u8g2_DrawStr(u8g2,48,48,str);
    u8g2_SetFont(u8g2, u8g2_font_crox4tb_tf);//字库选择
		u8g2_DrawStr(u8g2,30,13,"Photosen");
		u8g2_SendBuffer(u8g2);
		PWM_SetCompare(Value);
		fresh_flag = 1;
}

void Main_Hcsr04_fun2(u8g2_t *u8g2)
{
		HCSRO4_Init();
		uint8_t Value = Get_Sonar_Num();
		char str[20];
		sprintf(str,"%d",Value);
		u8g2_SetFontMode(u8g2, 1);
		u8g2_SetFont(u8g2, u8g2_font_unifont_t_symbols);
		u8g2_ClearBuffer(u8g2);
		u8g2_DrawStr(u8g2,0,48,"Value:");
		u8g2_DrawStr(u8g2,48,48,str);
    u8g2_SetFont(u8g2, u8g2_font_crox4tb_tf);//字库选择
		u8g2_DrawStr(u8g2,30,13,"Hcsr04");
		u8g2_SendBuffer(u8g2);
		PWM_SetCompare(Value);
		fresh_flag = 1;
}
/**************************************************************************/

/*********************************数组索引表************************************/
key_table table[20] =																												
{ 
	//{自身索引号,上一页的索引号,下一页的索引号,子菜单的索引号,自身执行的函数}                                                                        
	{0,0,0,1,Main_UI},                                                        
	                                                                          
	{1,4,2,5,Main_Remote_fun1},                                               
	{2,1,3,6,Main_Photosen_fun1},                                             
	{3,2,4,7,Main_Hcsr04_fun1},                                               
	{4,3,1,8,Main_Return_fun1},                                               
	                                                                          
	{5,1,1,1,Main_Remote_fun2},                                               
	{6,1,1,1,Main_Photosen_fun2},                                             
	{7,1,1,1,Main_Hcsr04_fun2},                                               
	{8,0,0,1,Main_UI}                                                         
};                                                                          
/*******************************************************************************/
                                                                              
void Menu_Koop(u8g2_t *u8g2)
{
	static u8 func_index=0;//当前页面索引值
	static u8 last_index=127;//上一个界面索引值
	static void (*current_operation_func)(u8g2_t *u8g2);//定义一个函数指针
	
	static uint8_t KeyNum;
	KeyNum	= Key_GetKeyNum();
	if(KeyNum != 0)
	{
		fresh_flag=1;
		last_index=func_index;
		switch(KeyNum)
		{
			case KEY_UP: func_index = table[func_index].up;break ;//更新索引号
			case KEY_DOWN: func_index = table[func_index].down;break ;
			case KEY_ENTER: func_index = table[func_index].enter;break ;
		}
	}
	if(fresh_flag ==1)//按键按下就刷新执行函数
	{
			fresh_flag=0;
			current_operation_func = table[func_index].current_operation;	
			u8g2_ClearBuffer(u8g2);
			(*current_operation_func)(u8g2);//执行当前操作函数
			u8g2_SendBuffer(u8g2);
			last_index = func_index;
	}
	if(func_index==0)
	{
		u8g2_ClearBuffer(u8g2);
		Main_UI(u8g2);
		u8g2_SendBuffer(u8g2);
	}
}

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值