【A/D转换 串口通讯】请教几个大家基础问题~
我最近学习2530时,需要用到一个温湿度传感器,我通过官方给的资料和单片机知识可以把温湿度信息传到电脑中了,但其中一些程序段没有理解,在此向各位前辈、朋友、同学们请教(问题在注释中):
单片机?数模转换?串口通讯?A/D
/*-----------------------------------------------
名称:串口通信
2013年1月28日
------------------------------------------------*/
#include<reg52.h> //包含头文件,一般情况不需要改动,头文件包含特殊功能寄存器的定义
#include"delay.h"
//#include<string.h>
typedef unsigned char U8;
typedef unsigned int U16;
U8 U8FLAG,U8temp;//貌似是标志位,但是没有理解意思
U8 U8comdata;/////校验值????????????????????????????????
U8 shidu_shi,shidu_ge,wendu_shi,wendu_ge;
U8 U8T_data_H,U8T_data_L,U8RH_data_H,U8RH_data_L,U8checkdata;
U8 U8T_data_H_temp,U8T_data_L_temp,U8RH_data_H_temp,U8RH_data_L_temp,U8checkdata_temp;
sbit P2_0 = P2^2;//此端口是数据输入端
U8 dispbuf1[]="hum= temp= 0"; //用于串口通讯的字符数组。
U8 table1[]="0123456789";
/*------------------------------------------------
函数声明
------------------------------------------------*/
void SendStr(unsigned char *s);
//////////////////////////////////////////
/*此部分是温湿度传感器公司给的程序段中的延时函数,为了便于理解,没有修改此处*/
void Delay(U16 z)
{
U8 x,y;
for(x=z;x>0;x--)
for(y=110;y>0;y--);
}
void Delay_10us(void)
{
U8 i;
i--;
i--;
i--;
i--;
i--;
i--;
}
/////////////////////////////////////////////////////////////////
/*------------------------------------------------
串口初始化
------------------------------------------------*/
void InitUART (void)
{
SCON = 0x50; // SCON: 模式 1, 8-bit UART, 使能接收
TMOD |= 0x20; // TMOD: timer 1, mode 2, 8-bit 重装
TH1 = 0xFD; // TH1: 重装值 9600 波特率 晶振 11.0592MHz
TR1 = 1; // TR1: timer 1 打开
EA = 1; //打开总中断
//ES = 1; //打开串口中断
}
void COM(void)//这个函数不好理解,我就把它当做A/D转化函数,即每次调用时,把模拟信号的值传递给U8comdata
{
U8 i;
for(i=0;i<8;i++)
{
U8FLAG=2;
while((!P2_0)&&U8FLAG++);
Delay_10us();
Delay_10us();
Delay_10us();
U8temp=0;
if(P2_0)U8temp=1;
U8FLAG=2;
while((P2_0)&&U8FLAG++);
if(U8FLAG==1)break;
U8comdata<<=1;
U8comdata|=U8temp;
}
}
void RH(void)
{
P2_0=0;
Delay(40);
P2_0=1;
Delay_10us();
Delay_10us();
Delay_10us();
//Delay_10us();
P2_0=1;
if(!P2_0)//【问题一】上面的P2_0永远为1,这里if里面的东西应该永远不会运行呀
{
U8FLAG=2;
while((!P2_0)&&U8FLAG++);//如果进来了,这里!P2_0为1,这里是不是可以删去!P2_0?即使可以加
U8FLAG=2;
while((P2_0)&&U8FLAG++);
COM();
U8RH_data_H_temp=U8comdata;//估计是每调用一次COM(),就会读取一位数值,根据 参数名字,是湿度高位
COM();
U8RH_data_L_temp=U8comdata;
COM();
U8T_data_H_temp=U8comdata;
COM();
U8T_data_L_temp=U8comdata;
COM();
U8checkdata_temp=U8comdata;//【疑问二】为什么不直接赋值,我的理解是:COM传递5个数值,前4个是有效值,最后一个U8checkdata_temp是校验值,当四个数值全传完才串口通信,不知这样理解对不对?
P2_0=1;
U8temp=(U8T_data_H_temp+U8T_data_L_temp+U8RH_data_H_temp+U8RH_data_L_temp);
if(U8temp==U8checkdata_temp)
{
U8RH_data_H=U8RH_data_H_temp;//温湿度数据传递
U8RH_data_L=U8RH_data_L_temp;
U8T_data_H=U8T_data_H_temp;
U8T_data_L=U8T_data_L_temp;
U8checkdata=U8checkdata_temp;
}
shidu_shi=U8T_data_H/10; //把读进来的数据放在shidu_shi中
shidu_ge=U8T_data_H%10;
wendu_shi=U8RH_data_H/10;
wendu_ge=U8RH_data_H%10;
//
dispbuf1[13]=table1[shidu_shi]; //把对应的数字放置在 字符数组 中准备传送、、问题是,为什么不直接赋值,而是通过另外一个数组转化?
dispbuf1[14]=table1[shidu_ge];
dispbuf1[4]=table1[wendu_shi]; //个位因为放大了 10 倍,此位实为小数位
dispbuf1[5]=table1[wendu_ge];
//
}
//display(shidu_shi,shidu_ge,wendu_shi,wendu_ge);
}
/*------------------------------------------------
主函数
------------------------------------------------*/
void main (void)
{
InitUART();
SendStr("UART test begain@\n\n\n\n\0");//提示已经开始测试
while (1)
{
RH();
//strcpy(SendStr,dispbuf1);
SendStr(dispbuf1);
// SendStr("UART test, his is a simple UART test, if you can see this@");
//SendStr("if you can see this, that mean your are success!\n\n");
DelayMs(240);//延时循环发送
DelayMs(240);
DelayMs(240);//延时循环发送
DelayMs(240);
DelayMs(240);//延时循环发送
DelayMs(240);
DelayMs(240);//延时循环发送
DelayMs(240);
}
SendStr("You should never see this@");
}
/*------------------------------------------------
发送一个字节?
------------------------------------------------*/
void SendByte(unsigned char dat)
{
SBUF = dat;
while(!TI);//【疑问三】这里我看定义为 sbit TI = SCON^1; 但不知道是什么意思?
TI = 0;
}
/*------------------------------------------------
发送一个字符串
------------------------------------------------*/
void SendStr(unsigned char *s)
{
while(*s!='\0')// \0 表示字符串结束标志,
//通过检测是否字符串末尾
{
SendByte(*s);
s++;
}
}