久久久久久久999_99精品久久精品一区二区爱城_成人欧美一区二区三区在线播放_国产精品日本一区二区不卡视频_国产午夜视频_欧美精品在线观看免费

專注電子技術學習與研究
當前位置:單片機教程網 >> MCU設計實例 >> 瀏覽文章

pic單片機計時秒表程序設計(時鐘顯示范圍00.00~99.99秒,分辨度為0.01秒)

作者:佚名   來源:本站原創   點擊數:  更新時間:2008年07月12日   【字體:

//此程序實現計時秒表功能,時鐘顯示范圍00.00~99.99秒,分辨度:0.01秒

#include "p18f458.h"

unsigned  char  s[4];   //定義0.01 秒、0.1 秒、1秒、10秒計時器
unsigned  char  k,data,sreg;
unsigned  int i;
const table[11]={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0XD8,0x80,0x90};
  //不帶小數點的顯示段碼表
const table0[10]={0X40,0X79,0X24,0X30,0X19,0X12,0X02,0X78,0X00,0X10}; 
//帶小數點的顯示段碼表

void clkint(void);

//TMR0初始化子程序
void tmint()
{
 T0CON=0XCF;    //設定TMR0L工作于8位定時器方式
       //內部時鐘,TMR0不用分頻
 INTCON=0X20;   //總中斷禁止,TMR0中斷允許,清除TMR0的中斷標志
 INTCON2bits.TMR0IP=1;  //TMR0中斷高優先級
 RCONbits.IPEN=1;   //使能中斷優先級
}

//系統其它部分初始化子程序
void initial()
{
 TRISA=0x00;    //A口設置為輸出
 TRISB=0XF0;    //RB1輸出,RB4輸入
 TRISC=0x00;    //SDO引腳為輸出,SCK引腳為輸出
 TRISE=0x00;    //E口設置為輸出
 SSPCON1=0x30;   //SSPEN=1;CKP=1,FOSC/4
 SSPSTAT=0xC0;   //時鐘下降沿發送數據
 PIR1=0;     //清除SSPIF標志
 data=0X00;    //待顯示的寄存器賦初值
 PORTBbits.RB1=0;
 PORTAbits.RA3=0;
 PORTE=0;    //將K1,K2,K3,K4四條列線置0
}

//SPI傳輸數據子程序
void   SPILED(char data)
{
 SSPBUF=data;      //啟動發送
 do
 {
   ;
 }while(PIR1bits.SSPIF==0);
 PIR1bits.SSPIF=0;
}

//顯示子程序,顯示4位數
void dispaly()
{
 PORTAbits.RA5=0;     //準備鎖存
 for(k=0;k<4;k++)
 {
  data=s[k];
  if(k==2) data=table0[data];  //個位需要顯示小數點
  else data=table[data];
  SPILED(data);     //發送顯示段碼
 }
 for(k=0;k<4;k++)
 {
  data=0xFF;
  SPILED(data);     //連續發送4個DARK,使顯示好看一些
 }
 PORTAbits.RA5=1;     //最后給鎖存信號,代表顯示任務完成
}

//軟件延時子程序
void  DELAY()
{
 for(i = 3553; --i ;)
 continue;
}

//鍵掃描子程序
void KEYSCAN()
{
 while(1)
 {
  dispaly();       //調用一次顯示子程序
  while(PORTBbits.RB4==0)
  {
   DELAY();     //若有鍵按下,則軟件延時
   break;
  }
  if (PORTBbits.RB4==0) break;  //若還有鍵按下,則終止循環掃描,返回
 }
}

//等鍵松開子程序
void keyrelax()
{
 while(1)
 {
  dispaly();       //調用一次顯示子程序
  if (PORTBbits.RB4==1) break;  //為防止按鍵過于靈敏,每次等鍵松開才返回
 }     
}

/*高優先級中斷向量*/
#pragma code InterruptVectorHigh=0x08
void InterruptVectorHigh (void)
{
  _asm
    goto clkint     //跳到中斷程序
  _endasm
}

