|
节气门(闭环)电机PWM调节,可以采集电压来调节电机转速,PID控制
- #include <STC12C5A60S2.H>
- #include <intrins.H>
- #define AD_SPEEDHH 0x60 // 0110,0000 90个时钟周期转换一次
- #define AD_SPEEDH 0x50 // 0100,0000 180个时钟周期转换一次
- #define AD_SPEEDL 0x20 // 0010,0000 360个时钟周期转换一次
- #define AD_SPEEDLL 0x00 // 0000,0000 540个时钟周期转换一次
- #define AD_POWER 0x80 //1000,0000 AD电源
- #define AD_FLAG 0x10 //0001,0000 AD标志位
- #define AD_START 0x08 //0000,1000 启动AD转换
- #define AD_CHANNEl 0x07 //0000,0111 AD转换通道选择
- #define uint unsigned int
- #define uchar unsigned char
- sbit PWM=P2^0;
- bit f1,f2;
- char ZKB;
- uint tb_ad,jqm1_ad,jqm2_ad;
- /*******************************************************
- 延时程序
- *******************************************************/
- delay(uint ms)
- {
- while(ms--);
- return 0;
- }
- /*******************************************************
- 中断程序
- *******************************************************/
- void timer0_init() //中断初始化
- {
- TH0=0xff; //11.0592M晶振,定时1/60000s
- TL0=0x46; //波形频率1200Hz
- TMOD=0x01;
- EA=1;
- ET0=1;
- TR0=1;
- }
- timer0() interrupt 1 //定时0.02ms
- {
- uchar a;
- TH0=0xff; //11.0592M晶振,定时1/60000s
- TL0=0x80;
- //TL0=0x46; //波形频率1200Hz
- a+=1;
- if(a>=50) a=0;
- if(a<ZKB) PWM=1;
- else PWM=0;
- }
- /*******************************************************
- AD转换程序
- *******************************************************/
- void ad_init() //AD转换初始化函数
- {
- ADC_RES = 0; //转换结果寄存器清空
- ADC_RESL = 0;
- P1ASF=0xff; //P1口作为模拟功能使用
- }
- uint get_AD_res(uchar ch) //AD转换函数
- {
- ch &= AD_CHANNEl; //选择转换通道
- ADC_CONTR = AD_POWER|AD_SPEEDHH|ch|AD_START; //1110,1***启动A/D电源、选择转换速度、选择通道、启动转换
- _nop_(); //必要的延时,至少四个空指令
- _nop_();
- _nop_();
- _nop_();
- while(!(ADC_CONTR&AD_FLAG)); //0001,0000等待转换完成
- ADC_CONTR &= 0xe7; //1110,0111 AD标志位清0,关闭AD转换
- return ADC_RES; //返回 A/D 高 8 位转换结果
- }
- /*******************************************************
- PID程序
- *******************************************************/
- PID(uint jqm_ad)
- {
- if(tb_ad<55)
- tb_ad=55;
- if((tb_ad-10)<jqm_ad<(tb_ad+10))
- ZKB=tb_ad/4.2;
- if(jqm_ad<(tb_ad-10))
- ZKB=(tb_ad+3*tb_ad-3*jqm_ad)/4.2;
- if(jqm_ad>(tb_ad+10))
- ZKB=(tb_ad+3*tb_ad-3*jqm_ad)/4.2;
- if(ZKB<=0)
- ZKB=0;
- if(ZKB>=50)
- ZKB=50;
- return 0;
- }
- /*******************************************************
- 主函数
- *******************************************************/
- main()
- {
- P2M1=0X00;
- P2M0=0X01;
- ad_init();
- timer0_init();
- P1=0;
- ZKB=0;
- delay(1000);
- while(1)
- {
- jqm1_ad=get_AD_res(2);
- delay(30);
- jqm2_ad=get_AD_res(0);
- delay(30);
- if((10<jqm1_ad<240)||(10<jqm2_ad<240))
- f1=1;
- else f1=0;
- while(f1)
- {
- jqm1_ad=get_AD_res(2);
- delay(30);
- jqm2_ad=get_AD_res(0);
- delay(30);
- jqm2_ad=250-jqm2_ad;
- tb_ad=get_AD_res(6);
- delay(30);
- if((20<jqm1_ad)&&(jqm1_ad<240))
- {
- f1=1;
- PID(jqm1_ad);
- }
- …………余下代码请下载附件…………
复制代码
完整源码下载:
pid采集电压电机控制.zip
(47.17 KB, 下载次数: 91)
|
|