posts - 25, comments - 7, trackbacks - 0, articles - 0

调试020时候的一个问题

Posted on 2007-10-08 16:46 谢龙飞 阅读(341) 评论(0)  编辑 收藏 引用

今天 调试一个020的数据处理程序碰到了一个问题,虽然已经解决,但是还是有点不明白,先记录在这里,以后有空的时候再好好 细细地想一下
我的原代码如下:
#include <C8051f020.h>

#define SYS_CLK 22118400

typedef struct                      //存储结构体
{
  unsigned char AD[93];                //2543的AD数据
  unsigned char shi;               //gprs的数据
  unsigned char fen;
  unsigned char miao;
  unsigned long jingdu_zheng;
  unsigned long jingdu_xiao;
  unsigned long weidu_zheng;
  unsigned long weidu_xiao;
  unsigned char sudu_zheng;
  unsigned char sudu_xiao;
}ram;

typedef struct                        //定义一个存储地址结构体
{
  unsigned char  adr_suocun;          //锁存的8位地址
  unsigned char  dptr_gao;        //dptr
  unsigned char  dptr_di;
 
}ADR_struct; 

void sysclk_Init(void);
void dog_Init(void);
void port_Init(void);
void cunchu_Init(void);
void cunchu_Init1(void);
void ram_init(unsigned char ADR);
void save_struct(ram a);
ram read_struct(void);

sbit AHH  = P1^0;         //用通用I/O来控制访问地址
sbit LB   = P1^1;
sbit UB   = P1^2; 
sbit ALE  = P0^5;

ADR_struct  dui_shou;     //存储队首地址
ADR_struct  dui_wei;      //存储队尾地址
    

void main()
{
  unsigned char i;
  ram a;
  sysclk_Init();
  dog_Init();
  cunchu_Init();
  port_Init();
  UB   = 1;
  LB   = 0;
  dui_wei.adr_suocun=0;          //锁存的8位地址
  dui_wei.dptr_gao=0x08;        //dptr
  dui_wei.dptr_di=0;

 
  for(i=0;i<93;i++)
   a.AD[i]=i;
  a.shi = 2;
  a.fen = 2;
  a.miao= 2;
  a.jingdu_zheng= 2;
  a.jingdu_xiao=2;
  a.weidu_zheng=2;
  a.weidu_xiao=2;
  a.sudu_zheng=2;
  a.sudu_xiao=2;

  for(i=0;i<17;i++)
    save_struct(a);
  
 
}

void ram_init(unsigned char ADR)   //ADR为要锁存的A8-A15 LU_B为 字节高低选择位为0 输出抵字节位 为1输出高字节位
{
  unsigned char i;
  AHH = 1;
  for(i=0;i<50;i++);     //等待稳定
  P3   = ADR;             //ADR为全局变量 选择存储块
  for(i=0;i<50;i++);     //等待稳定
  AHH  = 0;                   //注意 每一个LU_B ADR组合 对应4K的地址空间 每次换“块”的时候均需先调用此函数

}

 

 

