打印

全局变量 局部变量引发的问题

[复制链接]
12367|62
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
xyp749192072|  楼主 | 2010-5-5 22:04 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
本帖最后由 xyp749192072 于 2010-5-7 15:56 编辑

#include <reg52.h>
#include "intrins.h"
#define uchar unsigned char
#define uint  unsigned int
unsigned char code table[10] = {0x03, 0x9f, 0x25, 0x0d, 0x99, 0x49, 0x41, 0x1f, 0x01, 0x09};
uchar jump[4]={ 0xcc,0xcc,0xcc,0xcc};
uchar start[4]={0x44,0x44,0x44,0x44};
uchar read[4]={ 0xbe,0xbe,0xbe,0xbe};
uint temp;
uchar back[4];
uchar ret[4];
void delay(int z)  //以15um递增            
{ int x,y;
   for(x=0;x<110;x++)
     for(y=0;y<z;y++)
     ;
}
uchar reset() //复位四根缆
{ uchar flag,i;
   P1=0XFF;
   P1=0XF0;
   for(i=200;i>0;i--);         //延时 802 us time=1+2*i
    for(i=200;i>0;i--);
   P1=0XFF;
    for(i=60;i>0;i--);// 延时 120 us
   flag=P1&0x01;
  for(i=200;i>0;i--);// 延时 400us  满足 最小周期
  return flag;        //返回0则复位成功
}

void write_bit(uchar *wei) //wei地址存 P3^0         
{
  uchar i;
  uchar four=0;

  for(i=0;i<4;i++)
     four+=( ( *(wei+i) ) << i );//四通道位值转换成 一个数值
   P1=0XFF;
    P1=0;
   _nop_();
   _nop_();
   P1=four;
   for( i=30;i>0;i--);//满足最小 写周期
  P1=0XFF;
   
}
        
void write_byte(uchar *date)//data指向数据首地址     
{ uchar i,j;
  uchar a[4];

  for(i=0;i<8;i++)  
    {
        for(j=0;j<4;j++)
       a[j]=( ( *(date+j) ) >>i ) & 0x01;
     write_bit(a);               
    }               

}         

void read_bit()
{ uchar flag,i,bb;
   uchar aa=0;
   P1=0xff;
   P1=0;
  _nop_();
   _nop_();
   P1=0xFF;
   for(i=0;i<5;i++);
  flag=P1&0X0F;//只要低四位数值   
for(i=40;i>0;i--); //满足最小读周期

    P1=0xFF;                  //满足最大读时隙

   for(i=0;i<4;i++)//四通道数值 存到数组中             P2^0是第一个
    {  bb=(1<<i);
          aa=flag&bb;
          if(aa!=0)
            back=1;
          else
            back=0;
         }
   
}         
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
第一种:
uchar read_byte()
{
    uchar i,j;
    uchar mid;
    for(i=0;i<8;i++)
     {
            read_bit();
            for(j=0;j<4;j++)
                    {
               mid=back[j] <<i;
                ret[j]=ret[j]+mid;
                  
             }
      
     }
return ret[0];

}


第二种:
uchar  read_byte()
{  uchar ret[4]=【0】;
    uchar i,j;
    uchar mid;
    for(i=0;i<8;i++)
     {
            read_bit();
            for(j=0;j<4;j++)
                    {
               mid=back[j] <<i;
                ret[j]=ret[j]+mid;
                  
             }
      
     }
  return ret[0];

}


!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!

void display(uint tem)   
{
        P0 =table[tem / 100];
        P2 = 0x04;
        delay(10);
            P2=0;
        
        P0 =table[tem / 10 % 10];
        P2 = 0x02;
        delay(10);
                P2=0;
        
        P0 =table[tem % 10];
        P2 = 0x01;
        delay(10);
             P2=0;        

}
void main()
{                   uchar aa=0;
                     uchar bb=0;
                     P2 = 0x00;           
        while(1)
        {
                                reset() ;
                  write_byte(jump);
                write_byte(start);
                reset();
                write_byte(jump);
                write_byte(read);

                aa=read_byte();//低字节温度
        
                bb=read_byte()        ;//高字节温度
               
                       aa=aa&0XF8;
                       bb=bb&0X07;
                               temp=((bb*0XFF)+aa)*0.0625;
                           display(temp);        
        }
}


大家帮我看看,当采用第一种情况时候,我能采集到正确稳定的温度,当采用第二种情况时候,采集到的温度数字剧烈变化,且数字不正常。两者情况差别只在于全局变量和局部变量的分别,却造成这么大影响,谁能给解释一下?问了很多人都解释不了,只能到21ic上找牛人了

相关帖子

来自 2楼
冷漠| | 2010-5-6 17:24 | 只看该作者
本帖最后由 冷漠 于 2010-5-6 17:48 编辑

所以,根据22楼,使用全局变量时,下面的ret[0]+mid 初值并不等于 0+mid !正如26楼所说,ret[0]里面是上一次的结果数值。
......
   for(j=0;j<4;j++)
      (
               mid=back[j] <<i;
                ret[j]=ret[j]+mid;                   
        }
........



知道原因,只要修改第一种情况,在函数中添加一句全局变量赋初值0即可:

uchar read_byte()
{
    uchar i,j;
    uchar mid;


ret[0]=0;  ret[1]=0; ......

    for(i=0;i<8;i++)
     {
            read_bit();
            for(j=0;j<4;j++)
                    {
               mid=back[j] <<i;
                ret[j]=ret[j]+mid;
                  
             }
      
     }
return ret[0];

}



使用特权

