单片机秒表程序(自动切换时间

/* 
write by cjdsn
 时间计算
1/22.1184=0.0000005425
1/0.5425=1843317
1843317/40=46083
//我的是阳极显示,0开1关
*/


#include<reg52.h>  
unsigned char code Tab[12]=


{0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90,0x7f,0xff}; 
 //数码管显示0~9的段码表
unsigned char int_time;        //记录中断次数
unsigned char second;        //储存秒
unsigned char t,h;
sbit pd=P2^0;
sbit pc=P2^1;
sbit pb=P2^2;
sbit pa=P2^3;
sbit p27=P2^7;
/******************************************************************


*****
函数功能:快速动态扫描延时,延时约0.6毫秒
*******************************************************************


*****/
void delay(void)
{
  unsigned char i;
  for(i=0;i<200;i++)
        ;
}
/******************************************************************


*****
函数功能:显示秒
入口参数:k
出口参数:无
*******************************************************************


*****/
 void DisplaySecond(unsigned char k)
{
   pb=0;        //P2.1引脚输出低电平
P0=Tab[k/10];          //显示十位
delay();
delay();
delay();
delay();
delay();
delay();
delay();
delay();
   pb=1;
   pa=0;      //P2.0引脚输出低电平
P0=Tab[k%10];         //显示个位
delay();
delay();
delay();
delay();
delay();
delay();
delay();
delay();
pa=1;
pd=0;
P0=Tab[t/10];  //分 十位
delay();
delay();
delay();
delay();
delay();
delay();
delay();
delay();
pd=1;
pc=0;
P0=Tab[t%10];  //分 个位
delay();
delay();
delay();
delay();
delay();
delay();
delay();
delay();
pc=1;
///////////////////////////////////
pc=0;
P0=Tab[10];
delay();
delay();
delay();
delay();
delay();
delay();
pc=1;
//====================================//
/*
P2=0xff;     //关闭所有数码管
P0=0xff;        //显示个位
*/
//====================================//
}


///////////////////////////////////////////////////////////////////


/////////////////


 void Displayh()
{
   pb=0;        //P2.1引脚输出低电平
P0=Tab[t/10];          //显示十位
delay();
delay();
delay();
delay();
delay();
delay();
delay();
delay();
   pb=1;
   pa=0;      //P2.0引脚输出低电平
P0=Tab[t%10];         //显示个位
delay();
delay();
delay();
delay();
delay();
delay();
delay();
delay();
pa=1;
pd=0;
P0=Tab[h/10];  //分 十位
delay();
delay();
delay();
delay();
delay();
delay();
delay();
delay();
pd=1;
pc=0;
P0=Tab[h%10];  //分 个位
delay();
delay();
delay();
delay();
delay();
delay();
delay();
delay();
pc=1;
///////////////////////////////////
pc=0;
P0=Tab[10];
delay();
delay();
delay();
delay();
delay();
delay();
pc=1;
}


////////////////////////////////  显示小数点
displayms(void)
 {
P2=1;
p27=1;
pa=0;
pb=1;
P0=Tab[10];
delay();
delay();
delay();
delay();
delay();
delay();
delay();
delay();
delay();
delay();
delay();
delay();
delay();
delay();
pa=1;
 }


//==========================================================//


 
void main(void)     
   {
   P2=1;
   p27=1;
     TMOD=0x01;                 //使用定时器T0
    TH0=(-46083)/256;    //将定时器计时时间设定为


46083×1.085微秒
//=50000微秒=50毫秒
TL0=(-46083)%256;
EA=1;                 
      ET0=1;                 
          TR0=1;                   
  int_time=0;     //中断次数初始化
second=0;   //秒初始化
t=59;

while(1)
{       if(h<=0){
      DisplaySecond(second);//调用秒的显示子程序
  }
else Displayh();
}
 }  
//********************************************************
//函数功能:定时器T0的中断服务程序
//*******************************************************
  void interserve(void ) interrupt 1 using 1  
  {
    TR0=0;    //关闭定时器T0
    int_time ++;        //每来一次中断,中断次数int_time自加1


断次数清0  
if(int_time==40)   //够20次中断,即1秒钟进行一次检测结果采样
 {
        int_time=0;    //
second++;    //秒加1
if(h>0){displayms();}
if(second==60)
   {  second =0; //秒等于60就返回0
 t++;}
if(t==60){t=0;h++;
if(h==24)h=0;}
 }      
  TH0=(-46083)/256;   //重新给计数器T0赋初值
TL0=(-46083)%256;
TR0=1;     //启动定时器T0
 }  
发布了2 篇原创文章 · 获赞 3 · 访问量 1916
展开阅读全文

C语言 单片机秒表程序

04-05

本人是一个新手 对于下边的c程序每一个子函数能看懂,但是像这么多子函数放到一起 就晕了,想请亲们帮我把这个程序的流程梳理梳理中断是何时工作,各个子函数怎么在这个整体里运行 越详细越好,本人十分感谢! ``` /* 设计的秒表计数到小数点后两位,(ms)用到六个数码管一个小数点加两位小数*/ #include<reg52.h> sbit ADDR3=P1^3; sbit ENLED=P1^4; sbit KEY1=P2^4; sbit KEY2=P2^5; sbit KEY3=P2^6; sbit KEY4=P2^7; unsigned char code LedChar[] = { //数码管显示字符转换表 0xC0, 0xF9, 0xA4, 0xB0, 0x99, 0x92, 0x82, 0xF8, 0x80, 0x90, 0x88, 0x83, 0xC6, 0xA1, 0x86, 0x8E }; unsigned char LedBuff[6]={ 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF //数码管显示缓存区 }; unsigned char KeySta[4]={1,1,1,1}; bit StopwatchRunning=0; bit StopwatchRefresh=1; unsigned char IntegerPart=0;//整数部分 unsigned char DecimalPart=0;//小数部分 void ConfigTimer0(unsigned int ms); void StopwatchDisplay(); void KeyDriver(); void main() { EA=1; ENLED=0; ADDR3=1; P2=0XFE;//P2.0置零选第四行按键 ConfigTimer0(2);//T0定时2ms while(1) { if(StopwatchRefresh) //如果刷新需要调用显示函数 StopwatchRefresh=0; StopwatchDisplay(); KeyDriver(); } } /*配置并启动T0 ms就是T0的定时时间*/ void ConfigTimer0(unsigned int ms) { unsigned long tmp; tmp=11059200/12;// 1/T=f频率 tmp=(tmp*ms)/1000; // ms/1000=1s f*T=机械周期个数 tmp=65536-tmp; tmp=tmp+18; T0RH=(unsigned char)(tmp>>8); T0LH=(unsigned char)tmp; TMOD&=0xF0; TMOD|=0x01; TH0=T0RH; TL0=T0RL; ET0=1; TR0=1; } /*秒表计数显示函数*/ void StopwatchDisplay() { signed char i; unsigned char buf[4];//同理数据转换的缓冲区 /*小数部分转换到低2位*/ LedBuf[0]=LedChar[DecimalPart%10]; LedBuf[1]=LedChar[DecimalPart/10]; /*整数部分换到高4位 注意这里和小数部分区别是要用到缓存*/ buf[0]= IntegerPart%10; buf[0]= IntegerPart/10%10; buf[0]= IntegerPart/100%10; buf[0]= IntegerPart/1000%10; for(i=3;i>=1;i++)//把高位为零的换成空字符 { if(buf[i]==0) LedBuf[i+2]=0xFF;//置空 else break; } for(;i>=0;i--) { LedBuf[i+2]=LedChar[buf[i]]; } LedBuf[i+2]=0x7F;//运行到整数的最后一位上顺便点亮小数点 } /*秒表复位*/ void StopwatchReset() { StopwatchRunning=0; //停止秒表 IntegerPart=0; DecimalPart=0; StopwatchReset=1//重置刷新标志 } /*秒表启停函数*/ void StopwatchAction() { if(StopwatchRunning)//若是已经启动则停止 StopwatchRunning=0; else StopwatchRunning=1;//若是已经停止则启动 } /*按键驱动函数,检测到有按键动作,调度相应动作函数,只有两个按键另外四个。注意:需要在主函数调用*/ void KeyDriver() { unsigned char i; static unsigned char backup[4]=[1,1,1,1]; for(i=0;i<4;i++) { if(backup[i]!=KeySta[i]) { if(backup[i]!=0) { if(i==1) StopwatchReset(); else if(i==2) StopwatchAction(); } backup[i]=KeySta[i]; } } } /*数码管动态扫描刷新函数,注意:需在定时中断中调用*/ void LedScan() { static unsigned char i=0; P0=0XFF; P1=(P1&0xF8)|i; P0=LedBUF[i]; if(i<5) //在C里,i>5 i=0 继续走!!! i++; else i=0; } void KeyScan() { unsigned char i; static unsigned char keybuff[4]={ 0xFF,0xFF,0xFF,0xFF }; keybuff[0]=(keybuff[0]<<1)| KEY1; keybuff[1]=(keybuff[1]<<1)| KEY1; keybuff[2]=(keybuff[2]<<1)| KEY1; keybuff[3]=(keybuff[3]<<1)| KEY1; for(i=0;i<4;i++) { if(keybuff[i]==0x00)//连续8次扫描为0, 2ms*8(得移动8位上面才能有结果) { KeySta[i]=0; } else if(keybuff[i]==0xFF) { KeySta[i]=1; } } } /* 秒表计数函数,每隔10ms调用一次进行秒表计数累加 */ void StopwatchCount() { if (StopwatchRunning) //当处于运行状态时递增计数值 { DecimalPart++; //小数部分+1 if (DecimalPart >= 100) //小数部分计到100时进位到整数部分 { DecimalPart = 0; IntegerPart++; //整数部分+1 if (IntegerPart >= 10000) //整数部分计到10000时归零 { IntegerPart = 0; } } StopwatchRefresh = 1; //设置秒表计数刷新标志 } } /*T0中断函数,完成数码管扫描、按键扫描与秒表计数*/ void InterruptTimer0() interrupt 1 { static unsigned char tmr10ms =0; TH0=T0RH; TL0=T0RL; LedScan(); KeyScan(); //定时10ms进行一次秒表计数 tmr10ms++; if(tmr10ms>=5) //2ms一次 2*5=10ms { tmr10ms=0; StopwatchCount(); } } ``` 问答

没有更多推荐了,返回首页

©️2019 CSDN 皮肤主题: 大白 设计师: CSDN官方博客

分享到微信朋友圈

×

扫一扫,手机浏览