你好,
我使用3 GPIO作为唤醒计时器源。两个源总是在同一个级别上触发(一个低一个高),第三个源总是在两个级别上触发(在IRQ例程期间,我切换这个GPIO的触发器)。我没有去抖动时间(0毫秒),我希望至少有一个源发生时中断(计数器比较阈值为1)。一切正常。两个第一源总是在其预期级别上触发,而第三源总是在两个级别上触发。
// init序列:
hw_wkup_set_counter_threshold(1);
hw\u wkup\u set\u debounce\u time(0);
//等等
但是,当至少两个来源同时发生时,永远不会调用IRQ例程;而永远(我已经观察到中断例程,只有在两个源同时发生时才被调用)。如果我使用调用我的IRQ例程的软件看门狗,则此调用解锁系统,唤醒定时器中断再次抛出(因为我认为,IRQ条件 - GPIO级别和/或触发条件 - 在看门狗呼叫期间更新)。
我已阅读文档:
事件计数器是边缘敏感。检测到A.
活动边必须首先检测反向边
在它返回空闲状态之前
开始等待新的主动边缘。
是我的问题吗?我无法绕过这个条件!我无法更改源级别(GPIO级别),我无法更改触发级别(因为我不知道我是否在死锁条件下)......
任何答复都将非常欣赏。
问候,
Guillaume B.
设备:
你好,我是gbmej,
当您的同时发出中断时,我不会看到任何问题,唤醒控制器的中断不会触发的是,例如,如果允许说明您,则唤醒控制器的中断将不会触发。已配置为从3个不同的GPIO唤醒设备,并且触发手机对于剩余的两个和高电平,对于剩余的GPIO而高。现在,如果那些中断已经被置位(前两者的前两个或高度的一个来源的低电平),则不会发生中断,直到断言的引脚将被解除断言。所以也许这就是你正在遇到的,而不是在中断同时触发时。
谢谢你的对话
你好,
谢谢你的回答。我已经进行了更多的调查,以减少我的用例。我现在有一个GPIO中断在高到低的变化和另一个在每个中断切换。我观察到当GPIO 2的变化发生在GPIO 1中断之后,没有问题。但是如果更改发生在gpio1中断结束之前,但在gpio2检查之后,我就有了锁
唤醒处理程序()
{
hw_wkup_reset_interrupt();
if(checkgpio1condition())performgpio1job();
if(checkGPIO2COndition())performGPIO2Job();//切换触发器
//如果gpio2条件在gpio1中断期间在这里发生变化(我们称为performgpio1job()但不是performgpio2job())我有问题(GPIO中断从不抛出GPIO2。如果GPIO2条件发生在IRQ常规之后,我没有问题。
}
通过看门狗,我已经在锁定(执行但没有JOB2的作业)之后检查了GPIO状态:GPIO1高,GPIO2应该抛出中断......
问候,
Guillaume B.
你好,我是gbmej,
我不确定我完全得到了这一点,你提到的部分当你锁定时让我感到困惑,试图复制你所提到的内容,我在HRP_Sensor中完成了以下测试,它已经实现了一个唤醒源。触发“静态”唤醒源触发低电平,默认引脚配置是上拉更改唤醒源(中断例程中的配置更改配置)具有最初相同的手机,以及执行更改的代码在下面连接。
//全局变量
__保留的HW\u GPIO\u MODE my\u GPIO\u MODE=HW\u GPIO\u MODE\u INPUT\u PULLUP;
__ retated hw_gpio_func my_gpio_function;
静态void wkup_cb(空白)
{
#如果dg_configBLACK_ORCA_IC_REV==黑色_ORCA_IC_REV_A
hw_wkup_reset_counter();
#结束
hw_wkup_reset_interrupt();
hw_gpio_get_pin_function(cfg_start_advertising_trigger_1_gpio_port,cfg_start_advertising_trigger_1_gpio_pin,&my_gpio_mode,&my_gpio_function);
if(my_gpio_mode == hw_gpio_mode_input_pulldown){
my_gpio_mode = hw_gpio_mode_input_pullup;
}其他{
my\u gpio\u mode=HW\u gpio\u mode\u INPUT\u下拉列表;
}
hw_gpio_set_pin_function(cfg_start_advertising_trigger_1_gpio_port,cfg_start_advertising_trigger_1_gpio_pin,my_gpio_mode,hw_gpio_func_gpio);
hw_wkup_configure_pin(cfg_start_advertising_trigger_1_gpio_port,cfg_start_advertising_trigger_1_gpio_pin,true,
my_gpio_mode!= hw_gpio_mode_input_pulldown?hw_wkup_pin_state_low:hw_wkup_pin_state_high);
hw_cpm_trigger_sw_cursor()//这将有助于在每次中断触发时用一条细红线标识电源探查器中的中断
hrp_wkup_cb();
}
在periph_init():
hw_gpio_set_pin_function(cfg_start_advertising_trigger_1_gpio_port,cfg_start_advertising_trigger_1_gpio_pin,my_gpio_mode,hw_gpio_func_gpio);
只要触发中断,然后从触发状态释放行,都会出现在触发状态,因此应该检查上面的片段上的更改以及引脚的唤醒状态如何基于该中断用于检查默认引脚配置HW_GPIO_SET_PIN_FUNCTION()的默认引脚,HW_GPIO_GET_PIN_FUNCTION()用于设置正确的默认PIN状态(与先前中断命中相反)。
谢谢你的对话
你好,
非常感谢您的答案,但我没有问题触发器切换。当GPIO中断发生在另一个GPIO中断时,我有一个问题。这是我的伪代码(请参阅附件)。
- GPIOA中断每40毫秒发生一次。GPIOA任务责任GPIOA水平从低到高(它是清除传感器中断的传感器读数)。
- GPIOB中断每200ms发生一次。当电平从高到低电平时,抛出第一个中断。我们切换扳机以检查较低。任务GPIOB强制GPIOB从低电平返回高(驱动GPIOB信号的源)。然后抛出第二个中断,并再次拨动。它就像是一个按钮来获取新闻/发布事件,但源无法释放,直到考虑按事件进行按。
除了这个用例外,其他一切都很好:
[t+0ms中断1]
- GPIOA降低
- 抛出中断
-有效的GPIOA条件:我们唤醒GPIOA任务
- 无效的gpiob条件:我们不会切换gpiob触发器,我们不会唤醒gpiob任务
- 我们留下了中断
[任务GPIOA在T + 1ms]
- 我们读了传感器
- GPIOA水平返回高位
[T + 33ms的中断2]
-GPIOB调低
- 抛出中断
- 无效的GPIOA条件:我们不唤醒GPIOA任务
- 有效的GPIOB条件:我们切换GPIOB触发器,我们唤醒GPIOB任务
- 我们留下了中断
[T + 34MS的任务GPIOB]
- 我们确认GPIOB级别让源工作(大约6到8毫秒)
[在t+40ms时中断3]
- GPIOA降低
- 抛出中断
-唤醒GPIOA任务(有效的GPIOA条件)
-我们没有唤醒GPIOB任务(无效的GPIOB条件)
- 我们留下了中断
[T = + 41ms的任务GPIOA]
- 我们读了传感器
- GPIOA水平返回高位
如果GPIOB从低到高的级别在中断3之后更新(我们留下了中断向量例程),则没有错误。如果此更新发生在检查GPIOB中断条件之后,但在离开中断向量例程之前,则不再抛出中断。这是锁。我认为内部唤醒状态机保持在KEY\u RELEASE状态,因为GPIOA的KEY\u hit返回到零,但同时GPIOB的KEY\u hit变为1。。。
再次感谢你的帮助
纪尧姆
你好,我是gbmej,
你的意思是,M0正在执行一个按钮按下的ISR时没有中断?那是对的吗 ?这与唤醒控制器无关,而是M0和NVIC如何运行,如果处理器在执行中断处理程序时进行中断,因为两个中断都具有相同的优先级,因此挂起的中断标志将是相同的设置为1,一旦上一个ISR被执行,它将再次调用它来服务挂起的中断,并且就我测试了这正是68倍的所做中断。
现在在你的例子中,我看到你的管脚配置了下拉和上拉的内部电阻,我可以想象这就是中断锁定的原因,如果外部设备没有在特定状态下正确地驱动线路,可能会发生上拉,并保持唤醒控制器的中断信号至少为一个管脚源断言,我认为是切换其状态的管脚源,这就足够不发生中断,唤醒控制器在报告另一个中断之前等待中断被断言。因此,您可以尝试在确定外部传感器正确驱动线路的情况下不使用内部上拉,或者如果您想使用内部电阻器,则应将电阻器的默认状态更改为触发唤醒的相反状态,就像我在上一篇文章中提到的,使用hw\u gpio\u set\u pin\u函数()来更改默认的pin配置。
谢谢你的对话
你好,
我锁定了唤醒定时器中断,而不是另一个中断。一旦我有一个锁定(几秒钟后;我的代码在几秒钟内工作良好),唤醒定时器中断永远不会再抛出。当我在唤醒定时器中断功能由于GPIOA级别的变化和GPIOB的条件刚刚在检查GPIOB条件后而且在中断结束之前变得有效时,我有锁定。
我尝试过GPIO引脚重新配置(输入拉起然后向上向上等)+ UDPate的触发电平,没有更多的结果。
GPIOA任务在GPIOA interrup上被唤醒(使用freertos二进制信号量)。就在GPIOA任务唤醒之后,我将GPIOB状态存储在RAM中(level,trigger)。当我遇到锁(看门狗)时,我打印GPIOB状态:中断条件得到满足,但没有抛出中断(唤醒计时器中断)。如果我将此GPIOB状态与GPIOA中断期间的GPIOB状态进行比较(就在离开唤醒计时器中断之前,我也将其存储在RAM GPIOB状态中),我可以看到GPIOB条件在ISR(唤醒计时器中断)结束之前不满足,但在ISR结束之后满足。锁定40毫秒后,GPIOA的条件再次满足,但中断(唤醒计时器中断)不会抛出。
如果在我的看门狗回调期间,我称之为唤醒中断功能,这会解锁锁,然后中断继续工作......
谢谢你的帮助
纪尧姆
你好,我是gbmej,
唤醒定时器中断是我所讨论的,源可能是许多引脚,但唤醒定时器的中断是一个。如果有一个唤醒中断和ISR执行,然后在ISR执行期间又一次击中相同的中断,则将设置待处理的位(WKUP_GPIO_IRQN),并且只要ISR提供服务即可重新调用以服务待处理打断。
也许发生了以下情况,GPIOA变低(及其低触发),因此ISR运行,并且您提到任务正在读取传感器的状态以释放中断,因此瞬间有一个句点xGPIOA中断发生在断开中断的那一刻,即唤醒控制器不会接受来自其他源(包括GPIOB)的中断,因为GPIOA的状态仍然被断言,它与...不一定GPIOB中断的条件,如果仍然追随GPIOA,因此仍然触发GPIOB。
尝试使用分析仪检查信号并确保在信号断言时没有重叠,这意味着当另一个中断发生时,另一个不正常断言,因为这是唯一可以停止的条件唤醒控制器。
谢谢你的对话
你好
我更新了我的代码要使用闩锁模式(第4.3章)。结果更好。但是,我有一个关于清除中断的问题:函数
硬件启动复位中断
在具有多个中断源的示例中永远不会调用。这是一个错误吗?问候,
Guillaume B.
你好,我是gbmej,
hw_wkup_reset_interrupt()是API函数而不是回调函数,因此必须由任何用户指定的中断回调调用,以清除中断标志。如果您不调用此函数,则应用程序将永远不会调用,因此这不是错误。有关更多信息,请阅读3.2中的步骤#2。初始化功能章节的关键点,从我们的支持页面启动项目教程。
谢谢,下午好