评论回复
板凳
yewuyi| | 2010-5-5 22:12 | 只看该作者
呵呵,21IC你最牛拉...

使用特权

评论回复
地板
NE5532| | 2010-5-5 22:20 | 只看该作者
给你一个最牛的答案好了:你程序有问题。

使用特权

评论回复
5
jerkoh| | 2010-5-6 08:24 | 只看该作者
这问题 唉~~~
楼主 全局变量可以返回!
但你写的局部变量  函数不是uchar 类型

使用特权

评论回复
6
ayb_ice| | 2010-5-6 08:46 | 只看该作者
我猜不着
你这什么东东

使用特权

评论回复
7
gmgmgm| | 2010-5-6 09:39 | 只看该作者
何为高手?你不知道要读懂别人编的程序是件多痛苦的事情吗?要人家帮你弄清你的问题出在哪,还得叫人家必须先读懂你的的程序,哎~~

使用特权

评论回复
8
cly1005| | 2010-5-6 09:44 | 只看该作者
void read_byte()
{
   .........
   return ret[0];
}
牛人,这个也编译得通!用的哪个编译环境?

使用特权

评论回复
9
冷漠| | 2010-5-6 10:10 | 只看该作者
本帖最后由 冷漠 于 2010-5-6 10:39 编辑

这么简单的问题:(也许没全看懂)
在第二种情况下, uchar ret[4]=【0】; 被设为自动变量,自动变量是被分配在动态变量区的,(位于全局静态变量区下面)动态变量区内的自动变量是所有函数内部变量共享的,是随函数调用改变而随时可以被覆盖的!所以,当调用下面两个函数的时候:
........
aa=read_byte();//低字节温度
bb=read_byte();//高字节温度
........

LZ的 uchar ret[4]=【0】; 根本不是同一个分配 ret[4]  组合了!它随两次 read_byte( );  调用而被分配到了两(次)组不同的 ret[4] 单元。

若想在 read_byte( )函数中使用私有ret[4],  应该将其说明为局部静态变量,这样 ret[4]  将被分配在静态变量区域,而不会被共享、覆盖:
uchar   read_byte( )
{  static uchar ret[4];    // 自动初始化为0;
    uchar i,j;
    uchar mid;
......

那还差不多。

或者就是4楼说的更简单的原因:uchar    read_byte(  ){......}  这类错误是否应该在编译阶段就能检出?

使用特权

评论回复
10
xyp749192072|  楼主 | 2010-5-6 12:03 | 只看该作者
void read_byte()
{
   .........
   return ret[0];
}
牛人,这个也编译得通!用的哪个编译环境?
cly1005 发表于 2010-5-6 09:44


牛人一词引来你帮我找毛病,虽挨批,但值了! 你说的这个原因,是我粘帖子时候,忘改了,我机子上程序,是uchar型的。

使用特权

评论回复
11
夏风| | 2010-5-6 12:05 | 只看该作者
牛X........................   上来就一顿代码,喊只准高手看...   21还是你最牛.

使用特权

评论回复
12
xyp749192072|  楼主 | 2010-5-6 12:10 | 只看该作者
这么简单的问题:(也许没全看懂)
在第二种情况下, uchar ret[4]=【0】; 被设为自动变量,自动变量是被分配在动态变量区的,(位于全局静态变量区下面)动态变量区内的自动变量是所有函数内部变量共享的,是随函数 ...
冷漠 发表于 2010-5-6 10:10


非常感谢你的点评,很到位,但好像我没说清楚,我不想在read_byte()函数里私自使用ret数组,只想返回ret【0】给主函数使用,为什么定义成局部变量我的温度采集正确,定义成全局变量采集不正确,这是我问题的核心。非常感谢!

使用特权

评论回复
13
xyp749192072|  楼主 | 2010-5-6 12:11 | 只看该作者
void read_byte()
{
   .........
   return ret[0];
}
牛人,这个也编译得通!用的哪个编译环境?
cly1005 发表于 2010-5-6 09:44

粘帖子的时候忘改了,原型是uchar型的, 看来,你不是牛人,净找小毛病》

使用特权

评论回复
14
xyp749192072|  楼主 | 2010-5-6 12:15 | 只看该作者
这问题 唉~~~
楼主 全局变量可以返回!
但你写的局部变量  函数不是uchar 类型
jerkoh 发表于 2010-5-6 08:24

谢谢  ,特此声明:这个低级错误是粘帖子的时候不小心整的,实际不存在这种错误,现在问题依旧,谁给看看,是不是定义成全局变量 ,对其他部分造成影响了?

使用特权

评论回复
15
chiack26| | 2010-5-6 12:30 | 只看该作者
路过,看看牛X是怎样回答的

使用特权

评论回复
16
928315| | 2010-5-6 12:43 | 只看该作者
14# chiack26

观望。。。

使用特权

评论回复
17
jiabin1024| | 2010-5-6 12:52 | 只看该作者
新手观看!

使用特权

评论回复
18
jiabin1024| | 2010-5-6 13:01 | 只看该作者
第二种情况“ uchar ret[4]=【0】;
语句撒意思啊

使用特权

评论回复
19
mohanwei| | 2010-5-6 13:18 | 只看该作者
围观牛人&单片机高手……

使用特权

评论回复
20
e掾木| | 2010-5-6 13:29 | 只看该作者
你这个程序去参加C 乱码大赛一定会提名。高人啊

使用特权

评论回复
21
一棵小草| | 2010-5-6 13:31 | 只看该作者
要当牛人,就得先看懂程序----------

算了,牛人太苦了,飘过,等待牛人诞生------------

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

1

主题

77

帖子

1

粉丝