日韩欧美视频第二区,秋霞成人午夜鲁丝一区二区三区,美女日批视频在线观看,av在线不卡免费

電子開發網

電子開發網電子設計 | 電子開發網Rss 2.0 會員中心 會員注冊
搜索: 您現在的位置: 電子開發網 >> 電子開發 >> 單片機 >> 正文

單片機基于算盤碼的新型時鐘

作者:佚名    文章來源:本站原創    點擊數:    更新時間:2013-1-12

現在將一個實際編制的、帶有調整時間功能的算盤碼新型時鐘程序發布。硬件電路由于只有一個三基色LED和一個按鍵開關,就不貼出了。所選MCU主要是利用其內置的RTCC。
單個按鍵開關有短按和長按兩種用法。在正常報時狀態,短按無作用,長按可以進入調時狀態。進入調時狀態后,按照十小時、小時、十分、分的順序依次調整。每次短按鍵循環進行增量步進,長按鍵進入下一檔位,4種都調完最后一次長按鍵就回到正常報時狀態。在調整狀態,調整“小時”和“分鐘”時用白色和藍色分別顯示,白色表示正在調整的檔位,藍色則表示不調整的檔位。例如,在調整到第三檔的時候,第一個拍發的數碼是白色,表示“十分”,第二個拍發的數碼是藍色,表示“分”,在這個檔位短按鍵只調整白色的“十分”,不調整藍色的“分”。

/*------------------------------------------------------------------- 
編譯器:MCC18 V3.40 
日期:2011 0924             
版本:V1.1 
功能:用過去在Pic16論壇上發布過的算盤碼編碼格式,在pic18f26j13的RTCC上實現可以 
用兩位碼和光色來表示小時與分鐘的新型時鐘。 
前一位碼的光色表示“十小時”,碼型表示“小時”。后一位碼的光色表示“十分鐘”,碼型表示“分鐘”。 
光色表示的數值依照“藍,綠,黃,紅,青,紫”依次表示“0,1,2,3,4,5”。 
碼型以長短發光表示,以“劃”表示發光時間略長,“點”表示發光時間很短。以下從0--9的碼型分別為 
劃劃,點,點點,點點點,點點點點,劃,劃點,劃點點,劃點點點,劃點點點點。 
用較短的停頓區分前后碼,用較長的停頓表示分組。 
例如,21點整,表示為“黃點,藍劃劃” 
修改時鐘,要長按唯一的按鍵,直到發出持續的白光(白里泛紫),松鍵就用白光點劃表示等待修改的位,用藍光點劃表示不修改的位。 
修改狀態連續發出的兩個碼型,前面一組表示十小時和小時,后面一組表示十分鐘和分鐘。每次修改時,先修改十小時位,再修改小時位。 
此時顯示的兩個碼前面是十小時,后面是小時。前碼白光后碼藍光時修改十小時,通過短按鍵循環改變該位的值,修改完畢長按鍵就轉入后位修改, 
這時是前碼藍光,后碼白光,同樣是循環改變,完成這組后長按就進入十分鐘和分鐘修改。后一組的修改過程和結束方式同前。 
長按鍵要看到一組兩個碼完整顯示再松手,才能保證進入下一步。 
修改完成后會自動保存到RTCC,繼續正常發光報時任務。 
硬件電路非常簡單,除去主振蕩器12m和實時鐘晶體32768Hz外,只有程序最前部鍵定義連接的一個按鍵和一個三基色led。其它均按MCU手冊要求配電容電阻即可。 
特別聲明,本算盤碼的編碼方式,修改時鐘方式和整個程序屬于本人原創,可基于個人研究目的進行引用和復制,但不得作為商業用途使用。 
-------------------------------------------------------------------*/
 
#include <P18f26j13.h> 

#define Key PORTCbits.RC2 
#define LEDR TRISBbits.TRISB2        //紅led 
#define LEDG TRISBbits.TRISB0        //綠led 
#define LEDB TRISBbits.TRISB3        //藍led 

void
 main (void); 
