最近由於國賽的原因,開始學STM32,看不完全手冊和M3權威手冊,有一些問題,關於SETENA和CLRENA,他們兩個都是只能寫1,寫0會無效,但同時他們兩個都是可讀可寫的,既然可讀,那讀出來的東西就應該有意義有規律,應該能反映中斷的使能除能狀態,不然硬體設計師沒理由把這東西設計成可讀的。於是我就在想,假設我先對使能位寫一,然後對除能為寫一,那麼此時使能位應該是什嗎?理論推測,應該是0;這應該是一種反饋機制;(網上沒有查到相應的資料,M3裡面寫得也不是很詳細,所以此時只能是猜測),不過下面的程式簡單地驗證了這個猜想的反饋機制。
#include "sys.h"#include "delay.h"#include "usart.h"#define SETENA0(*((volatile unsigned long *)0xE000E100))#define CLRENA0(*((volatile unsigned long *)0xE000E180))#define SETPEND0(*((volatile unsigned long *)0xE000E200))#define CLRPEND0(*((volatile unsigned long *)0xE000E280))int main(void){//unsigned long t1 = 0;//unsigned long t2 = 0;Stm32_Clock_Init(9);delay_init(72);uart_init(72, 9600);//SETENA0 = 0x00080000;//SETENA0 = 0x00000000;//CLRENA0 = 0x00080000;//SETENA0 = 0x00080000;//SETPEND0 = 0x00040000;//SETPEND0 = 0x00000000;//CLRPEND0 = 0x00040000;//SETPEND0 = 0x00040000;//delay_ms(10);printf("process1:\n");printf("INPUT-: \tSETENA0:0;\tCLRENA0:0\n");delay_ms(10);SETENA0 = 0x00000000;CLRENA0 = 0x00000000;printf( "SETENA0:%lx\n" , SETENA0);printf( "CLRENA0:%lx\n" , CLRENA0);printf("process2:\n");printf("INPUT-: \tSETENA0:0;\tCLRENA0:1\n");delay_ms(10);SETENA0 = 0x00000000;CLRENA0 = 0x00080000;printf( "SETENA0:%lx\n" , SETENA0);printf( "CLRENA0:%lx\n" , CLRENA0);printf("process3:\n");printf("INPUT-: \tSETENA0:1;\tCLRENA0:0\n");delay_ms(10);SETENA0 = 0x00080000;CLRENA0 = 0x00000000;printf( "SETENA0:%lx\n" , SETENA0);printf( "CLRENA0:%lx\n" , CLRENA0);printf("process4:\n");printf("INPUT-: \tSETENA0:1;\tCLRENA0:1\n");delay_ms(10);SETENA0 = 0x00080000;CLRENA0 = 0x00080000;printf( "SETENA0:%lx\n" , SETENA0);printf( "CLRENA0:%lx\n" , CLRENA0);/***交換順序*/printf("switch the case:\n\n************************\n\n");printf("process5:\n");printf("INPUT-: \tCLRENA0:0;\tSETENA0:0\n");delay_ms(10);CLRENA0 = 0x00000000;SETENA0 = 0x00000000;printf( "SETENA0:%lx\n" , SETENA0);printf( "CLRENA0:%lx\n" , CLRENA0);printf("process6:\n");printf("INPUT-: \tCLRENA0:0;\tSETENA0:1\n");delay_ms(10);CLRENA0 = 0x00000000;SETENA0 = 0x00080000;printf( "SETENA0:%lx\n" , SETENA0);printf( "CLRENA0:%lx\n" , CLRENA0);printf("process7:\n");printf("INPUT-: \tCLRENA0:1;\tSETENA0:0\n");delay_ms(10);CLRENA0 = 0x00080000;SETENA0 = 0x00000000;printf( "SETENA0:%lx\n" , SETENA0);printf( "CLRENA0:%lx\n" , CLRENA0);printf("process8:\n");printf("INPUT-: \tCLRENA0:1;\tSETENA0:1\n");delay_ms(10);CLRENA0 = 0x00080000;SETENA0 = 0x00080000;printf( "SETENA0:%lx\n" , SETENA0);printf( "CLRENA0:%lx\n" , CLRENA0);//printf( "SETPEND0:%lx\n" , SETPEND0);//printf( "CLRPEND0:%lx\n" , CLRPEND0);/*while(1){printf("t:%d\n", t);delay_ms(500);t++;}*/}
以下是串口調試出來的結果
process1:INPUT-: SETENA0:0; CLRENA0:0SETENA0:0CLRENA0:0process2:INPUT-: SETENA0:0; CLRENA0:1SETENA0:0CLRENA0:0process3:INPUT-: SETENA0:1; CLRENA0:0SETENA0:80000CLRENA0:80000process4:INPUT-: SETENA0:1; CLRENA0:1SETENA0:0CLRENA0:0switch the case:************************process5:INPUT-: CLRENA0:0; SETENA0:0SETENA0:0CLRENA0:0process6:INPUT-: CLRENA0:0; SETENA0:1SETENA0:80000CLRENA0:80000process7:INPUT-: CLRENA0:1; SETENA0:0SETENA0:0CLRENA0:0process8:INPUT-: CLRENA0:1; SETENA0:1SETENA0:80000CLRENA0:80000
結果驗證了反饋的猜想,程式中,將使能和除能所有的賦值情況和複製順序都考慮進去了;但是帶來了一個新的問題,為什麼一開始對使能位寫一,除能位自動置一呢?這幾種情況中,所有的使能和除能無論怎麼寫,之後都會保持一致的狀態。這有什麼用處嗎?有什麼深意嗎?只能猜測這是為了方便,無論讀取的是使能位還是除能位,隨便讀取一個中斷寄存器,只要是1就是使能,只要是0就是除能。
當然這一切都只是根據現象做出的猜測,期望有瞭解硬體的大神給予令人信服的解釋,不勝感激。