由于到现在还没有收到开发板,但是活动又快结束了,就把自己以前弄的东西发表一下。
下面这个图是以前自己做的51系统板,包括很多模块。由于是在实验室自己做板,画得不是很正规。
那时候51的很多资源都学习过了,利用51做了很多控制类方面的东西。有一个是别人的毕业设计,是ds18b20和24c02结合弄成一个可存取的数字温度计,用12864液晶显示。列出部分程序吧,有兴趣的可以看一下。
#include <reg52.h>
#include<intrins.h>
#include"24c02.c"
#define uchar unsigned char
#define uint unsigned int
sbit DQ=P3^7;//定义18b20 I/O 接口
sbit feng=P3^6;//蜂鸣器端口设定
sbit RST=P2^0;//复位信号
sbit PSB= P2^1;//并行、串行选择信号
sbit SCLK=P2^2;//时钟信号E
sbit SID=P2^3;//数据信号RW
sbit CS=P2^4;//片选信号RS
uint temp,tem,shang,xia,ss,xx,shi,fen,miao,shi1,fen1,miao1,num;
uint temflag=0,temaddr=0,keynum=0,addrnum=0;
uchar dis0[5];
uchar dis1[5];
uchar dis2[5];
uchar dis3[6];
void wendudisplay();
void delay(uint i);
void shizhong();
void shijian();
/*****延时子程序**********/
void delay(uint i)
{
while(i--);
}
void delay1s()
{
uint i,j;
for(i=1000;i>0;i--)
for(j=110;j>0;j--);
}
/*****写字节指令*******/
void sendbyte(uchar zdata)
{
uint i;
for(i=0;i<8;i++)
{
SCLK=0;
if((zdata<<i)&0x80)
{
SID=1;
}
else
{
SID=0;
}
SCLK=1; //上升沿将数据读取
delay(20);
}
}
/*****写串口指令******/
void write_com(uchar cmdcode)
{
CS=1;
sendbyte(0xf8); //写指令
sendbyte(cmdcode & 0xf0);
sendbyte((cmdcode<<4) & 0xf0);
delay(20);
CS=0;
}
/****写数据*********/
void write_data(uchar Dispdata)
{
CS=1;
sendbyte(0xfa); //写数据
sendbyte(Dispdata & 0xf0);
sendbyte((Dispdata<<4) & 0xf0);
delay(20);
CS=0;
}
/*******初始化函数********/
void lcd_init()
{
RST = 0; //上电复位
delay(10);
RST = 1;
delay(10);
write_com(0x30); //基本指令集
delay(10);
write_com(0x0c); //开显示
delay(10);
write_com(0x01);
delay(10);
}
/*******************************************************************/
/* 初始化ds18b20子函数(复位脉冲和存在脉冲) */
/*******************************************************************/
void Init_DS18B20(void)
{
unsigned char x=0;
DQ = 1; //DQ复位
delay(8); //稍做延时
DQ = 0; //单片机将DQ拉低
delay(200); //精确延时 大于 480us
DQ = 1; //拉高总线 (释放总线)
delay(14); //等待18b20回应
x=DQ; //稍做延时后,读取总线状态,如果x=0则初始化成功 x=1则初始化失败
delay(20);
}
/***读字节子函数 (先低后高) ,向DS18B20读取一个字节的内容****/
ReadOneChar(void)
{
unsigned char i=0;
unsigned char dat = 0;
for (i=8;i>0;i--)
{
DQ = 0; // 给脉冲信号
dat>>=1;
DQ = 1; // 给脉冲信号
if(DQ)
{dat|=0x80;}
delay(5);
}
return(dat);
}
/****写字节子函数(先低后高)***/
void WriteOneChar(unsigned char dat)
{
unsigned char i=0;
for (i=8; i>0; i--)
{
DQ = 0; //拉低总线,开始写时序
DQ = dat&0x01; //控制字的最低位先送到总线
delay(3); //稍作延时,让DS18B20读取总线上的数据
DQ = 1; //拉高总线(释放总线),1bit写周期结束
dat>>=1;
}
}
/**DS18B20 begin change 发送温度转换命令**/
void get_temperaturechange(void)
{
Init_DS18B20(); //初始化DS18B20
delay(100); //延时
WriteOneChar(0xcc); // 跳过序列号命令 (skip rom命令)
WriteOneChar(0x44); //发送温度转换命令(发出convert T命令,读温度忙状态),结果存在暂存器中
}
/*get the temperature *得到温度值(0~99.9)*/
uint get_temperature()
{
float tt;
uchar a,b;
Init_DS18B20();
delay(100);
WriteOneChar(0xcc); //跳过序列号命令(skip rom命令)
WriteOneChar(0xbe); //发送读取数据命令(读暂存器的数据),读取DS18B20内部的寄存器内容
a=ReadOneChar(); //连续读两个字节数据 ,读温度值低位(内部RAM的第0个字节)
b=ReadOneChar(); //读温度值高位(内部RAM的第1个字节)
temp=b; //temp为整型,b为uchar型,将b转换为整型
temp<<=8; //高位全为0
temp=temp|a; //两字节合成一个整型变量,温度值放在temp中
tt=temp*0.0625; //得到真实十进制温度值,因为DS18B20
//可以精确到0.0625度,所以读回数据的最低位代表的是
//0.0625度。
// temp=tt*10+0.5; //放大十倍,这样做的目的将小数点后第一位
//也转换为可显示数字,同时进行一个四舍五入操作。
tem=(tt*100);
return tem; //返回温度值
}
void storetem()
{
init();
if(temflag==1)
{
temflag=0;
wendudisplay();
write_N_byte(temaddr,dis0);
write_N_byte(temaddr,dis0); //多写几次,保证数据写入成功
delay(500); //延时要合适,延时太短主机反应不过来
temaddr+=6;
if(temaddr>=(24*6))
{ temaddr=0; }
addrnum=temaddr;
lcd_pos (1,0);
display_string("保存当前温度: ");
keynum=0;
delay1s(); delay1s();
xianshi();
}
}
/*****主函数********/
void main()
{
feng=0;
ss=3500;
xx=1000;
shi1=9;
fen1=58;
miao1=55;
TMOD=0X01; // 设置定时器0为工作方式(M1M0为01)
TH0=(65536-50000)/256; //装初值,12MHZ晶振,定时50ms, 数为5000,高八位。
TL0=(65536-50000)%256; //低八位,12*(1/12MHZ)=1us,50ms/1us=5000.
EA=1; //总中断打开
ET0=1; // 打开定时器0中断
TR0=1;
PSB= 0; //串行口
delay(10);
firstscreen();
while(1)
{
keyscan(); //键盘扫描
mainscreen();
storetem();
if(tem>ss&&tem>xx) //温度大于温度上限
{
feng=1; delay1s();
feng=0; delay1s();
}
else if(tem<xx&&tem<ss)//温度小于温度下限
{
feng=1; delay1s();
feng=0; delay1s();
}
else//温度介于上限于下限之间
{ feng=0; }
}
}
void T0_time() interrupt 1//定时器0中断字函数
{
TH0=(65536-50000)/256;
TL0=(65536-50000)%256;
num++;
get_temperaturechange();//温度转换,
get_temperature(); //显示温度
if(num==20)//如果到了20次,说明1s时间到
{
num=0;
miao1++;
}
if(miao1==60)
{fen1++; miao1=0; }
if (fen1==60)
{fen1=0;shi1++; temflag=1; }
if(shi1==24)
{shi1=0;}
}