第十三届“蓝桥杯”单片机省赛——程序设计题
在比赛时候编写,代码仅供参考
如有不足,多多指教
1.题目
2.代码
main.c程序
#include "reg52.h"
#include "onewire.h"
#include "ds1302.h"
#define uchar unsigned char
#define uint unsigned int
//==============================参数定义
uchar read[7] = {0x81,0x83,0x85,0x87,0x89,0x8b,0x8d};
uchar write[7] = {0x80,0x82,0x84,0x86,0x88,0x8a,0x8c};
uchar time[7] = {0x40,0x59,0x22,0x00,0x00,0x00,0x00};//22时59分40秒
uchar code smg[] = {0xC0,0xF9,0xA4,0xB0,0x99,0x92,0x82,0xF8,0x80,0x90,0xc1,0xff,0x40,0x79,0x24,0x30,0x19,0x12,0x02,0x78,0x00,0x10,0xbf};
// 0 1 2 3 4 5 6 7 8 9 U 灭 0. 1. 2. 3. 4. 5. 6. 7. 8. 9. -
sbit c1 = P3^2;
sbit c2 = P3^3;
sfr AUXR = 0X8E;
uchar jiemian = 0;//温度显示界面 0 时间显示界面1(显示 时 分) 参数设置界面 2 时间显示界面3(显示 分 秒)(在s17按下的时候)
uchar moshi = 0;//温度控制 0 时间控制 1
uchar wengducanshu = 23;//温度参数初始化23 范围为10-99
unsigned short tempr;//用来存放实时温度(比如255是25.5摄氏度)
uchar flag = 0;
uchar flag1 = 0;
uchar count = 0;//用于计时(时间控制模式)5s
uchar count1 = 0;//用于计时(温度控制模式)无限闪烁(只要温度参数小于实际温度)
uchar xihe = 0;//继电器吸合(时间控制模式)标志位
uchar xihe1 = 0;//继电器吸合(温度控制模式)标志位
uchar led = 0;//led1亮标志位(仅在整点)
//==============================函数声明
void select(uchar channel);
void cls_sth();
void key_scan();
void smg_delay(uint time);
void smg_dis(uchar pos,uchar val);
void smg_all_off();
void smg_show();
void read_time();
void set_time();
void relay_show();
void Timer0Init(void); //50毫秒@12.000MHz
void led_show();
//==============================主函数
void main()
{
cls_sth();
set_time();
Timer0Init();
while(1)
{
tempr = rd_temperature();
relay_show();
led_show();
read_time();
key_scan();
smg_show();
}
}
//==============================初始化函数
void select(uchar channel)
{
switch(channel)
{
case 4 : P2 = (P2 & 0X1F) | 0X80;break;
case 5 : P2 = (P2 & 0X1F) | 0Xa0;break;
case 6 : P2 = (P2 & 0X1F) | 0Xc0;break;
case 7 : P2 = (P2 & 0X1F) | 0Xe0;break;
case 0 : P2 = (P2 & 0X1F) | 0X00;break;
}
}
void cls_sth()
{
select(4);
P0 = 0XFF;
select(5);
P0 &= 0xaf;
select(6);
P0 = 0XFF;
select(7);
P0 = 0XFF;
select(0);
}
//================================按键扫描函数
void key_scan()
{
P3 = (P3 & 0XDF) | 0X10;
c1 = c2 = 1;
if(c2 == 0)//s12按下
{
smg_show();
if(c2 == 0)
{
while(c2 == 0)
{
smg_show();
led_show();
}
switch(jiemian)
{
case 0 : jiemian = 1;break;
case 1 : jiemian = 2;break;
case 2 : jiemian = 0;break;
}
}
}
else if(c1 == 0)//s13按下
{
smg_show();
if(c1 == 0)
{
while(c1 == 0)
{
smg_show();
led_show();
}
switch(moshi)
{
case 0 : moshi = 1;break;
case 1 : moshi = 0;break;
}
}
}
P3 = (P3 & 0XeF) | 0X20;
c1 = c2 = 1;
if(c2 == 0)//s16按下
{
smg_show();
if(c2 == 0)
{
while(c2 == 0)
{
smg_show();
led_show();
}
if(jiemian == 2)
{
if(wengducanshu + 1 >99)
{
wengducanshu = 99;
}
else
{
wengducanshu += 1;
}
}
}
}
else if(c1 == 0)//s17按下
{
smg_show();
if(c1 == 0)
{
if(jiemian == 2)
{
while(c1 == 0)
{
smg_show();
led_show();
}
if(wengducanshu - 1 <10)
{
wengducanshu = 10;
}
else
{
wengducanshu -= 1;
}
}
else if(jiemian == 1)
{
while(c1 == 0)
{
jiemian = 3;
read_time();
relay_show();
led_show();
smg_show();
}
jiemian = 1;
}
}
}
}
//===================================数码管显示函数
void smg_delay(uint time)
{
while(time--);
}
void smg_dis(uchar pos,uchar val)
{
select(7);
P0 = 0XFF;
select(6);
P0 = 0x01 << pos;
select(7);
P0 = smg[val];
select(0);
smg_delay(500);
}
void smg_all_off()
{
select(7);
P0 = 0XFF;
select(6);
P0 = 0xff;
select(7);
P0 = 0xff;
select(0);
smg_delay(500);
}
void smg_show()
{
if(jiemian == 0)
{
smg_dis(0,10);
smg_dis(1,1);
smg_dis(2,11);
smg_dis(3,11);
smg_dis(4,11);
smg_dis(5,tempr/100);
smg_dis(6,tempr/10%10+12);
smg_dis(7,tempr%10);
smg_all_off();
}
else if(jiemian == 1)
{
smg_dis(0,10);
smg_dis(1,2);
smg_dis(2,11);
smg_dis(3,time[2]/16);
smg_dis(4,time[2]%16);
smg_dis(5,22);
smg_dis(6,time[1]/16);
smg_dis(7,time[1]%16);
smg_all_off();
}
else if(jiemian == 2)
{
smg_dis(0,10);
smg_dis(1,3);
smg_dis(2,11);
smg_dis(3,11);
smg_dis(4,11);
smg_dis(5,11);
smg_dis(6,wengducanshu/10);
smg_dis(7,wengducanshu%10);
smg_all_off();
}
else if(jiemian == 3)
{
smg_dis(0,10);
smg_dis(1,2);
smg_dis(2,11);
smg_dis(3,time[1]/16);
smg_dis(4,time[1]%16);
smg_dis(5,22);
smg_dis(6,time[0]/16);
smg_dis(7,time[0]%16);
smg_all_off();
}
}
//================================获取和写入时间函数
void read_time()
{
char i;
for(i = 0;i<7;i++)
{
time[i] = Read_Ds1302_Byte(read[i]);
}
}
void set_time()
{
char i;
Write_Ds1302_Byte(0x8e,0x00);
for(i = 0;i<7;i++)
{
Write_Ds1302_Byte(write[i],time[i]);
}
Write_Ds1302_Byte(0x8e,0x80);
}
//=================================继电器控制函数
void relay_show()
{
if(moshi == 0)
{
if(tempr > ((unsigned short)wengducanshu*10))
{
xihe1 = 1;
select(5);
P0 = (P0 & 0XAF) | 0X10;
select(0);
}
else
{
xihe1 = 0;
select(5);
P0 = P0 & 0XAF;
select(0);
}
}
else if(moshi == 1)
{
read_time();
if((time[0] == 0x00 && time[1] == 0x00) || xihe == 1)
{
xihe = 1;
if(xihe == 1)
{
select(5);
P0 = (P0 & 0XAF) | 0X10;
select(0);
}
else if(xihe == 0)
{
select(5);
P0 = P0 & 0XAF;
select(0);
}
}
else if(time[0] != 0x00 || time[1] != 0x00)
{
select(5);
P0 = P0 & 0XAF;
select(0);
}
}
}
//==================================定时器函数
void Timer0Init(void) //50毫秒@12.000MHz
{
AUXR &= 0x7F; //定时器时钟12T模式
TMOD &= 0xF0; //设置定时器模式
TL0 = 0xB0; //设置定时初始值
TH0 = 0x3C; //设置定时初始值
TF0 = 0; //清除TF0标志
ET0 = EA = 1;
TR0 = 1; //定时器0开始计时
}
void timer0_ser() interrupt 1
{
if(xihe == 1 || led == 1)
{
flag++;
if(flag%2 == 0)
{
count++;
if(count == 50)
{
led = 0;
xihe = 0;
count = 0;
flag = 0;
}
}
}
if(xihe1 ==1)
{
flag1++;
if(flag1%2 == 0)
{
count1++;
if(count1 == 50)
{
xihe1 = 1;
count1 = 0;
flag1 = 0;
}
}
}
}
//===================================LED函数
void led_show()
{
read_time();
if(time[0] == 0x00 && time[1] == 0x00 || led == 1)//led1亮
{
led = 1;
if(led == 1)
{
select(4);
P0 = (P0 & 0xfe) | 0Xf8;
select(0);
}
else if(led == 0)
{
select(4);
P0 |= 0xf9;
select(0);
}
}
else
{
select(4);
P0 |= 0xf9;
select(0);
}
if(moshi == 0)
{
select(4);
P0 = (P0 & 0XFD) | 0XF8;
select(0);
}
else
{
select(4);
P0 |= 0xfa;
select(0);
}
if((moshi == 1) && xihe == 1)
{
if(count%2 == 1)
{
select(4);
P0 = (P0 & 0XFB) | 0XF8;
select(0);
}
else if(count%2 == 0)
{
select(4);
P0 |= 0xfc;
select(0);
}
}
else if((moshi == 0) && xihe1 == 1)
{
if(count1%2 == 1)
{
select(4);
P0 = (P0 & 0XFB) | 0XF8;
select(0);
}
else if(count1%2 == 0)
{
select(4);
P0 |= 0xfc;
select(0);
}
}
else
{
select(4);
P0 |= 0xfc;
select(0);
}
}
onewire.c程序
#include "onewire.h"
//单总线内部延时函数
uchar i;
void Delay_OneWire(unsigned int t)
{
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(20);
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(20);
}
return dat;
}
//DS18B20初始化
bit init_ds18b20(void)
{
bit initflag = 0;
// DQ = 1;
// Delay_OneWire(12);
DQ = 0;
Delay_OneWire(200);
DQ = 1;
Delay_OneWire(20);
initflag = DQ;
Delay_OneWire(100);
return initflag;
}
//===============================温度读取函数
unsigned short rd_temperature()
{
uchar lsb,msb;
unsigned short temp = 0x0000;
init_ds18b20();
Write_DS18B20(0xcc);
Write_DS18B20(0x44);
Delay_OneWire(200);
init_ds18b20();
Write_DS18B20(0xcc);
Write_DS18B20(0xbe);
lsb = Read_DS18B20();
msb = Read_DS18B20();
init_ds18b20();
temp = msb;
temp = (temp << 8) | lsb;
if((temp & 0xf800) == 0x0000)
{
temp >>= 4;
temp = temp *10;
temp = temp + (lsb & 0x0f)*0.0625*10;
}
return temp;
}
onewire.h程序
#ifndef __ONEWIRE_H
#define __ONEWIRE_H
#include "reg52.h"
sbit DQ = P1^4;
unsigned short rd_temperature();
bit init_ds18b20(void);
unsigned char Read_DS18B20(void);
void Write_DS18B20(unsigned char dat);
void Delay_OneWire(unsigned int t);
#endif
ds1302.c程序
#include "ds1302.h"
//写字节
void Write_Ds1302(unsigned char temp)
{
unsigned char i;
for (i=0;i<8;i++)
{
SCK = 0;
SDA = temp&0x01;
temp>>=1;
SCK=1;
}
}
//向DS1302寄存器写入数据
void Write_Ds1302_Byte( unsigned char address,unsigned char dat )
{
RST=0; _nop_();
SCK=0; _nop_();
RST=1; _nop_();
Write_Ds1302(address);
Write_Ds1302(dat);
RST=0;
}
//从DS1302寄存器读出数据
unsigned char Read_Ds1302_Byte ( unsigned char address )
{
unsigned char i,temp=0x00;
RST=0; _nop_();
SCK=0; _nop_();
RST=1; _nop_();
Write_Ds1302(address);
for (i=0;i<8;i++)
{
SCK=0;
temp>>=1;
if(SDA)
temp|=0x80;
SCK=1;
}
RST=0; _nop_();
SCK=0; _nop_();
SCK=1; _nop_();
SDA=0; _nop_();
SDA=1; _nop_();
return (temp);
}
ds1302.h程序
#ifndef __DS1302_H
#define __DS1302_H
#include <reg52.h>
#include <intrins.h>
sbit SCK = P1^7;
sbit SDA = P2^3;
sbit RST = P1^3;
void Write_Ds1302(unsigned char temp);
void Write_Ds1302_Byte( unsigned char address,unsigned char dat );
unsigned char Read_Ds1302_Byte( unsigned char address );
#endif
比赛期间编写,如有不足,请多多指教!