【A/D转换 串口通讯】请教几个大家基础问题~

嘤鸣求友 2013-01-28 10:35:58
我最近学习2530时,需要用到一个温湿度传感器,我通过官方给的资料和单片机知识可以把温湿度信息传到电脑中了,但其中一些程序段没有理解,在此向各位前辈、朋友、同学们请教(问题在注释中):
 
/*-----------------------------------------------
名称:串口通信
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++;
}
}

...全文
283 6 打赏 收藏 转发到动态 举报
写回复
用AI写文章
6 条回复
切换为时间正序
请发表友善的回复…
发表回复
shagua0916 2013-01-31
  • 打赏
  • 举报
回复
兴趣是成功最好的帮手,不要急,慢慢来!
嘤鸣求友 2013-01-30
  • 打赏
  • 举报
回复
引用 2 楼 wangfan027 的回复:
while((!P2_0)&&U8FLAG++); 这个是等待P2_0变高,后面的U8FLAG++是用来处理超时的,你看他的初始值是2,每次+1,直到+满回到0然后超时退出等待. void COM(void)//这个函数不好理解,我就把它当做A/D转化函数,即每次调用时,把模拟信号的值传递给U8comdata 这个函数说简单点就是一个软件模拟……
楼上真是高手,让我晕了一周的东西大部分得以理解~ 我是觉得单片机很好玩,没有经过系统的学习,可能只重视结果没注意细节——我觉得这也是我很难深入了解的根源吧。 最近买了一本 郭天祥 的《51单片机C语言教程》,准备花两周时间看完呢,希望系统的学习对我有用。 还有阁下说到 自动换行勾掉,我勾去后,果然正常了,但是却无法换行——我的想法是,没传一次换一次行,但是U8 dispbuf1[]="hum= temp= \n";中的\n似乎没有用,不知这是为什么呢? 再次感谢~
嘤鸣求友 2013-01-30
  • 打赏
  • 举报
回复
感谢阁下的关注与回答,让我受益匪浅——我接触单片机有一段时间了,就是串口通信第一次接触~ “看完书这些都不是问题了!! ”——我学单片机纯粹是兴趣,没有受过系统的学习,这个问题我也发现了,听人家说《51单片机C语言教程》不错,我买了本在看呢~ 在此顺便再请教下,如何让串口通信自动换行?似乎字符串中的"\n"没有用?
fengfengzhi 2013-01-30
  • 打赏
  • 举报
回复
【问题一】上面的P2_0永远为1,这里if里面的东西应该永远不会运行呀 P2_0=1;是向引脚输出“1”,而if(!P2_0)离得P2_0是读引脚的值(即读入外部输入P2_0引脚的值),还有单片机的P2脚是准三态的,一般要先输出“1”,再读引脚。 【疑问三】这里我看定义为 sbit TI = SCON^1; 但不知道是什么意思? 这是单片机串口通信的相关问题,单片机串口没发完一个字节后TI标志位会自动置“1”,必须手动清零,才能再次发送。SCON是串口控制寄存器,他的第一位即SCON^1就是TI。楼主应该刚刚开始学的吧!!! 看完书这些都不是问题了!!
dceacho 2013-01-29
  • 打赏
  • 举报
回复
while((!P2_0)&&U8FLAG++); 这个是等待P2_0变高,后面的U8FLAG++是用来处理超时的,你看他的初始值是2,每次+1,直到+满回到0然后超时退出等待. void COM(void)//这个函数不好理解,我就把它当做A/D转化函数,即每次调用时,把模拟信号的值传递给U8comdata 这个函数说简单点就是一个软件模拟UART接收的函数. while(!TI);//【疑问三】这里我看定义为 sbit TI = SCON^1; 但不知道是什么意思? 这个教科书上有,使用硬件UART发送数据时若发送成功则TI会置1(如果对应中断开的话会触发中断,不过发送时间很短一般没必要开发送中断) 【问题一】上面的P2_0永远为1,这里if里面的东西应该永远不会运行呀 P2_0是模拟UART的接收线,是会"变"的 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); COM()是串口接收函数,接收到的数据放在U8comdata中, "当四个数值全传完才串口通信,不知这样理解对不对?" 不通信怎么能把数值传过来呢? //把对应的数字放置在 字符数组 中准备传送、、问题是,为什么不直接赋值,而是通过另外一个数组转化? 这个可能是考虑到结果数组可能其他地方还要用到所以就单独弄了一个数组存放读到的结果 2楼的问题,你把那个自动换行勾掉看看
嘤鸣求友 2013-01-28
  • 打赏
  • 举报
回复
哦,还有我输出的结果错位,不知是为什么,不知有没有人遇到这种问题?我没有设定大小和换行符呀~
见上图

27,382

社区成员

发帖
与我相关
我的任务
社区描述
硬件/嵌入开发 单片机/工控
社区管理员
  • 单片机/工控社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