基于AT89C52做秒表0~99秒
生活随笔
收集整理的這篇文章主要介紹了
基于AT89C52做秒表0~99秒
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
1、應網友要求做了個秒表。
2、定期器采用10毫秒,數碼管后2位顯示的是毫秒,故100毫秒進1秒,100毫秒*定時器10毫秒故就是1秒。
3、使用3個獨立按鍵,按鍵2表示啟動秒表,按鍵3表示暫停秒表,按鍵4表示清除秒表且暫停秒表。
4、已在我的清翔51開發板上實現,表現良好(只是按鍵的時候數碼管會滅,這個我就不解了,需要用定時器做按鍵判斷。)
main.c
#include "Time.h" #include "key.h" #include <reg52.h> #include "dt.h"void main(void) {unsigned char dt_state=1;//數碼管標志位Timer0_16bit(10);//配置初始化定時器0為10毫秒convert_data(9999,4);//初始化數碼管while(1){if(dt_state)//主程序驅動數碼管標志位{dt_display(4);//使用主程序驅動數碼管}switch(key2345()){case 2:TR0=1;dt_state=0;break;//啟動秒表,且使用定時器驅動數碼管case 3:TR0=0;dt_state=1;break;//暫停秒表,且使用主程序驅動數碼管case 4:TR0=0;TIME=0;convert_data(TIME,4);dt_state=1;break;//清除時間,且暫停計時器,且使用主程序驅動數碼管break;}} }delay.h
//這是一個延遲函數為毫秒級// #ifndef __DELAY_H__ #define __DELAY_H__ void delay_ms(unsigned char ms);//最大輸入255,ms=1,最小1ms時間 #endif // !__DELAY_H__?delay.c
//軟件延遲ms級別 void delay_ms(unsigned char ms) //設置毫秒級別延遲函數,z最大輸入65535 {unsigned char x;for (; ms > 0; ms--)for (x = 114; x > 0; x--); }key.h
#ifndef __KEY_H__ #define __KEY_H__#include <reg52.h> #include "delay.h"//獨立按鍵 sbit key_S2 = P3^0; sbit key_S3 = P3^1; sbit key_S4 = P3^2; sbit key_S5 = P3^3;#define key_all P3//按鍵占用P3口 unsigned char key2345(void); //函數返回值為2、3、4、5分別對應按鍵2、按鍵3、按鍵4、按鍵5,本函數只循環一次#endif // !__KEY_H__key.c
//獨立按鍵 S2 S3 S4 S5 //分別對應 P30 P31 P32 P33 #include"key.h"//獨立按鍵使用switch語句 unsigned char key2345(void) //函數返回值為2、3、4、5分別對應按鍵2、按鍵3、按鍵4、按鍵5,本函數只循環一次 {key_all |= 0x0f;if ((key_all&0x0f) != 0x0f) //&運算符沒有!=高,故需要加()括號{delay_ms(10);if ((key_all & 0x0f) != 0x0f){switch (key_all & 0x0f){case 0x0e:while ((key_all & 0x0f) != 0x0f);return 2; //while在這里進行松手檢測case 0x0d:while ((key_all & 0x0f) != 0x0f);return 3; //while在這里進行松手檢測case 0x0b:while ((key_all & 0x0f) != 0x0f);return 4; //while在這里進行松手檢測case 0x07:while ((key_all & 0x0f) != 0x0f);return 5; //while在這里進行松手檢測}}}return 0;//沒有按鍵按下時返回0 }Time.h
#ifndef __TIME_H__ #define __TIME_H__#include <REG52.h>extern unsigned int TIME; //定時器0初始化,并設定ms毫秒且工作方式1,16位模式 void Timer0_16bit(unsigned char time0_16_bit_ms);#endif // !__TIME_H__Time.c
#include "Time.h" #include "dt.h"static unsigned char H0 = 0, L0 = 0; unsigned int TIME=0; //定時器0初始化,設定ms毫秒且工作方式1,16位模式 void Timer0_16bit(unsigned char time0_16_bit_ms) {TMOD |= 0x01;TH0 =(65536 - (unsigned int)(time0_16_bit_ms * 921.6)) / 256;//需將計算的小數轉換整形TL0 =(65536 - (unsigned int)(time0_16_bit_ms * 921.6)) % 256;//需將計算的小數轉換整形H0 = TH0;L0 = TL0;EA = 1;//開啟總中斷ET0 = 1;//允許定時器0溢出進入中斷TR0 = 0;//先關閉定時器 } void Timer0Interrupt(void) interrupt 1 {TH0 = H0;TL0 = L0;dt_display(4);//每隔10毫秒刷新一下4個數碼管convert_data(TIME,4);//每隔10毫秒轉換一下時間if(TIME++==9999)//數碼管最大顯示99.99秒{TIME=0;} }dt.h
#ifndef __DT_H__ #define __DT_H__#include <reg52.h> #include "delay.h"sbit wei = P2^7; //鎖存器位選 sbit duan = P2^6; //鎖存器段選 #define dt_dt P0//0<=dt_data<=9999,y=4表示4個數碼管亮 void convert_data(unsigned int dt_data,unsigned char y);//y個數碼管顯示 void dt_display(unsigned char y);#endifdt.c
//數碼管dt 使用共陰極數碼管即位選是陰極時數碼管才選中 //使用P0-8個GPIO口 //P2.7位選腳(控制哪個數碼管亮)、P2.6段選腳(送數碼管值) 控制2個74鎖存器#include "dt.h"static unsigned char datax[8];//定義局部變量//用來存放小數及正整數,然后發給數碼管進行顯示低位到高位存放 static code unsigned char dt_duan[26] = //數碼管段選真值表 dt_duan[i] + 0x80 數碼管顯示數據并且此數據的右下角有小數點 {0x3F, //"0"0x06, //"1"0x5B, //"2"0x4F, //"3"0x66, //"4"0x6D, //"5"0x7D, //"6"0x07, //"7"0x7F, //"8"0x6F, //"9"0x80, //"."0x40, //"-"0x77, //"A"0x7C, //"B"0x39, //"C"0x5E, //"D"0x79, //"E"0x71, //"F"0x76, //"H"0x38, //"L"0x37, //"n"0x3E, //"u"0x73, //"P"0x5C, //"o"0x00, //熄滅0x00 //自定義 };static code unsigned char dt_wei[9]={0x7f,0xbf,0xdf,0xef,0xf7,0xfb,0xfd,0xfe,0xff};//1位-8位(0x7f表示最右邊哪個數碼管)0xff數碼管就不亮了static void clear_reset_dt(void)//清除數碼管,關閉數碼管,初始化數碼管 {dt_dt= dt_wei[8];//清除位碼,關閉所有數碼管wei=1;wei=0;dt_dt= dt_duan[25];//清除段碼,關閉所有數碼管顯示duan=1;duan=0;dt_dt=0xff;//恢復單片機IO口默認高電平狀態 }void dt_display(unsigned char y)//y表示的是要幾個數碼管顯示取值0~8 {unsigned char a;for (a = 0; a < y; a++)//a亮——a值——a值滅;a+1亮——a+1值——a+1值滅;開始循環(亮,真值,假值){dt_dt = dt_wei[a];//燈亮wei = 1; //打開位選wei = 0; //鎖存位選dt_dt = datax[a];//數字duan = 1; //打開段選duan = 0; //鎖存段選delay_ms(1);//亮的時間,防閃爍dt_dt = dt_duan[25];//數字熄滅,假值duan = 1; //打開段選duan = 0; //鎖存段選}clear_reset_dt();//清除數碼管顯示,初始化數碼管 }//將要顯示的正整數臨時存儲在數組里面,然后循環顯示數組里的元素即可 //x傳遞的數據10進制(x不是8位則高位不會亮) void convert_data(unsigned int dt_data,unsigned char y)//y表示的是要幾個數碼管顯示取值0~8 {unsigned char i; //數組標號也是段選真值unsigned char a; //流水號,用來表示數碼管1~8個for (a = 0;a < y;a++) //將x沒位的值存放到數組里面{i = dt_data % 10;//獲取最后一位數字dt_data = dt_data / 10;//每次舍去最低位if(a==2)datax[a] = dt_duan[i]+0x80;//0x80是小數點elsedatax[a] = dt_duan[i];}clear_reset_dt();//清除數碼管顯示 }總結
以上是生活随笔為你收集整理的基于AT89C52做秒表0~99秒的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: AT89C52汇编
- 下一篇: matlab复合形法优化设计,基于MAT