【GD32F427开发板试用】 ADC改变定时器1 PWM占空比

本篇文章来自极术社区与兆易创新组织的GD32F427开发板评测活动,更多开发板试用活动请关注极术社区网站。作者:我只是个野指针

1. 简介

使用定时器1 在PB3引脚上输出频率100K的PWM波,然后使用ADC0 的通道1采集输入的电压型号来改变定时器1PWM的占空比。

2. 时钟分析

  • Cortex-M4 时钟最高200M
  • APB2总线 时钟最高100M
  • APB1总线 时钟最高50M

ADC时钟由APB2时钟经2、4、6、8分频或由AHB时钟经5、6、10、20分频获得,它们是通过
设置ADC\\\\_SYNCCTL寄存器的ADCCK位来选择。

ADC时钟最高40MHz
TIMER时钟由AHB时钟分频获得,它的频率可以等于CK\\\\_APBx、CK\\\\_APBx的两倍或CK\\\\_APBx的四倍。
所以定时器时钟最高200M

3.串口重定向

//printf配置 初始化USART0 GPIOA15(Tx) GPIOA10(Rx)
void printf\\_config(void)
{
/* enable GPIO clock */
rcu\\_periph\\_clock\\_enable(RCU\\_GPIOA);

/* enable USART clock */
rcu\\_periph\\_clock\\_enable(RCU\\_USART0);

/* configure the USART0 TX pin and USART0 RX pin */
gpio\\_af\\_set(GPIOA, GPIO\\_AF\\_7, GPIO\\_PIN\\_15);
gpio\\_af\\_set(GPIOA, GPIO\\_AF\\_7, GPIO\\_PIN\\_10);

/* configure USART0 TX as alternate function push-pull */
gpio\\_mode\\_set(GPIOA, GPIO\\_MODE\\_AF, GPIO\\_PUPD\\_PULLUP, GPIO\\_PIN\\_15);
gpio\\_output\\_options\\_set(GPIOA, GPIO\\_OTYPE\\_PP, GPIO\\_OSPEED\\_50MHZ, GPIO\\_PIN\\_15);

/* configure USART0 RX as alternate function push-pull */
gpio\\_mode\\_set(GPIOA, GPIO\\_MODE\\_AF, GPIO\\_PUPD\\_PULLUP, GPIO\\_PIN\\_10);
gpio\\_output\\_options\\_set(GPIOA, GPIO\\_OTYPE\\_PP, GPIO\\_OSPEED\\_50MHZ, GPIO\\_PIN\\_10);

/* USART configure */
usart\\_deinit(USART0);
usart\\_baudrate\\_set(USART0, 115200U);
usart\\_receive\\_config(USART0, USART\\_RECEIVE\\_ENABLE);
usart\\_transmit\\_config(USART0, USART\\_TRANSMIT\\_ENABLE);
usart\\_enable(USART0);
}

/* 将C库的printf函数重定目标为USART */
int fputc(int ch, FILE *f)
{
usart\_data\_transmit(USART0, (uint8\_t)ch);
while(RESET == usart\_flag\_get(USART0, USART\_FLAG\_TBE));
return ch;
}

4.初始化定时器 配置PWM

设置PWM频率为100K,即设置周期计数2000
注意 计数器的分频值 = PSC+1 分频值不能设置为1 否则时钟频率则为100M了

