#include<reg52.h>
#define ucharunsigned char
#define uintunsigned int
int LCD_init(); //声明初始化函数
int write_com(unsignedchar);//声明写命令函数
intwrite_date(unsigned char);//声明写数据函数
intdelay(unsigned char);//声明延迟函数
voidtlc5615(unsigned int dat);// TLC5615转换函数
voidLCD_send(unsigned char,unsigned char,unsigned char[],unsigned char);//声明LCD函数
sbit addKey =P1^0;//用于增加目标电压按键
sbit subKey =P1^1;//用于减小目标电压按键
sbit CS=P3^5;//定义ADC0832脚位
sbit CLK=P3^7;//定义ADC0832脚位
sbit DO= P3^6;//定义ADC0832脚位
sbit DI=P3^4;//定义ADC0832脚位
sbit LED=P1^2;//定义LED灯脚位
sbit RS =P2^2;//定义LCD脚位
sbit RW =P2^1;//定义LCD脚位
sbit EN =P2^0;//定义LCD脚位
sbit CS5615=P1^6;//定义DAC5615脚位
sbitSCLK5615=P1^5;//定义DAC5615脚位
sbitDATA5615=P1^7;//定义DAC5615脚位
ucharvoltage[6]="0.00 V";//lcd显示负载电压
uchar end[6]="4.30V";//lcd显示目标电压
unsigned longint val;//(负载电压)用于单片机电压比较
unsigned longint endVal=430;//(目标电压)用于单片机电压比较
voiddelay2ms(void) //晶振12M,误差 0us,含调用
{
unsigned char a,b;
for(b=133;b>0;b--)
for(a=6;a>0;a--);
}
uchar AD0832()
{
uchar V =0,i = 0;
CS=0; //片选信号,低电平有效
DO=0; //DO为高阻态,这里置低为后续读取做准备
delay2ms();
//前三个脉冲为配置设置
CLK=0;
delay2ms();
DI=1;
CLK=1;//第一个脉冲,起始位
delay2ms();
CLK=0;
delay2ms();
DI=1;
CLK=1;//第二个脉冲,该位为“1”时是单端输入模式,为“0”时是差分输入模式
delay2ms();
CLK=0;
delay2ms();
DI=0; //第三个脉冲,DI=1表示选择通道1(CH2),DI=0表示选择通道0(CH1)
CLK=1;
delay2ms();
DI=0; //DI转为高阻态,状态无关紧要,这里给低方便下一轮读取
DO=1; //DO口恢复默认上拉,准备接收信号
CLK=1;
delay2ms();
CLK=0; //第一个下降沿,为去数做准备
delay2ms();//等待芯片接收下降沿并切换输出模式
//接收8位信号并转换
for(i=0;i<8;i++)
{
CLK = 1;
delay2ms();
CLK = 0;
if(DO)//如果DO为高电平,相应的位数是1
V= V | 1<<(7-i);
}
CS = 1;//关闭片选,结束一个转换周期
return V;
}
void Tran(uchardigit)//用于显示lcd显示负载电压
{
val = (unsigned longint)5*100*digit/256;
voltage[0] ='0'+ val/100;//百位
voltage[2] ='0'+ val/10%10;//十位
voltage[3] ='0'+ val%10;//个位
}
void key()//识别按键
{
if(addKey==0);//按键按下
{
delay(5);//延时
if(addKey==0)//按键按下
{
endVal=endVal+10;//增加目标电压
}
}
if(subKey==0)//按键按下
{
delay(5);//延时
if(subKey==0)//按键按下
{
endVal=endVal-10;//减少目标电压
}
}
if(endVal>480)//电压值不大于4.80V
{
endVal=480;//电压值不大于4.80V
}
end[0] ='0'+endVal/100;//百位
end[2]='0'+ endVal/10%10;//十位
end[3]='0'+ endVal%10;//个位
}
void nowEnd()//负载电压与目标电压比较
{
if(val>=endVal)//val为负载电压,endVal为目标电压
{
tlc5615(0);//5615电压输出为0
LED=0;//关闭LED灯
}
}
voidLCD_send(unsigned char i,unsigned char j,unsigned char str[],unsigned char n)
{
//输入:显示行数i,列数j,输出字符,输出字符长度n
unsigned char x=0;
if(i==1)
{write_com(0x80+j);}
else
{write_com(0x80+0x40+j);}
for(x=0;x<n;x++)
{
write_date(str[x]);
}
}
int LCD_init()//初始化函数体
{
EN = 0;
write_com(0X38);//设置16*2显示,5*7点阵,8位数据接口
write_com(0X0C);//设置开显示,不显示光标
write_com(0X06);//写一个字符时,整屏右移
write_com(0X01);//显示清零
return 0;
}
intwrite_com(unsigned char com)//写命令的函数体
{
RS = 0;
RW = 0;
P0 = com;
delay(5);
EN = 1;
delay(5);
EN = 0;
return 0;
}
intwrite_date(unsigned char data1)//写数据的函数体
{
RS = 1;
RW = 0;
P0 = data1;
delay(5);
EN = 1;
delay(5);
EN = 0;
return 0;
}
intdelay(unsigned char xms)//延迟函数
{
unsigned char x,y;
for(x=xms;x>0;x--)
for(y=110;y>0;y--);
return 0;
}
voidtlc5615(unsigned int dat)//控制5615电压输出
{
unsigned char i;
CS5615=1;
DATA5615=0;
SCLK5615=0; //CS高电平期间,SCLK为低电平
dat<<=6;// 数字量dat左移6位,保留原dat低10位。新dat的高10位有效,低6位全0。
CS5615=0; // CS片选有效,开始接收数据
SCLK5615=0;
for(i=0;i<12;i++)// 发送10位数据和2位0,从最高位开始发送。
{ // 非级联方式,只需要输入12位数据。
if((dat&0x8000)==0x8000)
DATA5615=1;
else
DATA5615=0;
SCLK5615=1; //SCLK上升沿,数据输入
dat<<=1;
SCLK5615=0; //SCLK恢复低电平
}
CS5615=1; // CS上升沿,数据送到DAC寄存器
// CS的上升沿和下降沿只有在SCLK为低的时候有效
SCLK5615=0;
DATA5615=0;// 拉高片选端,拉低时钟端与数据端,回到初始状态
}
void main()//主函数
{
tlc5615(430);
LCD_init();
LCD_send(1,0,"Now:",4);
LCD_send(2,0,"End:",4);
while(1)
{
Tran(AD083());
LCD_send(1,6,voltage,6);
LCD_send(2,6,end,6);
key();
nowEnd();
}
}
|