qq_29566853
qq_29566853
采纳率0%
2016-11-20 14:01

基于单片机的直流电机调速系统

怎么把这个数码管显示改成12864屏显示,我有C程序,但是我不会改。
图片说明
#include
#include
#define uchar unsigned char
#define uint unsigned int
#ifndef LCD_H
#define LCD_H
#include

#define
SPI_CLK
0x00000010
//P0.4
#define
SPI_DATA
0x00000020
//P0.5
#define
RW
0x00000800
//RW
#define
RS
0x00000400
//RS
#define
CS1
0x00001000
//CS1
#define
CS2
0x00002000
//CS2
#define
E
0x00004000
//E
#define
Kai
0x3F
#define
Guang
0x3E
#define
Hang
0xC0
#define
Ye
0xB8
#define
Lie
0x40
#define
Setlie(a)
\
IOCLR = RW;
\
IOCLR = RS;
\
send(Lie+a);
#define
Setye(a)
\

IOCLR = RW;
\
IOCLR = RS;
\
send(Ye+a);
#define
Setweizi(a,b)
\
IOCLR = RW;
\
IOCLR = RS;
\
send(Lie+a);
\
send(Ye+b);
#define
Write(a)

\
IOCLR = RW;
\
IOSET = RS;
\
send(a);
void send(uint8 dat);

void LCD_disp(uint8 a,uint8 b,uint8 c,uint8 d,uint8 m,uint8 *shuju)

;

void SetCS(uint8 a);

void LCD(uint8 a,uint8 b,uint8 c,uint8 d, uint8 *shuju);

void LCD_num(uint8 a,uint8 b,uint8 *shuju,uint8 n);

void LCD_str(uint8 a,uint8 b,uint8 *strtab,uint8 n);

void LCD_hanzi(uint8 a,uint8 b,uint8 *hanzitab,uint8 n);

void LCD_xian(uint8 a,uint8 b,uint8 *strtab,uint8 n);

void LCD_Main(void);

#endif

sbit PWM_FC=P3^0;

typedef struct PID
{
int e;
int e1;
int e2;//pid 偏差
float uk ;
float uk1 ;
float duk ;//pid输出值
float Kp ;
float Ki ;
float Kd ;//pid控制系数 10,12,1.5

} PID;

PID sPID;
int out=0;
int SpeedSet,SpeedOut;
uint cnt=0;
uint Inpluse=0;//脉冲计数
uint PWMTime=100;//脉冲宽度
unsigned char h,l,temp;
unsigned char key_num,key_flag,key_count; //全局变量
unsigned char flag,i,set_value;
char qian,bai,shi,ge;

void PIDControl();
void IncPIDInit();
void SystemInit();
void delay(uchar x);
void PWMOUT();
unsigned char keyscan();
void get_Data();
void set_Data();
void SegRefre(); //显示刷新

/**************PID模型************/
void IncPIDInit()
{
sPID.e=0;
sPID.e1=0;
sPID.e2=0;
sPID.uk=0;
sPID.uk1=0;
sPID.duk =0;
sPID.Kp=27; //28; //18
sPID.Ki=6.6; //6.7 ; //6.8
sPID.Kd=3.4; //3.6 ; //1.7
}

/**************主函数************/
void main()
{
SystemInit();
IncPIDInit();
while(1)
{

get_Data();
set_Data();
PWMOUT();
}
}

void SegRefre() //显示刷新
{
Data_Buffer[4]=SpeedOut/1000; //分离采集脉冲数各位
Data_Buffer[5]=SpeedOut%1000/100;
Data_Buffer[6]=SpeedOut%100/10;
Data_Buffer[7]=SpeedOut%10;
}

void PIDControl() //pid偏差计算
{
sPID.e=SpeedSet-SpeedOut;
sPID.duk=(sPID.Kp*(sPID.e-sPID.e1)+sPID.Ki*sPID.e
+sPID.Kd*(sPID.e-2*sPID.e1+sPID.e2))/10;

sPID.uk=sPID.uk1+sPID.duk;
out=(int)sPID.uk;
if(out>10000)
{
out=10000;
}
else if(out<0)
{
out=0;
}
sPID.uk1=sPID.uk;
sPID.e2=sPID.e1;
sPID.e1=sPID.e;
PWMTime=out;

}

