今天 调试一个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; //存储队尾地址
才解决错误
有时间好好考虑下 感觉
全局变量 是个关键