void
 InterruptHandlerHigh (void); 

unsigned char
 *ppptr; 
static const
 unsigned int morse_code[12]={0xee00,0x8000,0xa000,0xa800,0xaa00,0xe000,0xe800,0xea00, 
0xea80
,0xeaa0,0x0000,0x0000};        //算盤碼碼型 
static const unsigned char code_lenth[12]={0x0c,0x06,0x08,0x0a,0x0c,0x08,0x0a,0x0c,0x0f,0x11,0x0a,0x0a}; 
                                    //算盤碼碼長 
unsigned int *morse_ptr; 
unsigned char
 *code_lenth_ptr; 
static
 unsigned char morse_lenth; 
static
 unsigned int timing_code[4]={0x0000,0xaa00,0x0000,0x0000};        //輪流拍發的碼型存放位置 
static unsigned char timing_code_lenth[4]={0x05,0x05,0x00,0x05};            //輪流拍發的碼長存放位置 
unsigned char tens_or_ones; 
unsigned char
 colour,minus; 

unsigned char
 key_pules,key_count; 
static
 unsigned long key_status=0xffffffff;        //存儲按鍵歷史的變量,每次中斷存一位,為0表示長按鍵 
unsigned char key_down,key_up,last_key;            //表征按鍵按下、抬起的變量 
unsigned char t=0; 
unsigned char
 minut_colour,minut; 
unsigned char
 hour,hour_colour; 
unsigned char
 in_hour=1;            //區別小時和分鐘的變量 
unsigned int temp; 
unsigned int
 temperature;            //測試的變量名,沒有改正 

unsigned char
 Rtimehi[4]={0x0,0x09,0x1,0x54},Rtimelo[4]={0x11,0x11,0x15,0x30};        //保存RTCC日期時間的兩組變量 