void save_struct(ram a)         //将a存储到FIFO 队尾
{
 
  ram xdata *p;
  unsigned int i;
  cunchu_Init();
  ram_init(dui_wei.adr_suocun); //按队尾地址结构体中的suocun初始化sram
  dui_wei.dptr_gao<<=8;
  p  = dui_wei.dptr_gao+dui_wei.dptr_di;
  *p = a;                       //存储a到队尾
 
                               
//以下代码为队尾地址变换
  if((dui_wei.dptr_di==0x91)&&(dui_wei.dptr_gao==0x17)&&(dui_wei.adr_suocun==0xff)&&(UB ==0))     
//存储空间已经用完 地址循环至最低地址
  {                                                                             //此时最后一块内存 刚好存储1937个字节                      
    dui_wei.dptr_gao = 0x08;                                                    //dptr_di==1001 0001 dptr_gao==&&000 10 111
    dui_wei.dptr_di = 0x00;                                                     //suocun已经满ff UB为有效
 dui_wei.adr_suocun = 0;
 UB = !UB;
 LB = !LB;
  }
  else
  {
    if((dui_wei.dptr_gao<<8)+dui_wei.dptr_di<=(1937-114))                      //2k空间最多只能存储17帧即:1937个字节
    { 
   p=(dui_wei.dptr_gao<<8)+dui_wei.dptr_di+114;                      //每帧数据长114个字节 dptr值加上114;
      dui_wei.dptr_di  = (unsigned char)p;
      i = p;
   dui_wei.dptr_gao =i>>8;

    }
    else                                           //2k空间已经用完dptr=1937=0000111 10010001时 移动到下一个2k块 切换
    {
   if(dui_wei.dptr_gao==0x0f)                   //将高八位从000 01 111 切换成 000 10 000 低八位全清零
   {
     dui_wei.dptr_di=0;
        dui_wei.dptr_gao ^=0x1f;
   }
   else if(dui_wei.dptr_gao==0x17)              //将高八位从000 10 111 切换成 000 01 000 低八位全清零
   {                                            //并触发adr_suocun + 1
     dui_wei.dptr_di=0;
  dui_wei.dptr_gao ^=0x1f;
  
//以下为adr_suocun + 1处理代码                                                                   
     if(dui_wei.adr_suocun==0xff)                 //adr_suocun + 1过程中 要判断是否需要切换高低字节 用完低字节后 再用高字节
     {
       LB = !LB;
       UB = !UB;
    dui_wei.dptr_di  = 0;
    dui_wei.dptr_gao = 0x08;                  //将高八位切换成000 01 000 低八位清零
    dui_wei.adr_suocun=0;
        }
     else                                         //未用完 不切换
     { 
          dui_wei.dptr_di = 0;                     //将高八位切换成000 01 000 低八位清零
    dui_wei.dptr_gao = 0x08;                   
          dui_wei.adr_suocun++;
       }
      }
 /*     if(dui_wei==dui_shou)                           //如果存储速度大于读取速度 则覆盖最旧的数据
      {                                               //使得队首 向后移动一个 帧 从而丢弃最旧的数据帧
        adr_add_change;
      }*/
    }
  }
   
}
 

void sysclk_Init(void)   //系统时钟初始化
{
  int i;
  OSCXCN = 0x67;                    //启动外部11.0592MHz震荡器
  for(i = 0;i<255;i++);            //等待外部晶体起振
  while((OSCXCN & 0x80)==0x00);  //查询标志位 以判断外部时钟是否稳定
  OSCICN = 0x88;                 //使用外部震荡器做系统时钟并使能时钟丢失检测          
  CKCON = 0x10;       //初始化T1时钟为系统时钟
}

void dog_Init(void)      //看门狗设置为:关闭
{
  EA    =  0;
  WDTCN =  0xde;
  WDTCN =  0xad;
  EA    =  1;
}
void port_Init(void)     //端口分配与输入输出方式
{
  XBR2      =  0x44;        //使能交叉开关和全局弱上拉 配置UART1引脚,外部存储器接口配置到低端口
  XBR0      =  0x04;       //配置UARTO引脚
  XBR1      =  0x00;        
  P0MDOUT   =  0xf5;        //UART的RX引脚总被配置成开漏输出 TX引脚为推拉输出 RD WR ALE 2543EOC均为推拉输出
  P3MDOUT    =  0xff;       //DT0-DT7
 
}


void cunchu_Init(void)
{
  EMI0CF = 0x0c;          //配置外部存储器为复用方式 只使用片外XRAM ALE脉宽为一个系统时钟周期
  EMI0TC = 0x6d;          //配置外部存储器的接口时序
 
}                        

void cunchu_Init1(void)
{
  EMI0CF = 0x10;
  EMI0TC = 0x6d;
}

在build的时候老出现如下错误:

segment does not fit

刚开始知道是内部ram超限了

但是将 ram a 改成 xdata ram a
还是有问题

直到再将 全局变量
ADR_struct  dui_shou;     //存储队首地址
ADR_struct  dui_wei;      //存储队尾地址

改成
ADR_struct  idata dui_shou;     //存储队首地址
ADR_struct  idata dui_wei;      //存储队尾地址

才解决错误

有时间好好考虑下 感觉 全局变量 是个关键

只有注册用户登录后才能发表评论。
网站导航: 博客园   IT新闻   BlogJava   博问   Chat2DB   管理