|
仿真原理圖如下(proteus仿真工程文件可到本帖附件中下載)
電路圖
單片機源程序如下:
- //main.c
- -----------------------------------
- /*******************************************************************************
- *
- *
- --------------------------------------------------------------------------------
- * 實 驗 名 : 動態(tài)數(shù)碼管顯示,定時器
- * 實驗說明 :
- * 連接方式 :
- * 注 意 :
- *******************************************************************************/
- #include"STC15F2K.h"
- #include"epprom.h"
- //--定義使用的IO口--//
- #define u8 unsigned char
- #define u16 unsigned int
- sbit you1=P2^0;
- sbit you2=P2^1;
- sbit you3=P2^2;
- sbit you4=P2^3;
- sbit you23=P2^4;
- sbit kai=P2^5;
- sbit fen=P2^6;
- sbit shi=P2^7;
- sbit jidianqi=P3^7;
- //--定義全局變量--//
- u8 code DIG_PLACE[8] = {
- 0xfe,0xfd,0xfb,0xf7,0xef,0xdf,0xbf,0x7f};//位選控制 查表的方法控制
- u8 code DIG_CODE[18] = {
- 0x3f,0x06,0x5b,0x4f,0x66,
- 0x6d,0x7d,0x07,0x7f,0x6f,
- 0x77,0x7c,0x39,0x5e,0x79,
- 0x71,0x40,0x80};
- //0、1、2、3、4、5、6、7、8、9、A、b、C、d、E、F、- 的顯示碼
- u8 X1,X2,X3,X4,X5;
- u8 DisplayData[8];
- u16 DJS=0,fen60,shi6;
- bit kk=0; //開關(guān),1,倒計時進行,繼電器閉合;0,輸入時間,繼電器斷開
- u16 ff=10*60/*600秒*/,ss=60*60/*3600秒*/;
- u16 count_djs=0;
- u16 countt=0;
- u8 KKKEY;
- //--聲明全局函數(shù)--//
- void DigDisplay(); //動態(tài)顯示函數(shù)
- void ConfigTimer0(u8 ms);
- void key_sm();
- void anjian();
- /*******************************************************************************
- * 函 數(shù) 名 : XX,提供各個數(shù)碼管的數(shù)值
- *******************************************************************************/
- void XX()
- {
- countt=DJS-count_djs;
- if(kk==0) {
- X1=shi6/10;
- X2=shi6%10;
- X3=fen60/10;
- X4=fen60%10;
- X5=17;
- }
- if(kk==1)
- {
- if(countt<=3600)
- {
- X1=countt/600%10;
- X2=countt/60%10;
- X3=countt/10%6 ;
- X4=countt%10/*kk */ ;
- X5=17;
- }
- if(countt>3600)
- {
- X1=countt/36000%10;
- X2=countt/3600%10 ;
- X3=countt%3600/600%6;
- X4=countt%3600/60%10;
- }
- if(X1==0)
- { X1=16;
- if(X2==0)
- {X2=16;
- if(X3==0)X3=16;
- }}
- }
- }
- /*******************************************************************************
- * 函 數(shù) 名 : 掃描按鍵,賦值。
- *******************************************************************************/
- void key_sm()
- {
- anjian();
- if(KKKEY==1) {KKKEY=0;fen60=fen60+10;if(fen60>=60)fen60=0;}
- if(KKKEY==2) {KKKEY=0;shi6=shi6+1;if(shi6>6)shi6=0;}
- if(KKKEY==3) {KKKEY=0;kk=~kk;;}
- ////寫入epprom
- if(KKKEY>0){
- shanchu(0x0000);
- xieru(0x0001,fen60) ;
- xieru(0x0002,shi6) ; }
- DJS=(shi6*ss+fen60*60); //單位是秒。
- }
- /*******************************************************************************
- * 函 數(shù) 名 : main
- * 函數(shù)功能 : 主函數(shù)
- * 輸 入 : 無
- * 輸 出 : 無
- *******************************************************************************/
- void main(void)
- {
- ConfigTimer0(5);
- while(1)
- {
- key_sm();
-
- XX();
- jidianqi=!kk;
- DigDisplay();
- if(countt<=0){kk=0;you23=0; }
- }
- }
- /*******************************************************************************
- * 函 數(shù) 名 : DigDisplay
- * 函數(shù)功能 : 使用數(shù)碼管顯示
- * 輸 入 : 無
- * 輸 出 : 無
- *******************************************************************************/
- void DigDisplay()
- {
- unsigned int j;
- //******************************
- you1=0;
- P1= DIG_CODE[X1]; //發(fā)送位選
- j = 200; //掃描間隔時間設(shè)定
- while(j--);
- P1 = 0x00;//消隱
- you1=1;
- //******************************
- you2=0;
- P1= DIG_CODE[X2]; //發(fā)送位選
- j = 200; //掃描間隔時間設(shè)定
- while(j--);
- P1 = 0x00;//消隱
- you2=2;
- //******************************
- you3=0;
- P1= DIG_CODE[X3]; //發(fā)送位選
- j = 200; //掃描間隔時間設(shè)定
- while(j--);
- P1 = 0x00;//消隱
- you3=3;
- //******************************
- you4=0;
- P1 = DIG_CODE[X4]; //發(fā)送位選
- j = 200; //掃描間隔時間設(shè)定
- while(j--);
- P1 = 0x00;//消隱
- you4=1;
-
- }
- /* 配置并啟動T0,ms-T0定時時間 */
- void ConfigTimer0(u8 ms)
- {
- unsigned long tmp; //臨時變量
-
- tmp = 12000000 / 12; //定時器計數(shù)頻率
- tmp = (tmp * ms) / 1000; //計算所需的計數(shù)值
- tmp = 65536 - tmp; //計算定時器重載值
- TMOD &= 0xF0; //清零T0的控制位
- TH0 = (u8)(tmp>>8); //定時器重載值拆分為高低字節(jié)
- TL0 = (u8)tmp;
- ET0 = 1; //使能T0中斷
- TR0 = 1; //啟動T0
- EA=1;
- }
- //中斷定義為5毫秒
- void InterruptTimer0() interrupt 1
- {
- static u8 Di;
- Di++;
- if(kk==0){count_djs=0;you23=0; }
- if(Di==100) {you23=1;} //秒顯示賦值 0.5秒
- if(Di==200 &&kk==1 ) {{you23=0;count_djs=count_djs+1;; }}
- WDT_CONTR=0x37; //看門狗刷新 8.4S
-
- }
- /**/
- //按鈕掃描 需在定時中斷中調(diào)用
- void anjian()
- {
- static u16 JiShu =0;
- static u16 JiShu1=0;
- static u16 JiShu2=0;
- static u8 keybuf = 0xff;
- static u8 keybuf1 = 0xff;
- static u8 keybuf2 = 0xff;
- u8 nm=500;
- keybuf = (keybuf <<1) |fen;
- if(keybuf == 0x00)
- { JiShu++; if(JiShu>=nm) {JiShu=0;KKKEY=1;} }
- keybuf1 = (keybuf1 <<1) |shi;
- if(keybuf1 == 0x00)
- { JiShu1++; if(JiShu1>=nm) {JiShu1=0;KKKEY=2;} }
- keybuf2 = (keybuf2 <<1) |kai;
- if(keybuf2 == 0x00)
- { JiShu2++; if(JiShu2>=nm) {JiShu2=0;KKKEY=3;} }}
- // epprom.c
- #include "epprom.h"
- void Delay(uchar n)
- {
- uint x;
- while (n--)
- {
- x = 0;
- while (++x);
- }
- }
- void guanbi() //iap閑置
- {
- IAP_CONTR = 0; //Close IAP function \關(guān)閉IAP功能
- IAP_CMD = 0; //Clear command to standby \清除待命命令
- IAP_TRIG = 0; //Clear trigger register \清除觸發(fā)寄存器
- IAP_ADDRH = 0x80; //Data ptr point to non-EEPROM area \數(shù)據(jù)ptr指向非EEPROM區(qū)域
- IAP_ADDRL = 0; //Clear IAP address to prevent misuse \清除IAP地址以防止誤用
- }
- uchar duqu(uint addr)
- {
- uchar dat; //Data buffer \數(shù)據(jù)緩沖區(qū)
- IAP_CONTR = ENABLE_IAP; //Open IAP function, and set wait time \打開IAP功能,設(shè)置等待時間
- IAP_CMD = CMD_READ; //Set ISP/IAP/EEPROM READ command \設(shè)置ISP/IAP/EEPROM讀取命令
- IAP_ADDRL = addr; //Set ISP/IAP/EEPROM address low \將ISP/IAP/EEPROM地址設(shè)置為低位
- IAP_ADDRH = addr >> 8; //Set ISP/IAP/EEPROM address high \將ISP/IAP/EEPROM地址設(shè)置為高
- IAP_TRIG = 0x5a; //Send trigger command1 (0x5a) \發(fā)送觸發(fā)器命令1(0x5a)
- IAP_TRIG = 0xa5; //Send trigger command2 (0xa5) \發(fā)送觸發(fā)器命令2(0xa5)
- _nop_(); //MCU will hold here until ISP/IAP/EEPROM \MCU將在此保持,直到ISP/IAP/EEPROM
- //operation complete \操作完成
- dat = IAP_DATA; //Read ISP/IAP/EEPROM data \讀取ISP/IAP/EEPROM數(shù)據(jù)
- guanbi(); //Close ISP/IAP/EEPROM function \關(guān)閉ISP/IAP/EEPROM功能
- return dat; //Return Flash data \返回閃存數(shù)據(jù)
- }
- void xieru(uint addr, uchar dat)
- {
- IAP_CONTR = ENABLE_IAP; //Open IAP function, and set wait time \打開IAP功能,設(shè)置等待時間
- IAP_CMD = CMD_PROGRAM; //Set ISP/IAP/EEPROM PROGRAM command \設(shè)置ISP/IAP/EEPROM程序命令
- IAP_ADDRL = addr; //Set ISP/IAP/EEPROM address low \將ISP/IAP/EEPROM地址設(shè)置為低位
- IAP_ADDRH = addr >> 8; //Set ISP/IAP/EEPROM address high \將ISP/IAP/EEPROM地址設(shè)置為高
- IAP_DATA = dat; //Write ISP/IAP/EEPROM data \寫入ISP/IAP/EEPROM數(shù)據(jù)
- IAP_TRIG = 0x5a; //Send trigger command1 (0x5a) \發(fā)送觸發(fā)器命令1(0x5a)
- IAP_TRIG = 0xa5; //Send trigger command2 (0xa5) \發(fā)送觸發(fā)器命令2(0xa5)
- _nop_(); //MCU will hold here until ISP/IAP/EEPROM \MCU將在此保持,直到ISP/IAP/EEPROM
- //operation complete \操作完成
- guanbi();
- Delay(1);
- }
- void shanchu(uint addr)
- {
- IAP_CONTR = ENABLE_IAP; //Open IAP function, and set wait time \打開IAP功能,設(shè)置等待時間
- IAP_CMD = CMD_ERASE; //Set ISP/IAP/EEPROM ERASE command \設(shè)置ISP/IAP/EEPROM擦除命令
- IAP_ADDRL = addr; //Set ISP/IAP/EEPROM address low \將ISP/IAP/EEPROM地址設(shè)置為低位
- IAP_ADDRH = addr >> 8; //Set ISP/IAP/EEPROM address high \將ISP/IAP/EEPROM地址設(shè)置為高
- IAP_TRIG = 0x5a; //Send trigger command1 (0x5a) \發(fā)送觸發(fā)器命令1(0x5a)
- IAP_TRIG = 0xa5; //Send trigger command2 (0xa5) \發(fā)送觸發(fā)器命令2(0xa5)
- _nop_(); //MCU will hold here until ISP/IAP/EEPROM operation complete \MCU將在此保持,直到ISP/IAP/EEPROM操作完成
- //
- guanbi();
- }
- //epprom.h
- #ifndef __EPPROM1_H__
- #define __EPPROM1_H__
- //---包含頭文件---//
- #include "STC15F2K.h"
- #include "intrins.h"
- //typedef unsigned char BYTE;
- //typedef unsigned int WORD;
- //---重定義關(guān)鍵詞---//
- #ifndef uchar
- #define uchar unsigned char
- #endif
- #ifndef uint
- #define uint unsigned int
- #endif
- #endif
- #define CMD_IDLE 0 //Stand-By
- #define CMD_READ 1 //Byte-Read
- #define CMD_PROGRAM 2 //Byte-Program
- #define CMD_ERASE 3 //Sector-Erase
- #define ENABLE_IAP 0x82 //if SYSCLK<20MHz
- #define IAP_ADDRESS 0x0000
- void Delay(uchar n);
- void guanbi();
- uchar duqu(uint addr);
- void xieru(uint addr, uchar dat);
- void shanchu(uint addr);
復(fù)制代碼
Keil代碼與Proteus仿真下載:
定時器帶顯示20211206.7z
(1.57 MB, 下載次數(shù): 40)
2021-12-29 04:52 上傳
點擊文件名下載附件
|
評分
-
查看全部評分
|