簡 介: 本文給出了 MicroPython內核開發筆記:書內嵌入實驗任務 中的 mem32 軟件用例部分內容。
關鍵詞
:MicroPython,MM32F3277,mem32
利用 MicroPython 中一組可以直接訪問 MCU 內存的函數,mem8、mem16、mem32,可以分別按4字節、2字節、1字節訪問內存空間。 MCU 中的絕大多數功能模塊所對應的控制寄存器都分布在 ARM 內核存儲空間裡,因此 借助於這組內存訪問函數,不僅可以直接繞過 MicroPython 內核對MCU進行操作,提高軟件運行速度,更重要的是,能夠實現在 MicroPython內核中尚不具備的功能,或者部分功能存在缺陷需要修正。
下面通過一些具體示例來展示這方面的應用。
在 MM32F3277 內核中,具有兩個 模擬比較器:COMP1,COMP2,它們掛載在內部 APB2 總線上。
▲ 圖1.1.1 MM32F3277 內部功能模塊以及訪問總線
在現在的 MicroPython 內核中,並沒有將模擬比較器的相關功能實現。可以通過 mem32 函數來對模擬比較器進行初始化,並讀取比較器輸出狀態。
模擬比較器掛載在 APB2總線上,在使用之前,需要通過RCC控制器使能COMP1,COMP2的時鐘。
下面代碼是通過 APB2寄存器使能 模擬比較器時鐘。
RCC_BASE = const(0x40021000)
APB2ENR = const(RCC_BASE+11*4)
APB1ENR = const(RCC_BASE+12*4)
mem32[APB2ENR] |= 0x8000
根據 MM32F3277 數據手冊,查到模擬比較器對應的控制器存內部功能定義。具體如下圖所示。
▲ 圖1.1.2 模擬比較器的控制寄存器
通過改變該寄存器設置,可以選擇模擬比較器的輸入管腳,輸出管腳,以及工作模式。詳細情況可以參見MM32F3277數據手冊。 模擬比較器的輸出(OUT)位於比較控制寄存器的第30位。
下面代碼使能 COMP1,2。
COMP_BASE = const(0x40014000)
COMP_CSR1 = const(COMP_BASE+0xc)
COMP_CSR2 = const(COMP_BASE+0x10)
COMP_CRV = const(COMP_BASE+0x18)
COMP_POLL1 = const(COMP_BASE+0x1c)
COMP_POLL2 = const(COMP_BASE+0x20)
mem32[COMP_CSR1] |= 0x1
mem32[COMP_CSR2] |= 0x1
根據上面設置,兩個模擬比較器的輸入分別為 PA0(正向輸入端)、PA4(反向輸入端)。 通過以下代碼可以查看兩個比較器的輸出。
print('%08x'%mem32[COMP_CSR1])
print('%08x'%mem32[COMP_CSR2])
設置 PA0 為高電平, PA4 為低電平。查看比較器的輸出為:
40000001
40000001
可以看到結果中 30 位是 1,表示比較器輸出高電平。
設置 PA0 為低電平,PA4為高電平。查看比較器的輸出為:
00000001
00000001
結果中的 30位是0, 比較比較器輸出為低電平。可以看到 CSR 中的 OUT 位置反映了外部電壓比較的結果。
上面給出了通過 mem32 直接訪問單片機模擬比較器控制寄存器,實現比較器工作的方法。大家也可以進一步研究 MM32F3277 數據手冊,開發模擬比較器的新的使用方法。
在當前 MicroPython 中 PWM功能實現中,存在一個缺點,那就是 PWM 頻率精度會出現比較大的誤差。其中的原因就是 PWM 定時器的 ARR 被固定在 999,定時器的 CNT 的計數范圍是 0 ~ 999。 通過設置 PWM 的 duty 數值,可以使得 PWM 的占空比的變化精度為 1/1000。但這也帶來了 PWM 頻譜與設置頻率之間存在著較大的誤差。
下圖給出了設置 PWM 的頻率從 500 到 2000Hz 之間變化,通過外部頻率計實際測量輸出信號的頻率,它們之間的絕對誤差隨著設定頻率的不同而發生變化。特別是當設定頻率越高,可能產生的誤差越大。
▲ 圖1.2.1 PWM信號頻率誤差隨著頻率設定值產生的變化
產生誤差的原因來自於 PWM 定時器中的分配計數器只能取整數。 假設單片機定時器的工作頻率來自於 MCU 主頻,對應頻率為 f o s c = 120 M H z f_{osc} = 120MHz fosc=120MHz 。對於 A R R = 999 ARR = 999 ARR=999 ,PWM 的頻率是由 TIM3/TIM4 預分頻計數器的數值決定。 f P W M = f o s c ( 1 + P S C ) ⋅ ( A R R + 1 ) f_{PWM} = { {f_{osc} } \over {\left( {1 + PSC} \right) \cdot \left( {ARR + 1} \right)}} fPWM=(1+PSC)⋅(ARR+1)fosc 由於 PSC 必須采用整數,所以對應輸出 f P W M f_{PWM} fPWM 會存在一定的誤差。
如果針對 PWM 頻率誤差,同時調整 ARR 的取值,使其能夠補償由於 PSC 取整所帶來的的誤差。下面代碼利用了 mem32 函數直接對定時器中的 ARR 進行修改,使其補償頻率誤差。
#------------------------------------------------------------
from micropython import const
APB1PERIPH_BASE = const(0x40000000)
TIM3_BASE = const(APB1PERIPH_BASE + 0x0400)
TIM4_BASE = const(APB1PERIPH_BASE + 0x0800)
TIM_TYPE_CR1 = const(0*4)
TIM_TYPE_CR2 = const(1*4)
TIM_TYPE_SR = const(4*4)
TIM_TYPE_CNT = const(9*4)
TIM_TYPE_PSC = const(10*4)
TIM_TYPE_ARR = const(11*4)
TIM_TYPE_CCR1 = const(13*4)
TIM_TYPE_CCR2 = const(14*4)
TIM_TYPE_CCR3 = const(15*4)
TIM_TYPE_CCR4 = const(16*4)
def pwmFreq(f, pwm):
fosc = 96e6
psc = int(fosc/f/1000) - 1
arr = int(fosc/(1+psc)/f) - 1
if pwm < 4: base = TIM3_BASE
else: base = TIM4_BASE
mem32[base+TIM_TYPE_PSC] = psc
mem32[base+TIM_TYPE_ARR] = arr
return arr
經過實際測量,PWM 的輸出頻率與設定頻率之間的誤差基本上在 0.1% 左右,這就極大提高的 PWM 頻率的精度。
本文給出了 MicroPython內核開發筆記:書內嵌入實驗任務 中的 mem32 軟件用例部分內容。
■ 相關文獻鏈接:
● 相關圖表鏈接: