這是基于stm32的SPWM輸出程序,支持三相,有詳細注釋。
單片機源程序如下:
- #include "led.h"
- #include "delay.h"
- #include "sys.h"
- #include "usart.h"
- #include "SPWM.h"
- #include "stdio.h"
- char displayhc[20];
- int k=0;
- void my_delay_ms(int i)
- {
- for(;i>0;i--)
- {
- for(k=0;k<8000;k++)
- {
- __nop();
- }
- }
- }
- void Key_GPIO_Config(void)
- {
- GPIO_InitTypeDef GPIO_InitStructure;
- RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOC,ENABLE);
- GPIO_InitStructure.GPIO_Pin = GPIO_Pin_7|GPIO_Pin_8|GPIO_Pin_9|GPIO_Pin_10;
- GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU;
- GPIO_Init(GPIOC, &GPIO_InitStructure);
- }
- uint8_t Key_Scan(GPIO_TypeDef* GPIOx,uint16_t GPIO_Pin)
- {
- if(GPIO_ReadInputDataBit(GPIOx,GPIO_Pin) == 1 )
- {
- // while(GPIO_ReadInputDataBit(GPIOx,GPIO_Pin) == 0);
- return 1;
- }
- else
- return 0;
- }
- #include "oled.h"
- extern float pin_lv;
- uint8_t key1=1,key2=1,key3=1,key4=1;
- int key1_flag=0,key2_flag=0,key3_flag=0,key4_flag=2;
- void check_key(void)
- {
- // key1=Key_Scan(GPIOC,GPIO_Pin_10);
- key4=Key_Scan(GPIOC,GPIO_Pin_7);
- if(key4==0){my_delay_ms(30);key4=Key_Scan(GPIOC,GPIO_Pin_7);if(key4==0)key4_flag--;if(key4_flag<0)key4_flag=5;}
- while(key4==0)key4=Key_Scan(GPIOC,GPIO_Pin_7);
-
-
-
-
- if(Key_Scan(GPIOC,GPIO_Pin_8)==0){my_delay_ms(30);if(Key_Scan(GPIOC,GPIO_Pin_8)==0)
- {
- if(key4_flag==0)pin_lv=pin_lv+1.0;
-
-
- if(key4_flag==0)pin_lv=pin_lv-11.0;
- if(key4_flag==1)pin_lv=pin_lv-0.1;
- if(key4_flag==2)pin_lv=pin_lv-1.0;
- if(pin_lv<=20.0)pin_lv=20.0;
- TIM4->PSC=1.0/pin_lv/22.2259*10000000.0;
-
- sprintf(displayhc,"%3.1f",pin_lv);
- OLED_ShowString(64,6,displayhc);
- }
- }
- while(Key_Scan(GPIOC,GPIO_Pin_8)==0);
-
-
-
-
-
-
-
-
- if(Key_Scan(GPIOC,GPIO_Pin_9)==0){my_delay_ms(30);if(Key_Scan(GPIOC,GPIO_Pin_9)==0)
- {
- if(key4_flag==2)pin_lv=pin_lv+1.0;
- if(key4_flag==1)pin_lv=pin_lv+0.1;
- if(key4_flag==0)pin_lv=pin_lv+10.0;
- if(pin_lv>=100.0)pin_lv=100.0;
- TIM4->PSC=1.0/pin_lv/22.2259*10000000.0;
-
- sprintf(displayhc,"%3.1f",pin_lv);
- OLED_ShowString(64,6,displayhc);
- }
- }
- while(Key_Scan(GPIOC,GPIO_Pin_9)==0);
- }
- #include "stm32f10x_adc.h"
- void Adc_Init(void)
- {
- ADC_InitTypeDef ADC_InitStructure;
- GPIO_InitTypeDef GPIO_InitStructure;
- RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA |RCC_APB2Periph_ADC1 , ENABLE ); //使能ADC1通道時鐘
-
- RCC_ADCCLKConfig(RCC_PCLK2_Div6); //設置ADC分頻因子6 72M/6=12,ADC最大時間不能超過14M
- //PA1 作為模擬通道輸入引腳
- GPIO_InitStructure.GPIO_Pin = GPIO_Pin_1;
- GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AIN; //模擬輸入引腳
- GPIO_Init(GPIOA, &GPIO_InitStructure);
- ADC_DeInit(ADC1); //復位ADC1,將外設 ADC1 的全部寄存器重設為缺省值
- ADC_InitStructure.ADC_Mode = ADC_Mode_Independent; //ADC工作模式:ADC1和ADC2工作在獨立模式
- ADC_InitStructure.ADC_ScanConvMode = DISABLE; //模數轉換工作在單通道模式
- ADC_InitStructure.ADC_ContinuousConvMode = DISABLE; //模數轉換工作在單次轉換模式
- ADC_InitStructure.ADC_ExternalTrigConv = ADC_ExternalTrigConv_None; //轉換由軟件而不是外部觸發啟動
- ADC_InitStructure.ADC_DataAlign = ADC_DataAlign_Right; //ADC數據右對齊
- ADC_InitStructure.ADC_NbrOfChannel = 1; //順序進行規則轉換的ADC通道的數目
- ADC_Init(ADC1, &ADC_InitStructure); //根據ADC_InitStruct中指定的參數初始化外設ADCx的寄存器
-
- ADC_Cmd(ADC1, ENABLE); //使能指定的ADC1
-
- ADC_ResetCalibration(ADC1); //使能復位校準
-
- while(ADC_GetResetCalibrationStatus(ADC1)); //等待復位校準結束
-
- ADC_StartCalibration(ADC1); //開啟AD校準
-
- while(ADC_GetCalibrationStatus(ADC1)); //等待校準結束
-
- // ADC_SoftwareStartConvCmd(ADC1, ENABLE); //使能指定的ADC1的軟件轉換啟動功能
- }
- u16 Get_Adc(u8 ch)
- {
- //設置指定ADC的規則組通道,一個序列,采樣時間
- ADC_RegularChannelConfig(ADC1, ch, 1, ADC_SampleTime_1Cycles5 ); //ADC1,ADC通道,采樣時間為1.5周期
-
- ADC_SoftwareStartConvCmd(ADC1, ENABLE); //使能指定的ADC1的軟件轉換啟動功能
-
- while(!ADC_GetFlagStatus(ADC1, ADC_FLAG_EOC ));//等待轉換結束
- return ADC_GetConversionValue(ADC1); //返回最近一次ADC1規則組的轉換結果
- }
- double pid_lim(double x,double max,double min)
- {
- if(x>max)return max;
- if(x<min)return min;
- return x ;
- }
- int test1=0;
- int m=0;
- long int zhong=0;
- int zhi=0;
- #include "SPWM.H"
- #define guan_xi 20.0
- float set_vcc=706;
- float p=0.001,i=0,d=0.002;
- float err=0,last_err=0,err_sum=0;
- float pid_out=0;
- u16 acd_veul=0;
- int d_fen_pin=0;
- void wei_ya_pid()
- {
-
- for(i=0;i<100000;i++)
- {
- acd_veul=Get_Adc(ADC_Channel_2);
- zhong+=acd_veul;
-
- }
- zhi=zhong/100000;
- zhong=0;
- // err=702-zhi;
- // pid_out=err*p;
- // err_sum+=err;
- // err_sum=pid_lim(err_sum,100.0,-100.0);
- // pid_out+=err_sum*i;
- // pid_out+=(err-last_err)*d;
- //
- // d_fen_pin++;
- // if(d_fen_pin%10000)last_err=err;
- //
- // tiao_fu_sin_1_A(0.9+pid_out);
- // tiao_fu_sin_1_C(0.9+pid_out);
- if((zhi-set_vcc)>2)pid_out=pid_out-0.006;//
- if((zhi-set_vcc)<-2)pid_out=pid_out+0.006;//706
- tiao_fu_sin_1_A(0.8+pid_out); //0.9
- tiao_fu_sin_1_C(0.8+pid_out);
-
- }
- float wei_ding_dian_ya=0;
- int mo_shi=0;
- float xian_shi_pin_ln=50.1;
- float wei_1A=0.878,wei_2A=1.11;
- int main(void)
- {
- TIM_Int_Init();
- TIM_PWM_Init();
- TIM_Cmd(TIM3, ENABLE); /* TIM3 */
- TIM_Cmd(TIM4, ENABLE); /* TIM4 */
- Key_GPIO_Config();
- Adc_Init();
- delay_init(); //延時函數初始化
- OLED_Init(); //初始化OLED
- OLED_Clear();
-
- mo_shi=2018;
- OLED_ShowString(0,0,"2018");
- Lcd12864_Write16CnCHAR(32,0,"年電子競賽");
- // Lcd12864_Write16CnCHAR(0,2,"測試模式");
- Lcd12864_Write16CnCHAR(0,6,"頻率");
- // Lcd12864_Write16CnCHAR(0,6,"輸出電流");
-
- // sprintf(displayhc,"%d",mo_shi);
- // OLED_ShowString(64,2,displayhc);
-
-
-
- sprintf(displayhc,"%3.1f",pin_lv);
- OLED_ShowString(64,6,displayhc);
-
- //OLED_ShowString(64,4,xian_shi_pin_ln);
- // OLED_ShowString(64,6,3);
-
- while (1)
- {
- check_key();
-
- if(key4_flag==5) { tiao_fu_sin_1_A(wei_1A); tiao_fu_sin_1_C(wei_1A); if(Key_Scan(GPIOC,GPIO_Pin_9)==0){my_delay_ms(30);if(Key_Scan(GPIOC,GPIO_Pin_9)==0)
- {
- wei_1A=wei_1A+0.0025;
- }
- }
- while(Key_Scan(GPIOC,GPIO_Pin_9)==0);
-
-
- if(Key_Scan(GPIOC,GPIO_Pin_8)==0){my_delay_ms(30);if(Key_Scan(GPIOC,GPIO_Pin_8)==0)
- {
- wei_1A=wei_1A-0.0025;
- }
- }
- while(Key_Scan(GPIOC,GPIO_Pin_8)==0);
-
- }
-
-
-
-
- else if(key4_flag==4){ tiao_fu_sin_1_A(wei_2A ); tiao_fu_sin_1_C(wei_2A); if(Key_Scan(GPIOC,GPIO_Pin_9)==0){my_delay_ms(30);if(Key_Scan(GPIOC,GPIO_Pin_9)==0)
- {
- wei_2A=wei_2A+0.0025;
- }
- }
- while(Key_Scan(GPIOC,GPIO_Pin_9)==0);
-
-
- if(Key_Scan(GPIOC,GPIO_Pin_8)==0){my_delay_ms(30);if(Key_Scan(GPIOC,GPIO_Pin_8)==0)
- {
- wei_2A=wei_2A-0.0025;
- }
- }
- while(Key_Scan(GPIOC,GPIO_Pin_8)==0);
- }
-
-
-
- else
- {
- // key4_flag=3;
- // set_vcc=708;
- wei_ya_pid();
- }
- if(key4_flag==3){
- if(Key_Scan(GPIOC,GPIO_Pin_9)==0){my_delay_ms(10);if(Key_Scan(GPIOC,GPIO_Pin_9)==0)
- {
- // set_vcc=set_vcc+5;
- }
- }
- while(Key_Scan(GPIOC,GPIO_Pin_9)==0);
-
-
- if(Key_Scan(GPIOC,GPIO_Pin_8)==0){my_delay_ms(10);if(Key_Scan(GPIOC,GPIO_Pin_8)==0)
- {
- set_vcc=set_vcc-156;
- if(set_vcc==550){
- Lcd12864_Write16CnCHAR(0,3,"調壓到");
- sprintf(displayhc,"%3.1f",20.0);
- OLED_ShowString(64,3,displayhc);
- }
- if(set_vcc==394){
- sprintf(displayhc,"%3.1f",14.6);
- OLED_ShowString(64,3,displayhc);
-
- }
- }
- }
- while(Key_Scan(GPIOC,GPIO_Pin_8)==0){}
-
- }
- }
- }
-
復制代碼
所有資料51hei提供下載:
spwm例程.rar
(315.11 KB, 下載次數: 234)
2018-10-16 18:07 上傳
點擊文件名下載附件
|