注:第六届模拟题即第五届蓝桥杯单片机省赛试题
功能不多,逻辑也非常简单,相信大家一看便很清楚了,直接上程序,里面包含有注释。
main.c程序
#include
#include "ds18b20.h"
#define uchar unsigned char //定义无符号字符类型uchar
#define uint unsigned int //定义无符号整型类型uint
uchar code tab[]={
0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90,0xbf,0xff};//数字0~9,“-”,“关”
uchar yi,er,san,si,wu,liu,qi,ba; //定义字符型变量yi,er,san,si,wu,liu,qi,ba,当作数码管显示控制变量
uchar wendu,qujian=0,num=0,bz=0;
uchar min=20,max=30,tt=0,flog=0,shezhi=0,qingchu=0;
void delayms(int ms); //延时函数
void allinit(); //初始化函数
void keyscan16(); //矩阵按键函数
void display1(uchar yi,uchar er); //第一、二段数码管函数
void display2(uchar san,uchar si); //第三、四段数码管函数
void display3(uchar wu,uchar liu); //第五、六段数码管函数
void display4(uchar qi,uchar ba); //第七、八段数码管函数
void Timer0Init(void); //5毫秒@11.0592MHz
void main()//主函数
{
allinit(); //初始化函数
Timer0Init();
yi=1;er=2;san=3;si=4;wu=5;liu=6;qi=7;ba=8;//让数码管依次显示1~8,用来检验数码管显示函数程序是否有误
while(1)
{
if(shezhi==0) //非设置状态下
{
wendu=Tempget(); //获取温度
if(wendu<min){
qujian=0;P2=0XA0;P0=0X00;} //温度小于设定最小值时在区间0,关继电器
else if((wendu>=min)&&(wendu<=max)){
qujian=1;P2=0XA0;P0=0X00;} //温度大于等于设定最小值且小于等于设定最大值时在区间1,关继电器
if(wendu>max){
qujian=2;P2=0XA0;P0=0X10;} //温度大于设定最大值时在区间2,开继电器
yi=10;er=qujian;san=10;si=11;wu=11;liu=11;qi=wendu/10;ba=wendu%10; //温度显示页面
}
else if(shezhi==1) //判断是否在设置状态下
{
if((er==11)&&(bz==1)) //有按键按下且第二个数码管无显示
{
bz=0;er=num; //把按键标志位清零,然后把按键的值赋给第二个数码管
}
else if((san==11)&&(bz==1)) //有按键按下且第三个数码管无显示
{
bz=0;san=num; //把按键标志位清零,然后把按键的值赋给第三个数码管
}
else if((qi==11)&&(bz==1)) //有按键按下且第七个数码管无显示
{
bz=0;qi=num; //把按键标志位清零,然后把按键的值赋给第七个数码管
}
else if((ba==11)&&(bz==1)) //有按键按下且第八个数码管无显示
{
bz=0;ba=num; //把按键标志位清零,然后把按键的值赋给第八个数码管
if((er*10+san)<(qi*10+ba)){
P2=0X80;P0=0XFD;} //判断设定最大值是否小于设定最小值,是的话L2点亮
else if((er*10+san)>=(qi*10+ba)){
max=er*10+san;min=qi*10+ba;} //判断设定最大值是否大于或等于设定最小值,是的话赋值
}
}
keyscan16(); //矩阵按键函数
display1(yi,er); //第一、二段数码管函数
display2(san,si); //第三、四段数码管函数
display3(wu,liu); //第五、六段数码管函数
display4(qi,ba); //第七、八段数码管函数
}
}
void keyscan16()//矩阵按键函数
{
uchar temp; //定义一个无符号变量temp
P44=0;P42=1;P3=0x7f; //让第一列按键为低电平
temp=P3; //把P3的值赋给temp
temp=temp&0x0f; //把temp的值和0x0f相与,得到的值再赋给temp,依次来判断第一列是否有按键按下
if(temp!=0x0f) //判断第一列是否有按键按下
{
delayms(5); //延时5ms,用来按键消抖
temp=P3; //把P3的值重新赋给temp
temp=temp&0x0f; //把temp的值和0x0f相与,得到的值再赋给temp,依次来判断第一列是否有按键按下
if(temp!=0x0f) //再次判断第一列是否有按键按下
{
temp=P3; //把P3的值重新赋给temp
switch(temp)
{
case 0x7e:num=0;bz=1;break; //第一列第一个按键按下
case 0x7d:num=3;bz=1;break; //第一列第二个按键按下
case 0x7b:num=6;bz=1;break; //第一列第三个按键按下
case 0x77:num=9;bz=1;break; //第一列第四个按键按下
}
while(temp!=0x0f) //无按键按下则进入循环
{
temp=P3; //把P3的值重新赋给temp
temp=temp&0x0f; //把temp的值和0x0f相与,得到的值再赋给temp,依次来判断第一列是否有按键按下
}
}
}
P44=1;P42=0;P3=0xbf; //让第二列按键为低电平
temp=P3; //把P3的值赋给temp
temp=temp&0x0f; //把temp的值和0x0f相与,得到的值再赋给temp,依次来判断第一列是否有按键按下
if(temp!=0x0f) //判断第一列是否有按键按下
{
delayms(5); //延时5ms,用来按键消抖
temp=P3; //把P3的值重新赋给temp
temp=temp&0x0f; //把temp的值和0x0f相与,得到的值再赋给temp,依次来判断第一列是否有按键按下
if(temp!=0x0f) //再次判断第一列是否有按键按下
{
temp=P3; //把P3的值重新赋给temp
switch(temp)
{
case 0xbe:num=1;bz=1;break; //第二列第一个按键按下
case 0xbd:num=4;bz=1;break; //第二列第二个按键按下
case 0xbb:num=7;bz=1;break; //第二列第三个按键按下
case 0xb7:
if(shezhi==0)
{
shezhi=1; //按键按下进入温度设置页面
EA=0;ET0=0;P2=0XA0;P0=0X00;P2=0X80;P0=0XFF; //设置状态下关闭继电器和LED灯
yi=10;er=11;san=11;si=11;wu=11;liu=10;qi=11;ba=11; //显示设置状态页面
}
else if(shezhi==1)
{
shezhi=0; //按键按下进入温度显示页面
EA=1;ET0=1; //开定时器中断
}
break; //第二列第四个按键按下
}
while(temp!=0x0f) //无按键按下则进入循环
{
temp=P3; //把P3的值重新赋给temp
temp=temp&0x0f; //把temp的值和0x0f相与,得到的值再赋给temp,依次来判断第一列是否有按键按下
}
}
}
P44=1;P42=1;P3=0xdf; //让第三列按键为低电平
temp=P3; //把P3的值赋给temp
temp=temp&0x0f; //把temp的值和0x0f相与,得到的值再赋给temp,依次来判断第一列是否有按键按下
if(temp!=0x0f) //判断第一列是否有按键按下
{
delayms(5); //延时5ms,用来按键消抖
temp=P3; //把P3的值重新赋给temp
temp=temp&0x0f; //把temp的值和0x0f相与,得到的值再赋给temp,依次来判断第一列是否有按键按下
if(temp!=0x0f) //再次判断第一列是否有按键按下
{
temp=P3; //把P3的值重新赋给temp
switch(temp)
{
case 0xde:num=2;bz=1;break; //第三列第一个按键按下
case 0xdd:num=5;bz=1;break; //第三列第二个按键按下
case 0xdb:num=8;bz=1;break; //第三列第三个按键按下
case 0xd7:
if(qingchu==0)
{
qingchu=1;
yi=10;er=11;san=11;si=11;wu=11;liu=10;qi=11;ba=11;
}
else if(qingchu==1)
{
qingchu=0;
yi=10;er=11;san=11;si=11;wu=11;liu=10;qi=11;ba=11;
}
break; //第三列第四个按键按下
}
while(temp!=0x0f) //无按键按下则进入循环
{
temp=P3; //把P3的值重新赋给temp
temp=temp&0x0f; //把temp的值和0x0f相与,得到的值再赋给temp,依次来判断第一列是否有按键按下
}
}
}
}
void Timer0Init(void) //5毫秒@11.0592MHz
{
AUXR |= 0x80; //定时器时钟1T模式
TMOD &= 0xF0; //设置定时器模式
TL0 = 0x00; //设置定时初值
TH0 = 0x28; //设置定时初值
TF0 = 0; //清除TF0标志
TR0 = 1; //定时器0开始计时
EA=1;ET0=1; //开定时器中断
}
void time0 () interrupt 1
{
tt++;
if((tt==160)&&(qujian==0)) //判断当前温度是否在区间0,是的话L1以0.8秒为间隔闪烁
{
tt=0;
if(flog==0){
flog=1;P2=0X80;P0=0XFE;}
else if(flog==1){
flog=0;P2=0X80;P0=0XFF;}
}
else if((tt==80)&&(qujian==1)) //判断当前温度是否在区间0,是的话L1以0.4秒为间隔闪烁
{
tt=0;
if(flog==0){
flog=1;P2=0X80;P0=0XFE;}
else if(flog==1){
flog=0;P2=0X80;P0=0XFF;}
}
else if((tt==40)&&(qujian==2)) //判断当前温度是否在区间0,是的话L1以0.2秒为间隔闪烁
{
tt=0;
if(flog==0){
flog=1;P2=0X80;P0=0XFE;}
else if(flog==1){
flog=0;P2=0X80;P0=0XFF;}
}
}
void delayms(int ms)//延时函数
{
uint i,j;
for(i=ms;i>0;i--)
for(j=845;j>0;j--);
}
void allinit()//初始化函数
{
P2=0XA0;P0=0X00; //关闭蜂鸣器继电器
P2=0X80;P0=0XFF; //关闭所有LED灯
P2=0XC0;P0=0XFF; //选中所有数码管段选
P2=0XFF;P0=0XFF; //关闭所有数码管
}
void display1(uchar yi,uchar er)//第一、二段数码管函数
{
P2=0XC0;P0=0X01; //选中第一个数码管位选
P2=0XFF;P0=tab[yi]; //让第一个数码管显示yi指向的值
delayms(1); //延时1ms
P2=0XC0;P0=0X02; //选中第二个数码管位选
P2=0XFF;P0=tab[er]; //让第一个数码管显示er指向的值
delayms(1); //延时1ms
}
void display2(uchar san,uchar si)//第三、四段数码管函数
{
P2=0XC0;P0=0X04; //选中第s三个数码管位选
P2=0XFF;P0=tab[san]; //让第一个数码管显示san指向的值
delayms(1); //延时1ms
P2=0XC0;P0=0X08; //选中第四个数码管位选
P2=0XFF;P0=tab[si]; //让第一个数码管显示si指向的值
delayms(1); //延时1ms
}
void display3(uchar wu,uchar liu)//第五、六段数码管函数
{
P2=0XC0;P0=0X10; //选中第五个数码管位选
P2=0XFF;P0=tab[wu]; //让第一个数码管显示wu指向的值
delayms(1); //延时1ms
P2=0XC0;P0=0X20; //选中第六个数码管位选
P2=0XFF;P0=tab[liu]; //让第一个数码管显示liu指向的值
delayms(1); //延时1ms
}
void display4(uchar qi,uchar ba)//第七、八段数码管函数
{
P2=0XC0;P0=0X40; //选中第七个数码管位选
P2=0XFF;P0=tab[qi]; //让第一个数码管显示qi指向的值
delayms(1); //延时1ms
P2=0XC0;P0=0X80; //选中第八个数码管位选
P2=0XFF;P0=tab[ba]; //让第一个数码管显示ba指向的值
delayms(1); //延时1ms
P2=0XC0;P0=0X80; //选中第八个数码管位选
P2=0XFF;P0=0XFF; //让第八个数码管熄灭
}
ds18b20.c程序
#include
#include "ds18b20.h"
sbit DQ = P1^4; //单总线接口
//单总线延时函数
void Delay_OneWire(unsigned int t)
{
while(t--);
}
//通过单总线向DS18B20写一个字节
void Write_DS18B20(unsigned char dat)
{
unsigned char i;
for(i=0;i<8;i++)
{
DQ = 0;
DQ = dat&0x01;
Delay_OneWire(50);
DQ = 1;
dat >>= 1;
}
Delay_OneWire(50);
}
//从DS18B20读取一个字节
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(50);
}
return dat;
}
//DS18B20设备初始化
bit init_ds18b20(void)
{
bit initflag = 0;
DQ = 1;
Delay_OneWire(120);
DQ = 0;
Delay_OneWire(800);
DQ = 1;
Delay_OneWire(100);
initflag = DQ;
Delay_OneWire(50);
return initflag;
}
unsigned char Tempget()
{
unsigned char low,high,temp;
init_ds18b20();
Write_DS18B20(0xcc);
Write_DS18B20(0x44);
Delay_OneWire(200);
init_ds18b20();
Write_DS18B20(0xcc);
Write_DS18B20(0xbe);
low=Read_DS18B20();
high=Read_DS18B20();
temp=(high<<4);
temp|=(low>>4);
return temp;
}
ds18b20.h程序
#ifndef __DS18B20_H
#define __DS18B20_H
//单总线延时函数
void Delay_OneWire(unsigned int t);
void Write_DS18B20(unsigned char dat);
unsigned char Read_DS18B20(void);
bit init_ds18b20(void);
unsigned char Tempget();
#endif
第五届蓝桥杯单片机省赛作品演示