《东芝TT_M3HQ开发板试用体验》 + PWM之调频
简介:在我们驱动一些电机,一般调控占空比就足够,不过在很多地方使用调频往往比调占空比更重要,接下来我对官方例程进行了深入的研究,调试出了可控占空比和可调频率的程序,供大家参考.
任何功能初学都是比较难得,学会了简单的不得了,同时为了数据精准也进行了N次测试.
(这张图谁拍的那么好看 哈哈)
一.PWM相关配置可参考我的上一篇文章,本篇不在详细介绍
与上篇相比我增加了S6(PV2)引脚的使用 用于调节频率
(PV0 当做确认按键 ,PV1 用于调占空比 PJ0 PWM输出 ,PA1 串口打印)
二.PWM调频和调控占空比,软件配置
1.主要函数 为了方便大家更改所以将整函数 粘贴过来了
static TXZ_Result pulse_driver_initialize(void)
{
TXZ_Result result = TXZ_SUCCESS;
/*----------------------*/
/* GPIO */
/*----------------------*/
/* Driver initialize has done within BSP. */
/*----------------------*/
/* T32A */
/*----------------------*/
{
t32a_t *p_t32a = &instance.t32a_pulse;
/*--- Construct ---*/
/* Register Allocation */
switch (bsp_get_output_pulse_ch(BSP_OUT_PULSE_SAMPLE_A))
{
case 0:
p_t32a->p_instance = TSB_T32A0;
break;
case 1:
p_t32a->p_instance = TSB_T32A1;
break;
case 2:
p_t32a->p_instance = TSB_T32A2;
break;
case 3:
p_t32a->p_instance = TSB_T32A3;
break;
case 4:
p_t32a->p_instance = TSB_T32A4;
break;
case 5:
p_t32a->p_instance = TSB_T32A5;
break;
default:
p_t32a->p_instance = MAIN_NULL;
break;
}
/*--- Initialize ---*/
p_t32a->init_mode.mode.halt = T32A_DBG_HALT_STOP;
p_t32a->init_mode.mode.mode = T32A_MODE_16;
if (p_t32a->p_instance != MAIN_NULL)
{
if (t32a_mode_init(p_t32a) != TXZ_SUCCESS)
{
result = TXZ_ERROR;
}
}
else
{
result = TXZ_ERROR;
}
}
/*----------------------*/
/* Timer */
/*----------------------*/
/* Output Pulse timer */
{
pulse_t *p_pulse = &instance.pulse;
p_pulse->init.id = (uint32_t)&instance.pulse;
p_pulse->init.pulse_t32a = &instance.t32a_pulse;
p_pulse->init.type = bsp_get_output_pulse_type(BSP_OUT_PULSE_SAMPLE_A);
/* RisingTiming Initial Value 10%(50us) SET */
//p_pulse->init.pulse_rising = RisingTimingus[Rate];//50us, 125us, 250us, 375us, 450us */ //
p_pulse->init.pulse_rising = (100-FDuty)*1000/Frequency*10U; //50us, 125us, 250us, 375us, 450us */ //
/* TrailingTiming 500us SET */
p_pulse->init.pulse_trailing = 1000/Frequency*1000U;
/* TrailingTiming 500us SET */
//p_pulse->init.pulse_trailing = 500U;
p_pulse->init.irq = bsp_get_output_pulse_nvic(BSP_OUT_PULSE_SAMPLE_A);
pulse_initialize(p_pulse);
}
/*----------------------*/
/* Uart */
/*----------------------*/
/* Driver initialize will process within USB UART. */
return (result);
}
static TXZ_Result pulse_driver_initialize(void)
{
TXZ_Result result = TXZ_SUCCESS;
/*----------------------*/
/* GPIO */
/*----------------------*/
/* Driver initialize has done within BSP. */
/*----------------------*/
/* T32A */
/*----------------------*/
{
t32a_t *p_t32a = &instance.t32a_pulse;
/*--- Construct ---*/
/* Register Allocation */
switch (bsp_get_output_pulse_ch(BSP_OUT_PULSE_SAMPLE_A))
{
case 0:
p_t32a->p_instance = TSB_T32A0;
break;
case 1:
p_t32a->p_instance = TSB_T32A1;
break;
case 2:
p_t32a->p_instance = TSB_T32A2;
break;
case 3:
p_t32a->p_instance = TSB_T32A3;
break;
case 4:
p_t32a->p_instance = TSB_T32A4;
break;
case 5:
p_t32a->p_instance = TSB_T32A5;
break;
default:
p_t32a->p_instance = MAIN_NULL;
break;
}
/*--- Initialize ---*/
p_t32a->init_mode.mode.halt = T32A_DBG_HALT_STOP;
p_t32a->init_mode.mode.mode = T32A_MODE_16;
if (p_t32a->p_instance != MAIN_NULL)
{
if (t32a_mode_init(p_t32a) != TXZ_SUCCESS)
{
result = TXZ_ERROR;
}
}
else
{
result = TXZ_ERROR;
}
}
/*----------------------*/
/* Timer */
/*----------------------*/
/* Output Pulse timer */
{
pulse_t *p_pulse = &instance.pulse;
p_pulse->init.id = (uint32_t)&instance.pulse;
p_pulse->init.pulse_t32a = &instance.t32a_pulse;
p_pulse->init.type = bsp_get_output_pulse_type(BSP_OUT_PULSE_SAMPLE_A);
/* RisingTiming Initial Value 10%(50us) SET */
//p_pulse->init.pulse_rising = RisingTimingus[Rate];//50us, 125us, 250us, 375us, 450us */ //Õ¼¿Õ±È
p_pulse->init.pulse_rising = (100-FDuty)*1000/Frequency*10U; //50us, 125us, 250us, 375us, 450us */ //Õ¼¿Õ±È
/* TrailingTiming 500us SET */
p_pulse->init.pulse_trailing = 1000/Frequency*1000U;
/* TrailingTiming 500us SET */
//p_pulse->init.pulse_trailing = 500U;
p_pulse->init.irq = bsp_get_output_pulse_nvic(BSP_OUT_PULSE_SAMPLE_A);
pulse_initialize(p_pulse);
}
/*----------------------*/
/* Uart */
/*----------------------*/
/* Driver initialize will process within USB UART. */
return (result);
}
2.软件配置主要就是以下两行代码
{
TXZ_Result result = TXZ_SUCCESS;
/*----------------------*/
/* GPIO */
/*----------------------*/
/* Driver initialize has done within BSP. */
/*----------------------*/
/* T32A */
/*----------------------*/
{
t32a_t *p_t32a = &instance.t32a_pulse;
/*--- Construct ---*/
/* Register Allocation */
switch (bsp_get_output_pulse_ch(BSP_OUT_PULSE_SAMPLE_A))
{
case 0:
p_t32a->p_instance = TSB_T32A0;
break;
case 1:
p_t32a->p_instance = TSB_T32A1;
break;
case 2:
p_t32a->p_instance = TSB_T32A2;
break;
case 3:
p_t32a->p_instance = TSB_T32A3;
break;
case 4:
p_t32a->p_instance = TSB_T32A4;
break;
case 5:
p_t32a->p_instance = TSB_T32A5;
break;
default:
p_t32a->p_instance = MAIN_NULL;
break;
}
/*--- Initialize ---*/
p_t32a->init_mode.mode.halt = T32A_DBG_HALT_STOP;
p_t32a->init_mode.mode.mode = T32A_MODE_16;
if (p_t32a->p_instance != MAIN_NULL)
{
if (t32a_mode_init(p_t32a) != TXZ_SUCCESS)
{
result = TXZ_ERROR;
}
}
else
{
result = TXZ_ERROR;
}
}
/*----------------------*/
/* Timer */
/*----------------------*/
/* Output Pulse timer */
{
pulse_t *p_pulse = &instance.pulse;
p_pulse->init.id = (uint32_t)&instance.pulse;
p_pulse->init.pulse_t32a = &instance.t32a_pulse;
p_pulse->init.type = bsp_get_output_pulse_type(BSP_OUT_PULSE_SAMPLE_A);
/* RisingTiming Initial Value 10%(50us) SET */
//p_pulse->init.pulse_rising = RisingTimingus[Rate];//50us, 125us, 250us, 375us, 450us */ //
p_pulse->init.pulse_rising = (100-FDuty)*1000/Frequency*10U; //50us, 125us, 250us, 375us, 450us */ //
/* TrailingTiming 500us SET */
p_pulse->init.pulse_trailing = 1000/Frequency*1000U;
/* TrailingTiming 500us SET */
//p_pulse->init.pulse_trailing = 500U;
p_pulse->init.irq = bsp_get_output_pulse_nvic(BSP_OUT_PULSE_SAMPLE_A);
pulse_initialize(p_pulse);
}
/*----------------------*/
/* Uart */
/*----------------------*/
/* Driver initialize will process within USB UART. */
return (result);
}
static TXZ_Result pulse_driver_initialize(void)
{
TXZ_Result result = TXZ_SUCCESS;
/*----------------------*/
/* GPIO */
/*----------------------*/
/* Driver initialize has done within BSP. */
/*----------------------*/
/* T32A */
/*----------------------*/
{
t32a_t *p_t32a = &instance.t32a_pulse;
/*--- Construct ---*/
/* Register Allocation */
switch (bsp_get_output_pulse_ch(BSP_OUT_PULSE_SAMPLE_A))
{
case 0:
p_t32a->p_instance = TSB_T32A0;
break;
case 1:
p_t32a->p_instance = TSB_T32A1;
break;
case 2:
p_t32a->p_instance = TSB_T32A2;
break;
case 3:
p_t32a->p_instance = TSB_T32A3;
break;
case 4:
p_t32a->p_instance = TSB_T32A4;
break;
case 5:
p_t32a->p_instance = TSB_T32A5;
break;
default:
p_t32a->p_instance = MAIN_NULL;
break;
}
/*--- Initialize ---*/
p_t32a->init_mode.mode.halt = T32A_DBG_HALT_STOP;
p_t32a->init_mode.mode.mode = T32A_MODE_16;
if (p_t32a->p_instance != MAIN_NULL)
{
if (t32a_mode_init(p_t32a) != TXZ_SUCCESS)
{
result = TXZ_ERROR;
}
}
else
{
result = TXZ_ERROR;
}
}
/*----------------------*/
/* Timer */
/*----------------------*/
/* Output Pulse timer */
{
pulse_t *p_pulse = &instance.pulse;
p_pulse->init.id = (uint32_t)&instance.pulse;
p_pulse->init.pulse_t32a = &instance.t32a_pulse;
p_pulse->init.type = bsp_get_output_pulse_type(BSP_OUT_PULSE_SAMPLE_A);
/* RisingTiming Initial Value 10%(50us) SET */
//p_pulse->init.pulse_rising = RisingTimingus[Rate];//50us, 125us, 250us, 375us, 450us */ //Õ¼¿Õ±È
p_pulse->init.pulse_rising = (100-FDuty)*1000/Frequency*10U; //50us, 125us, 250us, 375us, 450us */ //Õ¼¿Õ±È
/* TrailingTiming 500us SET */
p_pulse->init.pulse_trailing = 1000/Frequency*1000U;
/* TrailingTiming 500us SET */
//p_pulse->init.pulse_trailing = 500U;
p_pulse->init.irq = bsp_get_output_pulse_nvic(BSP_OUT_PULSE_SAMPLE_A);
pulse_initialize(p_pulse);
}
/*----------------------*/
/* Uart */
/*----------------------*/
/* Driver initialize will process within USB UART. */
return (result);
}
2.软件配置主要就是以下两行代码
(1)p_pulse->init.pulse_rising = (100-FDuty)*1000/Frequency*10U;
(2)本行代码在官方的例程是:p_pulse->init.pulse_rising = RisingTimingus[Rate];,用于调控占空比,其实这段代码是用于控制脉冲上升周期来实现调控占空比的.
(3)p_pulse->init.pulse_trailing = 1000/Frequency*1000U;
(4)本行代码在官方的例程是:p_pulse->init.pulse_trailing = 500U; 这段代码用于控制脉冲停止时间。
(5)要实现调频率和占空比,就要合理的给两行代码赋值。
(6)原例程是写死的其输出的频率为2Khz其单位时间精确us,实际上可以输出nMhz,我在此设置为0-1Khz可调的范围.(1000/Frequency*1000U)为简单的算法 Frequency 是你想的到的频率值,经过逻辑计算赋值到PWM定时器.
(6)原例程是写死的其输出的频率为2Khz其单位时间精确us,实际上可以输出nMhz,我在此设置为0-1Khz可调的范围.(1000/Frequency*1000U)为简单的算法 Frequency 是你想的到的频率值,经过逻辑计算赋值到PWM定时器.
为了方便大家理解,拟个小公式-频率:P(脉冲停止时间)=1S(1000 000us) / F (预期频率)
(7)在程序逻辑或是实际的使用当中调频,会影响其设置的占空比偏差很大,这也就是为什么有这个<(100-FDuty)*1000/Frequency*10U>简单的算法,为方便大家理解,拟个小公式:D(脉冲上升周期)=(100%-D(预期占空比)*10)*(1000us/F (预期频率))
(8)(100%-D(预期占空比)*10)这段同样是1s为单位所以后面×10倍 ,占空比理论0-100可调,实际其他硬件输入捕获要得到好的效果10-90的范围。
三。实际测试效果
以下链接地址也可以下载到官方的例程:https://mbb.eet-china.com/forum/topic/73382_1_1.html