基於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 }

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM