基于TLC1549的单片机数字电压表程序
该系统实现了0-50V直流电压的测量,测量精度为0.05V。采用10位串行A/D (TLC1549)进行模数转换,比采用常用的8位并行A/D(ADC0809等)硬件电路更为简单,测量精度更高。1602液晶显示器比数码管显示更为直观,丰富的信息。
该系统只设计了测量显示功能,由于为单片机留有丰富的I/O,所以可以方便的扩展其他功能。
(本文系51hei单片机网会员jcde225原创。由于本人菜鸟一只,不足之处还请各位大虾指点。例如显示的电压值最低位常在0,4,9之间跳动。调了很久都没解决这个问题。)
#include reg52.h> //52系列头文件
#define Disdata P1 //液晶数据端口
#define uchar unsigned char //无符号字符8位
#define uint unsigned int //无符号整数8位
uint data dis[4]={0x00,0x00,0x00,0x00};//4个数据单元和一个
uchar code table[]="VOLTAGE:+ . V"; //定义初始上电液晶默认显示状态
uchar code table1[]="designed by :";
uchar code table3[]=" Li Xiaojun";
uchar code table2[]="SCOPE: 0-50.00V";
uchar code table4[]=" not reversed! ";
sbit lcden=P3^2;//定义液晶使能端
sbit lcdrs=P3^0;//定义液晶RS端
sbit rw=P3^1;//定义液晶RW端
sbit ALE=P2^3;//定义锁存地址控制位
sbit cs_ad=P3^5;//片选段,低电平有效
sbit dout=P3^4;//数据输出端
sbit clk=P3^3; //转换结束标志位
sbit speak=P3^7;//蜂鸣器
sbit bijiao=P3^6;//接反检测信号
data int result;//测量变量暂存地址
void jiefan();//接反子函数
uchar num,num1,num2,num3,num4,num5;
uchar shii,gei;
//********延时函数************
void delay(uint z)
{
uint x,y;
for(x=z;x>0;x--)
for(y=110;y>0;y--);
}
//*************
void write_com(uchar com) //液晶写命令函数
{
lcdrs=0;
P1=com;
delay(5);
lcden=1;
delay(5);
lcden=0;
}
void write_data(uchar date) //液晶写数据函数
{
lcdrs=1;
P1=date;
delay(5);
lcden=1;
delay(5);
lcden=0;
}
void write_sg(uchar add,uchar date) //写整数位和小数位函数
{
uchar shi,ge;
shi=date/10; //分解出一个2位数的十位
ge=date%10;
write_com(0x80+add);//设置显示位置
write_data(0x30+shi);//送去液晶显示十位
write_data(0x30+ge); //送去液晶显示个位
}
void init()
{
rw=0;
lcden=0;
shii=0;
gei=0;
write_com(0x38); //初始化1602液晶
write_com(0x0c);
write_com(0x06);
write_com(0x01);
write_com(0x80); //设置显示初始坐标
for(num2=0;num213;num2++)
{
write_data(table1[num2]);
delay(5);
}
write_com(0x80+40);
for(num3;num316;num3++)
{
write_data(table3[num3]);
delay(5);
}
delay(3000);
}
//*******************************
void scan1()
{
write_com(0x80); //设置显示初始坐标
for(num=0;num16;num++)
{
write_data(table[num]);
delay(5);
}
write_sg(9,shii);
write_sg(12,gei);
write_com(0x80+40);
for(num1;num116;num1++)
{
write_data(table2[num1]);
delay(5);
}
write_sg(9,shii);
write_sg(12,gei);
}
//****TLC1549转换处理子函数********
void test()
{
data uchar i;
cs_ad=1; //禁止i/o clock
cs_ad=0; //开启控制电路,使能data out和i/o clock
result=0; //清转换变量
for(i=0;i10;i++) //采集10次 ,即10bit
{
clk=0;
result*=2;
if(dout) result++;
clk=1;
}
delay(590);
cs_ad=1; ;;;; //data out 返回到高阻状态而终止序列
//****数据转换处理**********
result=result*10;//结果值扩大10倍
dis[2]=result/205;//计算整数位
dis[3]=result%205;//余数暂存
dis[3]=dis[3]*10;//计算小数第一位
dis[1]=dis[3]/205;
dis[3]=dis[3]%205;
dis[3]=dis[3]*10; //计算小数第二位
dis[0]=dis[3]/205;
shii=dis[2];
gei=dis[1]*10+dis[0];
write_sg(9,shii);
write_sg(12,gei);
}
//*****接反子函数*********
void jiefan()
{
if(bijiao==0)
{
delay(100);
if(bijiao==0)
{
speak=0;
}
else
speak=1;
}
else
{
speak=1;
}
}
//*******主函数*****
void main()
{
init();
scan1();
while(1)
{
test();
jiefan();
}
}
- TLC1549在8051系统中的应用(02-17)
- FPGA的DSP性能揭秘(06-16)
- 基于单片机通用引脚的软件UART设计(10-16)
- 分时操作系统思想在单片机中的具体应用 (10-30)
- 基于AT89C51+DSP的双CPU伺服运动控制器的研究(05-26)
- 关于RTX51 TINY的分析与探讨(05-30)