一、真题



二、模块构建
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.所有编写的函数,一定不要忘记放到主循环里
四、主函数代码
cpp
#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;
else
ADC_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;
}
}