typedefunion //定义联合体,
{
unsigned inti;
floatf;
}value; //定义联合体类型名称为value
#definenoACK0
#define ACK1
#defineSTATUS_REG_W0x06 //0x06=00000110
#defineSTATUS_REG_R0x07 //0x07=00000111
#defineMEASURE_TEMP0x03 //0x03=00000011
#defineMEASURE_HUMI0x05 //0x05=00000101
#defineRESET 0x1e //0x1e =00011110
#defineSDAP1_6 //定义SDA代表的是P1_6脚
#defineSCL P1_7
#definebeginP2_0
unsignedchard1,d2,d3,d4,d5,d6,d7;//定义无符号字符型变量
voidWait(unsigned intms) //定义wait函数,主要用于软件循环,延时作用
{
unsigned charg,k;
while(ms)
{
for(g=0;g<=167;g++)
{
for(k= 0;k<=48;k++);
}
ms--;
}
}
voidQWait()//1us的延时
{
asm("NOP"); //加入汇编操作语句,空操作,主要用于机器周期执行
asm("NOP");
asm("NOP");
asm("NOP");
asm("NOP");
asm("NOP");
asm("NOP");
asm("NOP");
asm("NOP");
asm("NOP");
asm("NOP");
}
voidinitUART(void) //初始化串口
{
IO_PER_LOC_USART0_AT_PORT0_PIN2345(); //具体函数的定义与用法,你得参考头文件中的程序代码了
IO_DIR_PORT_PIN(1,6,IO_OUT);
IO_DIR_PORT_PIN(1,7,IO_OUT);
//IO_IMODE_PORT_PIN(1,6,IO_IMODE_TRI);
//IO_IMODE_PORT_PIN(1,7, IO_IMODE_TRI);
IO_DIR_PORT_PIN(2, 0,IO_OUT);
IO_FUNC_PORT_PIN(2,0,IO_FUNC_GIO);
//SET_MAIN_CLOCK_SOURCE(RC);
SET_MAIN_CLOCK_SOURCE(CRYSTAL);
UART_SETUP(0, 115200,HIGH_STOP); //设置传输数据的波特率115200
UTX0IF=1;
U0CSR|=0XC7; //U0CSR = U0CSR|0x1010 0111 (进行位或操作)
IEN0|=0x84;
SDA=1;
SCL =0;
}
int putchar (int c) //定义输入字符函数,给的参数是一个整型的数
{
if(c=='\n') //判断参数c的值是否和'\n'的值相等
{
while(!
UTX0IF); //执行的时候UTX0IF的值是0,此处不是很理解?
UTX0IF=0; //给UTX0IF赋0
U0DBUF= 0x0d; //U0DBUF赋值0x0d = 00001011
}
while(!
UTX0IF);
UTX0IF=0;
return(U0DBUF= c); //如果c的值不是'\n'也就是换行符的时候,将c的值传递到U0DBUF寄存器中
}
chars_write_byte(unsignedcharvalue) //定义写字节函数(8位)
{
unsignedchar i,error =0;
for(i= 0x80;i >0;i/= 2) //i赋初始值0x80=128,执行判断是i> 0,执行语句是i=i/2;即i=128,64,32,16,8,4,2,1,0.5(0),8位
{
if(i &value)
SDA= 1;
else
SDA= 0;
SCL=1; //此时SCL端口处,也就是p1_7引脚处是高电平
QWait(); //因为写入需要时间,所以程序之中加入下面几条语句
QWait();
QWait();
QWait();
QWait();
SCL=0; //使能p1_7眼角处低电平,使的数据写入(具体需要看单片机控制芯片的手册
asm("NOP");
asm("NOP");
}
SDA= 1;
SCL=1;
asm("NOP");
error=SDA;
QWait();
QWait();
QWait();
SDA=1;
SCL=0;
returnerror;
}
chars_read_byte(unsigned charack) //读取数据,按照字节位的顺序读取(8位)128= 1000 0000,64=0100 0000,32 =0010 0000 ,16 =00010000, 8=0000 1000, 4=00000100,2=00000010,1=0000 0001
{
unsignedchari,val= 0;
SDA= 1;
for(i =0x80;i>0;i/=2) //同上
{
SCL= 1;
if(SDA) //判断SDA处是否有高电平
val = (val|i); //进行或操作
else
val= (val| 0x00);
SCL=0;
QWait();
QWait();
QWait();
QWait();
QWait();
}
SDA=!
ack;
SCL= 1;
QWait();
QWait();
QWait();
QWait();
QWait();
SCL=0;
SDA=1;
returnval; //返回读取到的数据,一个字节,八位
}
voids_transstart(void) //传输使能函数,就是给控制器引脚处相应电平,使对应模块工作
{
SDA= 1;
SCL=0;
QWait();
QWait();
SCL =1;
QWait();
QWait();
SDA=0;
QWait();
QWait();
SCL=0;
QWait();
QWait();
QWait();
QWait();
QWait();
SCL =1;
QWait();
QWait();
SDA=1;
QWait();
QWait();
SCL =0;
QWait();
QWait();
}
void s_connectionreset(void) //复位操作函数
{
unsignedchari;
SDA= 1;
SCL = 0;
for(i=0;i< 9;i++)
{
SCL =1;
QWait();
QWait();
SCL = 0;
QWait();
QWait();
}
s_transstart(); //调用开始函数
}
chars_measure(unsignedchar*p_value,unsignedchar*p_checksum, unsigned charmode)//函数,主要统计传输的数据个数
{
unsigned er= 0;
unsignedint i,j;
s_transstart();
switch(mode)
{
case3:
er +=s_write_byte(3);
break;
case5 :
er +=s_write_byte(5);
break;
default :
break;
}
for(i=0;i<65535;i++)
{
for(j =0;j <65535;j++)
{if(SDA==0)
{
break;
}
}
if(SDA ==0)
{
break;
}
}
if(SDA)
{
er +=1;
}
*(p_value)=s_read_byte(ACK);
*(p_value +1)=s_read_byte(ACK);
*p_checksum=s_read_byte(noACK);
d6 =*(p_value);
d7=*(p_value + 1);
returner;
}
voidcalc_sth11(float*p_humidity,float*p_temperature)//计算温度值
{
constfloat C1 =-4.0;
constfloatC2=+ 0.0405;
const float C3=-0.0000028;
constfloatT1=+ 0.01;
constfloatT2=+0.00008;
floatrh =*p_humidity;
float t =*p_temperature;
floatrh_lin;
floatrh_true;
floatt_C;
t_C= t *0.01- 44.0 ;
rh_lin = C3 *rh*rh+C2*rh+C1;
rh_true=(t*0.01-40.0 -25)* (T1+T2*rh)+rh_lin;
if(rh_true>100)
{
rh_true =100;
}
if(rh_true<0.1)
{
rh_true=0.1;
}
*p_temperature=t_C;
*p_humidity= rh_true;
}
void main() //主函数
{
valuehumi_val,temp_val; //声明两个联合体变量
unsignedcharerror,checksum; //声明两个无符号的字符型变量
initUART(); //初始化串口
P1INP |=0xC0; //初始化P1引脚 ,0xC0 = 1010 0000,使P1_7和P1_5引脚为1
begin=0;
s_connectionreset();
while
(1) //无限循环操作
{
error= 0;
error+=s_measure((unsigned char*)&humi_val.i,&checksum,5); //读入串口的数据进行温度的计算
d1=d6;
d2= d7;
error+=s_measure((unsignedchar*) &temp_val.i,&checksum,3);
d3 =d6;
d4 = d7;
if(error!
=0)
s_connectionreset();
else
{
humi_val.f= (float)humi_val.i;
temp_val.f=(float)temp_val.i;
humi_val.f=d1* 256+d2;
temp_val.f=d3*256+ d4;
calc_sth11(&humi_val.f,&temp_val.f);
printf("temp:
%5.1fChumi:
%5.1f%%\n",temp_val.f,humi_val.f);
//printf("t1:
%xh1:
%x\n",d1,d2);
//printf("t2:
%xh2:
%x\n",d3,d4);
}
Wait(150);
}
}
四、设计调试和心得体会
系统软件的主程序是调用子程序的,它是所有子程序在功能上的汇总,是整个程序的“首脑”,CPU是从从主程序开始读程序的,所以主程序的设计尤为重要。
这个系统软件的主程序主要完成温度在4位8段的数码管上显示温度的功能。
4.1功能实现分析
该硬件电路在最后测试中实现了准确的温湿度采集、能够传给KL25芯片发送采集到得参数。
基本实现了设计任务,并可根据外界运用需要更换和外扩其他功能传感器。
4.2心得体会
经过一个礼拜设计,调试和实践,我们已经在电路板上成功仿真运行了显示模块和温湿度测试模块。
仿真运行结果符合最初的实验设计要求。
唯有实践方能出真知,这次做的产品给我们上了一次很生动的课。
总的来说
这次实践,我们学到许多,不仅仅是书本或者是网上的资料给我们的知识,更重要的是动手实践后的体会,感悟。
由于时间的原因在设计过程中不能很好的做出我们设计所要达到的要求,对于以上的不足,我们只有通过以后的努力不断的提升。
在设计中我们基本实现了温湿度的读取,在后级电路中由于个人能力有限,而不能实现后级驱动电路,在这方面我相信在以后的学习生涯中能得到解决,
最后我要感谢我的导师陈儒敏老师,在他的帮助下我们做好了基于KL25芯片温湿度控制系统的课程设计,同时我也要感谢那些在我遇到难题时候给予我帮助的同学和好友。
五丶成果展示
下面为运行成功显示成果
参考文献
[1] 张毅刚. 单片机原理及应用[M]. 北京:
高等教育出版社,2003. [2] 万光毅. 单片机实验与实践教程[M]. 北京:
北京航空航天