PIC单片机计时秒表程序设计

发布者:真瓷堂最新更新时间:2012-12-11 来源: 51hei关键字:PIC单片机  计时秒表  时钟显示范围 手机看文章 扫描二维码
随时随地手机看文章

//此程序实现计时秒表功能,时钟显示范围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;
    }
   }
  }
 }
}[page]
//主程序
//http://www.51hei.com 提供此单片机程序有问题请联系
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 [page]
;*********** 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

关键字:PIC单片机  计时秒表  时钟显示范围 引用地址:PIC单片机计时秒表程序设计

上一篇:PIC18F458单片机休眠状态工作方式与激活
下一篇:PIC单片机CAN总线通讯汇编程序

推荐阅读最新更新时间:2024-03-16 13:14

PIC单片机上实时时钟PCF8563测试程序
..............................PCF8563测试程序主函数............................ ............................................................................... ............................................................................... #include #include pcf8563.h #include IIC.h __CONFIG(FOSC_INTOSC&WDTE_OFF&MCLRE_OFF)
[单片机]
PIC单片机的优点
一、引言 据统计,我国的单片机年容量已达1-3亿片,且每年以大约16%的速度增长,但相对于世界市场我国的占有率还不到1%。这说明单片机应用在我国才刚刚起步,有着广阔的前景。培养单片机应用人才,特别是在工程技术人员中普及单片机知识有着重要的现实意义。 当今单片机厂商琳琅满目,产品性能各异。针对具体情况,我们应选何种型号呢?首先,我们来弄清两个概念:集中指令集(CISC)和精简指令集(RISC)。采用CISC结构的单片机数据线和指令线分时复用,即所谓冯.诺伊曼结构。它的指令丰富,功能较强,但取指令和取数据不能同时进行,速度受限,价格亦高。采用RISC结构的单片机数据线和指令线分离,即所谓哈佛结构。这使得取指令和取数据可同时进行,且
[单片机]
PIC单片机c语言中如何喂狗
首先你要说明你用的是哪款PIC的单片机和用哪个C编译器。 PIC有中低端的八位单片机PIC10/12/16的,高端的八位单片机PIC18系列,1十六位单片机PIC24和dsPIC,还有一个PIC32是三十二位的。上述的都可以通过调用宏指令CLRWDT();来实现喂狗。 但他们的宏指令的声明一般都是在各自的头文件中,比如根据他们的数据手册PIC10/12/16系列的宏指令声明都在htc.h文件中,pic.h里我还没试过。 而PIC18我用过的是MPLAB C18编译器,其声明宏指令的头文件是这个芯片的名称,如PIC18F4680.h。 而PIC24我用的是MPLAB C30编译器我是直接根据数据手册的要求在C文件里定义宏的: #def
[单片机]
PIC单片机开发的经验、技巧总结分享
由美国Microchip公司生产的PIC系列单片机,由于其超小型、低功耗、低成本、多品种等特点,已广泛应用于工业控制、仪器、仪表、通信、家电、玩具等领域,本文总结了作者在PIC单片机开发过程中的一些经验、技巧,供同行参考。 1 怎样进一步降低功耗 功耗,在电池供电的仪器仪表中是一个重要的考虑因素。PIC16C××系列单片机本身的功耗较低(在5V,4MHz振荡频率时工作电流小于2mA)。为进一步降低功耗,在保证满足工作要求的前提下,可采用降低工作频率的方法,工作频率的下降可大大降低功耗(如PIC16C××在3V,32kHz下工作,其电流可减小到15μA),但较低的工作频率可能导致部分子程序(如数学计算)需占用较多的时间。在这种情
[单片机]
<font color='red'>PIC单片机</font>开发的经验、技巧总结分享
pic单片机控制HT1621 LCD程序
p IC 单片机 控制HT1621 LCD 程序 ;THIS PROGRAM IS HT1621 LCD DISPLAY ;VDD=5.0V IF VDD 5.0V PLEASE TO DELAY ;RECEIVE AND TRANSMIT BYTR’TIM ; FSR EQU 4H RB EQU 6H GENR0 EQU 09H GENR1 EQU 0AH WD_RG EQU 0BH ;the registers of LCD DISPLAY DATA DA_AG0 EQU 10H ;SEG0 SEG1 DA_AGF EQU 1FH ;SEG30 SEG31 ; ;RB BITS CS EQU
[单片机]
如何在PIC单片机上实现发送数据
该程序运行在pIC单片机p18f458上实现发送缓冲器0向接收缓冲器0发送数据的自测试模式,其中接收采用中断方式。 //发送采用查询方式 #include “p18f458.h” intCAN_FLAG; //定义标志寄存器 //**************初始化子程序*************** void initcan() { TRISB=(TRISB|0X08)&0XFB; //设置CANRX/RB3为输入,CANTX/RB2为输出 //设置CAN的波特率为125K,在Fosc=4M时,Tbit=8us,假设BRP=01h //则TQ=[2*(1+BRP)]/Fosc=2*(1+1)/4=1us。 //NOMINA
[单片机]
如何在<font color='red'>PIC单片机</font>上实现发送数据
PIC单片机lcd显示时钟演示程序
include p16f877.inc ;*---- ; 定义 LCD 数据& 控制I/O口 LCD_DATA equ PORTB LCD_CNTL1 equ PORTB LCD_CNTL2 equ PORTA ; 定义 LCD控制相应的I/O引脚 RS equ 1 E equ 5 ; LCD 模块命令 DISP_ON EQU 0x00C ; 开显示 DISP_ON_C EQU 0x00E ; 开显示, 开指针 DISP_ON_B EQU 0x00F ; 开显示, 开指针,开闪烁 DISP_OFF EQU 0x008 ; 关显示 CLR_DISP EQU 0x001 ; 清显示的操作数 ENTRY_INC EQU 0x00
[单片机]
PIC单片机一路AD的初始化方法
void delay(unsigned int x) { unsigned int a,b; for(a=x;a 0;a--) for(b=30;b 0;b--); } void ad() //采集函数 { INTCON=0X00; TRISA=0XFF; ADCON1=0B00000000; ADCON0=0B10000001;//AN1,RA0 delay(1); ADGO=1; delay(1); i=ADRESH; //采集到的AD值 ADRESH=0x00; } void Vad() //求AD平均值函数 { ad(); delay(1); j1=i; ad(); delay(1); j2=i; ad(); delay
[单片机]
小广播
添点儿料...
无论热点新闻、行业分析、技术干货……
设计资源 培训 开发板 精华推荐

最新单片机文章
何立民专栏 单片机及嵌入式宝典

北京航空航天大学教授,20余年来致力于单片机与嵌入式系统推广工作。

换一换 更多 相关热搜器件
电子工程世界版权所有 京B2-20211791 京ICP备10001474号-1 电信业务审批[2006]字第258号函 京公网安备 11010802033920号 Copyright © 2005-2024 EEWORLD.com.cn, Inc. All rights reserved