你好,
我试图使用计时器产生一个脉冲端口1引脚0一旦芯片连接到一个设备(例如OTA)。我正在遵循timer0通用中的示例。
空白pwm0_user_callback_function(空白)
{
如果(GPIO_GetPinStatus (GPIO_PORT_1 GPIO_PIN_0))
{
GPIO_SetInactive (GPIO_PORT_1 GPIO_PIN_0);
}
其他的
{
GPIO_SetActive (GPIO_PORT_1 GPIO_PIN_0);
}
}
空白init_timer_for_test(空白)
{
//输入设置的停止定时器
timer0_stop ();
// SWTIM_IRQn的注册回调函数
timer0_register_callback (pwm0_user_callback_function);
//启用TIMER0时钟
set_tmr_enable (CLK_PER_REG_TMR_ENABLED);
//设置TIMER0,TIMER2时钟分割因子为8,因此TIM0 Fclk为F = 16MHz/8 = 2Mhz
set_tmr_div (CLK_PER_REG_TMR_DIV_8);
//清除PWM设置寄存器不产生PWM
timer0_set_pwm_high_counter (NO_PWM);
timer0_set_pwm_low_counter (NO_PWM);
//设置2MHz源时钟除以10的定时器Fclk = 2MHz/10 = 200kHz
timer0_init (TIM0_CLK_FAST PWM_MODE_ONE TIM0_CLK_DIV_BY_10);
//重新加载100ms的值(T = 1/200kHz * RELOAD_100MS = 0,000005 * 20000 = 100ms)
timer0_set_pwm_on_counter (RELOAD_100MS);
//使能SWTIM_IRQn irq
timer0_enable_irq ();
pin_state = 0;
/ /开始Timer0
timer0_start ();
}
P1_0配置为输出。init_timer_for_test()函数在连接成功后被调用,即在app_connect_confirm()之后。我没有看到预期的100毫秒脉冲。是因为芯片现在连接到了一个设备上吗?有这样的依赖性吗?此外,如果定时器配置为PWM,输出在哪个引脚上产生?理想情况下,我希望连接成功后在GPIO上有一个短脉冲。从timer0 pwm例子来看,我有点不清楚。谢谢!
嗨vmore,
关于你的实现,我看到你配置了一个简单的定时器实现,你只是切换GPIO在每个中断,这是一种方法,但因为有一个PWM功能,我不认为这样做的原因,此外,当在PWM模式下操作计时器时,您可以在使用GPIO_ConfigurePin()函数和PID_PWMx函数配置引脚时,使用适当的功能将计时器的输出映射到您想要的任何GPIO。连接的回调是.app_on_connection回调。除此之外,请注意,当使用睡眠模式时,所有外围设备都会被关闭,所以我认为,如果禁用睡眠模式,设备就会运行,你可以看到线路的切换,对吗?
由于MT_dialog
你好!
谢谢你的建议。我同意这种方法不是最好的,但我不清楚如何使用PWM,所以这是一个简单的测试。感谢您指出PID_PWM功能。正如你所指出的,睡眠时外围设备会关闭。在连接成功后,我显式地调用了app_force_active api。我也使用这个调用来查看外设是否up:
无效的配置()
{
SetBits16 (PMU_CTRL_REG PERIPH_SLEEP 0);
while (GetWord16(SYS_STAT_REG) & PER_IS_UP));
GPIO_ConfigurePin(GPIO_PORT_1, GPIO_PIN_0, OUTPUT, PID_PWM0, false);
}
我的PWM定时器代码现在是这样的:
#定义TIMER_ON 3000
#定义PWM_HIGH 20
#定义PWM_LOW 2980
空白init_timer_test ()
{
//输入设置的停止定时器
timer0_stop ();
// SWTIM_IRQn的注册回调函数
timer0_register_callback (pwm0_user_callback_function);
//启用TIMER0时钟
set_tmr_enable (CLK_PER_REG_TMR_ENABLED);
set_tmr_div (CLK_PER_REG_TMR_DIV_8);
timer0_set (TIMER_ON PWM_HIGH PWM_LOW);
timer0_init (TIM0_CLK_32K PWM_MODE_ONE TIM0_CLK_NO_DIV);
//使能SWTIM_IRQn irq
timer0_enable_irq ();
/ /开始Timer0
timer0_start ();
空白pwm0_user_callback_function(空白)
{
timer0_set (TIMER_ON PWM_HIGH PWM_LOW);
}
当我将手机连接到OTA设备时,我看到一系列脉冲,间隔约为50ms。根据计数器的值,我应该得到一个高脉冲每750ms 5ms,但可能是计时器有不正确的值。所以我有两个问题:
(1)计时器计数器值不正确。当前的计时器设置有什么问题?
(2)由于这些脉冲,OTA图像上传失败(连接,但block发送卡住)。如何解决这个问题?
嗨vmore,
正如我从您的代码中看到的,您使用的是TIM0_CLK_32K,对于数据表,不能划分得太多。如果您决定使用TIM0_CLK_32K,您应该删除时钟分隔符(set_tmr_div(CLK_PER_REG_TMR_DIV_8)),您应该定义timer0_set()值如下:
·对于5msec高脉冲,#define PWM_HIGH 160
·对于750msec低脉冲,#define PWM_LOW 24000
TIMER_ON是独立于产生的PWM,它是一个定时器,产生中断,所以你不需要这个,你不需要更新定时器的值,一旦计时器过期,会产生PWM的值将自动重新加载。
关于OTA更新,没有明显的原因,如何OTA过程连接定时器,但我假设,如果有任何暗示连接这两个模块,也许你可以禁用中断从定时器和检查。
谢谢,PM_Dialog