1 实物与模型

(1)为什么DO和DI引脚连在一个引脚上?

由于ADC0832在通信时并不是会同时使用DO和DI端口,并且DO和DI端口与单片机的接口是双向的,所以在设计电路中可以用一根线将DO端和DI端连接到一起。

(2)ADC0832的外部连接采用SPI总线结构,这样便把它的连接方式与其他设备统一起来了。ADC0832采用同步串行传输,同步是通过时钟线进行数据同步;串行传输通过DO 数据口一位一位传输数据。

2 实验原理

3 系统设计

  传统的51单片机没有配置SPI,但是可以利用其并行接口线模拟SPI串行总线时序,以实现与SPI的器件连接。

4 软件设计

1 ADC0832模数转换函数(结合ADC时序图)

#ifndef __ADC0832_H__
#define __ADC0832_H__ #include <reg52.h>
#include <intrins.h> sbit ADC0832_CS_N = P1^0;
sbit ADC0832_CLK = P1^1;
sbit ADC0832_DI = P1^2;
sbit ADC0832_DO = P1^2; void ADC0832_Init(void);
unsigned char ADC0832_Conv(void); #endif
#include "ADC0832.h"

//ADC0832初始化
void ADC0832_Init(void)
{
ADC0832_CS_N = 1;
ADC0832_CLK = 0;
ADC0832_DI = 1;
} unsigned char ADC0832_Conv(void)
{
unsigned char adc_result1 = 0; //用来接收第一组数据
unsigned char adc_result2 = 0; //用来接收第二组数据 unsigned char i; //时序1,先将CS使能端置于低电平并且保持低电平直到转换完全结束
ADC0832_CS_N = 0;
ADC0832_CLK = 0; //时序2,由MCU向ADC0832时钟输入端CLK输入时钟脉冲,DO/DI端使用DI端输入通道功能选择的数据信号 //在第1个时钟脉冲的下降沿之前DI端必须是高电平,表示启动信号
ADC0832_DI = 1; //START BIT,启动信号
_nop_();
ADC0832_CLK = 1; //第一个脉冲
_nop_();
ADC0832_CLK = 0; //在第2、3个脉冲下降沿之前DI应输入2位数据用于选择通道功能
ADC0832_DI = 1; //单通道输入
_nop_();
ADC0832_CLK = 1; //第二个脉冲
_nop_();
ADC0832_CLK = 0; ADC0832_DI = 0; //选择CH0作为模拟信号输入端
_nop_();
ADC0832_CLK = 1; //第三个脉冲
_nop_();
ADC0832_CLK = 0; /*时序3,从第4个脉冲开始由DO输出转换数据最高位,
随后每个脉冲下降沿DO输出下一位数据,
直到第11个脉冲时发出最低位数据,一个字节的数据输出完成*/ ADC0832_DI = 1; //数据线拉高,主机准备读数据,高位在前
for(i=0;i<8;i++)
{
ADC0832_CLK = 1;
_nop_();
ADC0832_CLK = 0; //CLK下降沿
adc_result1 = adc_result1 << 1; //左移,0000_0001
if(ADC0832_DO==1)
adc_result1 = adc_result1 | 0x01;
} /*时序4,随后输出8个位数,与前面数据顺序相反,
同时第11个脉冲的下降沿输出DATA0,到第19个脉冲时输出完成DATA7*/
for(i=0;i<8;i++)
{
adc_result2 = adc_result2 >> 1; //右移,1000_000
if(ADC0832_DO==1)
adc_result2 = adc_result2 | 0x80;
ADC0832_CLK = 1;
_nop_();
ADC0832_CLK = 0;
} //时序5 一次AD转换结束
ADC0832_CS_N = 1;
ADC0832_CLK = 1;
ADC0832_DI = 0; return (adc_result1 == adc_result2)? adc_result1:0;
}

2 数码管动态显示函数