//中斷服務程序
#pragma code
#pragma interrupt clkint
void clkint()
{
 TMR0=0X13;     //對TMR0寫入一個調整值。因為寫入TMR0后接著的
        //兩個周期不能增量,中斷需要3個周期的響應時間,
        //以及C語言自動進行現場保護要消耗周期
 INTCONbits.T0IF=0;    //清除中斷標志
 sreg=sreg+1;     //中斷計數器加1
 if(sreg==40)     //中斷次數為40后,才對S0,S1,S2,S3 操作
 {
  sreg=0;
  s[0]=s[0]+1;
  if(s[0]==10)
  {
   s[0]=0 ;
   s[1]=s[1]+1;
   if(s[1]==10)
   {
    s[1]=0 ;
    s[2]=s[2]+1;
    if(s[2]==10)
    {
     s[2]=0;
     s[3]=s[3]+1;
     if(s[3]==10) s[3]=0;
    }
   }
  }
 }
}
//主程序
//http://www.zg4o1577.cn 提供此單片機程序有問題請聯系
main()
{
 tmint();     //TMR0初始化
 initial();     //spi顯示初始化及系統其它部分初始化
 INTCONbits.GIE=0;   //總中斷禁止
 while(1)
 {
  for(k=0;k<4;k++)
  {
   s[k]=0;
  } 
  sreg=0;    //賦顯示初值
  dispaly();    //調用一次顯示子程序
  KEYSCAN();   //鍵掃描,直到開始鍵按下
  keyrelax();   //等鍵松開
  INTCONbits.GIE=1;  //總中斷允許
  KEYSCAN();   //鍵掃描直到停止鍵按下,在鍵掃描時有顯示
  keyrelax();   //等鍵松開
  INTCONbits.GIE=0;  //總中斷禁止
  KEYSCAN();   //鍵掃描到清0鍵按下,在鍵掃描時有顯示
  keyrelax();   //等鍵松開
 }
}
 

---------------------匯編語言版本的pic單片機計時秒表程序設計--------------------------------------;此程序實現計時秒表功能
;時鐘顯示范圍:00.00秒-99.99秒,分辨度:0.01秒
;通過按鍵來啟動計時、停止計時及清0
;即第一次按下任意鍵開始計時,第二次按下任意鍵停止計時 ;第三次按下任意鍵使LED清0,等待下一次計時開始

  LIST  P=18F458
  INCLUDE  "P18F458.INC"

S0  EQU  0X20   ;0.01 秒計時器
S1  EQU  S0+1   ;0.1  秒計時器
S2  EQU  S0+2   ;1    秒計時器
S3  EQU  S0+3   ;10   秒計時器
SREG  EQU  S0+4   ;軟計數器
LEDF  EQU  S0+5   ;顯示的LED的位置指示寄存器
XW_TEMP  EQU  S0+6  ;用于中斷中保護W的值
XHOSTS  EQU  S0+7  ;用于中斷中保護STATUS的值
DEYH EQU  S0+8
DEYL EQU  S0+9   ;以上兩個寄存器用于軟件延時
HOSTF EQU  S0+0A  ;用于中斷中保護FSR0L的值
TEMP EQU  S0+0B  ;用于存放臨時值

  ORG   0X00
  GOTO  MAIN
  ORG   0X08
  GOTO  CLKINT   ;轉向中斷服務程序
  ORG   0X30

;數字到段碼的轉換子程序(最好放在程序開頭,避免超過2K的空間發生跨頁讀表)
;************不帶小數點的共陽極碼表**************
CONVERT  ADDWF  PCL,1
  RETLW  0XC0     ;0,顯示段碼與具體的硬件連接有關
  RETLW  0XF9     ;1
  RETLW  0XA4    ;2
  RETLW  0XB0     ;3
  RETLW  0X99     ;4
  RETLW  0X92     ;5
  RETLW  0X82     ;6
  RETLW  0XD8    ;7
  RETLW  0X80     ;8
  RETLW  0X90     ;9
  RETLW  0X88     ;A
  RETLW  0X83     ;B
  RETLW  0XC6     ;C
  RETLW  0XA1    ;D
  RETLW  0X86     ;E
  RETLW  0X8E     ;F
  RETLW  0X7F     ;"."
  RETLW  0XBF    ;"-"
  RETLW  0X89     ;H
  RETLW  0XFF     ;DARK
  RETURN

