思路:本次赛题比较简单,将界面与数据分开处理,这样代码会比较明了
两个底层就不细说了
#include <STC15F2K60S2.H>
#include <iic.h>
#include <onewire.h>
#define Px(adr,dat) {P2=(P2&0x1f)|(adr<<5);P0=dat;}
对于38译码器的处理我使用了一个宏定义
思路:P2&0x1f是将P2的高三位置0,adr<<5是将片选移到高三位,最后的或处理就能将38译码器配置好段选,最后的P0=dat就是直接输出了
/* 头文件 */
void Timer0Init();
void Smg_Show();
void Key_Ser();
void Key_Scan();
void LED_Display();
void Smg_Display();
void DAC_OUT();
/* 函数声明 */
unsigned char KeyDelay,Key,keynum,bloose;
/* 按键变量 */
unsigned char point,Smg_Dat[8],Smg_Arr[]={0xC0,0xF9,0xA4,0xB0,0x99,0x92,0x82,0xF8,0x80,0x90,0xc1,0xff,0x40,0x79,0x24,0x30,0x19,0x12,0x02,0x78,0x00,0x10,0xbf,0xa1,0x86,0xc6,0x7f,0x88,0x8c};
这些都是一些段码就不细说了
/* 数码管变量 */
float tempreature;
unsigned int Tcount,Tp_Cmp=25;
/* 温度变量 */
unsigned char page,mode;
/* 界面变量 */
unsigned char Dcount;
float DA_Dat;
/* DA变量 */
unsigned char LED;
/* LED变量 */
void main()
{
Timer0Init();
init_18b20();//初始化18b20,避免上电显示85的情况
Px(4,0xff);
Px(5,0x00);//关闭无关设备
while(1)
{
if (Tcount>=750)//温度读取 750ms读取一次
{
Tcount=0;
tempreature=TP_RD();
}
if (Dcount>=200)//DAC输出 200ms输出一次
{
Dcount=0;
DAC_OUT();
}
Smg_Display();
LED_Display();
if (keynum) Key_Ser();//按键处理函数 必须加上前面的判断 否则检测不到
}
}
void T0Int() interrupt 1
{
Tcount++;
Dcount++;
Smg_Show();//显示数码管
Key_Scan();//按键扫描
Px(4,~LED);//LED显示 这里将LED变量取反以便后续操作
}
void Timer0Init(void) //1毫秒@12.000MHz
{
AUXR &= 0x7F; //定时器时钟12T模式
TMOD &= 0xF0; //设置定时器模式
TL0 = 0x18; //设置定时初值
TH0 = 0xFC; //设置定时初值
TF0 = 0; //清除TF0标志
TR0 = 1; //定时器0开始计时
EA=1;
ET0=1;
}
void Smg_Show()//数码管显示函数
{
Px(6,0x01<<point);Px(7,Smg_Arr[Smg_Dat[point++]]);point%=8;
}
思路:用point变量作为指针,可同时对数码管的位选及其段选进行移位操作,将该函数直接在中断里调用
优点:对数码管段选数据的操作只需要改变Smg_Dat数组的各个位数
缺点:小数点不能进行或操作显示
unsigned char Key_Get()//扫描矩阵键盘
{
unsigned char keynum=0;
keynum=0;
P34=1;P35=1;P42=0;P44=1;
if (P30==0) keynum=11;
else if (P31==0) keynum=10;
else if (P32==0) keynum=9;
else if (P33==0) keynum=8;
P34=1;P35=1;P42=1;P44=0;
if (P30==0) keynum=7;
else if (P31==0) keynum=6;
else if (P32==0) keynum=5;
else if (P33==0) keynum=4;
return keynum;
}
void Key_Scan()//按键扫面函数 在中断里调用
{
if (KeyDelay==0)
{
Key=Key_Get();//获取第一次按下的键值
if (Key!=0) KeyDelay=15;//15ms消抖处理
else bloose=0;//松键判断标志 0为松键
}
else
{
if (--KeyDelay==0)//15ms延时结束
{
keynum=Key_Get();//再次获取键值
if (keynum!=Key) keynum=0;//前后键值不一样就会置0 防止按键按下进行错误操作
}
}
}
void Key_Ser()//按键处理函数
{
if (bloose==0)//松键进入
{
if (keynum==4)page++;//界面切换
else if (keynum==5&&page==2)mode=!mode;//DAC模式切换
else if (keynum==8&&page==1&&Tp_Cmp!=0)Tp_Cmp--;//温度参数处理
else if (keynum==9&&page==1&&Tp_Cmp!=99)Tp_Cmp++;
page%=3;
bloose=1;//将松键标志置1
}
keynum=0;
}
注:按键处理这里有两种思路,一是以界面划分,二是以键值划分,这里按键的功能和界面比较简单,所以采用按键划分
void Smg_Display()//数码管段选的数据处理
{
if (page==0)//初始默认界面
{
Smg_Dat[0]=25;
Smg_Dat[1]=11;
Smg_Dat[2]=11;
Smg_Dat[3]=11;
Smg_Dat[4]=(int)tempreature/10%10;
Smg_Dat[5]=(int)tempreature%10+12;
Smg_Dat[6]=(int)(tempreature*10)%10;
Smg_Dat[7]=(int)(tempreature*100)%10;
}
else if (page==1)//参数设置界面
{
Smg_Dat[0]=28;
Smg_Dat[1]=11;
Smg_Dat[2]=11;
Smg_Dat[3]=11;
Smg_Dat[4]=11;
Smg_Dat[5]=11;
Smg_Dat[6]=Tp_Cmp/10;
Smg_Dat[7]=Tp_Cmp%10;
}
else if (page==2)//DAC输出界面 DA_Dat在下面的DAC_OUT中处理的
{
Smg_Dat[0]=27;
Smg_Dat[1]=11;
Smg_Dat[2]=11;
Smg_Dat[3]=11;
Smg_Dat[4]=11;
Smg_Dat[5]=(int)DA_Dat+12;
Smg_Dat[6]=(int)(DA_Dat*10)%10;
Smg_Dat[7]=(int)(DA_Dat*100)%10;
}
}
void LED_Display()//LED数据处理界面 这里比较简单就不细说了
{
if (mode==0)LED|=0x01;
else LED&=0xfe;
if (page==0)LED|=0x02;
else LED&=0xfd;
if (page==1)LED|=0x04;
else LED&=0xfb;
if (page==2)LED|=0x08;
else LED&=0xf7;
}
void DAC_OUT()//DAC输出函数
{
if (mode==0)//模式1的输出方式
{
if (tempreature<Tp_Cmp){DAC(0);DA_Dat=0;}
else {DAC(255);DA_Dat=5;}
}
else //模式二的输出方式
{
if (tempreature<=20){DAC(51);DA_Dat=1;}
else {DAC((char)((tempreature*0.15-2)*51));DA_Dat=tempreature*0.15-2;}
}
}
18b 代码,这些原理不细说了
#include <STC15F2K60S2.H>
#include <intrins.h>
void Delay750ms() //@12.000MHz
{
unsigned char i, j, k;
_nop_();
_nop_();
i = 35;
j = 51;
k = 182;
do
{
do
{
while (--k);
} while (--j);
} while (--i);
}
sbit DQ = P1^4; //եПޓࠚ
//եПғʱگ˽
void Delay_OneWire(unsigned int t) //STC89C52RC
{
t*=12;
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(5);
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;
}
Delay_OneWire(5);
}
return dat;
}
//DS18B20ʨѸԵʼۯ
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 TP_RD()
{
unsigned char low,high;
init_ds18b20();
Write_DS18B20(0xcc);
Write_DS18B20(0xbe);
low=Read_DS18B20();
high=Read_DS18B20();
init_ds18b20();
Write_DS18B20(0xcc);
Write_DS18B20(0x44);
return ((high<<8)|low)/16.0;
}
void init_18b20()
{
init_ds18b20();
Write_DS18B20(0xcc);
Write_DS18B20(0x44);
Delay750ms();
init_ds18b20();
Write_DS18B20(0xcc);
Write_DS18B20(0xbe);
}
iic代码
#include "reg52.h"
#include "intrins.h"
#define somenop {_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;
}
unsigned char AD_RD(unsigned char adr)
{
unsigned char dat;
IIC_Start();
IIC_SendByte(0x90);
IIC_WaitAck();
IIC_SendByte(0x40|adr);
IIC_WaitAck();
IIC_Start();
IIC_SendByte(0x91);
IIC_WaitAck();
dat=IIC_RecByte();
IIC_Ack(0);
IIC_Stop();
return dat;
}
void DAC(unsigned char dat)
{
IIC_Start();
IIC_SendByte(0x90);
IIC_WaitAck();
IIC_SendByte(0x40);
IIC_WaitAck();
IIC_SendByte(dat);
IIC_WaitAck();
IIC_Stop();
}