题目要求
设计任务及要求
- 数码管显示单元
通过 8 位共阳数码管显示温度信息, 包括设定的温度上下限数值和当前温度值,显示格式如图 2 所示:
- 温度测量单元
通过 DS18B20 数字温度芯片测量环境温度。 - 按键控制单元
独立按键 S4 设定为“加上限” 按键;每按下一次,温度上限值增加 1℃;
独立按键 S5 设定为“加下限”按键;每按下一次,温度下限值增加 1℃;
独立按键 S6 设定为“减上限”按键; 每按下一次,温度上限值减少 1℃;
独立按键 S7 设定为“减下限”按键;每按下一次,温度下限值减少 1℃。 - EEPROM 记录单元
系统通过 AT24C02 存储温度信息, AT24C02 内部存储地址 0x00 和 0x01 分别存储温度上下限数据信息;温度上下限数据可通过外部按键进行修改,并通过数码管实时显示。 数据存储格式如图 3 所示:
- 直流电机驱动电路设计
设计一个直流电机驱动电路与单片机 P34 引脚连接。 - 温控单元
若当前温度数值超过 EEPROM 中存储的温度上限数据, 通过单片机 P34 口产生周期为 1KHz 占空比为 30%的 PWM 信号驱动直流电机工作。 待温度恢复到上下限阈值内时, P34 口输出高电平,直流电机停止工作若当前温度低于 EEPROM 中存储的温度下限数据, 继电器打开,当温度恢复到上3下限阈值内时,继电器自动关闭。 - 系统初始状态说明
上、下限温度值需要设定在 0℃到 99℃范围内,下限值不大于上限值。 系统上电后,从 EEPROM 中读取温度上、下限数值,并实时显示当前温度。
程序代码
主函数
#include<stc15f2k60s2.h>
#include "onewire.h"
#include "iic.h"
typedef unsigned char uchar;
typedef unsigned int uint;
sbit PWM=P3^4;
sbit dealy=P0^4;
sbit beep=P0^6;
uchar code SMG_duan[]={
0x3F,0x06,0x5B,0x4F,0x66,0x6D,0x7D,0x07,0x7F,0x6F};
uchar code SMG_wei[]={
0x01,0x02,0x04,0x08,0x10,0x20,0x40,0x80};
uchar temperature;
uchar max=30,min=23; //极限值
uchar limit_up=30,limit_down=23;
uchar temp_display[8];
uchar key_init();
void Timer0Init(); //1毫秒@11.0592MHz
void main()
{
uchar key_val;
P2=0XA0;P0=0X00;
P2=0X80;P0=0XFF;
Timer0Init();
DS18B20();
temp_display[4]=0x00; temp_display[5]=0x00;
while(1)
{
temperature=temp_get();
ET0=0;
max=Read(0x00);
min=Read(0x01);
limit_up=Read(0x00);
limit_down=Read(0x01);
ET0=1;
temp_display[0]=SMG_duan[max/10]; temp_display[1]=SMG_duan[max%10];
temp_display[2]=SMG_duan[min/10]; temp_display[3]=SMG_duan[min%10];
temp_display[6]=SMG_duan[temperature%100/10]; temp_display[7]=SMG_duan[temperature%10];
key_val=key_init();
switch(key_val)
{
case 4:
if(limit_up<99)
limit_up++;
Write(0x00,limit_up);
break; //加上限
case 5:
if(limit_down<99)
limit_down++;
Write(0x01,limit_down); //加下限
break;
case 6:
if(limit_up>0)
limit_up--;
Write(0x00,limit_up);
break;
case 7:
if(limit_down>0)
limit_down--;
Write(0x01,limit_down);
break;
}
if(temperature>limit_up)
{
PWM=1;
}
if(temperature<limit_down)
{
P2=0XA0;
dealy=1;
beep=0;
}
if((limit_down<=temperature)&&(temperature<=limit_up))
{
P2=0XA0;
dealy=0;
beep=0;
PWM=0;
}
}
}
#define KEY P3
#define key_state0 0
#define key_state1 1
#define key_state2 2
uchar key_init()
{
static uchar key_state=0;
uchar key_return=0,key_press;
key_press=KEY&0X0F;
switch(key_state)
{
case key_state0:
if(key_press!=0x0f)
key_state=key_state1;
break;
case key_state1:
if(key_press!=0x0f)
{
if(key_press==0x0e) key_return=7;
if(key_press==0x0d) key_return=6;
if(key_press==0x0b) key_return=5;
if(key_press==0x07) key_return=4;
key_state=key_state2;
}
else
key_state=key_state0;
break;
case key_state2:
if(key_press==0x0f)
key_state=key_state0;
break;
}
return key_return;
}
void Timer0Init() //100us @11.0592MHz
{
AUXR |= 0x80; //定时器时钟1T模式
TMOD &= 0xF0; //设置定时器模式
TL0 = 0xAE; //设置定时初值
TH0 = 0xFB; //设置定时初值
TF0 = 0; //清除TF0标志
TR0 = 1; //定时器0开始计时
EA=1;
ET0=1;
}
void Timer0() interrupt 1
{
uchar i;
static uint SMG_count=0,PWM_count=0;
SMG_count++,PWM_count++;
if(SMG_count==30)
{
SMG_count=0;
P2=0XC0;P0=0X00;
P2=0XC0;P0=SMG_wei[i];
P2=0XE0;P0=~temp_display[i];
i++;
if(i==8)
i=0;
}
if(PWM_count==7)
{
PWM=1;
}
if(PWM_count==10)
{
PWM=0;
}
}
DS18B20温度传感器
#include "onewire.h"
#include "intrins.h"
//单总线延时函数
void Delay_OneWire(unsigned int t)
{
while(t--);
}
void Delay500us();
void Delay100us();
void Delay60us();
void Delay15us();
void delayms(unsigned char ms)
{
int i,j;
for(i=0;i<ms;i++)
for(j=850;j>0;j--);
}
//DS18B20芯片初始化
bit Init_DS18B20(void)
{
bit initflag = 0;
DQ = 1;
Delay_OneWire(12);
DQ = 0;
Delay500us();
DQ = 1;
Delay15us();
initflag = DQ;
Delay_OneWire(5);
return initflag;
}
//通过单总线向DS18B20写一个字节
void Write_DS18B20(unsigned char dat)
{
unsigned char i;
for(i=0;i<8;i++)
{
DQ = 0;
DQ = dat&0x01;
Delay60us();
DQ = 1;
dat >>= 1;
}
Delay_OneWire(5);
}
//从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;
}
Delay100us();
}
return dat;
}
void DS18B20()
{
Init_DS18B20();
delayms(1);
Write_DS18B20(0xcc);
Write_DS18B20(0x44);
Init_DS18B20();
delayms(1);
Write_DS18B20(0xcc);
Write_DS18B20(0xbe);
}
int temp_get()
{
unsigned char low,high;
unsigned char temp;
DS18B20();
low=Read_DS18B20();
high=Read_DS18B20();
temp=high<<4;
temp|=low>>4;
return temp;
}
void Delay500us() //@11.0592MHz
{
unsigned char i, j;
_nop_();
_nop_();
i = 6;
j = 93;
do
{
while (--j);
} while (--i);
}
void Delay100us() //@11.0592MHz
{
unsigned char i, j;
_nop_();
_nop_();
i = 2;
j = 15;
do
{
while (--j);
} while (--i);
}
void Delay60us() //@11.0592MHz
{
unsigned char i, j;
i = 1;
j = 162;
do
{
while (--j);
} while (--i);
}
void Delay15us() //@11.0592MHz
{
unsigned char i;
i = 39;
while (--i);
}
EEPROM
/*
程序说明: IIC总线驱动程序
软件环境: Keil uVision 4.10
硬件环境: CT107单片机综合实训平台(12MHz)
日 期: 2011-8-9
*/
#include "iic.h"
void iic_delay(unsigned char i)
{
do
{
_nop_();
}while(i--);
}
void IIC_Start(void)
{
SDA = 1;
SCL = 1;
iic_delay(5);
SDA = 0;
iic_delay(5);
SCL = 0;
}
//总线停止条件
void IIC_Stop(void)
{
SDA = 0;
SCL = 1;
iic_delay(5);
SDA = 1;
}
/*
//应答位控制
void IIC_Ack(unsigned char ackbit)
{
if(ackbit)
{
SDA = 0;
}
else
{
SDA = 1;
}
iic_delay(5);
SCL = 1;
iic_delay(5);
SCL = 0;
SDA = 1;
iic_delay(5);
}
*/
//等待应答
bit IIC_WaitAck(void)
{
SDA = 1;
iic_delay(5);
SCL = 1;
iic_delay(5);
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;
}
iic_delay(5);
SCL = 1;
byt <<= 1;
iic_delay(5);
SCL = 0;
}
}
//从I2C总线上接收数据
unsigned char IIC_RecByte(void)
{
unsigned char da;
unsigned char i;
for(i=0;i<8;i++)
{
SCL = 1;
iic_delay(5);
da <<= 1;
if(SDA)
da |= 0x01;
SCL = 0;
iic_delay(5);
}
return da;
}
void Write(unsigned char add,unsigned char dat)
{
IIC_Start();
IIC_SendByte(0xa0);
IIC_WaitAck();
IIC_SendByte(add);
IIC_WaitAck();
IIC_SendByte(dat);
IIC_WaitAck();
IIC_Stop();
}
unsigned char Read(unsigned char dat)
{
unsigned char temp;
IIC_Start();
IIC_SendByte(0xa0); //写入 为0
IIC_WaitAck();
IIC_SendByte(dat);
IIC_WaitAck();
IIC_Start();
IIC_SendByte(0xa1); //读出为1
IIC_WaitAck();
temp=IIC_RecByte();
IIC_Stop();
return temp;
}
以上就是代码的全部内容,欢迎大家批评指正,共同学习~