基于STM32单片机实现屏幕休眠后OLED屏幕滚动效果

 

这次做项目时需要实现OLED屏幕上字符滚动的功能,从网上找到一个参考:https://blog.csdn.net/tbmmagic/article/details/111999673

int main(void)
{	
	delay_init();	    	       //延时函数初始化	  
	NVIC_Configuration(); 	   //设置NVIC中断分组2:2位抢占优先级,2位响应优先级 	
	OLED_Init();			         //初始化OLED  
	OLED_Clear(0);             //清屏(全黑)
	OLED_WR_Byte(0x2E,OLED_CMD);        //关闭滚动
        OLED_WR_Byte(0x26,OLED_CMD);        //水平向左或者右滚动 26/27
        OLED_WR_Byte(0x00,OLED_CMD);        //虚拟字节
        OLED_WR_Byte(0x00,OLED_CMD);        //起始页 0
        OLED_WR_Byte(0x07,OLED_CMD);        //滚动时间间隔
        OLED_WR_Byte(0x07,OLED_CMD);        //终止页 7
        OLED_WR_Byte(0x00,OLED_CMD);        //虚拟字节
        OLED_WR_Byte(0xFF,OLED_CMD);        //虚拟字节
		TEST_MainPage();         //主界面显示测试
        OLED_WR_Byte(0x2F,OLED_CMD);        //开启滚动
		

}

void TEST_MainPage(void)
{	
	GUI_ShowString(28,0,"HELLO",16,1);
	GUI_ShowCHinese(12,16,16,"欢迎来到重庆交通大学",1);
	delay_ms(1500);		
	delay_ms(1500);
}	

 

需要调用按键对切换屏幕上的菜单显示,修改数据。长时间未操作,切换到休眠页面,休眠时屏幕滚动显示时间,发生动作时解除休眠。

找到参考代码后,需要解决的一个问题时在while(1)循环里调用屏幕滚动的函数,出现字符无法滚动的现象。我使用了标志位解决了这个问题。

下面是我进行的改动

  1 char row2[22]={0};
  2 u8 weakup_flag=1; //唤醒标志初始为1,
  3 //屏幕滚动函数
  4 void OLED_SleepShow()
  5 {
  6     OLED_Init();                     //初始化OLED  
  7     OLED_Clear();             //清屏(全黑)
  8     OLED_WR_Byte(0x2E,OLED_CMD);        //关闭滚动
  9   OLED_WR_Byte(0x26,OLED_CMD);        //水平向左或者右滚动 26/27
 10   OLED_WR_Byte(0x00,OLED_CMD);        //虚拟字节
 11   OLED_WR_Byte(0x00,OLED_CMD);        //起始页 0
 12   OLED_WR_Byte(0x07,OLED_CMD);        //滚动时间间隔
 13   OLED_WR_Byte(0x07,OLED_CMD);        //终止页 7
 14   OLED_WR_Byte(0x00,OLED_CMD);        //虚拟字节
 15   OLED_WR_Byte(0xFF,OLED_CMD);        //虚拟字节     
 16 
 17 //使用snprintf需要#include " " #include "stdio.h"或者#include "string.h" 忘了,百度一下
  //这个语句太复杂了,作用就是将转换得到的str写入row2,之后显示在OLED屏幕上
18 snprintf(row2,22," 20%s-%s-%s %s:%s:%s ",convert(tmp_time.year, 2, 0, 1, str),convert(tmp_time.mon, 2, 0, 1, str1), 19 convert(tmp_time.day, 2, 0, 1, str2),convert(tmp_time.hour, 2, 0, 1, str3),convert(tmp_time.min, 2, 0, 1, str4) 20 ,convert(tmp_time.sec, 2, 0, 1 , str5)); 21 OLED_Print(0,2,row2,24); //调用相关的显示字符函数 22 delay_ms(1500); 23 delay_ms(1500); 24 25 OLED_WR_Byte(0x2F,OLED_CMD); //开启滚动 26 } 27 28 // /* 29 // * [convert 浮点型输出为字符串] 30 // * @Author WC 31 // * @DateTime 2019-06-29 32 // * @param data [浮点数] 33 // * @param digit [总位数] 34 // * @param dec_digit [小数位数] 35 // * @param mode [0:空格占位符 1:0占位符] 36 // * @param buf [缓存区] 37 // * @return [字符串] 38 // */ 39 char* convert(float data, u8 digit, u8 dec_digit, u8 mode , char* buf) 40 { 41 if (mode == 0) 42 { 43 sprintf(strformat, "%%%d.%df", digit, dec_digit); 44 } 45 else if (mode == 1) 46 { 47 sprintf(strformat, "%%0%d.%df", digit, dec_digit); 48 } 49 sprintf(buf, strformat, data); 50 return buf; 51 } 52 53 /* 54 屏幕唤醒判断 55 按键按下或者档位发生变化 唤醒屏幕 56 当前屏幕为主菜单且 57 */ 58 void WeakupScreen(Menu *menu,u8 key) 59 { 60 if((key!=0)||(gearposition!=0)) //按键按下或者档位变化 61 { 62 time_flag=0; 63 weakup_flag=1; //唤醒标志 64 65 } 66 //当前是主菜单并且达到休眠时间,我这里是调用了TIM3定时器,一个溢出中断立一个time_flag. 67 if((menu->current==0)&&(time_flag>=dp.sleep_time)) 68 { 69 time_flag=0; 70 weakup_flag=0; 71 } 72 } 73 74 75 int main() 76 { 77 while(1) 78 { //如果处于唤醒状态,就执行主要的功能函数,长时间未操作,休眠,切换标志位 79 if(weakup_flag==1) 80 { 81 // gearposition =GearPostion_Collect(); 82 key_value=KEY_Scan(0); 83 WeakupScreen(&menu,key_value); //通过键值得到Weakup标志位的值 84 // key_control(&menu,key_value); 85 // MenuSwitch(&menu,key_value); 86 // ScreenSleepDect(&menu); 87 key_value=0; //清除标志位 88 } 89 //休眠了, 90 if(weakup_flag==0) 91 { 92 OLED_SleepShow(); //滚动屏幕 93 //如果没有这个while,会因为外面的while(1),导致一直刷新,无法滚动屏幕 94 while(!weakup_flag) 95 { 96 key_value=KEY_Scan(0); 97 WeakupScreen(&menu,key_value);//判断是否被唤醒 98 key_value=0; 99 } 100 } 101 }

 

posted on 2021-01-27 20:39  chaina_家长  阅读(1622)  评论(0编辑  收藏  举报