|
1.可控电源设计液晶屏能正常显示功能实现
2.正确显示电压值、 DA能准确输出对应电压
3.能连续可调节0-12V的电压并正常显示
#include"reg52.h" //包含头文件
//宏定义
#define uchar unsigned char
#define uint unsigned int
//按键定义
sbit KEY1=P2^0;
sbit KEY2=P2^1;
sbit KEY3=P2^2;
sbit KEY4=P2^3;
//液晶控制引脚定义
sbit RS=P2^5;
sbit RW=P2^6;
sbit EN=P2^7;
//DAC定义
sbit CS_5615=P1^5; //定义选片信号IO口
sbit CLK_5615=P1^6; //定义时钟信号IO口
sbit DAT_5615=P1^7; //定义数据输入IO口
//ADC定义
sbit CS=P3^5; //定义选片信号IO口
sbit CLK=P3^3; //定义时钟信号IO口
sbit DIO=P3^4; //定义数据输入IO口
//报警指示灯定义
sbit led=P3^1;
uint U;
uchar GETU=0;
bit flag=0;
uint a=0;
unsigned char Int,Dec; //分别储存转换后的整数部分与小数部分
uchar code tab1[]={"Welcome to use "}; //固定字符
uchar code tab2[]={"adj power supply"}; //固定字符
uchar code tab3[]={"Voltage: . v"}; //固定字符
uchar code tab4[]={" "}; //固定字符
uchar code tab5[]={"Short circuit!!!"}; //固定字符
uchar code tab6[]={"Please restart!!"}; //固定字符
//延时函数
void delay(uint xms) //延时函数,有参函数
{
uint x,y;
for(x=xms;x>0;x--)
for(y=121;y>0;y--);
}
//液晶写入指令函数
void write_1602com(uchar com)
{
RS=0; //数据/指令选择置为指令
RW=0; //读写选择置为写
P0=com; //送入数据
delay(1);
EN=1; //拉高使能端,为制造有效的下降沿做准备
delay(1);
EN=0; //en由高变低,产生下降沿,液品执行命令
}
//液晶写入数据函数
void write_1602dat(uchar dat)
{
RS=1; //数据/指令选择置为数据
RW=0; //读写选择置为写
P0=dat; //送入数据
delay(1);
EN=1; //en置高电平,为制造下降沿做准备
delay(1);
EN=0; //en由高变低,产生下降沿,液晶执行命令
}
//液晶初始化函数
void lcd_init()
{
uchar p;
write_1602com(0x38); //设置液晶工作模式,意思: 16*2行显示,5*7点阵,8位数据
write_1602com(0x0c); //开显示不显示光标
write_1602com(0x06); //整屏不移动,光标自动右移
write_1602com(0x01); //清显示
write_1602com(0x80); //日历显示固定符号从第一行第1个位置之后开始显示
for(p=0;p<16;p++)
{
write_1602dat(tab1[p]); //向液晶屏写日历显示的固定符号部分
}
write_1602com(0xc0); //时间显示固定符号写入位置,从第2个位置后开始显示
for(p=0;p<16;p++)
{
write_1602dat(tab2[p]); //写显示时间固定符号,两个冒号
}
delay(1000);
write_1602com(0x80); //日历显示固定符号从第一行第1个位置之后开始显示
for(p=0;p<16;p++)
{
write_1602dat(tab3[p]); //向液晶屏写日历显示的固定符号部分
}
write_1602com(0xc0); //时间显示固定符号写入位置,从第2个位置后开始显示
for(p=0;p<16;p++)
{
write_1602dat(tab4[p]); //写显示时间固定符号,两个冒号
}
}
//液晶显示函数
void shuma(uint buf)
{
uchar a,b,c,d,p;
a=buf/1000; //十位
b=buf%1000/100; //个位
c=buf%100/10; //小数点后一位
d=buf%10; //小数点后两位
if(flag==0)
{
write_1602com(0x80+11);
write_1602dat(a+0x30);
write_1602dat(b+0x30);
write_1602dat('.');
write_1602dat(c+0x30);
}
if(flag==1) //短路提示
{
write_1602com(0x80); //时间显示固定符号写入位置,从第二个位置后开始显示
for(p=0;p<16;p++)
{
write_1602dat(tab5[p]); //写入时间固定符号,两个冒号
}
write_1602com(0xc0); //时间显示固定符号写入位置,从第二个位置后开始显示
for(p=0;p<16;p++)
{
write_1602dat(tab6[p]); //写入时间固定符号,两个冒号
}
}
}
//DAC5615驱动函数
void tlc_5615(uint buf) //DA输出
{
uint a,c; //定义变量
c=buf; //要输出的数据赋值
CS_5615=0; //引脚拉低
for(a=16;a>0;a--) //循环16次
{
DAT_5615=c>>15; //把数据串行口输入da芯片
c=c<<1; //将数据左移一位,下次循环时就是传输第二位数据了
CLK_5615=1; //拉高
CLK_5615=0; //拉低
}
CLK_5615=1;
CLK_5615=0;
CLK_5615=1;
CLK_5615=0;
CS_5615=1;
}
//ADC驱动函数
unsigned int A_D()
{
unsigned char i, dat;
CS=1; //一个转换周期开始
CLK=0; //为第一个脉冲作准备
CS=0; //CS置0,片选有效
DIO=1; //DI0置1,规定的起始信号
CLK=1; //第一个脉冲
CLK=0; //第一个脉冲的下降沿,此前DIO必须是高电平
DIO=1; //DI0置1,通道选择信号
CLK=1; //第二个脉冲,第2、3个脉冲下沉之前,DI必须跟别输入两位数据用于选择通道,这里选择通道1
CLK=0; //第二个脉冲下降沿
DIO=0; //DI置0,选择通道0
CLK=1; //第三个脉冲
CLK=0; //第三个脉冲下降沿
DIO=1; //第三个脉冲下沉之后,输入端DIO失去作用,应置1
CLK=1; //第四个脉冲
for(i=0;i<8;i++) //高位在前
{
CLK=1; //第四个咏冲
CLK=0;
dat<<=1; //将下面储存的低位数据向右移
dat|=(unsigned char)DIO; //将输出数据DIO通过或运算储存在dat最低位
}
CS=1; //片选无效
return dat; //将读出的数据返回
}
//主函数
void main(void)
{
U=0; //电压值显示0
lcd_init();
while(1) //进入循环
{
tlc_5615(U); //输出电压值
shuma(U/8*10); //显示电压值
if(flag==0) //没有短路
{
if(KEY1==0) //按键1按下
{
shuma(U/8*10);
shuma(U/8*10);
shuma(U/8*10);
shuma(U/8*10);
shuma(U/8*10);//此处调用显示函数就是延时去抖的作用
if(KEY1==0) //再次判断按键1按下
{
if(U<960) //1V 对应的是80 10位ad
U=U+8; //电压加0.1V
}
}
if(KEY2==0) //按键2按下
{
shuma(U/8*10);
shuma(U/8*10);
shuma(U/8*10);
shuma(U/8*10);
shuma(U/8*10);
if(KEY2==0)
{
if(U>=8) //电压减
U=U-8;
}
}
if(KEY3==0) //按键3按下
{
shuma(U/8*10);
shuma(U/8*10);
shuma(U/8*10);
shuma(U/8*10);
shuma(U/8*10);
if(KEY3==0)
{
U=528; //输出6.6V电压
}
}
if(KEY4==0) //按键4按下
{
shuma(U/8*10);
shuma(U/8*10);
shuma(U/8*10);
shuma(U/8*10);
if(KEY4==0)
{
U=0; //关闭输出
}
}
}
GETU=A_D(); //读取ad数据
if(GETU>=12) //0.0196V,采样电阻采集到的电压数据
{
U=0; //关闭输出
led=0;
a=0;
flag=1; //短路标志位
}
}
}
|
|