好了,今天一口气写了三年的题,这一周不会再写程序了,该好好复习高数了。
下周周日比赛,等下一周再把国赛题写一下,一个就差不多了。
还是自己最喜欢的那句话:让结局不留遗憾,让过程更加完美。
程序可以直接在这里下载:
main.c
#include
#include "sys.h"
bit flag_200ms = 0;
bit flag_pwm = 0, flag_relay = 0;
bit flag_write = 0;
u8 temper_low = 20, temper_high = 30;
int Real_temper = 0;
void main(void)
{
int tem = 0;
static u8 index = 0;
AllInit();
Timer0Init();
Start18B20();
if(Read_E2PROM(0x02) == 0x23)
{
temper_high = Read_E2PROM(0x00);
temper_low = Read_E2PROM(0x01);
}
EA = 1;
while(1)
{
//读取温度程序
if(flag_200ms)
{
flag_200ms = 0;
Get18B20Temp(&tem);
tem >>= 4; //分离温度整数部分
if((tem > 0) && (tem < 99))
Real_temper = tem;
Start18B20();
if(flag_write)
{
if(index == 0)
Write_E2PROM(0x00, temper_high);
else if(index == 1)
Write_E2PROM(0x01, temper_low);
else if(index == 2)
Write_E2PROM(0x02, 0x23);
else if(index == 3)
flag_write = 0;
index ++;
}
else
index = 0;
}
if(Real_temper > temper_high)
flag_pwm = 1;
else if(Real_temper < temper_low)
flag_relay = 1;
else
{
PWM = 1;
flag_pwm = 0;
flag_relay = 0;
}
KeyPress();
TubeShow();
}
}
sys.c
#include "sys.h"
void AllInit(void)
{
P2 = (P2 & 0x1f) | 0x80;
P0 = 0xff;
P2 = (P2 & 0x1f) | 0xc0;
P0 = 0x00;
P2 = (P2 & 0x1f) | 0xa0;
P0 = 0x00;
P2 = P2 & 0x1f;
}
void Timer0Init(void) //[email protected]
{
AUXR |= 0x80; //定时器时钟1T模式
TMOD &= 0xF0; //设置定时器模式
TL0 = 0xAE; //设置定时初值
TH0 = 0xFB; //设置定时初值
TF0 = 0; //清除TF0标志
TR0 = 1; //定时器0开始计时
ET0 = 1;
}
void Timer0(void) interrupt 1
{
static u16 T0count1 = 0;
static u8 Tocount2 = 0;
static u8 index = 0;
index ++;
T0count1 ++;
Tocount2 ++;
if(T0count1 >= 2000) //200ms
{
T0count1 = 0;
flag_200ms = 1;
}
if(Tocount2 >= 20) //2ms
{
Tocount2 = 0;
KeyScan();
TubeScan();
}
//P34输出PWM控制程序
if(flag_pwm == 1)
{
if(index < 3)
PWM = 1;
else if(index >= 3)
{
PWM = 0;
if(index >= 10)
index = 0;
}
}
else
index = 0;
//继电器控制程序
if(flag_relay)
{
P0 = 0x00;
P2 = (P2 & 0x1f) | 0xa0;
P04 = 1;
P2 = P2 & 0x1f;
}
else
{
P0 = 0x00;
P2 = (P2 & 0x1f) | 0xa0;
P04 = 0;
P2 = P2 & 0x1f;
}
}
sys.h
#ifndef _SYS_H_
#define _SYS_H_
typedef unsigned char u8;
typedef unsigned int u16;
typedef unsigned long u32;
#include
#include
#include "ds18b20.h"
#include "iic.h"
extern bit flag_200ms;
extern bit flag_pwm, flag_relay;
extern bit flag_write;
extern u8 temper_low, temper_high;
extern int Real_temper;
//function
void AllInit(void);
void Timer0Init(void);
void TubeScan(void);
void TubeShow(void);
void KeyScan(void);
void KeyAction(unsigned char key);
void KeyPress(void);
//pin
sbit S7 = P3^0;
sbit S6 = P3^1;
sbit S5 = P3^2;
sbit S4 = P3^3;
sbit PWM = P3^4;
#endif
display.c
#include "sys.h"
unsigned char code table[]={0xc0, 0xf9, 0xa4, 0xb0, 0x99, 0x92, 0x82, 0xf8,
0x80, 0x90, 0x88, 0x83, 0xc6, 0xa1, 0x86, 0x8e,
0xff, 0xbf};
u8 TubeBuff[] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff};
u8 smg1, smg2, smg3, smg4, smg5, smg6, smg7, smg8;
void TubeScan(void)
{
static u8 index = 0;
P2 = (P2 & 0x1f) | 0xe0;
P0 = 0xff;
P2 = (P2 & 0x1f) | 0xc0;
P0 = (0x01 << index);
P2 = (P2 & 0x1f) | 0xe0;
P0 = TubeBuff[index];
P2 = P2 & 0x1f;
index ++;
index &= 0x07;
}
void TubeShow(void)
{
smg1 = temper_high / 10;
smg2 = temper_high % 10;
smg3 = temper_low / 10;
smg4 = temper_low % 10;
smg5 = smg6 = 16;
smg7 = Real_temper / 10;
smg8 = Real_temper % 10;
TubeBuff[0] = table[smg1];
TubeBuff[1] = table[smg2];
TubeBuff[2] = table[smg3];
TubeBuff[3] = table[smg4];
TubeBuff[4] = table[smg5];
TubeBuff[5] = table[smg6];
TubeBuff[6] = table[smg7];
TubeBuff[7] = table[smg8];
}
key.c
#include "sys.h"
u8 KeySta[] = {1, 1, 1, 1};
u8 KeyBackup[] = {1, 1, 1, 1};
u8 KeyBuff[] = {0xff, 0xff, 0xff, 0xff};
void KeyScan(void)
{
u8 i;
KeyBuff[0] = (KeyBuff[0] << 1) | S7;
KeyBuff[1] = (KeyBuff[1] << 1) | S6;
KeyBuff[2] = (KeyBuff[2] << 1) | S5;
KeyBuff[3] = (KeyBuff[3] << 1) | S4;
for(i = 0; i < 4; i ++)
{
if(KeyBuff[i] == 0xff) //Key release
KeySta[i] = 1;
else if(KeyBuff[i] == 0x00) //Key press
KeySta[i] = 0;
else
{}
}
}
void KeyAction(unsigned char key)
{
if(key == 0) //S7 减下限
{
if(temper_low > 0)
temper_low --;
else
temper_low = 0;
}
else if(key == 1) //S6 减上限
{
if(temper_high > temper_low)
temper_high --;
else
temper_high = temper_low;
}
else if(key == 2) //S5 加下限
{
if(temper_low < temper_high)
temper_low ++;
else
temper_low = temper_high;
}
else if(key == 3) //S4 加上限
{
if(temper_high < 99)
temper_high ++;
else
temper_high = 99;
}
flag_write = 1;
}
void KeyPress(void)
{
u8 i;
for(i = 0; i < 4; i ++)
{
if(KeySta[i] != KeyBackup[i])
{
if(KeySta[i] == 0) //action when key press
KeyAction(i);
KeyBackup[i] = KeySta[i];
}
}
}
ds18b20.c
#include "sys.h"
sbit DS18B20_IO = P1^4;
void Delayus(unsigned int us)
{
do{
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
}while(--us);
}
bit Get18B20Ack(void)
{
bit ack;
DS18B20_IO = 0; //产生500us的复位脉冲
Delayus(500);
// EA = 0; //禁止总中断
ET0 = 0;
DS18B20_IO = 1; //延时60us
Delayus(60);
// EA = 1; //重新使能总中断
ET0 = 1;
ack = DS18B20_IO; //读取存在脉冲
while(!DS18B20_IO); //等待存在脉冲结束
return ack;
}
void DS18B20Write(unsigned char dat)
{
unsigned char mask;
for(mask = 0x01; mask != 0; mask <<= 1) //低位在先,依次移出8个bit
{
// EA = 0;
ET0 = 0;
DS18B20_IO = 0; //产生2us低电平脉冲
Delayus(2);
if(dat & mask) //输出该bit值
DS18B20_IO = 1;
else
DS18B20_IO = 0;
// EA = 1;
ET0 = 1;
Delayus(60); //延时60us
DS18B20_IO = 1; //拉高通信引脚
}
}
unsigned char DS18B20Read(void)
{
unsigned char mask, dat = 0;
for(mask = 0x01; mask != 0; mask <<= 1) //低位在先,依次采集8个bit
{
// EA = 0;
ET0 = 0;
DS18B20_IO = 0; //产生2us低电平脉冲
Delayus(2);
DS18B20_IO = 1; //结束低电平脉冲,等待18B20输出数据
Delayus(2); //延时2us
if(DS18B20_IO) //读取通信引脚上的值
dat |= mask;
// EA = 1;
ET0 = 1;
Delayus(60); //再延时60us
}
return dat;
}
bit Start18B20()
{
bit ack;
static bit flag = 1;
ack = Get18B20Ack(); //执行总线复位,并获取18B20应答
if(ack == 0) //如18B20正确应答,则启动一次转换
{
DS18B20Write(0xCC); //跳过ROM操作
if(flag)
{
flag = 0;
DS18B20Write(0x4e); //写暂存器指令4E
DS18B20Write(0x63); //写高速缓存器TH高温限值99度
DS18B20Write(0x00); //写高速缓存器TL低温限值0度
DS18B20Write(0x1f); //写配置寄存器4
//0x1f : 0.5000°C 转换时间93.75ms
//0x3f : 0.2000°C 转换时间187.5ms
//0x5f : 0.1250°C 转换时间375ms
//0x7f : 0.0625°C 转换时间750ms
}
ack = Get18B20Ack(); //执行总线复位,并获取18B20应答
if(ack == 0) //如18B20正确应答,则启动一次转换
{
DS18B20Write(0xCC); //跳过ROM操作
DS18B20Write(0x44); //启动一次温度转换
}
}
return ~ack; //ack == 0 表示操作成功,所以返回值对其取反
}
bit Get18B20Temp(int *temp)
{
bit ack;
unsigned char LSB, MSB; //16bit温度值的低字节和高字节
ack = Get18B20Ack(); //执行总线复位,并获取18B20应答
if(ack == 0) //如18B20正确应答,则读取温度值
{
DS18B20Write(0xCC); //跳过ROM操作
DS18B20Write(0xBE); //发送读命令
LSB = DS18B20Read(); //读温度值的低字节
MSB = DS18B20Read(); //读温度值的高字节
*temp = ( MSB << 8) + LSB; //合成16bit的整数
}
return ~ack; //ack == 0 表示操作应答,所以返回值为1其取反值
}
ds18b20.h
#ifndef __DS18B20_H
#define __DS18B20_H
//单总线延时函数
void Delayus(unsigned int us);
bit Get18B20Ack(void);
void DS18B20Write(unsigned char dat);
unsigned char DS18B20Read(void);
bit Start18B20();
bit Get18B20Temp(int *temp);
#endif
iic.c
/*
程序说明: IIC总线驱动程序
软件环境: Keil uVision 4.10
硬件环境: CT107单片机综合实训平台 8051,12MHz
日 期: 2011-8-9
*/
#include "sys.h"
#define somenop {_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();}
#define SlaveAddrW 0xA0
#define SlaveAddrR 0xA1
//总线引脚定义
sbit SDA = P2^1; /* 数据线 */
sbit SCL = P2^0; /* 时钟线 */
//总线启动条件
void IIC_Start(void)
{
SDA = 1;
SCL = 1;
somenop;
SDA = 0;
somenop;
SCL = 0;
}
//总线停止条件
void IIC_Stop(void)
{
SDA = 0;
SCL = 1;
somenop;
SDA = 1;
}
//应答位控制
void IIC_Ack(bit ackbit)
{
if(ackbit)
{
SDA = 0;
}
else
{
SDA = 1;
}
somenop;
SCL = 1;
somenop;
SCL = 0;
SDA = 1;
somenop;
}
//等待应答
bit IIC_WaitAck(void)
{
SDA = 1;
somenop;
SCL = 1;
somenop;
if(SDA)
{
SCL = 0;
IIC_Stop();
return 0;
}
else
{
SCL = 0;
return 1;
}
}
//通过I2C总线发送数据
void IIC_SendByte(unsigned char byt)
{
unsigned char i;
for(i=0;i<8;i++)
{
if(byt&0x80)
{
SDA = 1;
}
else
{
SDA = 0;
}
somenop;
SCL = 1;
byt <<= 1;
somenop;
SCL = 0;
}
}
//从I2C总线上接收数据
unsigned char IIC_RecByte(void)
{
unsigned char da;
unsigned char i;
for(i=0;i<8;i++)
{
SCL = 1;
somenop;
da <<= 1;
if(SDA)
da |= 0x01;
SCL = 0;
somenop;
}
return da;
}
void Write_E2PROM(unsigned char add, unsigned char dat)
{
// EA = 0;
ET0 = 0;
IIC_Start();
IIC_SendByte(0xa0); //发送器件地址
IIC_WaitAck();
IIC_SendByte(add); //发送操作地址
IIC_WaitAck();
IIC_SendByte(dat); //写一字节
IIC_WaitAck();
IIC_Stop();
somenop;
// EA = 1;
ET0 = 1;
}
unsigned char Read_E2PROM(unsigned char add)
{
unsigned char d;
IIC_Start();
IIC_SendByte(0xa0); //发送器件地址
IIC_WaitAck();
IIC_SendByte(add); //发送要操作的地址
IIC_WaitAck();
IIC_Stop();
IIC_Start();
IIC_SendByte(0xa1); //发送读操作
IIC_WaitAck();
d = IIC_RecByte(); //读一字节
IIC_Ack(0);
IIC_Stop();
return d;
}
iic.h
#ifndef _IIC_H
#define _IIC_H
//函数声明
void IIC_Start(void);
void IIC_Stop(void);
void IIC_Ack(bit ackbit);
void IIC_SendByte(unsigned char byt);
bit IIC_WaitAck(void);
unsigned char IIC_RecByte(void);
void Write_E2PROM(unsigned char add, unsigned char dat);
unsigned char Read_E2PROM(unsigned char add);
#endif