#ifndef __DisplaySmg_H__
#define __DisplaySmg_H__ #include <REG52.H> #define GPIO_SEG P0 //段选端
#define GPIO_SEL P2 //位选端 extern unsigned char LedBuf[]; //外部变量声明
extern unsigned char DotDig0,DotDig1,DotDig2,DotDig3; void DisplaySmg(void); #endif
#include "DisplaySmg.h"

unsigned char code LedData[]={    //共阴型数码管的段码表,字符,序号
0x3F, //"0",0
0x06, //"1",1
0x5B, //"2",2
0x4F, //"3",3
0x66, //"4",4
0x6D, //"5",5
0x7D, //"6",6
0x07, //"7",7
0x7F, //"8",8
0x6F, //"9",9
0x77, //"A",10
0x7C, //"B",11
0x39, //"C",12
0x5E, //"D",13
0x79, //"E",14
0x71, //"F",15
0x76, //"H",16
0x38, //"L",17
0x37, //"n",18
0x3E, //"u",19
0x73, //"P",20
0x5C, //"o",21
0x40, //"-",22
0x00, //熄灭 23
};
unsigned char DotDig0=0,DotDig1=0,DotDig2=0,DotDig3=0; //小数点控制位
unsigned char code LedAddr[]={0xfe,0xfd,0xfb,0xf7}; //数码管位选
unsigned char LedBuf[]={22,22,22,22}; //显示缓存区 void DisplaySmg() //四位数码管,考虑小数点
{
unsigned char i; //等价于 "static unsigned char i = 0;"
unsigned char temp;
switch(i)
{
case 0:
{
GPIO_SEG = 0x00; //消影
if(DotDig0==1) //小数点
{
temp = LedData[LedBuf[0]] | 0x80; //点亮小数点
}
else
{
temp = LedData[LedBuf[0]];
}
GPIO_SEG = temp; //段码
GPIO_SEL = LedAddr[0]; //位选
i++;
break;
} case 1:
GPIO_SEG = 0x00;
if(DotDig1==1) //小数点
{
temp = LedData[LedBuf[1]] | 0x80;
}
else
{
temp = LedData[LedBuf[1]];
}
GPIO_SEG = temp;
GPIO_SEL = LedAddr[1];
i++;
break;
case 2:
GPIO_SEG = 0x00;
if(DotDig2==1) //小数点
{
temp = LedData[LedBuf[2]] | 0x80;
}
else
{
temp = LedData[LedBuf[2]];
}
GPIO_SEG = temp;
GPIO_SEL = LedAddr[2];
i++;
break;
case 3:
GPIO_SEG = 0x00;
if(DotDig3==1) //小数点
{
temp = LedData[LedBuf[3]] | 0x80;
}
else
{
temp = LedData[LedBuf[3]];
}
GPIO_SEG = temp;
GPIO_SEL = LedAddr[3];
i=0;
break;
default:break;
}
}

3 定时器T0

#ifndef __Timer0_H__
#define __Timer0_H__ #include <reg52.h> void Timer0_Init(void); #endif
#include "Timer0.h"

void Timer0_Init(void)        //1毫秒@11.0592MHz
{
TMOD &= 0xF0; //设置定时器模式
TMOD |= 0x01; //设置定时器模式
TL0 = 0x66; //设置定时初始值
TH0 = 0xFC; //设置定时初始值
TF0 = 0; //清除TF0标志
TR0 = 1; //定时器0开始计时 ET0 = 1; //定时器0中断开关
// EA = 1; //中断总开关
} //中断服务函数一定是一个没有返回值的函数
//中断服务函数一定是没有参数的函数
//中断服务函数函数名后跟着关键字interrupt
//interrupt n 0~4 5个中断源,8*n+0003H
// 0003H INT0, 00BH T0, 0013H INT1, 001BH T1, 0023H ES
//中断服务函数不能被主程序或者其他程序所调用
//n后面跟着using m(0~3)工作寄存器组 //void Timer0_ISR(void) interrupt 1
//{
// TL0 = 0x66; //设置定时初始值
// TH0 = 0xFC; //设置定时初始值
//}

