描述:
我想把数码管改成LCD12864屏
求高手指导一下
C程序
#include<reg52.h>
#include<stdio.h>
#define uchar unsigned char
#define uint unsigned int
#ifndef _LCD_H_
#define _LCD_H_
#include <config.h>
#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<PWMTime)
{
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;