;*********帶小數點的共陽極碼表***********
CONVERT2 ADDWF  PCL,1
  RETLW  0X40     ;0
  RETLW  0X79     ;1
  RETLW  0X24     ;2
  RETLW  0X30     ;3
  RETLW  0X19     ;4
  RETLW  0X12     ;5
  RETLW  0X02     ;6
  RETLW  0X78     ;7
  RETLW  0X00     ;8
  RETLW  0X10     ;9
  RETURN
 
;***********SPI發送顯示子模塊************
TRANSMIT                      
  CLRF  PORTA         ;LACK送低電平,為鎖存做準備
  MOVWF  SSPBUF          ;啟動發送
WAIT NOP
  BTFSS  PIR1,SSPIF
  GOTO  WAIT            ;等待發送結束
  BCF   PIR1,SSPIF       ;清除中斷標志
  RETURN

;***********顯示子程序模塊************
DISPLAY
  MOVLW  0X01
  MOVWF  LEDF
  MOVLW  0XA0
  MOVWF  FSR0L
AGAINXIAN
  MOVF  LEDF,W
  SUBLW  0X03
  BTFSS  STATUS,Z
  GOTO  XIANB
  MOVF  INDF0,W
  CALL  CONVERT2    ;若是個位,則查帶小數點的碼表
  GOTO  TRAN
XIANB MOVF  INDF0,W
  CALL  CONVERT
TRAN CALL  TRANSMIT    ;發送一個顯示數據
  INCF   FSR0L
  INCF   LEDF
  MOVF  LEDF,W
  SUBLW  0X05
  BTFSS  STATUS,Z
  GOTO  AGAINXIAN
  MOVLW  0X01
  MOVWF  LEDF
XIANDARK
  MOVLW  0X27
  CALL  CONVERT
  CALL  TRANSMIT
  INCF   LEDF
  MOVF  LEDF,W
  SUBLW  0X05
  BTFSS  STATUS,Z
  GOTO  XIANDARK    ;顯示4個"DARK"
  BSF   PORTA,5    ;最后給一個鎖存信號,代表一次顯示任務完成
  RETURN
;********** S0計數溢出處理子程序***************
CS0
  CLRF  S0
  INCF   S1
  RETURN
;********** S1計數溢出處理子程序***************
CS1
  CLRF  S1
  INCF   S2
  RETURN
;********** S2計數溢出處理子程序***************
CS2
  CLRF  S2
  INCF   S3
  RETURN
;********** S3計數溢出處理子程序***************
CS3
  CLRF  S3
  RETURN
;***********時鐘中斷服務程序*******************
CLKINT
  MOVWF  XW_TEMP   ;保存W的值
  SWAPF  STATUS,W
  MOVWF  XHOSTS    ;暫存STATUS的值
  MOVF  FSR0L,W
  MOVWF  HOSTF    ;保存FSR0L的值。以上程序為中斷現場保護
  MOVLW  0X13
  MOVWF  TMR0L    ;對TMR0L寫入一個調整值,因為寫入
          ;TMR0L后接著的兩個周期不能增量
  BCF   INTCON,T0IF   ;清除中斷標志
  INCF   SREG
  MOVF  SREG,W
  SUBLW  0X28     ;TMR0L 每250us中斷一次
  BTFSS  STATUS,Z   ;其中斷40次后才執行對S0 S1 S2 S3 的操作
  GOTO  TIFAN
  CLRF  SREG
  INCF   S0
  MOVF  S0,W
  SUBLW  0X0A
  BTFSC  STATUS,Z
  CALL  CS0
  MOVF  S1,W
  SUBLW  0X0A
  BTFSC  STATUS,Z
  CALL  CS1
  MOVF  S2,W
  SUBLW  0X0A
  BTFSC  STATUS,Z
  CALL  CS2
  MOVF  S3,W
  SUBLW  0X0A
  BTFSC  STATUS,Z
  CALL  CS3
