小弟再使用stm32F1 時,遇到了一個蠻怪的問題 想跟版上大神們求救
1. 我宣告了這樣的變數
//==========================
struct out00_bit_def{
u8 bit0 :1; // y00
u8 bit1 :1; // y01
u8 bit2 :1; // y02
u8 bit3 :1; // y03
u8 bit4 :1; // y04
u8 bit5 :1; // y05
u8 bit6 :1; // y06
u8 bit7 :1; // y07
}
union{
struct out00_bit_def bit;
u8 byte;
}out00;
//==========================
2. 我在主程式中會使用下面的敘述,去改變 bit2 或 bit3 的狀態
out00.bit.bit2 = 1;
out00.bit.bit2 = 0;
out00.bit.bit3 = 1;
out00.bit.bit3 = 0;
3. 我在 timer中斷副程式中會使用下面的敘述,去改變 bit6 或 bit7 的狀態
out00.bit.bit6 = 1;
out00.bit.bit6 = 0;
out00.bit.bit7 = 1;
out00.bit.bit7 = 0;
4. 很怪的問題是,當我程式RUN起來後,偶發性的會發生
中斷副程式有執行過改變 bit6 或 bit7 的狀態,但Memory中的bit卻沒有改變
只有在timer中斷中執行改變的那些bit會出現異常
發生異常的情況像是中斷時執行out00.bit.bit6 = 1; 但執行後bit6沒有為1
或是中斷時執行 out00.bit.bit6 = 0; 但執行後bit6沒有為0
主程式中所執行的bit狀態完全不會有異常
5. 我猜測有可能是當主程式執行到類似 out00.bit.bit6 = 1; 這行程式時恰巧發生中斷,
當主程式執行到 out00.bit.bit6 = 1; 時,雖然只是一行 C語法程式,但實際 CPU執行的行為依序是
a) 將記憶體中的 out00.byte 載入到 cpu的暫存器
b) 將這個 CPU暫存器的值 OR 0x40
c) 將暫存器的值回寫到記憶體中 out00.byte
假設主程式執行到上面 a)動作之後,發生 timer中斷,timer中斷副程式中執行了 out00.bit.bit6 = 1;
然後結束中斷後回到主程式繼續從上面的 b)動作往下執行
因為這樣而發生了 timer中斷副程式中所作的動作無效(bit的狀態沒有被改變),
事實上是timer中斷副程式的動作有執行 bit6狀態的改變了,只是回到主程式後又被覆蓋回先前的資料
6. 我為了要確認上面假設是對的,我宣告了另一個物件
union{
struct out00_bit_def bit;
u8 byte;
}out01;
然後我在主程式中使用下面這樣的敘述去修改 bit2 或是 bit3的狀態
out01.bit.bit2 = 1;
out01.bit.bit2 = 0;
out01.bit.bit3 = 1;
out01.bit.bit3 = 0;
也就是說,主程式中只能改變 out01.byte裡面的值 , timer中斷副程式中只能改變 out00.byte裡面的值
最終要拿出來使用的時候使用以下敘述
a = out00.byte | out01.byte;
所得到的值就能夠正常,完全不會有"變更bit的狀態被 Lost"的事情發生
因為上面的測試,所以我猜測是因為主程式運行中,遇到timer中段所導致的問題
A. 我在其他的單片機上從沒發生過這樣的問題
B. 雖然目前用上面方法可以暫時規避問題,但如果我在主程式跟中斷成是中要操作相同的一個bit 還是會面臨同樣的問題
想問問板上各位大神們 有沒有遇過這樣的問題 何解?
友情提示: 此问题已得到解决,问题已经关闭,关闭后问题禁止继续编辑,回答。
2,这种定义位操作实际上都是对同一个u8变量进行“读-改-写”操作,所以在中断和主循环中要保证互斥访问(最简单的互斥是“关中断-改变量-开中断”);
一周热门 更多>