void delay(uchar x)
{
uint i,j;
for(i=x;i>0;i--)
for(j=50;j>0;j--);
}
void PWMOUT()
{
if(cnt {
PWM_FC=10000;
}
else
{
PWM_FC=0;
}
if(cnt>10000) cnt=0;
}
void SystemInit()
{
TMOD=0X21;

TH0=(65536-2000)/256;
TL0=(65536-2000)%256;
TH1=0xC0;
TL1=0XC0;
ET1=1;
ET0=1;
TR0=1;
TR1=1;
EX0=1; //中断0用来测量转速
IT0=1;
EA=1;
}

void int0() interrupt 0
{
Inpluse++;
}
void t0() interrupt 1
{
static unsigned char Bit=0;//静态变量,退出程序值保留
static unsigned int time=0;
TH0=(65536-1000)/256;
TL0=(65536-1000)%256;

Bit++;
time++;  //转速测量周期
if(Bit>8) Bit=0;          
P0=0xff;
P2=Duan[Data_Buffer[Bit]];  //显示段码
switch(Bit)                 //数码管位选
{
    case 0:P0=0X7F;break;
    case 1:P0=0XBF;break;
    case 2:P0=0XDF;break;
    case 3:P0=0XEF;break;
    case 4:P0=0XF7;break;
    case 5:P0=0XFB;break;
    case 6:P0=0XFD;break;
    case 7:P0=0XFE;break;
}

// if(time==300)PIDControl();

if(time>1000)
{
EX0=0;
SpeedOut=Inpluse; //算得1s采集的脉冲数
Inpluse=0;

time=0;
PIDControl(); //调用PID算法,输出PWM
EX0=1;
}
}
void timer_1() interrupt 3
{
cnt++; //cnt越大占空比越高
}

unsigned char keyscan()
{

KEY_PRESET(0X0F);
if(temp!=0X0F)//是否有键按下
{
delay(10);
temp=P1;
temp=temp&0X0F;
if(temp!=0X0F) //确实有键按下
{
key_flag=1;//按下键标志位
switch(temp)
{
case 0X0E:h=0;break; //行
case 0X0D:h=1;break;
case 0X0B:h=2;break;
case 0X07:h=3;break;
default:break;
}
KEY_PRESET(0XF0);
switch(temp)
{
case 0XE0:l=0;break; //列
case 0XD0:l=1;break;
case 0XB0:l=2;break;
case 0X70:l=3;break;
default:break;
}
key_num=3*h+l;//按下键的键值
if(key_num<=9) key_count++;
while(temp!=0XF0)//等待释放
{
temp=P1;
temp=temp&0XF0;
}

}
}

return key_num;//返回键值
}

void get_Data()
{

keyscan(); //键盘扫描
if(key_flag==1)//有键按下
{
if(key_num<=9&&key_count<5) //只允许输入一个4位的数值
{

                 key_flag=0;  //按下键标志位清零
                 if(key_count==1)//输入转速值第一位
                 {
                    Data_Buffer[0]=keyscan();
                    qian=keyscan();
                 }
                 if(key_count==2)//输入转速值第二位
                 {
                    Data_Buffer[1]=keyscan();
                    bai=keyscan();
                 }
                 if(key_count==3)//输入转速值第三位
                 {
                    Data_Buffer[2]=keyscan();
                    shi=keyscan();
                 }
                 if(key_count==4)//输入转速值第四位
                 {
                    Data_Buffer[3]=keyscan();
                    ge=keyscan();
                 }
           }
           if(key_num==10&&key_count>=4)//确认键按下
                   flag=1;//确认键按下标志位     
           if(key_num==11)//清除键按下
           {
                  flag=0;//确认键按下标志位清零
                  key_count=0; //按下数字计数清零
                  Data_Buffer[0]=10;  
                  Data_Buffer[1]=10;
                  Data_Buffer[2]=10;
                  Data_Buffer[3]=10;
                  SegRefre();
           }
      }  

}
void set_Data()
{
if(flag==1) //按下确定键,将数值送给PID
{
SpeedSet=qian*1000+bai*100+shi*10+ge;
SegRefre();

}

}

  • 点赞
  • 写回答
  • 关注问题
  • 收藏
  • 复制链接分享
  • 邀请回答

3条回答

为你推荐