/*!
\brief configure the TIMER peripheral
\param[in] none
\param[out] none
\retval none
*/
void timer_pwm_config(void)
{

timer_oc_parameter_struct timer_ocintpara;
timer_parameter_struct timer_initpara;

/*将PB3 (TIMER1 CH1)配置为备用功能*/
rcu_periph_clock_enable(RCU_GPIOB);

gpio_mode_set(GPIOB, GPIO_MODE_AF, GPIO_PUPD_NONE, GPIO_PIN_3);
gpio_output_options_set(GPIOB, GPIO_OTYPE_PP, GPIO_OSPEED_50MHZ,GPIO_PIN_3);

gpio_af_set(GPIOB, GPIO_AF_1, GPIO_PIN_3);

rcu_periph_clock_enable(RCU_TIMER1);
rcu_timer_clock_prescaler_config(RCU_TIMER_PSC_MUL4);

timer_deinit(TIMER1);

/* TIMER1 configuration */
timer_initpara.prescaler = 0;
timer_initpara.alignedmode = TIMER_COUNTER_EDGE;
timer_initpara.counterdirection = TIMER_COUNTER_UP;
timer_initpara.period = 1999;
timer_initpara.clockdivision = TIMER_CKDIV_DIV1;
timer_initpara.repetitioncounter = 0;
timer_init(TIMER1,&timer_initpara);

/* CH1 configuration in PWM mode */
timer_ocintpara.ocpolarity = TIMER_OC_POLARITY_HIGH;
timer_ocintpara.outputstate = TIMER_CCX_ENABLE;
timer_ocintpara.ocnpolarity = TIMER_OCN_POLARITY_HIGH;
timer_ocintpara.outputnstate = TIMER_CCXN_DISABLE;
timer_ocintpara.ocidlestate = TIMER_OC_IDLE_STATE_LOW;
timer_ocintpara.ocnidlestate = TIMER_OCN_IDLE_STATE_LOW;

timer_channel_output_config(TIMER1,TIMER_CH_1,&timer_ocintpara);

/* PWM模式1下的CH1配置 */
timer_channel_output_pulse_value_config(TIMER1,TIMER_CH_1,249);
timer_channel_output_mode_config(TIMER1,TIMER_CH_1,TIMER_OC_MODE_PWM0);
timer_channel_output_shadow_config(TIMER1,TIMER_CH_1,TIMER_OC_SHADOW_DISABLE);

/* auto-reload preload enable */
timer_auto_reload_shadow_enable(TIMER1);
/* auto-reload preload enable */
timer_enable(TIMER1);
}

5. 配置ADC

void adc_config(void)
{
/* enable GPIOA clock */
rcu_periph_clock_enable(RCU_GPIOA);
/* enable ADC clock */
rcu_periph_clock_enable(RCU_ADC0);
/* config ADC clock */
adc_clock_config(ADC_ADCCK_PCLK2_DIV8);

/* config the GPIO as analog mode */
gpio_mode_set(GPIOA, GPIO_MODE_ANALOG, GPIO_PUPD_NONE, GPIO_PIN_1);

adc_deinit();
adc_sync_mode_config(ADC_SYNC_MODE_INDEPENDENT);
adc_special_function_config(ADC0, ADC_CONTINUOUS_MODE, DISABLE);
adc_special_function_config(ADC0, ADC_SCAN_MODE, DISABLE); //启用或禁用ADC特殊转换模式功能:禁用
adc_data_alignment_config(ADC0, ADC_DATAALIGN_RIGHT); //ADC数据对其: 右
adc_channel_length_config(ADC0, ADC_REGULAR_CHANNEL, 1U); //ADC外部触发分频:1

adc_external_trigger_source_config(ADC0, ADC_REGULAR_CHANNEL, ADC_EXTTRIG_REGULAR_T0_CH0); //配置ADC外部触发源:TIMER0 CH0事件
adc_external_trigger_config(ADC0, ADC_REGULAR_CHANNEL, EXTERNAL_TRIGGER_DISABLE); //禁用外部触发器

adc_enable(ADC0); //启用ADC接口
delay_1ms(1U);
adc_calibration_enable(ADC0); //ADC校准
}

6.主函数

