/*************簡易數控電壓表**************************
程序功能:輸出可調0~5伏電壓,步進值為0.1V
涉及芯片:1602液晶、TLC5615、TLC549、AT89S52單片機
******************************************************/
#include<reg52.h>
#define uint unsigned int
#define uchar unsigned char
uchar code num[]={0x30,0x31,0x32,0x33,0x34,0x35,0x36,0x37,0x38,0x39};
/*uchar code dianya[]={21,41,65,84,104,125,145,166,186,206,227,247,267,
288,308,330,350,370,392,412,432,452,472,494,514,
534,556,576,596,616,636,658,678,698,720,740,760,
780,802,822,842,862,884,904,924,944,964}; */
sbit key1=P1^0;
sbit key2=P1^1;
sbit key3=P1^2;
sbit key4=P1^3;
sbit din=P3^0;
sbit scl=P3^1;
sbit cs1=P3^2;
sbit clock=P3^3;//時鐘線
sbit dout=P3^4;//數據輸出端
sbit cs=P3^5;//片選(低電平有效)
sbit rs=P2^0;//數據/命令選擇端(H/L)
sbit rw=P2^1;//讀/寫選擇端(H/L)
sbit en=P2^2; //使能選擇端
uchar bdata date; //位尋址
sbit date7=date^7;
sbit date6=date^6;
sbit date5=date^5;
sbit date4=date^4;
sbit date3=date^3;
sbit date2=date^2;
sbit date1=date^1;
sbit date0=date^0;
/****************函數聲明**********************/
void delay(uint time);
void write_com(uchar mingling);
void write_date(uchar shuju);
void chushihua();
void delayus(uint t)
{
while(t--);
}
void write_sip5615(uchar k)
{
date=k;
din=date7;
scl=0;
scl=1;
din=date6;
scl=0;
scl=1;
din=date5;
scl=0;
scl=1;
din=date4;
scl=0;
scl=1;
din=date3;
scl=0;
scl=1;
din=date2;
scl=0;
scl=1;
din=date1;
scl=0;
scl=1;
din=date0;
scl=0;
scl=1;
}
void write_5615(uint k)
{
k<<=2;
cs1=0;
write_sip5615(k>>8);
write_sip5615(k);
cs1=1;
}
uchar read_549()//數據得采集
{
uint i;
uchar k=0x00;//定義一個變量k,將在dout上采集的到的數據裝進K
dout=1;//該地方置不置高電平都可以,應為單片機的I/O口默認值為高點平
for(i=0;i<8;i++)
{
if(dout)
{
k|=(0x80)>>i;
}
clock=1;//高電平期間采集dout線上的數據
clock=0;
delayus(10);
}
return k;//返回值
}
uchar shuchu_549()//數據得讀取
{
uchar date;
cs=0;//片選低電平時數據有效
date=read_549();//將read_549()函數中采集到的數據付給變量date
cs=1;//片選拉高,表示數據讀取完畢
delayus(50);
return date;//返回值
}
void main()
{
uint i=0,n=0,m=0;
uchar k0,k1,k2,k3,k4,temp;
uchar t1,t2,t3,t4;
chushihua();
write_5615(0);
write_com(0x80+0x00);
write_date('O');
write_com(0x80+0x01);
write_date('X');
write_com(0x80+0x03);
write_date('N');
write_com(0x80+0x04);
write_date('u');
write_com(0x80+0x05);
write_date('m');
write_com(0x80+0x06);
write_date(':');
write_com(0x80+0x40);
write_date('D');
write_com(0x80+0x41);
write_date('i');
write_com(0x80+0x42);
write_date('a');
write_com(0x80+0x43);
write_date('n');
write_com(0x80+0x45);
write_date('Y');
write_com(0x80+0x46);
write_date('a');
write_com(0x80+0x47);
write_date(':');
write_com(0x80+0x4a);
write_date('.');
write_com(0x80+0x4f);
write_date('V');
while(1)
{
if(key1==0)
{
n++;
if(n==50)n=0;
while(!key1);
}
if(key2==0)
{
n--;
if(n==0)n=50;
while(!key2);
}
write_5615(20*n);
delayus(30);
k0=shuchu_549();
temp=k0;
k1=k0/100;
k2=k0%100;
k3=k2/10;
k4=k2%10;
t1=(uint)(temp*0.0186);
t2=(uint)(temp*0.186)%10;
t3=(uint)(temp*1.86)%10;
t4=(uint)(temp*18.6)%10;
write_com(0x80+0x08);//代碼
write_date(num[k1]);
write_com(0x80+0x09);
write_date(num[k3]);
write_com(0x80+0x0a);
write_date(num[k4]);
write_com(0x80+0x49);//電壓
write_date(num[t1]);
write_com(0x80+0x4b);
write_date(num[t2]);
write_com(0x80+0x4c);
write_date(num[t3]);
write_com(0x80+0x4d);
write_date(num[t4]);
}
}
/*void delay(uint time)//延時函數(運行的時間與晶振有關系)
{
uint i,j;
for(i=time;i>0;i--)
for(j=110;j>0;j--);
} */
void write_com(uchar mingling)//命令輸入函數
{
uchar gao,di; //定義高、低四位
gao=mingling&0xf0;//分出高四位
di=(mingling<<4)&0xf0;//分出低四位
//==========================================讀走高四位
P2=gao;//讓數據(mingling)高四位有效
rs=0;//rs端為低電平時,為接收命令
delayus(8);
en=1; //en一個高脈沖讀走高四位數據(mingling)
delayus(10);
en=0;//把使能端拉回低電平
//============================================讀走低四位
delayus(8);
P2=di;//讓數據(mingling)低四位有效
rs=0;//rs端為低電平時,為接收命令
delayus(8);
en=1 ;//en一個高電平讀走低四位命令(mingling)
delayus(10);
en=0;//把使能端拉回低電平
}
void write_date(uchar shuju)//數據輸入函數
{
uchar gao,di;
gao=shuju&0xf0;//分出高四位
di=(shuju<<4)&0xf0;//分出低四位
//=======================================讀走高四位
P2=gao;//讓數據(shuju)高四位有效
rs=1;//rs端為高電平時,為接收數據
delayus(8);
en=1;//en一個高電平讀走低四位數據 (shuju)
delayus(10);
en=0;//把使能端拉回低電平
//============================================讀走低四位
delayus(8);
P2=di;//讓數據(shuju)低四位有效
rs=1;//rs端為高電平時,為接收數據
delayus(8);
en=1;//en一個高電平讀走低四位數據(shuju)
delayus(10);
en=0;//把使能端拉回低電平
}
void chushihua()
{
rw=0;//把數據/命令選擇端先置為零
en=0;//把使能端先置為零
write_com(0x28);//設置16*12顯示,5*7點陣,4位數據接口
write_com(0x01);//清屏
write_com(0x0c);//顯示開啟,不顯示光標
write_com(0x06);//整屏不移動
}