//***************主函數***************** 
void main() 
{
 
    unsigned char
 i,j; 
    //**********RC2作為按鍵使用初始化********************** 
    ANCON1bits.PCFG11=1;    //RC2作為數字IO,不給ADC 
    TRISCbits.TRISC2=1;        //輸入,接Key 
    //*************************RTCC初始化******************* 
    T1GCON=0; 
    T1CON=0X8B;                //允許tmr1的振蕩器 
    RTCCFG=0X07; 
    RTCCAL=0X0;                //校準值 
    PADCFG1=0X02;            //輸出秒時鐘 
    _asm  movlw 0x55 _endasm 
    _asm movwf EECON2,0 _endasm 
    _asm movlw 0xAA _endasm 
    _asm  movwf EECON2,0 _endasm 
    _asm  bsf RTCCFG,5,1 _endasm    //開啟寫入 
    RTCCFGbits.RTCEN=1; 
    RTCCFG|=0x03;        //置指針為0b11 
    while (RTCCFGbits.RTCSYNC);    //等待不忙 
        for (i=0;i<4;i++)    //讀 
        { 
            Rtimelo[i]=RTCVALL; 
            Rtimehi[i]=RTCVALH; 
        }
 
        //****************TIMERS******************* 
        T0CON=0X84;                //定時器, 分頻 
        INTCONbits.T0IE=1; 
        T5CON=0X3F;                //1/4Fosc,1:8 prescale,T1OSC, 16 bits WR,enabled 
        T5GCON=0;                //no gate 
        PIE5bits.TMR5IE=1; 
        //*****************中斷開啟*************** 
        INTCONbits.PEIE=1; 
        INTCONbits.GIE=1; 
        //****************按鍵相關設置************* 
        morse_ptr=timing_code; 
        code_lenth_ptr=timing_code_lenth; 
        t=timing_code_lenth[1]; 
        temp=timing_code[1]; 
        key_up=0;                        //缺省為按鍵抬起狀態 
        key_down=0; 
        last_key=1; 
        //**************************主循環************************ 
        while(1) 
        {
 
            RTCCFG|=0x03;        //置指針為0b11 
            Rtimelo[0]=RTCVALL;        //讀年 
            Rtimehi[0]=RTCVALH;        //讀空 
            Rtimelo[1]=RTCVALL;        //讀日 
            Rtimehi[1]=RTCVALH;        //讀月 
            Rtimelo[2]=RTCVALL;        //讀小時 
            Rtimehi[2]=RTCVALH;        //讀星期 
            Rtimelo[3]=RTCVALL;        //讀秒 
            Rtimehi[3]=RTCVALH;        //讀分 
    
            hour_colour=Rtimelo[2]>>4;            //十小時顏色 
            hour=Rtimelo[2]&0x0f;                //小時 
            minut_colour=Rtimehi[3]>>4;            //十分顏色 
            minut=Rtimehi[3]&0x0f;                //分鐘 
            timing_code[1]=morse_code[hour];            //小時的碼型 
            timing_code_lenth[1]=code_lenth[hour];        //小時的碼長 
            timing_code[2]=morse_code[minut];            //分的碼型 
            timing_code_lenth[2]=code_lenth[minut];    //分的碼長 

            //以下為修改時鐘的鍵操作部分 
            if (key_status==0) 
            {
 
                hour_colour=6;                //白色光 
                minut_colour=0; 
                for
 (i=0;i<3;i++) 
                timing_code[i]=0xffff;            //全長劃,表示進入調整時鐘模式 
                while (key_status==0); 
                for
 (i=0;i<3;i++) 
                    timing_code[i]=0;    
                while
 (key_status)                //一次長按鍵之前,修改十小時值 
                { 
                    timing_code[1]=morse_code[Rtimelo[2]>>4];    //十小時 
                    timing_code_lenth[1]=code_lenth[Rtimelo[2]>>4]; 
                    timing_code[2]=morse_code[Rtimelo[2]&0x0f];    //小時 
                    timing_code_lenth[2]=code_lenth[Rtimelo[2]&0x0f]; 
                    if
 (key_up==1)                //如果發現短時間按鍵的抬鍵信號 
                    { 
                        Rtimelo[2]+=0x10;                //步進十小時 
                        key_up=0;                    //清除短時間按鍵標志 
                    } 
                    if
 (Rtimelo[2]>0x23) 
                        Rtimelo[2]=0; 
                    }
 
                    while
 (key_status==0) key_up=0;        //防止一次按鍵連續動作 
                        hour_colour=0;                //lan色光 
                    minut_colour=6;                //白色光 
                    while (key_status)                //一次長按鍵之前,修改小時值 
                    { 
                        timing_code[1]=morse_code[Rtimelo[2]>>4];    //十小時 
                        timing_code_lenth[1]=code_lenth[Rtimelo[2]>>4]; 
                        timing_code[2]=morse_code[Rtimelo[2]&0x0f];    //小時 
                        timing_code_lenth[2]=code_lenth[Rtimelo[2]&0x0f]; 
                        if
 (key_up==1)                //如果發現短時間按鍵的抬鍵信號 
                        { 
                            Rtimelo[2]++;                //步進小時 
                            key_up=0;                    //清除短時間按鍵標志 
                        } 
                        if
 (Rtimelo[2]>0x23)            //總小時數若大于23,則小時個位置0 
                        Rtimelo[2]=0x20; 
        
                        if
 ((Rtimelo[2]&0x0f)>9)        //小時值若大于9 
                        Rtimelo[2]&=0xf0;            //修改為0 
                    } 
                    while
 (key_status==0) key_up=0;        //防止一次按鍵連續動作 
                    //以下修改分鐘 
                    hour_colour=6;                //白色光 
                    minut_colour=0;                //藍色光 
                    while (key_status)                //一次長按鍵之前,修改十分鐘值 
                    { 
                        timing_code[1]=morse_code[Rtimehi[3]>>4];    //十分鐘 
                        timing_code_lenth[1]=code_lenth[Rtimehi[3]>>4]; 
                        timing_code[2]=morse_code[Rtimehi[3]&0x0f];    //分鐘 
                        timing_code_lenth[2]=code_lenth[Rtimehi[3]&0x0f]; 
                        if
 (key_up==1)                        //如果發現短時間按鍵的抬鍵信號 
                        { 
                            Rtimehi[3]+=0x10;                    //步進十分鐘 
                            key_up=0;                            //清除短時間按鍵標志 
                        } 
                        if
 (Rtimehi[3]>0x59)                //總fen數若大于59,則十分鐘位置0 
                        Rtimehi[3]&=0x0f; 
                    }
 
                    while
 (key_status==0) key_up=0;        //防止一次按鍵連續動作 
                    hour_colour=0;                        //藍色光 
                    minut_colour=6;                        //白色光 
                    bwhile (key_status)                    //一次長按鍵之前,修改分鐘值 
                    { 
                        timing_code[1]=morse_code[Rtimehi[3]>>4];    //十分鐘 
                        timing_code_lenth[1]=code_lenth[Rtimehi[3]>>4]; 
                        timing_code[2]=morse_code[Rtimehi[3]&0x0f];    //分鐘 
                        timing_code_lenth[2]=code_lenth[Rtimehi[3]&0x0f]; 
                        if
 (key_up==1)                        //如果發現短時間按鍵的抬鍵信號 
                        {    
                            Rtimehi[3]++;                        //步進分鐘 
                            key_up=0;                            //清除短時間按鍵標志 
                        } 
                        if
 ((Rtimehi[3]&0x0f)>9)            //fen數個位若大于9,則分鐘位置0 
                            Rtimehi[3]=Rtimehi[3]&0xf0; 
                    }
 
                    while
 (key_status==0) key_up=0;        //防止一次按鍵連續動作 
                    //寫入RTCC 
                    RTCCFG|=0x03;        //置指針為0b11 
                    while (RTCCFGbits.RTCSYNC);    //等待不忙 
                    for (i=0;i<4;i++)    //寫 
                    { 
                        RTCVALL=Rtimelo[i]; 
                        RTCVALH=Rtimehi[i]; 
                    } 
            }
 
            //到達MAIN最后部分 
        } 
}
 
