這個帖子/viewthread.php?tid=40962&highlight=%E4%B8%B2%E5%8F%A3
static void UartInterruptService(void) interrupt 4
{
ES = 0;
RI = 0;
uart_process(SBUF);
ES=1;
}
復制代碼原帖說
為了防止在處理數據過程中不受干擾,通常在處理接受數據前關閉中斷,處理完后再開。
真不知道什么干擾?
加入這兩句話“ES = 0”“ES = 1”有什么用?
是不是對自己的程序不自信?還是慣性!??
我看除了如存在更高級別中斷,啥種情況能形成干擾?
多謝
網友評論:看9樓的第一條。
網友評論:我覺得這再容易理解不過了,ES=0,ES=1,這就好比你正在做手頭某個重要的事情,你先把你的手機調靜音(就==ES=0)讓他不要來打斷你,當你做完了這個事關閉靜音(==ES=1),因為或許你有重要的電話聽不見,我覺得這沒什么好說的,你卻一直說錯了,我的第一點就是這個意思
網友評論:ES = 1; 的功能是什么? 在串口中斷里還有可能再進入串口中斷嗎?
網友評論:其實當我看了第一句話后就不愿再往下看了,關閉串口中斷沒什么用??,你去試試。你試試當你把串口收到的數據再發到電腦上來,你在發的程序里不要寫ES=0,ES=1。我勸你去試試再說
網友評論:你怎么知道我沒試過? 是不是回帖的人只有你一個人試驗過?本來是你自己程序有問題,還非要關閉串口中斷,你這樣表面上是解決問題了,但在你關閉串口中斷的時間內,就接收不到數據了,好好一個全雙工串口被你給搞成半雙工的了。
網友評論:你錯就錯這里,關了串口中斷就收不到數據了。
網友評論:你看清楚了,樓主貼的程序,ES=1;是在串口中斷里,在串口中斷里寫這句一點用都沒有。據你的描述,你所謂的“把串口收到的數據再發到電腦上來”發送是在主程序里,而不是中斷里。我跟你講不明白,因為你滿腦子都是錯誤觀點。你慢慢悟吧,如果一周之內你還覺得自己是對的,那只能說明你不適合做這行。
網友評論:
首先要理解51只有2級中斷,同級別再分優先位。
1.高優先級:
因為中斷程序不執行RETI指令,即不放棄對高優先級的控制,即使優先級
排位較高的中斷也無法嵌套中斷。ES=0也無任何意義。
2.低優先級:
高優先級中斷不會理會ES=X而會強行嵌套。
對于同級別中斷,同時發生中斷請求時才有“中斷優先響應”問題。
當某中斷響應進入中斷后,它就是同級的“王道”~~~“王道就是霸道”
只有在它執行了RETI指令后其他高級或被掛起的同級中斷才能按級別或優先位
再次爭奪中斷控制權~~~
參見:“中斷隱身”
網友評論:你錯就錯這里,關了串口中斷就收不到數據了。
鮮為人知 發表于 2009-12-13 11:25
請問在你用查詢方式發送數據的過程中,關閉串口中斷還怎么接收數據?
網友評論:我看錯了問題,第二點確實沒必要說。我不知道Ls的還有20L做沒做過串口通訊,不要來了就扣頂錯了的大帽子,如果錯了就指出來。如果你只是天天看著書來說,我想說那你還沒有真正了解這個東西。我這幾天就在搞串口通訊 ...
鮮為人知 發表于 2009-12-13 10:46
51和STM32接收都一樣的。對于發送,STM32比51多一種方式.
網友評論:這個程序又不是教科書上的,難免有不成熟的地方。
按作者的意思,大概是擔心在處理串口中斷的過程中被其它中斷所搶占。但關閉串口中斷允許(ES=0)根本起不到保護這個中斷不被搶占的作用。
其實如果怕串口中斷被其 ...
desert_hawk 發表于 2009-12-11 22:12
你對51的中斷體系不了解!
網友評論:你對51的中斷體系不了解!
李冬發 發表于 2009-12-13 13:54
沒下文了? 請賜教一下?
網友評論:你對51的中斷體系不了解!
李冬發 發表于 2009-12-13 13:54
大俠咋理解的?say兩句!?
網友評論:你對51的中斷體系不了解!
李冬發 發表于 2009-12-13 13:54
大俠咋理解的?say兩句!?
xlsbz 發表于 2009-12-13 14:43
這位大俠除了說我不了解,別的什么也說不出來了。我只能說,我對這位大俠“心中”的51不太了解。
網友評論:你看清楚了,樓主貼的程序,ES=1;是在串口中斷里,在串口中斷里寫這句一點用都沒有。據你的描述,你所謂的“把串口收到的數據再發到電腦上來”發送是在主程序里,而不是中斷里。我跟你講不明白,因為你滿腦子都是錯 ...
desert_hawk 發表于 2009-12-13 11:29
我覺得你不適合討論技術,或許適合上街賣大白菜,當菜販子。另外你在另一層問“如果用......發送,怎樣接收,你可以查詢接收”。
網友評論:我覺得你不適合討論技術,或許適合上街賣大白菜,當菜販子。另外你在另一層問“如果用......發送,怎樣接收,你可以查詢接收”。
鮮為人知 發表于 2009-12-13 16:00
菜販子比你混的好的有很多。。。。
我倒是很好奇,發送過程被接收中斷所打斷,是怎么導致你“發送的是亂數”的?查詢接收可以用,中斷接收卻不可以用?
網友評論:1.(假如你要將你接受到的數據通過串口發送)&&(沒有關中斷),那么可能你還沒有發送完就又開始來了接收中斷,那你發送的將是一串亂數據。所以要關閉中斷,當你把已經通過串口接收的數據發送完后在允許中斷。
2.當 ...
鮮為人知 發表于 2009-12-12 17:22
個人覺得,像這種水平還回帖,說的有鼻子有眼的,完全可以起到誤導廣大新人的作用。當然,回帖是每個人的權利和自由。
網友評論:菜販子比你混的好的有很多。。。。
我倒是很好奇,發送過程被接收中斷所打斷,是怎么導致你“發送的是亂數”的?查詢接收可以用,中斷接收卻不可以用? ...
desert_hawk 發表于 2009-12-13 16:12
那是價值觀的問題,不是混的好與壞的問題。
可能不止好奇這一點吧,我就不來回答你的問題了,我覺得這是個很簡單的問題,但你卻不這么認為,因為你說讓我去研究一周,哈哈。那你慢慢研究吧,但不要說“你不適合搞什么”這之內的,因為你甚至根本不了解別人在做什么。除非那人什么都沒做,才可能被你說中,但那就毫無意義了,好了吧,因為這是技術貼,討論這些也沒什么用,如果我錯了,但只要不至于引導人走向犯罪 就沒什么的
網友評論:那是價值觀的問題,不是混的好與壞的問題。
可能不止好奇這一點吧,我就不來回答你的問題了,我覺得這是個很簡單的問題,但你卻不這么認為,因為你說讓我去研究一周,哈哈。那你慢慢研究吧,但不要說“你不適合搞什 ...
鮮為人知 發表于 2009-12-13 16:46
以你現在的發言,我真的很覺得你不適合做這一行。當然,只是個人看法。表達一下個人看法沒什么問題吧。
網友評論:1.(假如你要將你接受到的數據通過串口發送)&&(沒有關中斷),那么可能你還沒有發送完就又開始來了接收中斷,那你發送的將是一串亂數據。所以要關閉中斷,當你把已經通過串口接收的數據發送完后在允許中斷。
2.當 ...
鮮為人知 發表于 2009-12-12 17:22
我看錯了問題,第二點確實沒必要說。我不知道Ls的還有20L做沒做過串口通訊,不要來了就扣頂錯了的大帽子,如果錯了就指出來。如果你只是天天看著書來說,我想說那你還沒有真正了解這個東西。我這幾天就在搞串口通訊 ...
鮮為人知 發表于 2009-12-13 10:46
頂一下。讓更多的人看看這些“鮮為人知”的道理。看看號稱搞“串口通訊網絡”的牛人是怎么“真正了解”這么一個“很簡單的問題”的。
網友評論:技術只占很小一部分!但是也是立身之本!
網友評論:倒塌,我竟然把ES看成EA了。
投降!
網友評論:俺答的沒錯呀~~~
網友評論:俺答的沒錯呀~~~
hotpower 發表于 2009-12-14 04:28
問題是,某些“做過串口通訊”的“高手”是不會仔細看誰的回答的,唯一正確的是他自己心中的“實踐經驗”。
網友評論:好玩。誰都沒說到正根上。
還有19樓第一條確實理解有誤,“把接收來的數據再發送回去,......這時下一個接收數據中斷又到了,......”你做的是RS485 ?如果是RS232全雙工,發送—接收是兩個獨立的通道,不可能撞車的。否則是編程問題。做芯片的人都是絕頂聰明的人,不會設計那么差的
硬件中斷電路。
網友評論:再說LZ的問題,中斷內部電路有一個“優先級激活
觸發器”一旦CPU響應某一中斷,即將“優先級激活觸發器”置位,以阻斷同優先級和低優先級的所有中斷。只有RETI指令能夠清除“優先級激活觸發器”,從而再次打開所有中斷。
所以,當串口中斷發生,CPU響應并進入中斷之后,串口中斷當然自動被阻斷,即使你再次接收到多少數據,CPU在RETI結束之前都不會響應。
所以,在串口中斷內,“ES=0/1“,純粹是裝聰明。設計芯片的人沒那么笨,想不到這一點?
網友評論:
對19樓的第一條,還有一點:如果將接收緩沖器的數據搬移到發送緩沖器發送回去,進入發送緩沖器的數據將毫無阻礙地、不受任何干擾和控制地、由發送硬件時序電路發送出去,無論接收通道發生了什么事件、中斷不中斷,發送時序電路都會將緩沖器內的數據“義無反顧地”堅持發送完,并置位TI向CPU 告知“發送緩沖器空,可以輸入下一發送數據”。至于CPU是否響應TI的請求,那是CPU的事情。它可以因為正在處理RI中斷而對TI請求置之不理或者推后處理,因為RI顯然應該緊急性更高。
所以,MOVSBUF,DATA; 之后,發送動作已經開始,誰想或者誰能夠打亂、停止這個發送操作,可能“后悔莫及”。除非有人過于高明。
在那些成幀發送標準適配器中,例如:CAN,CSMA,HDLC,發送緩沖器一幀可能1,000字節之長連續發送,那里可以有CPU 半途廢棄,終止發送的指令。玩過嗎?
網友評論:呵呵,估計19樓的高手已經沒有勇氣再看這個帖子了。
網友評論:
52#
大俠很厲害!功力很深!
看看這個.........
執行下面的語句(單片機與電腦連接)
while (1) {
SBUF = 'a';
SBUF = 'b';
}
那么電腦能收到啥?
--------------------------
執行下面的語句(單片機與電腦連接)
while (1) {
SBUF = 'a';
SBUF = 'b';
SBUF = 'c';
}
那么電腦能收到啥?
--------------------------
執行下面的語句(單片機與電腦連接)
while (1) {
SBUF = 'a';
SBUF = 'b';
SBUF = 'c';
SBUF = 'd';
}
那么電腦能收到啥?
網友評論:MOVSBUF,DATA; 之后,發送動作已經開始,誰想或者誰能夠打亂、停止這個發送操作,可能“后悔莫及”。除非有人過于高明。
冷漠 發表于 2009-12-15 11:16
哈哈我想到一個辦法!!
MOVSBUF,DATA0 ;//這條語句用波特率較低速度運行比如說300
這里趕緊變換成速度快的波特率啊,換的越利索越好
MOVSBUF,DATA1 ;// 以速度快的波特率運行這句
那么DATA1不能追上DATA0的后幾位么?追上幾位就干掉幾位!
網友評論:停止發送是應該可以的,畢竟串口節拍需要一個定時器配合,所以讓那定時器停止就可以了
網友評論:哈哈我想到一個辦法!!
MOVSBUF,DATA0 ;//這條語句用波特率較低速度運行比如說300
這里趕緊變換成速度快的波特率啊,換的越利索越好
MOVSBUF,DATA1 ;// 以速度快的波特率運行這句
那么DATA1不能追上DA ...
xlsbz 發表于 2009-12-15 12:10
嗨 暈頭了!這種方法可行性可能只有一半吧!
網友評論:停止發送是應該可以的,畢竟串口節拍需要一個定時器配合,所以讓那定時器停止就可以了
5880527 發表于 2009-12-15 13:54
冷漠的意思是數據已經完全進入了移位
寄存器了!
定時器已經管不著了
網友評論:沒啥用,沒這兩句話,中斷返回前也不會進入新的串口中斷。
網友評論:58#
數據進入移位寄存器了也應該是受定時器管的,旁邊沒人吹口哨喊121了它也不走了
網友評論:60#
很抱歉,你的認識是錯誤的!
網友評論:有意思。一口米飯的吞咽動作已經完成,下咽到胃的結果好像已經不可控了。如何讓米飯不進入胃里而半途終止?
有人想了個辦法:那還不好辦,我給他心臟一槍,讓他生命即刻中止不就完啦?聰明!可惜,難怪咱們設計不出芯片。別人是在數據流的發送器出口上設計閘門硬件,咱們是在數據流的尾巴拽住它。東、西方思維的差別,連打鬼子都是“到敵人后方去,...”
還有個疑問:這兩種做法的最終后果是什么?
1、關閉發送器,經過恰當時間,再次打開時,發送緩沖器必為空。
2、停止發送時鐘,經過恰當時間再次開放時鐘時,發送緩沖器遺留的數據,將再次被驅動發到接收方,接收方對不完整殘幀數據是會有動作的,并且會產生異常中斷要求CPU來處理的。這恐怕不是發送端程序員的初衷吧。“多做之過。”
設計芯片的人早就設想到了第2種方法可能的后果,他不會連這點后果都考慮不到吧。——你給對方接收方(適配器)造成了什么;對方的適配器硬件如何設計處理你的發送異常。
再有一點,由于成幀發送標準都是由適配器采用同步技術按比特流發送的,所以芯片設計的關閉發送器電路是精確關閉點的;例如:它不會在停止域關閉發送器,即使這時你已經程控發出了異常停止發送指令。
呵呵,那么咱們想到的通過停止發送時鐘的方法能夠精確關閉點嗎?在停止位那一點突然停止了時鐘,這一幀白干啦?
再有沒想到的一點,....唉,想不到的技術還多呢。同步通信技術是怎么回事還沒搞清楚呢。咱們慢慢學吧。
也許還有什么更多的我們沒想到的東西?落后的差距就源于“不是做不到,而是想不到。”
網友評論:正好剛看完一篇報道《中國軍人不生疏》。意為現代戰爭,不怕敵強我弱,最怕對方采用的高科技武器咱們沒見過,不知道性能厲害。
想當年中越反擊戰,小小的越南竟然能夠以20:1 的弱勢兵力和中國對抗。結果不但有絕對的空中優勢,地面也是占盡便宜。全是美國最新武器,中國軍人不但沒見過,想都想不到。20個中國軍人一次只能仍一顆手榴彈,扔不到50米?美國的擲彈筒百米開外,一個人一次發射一片。距離夠不著對手,干挨打。最后的傷亡人數恐怕遠不止20:1 了。
所以,什么事多想想可能還有什么想不到的。否則別人35,000米高空施展打擊,束手無策干挨打了。
網友評論:大俠高論啊!深奧!
網友評論:52#
大俠很厲害!功力很深!
看看這個.........
執行下面的語句(單片機與電腦連接)
while (1) {
SBUF = 'a';
SBUF = 'b';
}
那么電腦能收到啥?
--------------------------
執行下面的語句(單片機與電腦連接)
while (1) {
SBUF = 'a';
SBUF = 'b';
SBUF = 'c';
}
那么電腦能收到啥?
--------------------------
執行下面的語句(單片機與電腦連接)
while (1) {
SBUF = 'a';
SBUF = 'b';
SBUF = 'c';
SBUF = 'd';
}
那么電腦能收到啥?
xlsbz 發表于 2009-12-15 12:00
這個程序是我剛學單片機的串口時弄的。
也是我發現的第一個keil軟件仿真不正確的程序。
最后的硬件運行結果是
SBUF = 'a';
則 上位機 收到的數據是
61 61 61 。。。。。。。。。
SBUF = 'a';
SBUF = 'b';
則上位機收到的數據是
61 62 62
61 62 62
61 62 62
.......
SBUF = 'a';
SBUF = 'b';
SBUF = 'c';
則上位機收到的數據是
63 62 61 63
63 62 61 63
63 62 61 63
63 62 61 63
63 62 61 63
用 SBUF = 'a';
SBUF = 'b';
SBUF = 'c';
SBUF = 'd';
則上位機收到的數據是
全部都是 61
可以看到無論什么情況,第一個發送的字符a總有機會發送成功。
有一點是肯定的:就是字符完全進入移位寄存器后,是以波特率的速度發送的。
另外這兩點也可能是對的:(1)字符完全移到移位寄存器外面后,其他字符才會進入到移位寄存器。(2)緩沖器的字符進入到移位寄存器是按照并行方式進入的,就是說是幾乎不花時間的。
網友評論:好題目。只是你沒有得到確定的結果。這個實驗換了我做,肯定會得到另一個結果。——說不清結論啦。
其實都是讓中國教授寫的書害的。剛看了一本美國教授寫的《8051微
控制器和嵌入式系統》,同樣也是RI/TI 的講述,幾句話就讓人——讓咱們中國的8051學習者茅塞頓開。怎么中國的教授寫的書就那么草根呢,連LS提出的幾個問題都講不清楚,20多年了,國人教授寫的8051教材比草還多了,有一本講清楚LS的問題了嗎?(待續)
網友評論:66#
多謝 推薦《8051微控制器和嵌入式系統》,
請問有PDF版本的《8051微控制器和嵌入式系統》么?我在網上沒有找到
網友評論:我是在互動出版網上買的。還有1、2本美國人寫的關于8051控制器,發現別人寫的就是不一樣。首先講述的是設計原理而不是使用方法。
所以,根據設計原理,你的實驗結果根本不用做實驗就知道結論了。——肯定是它。除非你變換了標準程序寫法。
網友評論:68#
我一直想找一本講多講原理少講例子的書
《8051微控制器和嵌入式系統》的PDF版我再找找看
推薦一本書《代碼大全》 絕對好書。 我閑著沒事就看!
網友評論:61#
呆會我去驗證一下,我總覺得它發送了半截后定時器重裝值改變了波特率也就會改變,而關閉那定時器發送也就終止了
網友評論:麻煩LS 順便做一下:發送半截,令TI=1;看看能否中止發送。這才是中外8051教材里講述的理論上的重要差別。也是中外教授頭腦思維的差別。可以引發出很多設計原理,寫一篇前人不曾寫過的碩士級別的論文。
像LS提出的2種方法無疑是肯定可行的,——人為破壞波特率的穩定條件,但是“有用”嗎?能證明什么理論問題?
UART的時鐘在具體應用中應該視為固定不變的穩定波特率,可編程的內部時鐘一旦初始化設置,顯然希望像固定振蕩源一樣穩定可靠。——結果2個方法都不能用了。我們只能從這些方面考慮問題?
網友評論:我和樓主xlsbz的方法都是有點鉆牛角尖了冷漠的觀點是別人設計單片機硬件時已經保證了串口的足夠可靠,這是正確的。
剛才試了一下,我的觀點是正確的,在數據送到SBUF后延時一段時間在數據還沒完全移位完成之前關閉定時器是能阻止數據的后面幾位移出的
網友評論:書本上有這樣一段“方式1和方式3的波特率可變,由定時器T1的溢出率決定”,所以停止定時器自然就沒了節拍信號
網友評論:做這樣的實驗顯然不能用循環發送,應該只發送一次。像這樣:
// while (1) {
SBUF = 'a';
SBUF = 'b';
SBUF = 'c';
while(1);
//}
還有:下面的寫法,將得到不同的結果。(只有從不同的結果中才能發現更多的東西。)
while (1) {
TI=1; // 關閉發送中斷條件下
SBUF = 'a';
SBUF = 'b';
SBUF = 'c';
TI=0;
while(1);
}
這正是中外教授的不同。中國的51教材上寫的是“TI=1表示發送器空;通知CPU可以送入下一數據。”“TI必須軟件清除為0。”
哈!為什么要軟件清除?TI=0應該表示發送器不空(滿),那么為什么硬件設計上不利用以發送器SBUF為目標的寫脈沖(MOVSBUF, #DATA )自動清零TI,而要把這個完全可以自動實現的操作留給用戶來軟件控制實施?——誰都清楚:中外教材上寫的很清楚:是MOVSBUF, #DATA 指令(寫脈沖)啟動了發送控制器發送開始。那么它同時自動清零TI不是很合理的設計嗎?為何留給用戶操作?(這里沒考慮清除中斷的作用。)
這就是中國教材上20年沒有講清楚的地方。
所以,可以展開想象:軟件CLR TI; 是有控制作用的。而不僅僅是復位中斷申請信號。
SETB TI ; //關中斷條件下
MOVSBUF,#DATA;
會發生什么?
網友評論:樓上做的這個研究有點意思,以前還真沒做過類似試驗,現在手頭也沒有51的板子,沒法試了,胡亂猜測一下:看了下51的串口內部結構圖,發送似乎是單緩沖,即發送SBUF即是緩沖器又是移位寄存器,所以在啟動一次發送后,單片機會有一種“保護機制”保護當前正在發送的SBUF內的數據不被改寫,在此期間“寫SBUF”的操作是不起作用的,直到發送完成后,TI置位,用戶軟件對TI進行清除后,才撤銷了這種保護機制,所以“TI = 0;”的作用,一是清除中斷標志,二有可能就是撤銷這種保護機制了。猜的,如果不對,請別拍磚,呵呵。
網友評論:浮云 都是浮云啊.........