使用ADC0832实现数码管/LCD显示:Proteus仿真实验
目录
前言:
模数A/D转换理论知识持续学习:2022–7–24
ADC0832时序图:
ADC0832模数转换
ADC0832模数转换模拟时序代码如下:
//函数名:ADC0832_ReadAD
//形参变量:无
//返回值return:AD_value:转化之后的数字量#include"reg52.h"
#include"Delay.h"sbit ADC0832_CS=P2^4;//片选信号段
sbit ADC0832_CLK=P2^5;//时钟信号端
sbit ADC0832_DIN=P2^6;//串行数据输入端
sbit ADC0832_DOUT=P2^7;//串行数据输出端void ADC0832_init(void)
{
ADC0832_CS=1;//芯片不工作
ADC0832_CLK=0;
ADC0832_DIN=0;
}unsigned char ADC0832_ReadAD(void)
{
unsigned char i,AD_value1=0x00,AD_value2=0x00;
ADC0832_CS=0;//芯片工作(初始cs信号为高电平)
ADC0832_DIN=1;//起始信号S
ADC0832_CLK=1;//上升沿将起始信号Start写入
ADC0832_CLK=0;
//—————-通道地址设置—-0通道(单端模式)—————//
ADC0832_DIN=1;//mode状态位置1
ADC0832_CLK=1;//将mode状态位写入
ADC0832_CLK=0;
ADC0832_DIN=0;//通道选择0通道
ADC0832_CLK=1;//将通道选择位写入
ADC0832_CLK=0;//第4个脉冲下降沿后,ADC0832_DIN端口失效,无作用
ADC0832_DIN=1;//ADC0832_DIN转为改高阻状态(数据线拉高,等待下次接收数据)
//———————读取相对应的通道0的AD数据————————–//
ADC0832_DOUT=1;//数据线拉高,等待接收数据
for(i=0;i<8;i++)//MSB
{
ADC0832_CLK=1;
ADC0832_CLK=0;
if(ADC0832_DOUT){AD_value1=AD_value1 |(0x80>>i);}//优先读取最高位 MSB
}
for(i=0;i<8;i++)//LSB
{
if(ADC0832_DOUT){AD_value2=AD_value2 |(0x01<<i);}//优先读取最低位 LSB
ADC0832_CLK=1;
ADC0832_CLK=0;
}ADC0832_DOUT=1;//数据线拉高,等待接收数据
ADC0832_CS=1;//芯片停止工作
return (AD_value1==AD_value2)? AD_value1:0;//判断前后两次读取数据是否相同(前后两个字节数据校验)
}
数码管显示函数代码
数码管显示函数代码如下:(8段4位共阴数码管)
//函数名:7段4位数码管显示函数
//形参变量:wei:位数 num:对应位显示的数值
//返回值return:无#include"reg52.h"
#include"Delay.h"#define SMG_DUAN_PORT P3//段选
#define SMG_WEI_POER P1//位选unsigned char code smg_code[]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f};//无小数点—–0-9字形码
unsigned char code smgd_code[]={0xbf,0x86,0xdb,0xcf,0xe6,0xed,0xfd,0x87,0xff,0xef};//有小数点—–0-9字形码void smg_display(unsigned char wei,num)//共阴极数码管
{
unsigned char i;
for(i=0;i<4;i++)
{
switch(wei)//位选
{
case 1:SMG_WEI_POER=0xfe;break;
case 2:SMG_WEI_POER=0xfd;break;
case 3:SMG_WEI_POER=0xfb;break;
case 4:SMG_WEI_POER=0xf7;break;
}
if(wei==2)
SMG_DUAN_PORT=smgd_code[num];
else
SMG_DUAN_PORT=smg_code[num];
delay_ms(1);//延时,增加其亮度
SMG_DUAN_PORT=0x00;//消隐
}
}
LCD1602显示函数
LCD1602显示函数代码如下:
#include "reg52.h"
#include "Delay.h"#define u8 unsigned char
#define u16 unsigned int
#define LCD_DATA_PORT P0sbit LCD_WR=P2^1;//读写控制端
sbit LCD_RS=P2^0;//数据指令端
sbit LCD_EN=P2^2;//有效使能端void lcd_write_cmd(u8 cmd)//写指令函数
{
LCD_RS=0;
LCD_WR=0;
LCD_DATA_PORT=cmd;
LCD_EN=0;
delay_ms(1);
LCD_EN=1;
delay_ms(1);
LCD_EN=0;
}void lcd_write_data(u8 Data)//写数据函数,将数据写入DDRAM中
{
LCD_RS=1;
LCD_WR=0;
LCD_DATA_PORT=Data;
LCD_EN=0;
delay_ms(1);
LCD_EN=1;
delay_ms(1);
LCD_EN=0;
}void lcd_init(void)//初始化函数
{
lcd_write_cmd(0x38);//功能设定指令
lcd_write_cmd(0x0c);//显示开关控制指令
lcd_write_cmd(0x06);//模式设定指令
lcd_write_cmd(0x01);//清屏指令
}void lcd_clear(void)//清屏函数
{
lcd_write_cmd(0x01);//清屏指令
}void setcursor(u8 line,u8 column)//光标定位函数,确定DDRAM中的坐标
{
if(line==1)
lcd_write_cmd(0x80+column-1);
else
lcd_write_cmd(0x80+0x40+column-1);
}//函数名:单个字符显示函数
//形参变量:line:行 column:列
//返回值return:无
void lcd_showchar(u8 line,u8 column,u8 Char)
{
setcursor(line,column);
lcd_write_data(Char);
}
//函数名:字符串显示函数
//形参变量:line:行(1-2) column:列(1-40 *string:字符串
//返回值return:无
void lcd_showstring(u8 line,u8 column,u8 *string)
{
setcursor(line,column);//光标定位
while(*string!='\0')
{
lcd_write_data(*string);
string++;
}
}
//函数名:单个无符号数字显示函数
//形参变量:line:行(1-2) column:列(1-40) num:0-9(取值范围)
//返回值return:无
void lcd_show_onenum(u8 line,u8 column,u8 num)
{
setcursor(line,column);//光标定位
lcd_write_data(num+0x30);
}
//函数名:多个无符号数字显示函数
//形参变量:line:行 column:列 nums:数值 length:数值长度
//返回值return:无
u16 num_pow(u8 x,u8 y)//次方函数:x:底数 y:幂(次数)
{
u16 result=1;
while(y–)
{
result*=x;
}
return result;
}
void lcd_shownums(u8 line,u8 column,u16 nums,u8 length)
{
u8 i;
setcursor(line,column);//光标定位
for(i=length;i>0;i–)
{
lcd_write_data(nums/num_pow(10,i-1)%10+0x30);
}
}//函数名:多个有符号数字显示函数
//形参变量:line:行 column:列 nums:数值取值范围:-32768-32767 length:数值长度
//返回值return:无void lcd_showsignednums(u8 line,u8 column,int nums,u8 length)
{
u8 i;
u16 number1;
setcursor(line,column);//光标定位
if(nums<=0)
{
lcd_write_data('-');
number1=-nums;
}
else
{
lcd_write_data('+');
number1=nums;
}
for(i=length;i>0;i–)
{
lcd_write_data(number1/num_pow(10,i-1)%10+0x30);
}
}//函数名:十六进制数字显示函数
//形参变量:line:行 column:列 nums:数值 length:数值长度
//返回值return:无void lcd_showhexnums(u8 line,u8 column,u16 nums,u8 length)
{
u8 i,number;
setcursor(line,column);//光标定位
for(i=length;i>0;i–)
{
number=nums/num_pow(16,i-1)%16;
if(number<10)//转化为十进制数判断
lcd_write_data(number+'0');
else
lcd_write_data(number+'A'-10);//'A':0x40H
}
}//函数名:二进制数字显示函数
//形参变量:line:行 column:列 nums:数值 length:二进制数值长度,例如,0xfe:1111 1110(8位)
//返回值return:无void lcd_showbinnums(u8 line,u8 column,u16 nums,u8 length)
{
u8 i,number;
setcursor(line,column);//光标定位
for(i=length;i>0;i–)
{
number=nums/num_pow(2,i-1)%2;
if(number<10)//转化为十进制数判断
lcd_write_data(number+'0');
else
lcd_write_data(number+'A'-10);//'A':0x40H
}
}
主函数
主函数代码如下:
/*********************************************
功能说明:利用模数AD转化,将电位器的阻值和电位显示在LCD1602和数码管上
*********************************************/
#include"reg52.h"
#include"LCD1602_display.h"
#include"ADC0832.h"
#include"Delay.h"
#include"7SEG_MPX4.h"
#define u8 unsigned char
#define u16 unsigned int
float Resister;//电阻
float Voltage;//电阻分压
u16 Voltage_show;
void main()
{
lcd_init();//LCD1602初始化
ADC0832_init();//ADC0832初始化
lcd_showstring(1,1,"Voltage:");
lcd_showstring(2,1,"Resister:");
while(1)
{
Resister=ADC0832_ReadAD()*1000.0/255;//传递A/D转换后的数字量
Voltage=(Resister*5/1000);
Voltage_show=Voltage*100;
lcd_shownums(1,10,Voltage_show,3);
lcd_shownums(2,10,Resister,4);
smg_display(2,Voltage_show/100%10);
smg_display(3,Voltage_show/10%10);
smg_display(4,Voltage_show/1%10);
}
}
proteus仿真图
proteus仿真图如下: