基于PIC16F877A的秒表程序

发布者:Xingfu6666最新更新时间:2017-12-07 来源: eefocus关键字:PIC16F877A  秒表程序 手机看文章 扫描二维码
随时随地手机看文章

//该源程序已在实验板上调试通过,读者可直接引用,并可利用软件编程的灵活性,加以拓展,实现更为复杂的功能。

//此程序实现计时秒表功能,时钟显示范围00.00~99.99秒,分辨度:0.01秒

//定义0.01 秒、0.1 秒、1秒、10秒计时器
#include IC.h>
#include  
unsigned  char  s0,s1,s2,s3;

unsigned  char   s[4];
unsigned  char   k ,data ,sreg;
unsigned   int  i;
const table[10]={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0XD8,0x80,0x90};
//不带小数点的显示段码表
const table0[10]={0X40,0X79,0X24,0X30,0X19,0X12,0X02,0X78,0X00,0X10};
//带小数点的显示段码表
//TMR0初始化子程序
void  tmint()
{
 T0CS=0;    //TMR0工作于定时器方式
 PSA=1;     //TMR0不用分频
 T0IF=0;     //清除TMR0的中断标志
 T0IE=1;     //TMR0中断允许
}
//spi显示初始化子程序
void  SPIINIT()
{
 PIR1=0;
 SSPCON=0x30;
 SSPSTAT=0xC0;
//设置SPI的控制方式,允许SSP方式,并且时钟下降沿发送。与"74HC595,当其
//SCLK从低到高跳变时,串行输入寄存器"的特点相对应
 TRISC=0xD7;   //SDO引脚为输出,SCK引脚为输出
 TRISA5=0;    //RA5引脚置为输出,输出显示锁存信号
}
//系统其它部分初始化子程序
void  initial()
{
 TRISB1=0;
 TRISB2=0;
 TRISB4=1;
 TRISB5=1;    //设置与键盘有关的各口的输入输出方式
 RB1=0;
 RB2=0;     //建立键盘扫描的初始条件
}
//SPI传输数据子程序
void   SPILED(data)
{
 SSPBUF=data;   //启动发送
 do {
     ;
  }while(SSPIF==0);
 SSPIF=0;
}
//显示子程序,显示4位数
void  dispaly()
{
 RA5=0;     //准备锁存
 for(k=4;k>0;k--)
 {
  data=s[k-1];
  if(k==3) data=table0[data];//第二位需要显示小数点
  else data=table[data];
  SPILED(data);  //发送显示段码
 }
 for(k=0;k<4;k++)
 {
  data=0xFF;
  SPILED(data);  //连续发送4个DARK,使显示好看一些
 }
 RA5=1;     //最后给锁存信号,代表显示任务完成
}
//软件延时子程序
void   DELAY()
{
 for(i = 3553; --i ;) continue;

//键扫描子程序
void  KEYSCAN()
{
while(1){ 
while(1)
 {
  dispaly();   //调用一次显示子程序
  if ((RB5==0)||(RB4==0)) break;
 }
  DELAY();   //若有键按下,则软件延时
  if ((RB5==0)||(RB4==0)) break;//若还有键按下,则终止循环扫描,返回
   }
}
//等键松开子程序
void  keyrelax()
{
while(1){
 dispaly();    //调用一次显示子程序
 if ((RB5==1)&&(RB4==1)) break;
 }      //为防止按键过于灵敏,每次等键松开才返回
}
//系统赋值初始化子程序
void  inizhi()

 s0=0x00;
 s[0]=s0;
 s1=0x00;
 s[1]=s1;
 s2=0x00;
 s[2]=s2;
 s3=0x00;
 s[3]=s3;     //s0=s1=s2=s3=0,并放入显示缓冲数组中
 sreg=0x00;    //tmr0中断次数寄存器清0
}
//中断服务程序
void  interrupt clkint(void)
{
 TMR0=0X13;   //对TMR0写入一个调整值。因为写入TMR0后接着的
 //两个周期不能增量,中断需要3个周期的响应时间
 //以及C语言自动进行现场保护要消耗周期
 T0IF=0;     //清除中断标志
 CLRWDT();
 sreg=sreg+1;    //中断计数器加1
 if(sreg==40)    //中断次数为40后,才对S0,S1,S2,S3 操作
 {
  sreg=0;
  s0=s0+1;
  if(s0==10){
   s0=0 ;
   s1=s1+1;
   if(s1==10){
    s1=0 ;
    s2=s2+1;
    if(s2==10){
     s2=0;
     s3=s3+1;
     if(s3==10) s3=0 ;
    }
   }
  }
 }
 s[0]=s0;
 s[1]=s1;
 s[2]=s2;
 s[3]=s3;
}
//主程序
main()
{
 OPTION=0XFF;
 tmint();     //TMR0初始化
 SPIINIT();    //spi显示初始化
 initial();     //系统其它部分初始化
 di();     //总中断禁止
 while(1) { 
  inizhi();    //系统赋值初始化
  KEYSCAN();  //键扫描,直到开始键按下
  keyrelax();   //等键松开
  ei();    //总中断允许
  TMR0=0X08;
 KEYSCAN();  //键扫描直到停止键按下,在键扫描时有显示
  keyrelax() ;   //等键松开
  di();    //总中断禁止
  KEYSCAN();  //键扫描到清0键按下,在键扫描时有显示 
  keyrelax() ;   //等键松开
 }
}


关键字:PIC16F877A  秒表程序 引用地址:基于PIC16F877A的秒表程序

上一篇:PIC12C508单片机控制灯光源程序
下一篇:基于PIC16F72的两路交流信号AD转换(C程序)

推荐阅读最新更新时间:2024-03-16 15:48

