文章目录
- 比赛题目
- 一、代码相关定义、声明
- 1.头文件声明
- 2.变量声明
- 二、主要函数
- 1.main函数
- 2.按键扫描
- 3.数码管显示
- 4.LED显示
- 5.定时器中断
- 三、次要函数
- 1.初始化函数Init
- 2.按键函数Key
- 3.LED函数Led
- 4.数码管函数Seg
- 5.iic函数中
- 6.onewire函数中
- 总结
比赛题目
这里因为我没有这个题目的pdf版本所以截取的是博主:是七喜呀!这个博主大大的,侵权删!
一、代码相关定义、声明
1.头文件声明
/* 头文件声明区 */
#include <STC15F2K60S2.H>//单片机寄存器专用头文件
#include <Init.h>//初始化底层驱动专用头文件
#include <Led.h>//Led底层驱动专用头文件
#include <Key.h>//按键底层驱动专用头文件
#include <Seg.h>//数码管底层驱动专用头文件
#include "onewire.h"
#include "iic.h"
2.变量声明
/* 变量声明区 */
unsigned char Key_Val,Key_Down,Key_Old,Key_Up;//按键专用变量
unsigned char Key_Slow_Down;//按键减速专用变量
unsigned char Seg_Buf[8] = {10,10,10,10,10,10,10,10};//数码管显示数据存放数组
unsigned char Seg_Point[8] = {0,0,0,0,0,0,0,0};//数码管小数点数据存放数组
unsigned char Seg_Pos;//数码管扫描专用变量
unsigned int Seg_Slow_Down;//数码管减速专用变量
unsigned char ucLed[8] = {0,0,0,0,0,0,0,0};//Led显示数据存放数组
unsigned char Seg_Disp_Mode;//0-频率显示界面 1-电压显示界面
unsigned int Freq;//实施频率
unsigned int Timer_1000Ms;//计时变量
float Volate;//实时电压
bit Output_Mode;//电压输出状态
float Volate_Out;//输出电压
bit Led_Flag = 1;//LED状态
bit Seg_Flag = 1;//数码管状态
二、主要函数
1.main函数
/* Main */
void main()
{
System_Init();
Timer1_Init();
Timer0Init();
while (1)
{
Key_Proc();
Seg_Proc();
Led_Proc();
}
}
2.按键扫描
/* 键盘处理函数 */
void Key_Proc()
{
if(Key_Slow_Down) return;
Key_Slow_Down = 1;//键盘减速程序
Key_Val = Key_Read();//实时读取键码值
Key_Down = Key_Val & (Key_Old ^ Key_Val);//捕捉按键下降沿
Key_Up = ~Key_Val & (Key_Old ^ Key_Val);//捕捉按键上降沿
Key_Old = Key_Val;//辅助扫描变量
switch(Key_Down)
{
case 4:
Seg_Disp_Mode ^= 1;
break;
case 5:
Output_Mode ^= 1;
break;
case 6:
Led_Flag ^= 1;
break;
case 7:
Seg_Flag ^= 1;
break;
}
}
3.数码管显示
/* 信息处理函数 */
void Seg_Proc()
{
unsigned char i = 3;
if(Seg_Slow_Down) return;
Seg_Slow_Down = 1;//数码管减速程序
Volate = Ad_Read(0x43) / 51.0;
if(Output_Mode == 0)
Volate_Out = 2;
else Volate_Out = Volate;
switch(Seg_Disp_Mode)
{
case 0:
Seg_Buf[0] = 11;
Seg_Buf[3] = Freq / 10000 % 10;
Seg_Buf[4] = Freq / 1000 % 10;
Seg_Buf[5] = Freq / 100 % 10;
Seg_Buf[6] = Freq / 10 % 10;
Seg_Buf[7] = Freq % 10;
Seg_Point[5] = 0;
while(Seg_Buf[i] == 0)
{
Seg_Buf[i] = 10;
if(++i == 7) break;
}
break;
case 1:
Seg_Buf[0] = 12;
Seg_Buf[3] = 10;
Seg_Buf[4] = 10;
Seg_Buf[5] = (unsigned char)Volate;
Seg_Buf[6] = (unsigned int)(Volate * 100) / 10 % 10;
Seg_Buf[7] = (unsigned int)(Volate * 100) % 10;
Seg_Point[5] = 1;
break;
}
}
4.LED显示
/* 其他显示函数 */
void Led_Proc()
{
unsigned char i = 0;
Da_Write(Volate_Out * 51);
for(i = 0 ; i < 2 ; ++ i)
ucLed[i] = (i == Seg_Disp_Mode);
ucLed[2] = ((Volate >= 1.5 && Volate < 2.5) || (Volate >= 3.5));
ucLed[3] = ((Freq >= 1000 && Freq < 5000) || (Freq >= 10000));
ucLed[4] = Output_Mode;
}
5.定时器中断
/* 定时器0中断初始化函数 */
void Timer0Init(void) //0毫秒@12.000MHz
{
AUXR &= 0x7F; //定时器时钟12T模式
TMOD &= 0xF0; //设置定时器模式
TMOD |= 0x05;
TL0 = 0x00; //设置定时初始值
TH0 = 0x00; //设置定时初始值
TF0 = 0; //清除TF0标志
TR0 = 1; //定时器0开始计时
}
void Timer1_Init(void) //1毫秒@12.000MHz
{
AUXR &= 0xBF; //定时器时钟12T模式
TMOD &= 0x0F; //设置定时器模式
TL1 = 0x18; //设置定时初始值
TH1 = 0xFC; //设置定时初始值
TF1 = 0; //清除TF1标志
TR1 = 1; //定时器1开始计时
ET1 = 1;
EA = 1;
}
/* 定时器0中断服务函数 */
void Timer0Server() interrupt 3
{
if(++Key_Slow_Down == 10) Key_Slow_Down = 0;//键盘减速专用
if(++Seg_Slow_Down == 500) Seg_Slow_Down = 0;//数码管减速专用
if(++Seg_Pos == 8) Seg_Pos = 0;//数码管显示专用
if(Seg_Flag == 1)
Seg_Disp(Seg_Pos,Seg_Buf[Seg_Pos],Seg_Point[Seg_Pos]);
else
Seg_Disp(Seg_Pos,10,0);
if(Led_Flag == 1)
Led_Disp(Seg_Pos,ucLed[Seg_Pos]);
else Led_Disp(Seg_Pos,0);
if(++Timer_1000Ms == 1000)
{
Timer_1000Ms = 0;
Freq = TH0 << 8 | TL0;
TH0 = TL0 = 0;
}
}
三、次要函数
1.初始化函数Init
在Init.c文件当中
#include <Init.h>
void System_Init()
{
P0 = 0xff;
P2 = P2 & 0x1f | 0x80;
P2 &= 0x1f;
P0 = 0x00;
P2 = P2 & 0x1f | 0xa0;
P2 &= 0x1f;
}
在Init.h文件当中
#include <STC15F2K60S2.H>
void System_Init();
2.按键函数Key
在Key.c文件当中
#include <Key.h>
/*
unsigned char Key_Read()
{
unsigned char temp = 0;
P44 = 0;P42 = 1;P35 = 1;P34 = 1;
if(P33 == 0) temp = 4;
if(P32 == 0) temp = 5;
if(P31 == 0) temp = 6;
if(P30 == 0) temp = 7;
P44 = 1;P42 = 0;P35 = 1;P34 = 1;
if(P33 == 0) temp = 8;
if(P32 == 0) temp = 9;
if(P31 == 0) temp = 10;
if(P30 == 0) temp = 11;
P44 = 1;P42 = 1;P35 = 0;P34 = 1;
if(P33 == 0) temp = 12;
if(P32 == 0) temp = 13;
if(P31 == 0) temp = 14;
if(P30 == 0) temp = 15;
P44 = 1;P42 = 1;P35 = 1;P34 = 0;
if(P33 == 0) temp = 16;
if(P32 == 0) temp = 17;
if(P31 == 0) temp = 18;
if(P30 == 0) temp = 19;
return temp;
}
*/
unsigned char Key_Read()
{
unsigned char temp = 0;
if(P33 == 0) temp = 4;
if(P32 == 0) temp = 5;
if(P31 == 0) temp = 6;
if(P30 == 0) temp = 7;
return temp;
}
在Key.h文件当中
#include <STC15F2K60S2.H>
unsigned char Key_Read();
3.LED函数Led
#include <Led.h>
void Led_Disp(unsigned char addr,enable)
{
static unsigned char temp = 0x00;
static unsigned char temp_old = 0xff;
if(enable)
temp |= 0x01 << addr;
else
temp &= ~(0x01 << addr);
if(temp != temp_old)
{
P0 = ~temp;
P2 = P2 & 0x1f | 0x80;
P2 &= 0x1f;
temp_old = temp;
}
}
void Beep(unsigned char flag)
{
static unsigned char temp = 0x00;
static unsigned char temp_old = 0xff;
if(flag)
temp |= 0x40;
else
temp &= ~0x40;
if(temp != temp_old)
{
P0 = temp;
P2 = P2 & 0x1f | 0xa0;
P2 &= 0x1f;
temp_old = temp;
}
}
void Relay(unsigned char flag)
{
static unsigned char temp = 0x00;
static unsigned char temp_old = 0xff;
if(flag)
temp |= 0x10;
else
temp &= ~0x10;
if(temp != temp_old)
{
P0 = temp;
P2 = P2 & 0x1f | 0xa0;
P2 &= 0x1f;
temp_old = temp;
}
}
4.数码管函数Seg
#include <Seg.h>
unsigned char seg_dula[] = {0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90,0xff,0xc6,0x8c,0x88};
unsigned char seg_wela[] = {0x01,0x02,0x04,0x08,0x10,0x20,0x40,0x80};
void Seg_Disp(unsigned char wela,dula,point)
{
P0 = 0xff;
P2 = P2 & 0x1f | 0xe0;
P2 &= 0x1f;
P0 = seg_wela[wela];
P2 = P2 & 0x1f | 0xc0;
P2 &= 0x1f;
P0 = seg_dula[dula];
if(point)
P0 &= 0x7f;
P2 = P2 & 0x1f | 0xe0;
P2 &= 0x1f;
}
5.iic函数中
/* # I2C代码片段说明
1. 本文件夹中提供的驱动代码供参赛选手完成程序设计参考。
2. 参赛选手可以自行编写相关代码或以该代码为基础,根据所选单片机类型、运行速度和试题
中对单片机时钟频率的要求,进行代码调试和修改。
*/
#include "iic.h"
#define DELAY_TIME 5
//
static void I2C_Delay(unsigned char n)
{
do
{
_nop_();_nop_();_nop_();_nop_();_nop_();
_nop_();_nop_();_nop_();_nop_();_nop_();
_nop_();_nop_();_nop_();_nop_();_nop_();
}
while(n--);
}
//
void I2CStart(void)
{
sda = 1;
scl = 1;
I2C_Delay(DELAY_TIME);
sda = 0;
I2C_Delay(DELAY_TIME);
scl = 0;
}
//
void I2CStop(void)
{
sda = 0;
scl = 1;
I2C_Delay(DELAY_TIME);
sda = 1;
I2C_Delay(DELAY_TIME);
}
//
void I2CSendByte(unsigned char byt)
{
unsigned char i;
for(i=0; i<8; i++){
scl = 0;
I2C_Delay(DELAY_TIME);
if(byt & 0x80){
sda = 1;
}
else{
sda = 0;
}
I2C_Delay(DELAY_TIME);
scl = 1;
byt <<= 1;
I2C_Delay(DELAY_TIME);
}
scl = 0;
}
//
unsigned char I2CReceiveByte(void)
{
unsigned char da;
unsigned char i;
for(i=0;i<8;i++){
scl = 1;
I2C_Delay(DELAY_TIME);
da <<= 1;
if(sda)
da |= 0x01;
scl = 0;
I2C_Delay(DELAY_TIME);
}
return da;
}
//
unsigned char I2CWaitAck(void)
{
unsigned char ackbit;
scl = 1;
I2C_Delay(DELAY_TIME);
ackbit = sda;
scl = 0;
I2C_Delay(DELAY_TIME);
return ackbit;
}
//
void I2CSendAck(unsigned char ackbit)
{
scl = 0;
sda = ackbit;
I2C_Delay(DELAY_TIME);
scl = 1;
I2C_Delay(DELAY_TIME);
scl = 0;
sda = 1;
I2C_Delay(DELAY_TIME);
}
//=========================
unsigned char Ad_Read(unsigned char addr)
{
unsigned char temp;
I2CStart();
I2CSendByte(0x90);
I2CWaitAck();
I2CSendByte(addr);
I2CWaitAck();
I2CStart();
I2CSendByte(0x91);
I2CWaitAck();
temp = I2CReceiveByte();
I2CSendAck(1);
I2CStop();
return temp;
}
void Da_Write(unsigned char dat)
{
I2CStart();
I2CSendByte(0x90);
I2CWaitAck();
I2CSendByte(0x41);
I2CWaitAck();
I2CSendByte(dat);
I2CWaitAck();
I2CStop();
}
6.onewire函数中
/* # 单总线代码片段说明
1. 本文件夹中提供的驱动代码供参赛选手完成程序设计参考。
2. 参赛选手可以自行编写相关代码或以该代码为基础,根据所选单片机类型、运行速度和试题
中对单片机时钟频率的要求,进行代码调试和修改。
*/
#include <reg52.h>
sbit DQ = P1^4;
//
void Delay_OneWire(unsigned int t)
{
unsigned char i;
while(t--){
for(i=0;i<12;i++);
}
}
//
void Write_DS18B20(unsigned char dat)
{
unsigned char i;
for(i=0;i<8;i++)
{
DQ = 0;
DQ = dat&0x01;
Delay_OneWire(5);
DQ = 1;
dat >>= 1;
}
Delay_OneWire(5);
}
//
unsigned char Read_DS18B20(void)
{
unsigned char i;
unsigned char dat;
for(i=0;i<8;i++)
{
DQ = 0;
dat >>= 1;
DQ = 1;
if(DQ)
{
dat |= 0x80;
}
Delay_OneWire(5);
}
return dat;
}
//
bit init_ds18b20(void)
{
bit initflag = 0;
DQ = 1;
Delay_OneWire(12);
DQ = 0;
Delay_OneWire(80);
DQ = 1;
Delay_OneWire(10);
initflag = DQ;
Delay_OneWire(5);
return initflag;
}
//========================
float rd_temperature(void)
{
unsigned char low,high;//返回温度的高低八位
init_ds18b20();//初始化
Write_DS18B20(0xcc);//跳过ROM
Write_DS18B20(0x44);//进行温度转换
init_ds18b20();//初始化
Write_DS18B20(0xcc);//跳过ROM
Write_DS18B20(0xbe);//读取温度
low = Read_DS18B20();//读取低位
high = Read_DS18B20();//读取高位
return ((high << 8) | low ) / 16.0;
}
总结
1.主要学习了AD的读取—AD_Read(0x43)/ 51;
然后输出则是Da_Write(Volate_Out * 51);
2.然后就是NE555的配置方法
//将原本的数据改成这个样子其实就是TMOD |= 0x05要被加入
void Timer0Init(void) //0毫秒@12.000MHz
{
AUXR &= 0x7F; //定时器时钟12T模式
TMOD &= 0xF0; //设置定时器模式
TMOD |= 0x05;
TL0 = 0x00; //设置定时初始值
TH0 = 0x00; //设置定时初始值
TF0 = 0; //清除TF0标志
TR0 = 1; //定时器0开始计时
}
//生成的是12T自动重装载的1毫秒的定时器1的定时器
void Timer1_Init(void) //1毫秒@12.000MHz
{
AUXR &= 0xBF; //定时器时钟12T模式
TMOD &= 0x0F; //设置定时器模式
TL1 = 0x18; //设置定时初始值
TH1 = 0xFC; //设置定时初始值
TF1 = 0; //清除TF1标志
TR1 = 1; //定时器1开始计时
ET1 = 1;
EA = 1;
}
void Timer0Server() interrupt 3//这里修改成3
写在定时器三里面
if(++Timer_1000Ms == 1000)
{
Timer_1000Ms = 0;
Freq = TH0 << 8 | TL0;
TH0 = TL0 = 0;
}