前言
最近比较忙,测评一直被耽误,赶在活动结束才挤出时间,做一个简单的测评,杰发作为主打车规芯片的厂商,AC7802也只要面向车载应用,在车载中电机的控制是一个很常用的功能,这里用AC7802做一下可调PWM频率测试,实现定时器输出频率可调的PWM波,可用于步进电机的加减速应用。也赶上项目需要,步进电机的负载较大,直接启动会造成堵转。这里正好测试一下。 开箱
此次开发板的开箱是比较舒适的,第一次拿到包装如此完善的开发板,抽屉式包装加上黑色海绵减震,板子显得小巧精致。 开发板的黑色盖油端庄大气,芯片很小,但是相关外设的堆料不含糊,SWD和JTAG调试接口均有引出,方便使用,对于USART还贴心的使用了Type-C接口,此外地线的引出也是大大方便信号的观测。 开发环境
不得不说,杰发开发环境方面的真是下足了功夫,数据手册和用户手册均提供了中文和英文两个版本,再也不用吐槽没有中文手册的诟病了,同时提供了开发板入门指南,对开发板的软件件资源均做了详细的介绍,同时手把手教学如何开始第一个测试工程。就是MDK的开发环境必须在5.23版本以上(除 5.30 ),而我恰好是5.30,只能升级了一下。
对于软件方面来说,AC7802的库函数非常给力,很多的功能都做了封装,在开发时非常省力,一个函数就可以完成之前一大串的代码操作,高效省时。
频率可调PWM
可调PWM主要用于电机的加减速应用,那加减速使用的场景有那些呢?
为什么要使用加减速呢?在实际应用情况中,如果硬件驱动细分器与软件的细分参数或定时器分频参数设置不当时启动电机时, 会遇见步进电机有啸叫声但是不会转动,这是因为软件产生脉冲的频率大于步进电机的启动频率,步进电机有一个很重要的技术参数: 空载启动频率,也就是在没有负载的情况下能够正常启动的最大脉冲频率,如果脉冲频率大于该值,步进电机则不能够正常启动, 发生丢步或者堵转的情况;或者也可以理解为由于步进脉冲变化过快,转子由于惯性的作用跟不上电信号的变化。 所以要使用加减速来解决启动频率低的问题,在启动时使用较低的脉冲频率,然后逐渐的加快频率。 基于上述原因,我为了方便,直接套用了官方例程中的05_PWM_Output_Compare例程,在例程中的三通道输出PWM的基础上,通过开启比较中断,在触发比较器中断后修改比较值达到目的。 如上图所示,定时器设置为比较反转模式,触发中断后改变比较值,每当计数值达到比较值就会翻转,我们修改比较值,当计数值再次到达新的比较值会再次翻转,比较值的大小直接影响脉冲的宽度。 具体代码如下:
通过初始化定时器,设置初始比较值,这只PWM为比较输出,同时开启中断,定时器为向上技术模式,当计数到比较值后触发中断,在中断中修改比较值。这里一般会采用梯形算法或者S型算法,这里为了测试功能,只是输出可变的波形。 uint8_t g_pwm2_overflag = 0;
uint8_t Flag = 0;
uint32_t sum_value = 0;
/* ==================================== Functions declaration ===================================== */
/* ====================================== Functions define ======================================== */
/*!
* [url=home.php?mod=space&uid=247401]@brief[/url] PWM2_Callback
* PWM2模块中断回调函数
* @param wpara:溢出中断标志参数
* lpara:通道中断标志参数
* [url=home.php?mod=space&uid=266161]@return[/url] none
*/
uint16_t Count_Value = 0;
void PWM2_Callback(void *device, uint32_t wpara, uint32_t lpara)
{
if (0 != wpara)
{
g_pwm2_overflag = 1;
}
if (0 != (lpara & PWM_STR_CH0SF_Msk)) /*通道中断*/
{
// Count_Value = PWM_GetChannelCountValue(PWM2,PWM_CH_0);
PWM2->CNT = 0;
if(Flag==0)
{
sum_value++;
// Count_Value = Count_Value+(200*sum_value);
Count_Value = 200*sum_value;
PWM_SetChannelCountValue(PWM2,PWM_CH_0,Count_Value);
// PWM2->CHANNELS->CHV = Count_Value;
if(Count_Value>60000)
{
// Count_Value = 65535;
sum_value = 0;
Flag = 1;
}
}else{
sum_value++;
Count_Value = 65535-(200*sum_value);
PWM_SetChannelCountValue(PWM2,PWM_CH_0,Count_Value);
// Count_Value = PWM_GetChannelCountValue(PWM2,PWM_CH_0);
if(Count_Value>1000)
{
Flag = 0;
}
}
}
}
/*!
* @brief PWM2_OutputCompare_Init
* PWM2_CH0输出比较模式,匹配时翻转输出
* PWM2_CH1输出比较模式,匹配时清除输出
* PWM2_CH2输出比较输出,匹配时设置输出
* @param none
* @return none
*/
void PWM2_OutputCompare_Init(void)
{
PWM_ConfigType config;
PWM_OutputCompareConfigType outputCompconfig;
PWM_OutputCompareChConfigType outputChConfig[3];
memset(&config, 0U, sizeof(config));
memset(&outputCompconfig, 0U, sizeof(outputCompconfig));
memset(&outputChConfig, 0U, sizeof(outputChConfig));
GPIO_SetFunc(GPIOA, GPIO_PIN3, GPIO_FUN1); /* PA3--PWM2_CH0.*/
/*output channel config*/
outputChConfig[0].channel = PWM_CH_0; /*输出比较通道 */
outputChConfig[0].comparedValue = 3000; /*输出比较模式匹配点 */
outputChConfig[0].mode = PWM_TOGGLE_OUTPUT; /*输出模式选择,当计数器值与通道值匹配时,翻转通道输出 */
outputChConfig[0].interruptEn = ENABLE; /*通道中断使能位 */
outputChConfig[0].initLevel = PWM_HIGH_LEVEL; /*通道初始电平输出配置,该配置受initChOutputEn控制,决定PMM计数器未工作前PWM口的输出电平 */
outputChConfig[0].triggerEn = DISABLE; /*通道匹配触发使能位,在通道值匹配时可产生触发信号用于其他模块的触发信号 */
/*output compare config*/
outputCompconfig.channelNum = 3; /*输出比较通道数目 */
outputCompconfig.channelConfig = outputChConfig; /*输出比较通道配置赋值 */
outputCompconfig.initChOutputEn = ENABLE; /*初始化通道输出使能位,使能后独立PWM模式的 initLevel 和组合模式的ch1stInitLevel和ch2ndInitLevel配置才会生效*/
/*pwm config*/
config.mode = PWM_MODE_OUTPUT_COMPARE; /*PWM模式配置,PWM_MODE_MODULATION--PWM调制模式 */
config.initModeStruct = &outputCompconfig; /*不同模式相应初始化配置结构体赋值 */
config.clkSource = PWM_CLK_SOURCE_APB; /*PWM时钟源选择 */
config.clkPsc = 1; /*时钟分频系数 */
config.initValue = 0; /*初始计数值 */
config.maxValue = 65535; /*最大计数值,决定输出波形频率 */
config.overflowInterrupEn = DISABLE; /*溢出中断使能位 */
config.cntOverflowFreq = 0; /*溢出中断产生的频率与计数器频率的关系,0表示每次计数器溢出都产生中断,1表示间隔一次,以此类推 */
config.interruptEn = ENABLE; /*PWM总中断使能位 */
config.callBack = PWM2_Callback; /*中断回调函数 */
PWM_Init(PWM2, &config);
}
输出结果如下
|