yuan2020
所在地区:
全国
首页
服务/硬件产品
行业解决方案
案例
方案概述:
该设计是基于51单片机的ADC0832数字电压表设计,可以直接应用于多种单片机。硬件构成包括单片机、最小系统、四位一体共阳数码管、ADC0832模数转换芯片和电位器调节模块。该设计提供了C语言单片机源程序、PROTEUS仿真文件和元件清单。源程序实现了温度和距离的测量,并通过LCD1602显示出来。适用于工业领域的各种应用场景。
基于51单片机的ADC0832数字电压表设计源程序及仿真
本设计是基于51单片机的ADC0832数字电压表设计,可以直接应用于多种单片机,如STC89C51、STC89C52、AT89S51、AT89S52、AT89C51、AT89C52等。硬件构成包括单片机、最小系统、四位一体共阳数码管、ADC0832模数转换芯片和电位器调节模块。ADC0832芯片用于模数转换,其量程为0-5V,分辨率为0.08V。
本设计提供了C语言单片机源程序(编程环境Keil4)、PROTEUS7.8及以上版本的仿真文件和元件清单。
以下是单片机源程序清单:
```c
#include
#include
#include
#include
#define uchar unsigned char
#define uint unsigned int
#define skiprom(); wr_byte1820(0xcc); //跳过ROM操作
#define rdrom(); wr_byte1820(0x33); //读ROM
#define convert(); wr_byte1820(0x44); //启动温度转换
#define wrscart(); wr_byte1820(0x4e); //写高速缓存
#define rdscart(); wr_byte1820(0xbe); //读高速缓存
#define copyscrat(); wr_byte1820(0x48); //将高速缓存复制到EERAM
#define callscart(); wr_byte1820(0xb8); //从EERASM复制到缓存
sbit DQ = P3^3; //18b20IO口
sbit rs1602 = P2^0; //H选数据L选命令/状态
sbit rw1602 = P2^1; //H读操作L写操作
sbit e1602 = P2^2; //1602使能
sbit BEEP = P2^7;
sbit Trig = P1^7;
sbit Echo = P1^5;
volatile uchar th, tl, tth, ttl;
volatile uchar temp[5];
volatile uchar distance[3];
volatile uchar tint, tdec, count = 0;
unsigned char table[] = {0x00, 0x10, 0x06, 0x09, 0x08, 0x08, 0x09, 0x06}; //摄氏度温标
uchar code str1[] = "welcome!";
uchar code str2[] = "distance=";
uchar code str3[] = "now temp=";
uchar code str4[] = "senser error!";
uchar code str5[] = "check it out!";
uchar code str6[] = "cm";
uint h;
uchar flag;
//**************温度小数部分用查表法***********
uchar code ditab[16] = {0x30, 0x31, 0x31, 0x32, 0x33, 0x33, 0x34, 0x34, 0x35, 0x36, 0x36, 0x37, 0x38, 0x38, 0x39, 0x39};
uchar data temp_data[2] = {0x00, 0x00}; //读出温度暂放
// /***********11微秒延时函数**********/
// void delay(uint t) {
// for(;t0;t--);
// }
// void delay_us(unsigned int i) //延时:i=12 ,i的最小延时单12 us
// {
// i=i/10;
// while(--i);
// }
void delay_ms(unsigned int n) //延时n ms
{
n=n+1;
while(--n) delay_us(900); //延时 1ms,同时进行补偿
}
/***********18B20复位函数**********/
bit reset1820(void) //复位函数说明 取消while 可正常返回存在信号
{
bit flag;
DQ=1;_nop_();_nop_(); DQ = 0; // delay(50); // 550us
DQ = 1; // delay(6); // 66us
flag=DQ;
delay(45); //延时500us
DQ=1;
return(flag);
}
// /**********18B20写命令函数*********/
//向 1-WIRE 总线上写一个字节
void write_byte(uchar val)
{
uchar i;
for (i=8; i0; i--)
{
DQ=1;_nop_();_nop_(); DQ = 0;_nop_();_nop_();_nop_();_nop_();_nop_();//5us
DQ = val&0x01; //最低位移出
delay(6); //66us
val=val>>1; //右移一位
}
DQ = 1;
delay(1);
}
/*********18B20读1个字节函数********/
//从总线上读取一个字节
uchar read_byte(void)
{
uchar i;
uchar value = 0;
for (i=8;i0;i--)
{
DQ=1;_nop_();_nop_(); value=1;
DQ = 0; // _nop_();_nop_();_nop_();_nop_(); //4us
DQ = 1;_nop_();_nop_();_nop_();_nop_(); //4us
if(DQ)value|=0x80;
delay(6); //66us
}
DQ=1;
return(value);
}
/***********读出温度函数**********/
void read_temp()
{
reset1820(); //总线复位
write_byte(0xCC); // 发Skip ROM命令
write_byte(0xbe); // 发读命令
temp_data[0]=read_byte(); //温度低8位
temp_data[1]=read_byte(); //温度高8位
reset1820();
write_byte(0xCC); // Skip ROM
write_byte(0x44); // 发转换命令
}
/*********LCD子程序********/
bit lcd1602_test()//测试LCM是否就绪 0=Y 1=N
{
uchar status;
P0=0xff;//P0输入方式
rs1602=0;//选状态口
rw1602=1;//读操作
e1602=1;//1602使能
_nop_();
status=P0;//读状态字
_nop_();//禁用
e1602=0;//返回状态
return status&0x80;
}
void lcd1602_wr_cmd(uchar cmd,bit test)//写命令到1602
{
if(test) while(lcd1602_test());//等待就绪信号
rs1602=0;//选命令
rw1602=0;//写操作
P0=cmd;//输出命令
e1602=1;//使能脉冲
_nop_();
e1602=0;
}
void lcd1602_wr_dat(uchar dat)//向当前RAM写数据
{
while(lcd1602_test());//等待就绪信号
rs1602=1;//选数据口
rw1602=0;//写操作
P0=dat;//输出代码
e1602=1;
_nop_();
e1602=0;
}
void lcd1602_xy(uchar x,uchar y)//定位显示数据
{
uchar ramaddr=y*0x40+x;
lcd1602_wr_cmd(ramaddr|0x80,1);
}
void lcd1602_clr(bit len)//清除单行
{
uchar i;
lcd1602_wr_cmd(len? 0xc0:0xe0,1);
for(i=0;i16;i++) lcd1602_wr_dat(32);
}
void lcd1602_wr_srt1(uchar *ptr,uchar n)//当前位置写入字符串
{
uchar i;
for(i=0;in;i++) lcd1602_wr_dat(*ptr++);
}
void lcd1602_wr_str2(uchar *ptr,uchar x,uchar y)//指定位置写入字符串,自动换行
{
char i=0;
while(ptr[i]!=0)
{
lcd1602_xy(x++,y);
lcd1602_wr_dat(ptr[i++]);
if(x31) x=y=0;
else if(x15)
{
x=0;
y=1;
}
}
}
void init1602()//初始化1602
{
delay_ms(200);//复位延时
e1602=1;
lcd1602_wr_cmd(0x38,0);//初始化:16*2显示
delay_ms(5);
lcd1602_wr_cmd(0x38,0);
delay_ms(5);
lcd1602_wr_cmd(0x38,0);
lcd1602_wr_cmd(0x08,1);//关显示,光标不闪烁,不显示
lcd1602_wr_cmd(0x01,1);//清除RAM
lcd1602_wr_cmd(0x06,1);//光标移动模式
lcd1602_wr_cmd(0x0c,1);//开显示
}
void temp2disp()//温度转换为显示码
{
uchar tint2;
tint=temp_data[1];
tint=0xf0;
if(tint==0xf0)//判断温度正负
{
if(temp_data[0]==0)
{
temp_data[0]=~temp_data[0]+1;
temp_data[1]=~temp_data[1]+1;
}
else
{
temp_data[0]=~temp_data[0]+1;
temp_data[1]=~temp_data[1];
}
}
tint=temp_data[1]4;//取低四位
tint2=temp_data[0]4;//取高四位
tint=tint|tint2;//合成整数温度值
tth=tint;
temp[0]=tint/100+0x30;//百位
temp[1]=tint/10%10+0x30;//十位
temp[2]=tint%10+0x30;//个位
temp[3]=0x2e;//小数点
if(temp[0]==0x30) temp[0]=0x20;//百位为0显示空格
tdec=temp_data[0]0x0f;
ttl=tdec;
temp[4]=ditab[tdec];//十分位
}
void display()
{
lcd1602_xy(9,0);//显示定位
lcd1602_wr_srt1(distance,3);//设定值
lcd1602_wr_srt1(str6,2);//温度符号
lcd1602_xy(9,1);//显示定位
lcd1602_wr_srt1(temp,5);//当前值
lcd1602_wr_dat(0x00); //温度符号
}
/**************主函数****************/
main()
{
unsigned char i,j,k,tmp;
unsigned int dis,long;
tmp=0x40;
init1602();//初始化1602
for(i=0;i8;i++)//写入 摄氏度符号
{
lcd1602_wr_cmd(tmp+i,1);
lcd1602_wr_dat(table[i]);
}
reset1820();//初始化18b20
while(reset1820()==1)//存在性检测
{
lcd1602_wr_cmd(0x01,1);//写命令 清屏
lcd1602_xy(0,0);//显示定位
lcd1602_wr_srt1(str4,13);//错误信息1
lcd1602_xy(0,1);//显示定位
lcd1602_wr_srt1(str5,13);//错误信息2
delay_ms(2000);//延时2秒
reset1820();//重新初始化
}
lcd1602_wr_cmd(0x01,1);
lcd1602_xy(0,0);
lcd1602_wr_srt1(str1,8);//显示欢迎画面
delay_ms(1000);
lcd1602_xy(0,0);//显示定位
lcd1602_wr_srt1(str2,9);//set temp=
lcd1602_xy(0,1);//显示定位
lcd1602_wr_srt1(str3,9);//now temp=
reset1820();
write_byte(0xcc);
write_byte(0x4e);
write_byte(0x02);
write_byte(0x01);
write_byte(0x7f);
reset1820(); // 开机先转换一次
write_byte(0xCC); // Skip ROM
write_byte(0x44); // 发转换命令
while(1)
{
read_temp(); //读出18B20温度数据
for(k=0,k10;k++)
{
Trig=1;//——↓
for(j=0;j10;j++);//这 三句就是高脉冲,延时20US。
Trig=0;//——↑
while(!Echo);//以下就是统计高电平时间
TR0=1;
while(Echo);
TR0=0;
dis=(th08)tl0;
long=dis/59;
distance[0]=long/100+0x30;//百位
distance[1]=long/10%10+0x30;//十位
distance[2]=long%10+0x30;
temp2disp(); //温度转换
display(); //显示输出
delay_ms(100);
}
}
}
```
以上是基于51单片机的ADC0832数字电压表设计的源程序。该程序可以实现温度和距离的测量,并通过LCD1602显示出来。通过该设计,可以方便地获取温度和距离信息,适用于工业领域的各种应用场景。
本设计是基于51单片机的ADC0832数字电压表设计,可以直接应用于多种单片机,如STC89C51、STC89C52、AT89S51、AT89S52、AT89C51、AT89C52等。硬件构成包括单片机、最小系统、四位一体共阳数码管、ADC0832模数转换芯片和电位器调节模块。ADC0832芯片用于模数转换,其量程为0-5V,分辨率为0.08V。
本设计提供了C语言单片机源程序(编程环境Keil4)、PROTEUS7.8及以上版本的仿真文件和元件清单。
以下是单片机源程序清单:
```c
#include
#include
#include
#include
#define uchar unsigned char
#define uint unsigned int
#define skiprom(); wr_byte1820(0xcc); //跳过ROM操作
#define rdrom(); wr_byte1820(0x33); //读ROM
#define convert(); wr_byte1820(0x44); //启动温度转换
#define wrscart(); wr_byte1820(0x4e); //写高速缓存
#define rdscart(); wr_byte1820(0xbe); //读高速缓存
#define copyscrat(); wr_byte1820(0x48); //将高速缓存复制到EERAM
#define callscart(); wr_byte1820(0xb8); //从EERASM复制到缓存
sbit DQ = P3^3; //18b20IO口
sbit rs1602 = P2^0; //H选数据L选命令/状态
sbit rw1602 = P2^1; //H读操作L写操作
sbit e1602 = P2^2; //1602使能
sbit BEEP = P2^7;
sbit Trig = P1^7;
sbit Echo = P1^5;
volatile uchar th, tl, tth, ttl;
volatile uchar temp[5];
volatile uchar distance[3];
volatile uchar tint, tdec, count = 0;
unsigned char table[] = {0x00, 0x10, 0x06, 0x09, 0x08, 0x08, 0x09, 0x06}; //摄氏度温标
uchar code str1[] = "welcome!";
uchar code str2[] = "distance=";
uchar code str3[] = "now temp=";
uchar code str4[] = "senser error!";
uchar code str5[] = "check it out!";
uchar code str6[] = "cm";
uint h;
uchar flag;
//**************温度小数部分用查表法***********
uchar code ditab[16] = {0x30, 0x31, 0x31, 0x32, 0x33, 0x33, 0x34, 0x34, 0x35, 0x36, 0x36, 0x37, 0x38, 0x38, 0x39, 0x39};
uchar data temp_data[2] = {0x00, 0x00}; //读出温度暂放
// /***********11微秒延时函数**********/
// void delay(uint t) {
// for(;t0;t--);
// }
// void delay_us(unsigned int i) //延时:i=12 ,i的最小延时单12 us
// {
// i=i/10;
// while(--i);
// }
void delay_ms(unsigned int n) //延时n ms
{
n=n+1;
while(--n) delay_us(900); //延时 1ms,同时进行补偿
}
/***********18B20复位函数**********/
bit reset1820(void) //复位函数说明 取消while 可正常返回存在信号
{
bit flag;
DQ=1;_nop_();_nop_(); DQ = 0; // delay(50); // 550us
DQ = 1; // delay(6); // 66us
flag=DQ;
delay(45); //延时500us
DQ=1;
return(flag);
}
// /**********18B20写命令函数*********/
//向 1-WIRE 总线上写一个字节
void write_byte(uchar val)
{
uchar i;
for (i=8; i0; i--)
{
DQ=1;_nop_();_nop_(); DQ = 0;_nop_();_nop_();_nop_();_nop_();_nop_();//5us
DQ = val&0x01; //最低位移出
delay(6); //66us
val=val>>1; //右移一位
}
DQ = 1;
delay(1);
}
/*********18B20读1个字节函数********/
//从总线上读取一个字节
uchar read_byte(void)
{
uchar i;
uchar value = 0;
for (i=8;i0;i--)
{
DQ=1;_nop_();_nop_(); value=1;
DQ = 0; // _nop_();_nop_();_nop_();_nop_(); //4us
DQ = 1;_nop_();_nop_();_nop_();_nop_(); //4us
if(DQ)value|=0x80;
delay(6); //66us
}
DQ=1;
return(value);
}
/***********读出温度函数**********/
void read_temp()
{
reset1820(); //总线复位
write_byte(0xCC); // 发Skip ROM命令
write_byte(0xbe); // 发读命令
temp_data[0]=read_byte(); //温度低8位
temp_data[1]=read_byte(); //温度高8位
reset1820();
write_byte(0xCC); // Skip ROM
write_byte(0x44); // 发转换命令
}
/*********LCD子程序********/
bit lcd1602_test()//测试LCM是否就绪 0=Y 1=N
{
uchar status;
P0=0xff;//P0输入方式
rs1602=0;//选状态口
rw1602=1;//读操作
e1602=1;//1602使能
_nop_();
status=P0;//读状态字
_nop_();//禁用
e1602=0;//返回状态
return status&0x80;
}
void lcd1602_wr_cmd(uchar cmd,bit test)//写命令到1602
{
if(test) while(lcd1602_test());//等待就绪信号
rs1602=0;//选命令
rw1602=0;//写操作
P0=cmd;//输出命令
e1602=1;//使能脉冲
_nop_();
e1602=0;
}
void lcd1602_wr_dat(uchar dat)//向当前RAM写数据
{
while(lcd1602_test());//等待就绪信号
rs1602=1;//选数据口
rw1602=0;//写操作
P0=dat;//输出代码
e1602=1;
_nop_();
e1602=0;
}
void lcd1602_xy(uchar x,uchar y)//定位显示数据
{
uchar ramaddr=y*0x40+x;
lcd1602_wr_cmd(ramaddr|0x80,1);
}
void lcd1602_clr(bit len)//清除单行
{
uchar i;
lcd1602_wr_cmd(len? 0xc0:0xe0,1);
for(i=0;i16;i++) lcd1602_wr_dat(32);
}
void lcd1602_wr_srt1(uchar *ptr,uchar n)//当前位置写入字符串
{
uchar i;
for(i=0;in;i++) lcd1602_wr_dat(*ptr++);
}
void lcd1602_wr_str2(uchar *ptr,uchar x,uchar y)//指定位置写入字符串,自动换行
{
char i=0;
while(ptr[i]!=0)
{
lcd1602_xy(x++,y);
lcd1602_wr_dat(ptr[i++]);
if(x31) x=y=0;
else if(x15)
{
x=0;
y=1;
}
}
}
void init1602()//初始化1602
{
delay_ms(200);//复位延时
e1602=1;
lcd1602_wr_cmd(0x38,0);//初始化:16*2显示
delay_ms(5);
lcd1602_wr_cmd(0x38,0);
delay_ms(5);
lcd1602_wr_cmd(0x38,0);
lcd1602_wr_cmd(0x08,1);//关显示,光标不闪烁,不显示
lcd1602_wr_cmd(0x01,1);//清除RAM
lcd1602_wr_cmd(0x06,1);//光标移动模式
lcd1602_wr_cmd(0x0c,1);//开显示
}
void temp2disp()//温度转换为显示码
{
uchar tint2;
tint=temp_data[1];
tint=0xf0;
if(tint==0xf0)//判断温度正负
{
if(temp_data[0]==0)
{
temp_data[0]=~temp_data[0]+1;
temp_data[1]=~temp_data[1]+1;
}
else
{
temp_data[0]=~temp_data[0]+1;
temp_data[1]=~temp_data[1];
}
}
tint=temp_data[1]4;//取低四位
tint2=temp_data[0]4;//取高四位
tint=tint|tint2;//合成整数温度值
tth=tint;
temp[0]=tint/100+0x30;//百位
temp[1]=tint/10%10+0x30;//十位
temp[2]=tint%10+0x30;//个位
temp[3]=0x2e;//小数点
if(temp[0]==0x30) temp[0]=0x20;//百位为0显示空格
tdec=temp_data[0]0x0f;
ttl=tdec;
temp[4]=ditab[tdec];//十分位
}
void display()
{
lcd1602_xy(9,0);//显示定位
lcd1602_wr_srt1(distance,3);//设定值
lcd1602_wr_srt1(str6,2);//温度符号
lcd1602_xy(9,1);//显示定位
lcd1602_wr_srt1(temp,5);//当前值
lcd1602_wr_dat(0x00); //温度符号
}
/**************主函数****************/
main()
{
unsigned char i,j,k,tmp;
unsigned int dis,long;
tmp=0x40;
init1602();//初始化1602
for(i=0;i8;i++)//写入 摄氏度符号
{
lcd1602_wr_cmd(tmp+i,1);
lcd1602_wr_dat(table[i]);
}
reset1820();//初始化18b20
while(reset1820()==1)//存在性检测
{
lcd1602_wr_cmd(0x01,1);//写命令 清屏
lcd1602_xy(0,0);//显示定位
lcd1602_wr_srt1(str4,13);//错误信息1
lcd1602_xy(0,1);//显示定位
lcd1602_wr_srt1(str5,13);//错误信息2
delay_ms(2000);//延时2秒
reset1820();//重新初始化
}
lcd1602_wr_cmd(0x01,1);
lcd1602_xy(0,0);
lcd1602_wr_srt1(str1,8);//显示欢迎画面
delay_ms(1000);
lcd1602_xy(0,0);//显示定位
lcd1602_wr_srt1(str2,9);//set temp=
lcd1602_xy(0,1);//显示定位
lcd1602_wr_srt1(str3,9);//now temp=
reset1820();
write_byte(0xcc);
write_byte(0x4e);
write_byte(0x02);
write_byte(0x01);
write_byte(0x7f);
reset1820(); // 开机先转换一次
write_byte(0xCC); // Skip ROM
write_byte(0x44); // 发转换命令
while(1)
{
read_temp(); //读出18B20温度数据
for(k=0,k10;k++)
{
Trig=1;//——↓
for(j=0;j10;j++);//这 三句就是高脉冲,延时20US。
Trig=0;//——↑
while(!Echo);//以下就是统计高电平时间
TR0=1;
while(Echo);
TR0=0;
dis=(th08)tl0;
long=dis/59;
distance[0]=long/100+0x30;//百位
distance[1]=long/10%10+0x30;//十位
distance[2]=long%10+0x30;
temp2disp(); //温度转换
display(); //显示输出
delay_ms(100);
}
}
}
```
以上是基于51单片机的ADC0832数字电压表设计的源程序。该程序可以实现温度和距离的测量,并通过LCD1602显示出来。通过该设计,可以方便地获取温度和距离信息,适用于工业领域的各种应用场景。
为您推荐其他供应商的行业解决方案
免责声明:本网站部分内容来源互联网,如权利人发现存在侵权信息,请及时与本站联系删除。
供应商:
yuan2020
所在区域: 全国
yuan2020是一家专注于单片机初学入门的公司。我们致力于收集、整理单片机初学入门的常用程序和电路,为初学者提供帮助。我们提供的程序和电路都是经过验证的,能够帮助初学者少走弯路,节约时间。
我们擅长的领域包括51单片机、单片机仿真、超声波测距原理图、超声波测距源程序、温度传感器18b20、多功能时钟、电压表测量电路、计算器程序、超声波倒车、汇编语言、电路图及BOM、点阵显示屏、霍尔传感器、霍尔测速、PWM控制电机、转速调节、手机app控制、蓝牙、密码锁仿真、秒表倒计时仿真电路、秒表倒计时源程序、ds18b20温度采集电路、程序实例、温度报警器、DS1820、电路设计方案、电路设计、温度传感器等。
我们提供的解决方案包括基于51单片机铂电阻PT100温度计程序设计与仿真、51单片机一体化超声波设计倒车雷达、51单片机超声波测距仿真倒车雷达系统设计、51单片机6位数码管显示DS1302时钟带DS18B20温度仿真及C语言程序、基于51单片机的ADC0832数字电压表设计1602显示源程序及仿真、基于51单片机的简易计算器设计、51单片机超声波测距仿真设计HC-SR04模块倒车雷达C语言源程序等。
我们的目标是为初学者提供高质量的单片机学习资源,帮助他们快速入门,掌握相关技能。如果您对单片机初学入门有需求,欢迎联系我们,我们将竭诚为您提供帮助。