今天 調(diào)試一個020的數(shù)據(jù)處理程序碰到了一個問題,雖然已經(jīng)解決,但是還是有點不明白,先記錄在這里,以后有空的時候再好好 細(xì)細(xì)地想一下
我的原代碼如下:
#include <C8051f020.h>
#define SYS_CLK 22118400
typedef struct //存儲結(jié)構(gòu)體
{
unsigned char AD[93]; //2543的AD數(shù)據(jù)
unsigned char shi; //gprs的數(shù)據(jù)
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 //定義一個存儲地址結(jié)構(gòu)體
{
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為 字節(jié)高低選擇位為0 輸出抵字節(jié)位 為1輸出高字節(jié)位
{
unsigned char i;
AHH = 1;
for(i=0;i<50;i++); //等待穩(wěn)定
P3 = ADR; //ADR為全局變量 選擇存儲塊
for(i=0;i<50;i++); //等待穩(wěn)定
AHH = 0; //注意 每一個LU_B ADR組合 對應(yīng)4K的地址空間 每次換“塊”的時候均需先調(diào)用此函數(shù)
}
void save_struct(ram a) //將a存儲到FIFO 隊尾
{
ram xdata *p;
unsigned int i;
cunchu_Init();
ram_init(dui_wei.adr_suocun); //按隊尾地址結(jié)構(gòu)體中的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))
//存儲空間已經(jīng)用完 地址循環(huán)至最低地址
{ //此時最后一塊內(nèi)存 剛好存儲1937個字節(jié)
dui_wei.dptr_gao = 0x08; //dptr_di==1001 0001 dptr_gao==&&000 10 111
dui_wei.dptr_di = 0x00; //suocun已經(jīng)滿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個字節(jié)
{
p=(dui_wei.dptr_gao<<8)+dui_wei.dptr_di+114; //每幀數(shù)據(jù)長114個字節(jié) dptr值加上114;
dui_wei.dptr_di = (unsigned char)p;
i = p;
dui_wei.dptr_gao =i>>8;
}
else //2k空間已經(jīng)用完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 低八位全清零
{ //并觸發(fā)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過程中 要判斷是否需要切換高低字節(jié) 用完低字節(jié)后 再用高字節(jié)
{
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) //如果存儲速度大于讀取速度 則覆蓋最舊的數(shù)據(jù)
{ //使得隊首 向后移動一個 幀 從而丟棄最舊的數(shù)據(jù)幀
adr_add_change;
}*/
}
}
}
void sysclk_Init(void) //系統(tǒng)時鐘初始化
{
int i;
OSCXCN = 0x67; //啟動外部11.0592MHz震蕩器
for(i = 0;i<255;i++); //等待外部晶體起振
while((OSCXCN & 0x80)==0x00); //查詢標(biāo)志位 以判斷外部時鐘是否穩(wěn)定
OSCICN = 0x88; //使用外部震蕩器做系統(tǒng)時鐘并使能時鐘丟失檢測
CKCON = 0x10; //初始化T1時鐘為系統(tǒng)時鐘
}
void dog_Init(void) //看門狗設(shè)置為:關(guān)閉
{
EA = 0;
WDTCN = 0xde;
WDTCN = 0xad;
EA = 1;
}
void port_Init(void) //端口分配與輸入輸出方式
{
XBR2 = 0x44; //使能交叉開關(guān)和全局弱上拉 配置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; //配置外部存儲器為復(fù)用方式 只使用片外XRAM ALE脈寬為一個系統(tǒng)時鐘周期
EMI0TC = 0x6d; //配置外部存儲器的接口時序
}
void cunchu_Init1(void)
{
EMI0CF = 0x10;
EMI0TC = 0x6d;
}
在build的時候老出現(xiàn)如下錯誤:
segment does not fit
剛開始知道是內(nèi)部ram超限了
但是將
ram a 改成
xdata ram a
還是有問題
直到再將 全局變量
ADR_struct dui_shou; //存儲隊首地址
ADR_struct dui_wei; //存儲隊尾地址
改成
ADR_struct
idata dui_shou; //存儲隊首地址
ADR_struct
idata dui_wei; //存儲隊尾地址
才解決錯誤
有時間好好考慮下 感覺
全局變量 是個關(guān)鍵