4 主函数(对采集的数据进行均值滤波)

#include <REG52.H>
#include "DisplaySmg.h"
#include "ADC0832.h"
#include "Timer0.h" unsigned char adc_result = 0;
int adc_result_show = 0; void disp_num(void) //显示四位十进制数
{
LedBuf[0]= 23; //千位,不显示
LedBuf[1]= adc_result_show/100; //百位
LedBuf[2]= adc_result_show/10%10;//十位
LedBuf[3]= adc_result_show%10; //个位
} void main()
{
int adc_result_reg;
int adc_result_fliter; //采用均值滤波
unsigned char adc_cnt; //采样次数 Timer0_Init(); //定时/计数器T0初始化
ADC0832_Init();
EA=1; //中断总开关
DotDig1=1; //点亮第二个数码管的小数点
while(1)
{
adc_result = ADC0832_Conv(); //采集数据,ADC转换后结果
adc_result_reg = adc_result*1.0*100*5/255; //数据变换处理(线性标度变换)
adc_result_fliter = adc_result_fliter + adc_result_reg; //数据累加
adc_cnt++;
if(adc_cnt > 7)
{
adc_result_show = adc_result_fliter >> 3; //等价于除于8,取平均值
adc_cnt = 0;
adc_result_fliter = 0;
}
disp_num(); //显示数据
}
} void Timer0_ISR(void) interrupt 1
{
TR0=0; //关闭定时器
DisplaySmg(); //每过1ms,刷新一次数码管显示函数
TL0 = 0x66; //设置定时初始值,定时1ms
TH0 = 0xFC; //设置定时初始值,定时1ms
TR0=1; //打开定时器
}

5 参考来源

(1)(141条消息) 【mcuclub】模数转换ADC0832_单片机俱乐部--官方的博客-CSDN博客_adc0832模数转换原理

(2)单片机应用——利用串行A/D转换器件ADC0832实现模拟电压信号的A/D转换_哔哩哔哩_bilibili

