C51中遇到一個(gè)有關(guān)data與xdata的問(wèn)題,已解決
環(huán)境:
我在某個(gè)C文件定義了一個(gè)結(jié)構(gòu)體變量,然后該變量只是在本文件內(nèi)被一個(gè)函數(shù)使用,然后又在中斷中調(diào)用了該函數(shù),目的是改變一個(gè)IO口的輸出狀態(tài),結(jié)果執(zhí)行時(shí)怎么也達(dá)不到要的效果。
structBE
{
unsignedintCountFR;//定時(shí)器計(jì)數(shù)值,通過(guò)改變計(jì)數(shù)值改變音頻頻率
unsignedcharPWR_time;//開(kāi)啟時(shí)間,單位為10mS
unsignedcharFREQ_time;//音頻供給時(shí)間,單位為10mS
unsignedcharindex;//音符計(jì)數(shù),指示當(dāng)前需要演奏的音符
};
structBEBeep;
/*******************************************************************************
*函數(shù)名:Timer1Int
*函數(shù)功能:定時(shí)器1中斷服務(wù)函數(shù),控制節(jié)拍時(shí)長(zhǎng)10ms
*輸入:無(wú)
*輸出:無(wú)
*******************************************************************************/
voidTimer1Int()interrupt3using3//采用中斷3控制頻率
{
if(flag==1)
{
TH1=(65536-10000)/256;
TL1=(65536-10000)%256;//10ms定時(shí)
//BeepControl();
Beep_control();
return;
}
//--進(jìn)入一次中斷,表明計(jì)數(shù)到了65536--//
Freq=Freq+65536;
}
現(xiàn)象:
使用示波器查看IO口輸出,奇葩的是當(dāng)斷開(kāi)外設(shè),引腳懸空時(shí)(51單片機(jī)輸出默認(rèn)是上拉為高的),在復(fù)位啟動(dòng)的情況下IO口輸出正常,但是在斷電啟動(dòng)的情況下,IO口輸出異常;當(dāng)引腳接外設(shè),外設(shè)是一個(gè)三極管,連基極,如果很快斷電重啟,輸出也為正常,只是偶爾會(huì)變形。在異常情況下,IO口輸出一直保持低電平,但是另一個(gè)IO口輸出正常,另一個(gè)IO口是在另一個(gè)優(yōu)先級(jí)較高的定時(shí)器里實(shí)現(xiàn)的。模擬仿真時(shí),輸出波形也是對(duì)的,就是實(shí)時(shí)運(yùn)行時(shí)不對(duì)。
/*******************************************************************************
*函數(shù)名:Timer0Int
*函數(shù)功能:定時(shí)器0中斷函數(shù),每隔TIME_MSms進(jìn)入
*輸入:無(wú)
*輸出:無(wú)
*******************************************************************************/
voidTimer0Int()interrupt1using1
{
staticunsignedintcount1s=0;
if(flag==1)
{
TH0=Beep.CountFR/256;
TL0=Beep.CountFR%256;
BUZZER_IO=~BUZZER_IO;
return;
}
解決方法:
將該結(jié)構(gòu)體變量添加data修飾就好了,如下:
datastructBEBeep;
現(xiàn)在還不知道為什么會(huì)這樣,添加之后,可以看編譯結(jié)果該變量存儲(chǔ)到data區(qū)域了,反正后面運(yùn)行均正常。具體原因,有時(shí)間再研究。