文章目录
- 比赛题目
- 一、代码相关定义、声明
- 1.头文件声明
- 2.变量声明
- 二、主要函数
- 1.main函数
- 2.按键扫描
- 3.数码管显示
- 4.电压模式1、2输出 & LED显示
- 5.定时器中断
- 6.消除85°C显示
- 三、次要函数
- 1.初始化函数Init
- 2.按键函数Key
- 3.LED函数Led
- 4.数码管函数Seg
- 5.iic函数中
- 6.onewire函数中
比赛题目
一、代码相关定义、声明
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-参数设置 2-DA输出
float Temperature;//实时温度变量
unsigned char Seg_temp_Disp = 25;//显示参数
unsigned char Seg_temp_contorl = 25;//参数控制
float Volat;//AD
bit Out_Put;//AD模式转换变量
二、主要函数
1.main函数
/* Main */
void main()
{rd_temperature();Delay750ms();System_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:if(++Seg_Disp_Mode == 3) Seg_Disp_Mode = 0;if(Seg_Disp_Mode == 1) Seg_temp_Disp = Seg_temp_contorl;if(Seg_Disp_Mode == 2) Seg_temp_contorl = Seg_temp_Disp;break;case 8:if(Seg_Disp_Mode == 1){if(--Seg_temp_Disp == 255) Seg_temp_Disp = 0;}break;case 9:if(Seg_Disp_Mode == 1){if(++Seg_temp_Disp == 100) Seg_temp_Disp = 99;}break;case 5:Out_Put ^= 1;break;}
}
3.数码管显示
/* 信息处理函数 */
void Seg_Proc()
{if(Seg_Slow_Down) return;Seg_Slow_Down = 1;//数码管减速程序//信息获取区域Temperature = rd_temperature();//实时读取温度值Volat = Ad_Read();switch(Seg_Disp_Mode){case 0://温度显示界面Seg_Buf[0] = 11;//CSeg_Buf[4] = (unsigned char)Temperature / 10 % 10;Seg_Buf[5] = (unsigned char)Temperature % 10;Seg_Buf[6] = (unsigned int)(Temperature * 100) / 10 % 10;Seg_Buf[7] = (unsigned int)(Temperature * 100)% 10;Seg_Point[5] = 1;break;case 1:Seg_Buf[0] = 12;//PSeg_Buf[4] = 10;Seg_Buf[5] = 10;Seg_Buf[6] = Seg_temp_Disp / 10 % 10;Seg_Buf[7] = Seg_temp_Disp % 10;Seg_Point[5] = 0;break;case 2:Seg_Buf[0] = 13;//PSeg_Buf[5] = (unsigned char)Volat;Seg_Buf[6] = (unsigned int)(Volat * 100) / 10 % 10;Seg_Buf[7] = (unsigned int)(Volat * 100) % 10;Seg_Point[5] = 1;break;}
}
4.电压模式1、2输出 & LED显示
/* 其他显示函数 */
void Led_Proc()
{unsigned char i = 0;if(Out_Put == 0){if(Temperature < Seg_temp_Disp)Volat = 0;else Volat = 5;}else{if(Temperature < 20)Volat = 1;else if(Temperature > 40)Volat = 4;else Volat = 0.15 * (Temperature - 20) + 1;}Da_Write(Volat * 51);ucLed[0] = !Out_Put;for(i = 0 ; i < 3 ; ++ i)ucLed[i + 1] = (i == Seg_Disp_Mode);
}
5.定时器中断
/* 定时器0中断初始化函数 */
void Timer0Init(void) //1毫秒@12.000MHz
{AUXR &= 0x7F; //定时器时钟12T模式TMOD &= 0xF0; //设置定时器模式TL0 = 0x18; //设置定时初始值TH0 = 0xFC; //设置定时初始值TF0 = 0; //清除TF0标志TR0 = 1; //定时器0开始计时ET0 = 1; //定时器中断0打开EA = 1; //总中断打开
}/* 定时器0中断服务函数 */
void Timer0Server() interrupt 1
{ 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;//数码管显示专用Seg_Disp(Seg_Pos,Seg_Buf[Seg_Pos],Seg_Point[Seg_Pos]);Led_Disp(Seg_Pos,ucLed[Seg_Pos]);
}
6.消除85°C显示
void Delay750ms(void) //@12.000MHz
{unsigned char data i, j, k;i = 35;j = 51;k = 182;do{do{while (--k);} while (--j);} while (--i);
}
三、次要函数
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;elsetemp &= ~(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;elsetemp &= ~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;elsetemp &= ~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);//跳过ROMWrite_DS18B20(0x44);//进行温度转换init_ds18b20();//初始化Write_DS18B20(0xcc);//跳过ROMWrite_DS18B20(0xbe);//读取温度low = Read_DS18B20();//读取低位high = Read_DS18B20();//读取高位return ((high << 8) | low ) / 16.0;
}