MM32W無線MCU系列產(chǎn)品應用筆記——中斷式例程
在上一章節(jié),我們了解了MM32W0系列藍牙模塊的基本參數(shù),也使用AT指令對模塊進行了簡單的操作,下面我們將對軟件架構進行簡單的講解。圖1 藍牙通信框圖
MM32W0控制模塊通過SPI通信對射頻模塊進行控制,MM32W0的藍牙程序提供以庫的形式提供給大家使用,用戶無需了解藍牙協(xié)議棧,只需要對MCU進行控制即可實現(xiàn)藍牙控制。在協(xié)議棧中為方便用戶使用預留接口函數(shù),用戶通過調(diào)用相關接口的方式實現(xiàn)對應功能。
以下幾點需要注意:
1)控制模塊SPI2 僅且只能用于與射頻模塊的通信。
2)IRQ 信號引腳用于射頻模塊與控制模塊的喚醒,且PB8 引腳只能用于控制模塊喚醒。
3)AVDD 供電電壓為2.2V ~ 3.6V
目前藍牙控制程序有兩種類型:中斷式和阻塞式,中斷方式是是以中斷服務的方式運行,適合于實現(xiàn)用戶某功能需要占用較長CPU 時間但可以被任意打斷的應用場景;阻塞方式是藍牙協(xié)議運行的入口函數(shù)為ble_run(),該函數(shù)不會返回,兩種方式調(diào)用的接口函數(shù)都相同。
中斷式例程介紹
中斷服務程序方式運行的軟件架構如下圖所示。
圖2 中斷方式軟件構架
main()函數(shù):
int main(void)
{
unsigned long temp=0x800000;
unsigned long i=0;
while(temp--);
SystemClk_HSEInit();
PWM_Init();
#ifdef USE_UART
#ifdef USE_AT_CMD
SleepStop = 0x02;
#endif
#endif
#ifdef USE_UART
uart_initwBaudRate();
#endif
#ifdef USE_I2C
IIC_Init(I2C1);
#endif
SysTick_Configuration();
SPIM_Init(SPI2,/*0x06*/0x06); //6Mhz
IRQ_RF();
SetBleIntRunningMode();
radio_initBle(TXPWR_0DBM, &ble_mac_addr);
SysTick_Count = 0;
while(SysTick_Count < 5){}; //delay at least 5ms between radio_initBle() and ble_run...
//ble_set_adv_data(pld_adv, LEN_ADV);
ble_run_interrupt_start(160*2); //320*0.625=200 ms
while(1)
{
//do sometging and sleep
//delay_ms(50);
IrqMcuGotoSleepAndWakeup();
}
}
在IRQ中斷服務中的常用配置如下:
void EXTI4_15_IRQHandler(void)
{
EXTI_ClearITPendingBit(EXTI_Line8);//確認是PB8引起的中斷
if(2 == SleepStatus) //從STOP模式喚醒,重新啟動HSI,配置系統(tǒng)時鐘
{
RCC->CR|=RCC_CR_HSION;
RCC->CR |= RCC_CR_PLLON;
RCC->CFGR |= (uint32_t)RCC_CFGR_SW_PLL;
SysTick_Config(48000);
}
SleepStatus = 0; //設置當前狀態(tài)為喚醒
ble_run(0);
}
中斷式例程需要用到兩個中斷服務程序,一個是藍牙IRQ 中斷PB8對應的外部中斷線,一個是實現(xiàn)SysTick 對應的中斷。IRQ 對應的中斷服務程序用以運行藍牙協(xié)議,需要有較高的中斷優(yōu)先級(針對所有系統(tǒng)中斷來說)。
UART,SPI,IRQ,USB等控制模塊上的配置同阻塞方式。
SPIM_Init(SPI2,0x06)是控制模塊和射頻模塊間通信的初始化,SPI2只能用于與射頻模塊的通信。
IRQ_RF將PB8設置為外部中斷,用于實現(xiàn)IRQ外部喚醒功能,通過一個下降沿喚醒MCU。PB8 引腳只能用于控制模塊喚醒。
uart_initwBaudRate()是UART的初始化,對于兩種封裝對應的UART和GPIO接口不同。
不同點:
① 初始化藍牙配置函數(shù)radio_initBle()之前,需要先調(diào)用SetBleIntRunningMode()函數(shù)。
②啟動藍牙調(diào)用ble_run_interrupt_start()而不是ble_run(),后面需要一個while(1)循環(huán),可以將用戶程序放在這里。
③ 進入休眠模式的函數(shù)需要主動調(diào)用IrqMcuGotoSleepAndWakeup()函數(shù),函數(shù)McuGotoSleepAndWakeup()不再被調(diào)用。根據(jù)啟動藍牙時的參數(shù),射頻模塊將定時觸發(fā)IRQ的外部中斷喚醒MCU。
編輯:ls 最后修改時間:2022-06-09