TIFAN
  MOVF  HOSTF,W   ;以下為中斷現場恢復
  MOVWF  FSR0L    ;恢復間接尋址指針FSR0L的值
  SWAPF  XHOSTS,W
  MOVWF  STATUS    ;恢復STATUS的值
  SWAPF  XW_TEMP,1
  SWAPF  XW_TEMP,W   ;恢復W的值
  RETFIE
;*********** TMR0初始化子程序***************
CLKINSUB
  MOVLW  0XCF
  MOVWF  T0CON    ;設定TMR0L工作于8位定時器方式
           ;內部時鐘,TMR0不用分頻
  BCF   INTCON,TMR0IF  ;清除TMR0的中斷標志
  BCF   INTCON,GIE   ;總中斷禁止
  BSF   INTCON,TMR0IE  ;TMR0中斷允許
  BSF   INTCON2,2   ;TMR0中斷高優先級
  BSF   RCON,7    ;使能中斷優先級
  RETURN
;***************系統初始化子程序*****************
MAINSUB
  BCF   TRISA,5       ;置RA5為輸出方式,以輸出鎖存信號
  BCF   TRISB,1
  BCF   TRISA,3
  BCF   TRISE,0
  BCF   TRISE,1
  BSF   TRISB,4       ;設置與鍵盤有關的各口的輸入輸出方式
  BCF   TRISC,5
  BCF   TRISC,3        ;設置SCK與SDO為輸出方式
  BCF   INTCON,GIE    ;關閉所有中斷
  MOVLW  0XC0
  MOVWF  SSPSTAT       ;設置SSPSTAT寄存器
  MOVLW  0X30
  MOVWF  SSPCON1        ;設置SPI的控制方式,允許SSP方式,
          ;并且時鐘下降沿發送,與"74HC595當
          ;其SCLK從低到高平跳變時,串行輸入數據
          ;(DI)移入寄存器"的特點相對應
     RETURN                  ;返回
;***********鍵掃描子程序********************
KEYSCAN
  BCF   PORTB,1
  BCF   PORTA,3
  BCF   PORTE,0
  BCF   PORTE,1        ;送低電平至K1,K2,K3,K4
  RETURN 
;*********鍵盤去抖子程序(8ms的延時)******************
KEYDELAY
  MOVLW  0X0A
  MOVWF  DEYH
AGAIN2 MOVLW  0XFF
      MOVWF  DEYL
AGAIN1 DECFSZ  DEYL,1
      GOTO  AGAIN1
      DECFSZ  DEYH,1
      GOTO  AGAIN2    ;具體程序語句參考3. 2節
  RETURN
;*************顯示緩沖區處理子程序****************
XIANHUAN
  MOVLW  0XA0
  MOVWF  FSR0L
  RLNCF  S0,0
  MOVWF  TEMP
  INCF   TEMP,0   
  MOVWF  INDF0
  INCF   FSR0L
  RLNCF  S1,0
  MOVWF  TEMP
  INCF   TEMP,0
  MOVWF  INDF0
  INCF   FSR0L
  RLNCF  S2,0
  MOVWF  TEMP
  INCF   TEMP,0
  MOVWF  INDF0
  INCF   FSR0L
  RLNCF  S3,0
  MOVWF  TEMP
  INCF   TEMP,0
  MOVWF  INDF0
  RETURN
;**************主程序******************
MAIN NOP
  CALL  MAINSUB    ;系統初始化
  CALL  CLKINSUB   ;調用時鐘初始化子程序
DENJIAN BCF   INTCON,GIE
  CLRF  S0
  CLRF  S1
  CLRF  S2
  CLRF  S3
  CLRF  SREG
  CLRF  LEDF    ;S0=S1=S2=S3=0
  CALL  XIANHUAN   ;把S3、S2、S1、S0的值裝入顯示緩沖區
  CALL  DISPLAY    ;顯示