PIC16F877A TIMER1计数操作
/********************** Title:PIC16F877A TIMER1计数操作 Author:hnrain Date:2010-12-28 使用前置分频器 T1CKPS1 T1CKPS1 0 0 1 分频 TMR1时钟为晶振时钟/(4*1) 0 1 2 分频 TMR1时钟为晶振时钟/(4*2) 1 0 4 分频 TMR1时钟为晶振时钟/(4*4) 1 1 8 分频 TMR1时钟为晶振时钟/(4*8) TMR1是16位宽度的TMR1由2个8位的可读写的寄存器TMR1H和TMR1L组成。 TMR1有专门的启停控制位TMR1ON,通过
[单片机]
PIC16F877A 点亮LED
知识重点: PORTA,PORTB,PORTC,PORTD,PORTE复位后为输入状态 PORTA.4为开漏输出 TRISx 为方向寄存器为0时表示输出,为1时表示输入 PORTx为IO端口 PORTA口,默认不是数字IO口,而是模拟IO口。如果我们 要把PORTA口当做数字IO口则要设置ADCON1 = 0x06; *****************************/ #include pic.h #include ../head/config.h //包含自己的配置头文件 __CONFIG(HS&WDTDIS&LVPDIS&PWRTEN);//对熔丝位进行设置 //HS振荡,禁止看门狗,低压编程关闭,启动延时定时器
[单片机]
单纯数码管的显示C程序-用PIC16F877A单片机
单纯数码管的显示C程序 #include htc.h #define HC595_SER RB7 #define HC595_SCK RB6 #define HC595_RCK RB5 #define key_164_data RB3 #define key_164_clk RB2 #define key_com1 RB1 #define key_com0 RB0 #define TURE 1 bit key_finish; //定义位变量,这是PICmate仿真软件环境的特有的地方 unsigned int sample_
[单片机]
基本I/O口操作
//单片机I/O口的使用 //★★★★★★★★★单片机I/O口的使用★★★★★★★★★★★\\ //单片机型号:PIC16F877A //功能描述:让RC0口灯闪烁 #include pic.h //包含单片机内部资源预定义 __CONFIG(0XF73A); //芯片配置字 void delay(); //delay函数申明 //=============================================================================== //函数功能:主函数 //函数名称:void main() void main() /
[单片机]
关于PIC16F877A PWM计算的问题
第一次看这个图时候觉得有的懵~ 后来看懂也就好多了。 对pwm实验,我们一般只关心频率和占空比的问题,下来我来讲解下这个图: 首先假设单片机外接4MHz晶振; PWM波的周期是由PR2寄存器来决定的,占空比是由CCPR1L+2位组成一个10位分辨率; 而周期却是8位分辨率,分子大于分母,那这PWM还能正常工作吗? 我相信很多人一开始可能跟我一样,有这样的疑惑! 我们看下官方数据手册上面是如何计算周期的: PWM周期=(PR2+1)*4*Tosc*TMR2分频数 这个公式里有2个地方需要注意: ① Tosc是4MHz,而不是1MHz ② 乘以4这个就是CCPR1L 2(右移2位)的意思 假
[单片机]
关于<font color='red'>PIC16F877A</font> PWM计算的问题
PIC16F877A单片机 (外部中断与定时器Timer0的综合使用)
1 实现原理 见前面的定时器0和外部中断的内容 2 实现电路图 3 源代码 /*----------------函数功能: 定时器0+外部中断的运用 功能1:LED0灯一直闪烁; 功能2:没有按键按下时,LED1灯灭。有按键按下时,LED1灯亮。 --------------------------*/ #include pic.h // 调用PIC16f87XA单片机的头文件 //#include delay.h //调用延时子函数 __CONFIG(0xFF32);//芯片配置字,看门狗关,上电延时开,掉电检测关,低压编程关 //__CONFIG(HS&WDTDIS&LVPDIS);
[单片机]
<font color='red'>PIC16F877A</font>单片机 (外部中断与定时器Timer0的综合使用)
pic16f877a的电平变化中断(interrupt on change)使用误区
在PORTB的RB4:RB7是电平变化中断(interrupt on change),要使用它,将它们引脚对应于TRISB的位设定为输入是必须的,然后配置中断。 工作原理:RB4:RB7是电平变化中断的引脚的输入状态和上一次读取PORTB的锁存器的值进行比较,当两组数据相异时,发生中断同,当这四个引脚的一部分发生电平变化时 ,将会最后取或,只要有一个引脚的输入状态发生变化,就会发生中断改变。 注意:在进入中断服务子程序时,一定要读取或写入PORTB锁存器的值,这样才会结束两组数据的比较,然后再去清除中断标志位。如果没有读取PORTB的值,两组数据的比较一直存在,先清除中断标志(RBIF)是没有用的,RBIF也
[单片机]
基于AT89S52与PIC16F877A的在线编程控制系统的设计
l 引 言 通常进行单片机的实验或开发时,传统的并行编程方法中,编程器是必不可少的。仿真、调试完的程序需要借助编程器烧到单片机内部或外接的程序存储器中。在开发过程中,程序每改动一次就要拔下电路板上的芯片,编程后再插上。随着计算机技术的发展,许多公司推出了带有片内FLASH存储器的MCU,FLASH存储器具有电可擦除、无需后备电源保护数据、可在线编程等特点。在线编程目前有两种实现方法:在线系统编程(ISP)和在线应用编程(IAP)。ISP一般是通过单片机专用的串行编程接口对单片机内部的FLASH存储器进行编程,例如AT-MEL公司的单片机AT89S52就提供了一个SPI串行接口对内部程序存储器编程(ISP)。 在线编程(ISP)
[应用]
小广播
添点儿料...
无论热点新闻、行业分析、技术干货……
设计资源 培训 开发板 精华推荐

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

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

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