OpenEdv-开源电子网

 找回密码
 立即注册
正点原子全套STM32/Linux/FPGA开发资料,上千讲STM32视频教程免费下载...
查看: 6206|回复: 6

关于DCDC直流开关电源采集输出电压ADC后反馈到PWM的占空比来稳定输出的问题

[复制链接]

2

主题

6

帖子

0

精华

新手上路

积分
34
金钱
34
注册时间
2015-7-14
在线时间
0 小时
发表于 2015-7-17 15:46:19 | 显示全部楼层 |阅读模式
5金钱
我对原子哥的历程中的PWM输出实验和ADC实验进行了改动和组合 首先不加反馈  是可以进行pwm输出和ADC测量显示的
[mw_shl_code=c,true]int main(void) { u16 adcx; float led0pwmval=250; NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);//?è????????????????·?×é2 delay_init(168); //?????????±???? uart_init(115200); //???????®???¨??????115200 LED_Init(); //??????LED LCD_Init(); //??????LCD???? Adc_Init(); //??????ADC TIM14_PWM_Init (500-1,8-1); POINT_COLOR=RED; LCD_ShowString(30,50,200,16,16,"Explorer STM32F4"); LCD_ShowString(30,70,200,16,16,"ADC TEST"); LCD_ShowString(30,90,200,16,16,"ATOM@ALIENTEK"); LCD_ShowString(30,110,200,16,16,"2014/5/6"); POINT_COLOR=BLUE;//?è??×????????? LCD_ShowString(30,130,200,16,16,"ADC1_CH5_VAL:"); LCD_ShowString(30,150,200,16,16,"ADC1_CH5_VOL:0.000V"); //???????¨?????????????? while(1) { adcx=Get_Adc_Average(ADC_Channel_5,20);//?????¨??5??×???????20???????ù LCD_ShowxNum(134,130,adcx,4,16,0); //????ADCC???ù?ó???????? temp=(float)adcx*(3.3/4096); //?????????ó??????????????????????±???3.1111 adcx=temp; //??????????·???adcx±??????ò??adcx??u16???? LCD_ShowxNum(134,150,adcx,1,16,0); //??????????????????·???3.1111???°??????????????3 temp-=adcx; //°?????????????????·?????????????????·???±???3.1111-3=0.1111 temp*=1000; //??????·?????1000????????0.1111??×?????111.1???à?±??±????????????? LCD_ShowxNum(150,150,temp,3,16,0X80); //??????????·??¨?°??×????????????????©????????????????111. LED0=!LED0; TIM_SetCompare1(TIM14,led0pwmval); delay_ms(10); } } [/mw_shl_code]
然后我的想法是  首先如上的代码是输出一个21KHZ,占空比50%的PWM波,然后我会在程序中设置一个我需要输出的电压值,根据ADC采集的当前输出电压来和当前这50%占空比来计算出当前的输入电压,之后根据当前的输入电压和理想输出电压来计算我需要的占空比来改变led0pwmval来改变PWM的占空比。   代码如下
[mw_shl_code=c,true]int main(void) { u16 adcx; float led0pwmval=250; float temp; float Voutideal=3; float zkb; NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);//?è????????????????·?×é2 delay_init(168); //?????????±???? uart_init(115200); //???????®???¨??????115200 LED_Init(); //??????LED LCD_Init(); //??????LCD???? Adc_Init(); //??????ADC TIM14_PWM_Init (500-1,8-1); POINT_COLOR=RED; LCD_ShowString(30,50,200,16,16,"Explorer STM32F4"); LCD_ShowString(30,70,200,16,16,"ADC TEST"); LCD_ShowString(30,90,200,16,16,"ATOM@ALIENTEK"); LCD_ShowString(30,110,200,16,16,"2014/5/6"); POINT_COLOR=BLUE;//?è??×????????? LCD_ShowString(30,130,200,16,16,"ADC1_CH5_VAL:"); LCD_ShowString(30,150,200,16,16,"ADC1_CH5_VOL:0.000V"); //???????¨?????????????? while(1) { adcx=Get_Adc_Average(ADC_Channel_5,20);//?????¨??5??×???????20???????ù LCD_ShowxNum(134,130,adcx,4,16,0); //????ADCC???ù?ó???????? temp=(float)adcx*(3.3/4096); //?????????ó??????????????????????±???3.1111 adcx=temp; //??????????·???adcx±??????ò??adcx??u16???? LCD_ShowxNum(134,150,adcx,1,16,0); //??????????????????·???3.1111???°??????????????3 temp-=adcx; //°?????????????????·?????????????????·???±???3.1111-3=0.1111 temp*=1000; //??????·?????1000????????0.1111??×?????111.1???à?±??±????????????? LCD_ShowxNum(150,150,temp,3,16,0X80); //??????????·??¨?°??×????????????????©????????????????111. LED0=!LED0; TIM_SetCompare1(TIM14,led0pwmval); zkb=(500-led0pwmval)/500; led0pwmval=500-((500*Voutideal*zkb)/temp); delay_ms(10); } } [/mw_shl_code]
即为我想要的输出为3V,来改变PWM的占空比,但是改完之后可以读取ADC,但PWM不输出了,不知道错误出在哪里,希望大家可以帮助我一下。
我是为了做大学生电子竞赛来学习的这些知识,目前还是小白一个,所以希望大家能说的简单一些,让我这个小白尽量理解,谢谢了。