//---------------------------------------------------------------------------- 
// High priority interrupt vector 
#pragma code InterruptVectorHigh = 0x08 
void InterruptVectorHigh (void) 
{
 
  _asm 
    goto
 InterruptHandlerHigh         //jump to interrupt routine 
  _endasm 
}
 
//---------------------------------------------------------------------------- 
// High priority interrupt routine 
#pragma code 
#pragma interrupt InterruptHandlerHigh 

void
 
InterruptHandlerHigh () 
{
 
    if
 (INTCONbits.TMR0IF) 
    {
                                 //check for TMR0 overflow 
        INTCONbits.TMR0IF = 0;        //clear interrupt flag 
        TMR0H=0X20;                            //略加快點劃速率 
        TMR0L=0; 
        if
 ((t<=0)|t>25) 
        {
 
            if
 (morse_ptr>&timing_code[2]) 
            {
 
                morse_ptr=timing_code; 
                code_lenth_ptr=timing_code_lenth; 
            }
 
            else
 
            {
 
                morse_ptr++; 
                code_lenth_ptr++; 
            }
 
            if
 (morse_ptr>(&timing_code[1]))        //小時在1,分在2,據此決定in_hour 
                in_hour=0; 
            else
 
                in_hour=1; 
            if
 (in_hour==0)                    //十分鐘顏色 
            { 
                if
 (minut_colour==0)                                //藍 
                { 
                    LEDG=1; 
                    LEDR=1; 
                    LEDB=0; 
                }
 
                else if
 (minut_colour==1)                            //綠 
                { 
                    LEDG=0; 
                    LEDR=1; 
                    LEDB=1; 
                }
 
                else if
 (minut_colour==2)                            //黃 
                { 
                    LEDG=0; 
                    LEDR=0; 
                    LEDB=1; 
                }
 
                else if
 (minut_colour==3)                            //紅 
                { 
                    LEDG=1; 
                    LEDR=0; 
                    LEDB=1; 
                }
 
                else if
 (minut_colour==4)                            //青 
                { 
                    LEDG=0; 
                    LEDR=1; 
                    LEDB=0; 
                }
 
                else if
 (minut_colour==5)                            //紫 
                { 
                    LEDG=1; 
                    LEDR=0; 
                    LEDB=0; 
                }
 
                else
                                                //白 
                { 
                    LEDG=0; 
                    LEDR=0; 
                    LEDB=0; 
                } 
            }
 
            else
                                //十小時顏色 
            { 
                if
 (hour_colour==0)                                //藍 
                { 
                    LEDG=1; 
                    LEDR=1; 
                    LEDB=0; 
                }
 
                else if
 (hour_colour==1)                            //綠 
                { 
                    LEDG=0; 
                    LEDR=1; 
                    LEDB=1; 
                }
 
                else if
 (hour_colour==2)                            //黃 
                { 
                    LEDG=0; 
                    LEDR=0; 
                    LEDB=1; 
                }
 
                else if
 (hour_colour==3)                            //紅 
                { 
                    LEDG=1; 
                    LEDR=0; 
                    LEDB=1; 
                }
     
                else if
 (hour_colour==4)                            //青 
                { 
                    LEDG=0; 
                    LEDR=1; 
                    LEDB=0; 
                }
 
                else if
 (hour_colour==5)                            //紫 
                { 
                    LEDG=1; 
                    LEDR=0; 
                    LEDB=0; 
                }
 
                else
                                                //白 
                { 
                    LEDG=0; 
                    LEDR=0; 
                    LEDB=0; 
                } 
            }
 
            temp=*morse_ptr;                    //取得指針位置的值 
            t=*code_lenth_ptr;                    //同上 
        } 
        else
 
        {
 
            t--; 
        }
 
        if
 ((temp&0x8000)==0)                //這段是拍發算盤碼的執行部分 
            LATB = LATB|0b00001101; 
        else
 
            LATB = LATB&0b1110010; 
        temp=temp<<1; 
    }
 
    else if
 (PIR5bits.TMR5IF)            //該定時器用來識別按鍵動作 
    { 
        PIR5bits.TMR5IF = 0;            //clear interrupt flag 
        if (key_down==1&last_key==1)    //只有下鍵后才進入判斷 
        { 
            if
 (key_status)                //在沒有全0序列情況下 
            if (Key==1)                    //確認抬鍵 
            { 
                key_up=1; 
                key_down=0; 
            } 
        }
 
        else if
 (last_key==0) 
        {
 
            if
 (Key==0) 
            {
 
                key_down=1;                        //確認下鍵 
                key_up=0; 
            } 
        }
 
        last_key=Key;                    //當前鍵值賦予舊鍵值 
        key_status=key_status<<1;        //鍵狀態左移1位 
        key_status|=Key;                //末位置Key的值 
    } 
}

Tags:單片機,pic18,時鐘,程序  
責任編輯:admin
請文明參與討論,禁止漫罵攻擊,不要惡意評論、違禁詞語。 昵稱:
1分 2分 3分 4分 5分

還可以輸入 200 個字
[ 查看全部 ] 網友評論
關于我們 - 聯系我們 - 廣告服務 - 友情鏈接 - 網站地圖 - 版權聲明 - 在線幫助 - 文章列表
返回頂部
刷新頁面
下到頁底
晶體管查詢
主站蜘蛛池模板: 德格县| 鄂温| 阳西县| 温宿县| 固安县| 河池市| 尉犁县| 四平市| 兖州市| 墨玉县| 西林县| 永定县| 漯河市| 孙吴县| 调兵山市| 沈阳市| 延庆县| 卓尼县| 兴安县| 客服| 普格县| 正蓝旗| 务川| 会泽县| 德兴市| 巴塘县| 庄浪县| 泰来县| 松溪县| 册亨县| 柞水县| 辽中县| 偏关县| 吴川市| 绿春县| 庆阳市| 双桥区| 安溪县| 林口县| 福海县| 宜州市|