你好,
我使用3个GPIO作为唤醒定时器来源。两个源触发始终在同一级别(一个低点和一个高)和两个级别的第三个源(在IRQ例程期间,我切换此GPIO的触发器)。我没有比赛时间(0毫秒),我期待一旦发生至少一个源(计数器比较阈值为1)。一切都在运作良好。两个第一个源始终触发其预期水平和两个级别的第三个源触发器。
// init序列:
hw_wkup_set_counter_threshold(1);
hw_wkup_set_debounce_time(0);
/ /等
但是,当至少两个来源同时发生时,永远不会调用IRQ例程;而永远(我已经观察到中断例程,只有在两个源同时发生时才被调用)。如果我使用调用我的IRQ例程的软件看门狗,则此调用解锁系统,唤醒定时器中断再次抛出(因为我认为,IRQ条件 - GPIO级别和/或触发条件 - 在看门狗呼叫期间更新)。
我在文档中读过:
事件计数器是边缘敏感的。检测后
主动边缘必须首先检测反向边缘
在它回到空闲状态之前,从那里开始
开始等待新的主动边缘。
是我的问题吗?我无法绕过这个条件!我无法更改源级别(GPIO级别),我无法更改触发级别(因为我不知道我是否在死锁条件下)......
任何答复都将非常欣赏。
问候,
Guillaume B。
设备:
嗨gbmej,
当您的同时发出中断时,我不会看到任何问题,唤醒控制器的中断不会触发的是,例如,如果允许说明您,则唤醒控制器的中断将不会触发。已配置为从3个不同的GPIO唤醒设备,并且触发手机对于剩余的两个和高电平,对于剩余的GPIO而高。现在,如果那些中断已经被置位(前两者的前两个或高度的一个来源的低电平),则不会发生中断,直到断言的引脚将被解除断言。所以也许这就是你正在遇到的,而不是在中断同时触发时。
谢谢mt_dialog.
你好,
谢谢您的回答。我已经进行了更多的调查以减少我的用例。我现在有一个GPIO中断,高于低变化,另一个在每个中断时切换的内容。当GPIO 2发生在GPIO 1中断之后发生时,我已经观察到,没有问题。但如果在GPIO结束之前发生变化1中断但是在GPIO 2检查后,我有锁定
kekuup_handler()
{
hw_wkup_reset_interrupt ();
if(checkgpio1condition())performgpio1job();
if(checkgpio2condition())performgpio2job();//切换触发器
//如果GPIO1中断期间GPIO2条件改变(我们已经调用了performGPIO1Job(),但没有调用performGPIO2Job()),我有问题(GPIO中断永远不会被GPIO2抛出)。如果在IRQ例程之后GPIO2条件发生了变化,我没有问题。
}
通过看门狗,我已经在锁定(执行但没有JOB2的作业)之后检查了GPIO状态:GPIO1高,GPIO2应该抛出中断......
问候,
Guillaume B。
嗨gbmej,
我不确定我是否准确地理解这一点,你提到的部分,当你得到锁让我有点困惑,试图复制你提到的,我已经在hrp_sensor中做了以下测试,它已经实现了一个唤醒源。“静态”唤醒源被触发为LOW,默认引脚配置为PULLUP,改变唤醒源(在中断程序中改变配置的那个)最初具有相同的极性,执行改变的代码附在下面。
//全局变量
__retated hw_gpio_mode my_gpio_mode = hw_gpio_mode_input_pullup;
__ retated hw_gpio_func my_gpio_function;
静态void 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,真的,
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_get_pin_function()用于检查默认引脚配置hw_gpio_set_pin_function()用于设置正确的默认引脚状态(与前面的中断击中相反)。
谢谢mt_dialog.
你好,
非常感谢您的答案,但我没有问题触发器切换。当GPIO中断发生在另一个GPIO中断时,我有一个问题。这是我的伪代码(请参阅附件)。
—每40ms发生一次GPIOA中断。GPIOA任务强制GPIOA级别从LOW返回HIGH(这是一个清除传感器中断的传感器读取)。
- 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任务
- 我们留下了中断
[任务GPIOB at t +34ms]
-我们ack GPIOB级别,让源代码工作(大约6到8毫秒)
[T + 40ms的中断3]
- GPIOA降低
- 抛出中断
- 我们唤醒GPIOA任务(有效的GPIOA条件)
- 我们唤醒gpiob任务(无效的gpiob条件)
- 我们留下了中断
[任务GPIOA at t = +41ms]
- 我们读了传感器
- GPIOA水平返回高位
如果在中断3(我们留下中断向量例程)之后更新GPIOB低至高电平,则没有错误。如果此更新发生在检查GPIOB中断条件后,但在离开中断向量例程之前,则不会抛出更多中断。这是锁。我认为内部唤醒状态机保持在key_release状态,因为GPIOA的KEY_HIT返回零,但同时,GPIOB的KEY_HIT转到1 ...
再次感谢你的帮助
guillaume.
嗨gbmej,
你的意思是当M0执行按下按钮的ISR时没有中断?对吗?这与唤醒控制器无关,但M0和NVIC是如何操作的,如果处理器得到一个中断而另一个中断正在执行中断处理程序,由于两个中断具有相同的优先级,挂起的中断标志将被设置为1,一旦前一个ISR被执行,它将再次被调用来服务挂起的中断,就我所测试的而言,这正是68x所做的。
现在在您的情况下,我看到您的引脚配置了下拉和上拉的内部电阻,我可以想象这是锁定中断的原因,也许在外部设备未正确驱动特定线路的情况下状态将发生上拉并保持唤醒控制器的中断信号,用于至少一个引脚源,我假设是切换其状态的引脚源,这足以发生中断,并且唤醒控制器等待唤醒控制器对于在报告另一个中断之前要断言中断。因此,如果您确定外部传感器正常驱动线路,或者如果您想使用内部电阻,则可以尝试使用内部拉动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运行,你提到一个任务正在读取传感器的状态,以释放中断,所以从GPIOA中断发生的时刻到中断被取消断言的时刻有一个周期x,唤醒控制器不接受来自其他来源(包括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.