最佳答案

查看完整内容[请看2#楼]

1. 进入调试模式检查输出值是否有效 , 明显 L28 和 L30 有问题 . 2. 开关电源没这么简单的 , 如果你不懂 ID , 建议好好看一下自动控制原理 , 虽然 ID 在这里用不是太合适 , 高等数学也要相当扎实 .
正点原子逻辑分析仪DL16劲爆上市
回复

使用道具 举报

2

主题

1436

帖子

1

精华

金牌会员

Rank: 6Rank: 6

积分
2209
金钱
2209
注册时间
2010-12-16
在线时间
190 小时
发表于 2015-7-17 15:46:20 | 显示全部楼层
1. 进入调试模式检查输出值是否有效 , 明显 L28 和 L30 有问题 .

2. 开关电源没这么简单的 , 如果你不懂 ID , 建议好好看一下自动控制原理 , 虽然 ID 在这里用不是太合适 , 高等数学也要相当扎实 .
技术讨论请发帖 , 需要我回复请点左下的 < 回复 > 让系统通知我 . 本人不通过其他方式返回任何参数.
回复

使用道具 举报

2

主题

6

帖子

0

精华

新手上路

积分
34
金钱
34
注册时间
2015-7-14
在线时间
0 小时
 楼主| 发表于 2015-7-17 17:43:37 | 显示全部楼层
回复【2楼】shihantu:
---------------------------------
L28 和L30是指第28和30行么?   那个是在LCD上显示采集电压的代码,对运算时没有效果的,其实可以删除的 我觉得可能是在pwm和adc的频率有问题   还有就是34-39行的问题
回复

使用道具 举报

2

主题

6

帖子

0

精华

新手上路

积分
34
金钱
34
注册时间
2015-7-14
在线时间
0 小时
 楼主| 发表于 2015-7-17 17:44:44 | 显示全部楼层
[mw_shl_code=c,true]void Adc_Init(void) { GPIO_InitTypeDef GPIO_InitStructure; ADC_CommonInitTypeDef ADC_CommonInitStructure; ADC_InitTypeDef ADC_InitStructure; RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOA, ENABLE);//????GPIOA?±?? RCC_APB2PeriphClockCmd(RCC_APB2Periph_ADC1, ENABLE); //????ADC1?±?? //????????ADC1?¨??5 IO?? GPIO_InitStructure.GPIO_Pin = GPIO_Pin_5;//PA5 ?¨??5 GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AN;//???????? GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL ;//?????????? GPIO_Init(GPIOA, &GPIO_InitStructure);//?????? RCC_APB2PeriphResetCmd(RCC_APB2Periph_ADC1,ENABLE); //ADC1???? RCC_APB2PeriphResetCmd(RCC_APB2Periph_ADC1,DISABLE); //?????á?? ADC_CommonInitStructure.ADC_Mode = ADC_Mode_Independent;//???????? ADC_CommonInitStructure.ADC_TwoSamplingDelay = ADC_TwoSamplingDelay_5Cycles;//???????ù?×???®????????5???±?? ADC_CommonInitStructure.ADC_DMAAccessMode = ADC_DMAAccessMode_Disabled; //DMA?§?? ADC_CommonInitStructure.ADC_Prescaler = ADC_Prescaler_Div4;//?¤·???4·?????ADCCLK=PCLK2/4=84/4=21Mhz,ADC?±??×???????????36Mhz ADC_CommonInit(&ADC_CommonInitStructure);//?????? ADC_InitStructure.ADC_Resolution = ADC_Resolution_12b;//12?????? ADC_InitStructure.ADC_ScanConvMode = DISABLE;//·??¨?è???? ADC_InitStructure.ADC_ContinuousConvMode = DISABLE;//??±?????×??? ADC_InitStructure.ADC_ExternalTrigConvEdge = ADC_ExternalTrigConvEdge_None;//??????·??ì?????????í????·? ADC_InitStructure.ADC_DataAlign = ADC_DataAlign_Right;//?????? ADC_InitStructure.ADC_NbrOfConversion = 1;//1??×????????ò?ò???? ????????×??????ò?ò??1 ADC_Init(ADC1, &ADC_InitStructure);//ADC?????? ADC_Cmd(ADC1, ENABLE);//????AD×????÷ } //????ADC?? //ch: @ref ADC_channels //?¨???? 0~16????·??§????ADC_Channel_0~ADC_Channel_16 //·?????:×????á?? u16 Get_Adc(u8 ch) { //?è?????¨ADC?????ò×é?¨?????????ò???????ù?±?? ADC_RegularChannelConfig(ADC1, ch, 1, ADC_SampleTime_480Cycles ); //ADC1,ADC?¨??,480??????,?á?????ù?±???????á?????·?? ADC_SoftwareStartConv(ADC1); //???????¨??ADC1???í??×??????????? while(!ADC_GetFlagStatus(ADC1, ADC_FLAG_EOC ));//????×????á?? return ADC_GetConversionValue(ADC1); //·???×??ü????ADC1???ò×é??×????á?? } //?????¨??ch??×?????????times??,???ó???ù //ch:?¨??±à?? //times:???????? //·?????:?¨??ch??times??×????á?????ù?? u16 Get_Adc_Average(u8 ch,u8 times) { u32 temp_val=0; u8 t; for(t=0;t<times;t++) { temp_val+=Get_Adc(ch); delay_ms(5); } return temp_val/times;//???ù?????? } [/mw_shl_code]
这是ADC.C
[mw_shl_code=c,true]void TIM14_PWM_Init(u32 arr,u32 psc) { //????·??è????????IO???è?? GPIO_InitTypeDef GPIO_InitStructure; TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure; TIM_OCInitTypeDef TIM_OCInitStructure; RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM14,ENABLE); //TIM14?±?????? RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOA, ENABLE); //????PORTF?±?? GPIO_PinAFConfig(GPIOA,GPIO_PinSource7,GPIO_AF_TIM14); //GPIOF9???????¨?±?÷14 GPIO_InitStructure.GPIO_Pin = GPIO_Pin_7; //GPIOF9 GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF; //???????? GPIO_InitStructure.GPIO_Speed = GPIO_Speed_100MHz; //????100MHz GPIO_InitStructure.GPIO_OType = GPIO_OType_PP; //???ì???????? GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP; //???? GPIO_Init(GPIOA,&GPIO_InitStructure); //??????PF9 TIM_TimeBaseStructure.TIM_Prescaler=psc; //?¨?±?÷·??? TIM_TimeBaseStructure.TIM_CounterMode=TIM_CounterMode_Up; //?ò?????????? TIM_TimeBaseStructure.TIM_Period=arr; //×?????×°???? TIM_TimeBaseStructure.TIM_ClockDivision=TIM_CKD_DIV1; TIM_TimeBaseInit(TIM14,&TIM_TimeBaseStructure);//???????¨?±?÷14 //??????TIM14 Channel1 PWM???? TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM1; //?????¨?±?÷????:TIM?????í???÷??????2 TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable; //±??????????? TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_Low; //????????:TIM????±????????? TIM_OC1Init(TIM14, &TIM_OCInitStructure); //?ù??T???¨???????????????èTIM1 4OC1 TIM_OC1PreloadConfig(TIM14, TIM_OCPreload_Enable); //????TIM14??CCR1?????¤×°???????÷ TIM_ARRPreloadConfig(TIM14,ENABLE);//ARPE???? TIM_Cmd(TIM14, ENABLE); //????TIM14 } [/mw_shl_code]
这是PWM.C
回复

使用道具 举报

2

主题

1436

帖子

1

精华

金牌会员

Rank: 6Rank: 6

积分
2209
金钱
2209
注册时间
2010-12-16
在线时间
190 小时
发表于 2015-7-18 13:50:43 | 显示全部楼层
回复【3楼】暴走的晟哥哥:
---------------------------------
L28 和 L30 把 temp 减到 0 了 , 你说没影响 ???

printf参与反馈环的采样时间 , 这点就不需要看你其他代码了 , 自动控制大忌 .
技术讨论请发帖 , 需要我回复请点左下的 < 回复 > 让系统通知我 . 本人不通过其他方式返回任何参数.
回复

使用道具 举报

2

主题

6

帖子

0

精华

新手上路

积分
34
金钱
34
注册时间
2015-7-14
在线时间
0 小时
 楼主| 发表于 2015-7-18 15:46:24 | 显示全部楼层
回复【5楼】shihantu:
---------------------------------
嗯  我也发现了  现在改成了在LCD代码之前改变占空比了  就避免了temp的改变  谢谢您了
回复

使用道具 举报

4

主题

9

帖子

0

精华

新手上路

积分
35
金钱
35
注册时间
2017-7-21
在线时间
25 小时
发表于 2017-7-21 16:17:33 | 显示全部楼层
楼主,你是怎么解决的,我现在也遇到了和你相同的问题
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则



关闭

原子哥极力推荐上一条 /2 下一条

正点原子公众号

QQ|手机版|OpenEdv-开源电子网 ( 粤ICP备12000418号-1 )

GMT+8, 2024-12-23 03:15

Powered by OpenEdv-开源电子网

© 2001-2030 OpenEdv-开源电子网

快速回复 返回顶部 返回列表