int main(void)
{
unsigned int adc_voltage_value = 0;
unsigned int duty_cycle_value = 0;
/* configure systick */
systick_config();
printf_config();

timer_pwm_config();
adc_config();

while(1) {

adc_voltage_value = adc_channel_sample(ADC_CHANNEL_1);
duty_cycle_value = adc_voltage_value*2000 /4095;
timer_channel_output_pulse_value_config(TIMER1,TIMER_CH_1,duty_cycle_value);
printf("adc_channel_sample = %d \r\n",adc_voltage_value);
printf("duty_cycle_value = %d \r\n",duty_cycle_value);
delay_1ms(100);

}
}

7.下载验证

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
电压源设计思路介绍: 1、改高精度电压源基于GD32F190设计完成。利用GD190内部的高精度OPAMP,对经过整流后的直流电压进行电压采样,对比取样后的电压,通过GD190内部的DAC控制场效应管的导通,从而控制输出电压的大小。 2、 另一方面,通过GD190内部12位的ADC对采样电压采样,然后将采样的结果显示到LCD5110,而且可以通过小红上面的按键调节输出电压的大小。 GD32开发资料汇总详见链接: 高精度电压源硬件设计框图:https://www.cirmall.com/circuit/3721/ 高电压源视频展示: 设计心得总结: 1、本案例的核心在于软件PWM的生成,100路8分辨率PWM输出对于普通单片机来说还是有一定的压力,还要同时处理DMX512数据的接收,得益于GD32F207的120M运行速度,可以在短时间内处理更多的指令,将100路PWM计数变量分成10组,通过轮流的方式更新每一组IO的计数变量,同时更新IO的状态,有效的减少中断处理的数据量,缩短处理时间,本案例中实现了8位分辨率400HZ以上的PWM输出,用来控制调光灯,完全不会出现闪烁的情况。串口中断方式接收DMX512数据帧,即时保存在DMX512的缓冲区中,按DMX512数据每秒40帧的更新速度,最多在第2帧数据到来时可以把当前状态更新到所控制的灯上。 2、本案例控制IO输出采用了数据表映射的方式,可以任意修改IO所对应DMX512数据字节,操作时读取数据表里的映射数据,直接操作GPIO控制寄存器,也有效的减少操作指令,提高了操作效率。 3、采用高频率的单片机模拟多路PWM的方式,取代市场上现有的使用FPGA的方案,在满足性能的同时有效的降低了产品的设计复杂程度和产品成本。
PID调节PWM比的原理是通过PID控制算法实现的。首先,PID控制算法是一个负反馈闭环系统,它通过计算目标值与实际值之间的误差来调节输出。具体来说,PID控制算法包括比例项、积分项和微分项。 在PID调节PWM比的过程中,首先需要设定PID的目标值和参数,目标值可以是电机的速度值。然后,通过计算目标值与实际值的误差,得到误差项。接下来,将误差项分别乘以比例系数Kp、积分系数Ki和微分系数Kd,并将它们相加得到PID的输出值。这个输出值就是PWM比。 具体的反馈流程是,每次的PID输出作为电机的输入,编码器读取电机的实际速度值,并将其作为实际值传入PID控制算法。PID控制算法会不断计算误差,并根据误差调整输出值,直到误差为0。这个过程会一直进行,直到达到设定的目标值。最终稳定的输出值就是PWM比。 需要注意的是,PID控制算法可以根据实际控制需求进行调整,不一定需要使用三个环节(比例、积分、微分)都进行控制。有时候也可以使用PI控制或PD控制。而具体的PID参数设置会直接影响到PWM比的稳定值。 #### 引用[.reference_title] - *1* *3* [PID控制电机输出作为电机PWM比输入的理解](https://blog.csdn.net/qq_26972441/article/details/126174437)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^koosearch_v1,239^v3^insert_chatgpt"}} ] [.reference_item] - *2* [[转]PID算法与直流电机的PWM技术控制()](https://blog.csdn.net/weixin_44026026/article/details/113488461)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^koosearch_v1,239^v3^insert_chatgpt"}} ] [.reference_item] [ .reference_list ]

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值