微控制器學習筆記————51微控制器實現操作AT24C02時,利用“一氣呵成的定時器延時”改善數碼管的閃爍現象
阿新 • • 發佈:2020-08-09
一、使用proteus繪製簡單的電路圖,用於後續模擬
關於IIC的讀寫:
二、編寫程式
/********************************************************************************************************************
---- @Project: AT24C02
---- @File: main.c
---- @Edit: ZHQ
---- @Version: V1.0
---- @CreationTime: 20200722
---- @ModifiedTime: 20200722
---- @Description: 實現功能:
---- 4個被更改後的引數斷電後不丟失,資料可以儲存,斷電再上電後還是上一次最新被修改的資料。如果AT24C02短路,虛焊,或者壞了,系統可以檢查出來,並且蜂鳴器會間歇性鳴叫報警。按更改引數按鍵時,數碼管比上一節大大降低了閃爍現象。
---- 顯示和獨立按鍵部分根據數碼管顯示程式來改編,S1,S5,S9作為獨立按鍵。
---- 一共有4個視窗。每個視窗顯示一個引數。
---- 第8,7,6,5位數碼管顯示當前視窗,P-1代表第1個視窗,P-2代表第2個視窗,P-3代表第3個視窗,P-4代表第1個視窗。
---- 第4,3,2,1位數碼管顯示當前視窗被設定的引數。範圍是從0到9999。S1是加按鍵,按下此按鍵會依次增加當前視窗的引數。S5是減按鍵,按下此按鍵會依次減少當前視窗的引數。S9是切換視窗按鍵,按下此按鍵會依次迴圈切換不同的視窗。
---- 微控制器:AT89C52
********************************************************************************************************************/
#include "reg52.h"
/*——————巨集定義——————*/
#define FOSC 11059200L
#define BAUD 9600
#define T1MS (65536-FOSC/12/500) /*0.5ms timer calculation method in 12Tmode*/
#define OP_READ 0xa1 /*器件地址以及讀取操作,0xa1即為1010 0001B*/
#define OP_WRITE 0xa0 /*器件地址以及寫入操作,0xa0即為1010 0000B*/
#define const_key_time1 9 /*按鍵去抖動延時的時間*/
#define const_key_time2 9 /*按鍵去抖動延時的時間*/
#define const_key_time3 9 /*按鍵去抖動延時的時間*/
#define const_eeprom_1s 96 /* 大概1秒的時間 */
#define const_voice_short 20 /*蜂鳴器短叫的持續時間*/
/*——————變數函式定義及宣告——————*/
/*蜂鳴器的驅動IO口*/
sbit BEEP = P2^7;
/*LED*/
sbit LED = P3^5;
/*按鍵*/
sbit Key_S1 = P0^0; /*對應S1鍵,加鍵*/
sbit Key_S2 = P0^1; /*對應S5鍵,減鍵*/
sbit Key_S3 = P0^2; /*對應S9鍵,切換視窗*/
sbit Key_Gnd = P0^4;
/*數碼管*/
sbit Dig_Hc595_Sh = P2^0;
sbit Dig_Hc595_St = P2^1;
sbit Dig_Hc595_Ds = P2^2;
/*EEPROM*/
sbit eeprom_scl_dr = P3^7; /*時鐘線*/
sbit eeprom_sda_dr_sr = P3^6; /*資料的輸出線和輸入線*/
unsigned char ucKeySec = 0; /*被觸發的按鍵編號*/
unsigned int uiKeyTimeCnt1 = 0; /*按鍵去抖動延時計數器*/
unsigned char ucKeyLock1 = 0; /*按鍵觸發後自鎖的變數標誌*/
unsigned int uiKeyTimeCnt2 = 0; /*按鍵去抖動延時計數器*/
unsigned char ucKeyLock2 = 0; /*按鍵觸發後自鎖的變數標誌*/
unsigned int uiKeyTimeCnt3 = 0; /*按鍵去抖動延時計數器*/
unsigned char ucKeyLock3 = 0; /*按鍵觸發後自鎖的變數標誌*/
unsigned int uiVoiceCnt = 0; /*蜂鳴器鳴叫的持續時間計數器*/
unsigned char ucVoiceLock = 0; /*蜂鳴器鳴叫的原子鎖*/
unsigned char ucDigShow8; /*第8位數碼管要顯示的內容*/
unsigned char ucDigShow7; /*第7位數碼管要顯示的內容*/
unsigned char ucDigShow6; /*第6位數碼管要顯示的內容*/
unsigned char ucDigShow5; /*第5位數碼管要顯示的內容*/
unsigned char ucDigShow4; /*第4位數碼管要顯示的內容*/
unsigned char ucDigShow3; /*第3位數碼管要顯示的內容*/
unsigned char ucDigShow2; /*第2位數碼管要顯示的內容*/
unsigned char ucDigShow1; /*第1位數碼管要顯示的內容*/
unsigned char ucDigDot8; /*數碼管8的小數點是否顯示的標誌*/
unsigned char ucDigDot7; /*數碼管7的小數點是否顯示的標誌*/
unsigned char ucDigDot6; /*數碼管6的小數點是否顯示的標誌*/
unsigned char ucDigDot5; /*數碼管5的小數點是否顯示的標誌*/
unsigned char ucDigDot4; /*數碼管4的小數點是否顯示的標誌*/
unsigned char ucDigDot3; /*數碼管3的小數點是否顯示的標誌*/
unsigned char ucDigDot2; /*數碼管2的小數點是否顯示的標誌*/
unsigned char ucDigDot1; /*數碼管1的小數點是否顯示的標誌*/
unsigned char ucDigShowTemp = 0; /*臨時中間變數*/
unsigned char ucDisplayDriveStep = 1; /*動態掃描數碼管的步驟變數*/
unsigned char ucWd1Update = 1; /*視窗1更新顯示標誌*/
unsigned char ucWd2Update = 0; /*視窗2更新顯示標誌*/
unsigned char ucWd3Update = 0; /*視窗3更新顯示標誌*/
unsigned char ucWd4Update = 0; /*視窗4更新顯示標誌*/
unsigned char ucWd = 1; /*本程式的核心變數,視窗顯示變數。類似於一級選單的變數。代表顯示不同的視窗。*/
unsigned int uiSetData1 = 0; /*本程式中需要被設定的引數1*/
unsigned int uiSetData2 = 0; /*本程式中需要被設定的引數2*/
unsigned int uiSetData3 = 0; /*本程式中需要被設定的引數3*/
unsigned int uiSetData4 = 0; /*本程式中需要被設定的引數4*/
unsigned char ucTemp1 = 0; /*中間過渡變數*/
unsigned char ucTemp2 = 0; /*中間過渡變數*/
unsigned char ucTemp3 = 0; /*中間過渡變數*/
unsigned char ucTemp4 = 0; /*中間過渡變數*/
unsigned char ucDelayTimerLock = 0; /* 原子鎖 */
unsigned int uiDelayTimer = 0;
unsigned char ucCheckEeprom = 0; /* 檢查EEPROM晶片是否正常 */
unsigned char ucEepromError = 0; /* EEPROM晶片是否正常的標誌 */
unsigned char ucEepromLock = 0; /* 原子鎖 */
unsigned int uiEepromCnt = 0; /* 間歇性蜂鳴器報警的計時器 */
void Dig_Hc595_Drive(unsigned char, unsigned char);
/*根據原理圖得出的共陰數碼管字模表*/
code unsigned char Dig_Table[] =
{
0x3f, /*0 序號0*/
0x06, /*1 序號1*/
0x5b, /*2 序號2*/
0x4f, /*3 序號3*/
0x66, /*4 序號4*/
0x6d, /*5 序號5*/