简易数字电压表+ADC0832+串行SPI方式实现1路数据转换的更多相关文章

  1. (九)串行口方式0 拓展并行输入端口 74LS165 芯片

    74LS165芯片讲解: 外接一个同步移位寄存器 74LS165芯片,拓展一个 8 位 并行输入端口的电路, 可将接在74LS165芯片的8个开关 S0——S7 的状态 通过 串行口方式 0 读到 单 ...

  2. (九)串行口方式0 拓展并行输出端口 02 74LS164芯片

    1.先讲解74LS164 移位芯片: 74HC164.74HCT164 是 8 位边沿触发式移位寄存器,串行输入数据,然后并行输出. 数据通过两个输入端(DSA 或 DSB)之一串行输入:任一输入端可 ...

  3. FLASH 存储学习-串行SPI NOR FLASH

    1.1 SST25VF080B简介1.1.1 主要特性 关键点:容量.速度(时钟速度.读写速度).功耗. l 容量:8MBit: l 最高SPI时钟频率:50MHz: l 低功耗模式下电流消耗:5uA ...

  4. FLASH 存储学习-串行SPI nor

    1.1 SST25VF080B简介 1.1.1 主要特性 关键点:容量.速度(时钟速度.读写速度).功耗. 容量:8MBit: 最高SPI时钟频率:50MHz: 低功耗模式下电流消耗:5uA,正常读模 ...

  5. LTC2440串行SPI通讯时序

    LTC2440 简介 我们使用4-wire SPI接口 按照时序图上的描述,SDO是在SCLK的下降沿更新数据,那么FPGA接收端就应该在上升沿采集数据. 实际测试发现SDO数据相对于SCLK延迟了6 ...

  6. STM32学习笔记——SPI串行通讯(向原子哥学习)

    一.SPI  简介 SPI是 Serial Peripheral interface 的缩写,就是串行外围设备接口.SPI 接口主要应用在  EEPROM, FLASH,实时时钟,AD 转换器,还有数 ...

  7. STM32-串行SPI nor

    源:FLASH 存储学习-串行SPI nor 1.1 SST25VF080B简介1.1.1 主要特性 关键点:容量.速度(时钟速度.读写速度).功耗. l 容量:8MBit: l 最高SPI时钟频率: ...

  8. COM口,串行通讯端口,RS-232接口 基础知识

    COM口即串行通讯端口. COM口的接口标准规范和总线标准规范是RS-232,有时候也叫做RS-232口.电脑上的com口多为9针,最大速率115200bps.通常用于连接鼠标(串口)及通讯设备(如连 ...

  9. 基于51的串行通讯原理及协议详解(uart)

    串行与并行通讯方式并行:控制简单,传输速度快.线多,长距离成本较高且同时接受困难.串行:将数据字节分成一位一位的行驶在一条传输线上进行传输.如图:   同步与异步串行通讯方式同步串行通讯方式:同步通讯 ...

  10. vue使用技巧:Promise + async + await 解决组件间串行编程问题

    业务场景描述 大家都通过互联网投递过简历,比如在智联.58.猎聘等平台.投递心仪的职位前一般都需要前提创建一份简历,简历编辑界面常规的布局最上面是用户的个人基本信息,如姓名.性别.年龄.名族等,接着是 ...

随机推荐

  1. PC常见问题

    主PC有传入连接,VMware虚拟机的VPN就连不上

  2. [CSP-S 2022] 假期计划

    link \(1-A-B-C-D-1\) 非常对称,我们断开来,分成 \(1-A-B\) 和 \(C-D-1\) 两部分,不难发现这两块是完全一致的. 首先对于每个景点 \(x\) 求出距离它不过 K ...

  3. 天天用lock,不好奇他到底怎么工作的吗 —ReentrantLock 大白话

    从ReentrantLock到AQS 新手学习,若有不对,欢迎大佬 调教 ReentrantLock 我们经常用的 *ReentrantLock*是干什么的呢 我认为这是一个前台/门面(类似设计模式中 ...

  4. DXF 最简单的一个文件生成一个直线 (1)

    记得把# 注释删除 0 SECTION 2 HEADER 9 $ACADVER 1 AC1009 9 $INSBASE 10 0.000000 20 0.000000 30 0.000000 9 $E ...

  5. 合合信息:基于 JuiceFS 构建统一存储,支撑 PB 级 AI 训练

    合合信息是一家专注于智能文字识别.图像处理.自然语言处理.知识图谱与大数据挖掘的科技公司,依托自主研发的 AI 与大数据技术,已在上交所科创板上市.公司主要 C 端产品包括扫描全能王.名片全能王和启信 ...

  6. Rust中的workspace

    java项目中用maven管理代码时,如果遇到大型工程,一般会拆分成不同的模块,比如spring-mvc中,通常会按model, view, controller建3个模块,然后根据一定的依赖关系进行 ...

  7. ERROR 2003 (HY000): Can't connect to MySQL server on 'localhost' (10061) --九五小庞

    修改Mysql数据库默认密码后登陆报  ERROR 2003 (HY000): Can't connect to MySQL server on 'localhost' (10061) 注意:当修改M ...

  8. CC BY-SA 4.0 是什么?--九五小庞

    CC BY-SA 4.0 是一种许可协议,最近改版的CSDN在公开博客中推出了该协议. 该协议的赋予遵守者两项重要权利: 一.共享的权利.允许通过任何媒介和任何形式复制.发行作品.二.改编的权利.允许 ...

  9. 【🔥🔥🔥RDB还是AOF ?】Redis持久化原理全景解读与生产级决策手册

    Redis 的持久化机制是其高可用性的基石,主要包含 RDB (Redis Database) 和 AOF (Append Only File) 两种方式,它们的设计目标.实现原理和适用场景各有不同. ...

  10. 游戏技术博客推荐 Red Blob Games

    https://www.redblobgames.com/ 一名专注于游戏中算法实现的大佬