Nuoeriris · 2020年07月08日

MM32W无线MCU系列产品应用笔记——中断式例程

在上一章节,我们了解了MM32W0系列蓝牙模块的基本参数,也使用AT指令对模块进行了简单的操作,下面我们将对软件架构进行简单的讲解。
1.jpg
图1 蓝牙通信框图

MM32W0控制模块通过SPI通信对射频模块进行控制,MM32W0的蓝牙程序提供以库的形式提供给大家使用,用户无需了解蓝牙协议栈,只需要对MCU进行控制即可实现蓝牙控制。在协议栈中为方便用户使用预留接口函数,用户通过调用相关接口的方式实现对应功能。

以下几点需要注意:

  1. 控制模块SPI2 仅且只能用于与射频模块的通信。
  2. IRQ 信号引脚用于射频模块与控制模块的唤醒,且PB8 引脚只能用于控制模块唤醒。
  3. AVDD 供电电压为2.2V \~ 3.6V

目前蓝牙控制程序有两种类型:中断式和阻塞式,中断方式是是以中断服务的方式运行,适合于实现用户某功能需要占用较长CPU 时间但可以被任意打断的应用场景;阻塞方式是蓝牙协议运行的入口函数为ble\_run(),该函数不会返回,两种方式调用的接口函数都相同。

中断式例程介绍

中断服务程序方式运行的软件架构如下图所示。
2.jpg
图2 中断方式软件构架

main()函数:
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,配置系统时钟
{
RCC->CR|=RCC_CR_HSION;
RCC->CR |= RCC_CR_PLLON;
RCC->CFGR |= (uint32_t)RCC_CFGR_SW_PLL;
SysTick_Config(48000);
}
SleepStatus = 0;         //设置当前状态为唤醒
ble_run(0); 
}

中断式例程需要用到两个中断服务程序,一个是蓝牙IRQ 中断PB8对应的外部中断线,一个是实现SysTick 对应的中断。IRQ 对应的中断服务程序用以运行蓝牙协议,需要有较高的中断优先级(针对所有系统中断来说)。
 
UART,SPI,IRQ,USB等控制模块上的配置同阻塞方式。
 
SPIM\_Init(SPI2,0x06)是控制模块和射频模块间通信的初始化,SPI2只能用于与射频模块的通信。

IRQ\_RF将PB8设置为外部中断,用于实现IRQ外部唤醒功能,通过一个下降沿唤醒MCU。PB8 引脚只能用于控制模块唤醒。

uart\_initwBaudRate()是UART的初始化,对于两种封装对应的UART和GPIO接口不同。

不同点:

  1. 初始化蓝牙配置函数radio\_initBle()之前,需要先调用SetBleIntRunningMode()函数。
  2. 启动蓝牙调用ble\_run\_interrupt\_start()而不是ble\_run(),后面需要一个while(1)循环,可以将用户程序放在这里。
  3. 进入休眠模式的函数需要主动调用IrqMcuGotoSleepAndWakeup()函数,函数McuGotoSleepAndWakeup()不再被调用。根据启动蓝牙时的参数,射频模块将定时触发IRQ的外部中断唤醒MCU。
推荐阅读
关注数
6108
内容数
272
灵动MM32 MCU相关技术知识,欢迎关注~
目录
极术微信服务号
关注极术微信号
实时接收点赞提醒和评论通知
安谋科技学堂公众号
关注安谋科技学堂
实时获取安谋科技及 Arm 教学资源
安谋科技招聘公众号
关注安谋科技招聘
实时获取安谋科技中国职位信息