pidout1=90 + PIDcontrol(setjiaodu,jiaodu); //pid算式这个90是哪里来的?具体指什么?
- #include <reg52.h>
- #include <intrins.H>
- #include <math.H>
- #include <stdio.h>
- #define u8 unsigned char
- #define uchar unsigned char
- #define uint unsigned int
- #define u16 unsigned int
- #define uchar unsigned char
- #define uint unsigned int
- typedef unsigned char Uint8; /* defined for unsigned 8-bits integer variable 无符号8位整型变量 */
- typedef unsigned int Uint16; /* defined for unsigned 16-bits integer variable 无符号16位整型变量 */
- typedef unsigned long Uint32; /* defined for unsigned 32-bits integer variable 无符号32位整型变量 */
- sbit LCD_RS = P1^0; //液晶1602 RS端口
- sbit LCD_RW = P1^1; //液晶1602 RS端口
- sbit LCD_EP = P1^2; //液晶1602 EN端口
- sbit PWM_PIN0 = P2^0 ;
- sbit PWM_PIN1 = P2^1 ;
- int setjiaodu = 40;//占空比最大100 6 16
- u16 pwm;//占空比最大100 6 16
- sbit Key_Set = P1^3 ;
- sbit Key_Up = P1^4 ;
- sbit Key_Dowm = P1^5 ;
- uchar code table[] = {": "}; //设定速度初始化
- uchar code table1[] = {" "}; // 动态显示初始化
- uchar n , i,x,table2[5],table3[5],ge,shi,bai,flag1,key1n,temp;
- ///***********延时1MS程序***/
- void delay(uint z)
- { uint x,y;
- for(x=z;x>0;x--)
- for(y=80;y>0;y--);
- }
- float kp = 0.70;
- float ki = 0.0005;
- float kd = 0.001;
- float ee,eeh,p; //PID误差和误差累计
- float pidout1,pidout2,pidout3;
- float PIDcontrol( int uset , int feedback) //pid算式
- {
- float duk,D;
- eeh=ee;
- ee=uset*1.0-feedback*1.0;
- p += ee;
- D = ee -eeh;
- duk=kp*ee+ki*p-kd*D;
- return duk;
- }
- /******液晶写命令************/
- void write_com(uchar com)
- { LCD_RS=0;
-
- P0=com ;
- // delay(1);
- LCD_EP=1;
- delay(1);
- LCD_EP=0;
- }
- /*****************/
- /********液晶写数据***********/
- void write_data(uchar date)
- { LCD_RS=1;
-
- P0=date ;
- //delay(1);
- LCD_EP=1;
- delay(1);
- LCD_EP=0;
- }
- /*****************************/
- /********显示动态速度数据*********/
- void display_val(unsigned int zhuan)
- {
-
- table2[0]=zhuan/10000+0x30; //取万位
- table2[1]=(zhuan%10000)/1000+0x30; //取千位
- table2[2]=(zhuan%1000)/100+0x30; //取百位
- table2[3]=(zhuan%100)/10+0x30; //取十位
- table2[4]=zhuan%10+0x30; //取个位
- // write_com(0x80+0x40+7);
- // write_data(table2[0]);
- // write_com(0x80+0x40+8);
- // write_data(table2[1]);
- write_com(0x80+0x40+4);
- //write_data(table2[2]);
- //write_com(0x80+0x40+10);
- write_data(table2[3]);
- //write_com(0x80+0x40+11);
- write_data(table2[4]);
-
- }
- void dis(int z,unsigned int zhua,int x,int y)
- {
-
- table2[0]=zhua/10000+0x30; //取万位
- table2[1]=(zhua%10000)/1000+0x30; //取千位
- table2[2]=(zhua%1000)/100+0x30; //取百位
- table2[3]=(zhua%100)/10+0x30; //取十位
- table2[4]=zhua%10+0x30; //取个位
- if(z==1)
- write_com(0x80+x);
- if(z==2)
- write_com(0x80+0x40+x);
- // write_data(table2[0]);
- // write_data(table2[1]);
- write_data(table2[2]);
- if(y==1)
- write_data('.');
- write_data(table2[3]);
- // if(y==2)
- // write_data('.');
- write_data(table2[4]);
- write_com(0x80+16);
-
-
- }
- void dis0(int z,int zhua,int x,int y)
- {
- if(zhua>0)
- {
- table2[0]=zhua/10000+0x30; //取万位
- table2[1]=' '; //取千位
- table2[2]=(zhua%1000)/100+0x30; //取百位
- table2[3]=(zhua%100)/10+0x30; //取十位
- table2[4]=zhua%10+0x30; //取个位
- if(z==1)
- write_com(0x80+x);
- if(z==2)
- write_com(0x80+0x40+x-1);
- write_data(table2[1]);
- write_data(table2[2]);
- write_data(table2[3]);
- write_data(table2[4]);
- write_com(0x80+16);
- }
- else
- {
- zhua=abs(zhua);
- table2[0]=zhua/10000+0x30; //取万位
- table2[1]='-'; //取千位
- table2[2]=(zhua%1000)/100+0x30;
- table2[3]=(zhua%100)/10+0x30; //取十位
- table2[4]=zhua%10+0x30; //取个位
- if(z==1)
- write_com(0x80+x);
- if(z==2)
- write_com(0x80+0x40+x-1);
- write_data(table2[1]);
- write_data(table2[2]);
- write_data(table2[3]);
- write_data(table2[4]);
- write_com(0x80+16);
- }
-
- }
- /*--------------------------液晶初始化-----------------------------*/
- void init_lcd()
- {
- LCD_EP=0;
- write_com(0x38);
- write_com(0x08);
- write_com(0x06);
- write_com(0x0c);
- write_com(0x01);
- //初始化显示
- write_com(0x80+2);
- for(i=0;i<13;i++)
- {
- write_data(table[i]);
- delay(3);
- }
- write_com(0x80+0x40);
- for(i=0;i<14;i++)
- {
- write_data(table1[i]);
- delay(3);
- }
- }
- void PWMInit()
- {
- TMOD|=0x01; //模式设置,00000001,可见采用的是定时器0,工作与模式1(M1=0,M0=1)。
- TR0=1; //打开定时器
- TH0=0Xff; //定时器设置,每隔100微秒发起一次中断。
- TL0=0Xc1;
- ET0=1; //开定时器0中断
- EA=1; //开总中断
- }
- sbit ADCS = P2^4; //ADC0832 片选
- sbit ADCLK = P2^5; //ADC0832 时钟
- sbit ADDI = P2^6; //ADC0832 数据输入 /*因为单片机的管脚是双向的,且ADC0832的数据输入输出不同时进行,
- sbit ADDO = P2^6; //ADC0832 数据输出 /*为节省单片机引脚,简化电路所以输入输出连接在同一个引脚上
- static unsigned char Adc0832(unsigned char channel)
- {
- Uint8 i=0;
- Uint8 j;
- Uint16 dat=0;
- Uint8 ndat=0;
- Uint8 Vot=0;
- if(channel==0)channel=2;
- if(channel==1)channel=3;
- ADDI=1;
- _nop_();
- _nop_();
- ADCS=0;//拉低CS端
- _nop_();
- _nop_();
- ADCLK=1;//拉高CLK端
- _nop_();
- _nop_();
- ADCLK=0;//拉低CLK端,形成下降沿1
- _nop_();
- _nop_();
- ADCLK=1;//拉高CLK端
- ADDI=channel&0x1;
- _nop_();
- _nop_();
- ADCLK=0;//拉低CLK端,形成下降沿2
- _nop_();
- _nop_();
- ADCLK=1;//拉高CLK端
- ADDI=(channel>>1)&0x1;
- _nop_();
- _nop_();
- ADCLK=0;//拉低CLK端,形成下降沿3
- ADDI=1;//控制命令结束
- _nop_();
- _nop_();
- dat=0;
- for(i=0;i<8;i++)
- {
- dat|=ADDO;//收数据
- ADCLK=1;
- _nop_();
- _nop_();
- ADCLK=0;//形成一次时钟脉冲
- _nop_();
- _nop_();
- dat<<=1;
- if(i==7)dat|=ADDO;
- }
- for(i=0;i<8;i++)
- {
- j=0;
- j=j|ADDO;//收数据
- ADCLK=1;
- _nop_();
- _nop_();
- ADCLK=0;//形成一次时钟脉冲
- _nop_();
- _nop_();
- j=j<<7;
- ndat=ndat|j;
- if(i<7)ndat>>=1;
- }
- ADCS=1;//拉低CS端
- ADCLK=0;//拉低CLK端
- ADDO=1;//拉高数据端,回到初始状态
- dat<<=8;
- dat|=ndat;
- return(dat); //return ad data
- }
- Uint16 ReadAdc(unsigned char channel,unsigned int Number)//channel为通道 Number为输出值最大值
- {
- Uint8 Read_AD;
- Uint16 AdResult;
- Read_AD = Adc0832(channel);
- AdResult = (Uint32)4*Read_AD*Number/255;//255
- return AdResult;
- }
- #define KEYDELAY 20
- void KeyScanDeal(Uint8 sMenu,Uint16 *Setnumb1,float *Setnumb2,float *Setnumb3,float *Setnumb4)
- {
-
- static Uint8 Menu = 0;
- if(Key_Set == 0)
- {
- Menu ++;
- if(Menu > sMenu)
- Menu = 0;
- while(Key_Set == 0);
- }
-
- switch (Menu)
- {
- case 1:
- {
- if(Key_Up == 0)
- {
- delay(KEYDELAY);
- if(Key_Up == 0 && (*Setnumb1) < 100)
- {
- (*Setnumb1) =*Setnumb1 + 1;
- }
- }
- else if(Key_Dowm == 0 && (*Setnumb1) > 0)
- {
- delay(KEYDELAY);
- if(Key_Dowm == 0)
- {
- (*Setnumb1) =*Setnumb1 - 1;
- }
- }
- break;
- }
- case 2:
- {
- if(Key_Up == 0 && (*Setnumb2) < 100)
- {
- delay(KEYDELAY);
- if(Key_Up == 0)
- {
- (*Setnumb2) =*Setnumb2 + 0.01;
- }
- }
- else if(Key_Dowm == 0 && (*Setnumb2) > 0)
- {
- delay(KEYDELAY);
- if(Key_Dowm == 0)
- {
- (*Setnumb2) =*Setnumb2 -0.01;
- }
- }
- break;
- }
- case 3:
- {
- if(Key_Up == 0 && (*Setnumb3) < 50)
- {
- delay(KEYDELAY);
- if(Key_Up == 0)
- {
- (*Setnumb3) =*Setnumb3 + 0.0001;
- }
- }
- else if(Key_Dowm == 0)
- {
- delay(KEYDELAY);
- if(Key_Dowm == 0 && (*Setnumb3) > 0)
- {
- (*Setnumb3) =*Setnumb3 -0.0001;
- }
- }
- break;
- }
- case 4:
- {
- if(Key_Up == 0 && (*Setnumb4) < 59)
- {
- delay(KEYDELAY);
- if(Key_Up == 0)
- {
- (*Setnumb4) =*Setnumb4 + 0.001;
- }
- }
- else if(Key_Dowm == 0 && (*Setnumb4) > 0)
- {
- delay(KEYDELAY);
- if(Key_Dowm == 0)
- {
- (*Setnumb4) =*Setnumb4 -0.001;
- }
- }
- break;
- }
- }
- }
-
- void main()
- {
- Uint8 i = 0;
- int jiaodu = 0;
- PWMInit();
- LCD_RW=0;
- init_lcd(); // 初始化液晶显示
- PWMInit();
- PWM_PIN1 = 1;
- while(1)
- {
- i ++;
- if(i%5 ==0)
- {
- KeyScanDeal(4,&setjiaodu,&kp,&ki,&kd);
- dis(1,setjiaodu,0,2);
- dis(1,jiaodu,6,2);
- dis(2,kp*100,0,2);
- dis(2,ki*10000,5,2);
- dis(2,kd*1000,9,2);
-
- }
- jiaodu = ReadAdc(0,80) - 156;
- pidout1=90 + PIDcontrol(setjiaodu,jiaodu); //pid算式
- if(pidout1 > 100)
- {
- pwm = 99;
- }
- else if(pidout1 <1)
- {
- pwm = 1;
- }
- else
- {
- pwm = pidout1;
- }
- }
- }
- void time0() interrupt 1
- {
- static int cnt = 0;
-
- if(cnt <= pwm)
- {
- PWM_PIN0 = 1;
- }
- else
- {
- PWM_PIN0 = 0;
- }
-
- cnt++;
-
- if(cnt > 100)
- {
- cnt = 0;
- }
- TH0=0Xff;
- TL0=0Xc1;
-
- }
复制代码 |