【待续】Arduino踩坑手册-《中断故障排查指南》-中断、串口、定时器等片内硬件资源之间的冲突
有個老師說:Arduino這玩意 更多的時候是兒童玩具 這話說的不錯
我還挺愿意把這話推廣一下 :過度封裝(而不讀文檔)是萬坑之源
各位可以發(fā)現(xiàn):很多稍微高級一些的操作與arduino庫函數(shù)共用就會出現(xiàn)奇怪的問題
編者本著刨根問底的精神 看了些官方庫源碼 現(xiàn)將這幾天的研究結(jié)果總結(jié)如下
時間所限,如有疏漏之處還請各位看官指正
一、定時器相關(guān)
arduino uno(atmega328p)帶有三個定時器T0,T1,T2。T0和T2是8位定時器,T1是16位定時器,當(dāng)noInterrputs函數(shù)執(zhí)行之后,這三個計時器都會罷工。
1.不靠譜的tone,delay,millis函數(shù)
tone函數(shù):
是利用T2定時器實現(xiàn)異步定時蜂鳴的,使用MsTimer2時要注意避免與tone發(fā)生沖突(癥狀:tone會影響MsTimer2的時鐘周期)。
這里可以考慮使用外國友人制作的TimerFreeTone庫,本質(zhì)上是軟件實現(xiàn)的蜂鳴輸出,沒直接用定時器,但是用了millis(軟蜂鳴音與定時器產(chǎn)生的蜂鳴信號可能不是一個波形,用耳朵仔細聽會發(fā)現(xiàn)兩者音色不同,有強迫癥的朋友要小心了)
delay函數(shù)與millis函數(shù):
是利用T0定時器實現(xiàn)延時,計時的,只要你不瞎調(diào)T0有關(guān)的寄存器,正常使用是沒問題的。
什么時候T0有關(guān)的寄存器會被更改呢?請看“PWM相關(guān)”一節(jié)。
2.題外話:VisualStudio相關(guān)
VisualStudio有個良心插件:VisualMicro,可以為用戶提供對Arduino調(diào)試的功能,然而Atmega xx8系列(Uno)統(tǒng)統(tǒng)是不支持JTAG調(diào)試的(兒童玩具實錘),剩下的方案就只有利用定時器實現(xiàn)軟調(diào)試,這個良心插件做到了軟調(diào)試,然而:
已知軟調(diào)試的不能做的:
- 在不經(jīng)任何處理的情況下,在attachInterrupt等中斷服務(wù)函數(shù)里跟蹤變量值
- 在一切比定時器優(yōu)先級高的中斷面前仍能守住控制權(quán)
- 在noInterrupts之后與上位機保持聯(lián)系
- 從兒童玩具變成實用工具
除非你能保證本文里提到的除adc、串口外的一切資源,你都不會使用,否則用它很難讓你開心的調(diào)試。
二、attachInterrupt、Serial.event、Wire.begin等中斷相關(guān)
這個是用來設(shè)置外部中斷的(相似的有IIC從機模式中斷設(shè)置函數(shù)、串口中斷設(shè)置函數(shù)(MsTimer2的中斷函數(shù)設(shè)置暫時沒發(fā)現(xiàn)有下述問題)),通常會引發(fā)一些很迷的問題(“萬物皆失靈,中斷行不行。“),比如IIC設(shè)備輸出失靈,計時函數(shù)失靈
1.異常原因
進入使用attachInterrupt設(shè)置過的中斷函數(shù)前,arduino 會執(zhí)行noInterrupts函數(shù),關(guān)閉自己和比自己優(yōu)先級低的中斷(優(yōu)先級更低的中斷是否被關(guān)閉了有待考證)
2.異常名單
已測試可用的:
- Serial.println()
- pwm輸出
已測試有異常的:
- IIC OLED輸出失靈
- delay,tone瞬間完成
- millis不計時
3.解決方法
在需要恢復(fù)定時器中斷的地方使用sei();恢復(fù)中斷
例子:
三、PWM相關(guān)
arduino uno一共有6個PWM輸出腳,他們是基于定時器做輸出的
不同的引腳工作時占用的定時器不同(這里就可能有時鐘周期無意間被改動了的問題)
列表如下:
| 5\6 | T0 |
| 9\10 | T1 |
| 11\3 | T2 |
如果你發(fā)現(xiàn)你設(shè)置的定時器本來應(yīng)該每一秒做某事,結(jié)果這個周期突然就變了,可以考慮從這個方向排查一下,更換一組不與目前正在用的定時中斷沖突的PWM引腳
已經(jīng)發(fā)現(xiàn)的異常
- MsTimer2與tone()共用,結(jié)果MsTimer2突然飛快計時
- (猜測)TimerOne與9/10腳pwm輸出同時使用,可能導(dǎo)致TimerOne周期異常
四、ADC相關(guān)
stc15系列做adc查詢推薦了一種中斷式查詢方案,在這里我想說,幸虧arduino沒用這個方案,所以目前看來analogRead()應(yīng)該是你做過的最安全的事情之一,這個函數(shù)是阻塞式查詢的(這幾乎是廢話,因為異步查詢的函數(shù)一定會讓開發(fā)者提供個回調(diào)函數(shù),或是個存返回值的地址,而analogRead顯然沒有)——在adc采完樣之前,cpu會一直等著,卡在while循環(huán)里等著adc忙位回零。
但是仍然要小心,adc查詢過程可能會被中斷打斷,這就可能影響你采集數(shù)據(jù)的時效性,怎么說呢,analogRead還是挺耗時的,這就容易被中斷攔腰斬,所以,在時效性采集項目里,請管好你的中斷!
(未完待續(xù) 歡迎各位指正)
總結(jié)
以上是生活随笔為你收集整理的【待续】Arduino踩坑手册-《中断故障排查指南》-中断、串口、定时器等片内硬件资源之间的冲突的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Linux配置本机ssh免登陆(解决启动
- 下一篇: MTK外部音频功放gpio控制