你好,
我使用3个GPIO作为唤醒定时器来源。两个源触发始终在同一级别(一个低点和一个高)和两个级别的第三个源(在IRQ例程期间,我切换此GPIO的触发器)。我没有比赛时间(0毫秒),我期待一旦发生至少一个源(计数器比较阈值为1)。一切都在运作良好。两个第一个源始终触发其预期水平和两个级别的第三个源触发器。
/ /初始化序列:
hw_wkup_set_counter_threshold (1);
hw_wkup_set_debounce_time(0);
//等等
然而,当至少两个源同时出现时,IRQ例程永远不会被调用;和forever(我观察到只有当两个源同时出现时才会调用中断例程)。如果我使用软件watchdog调用我的IRQ例程,这个调用将解锁系统,并再次抛出唤醒计时器中断(因为,我认为,IRQ条件- GPIO级别和/或触发条件-在watchdog调用期间更新)。
我已阅读文档:
事件计数器是边缘敏感。检测到A.
主动边缘必须首先检测反向边缘
在它回到空闲状态之前,从那里开始
开始等待一个新的活动边缘。
是我的问题吗?我不能绕过这个条件!我不能改变源电平(GPIO电平),也不能改变触发器电平(因为我不知道我是否处于死锁状态)…
任何回复都将不胜感激。
问候,
Guillaume B.
设备:
嗨gbmej,
我没有看到任何问题,当中断在同一时间发出,什么可能发生和中断从唤醒控制器将不会触发是当一个中断源已经断言,例如,如果让我们举例说,你已经配置从3个不同的gpios和触发器极化是低的前两个和高的其余一个。现在,如果一个中断已经被断言(低为前两个源之一或高为后一个源),那么没有中断将发生,直到断言引脚将被取消断言。所以,也许这就是你正在经历的,而不是当这些干扰同时被触发时。
谢谢mt_dialog.
你好,
谢谢您的回答。我已经进行了更多的调查以减少我的用例。我现在有一个GPIO中断,高于低变化,另一个在每个中断时切换的内容。当GPIO 2发生在GPIO 1中断之后发生时,我已经观察到,没有问题。但如果在GPIO结束之前发生变化1中断但是在GPIO 2检查后,我有锁定
kekuup_handler()
{
hw_wkup_reset_interrupt();
如果(checkGPIO1COndition ()) performGPIO1Job ();
if(checkgpio2condition())performgpio2job();//切换触发器
//如果gpio2条件在gpio1中断期间在这里发生变化(我们称为performgpio1job()但不是performgpio2job())我有问题(GPIO中断从不抛出GPIO2。如果GPIO2条件发生在IRQ常规之后,我没有问题。
}
通过看门狗,我检查了锁之后的GPIO状态(执行了job1但没有执行job2): GPIO1是HIGH, GPIO2应该抛出中断…
问候,
Guillaume B.
嗨gbmej,
我不确定我完全得到了这一点,你提到的部分当你锁定时让我感到困惑,试图复制你所提到的内容,我在HRP_Sensor中完成了以下测试,它已经实现了一个唤醒源。触发“静态”唤醒源触发低电平,默认引脚配置是上拉更改唤醒源(中断例程中的配置更改配置)具有最初相同的手机,以及执行更改的代码在下面连接。
//全局变量
__retated hw_gpio_mode my_gpio_mode = hw_gpio_mode_input_pullup;
__RETAINED HW_GPIO_FUNC my_gpio_function;
静态孔隙wkup_cb(空白)
{
#if dg_configblack_orca_ic_rev == black_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_gpio_mode = hw_gpio_mode_input_pulldown;
}
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状态(与先前中断命中相反)。
谢谢mt_dialog.
你好,
非常感谢你的回答,但我对触发按钮没有问题。我有一个问题,当一个GPIO中断发生在另一个GPIO中断。这是我的伪代码(见附件)。
- GPIOA中断每40毫秒发生一次。GPIOA任务责任GPIOA水平从低到高(它是清除传感器中断的传感器读数)。
—GPIOB中断每200ms发生一次。第一个中断被抛出时,电平从高到低。我们拨动触发器,现在检查LOW到HIGH。任务GPIOB强制GPIOB从LOW返回HIGH(驱动GPIOB信号的源)。然后第二个中断被抛出,我们再次切换。这就像一个按钮,获取新闻/发布事件,但源不能发布,直到考虑到新闻事件。
一切都适合,除了这个用例:
[T + 0ms的中断1]
—GPIOA进入LOW
中断被抛出
- 有效的GPIOA条件:我们唤醒GPIOA任务
- 无效的gpiob条件:我们不会切换gpiob触发器,我们不会唤醒gpiob任务
-我们离开中断
[任务GPIOA at t +1ms]
-我们读取了传感器
—GPIOA恢复到高
[在t +33ms时中断2]
- GPIOB转到低调
中断被抛出
- 无效的GPIOA条件:我们不唤醒GPIOA任务
- 有效的GPIOB条件:我们切换GPIOB触发器,我们唤醒GPIOB任务
-我们离开中断
[T + 34MS的任务GPIOB]
- 我们确认GPIOB级别让源工作(大约6到8毫秒)
[T + 40ms的中断3]
—GPIOA进入LOW
中断被抛出
- 我们唤醒GPIOA任务(有效的GPIOA条件)
- 我们唤醒gpiob任务(无效的gpiob条件)
-我们离开中断
[T = + 41ms的任务GPIOA]
-我们读取了传感器
—GPIOA恢复到高
如果在中断3(我们留下中断向量例程)之后更新GPIOB低至高电平,则没有错误。如果此更新发生在检查GPIOB中断条件后,但在离开中断向量例程之前,则不会抛出更多中断。这是锁。我认为内部唤醒状态机保持在key_release状态,因为GPIOA的KEY_HIT返回零,但同时,GPIOB的KEY_HIT转到1 ...
再次感谢你的帮助
guillaume.
嗨gbmej,
你的意思是,M0正在执行一个按钮按下的ISR时没有中断?那是对的吗 ?这与唤醒控制器无关,而是M0和NVIC如何运行,如果处理器在执行中断处理程序时进行中断,因为两个中断都具有相同的优先级,因此挂起的中断标志将是相同的设置为1,一旦上一个ISR被执行,它将再次调用它来服务挂起的中断,并且就我测试了这正是68倍的所做中断。
现在在您的情况下,我看到您的引脚配置了下拉和上拉的内部电阻,我可以想象这是锁定中断的原因,也许在外部设备未正确驱动特定线路的情况下状态将发生上拉并保持唤醒控制器的中断信号,用于至少一个引脚源,我假设是切换其状态的引脚源,这足以发生中断,并且唤醒控制器等待唤醒控制器对于在报告另一个中断之前要断言中断。因此,如果您确定外部传感器正常驱动线路,或者如果您想使用内部电阻,则可以尝试使用内部拉动UPS,或者您应该将电阻的默认状态更改为相反的电阻将触发唤醒的状态,使用HW_GPIO_SET_PIN_FUNCTION()在我的前一篇文章中提到的内容,以便更改默认引脚配置。
谢谢mt_dialog.
你好,
我锁定了唤醒计时器中断,而不是其他中断。只要我有了锁(几秒钟后;我的代码在几秒钟内工作得很好),唤醒计时器中断永远不会再次抛出。当我处于GPIOA级别变化的唤醒定时器中断功能中,并且GPIOB的条件在GPIOB条件检查之后变得有效,但在中断结束之前,我有锁。
我尝试了gpio引脚重新配置(输入拉上,然后下,然后上等)+触发级别的udpate,没有更多的结果。
GPIOA任务在GPIOA Interpup(使用Freertos二进制信号量)上展现。就在GPIOA任务唤醒之后,我将GPIOB状态存储在RAM(级别,触发器)中。当我遇到锁(看门狗)时,我打印GPIOB状态:满足中断条件,但没有中断(唤醒定时器中断)被抛出。如果我在GPIOA中断期间将这个GPIOB状态与GPIOB状态进行比较)但在ISR之后满意。在锁后40ms后,GPIOA的条件也非常满足,但不抛出中断(唤醒定时器中断)。
如果在我的看门狗回调,我调用唤醒中断功能,这解锁锁,然后中断继续工作…
守止你的帮助
guillaume.
嗨gbmej,
唤醒定时器中断是我所讨论的,源可能是许多引脚,但唤醒定时器的中断是一个。如果有一个唤醒中断和ISR执行,然后在ISR执行期间又一次击中相同的中断,则将设置待处理的位(WKUP_GPIO_IRQN),并且只要ISR提供服务即可重新调用以服务待处理打断。
也许发生了以下情况,GPIOA变低(及其低触发),因此ISR运行,并且您提到任务正在读取传感器的状态以释放中断,因此瞬间有一个句点xGPIOA中断发生在断开中断的那一刻,即唤醒控制器不会接受来自其他源(包括GPIOB)的中断,因为GPIOA的状态仍然被断言,它与...不一定GPIOB中断的条件,如果仍然追随GPIOA,因此仍然触发GPIOB。
试着检查一个分析器的信号中断发生时,确保没有重叠的断言的信号,这意味着当一个中断发生其他不是已经断言,因为这是唯一的条件是可以拖延醒来控制器。
谢谢mt_dialog.
你好
我更新了我的代码要使用锁存模式(第4.3章)。结果更好。但是,我有一个关于清除中断的问题:函数
hw_wkup_reset_interrupt.
在具有多个中断源的示例中永远不会调用。这是一个错误吗?问候,
Guillaume B.
嗨gbmej,
hw_wkup_reset_interrupt()是一个API函数,不是回调函数,所以必须由用户指定的任何中断回调函数调用它,以清除中断标志。如果你不调用这个函数,应用程序将永远不会调用它,所以这不是一个错误。更多信息,请阅读3.2中的步骤2。初始化功能章节的关键点,从我们的支持页面开始一个项目教程。
谢谢,PM_DIALOG.