DENAN BCF   INTCON,GIE   ;關中斷
  CALL  KEYSCAN    ;進行鍵掃描
  BTFSS  PORTB,4
  GOTO  XIAODOU1   ;如起始鍵按下,則消抖動
  GOTO  DENAN    ;如起始鍵沒按下,則繼續等待
XIAODOU1
  CALL  KEYDELAY   ;延時消抖動
  CALL  KEYSCAN    ;再次進行鍵掃描
  BTFSC  PORTB,4
  GOTO  DENAN    ;若為干擾,則再次等待鍵按下
  CLRF  S0
  CLRF  S1
  CLRF  S2
  CLRF  S3
  CLRF  SREG    ;設置新一次計時的初始條件 
WAITS CALL  KEYSCAN 
  BTFSS  PORTB,4
  GOTO  WAITS    ;為了防止按鍵過于靈敏,等鍵松開后再進行
          ;下面的操作
  BSF   INTCON,GIE   ;開總中斷
HERE CALL  XIANHUAN   ;顯示緩沖區處理
  CALL  DISPLAY    ;即時更新顯示內容
  CALL  KEYSCAN
  BTFSS  PORTB,4
  GOTO  XIAODOU    ;若停止計時鍵按下,則消抖
  GOTO  HERE    ;若停止計時鍵沒按下,則繼續等待中斷計時
XIAODOU
  CALL  DISPLAY    ;利用消抖動時間調用顯示程序
  CALL  DISPLAY
  CALL  DISPLAY
  CALL  DISPLAY
  CALL  DISPLAY
  CALL  DISPLAY
  CALL  DISPLAY
  CALL  DISPLAY
  CALL  DISPLAY
  CALL  KEYSCAN
  BTFSC  PORTB,4
  GOTO  HERE    ;若為干擾,則繼續等待停止鍵按下 
  BCF   INTCON,GIE   ;若停止鍵按下,則禁止中斷
  CALL  DISPLAY    ;若不為干擾,則禁止中斷,更新顯示內容
WAITR CALL  KEYSCAN 
  BTFSS  PORTB,4
  GOTO  WAITR    ;為了防止按鍵過于靈敏,等鍵松開后再進行
          ;下面的操作 
DENDAI CALL  KEYSCAN
  BTFSC  PORTB,4
  GOTO  DENDAI    ;循環進行鍵掃描,等待清0鍵按下
  CALL  KEYDELAY   ;延時消抖
  CALL  KEYSCAN
  BTFSC  PORTB,4
  GOTO  DENDAI   
WAIT19 CALL  KEYSCAN
  BTFSS  PORTB,4
  GOTO  WAIT19    ;等鍵松開
  GOTO  DENJIAN    ;新一次計時開始
  END
 

 
 

關閉窗口
主站蜘蛛池模板: 亚洲精品一区二区三区丝袜 | 中文字幕高清 | 欧美成人精品二区三区99精品 | 午夜视频一区二区 | 在线一区二区三区 | 国产一区视频在线 | 中文字幕亚洲一区二区三区 | 欧美午夜视频 | 亚洲视频在线看 | 日本成人三级电影 | 一区二区视频在线观看 | 特级黄一级播放 | 久久高清免费视频 | 国产精品免费一区二区 | 久久99精品久久久久久国产越南 | 97精品超碰一区二区三区 | 国产精品久久久久久av公交车 | 欧美黄色一区 | 久久久久久免费毛片精品 | 色黄爽 | 国产高清视频在线 | 国产精品综合 | 亚洲视频在线观看免费 | 日韩福利片 | 一区二区在线免费观看视频 | 国产污视频在线 | 亚洲不卡av在线 | 日韩欧美手机在线 | 国产精品看片 | 国产91综合 | 欧美性久久 | 91在线视频免费观看 | av片免费 | cao视频| 91精品一区二区三区久久久久久 | 韩国精品一区二区三区 | 中文字幕精品视频 | 亚洲天天干 | 精品久久久久久亚洲综合网站 | 亚洲国产精品一区二区第一页 | 亚洲成人网在线 |