一、真題



二、模塊構建
1.編寫初始化函數(init.c)?
void Cls_Peripheral(void);
- 關閉led? ? led對應的鎖存器由Y4C控制
- 關閉蜂鳴器和繼電器 由Y5C控制
2.編寫LED函數(led.c)
void Led_Disp(unsigned char ucLed);
-
將ucLed取反的值賦給P0
-
開啟鎖存器
-
關閉鎖存器
3.編寫數碼管函數(seg.c)
void Seg_Tran(unsigned char *pucSeg_Buf,unsigned char *pucSeg_Code);
(1)段碼轉換函數
- 定義數組要加*
- 定義兩個變量i,j
- for循環加Switch語句進行段碼轉換,在資源數據包查找段碼表,并根據題目要求進行段碼轉換
- 注意添加空格代表都不顯示
- case記得加' '
- 判斷是否有 .,是用j+1位判斷
void Seg_Disp(unsigned char *pucSeg_Code,unsigned char ucSeg_Pos);
(2)數碼管顯示函數
- 要對數碼管進行消隱
- 顯示的位置
- 顯示的內容
4.獨立按鍵代碼編寫
unsigned char Key_Read_BTN(void)
- 有返回值函數(unsigned char)
- if語句判斷按鍵是否按下
- 返回按鍵所對應的數字
- 沒有按鍵按下時返回0
5.編寫ADC代碼
unsigned char PCF8591_ADC(unsigned char dat);
- ?定義SCL,SDA
- 添加"intrins.h"頭文件
- 定義變量用于存儲采集的電壓
- 函數定義寫入地址dat,來判斷讀取哪一路
- 寫入流程:開始--發送寫入地址--等待應答--發送dat地址--等待應答
- 讀取流程:開始--發送讀取地址--等待應答--變量接收數據--發送應答--終止
- 讀取地址為0x91 寫入地址為0x90
- 電位器地址為0x43 光敏電阻地址為0x41
?6.編寫頻率代碼
通過TMODE 配置將定時器0配置為計數器,實現頻率讀取
7.編寫定時器代碼
- 將定時器1用作定時器,定時器0作為計數器供NE555使用
- 定時器1為1毫秒定時器,用stc-isp生成,加上ET1=1!!!;
- 定時器0的使用需要對TMOD寄存器進行配置
三、主函數代碼
1.初始化,定時器0,定時器1,中斷總開關,stdio.h
2.編寫數碼管函數
- 數碼管的數組和數字位置定義 12 8 0
- 時間為200ms
- 判斷顯示模式
- 數碼管轉換函數
3.編寫定時器中斷函數
- 所有計時變量自增
- 每2ms數碼管顯示
- 每1s讀取一次頻率并清零
- 將signal和P34引腳短接
4.周期界面
-
周期為頻率的倒數?
-
因為題目要求周期單位為微秒,所以要乘以10的6次方后再除以頻率
-
頻率和周期都定義為unsigned int型
5.編寫按鍵代碼
- 時間為20ms
- 定義兩個按鍵用于消抖
- 調用讀取按鍵函數并賦值給變量Key_Val
- 判斷Key_Val和Key_Val_Old是否相等,相等返回
- Switch語句判斷哪個按鍵按下
- 再將Key_Val的值賦值給?Key_Val_Old
- 按下4按鍵,將Disp_Mode自加對3取模,因為有三個界面
- 當s6,s7按鍵按下時,定義一個新變量用于數據緩存,直接將原來的值賦值給現在的變量
- 對于s7是否長按的處理,將ulms的值賦值給S7_Down,然后在case 0時判斷ulms - S7_Down > 1000,如果是,則直接則執行長按相關命令
6.電壓界面
- 定義兩個變量分別為光敏電阻和滑動變阻器的電壓值
- ?定義ADC_Mode用于切換兩個界面
7.編寫ADC函數
- 時間為200ms
-
在同時讀取兩路ADC時會出現反轉的現象
因此在要求同時采集兩路時,將兩個寫入的數據調換位置
8.所有編寫的函數,一定不要忘記放到主循環里
四、主函數代碼
#include "init.h"
#include "seg.h"
#include "led.h"
#include "key.h"
#include "iic.h"
#include "stdio.h"
#include "tim.h"
//seg
unsigned char pucSeg_Buf[12],pucSeg_Code[8],ucSeg_Pos=0;
//led
unsigned char ucLed=0;
//key
unsigned char Key_Val=0,Key_Val_Old=0;
//ADC
unsigned char ucADC_Res=0,ucADC_Photo=0;
unsigned char ucADC_Res_Buf=255;
//Timer
unsigned long ulms=0;
unsigned long S7_Down=0;
unsigned int uiSeg_Dly=0;
unsigned int uiKey_Dly=0;
unsigned int uiADC_Dly=0;
unsigned int uiLed_Dly=0;
//freq
unsigned int uiFreq=0;
unsigned int uiTime=0;
unsigned int uiFreq_Buf=65535;
//function
void Seg_Proc(void);
void Key_Proc(void);
void ADC_Proc(void);
void Led_Proc(void);
//mode
unsigned char Disp_Mode=0;
unsigned char ADC_Mode=1;
unsigned char Led_Mode = 1;
void main(void)
{Cls_Peripheral();Timer0Init();Timer1Init();EA=1;while(1){Seg_Proc();Key_Proc();ADC_Proc();Led_Proc();}
}
void Led_Proc(void)
{if(uiLed_Dly<200)return;uiLed_Dly=0;if(Led_Mode == 0){ucLed = 0x00;}else{if(ucADC_Res>ucADC_Res_Buf){ucLed|=0x01;}else{ucLed&=~0x01;}if(uiFreq > uiFreq_Buf){ucLed |= 0x02;}else{ucLed &= ~0x02;}if(Disp_Mode == 0){ucLed |= 0x04;ucLed &= ~0x18;}else if(Disp_Mode == 1){ucLed |= 0x08;ucLed &= ~0x14;}else{ucLed |= 0x10;ucLed &= ~0x0C;}Led_Disp(ucLed);}
}
void Seg_Proc(void)
{if(uiSeg_Dly<200)return;uiSeg_Dly=0;if(Disp_Mode==0){sprintf(pucSeg_Buf,"F%7u",uiFreq);}else if(Disp_Mode==1){sprintf(pucSeg_Buf,"N%7u",uiTime);}else {if(ADC_Mode==1){sprintf(pucSeg_Buf,"U-1 %4.2f",ucADC_Photo/51.0);}else{sprintf(pucSeg_Buf,"U-3 %4.2f",ucADC_Res/51.0);}}Seg_Tran(pucSeg_Buf,pucSeg_Code);
}
void Key_Proc(void)
{if(uiKey_Dly<20)return;uiKey_Dly=0;Key_Val=Key_Read_BTN();if(Key_Val==Key_Val_Old)return;switch(Key_Val){case 0:if(Key_Val_Old==7){if(ulms-S7_Down>1000) {Led_Mode=(Led_Mode+1)%2;}else{uiFreq_Buf = uiFreq;}}case 4:Disp_Mode=(Disp_Mode+1)%3;if(Disp_Mode==2){ADC_Mode=1;}break;case 5:if(Disp_Mode==2){if(ADC_Mode==1)ADC_Mode=3;elseADC_Mode=1;}break;case 6:ucADC_Res_Buf=ucADC_Res;break;case 7:S7_Down=ulms;uiFreq_Buf=uiFreq;break;}Key_Val_Old=Key_Val;
}
void ADC_Proc(void)
{if(uiADC_Dly<200)return;uiADC_Dly=0;ucADC_Res=PCF8591_ADC(0x41);ucADC_Photo=PCF8591_ADC(0x43);
}
void Time_1(void) interrupt 3
{ulms++;uiSeg_Dly++;uiKey_Dly++;uiADC_Dly++;uiLed_Dly++;if(ulms%2==0){ucSeg_Pos=(ucSeg_Pos+1)%8;Seg_Disp(pucSeg_Code,ucSeg_Pos);}if(ulms%1000==0){uiFreq=((TH0<<8)|TL0);uiTime=1000000/uiFreq;//以微秒為單位TH0=0;TL0=0;}
}