新聞中心

        EEPW首頁 > 嵌入式系統 > 設計應用 > 基于STM32的多功能數字鐘

        基于STM32的多功能數字鐘

        作者: 時間:2016-11-18 來源:網絡 收藏
        /**************************************************************************************
        程序功能:基于STM32的多功能數字鐘
        **************************************************************************************
        1、時鐘的基準用STM32F103RCT6自帶的RTC實現。
        2、這三個按鍵的功能分別為:"設置"、"+"、"-"。(WAKEUP KEY0 KEY1)
        三個按鍵作為這三個功能:
        鍵盤上的WAKEUP用作"設置",KEY0用作"+",KEY1用作"-"。
        設定時間、日期、星期時,按下設定鍵,
        相應的參數會閃動,即一亮一滅,提示正的修改的數據,每按一下設置鍵,
        設定的項目就會變化,順序為:
        秒--分--時--星期--日--月--年。
        順序設定完后,再按一下設定鍵,就退出設定狀態,回到正顯示狀態。
        3、用DS18B20顯示溫度。精確到小數點后一位。如:33.5℃。
        4、增加用紅外遙控器的CH CH+ CH- 三個按鍵進行時間設置,
        功能等同于鍵盤上的(WAKEUP KEY0 KEY1)"設置"、"+"、"-"。
        5、通過串行口設置時間日期。
        如串行口發送t12:30:00 設置時間;
        如串行口發送d2016-08-12 設置日期;
        6、通過觸摸屏進行時間日期設置
        在觸摸屏上有 SET + -三個標志,當用觸筆去按時,就會產生同開發板上的
        按鍵一樣的效果。
        觸摸按下去和彈起來時,按鍵的顏色會發生變化。
        **************************************************************************************
        硬件:LED0----GPIOA.8
        KEY0----GPIOC.5
        KEY1----GPIOA.15
        KEY_WAKEUP----GPIOA.0
        TIMER2定時器定時功能。
        TIMER5定時器的定時和捕獲功能
        TFT液晶屏2。8寸屏帶觸摸功能。
        TOUCH觸摸屏。
        DS18B20---PC4;
        HS138紅外遙控---PA1;
        串行口USART1;
        RTC實時時鐘
        開發板:正點原子MINI開發板
        **************************************************************************************
        編程目的:讓大賽學生盡快學會STM32的綜合編程。
        **************************************************************************************
        編程軟件:KEIL5
        **************************************************************************************
        常用的算法:
        按鍵采用狀態機實現按鍵掃描。在定時器中對按鍵進行處理。
        紅外部分采用定時器捕獲功能實現。
        時間用STM32自帶的RTC實現;
        **************************************************************************************
        時間:2016.8.12
        作者:王廬山
        工作室:湖北工業職業技術學院電子創新中心
        ***************************************************************************************/
        #include "stm32f10x_conf.h"
        #include "delay.h"
        #include "sys.h"
        #include "LED.h"
        #include "key.h"
        #include "timer2.h"
        #include "24cxx.h"
        #include "lcd.h"
        #include "touch.h"
        #include "usart.h"
        #include "rtc.h"
        #include "ds18b20.h"
        #include "remote.h"
        //時間結構體
        typedef struct
        {
        vu8 s_hour;
        vu8 s_min;
        vu8 s_sec;
        //公歷日月年周
        vu16 s_year;
        vu8 s_month;
        vu8 s_date;
        vu8 s_week;
        }Timer;
        Timer S_timer;
        unsigned char flag_20ms=0x0,flag_500ms=0,flag_250ms=0,flag_1s=0;//定時標志
        unsigned char flag_key0=0,flag_key1=0,flag_key2=0,flag_tiao=0,key_remot=0;
        void Disp_Tiao_Shan(void);
        void Load_Drow_Dialog(void);
        int main(void)
        {
        unsigned char temp[12],sec_back=0xff,t=0,len=0;
        short temp5;
        delay_init();
        NVIC_Configuration();
        uart_init(9600);
        Led_Init();
        key_init();
        Timer2_config(71,2000); //定時兩毫秒
        DS18B20_Init();
        Remote_Init();
        AT24CXX_Init();
        RTC_Init();
        LCD_Init();
        LCD_Clear(BLUE);
        TP_Init();
        POINT_COLOR=RED;
        BACK_COLOR=BLUE;
        LCD_ShowString(10,50,220,24,24,"--MULT FUNC CLOCK--");
        LCD_ShowString(60,260,180,24,24,"SET + - ");
        // POINT_COLOR=YELLOW ;
        LCD_DrawRectangle(50,250,100,290);
        LCD_DrawRectangle(110,250,160,290);
        LCD_DrawRectangle(170,250,220,290);
        while(1)
        {
        if(tp_dev.sta&TP_PRES_DOWN)//有觸摸按下狀態。
        {//按下時,方框的顏色要發生變化,這樣看效果才明顯示,
        //手松開后,又要恢復原畫的顏色。
        if((tp_dev.x[0]>50)&&(tp_dev.x[0]<100)&&(tp_dev.y[0]>250)&&(tp_dev.y[0]<290))
        {LCD_Fill(51,251,99,289,YELLOW);LCD_ShowString(60,260,36,24,24,"SET");}
        else if((tp_dev.x[0]>110)&&(tp_dev.x[0]<160)&&(tp_dev.y[0]>250)&&(tp_dev.y[0]<290))
        {LCD_Fill(111,251,159,289,YELLOW);LCD_ShowString(120,260,36,24,24," + ");}
        else if((tp_dev.x[0]>170)&&(tp_dev.x[0]<220)&&(tp_dev.y[0]>250)&&(tp_dev.y[0]<290))
        {LCD_Fill(171,251,219,289,YELLOW);LCD_ShowString(180,260,36,24,24," - ");}
        }
        if((USART_RX_STA&0x8000))//收到了一幀串行口數據,進行解析。
        {
        switch(USART_RX_BUF[0])
        {
        case t:{//time是調時間
        S_timer.s_hour=(USART_RX_BUF[1]-0)*10+(USART_RX_BUF[2]-0);
        S_timer.s_min=(USART_RX_BUF[3]-0)*10+(USART_RX_BUF[4]-0);
        S_timer.s_sec=(USART_RX_BUF[5]-0)*10+(USART_RX_BUF[6]-0);
        USART_RX_STA=0;
        printf("set time:%s",USART_RX_BUF);
        calendar.sec=S_timer.s_sec;
        calendar.hour=S_timer.s_hour;
        calendar.min=S_timer.s_min;
        calendar.w_date=S_timer.s_date;
        calendar.w_month=S_timer.s_month;
        calendar.w_year=S_timer.s_year;
        calendar.week=S_timer.s_week;
        RTC_Set(calendar.w_year,calendar.w_month,calendar.w_date,calendar.hour,calendar.min,calendar.sec);
        break;
        }
        case d:{//date是調日期
        S_timer.s_year =(USART_RX_BUF[1]-0)*1000+(USART_RX_BUF[2]-0)*100+(USART_RX_BUF[3]-0)*10+(USART_RX_BUF[4]-0);
        S_timer.s_month=(USART_RX_BUF[5]-0)*10+(USART_RX_BUF[6]-0);
        S_timer.s_date=(USART_RX_BUF[7]-0)*10+(USART_RX_BUF[8]-0);
        USART_RX_STA=0;
        printf("set date:%s",USART_RX_BUF);
        calendar.sec=S_timer.s_sec;
        calendar.hour=S_timer.s_hour;
        calendar.min=S_timer.s_min;
        calendar.w_date=S_timer.s_date;
        calendar.w_month=S_timer.s_month;
        calendar.w_year=S_timer.s_year;
        calendar.week=S_timer.s_week;
        RTC_Set(calendar.w_year,calendar.w_month,calendar.w_date,calendar.hour,calendar.min,calendar.sec);
        break;
        }
        default :break;
        }
        }
        if(flag_tiao!=0)//用于調節時閃爍顯示
        {
        switch(flag_tiao)
        {
        case 1: {
        if(flag_250ms==1)
        {
        LCD_ShowString(30+12*13,140,24,24,24," ");
        break;
        }
        else goto kk2;
        }
        case 2: {
        if(flag_250ms==1)
        {
        LCD_ShowString(30+12*10,140,24,24,24," ");
        break;
        }
        else goto kk2;
        }
        case 3: {
        if(flag_250ms==1)
        {
        LCD_ShowString(30+12*7,140,24,24,24," ");
        break;
        }
        else goto kk2;
        }
        case 4: {
        if(flag_250ms==1)
        {
        LCD_ShowString(30+12*15,100,24,24,24," ");
        break;
        }
        else goto kk2;
        }
        case 5: {
        if(flag_250ms==1)
        {
        LCD_ShowString(30+12*12,100,24,24,24," ");
        break;
        }
        else goto kk2;
        }
        case 6: {
        if(flag_250ms==1)
        {
        LCD_ShowString(30+12*10,100,24,24,24," ");
        break;
        }
        else goto kk2;
        }
        case 7: {
        if(flag_250ms==1)
        {
        LCD_ShowString(30+12*5,100,48,24,24," ");
        break;
        }
        else goto kk2;
        }
        kk2:
        {
        sprintf(temp,"DATE:%d-%d-%d %d",calendar.w_year,calendar.w_month,calendar.w_date,calendar.week);
        LCD_ShowString(30,100,210,24,24,temp);
        sprintf(temp,"TIME: %d:%d:%d ",calendar.hour,calendar.min,calendar.sec);
        LCD_ShowString(30,140,210,24,24,temp);
        break;
        }
        default :break ;
        }
        }
        else//正常顯示
        {
        if(sec_back!=calendar.sec)
        {
        sprintf(temp,"DATE:%d-%d-%d %d",calendar.w_year,calendar.w_month,calendar.w_date,calendar.week);
        LCD_ShowString(30,100,210,24,24,temp);
        sprintf(temp,"TIME: %d:%d:%d ",calendar.hour,calendar.min,calendar.sec);
        LCD_ShowString(30,140,210,24,24,temp);
        }
        }
        keyfunction();//按鍵掃描和功能解析(包括了開發板上的按鍵、紅外遙控按鍵、觸摸按鍵
        if(flag_1s ==1)//每秒讀取一次溫度
        {
        flag_1s =0;
        LCD_ShowString(30+5*12,180,210,24,24," ");
        temp5=DS18B20_Get_Temp();
        sprintf(temp,"TEMP:%d.%d",temp5/10,temp5%10);
        LCD_ShowString(30,180,210,24,24,temp);
        }
        }
        }
        /*
        函數功能:顯示畫圖框
        */
        void Load_Drow_Dialog(void)
        {
        LCD_Clear(RED);//清屏
        POINT_COLOR=BLUE;//設置字體為藍色
        LCD_ShowString(lcddev.width-30,0,200,24,24,"RST");//顯示清屏區域
        }
        void Disp_Tiao_Shan(void)
        {
        unsigned char temp[12];
        switch(flag_tiao)
        {
        case 1: {
        if(flag_250ms==1)
        {
        LCD_ShowString(30+12*13,140,24,24,24," ");
        break;
        }
        else goto kk2;
        }
        case 2: {
        if(flag_250ms==1)
        {
        LCD_ShowString(30+12*10,140,24,24,24," ");
        break;
        }
        else goto kk2;
        }
        case 3: {
        if(flag_250ms==1)
        {
        LCD_ShowString(30+12*7,140,24,24,24," ");
        break;
        }
        else goto kk2;
        }
        case 4: {
        if(flag_250ms==1)
        {
        LCD_ShowString(30+12*15,100,24,24,24," ");
        break;
        }
        else goto kk2;
        }
        case 5: {
        if(flag_250ms==1)
        {
        LCD_ShowString(30+12*12,100,24,24,24," ");
        break;
        }
        else goto kk2;
        }
        case 6: {
        if(flag_250ms==1)
        {
        LCD_ShowString(30+12*10,100,24,24,24," ");
        break;
        }
        else goto kk2;
        }
        case 7: {
        if(flag_250ms==1)
        {
        LCD_ShowString(30+12*5,100,48,24,24," ");
        break;
        }
        else goto kk2;
        }
        kk2:
        {
        sprintf(temp,"DATE:%d-%d-%d %d",calendar.w_year,calendar.w_month,calendar.w_date,calendar.week);
        LCD_ShowString(30,100,210,24,24,temp);
        sprintf(temp,"TIME: %d:%d:%d ",calendar.hour,calendar.min,calendar.sec);
        LCD_ShowString(30,140,210,24,24,temp);
        break;
        }
        default :break ;
        }
        }
        #include "sys.h"
        #include "delay.h"
        #include "key.h"
        #include "rtc.h"
        #include "remote.h"
        #include "touch.h"
        #include "lcd.h"
        typedef struct
        {
        vu8 s_hour;
        vu8 s_min;
        vu8 s_sec;
        //公歷日月年周
        vu16 s_year;
        vu8 s_month;
        vu8 s_date;
        vu8 s_week;
        }Timer;
        extern unsigned char flag_20ms;
        extern unsigned char flag_key0,flag_key1,flag_key2,flag_tiao;
        extern Timer S_timer;
        void key_init(void)
        {
        GPIO_InitTypeDef KEY_InitTypeDef;
        RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA|RCC_APB2Periph_GPIOD|RCC_APB2Periph_GPIOC,ENABLE);
        KEY_InitTypeDef.GPIO_Pin=GPIO_Pin_0;
        KEY_InitTypeDef.GPIO_Mode=GPIO_Mode_IPD;
        KEY_InitTypeDef.GPIO_Speed=GPIO_Speed_50MHz;
        GPIO_Init(GPIOA,&KEY_InitTypeDef);
        KEY_InitTypeDef.GPIO_Pin=GPIO_Pin_5;
        KEY_InitTypeDef.GPIO_Mode=GPIO_Mode_IPU;
        GPIO_Init(GPIOC,&KEY_InitTypeDef);
        KEY_InitTypeDef.GPIO_Pin=GPIO_Pin_15;
        KEY_InitTypeDef.GPIO_Mode=GPIO_Mode_IPU;
        GPIO_Init(GPIOA,&KEY_InitTypeDef);
        KEY0=1;
        KEY1=1;
        WK_UP=0;
        }
        /*
        函數功能:按鍵掃描函數
        輸入參數:無
        輸出參數:返回鍵碼。無按鍵時返回0;
        外部變量:
        算法:采用軟件延時實現按鍵掃描。
        */
        unsigned char KeyScan(void)
        {
        unsigned char keynum=0;
        if((KEY0!=1)||(KEY1!=1)||(WK_UP!=0))
        {
        delay_ms(10);
        if((KEY0!=1)||(KEY1!=1)||(WK_UP!=0))
        {
        if(KEY0!=1)
        {
        while(KEY0!=1);
        keynum=1;return keynum;}
        else if(KEY1!=1)
        {while(KEY1!=1);
        keynum=2;return keynum;}
        else if(WK_UP!=0)
        {while(WK_UP!=0);
        keynum=3;return keynum;}
        else
        return 0;
        }
        else
        return keynum;
        }
        else
        return keynum;
        }
        /*
        函數功能:按鍵掃描函數
        輸入參數:無
        輸出參數:返回鍵碼。無按鍵時返回0;
        外部變量:flag_20ms
        算法:采用狀態機實現按鍵掃描。
        */
        unsigned char KeyScan2(void)
        {
        static unsigned char keynum=0,step1=0;
        if(flag_20ms==0x01)
        {
        flag_20ms=0;
        switch(step1)
        {
        case 0:{//狀態1:檢測是否有按鍵按下
        if((KEY0!=1)||(KEY1!=1)||(WK_UP!=0))
        step1=1;
        else
        step1=0;
        return 0;
        //break;
        }
        case 1:{//狀態2:檢測是否真的有按鍵按下
        if((KEY0!=1)||(KEY1!=1)||(WK_UP!=0))
        {
        if(KEY0!=1)
        {step1=2; keynum=1;}
        else if(KEY1!=1)
        {step1=2; keynum=2;}
        else if(WK_UP!=0)
        {step1=2; keynum=3;}
        else
        {step1=0; }
        }
        return 0;
        //break;
        }
        case 2:{//狀態3:檢測按鍵是否彈起
        if((KEY0!=1)||(KEY1!=1)||(WK_UP!=0))
        {step1=2; return 0;}
        else
        { step1=0;return keynum;}
        //break;
        }
        default :return 0;
        }
        }
        return 0;
        }
        /*
        函數功能:按鍵功能解析函數
        輸入參數:無
        輸入函數:KeyScan2();
        輸出參數:無
        外部變量:flag_key0,flag_key1
        */
        void keyfunction(void)
        {
        unsigned char temp;
        temp=(KeyScan2())|(Remote_Scan());
        if(TP_Scan(0))//當觸摸按鍵按下并松開后才返回1,否則返回0;
        {//按下時,方框的顏色要發生變化,這樣看效果才明顯示,
        //手松開后,又要恢復原畫的顏色。
        if((tp_dev.x[0]>50)&&(tp_dev.x[0]<100)&&(tp_dev.y[0]>250)&&(tp_dev.y[0]<290))
        { temp =3;
        {LCD_Fill(51,251,99,289,BLUE);LCD_ShowString(60,260,180,24,24,"SET");}
        }
        else if((tp_dev.x[0]>110)&&(tp_dev.x[0]<160)&&(tp_dev.y[0]>250)&&(tp_dev.y[0]<290))
        { temp=1;
        {LCD_Fill(111,251,159,289,BLUE);LCD_ShowString(120,260,180,24,24," + ");}
        }
        else if((tp_dev.x[0]>170)&&(tp_dev.x[0]<220)&&(tp_dev.y[0]>250)&&(tp_dev.y[0]<290))
        {temp=2;
        {LCD_Fill(171,251,219,289,BLUE);LCD_ShowString(180,260,180,24,24," - ");}
        }
        }
        if(temp>0)
        { TIM_Cmd(TIM2,ENABLE);
        switch(temp)
        {
        case 1:{
        flag_key0=1;
        if(flag_tiao>0)
        {
        S_timer.s_sec =calendar.sec;
        S_timer.s_hour=calendar.hour;
        S_timer.s_min =calendar.min;
        S_timer.s_date=calendar.w_date;
        S_timer.s_month =calendar.w_month;
        S_timer.s_year=calendar.w_year;
        S_timer.s_week =calendar.week;
        switch(flag_tiao)
        {
        case 1: {
        if((S_timer.s_sec)<60);
        else
        S_timer.s_sec=0;
        goto kk1;
        }
        case 2: {
        if(S_timer.s_min++<60);
        else
        S_timer.s_min=0; goto kk1;
        }
        case 3: {
        if(S_timer.s_hour ++<60);
        else
        S_timer.s_hour=0; goto kk1;
        }
        case 4: {
        if(S_timer.s_week++<7);
        else
        S_timer.s_week =1; goto kk1;
        }
        case 5: {
        if(S_timer.s_date++<30);
        else
        S_timer.s_date=1; goto kk1;
        }
        case 6: {
        if(S_timer.s_month++<12);
        else
        S_timer.s_month =1; goto kk1;
        }
        case 7: {
        if(S_timer.s_year++<2099);
        else
        S_timer.s_year =1970; goto kk1;
        }
        default :break ;
        }
        }
        break;
        }
        case 2:{
        flag_key1=1;
        if(flag_tiao>0)
        {
        S_timer.s_sec =calendar.sec;
        S_timer.s_hour=calendar.hour;
        S_timer.s_min =calendar.min;
        S_timer.s_date=calendar.w_date;
        S_timer.s_month =calendar.w_month;
        S_timer.s_year=calendar.w_year;
        S_timer.s_week =calendar.week;
        switch(flag_tiao)
        {
        case 1: {
        if((S_timer.s_sec)-->0);
        else
        S_timer.s_sec=60; goto kk1;
        //break ;
        }
        case 2: {
        if(S_timer.s_min-->0);
        else
        S_timer.s_min=60; goto kk1;
        //break ;
        }
        case 3: {
        if(S_timer.s_hour-->0);
        else
        S_timer.s_hour=24; goto kk1;
        //break ;
        }
        case 4: {
        if(S_timer.s_week-->0);
        else
        S_timer.s_week =7; goto kk1;
        //break ;
        }
        case 5: {
        if(S_timer.s_date-->0);
        else
        S_timer.s_date=31; goto kk1;
        //break ;
        }
        case 6: {
        if(S_timer.s_month-->0);
        else
        S_timer.s_month =12; goto kk1;
        //break ;
        }
        case 7: {
        if(S_timer.s_year-->1970);
        else
        S_timer.s_year =1970; goto kk1;
        //break ;
        }
        kk1:
        calendar.sec=S_timer.s_sec;
        calendar.hour=S_timer.s_hour;
        calendar.min=S_timer.s_min;
        calendar.w_date=S_timer.s_date;
        calendar.w_month=S_timer.s_month;
        calendar.w_year=S_timer.s_year;
        calendar.week=S_timer.s_week;
        RTC_Set(calendar.w_year,calendar.w_month,calendar.w_date,calendar.hour,calendar.min,calendar.sec);
        break;
        default :break ;
        }
        }
        break;
        }
        case 3:{
        flag_key2=1;
        if(flag_tiao++<7);
        else
        flag_tiao=0;
        break;
        }
        default :break;
        }
        TIM_Cmd(TIM2,ENABLE);
        }
        }



        關鍵詞: STM32數字

        評論


        技術專區

        關閉
        主站蜘蛛池模板: 南澳县| 邵东县| 包头市| 高要市| 桦川县| 成武县| 邢台市| 桂东县| 武乡县| 库伦旗| 会昌县| 上高县| 邓州市| 嘉鱼县| 淮滨县| 临沭县| 寿光市| 苏州市| 宁武县| 桦甸市| 满城县| 罗甸县| 龙口市| 咸丰县| 阿尔山市| 武邑县| 广宁县| 克拉玛依市| 洛扎县| 抚州市| 喜德县| 耿马| 昌图县| 大悟县| 盐源县| 八宿县| 和政县| 丹东市| 宜阳县| 昌乐县| 柳州市|