首页 诗词 字典 板报 句子 名言 友答 励志 学校 网站地图
当前位置: 首页 > 教程频道 > 嵌入开发 > 单片机 >

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

2013-02-24 
【A/D转换串口通讯】请教几个大家基础问题~我最近学习2530时,需要用到一个温湿度传感器,我通过官方给的资料

【A/D转换 串口通讯】请教几个大家基础问题~
我最近学习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++;
  }
}

单片机?数模转换?串口通讯?A/D
[解决办法]
 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楼的问题,你把那个自动换行勾掉看看


[解决办法]
【问题一】上面的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。楼主应该刚刚开始学的吧!!!
看完书这些都不是问题了!!

热点排行