📄 main.c
字号:
#include "reg52.h"
#include <intrins.h>
#define uchar unsigned char
#define uint unsigned int
/****************************************************************
I2C总线协议程序
****************************************************************/
#define NOP _nop_() /*定义空指令*/
sbit SDA=P1^2; /*模拟I2C数据传送位*/
sbit SCL=P1^3; /*模拟I2C时钟控制位*/
bit ack; /*应答标志位*/
void Start_I2c()
{
SDA=1; NOP;
SCL=1; NOP;
SDA=0; NOP;
SCL=0; NOP;
}
void Stop_I2c()
{
SDA=0; NOP;
SCL=1; NOP;
SDA=1; NOP;
}
void Senduchar(uchar c)
{
uchar i;
for(i=0;i<8;i++) /*要传送的数据长度为8位*/
{
if((c<<i)&0x80)SDA=1;
else SDA=0; NOP;
SCL=1; NOP;
SCL=0; NOP;
}
SDA=1; NOP;
SCL=1; NOP;
if(SDA==1)ack=0; else ack=1;
SCL=0; NOP;
}
uchar Rcvuchar()
{
uchar x=0;
uchar i;
SDA=1; /*置数据线为输入方式*/
for(i=0;i<8;i++)
{
SCL=0; NOP;
SCL=1; NOP;
x=x<<1;
if(SDA==1) x=x+1; /*读数据位,接收的数据位放入retc中 */
NOP;
}
SCL=0; NOP;
return(x);
}
void Ack_I2c(bit a)
{
if(a==0) SDA=0;
else SDA=1;
NOP;
SCL=1; NOP;
SCL=0; NOP;
}
bit ISendStr(uchar sla,uchar suba,uchar *s,uchar no)
{
uchar i;
Start_I2c(); /*启动总线*/
Senduchar(sla); /*发送器件地址*/
if(ack==0)return(0);
Senduchar(suba); /*发送器件子地址*/
if(ack==0)return(0);
for(i=0;i<no;i++)
{
Senduchar(*s); /*发送数据*/
if(ack==0)return(0);
s++;
}
Stop_I2c(); /*结束总线*/
return(1);
}
bit IRcvStr(uchar sla,uchar suba,uchar *s,uchar no)
{
uchar i;
Start_I2c(); /*启动总线*/
Senduchar(sla); /*发送器件地址*/
if(ack==0)return(0);
Senduchar(suba); /*发送器件子地址*/
if(ack==0)return(0);
Start_I2c();
Senduchar(sla+1);
if(ack==0)return(0);
for(i=0;i<no-1;i++)
{
*s=Rcvuchar(); /*发送数据*/
Ack_I2c(0); /*发送就答位*/
s++;
}
*s=Rcvuchar();
Ack_I2c(1); /*发送非应位*/
Stop_I2c(); /*结束总线*/
return(1);
}
/****************************************************************
ZLG7219程序
****************************************************************/
#define zlg7290 0x70 //ZLG7290的IIC地址
#define SubKey 0x01
#define SubCmdBuf 0x07
#define SubDpRam 0x10
void delayMS(uint i)
{
uchar j;
while(i--)
for(j=0;j<60;j++);
}
uchar ZLG7290_SendCmd(uchar Data1,uchar Data2)
{
uchar Data[2];
Data[0]=Data1;
Data[1]=Data2;
ISendStr(zlg7290,0x07,Data,2);
delayMS(10);
return 1;
}
uchar ZLG7290_GetKey()
{
uchar rece;
rece=0;
IRcvStr(zlg7290,1,&rece,1);
delayMS(10);
return rece;
}
/***************************************************
TLC549 A/D转换
TLC5620 D/A转换
****************************************************/
sbit CLK=P1^5;
sbit DAT=P1^6;
sbit CS =P1^7;
sbit LOAD=P1^4;
uchar TLC549ADC(void)
{
uchar i,x;
CLK=0; DAT=1; CS=0;
for(i=0;i<8;i++)
{
CLK=1; NOP;
x<<=1;
if(DAT==1) x++;
CLK=0; NOP;
}
CS=1;
return (x);
}
void DAC5620(uchar ch,uchar dat)
{
uchar i,x;
ch=ch<<6;
x=ch;//+0x20; //这里要看参考电压是5V还是2.5V
for(i=0;i<3;i++)
{
x=x<<1;
DAT=CY;;
CLK=1; NOP;
CLK=0; NOP;
}
x=dat;
for(i=0;i<8;i++)
{
x=x<<1;
DAT=CY;;
CLK=1; NOP;
CLK=0; NOP;
}
LOAD=0; LOAD=1;
}
/*********************************************************/
sbit RST=P1^0;
sbit KEY_INT=P3^3;
uchar key,adc,dac,sr;
int r,e0,e1,e2,y0,u;
uint m,s,tm1,tm2;
unsigned char disp[8]={8,9,5,1,5,2,6,7};
#define time1 -10000
#define time2 -2000
#define K 20 //@@@* 加入K只是为了化小数运算为整数运算,加入K即是将原来小数的Kp,Ki,Kd乘上K得现在整数的Kp,Ki,Kd,K可取100
#define Kp 3
#define Ki 1
#define Kd 0
void Display() interrupt 1
{
TH0=time1>>8;TL0=time1&0xff;
tm1++;
}
void GetKey() interrupt 2
{
key=ZLG7290_GetKey();
}
void Control() interrupt 3
{
TH1=time2>>8;TL1=time2&0xff;
if(++tm2>10)
{
tm2=0;
adc=TLC549ADC();
y0=adc;r=sr;
e2=e1; e1=e0; e0=r-y0;
u+=e0*Ki+(e0-e1)*Kp+(e0-2*e1+e2)*Kd;
if(u>255*K) u=255*K;
if(u<0) u=0;
dac=u/K;
DAC5620(3,dac);
}
}
void main()
{
uchar i,p,n;
IE=0x80+0x08+0x04+0x02; TMOD=0x11; IT1=1;
TH0=time1>>8;TL0=time1&0xff;TR0=1;
TH1=time2>>8;TL1=time2&0xff;TR1=1;
RST=0;
delayMS(10);
RST=1; sr=0x80;
delayMS(10);
tm1=0; tm2=0; m=0;
DAC5620(0,0x20);
DAC5620(1,0x40);
DAC5620(2,0x80);
DAC5620(3,0xc0);
while(1)
{
if(tm1>50)
{
tm1=0; s=p;
switch(key)
{
case 1: sr=0x10; break;
case 2: sr=0x30; break;
case 3: sr=0x50; break;
case 4: sr=0x70; break;
case 5: sr=0x90; break;
case 6: sr=0xb0; break;
case 7: sr=0xd0; break;
case 8: sr=0xf0; break;
}
if(key!=0) n=key;
key=0;
disp[0]=dac&0xf;
disp[1]=(dac>>4)&0xf;
disp[2]=0x1f;
disp[3]=adc&0xf;
disp[4]=(adc>>4)&0xf;
disp[5]=0x1f;
disp[6]=sr&15;
disp[7]=(sr>>4)&15;
for(i=0;i<8;i++)
{
ZLG7290_SendCmd(0x60+i,disp[i]);
delayMS(10);
}
}
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -