微波EDA网,见证研发工程师的成长!
首页 > 硬件设计 > 嵌入式设计 > PIC单片机计时秒表程序设计

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

时间:12-11 来源:互联网 点击:

//此程序实现计时秒表功能,时钟显示范围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;k4;k++)
{
data=s[k];
if(k==2) data=table0[data]; //个位需要显示小数点
else data=table[data];
SPILED(data); //发送显示段码
}
for(k=0;k4;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.51hei.com提供此单片机程序有问题请联系
main()
{
tmint(); //TMR0初始化
initial(); //spi显示初始化及系统其它部分初始化
INTCONbits.GIE=0; //总中断禁止
while(1)
{
for(k=0;k4;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 ;用于存放临时值

Copyright © 2017-2020 微波EDA网 版权所有

网站地图

Top