環境:
我在某個C文件定義了一個結構體變量,然後該變量只是在本文件內被一個函數使用,然後又在中斷中調用了該函數,目的是改變一個IO口的輸出狀態,結果執行時怎麼也達不到要的效果。
struct BE
{
unsigned int CountFR; //定時器計數值,通過改變計數值改變音頻頻率
unsigned char PWR_time; //開啓時間,單位爲10mS
unsigned char FREQ_time; //音頻供給時間,單位爲10mS
unsigned char index; //音符計數,指示當前需要演奏的音符
};
struct BE Beep;
/*******************************************************************************
* 函 數 名 :Timer1Int
* 函數功能 :定時器1中斷服務函數, 控制節拍時長 10ms
* 輸 入 :無
* 輸 出 :無
*******************************************************************************/
void Timer1Int() interrupt 3 using 3 //採用中斷3 控制頻率
{
if(flag == 1)
{
TH1=(65536-10000)/256;
TL1=(65536-10000)%256; //10ms定時
// BeepControl();
Beep_control();
return;
}
//--進入一次中斷,表明計數到了65536--//
Freq=Freq+65536;
}
現象:
使用示波器查看IO口輸出,奇葩的是當斷開外設,引腳懸空時(51單片機輸出默認是上拉爲高的),在復位啓動的情況下IO口輸出正常,但是在斷電啓動的情況下,IO口輸出異常;當引腳接外設,外設是一個三極管,連基極,如果很快斷電重啓,輸出也爲正常,只是偶爾會變形。在異常情況下,IO口輸出一直保持低電平,但是另一個IO口輸出正常,另一個IO口是在另一個優先級較高的定時器裏實現的。模擬仿真時,輸出波形也是對的,就是實時運行時不對。
/*******************************************************************************
* 函 數 名 :Timer0Int
* 函數功能 :定時器0中斷函數 , 每隔TIME_MS ms進入
* 輸 入 :無
* 輸 出 :無
*******************************************************************************/
void Timer0Int() interrupt 1 using 1
{
static unsigned int count1s = 0;
if(flag == 1)
{
TH0=Beep.CountFR/256;
TL0=Beep.CountFR%256;
BUZZER_IO = ~BUZZER_IO;
return;
}
解決方法:
將該結構體變量添加data修飾就好了,如下:
data struct BE Beep;
現在還不知道爲什麼會這樣,添加之後,可以看編譯結果該變量存儲到data區域了,反正後面運行均正常。具體原因,有時間再研究。