1、Ltc1684芯片介绍
该芯片是一款高精度的16位模数转换器(ADC),适合于高精度仪器的开发,它能提供精准的模拟信号到数字信号的转换。
特性
采用 MSOP 封装的 16 位、250ksps ADC
单 5V 电源
低电源电流:850μA (典型值) 自动停机功能可把电源电流减小至 2μA (在 1ksps)
真正的差分输入
单通道 (LTC1864) 或双通道 (LTC1865) 版本
SPI/MICROWIRE™ 兼容型串行 I/O
特点
-
16位分辨率:这是AD转换器的关键参数之一,意味着它可以将模拟信号分成2^16,即65536个不同的数字级别,从而提供非常细腻的信号分辨率。
- 精度:高精度意味着转换器输出的数字值与实际输入信号非常接近,误差很小。这对于那些对精确度要求非常高的应用场景(例如医疗设备、实验室仪器和精密测量设备)来说至关重要。
- 适用性:LTC1684适合高精度仪器的开发,表明它的设计兼顾了性能和使用的便捷性,使其能够在广泛的工业和科研领域中应用。
- 性能指标:除了分辨率和精度,LTC1684还可能具有高速采样、低功耗、低噪声等特性,这些都能进一步提高转换性能,对于高精度仪器来说尤其重要。
引脚图
引脚名称 | 中文释义 |
---|---|
VREF (Pin 1) | 参考输入。参考输入定义了A/D转换器的范围,必须相对于GND保持无噪声。 |
IN+, IN- (Pins 2, 3) | 模拟输入。这些输入必须相对于GND保持无噪声。 |
GND (Pin 4) | 模拟地。GND应直接连接到模拟地平面。 |
CONV (Pin 5) | 转换输入。在此输入上逻辑高电平启动A/D转换过程。如果CONV输入在A/D转换完成后保持高电平,部件将保持高电平。 |
SDO (Pin 6) | 数字数据输出。A/D转换结果从此引脚移出。 |
SCK (Pin 7) | 移位时钟输入。此时钟同步串行数据传输。 |
Vcc (Pin 8) | 正电源。此电源必须保持无噪声和纹波,通过直接绕过到模拟地平面来实现。 |
关键参数
重点关注INL(增益误差,Integral Non-Linearity)的数据。因为是仿真不是实测,所以很难评价。
时序图
2、仿真电路
按照图示接线,电压在数码管上显示为x.xxxx
3、软件代码
main.c
//***************************************************************************/
//* 文件名:min_sys_887.c
//* 文件描述:用于单个模块的驱动测试仿真
//* 创建人:bianjingyuan 2024年11月4日
//* 编译环境: Windows XP + MPLAB IDE 8.83 + Picc 9.60
//* 硬件信息:PIC16f887(20MHZ),max7219(8位数码管)
//* 修改记录:无
//***************************************************************************/
// 原始硬件资源分配表:
// pic16f887工作频率 20MHZ 外部晶体振荡
//***************************************************************************/
// max7219的引脚定义如下:
// din RE0 //RE0-RE2为887引脚输出
// clk_1 RE2=1
// clk_0 RE2=0
// load_1 RE1=1
// load_0 RE1=0
//***************************************************************************/
#include "pic.h" //包含单片机内部资源预定义
//#include "max1241-Io.h"
//#include "Adc0808.h"
#include "PIC16F887_Delay.h"
// 数据类型定义
#define uchar unsigned char
#define uint unsigned int
#define ulong unsigned long
#define nop asm("NOP")
#define sleep asm("sleep")
/*------max7219主要引脚-------*/
//RE0-RE2为887引脚输出
#define din RE0
#define load_1 RE1=1
#define load_0 RE1=0
#define clk_1 RE2=1
#define clk_0 RE2=0
// ****************************887芯片配置位*************************************/
__CONFIG (0x20F2); // 20MHZ外部晶振
//#define XTAL_FREQ 20 // 定义主频,单位为赫兹 (MHz), 请根据实际晶振频率设置
// *************************以下声明本模块中所调用的函数类型 *****************/
//void delayus(uchar a);// 延时10us最准
//void delayms(uchar a);// 延时100ms最准
void delay1s(void);// 延时约1秒钟
void Initial_System(void);// 初始化系统参数和配置
void Set_Port_IO(void);// 设置I/O端口状态
void ad_init(void);
void send(uchar addres, uchar data);
void max7219_int(void);
void cal_hex(uint add4) ; //计算显示数值X.XXX
void cal_ltc1684_hex(uint add4); //计算显示数值X.XXXx
// *****************************定义全局变量***********************************/
uchar k,i,m; //定义循环控制变量
uchar add3,add2,add1,add0; //显示数据寄存器4位
//**************************新增模块的相关定义**********************************/
extern uchar temp_h; // 存储温度整数部分(范围从 0 到 255)
extern uchar temp_l; // 存储温度小数部分(范围从 0 到 99)
extern uint adre_1684;
extern uchar ltc1684_hex[5]; //显示数据x.xxxx
extern ulong counter; //n次A/D采样结果累加寄存器,n小于16
//**************************新增模块的函数定义**********************************/
extern void LTC1684_init_io(void);
extern void LTC1684_read_io() ;
//********************************************************************
//* 文件名:main.c
//* 文件描述:单片机主程序,负责系统初始化和电压监测
//* 编译环境: Windows XP + MPLAB IDE 8.83 + Picc 9.60
//* 编程者: bianjingyuan
//* 编程日期: 2024-11-05
//* 版本号:1.0
//* 修改记录:无
//********************************************************************
void main()
{
Initial_System(); // 初始化系统设置
ad_init(); // 初始化AD转换功能
Set_Port_IO(); // 设置端口IO方向
max7219_int(); // 初始化MAX7219显示驱动
di(); // 禁用全局中断
TRISC0 = 1; // 设置RC0为输入
LTC1684_init_io(); // 初始化LTC1684的IO口
send(0x01, XTAL_FREQ / 10); // 发送ADC结果的高位
send(0x02, XTAL_FREQ % 10); // 发送ADC结果的低位
send(0x03, 15); // 发送固定值15
send(0x04, 4); // 发送固定值4
ltc1684_hex[0] = 0;
ltc1684_hex[1] = 0;
ltc1684_hex[2] = 0;
ltc1684_hex[3] = 0;
ltc1684_hex[4] = 0;
add3 = 0;
add2 = 0; // 清除显示数据
add1 = 0;
add0 = 0;
redo: // 循环标签
counter = 0; // 初始化计数器
for (k = 50; k > 0; k--) // 基准电压5.12V的采样
{
LTC1684_read_io(); // 读取LTC1684转换结果
counter = counter + adre_1684; // 累加AD转换结果
}
cal_ltc1684_hex(counter >> 6); // 将ADC结果计算为十六进制格式并加小数点
send(0x04, ltc1684_hex[4] + 128); // 发送格式化后的数据
send(0x05, ltc1684_hex[3]); // 发送LTC1684的高位
send(0x06, ltc1684_hex[2]); // 发送LTC1684的次高位
send(0x07, ltc1684_hex[1]); // 发送LTC1684的次低位
send(0x08, ltc1684_hex[0]); // 发送LTC1684的低位
delayms(100); // 延时100毫秒
goto redo; // 循环返回到redo标签
}
/**************************以下为函数和子程序********************************/
void Initial_System(void)
{
OPTION = 0b01010000; // 设置定时器的时间为1us
// OSCCON = 0x71; // 内部震荡器设置为8MHz
INTCON = 0b01000000; // 使能外围模块中断
}
void Set_Port_IO(void)
{
TRISA = 0b00000000; // 设置PORTA为输出
PORTA = 0b00000000; // 初始化PORTA为低
TRISB = 0b00000000; // 设置PORTB为输出
PORTB = 0b00000000; // 初始化PORTB为低
TRISC = 0b00000000; // 设置PORTC为输出
PORTC = 0b00000000; // 初始化PORTC为低
TRISD = 0b00000000; // 设置PORTD为输出
PORTD = 0b00000000; // 初始化PORTD为低
TRISE = 0b00000000; // 设置PORTE为输出,显示驱动
PORTE = 0b00000000; // 初始化PORTE为低
}
void ad_init(void)
{
ANSEL = 0; // 清除模拟数字选择,允许数字操作
ANSELH = 0b00000000; // 清除高位选择,使用数字操作
ADCON0 = 0b10000001; // 从0通道开始,FOSC/32
// ADCON1 = 0b10110000; // 右对齐,选择正负电压基准
ADCON1 = 0b10000000; // 设置右对齐,选择单电压基准
}
void delay1s(void) // 延迟1秒
{
ulong d = 185300; // 对应20MHz的工作频率
while (--d); // 计数减少实现延迟
}
void send(uchar address, uchar data)
{
uchar i = 8;
load_0; // 准备移位
// 发送位地址
for (i = 8; i > 0; i--)
{
clk_0; // 产生时钟信号
din = (address & 0x80) ? 1 : 0; // 取高位
address <<= 1; // 地址左移
nop; nop; nop; nop; nop; // 延迟
clk_1; // 结束时钟信号
}
// 发送数据
for (i = 8; i > 0; i--)
{
clk_0; // 产生时钟信号
din = (data & 0x80) ? 1 : 0; // 取高位
data <<= 1; // 数据左移
nop; nop; nop; nop; nop; // 延迟
clk_1; // 结束时钟信号
}
nop; nop; nop; nop; nop; // 额外延迟
load_1; // 锁存数据
}
void max7219_int()
{
send(0x0F, 0x00); // 发送命令以设置正常操作
send(0x0C, 0x01); // 发送命令以不进入省电模式
send(0x0B, 0x07); // 发送命令以显示8个数码管
send(0x0A, 0x04); // 发送命令以设置显示强度
send(0x09, 0xFF); // 发送命令以全解码8个数码管
send(0x01, 1); // 测试数码管的完整性,发送测试数据1
send(0x02, 2);
send(0x03, 3);
send(0x04, 4);
send(0x05, 5);
send(0x06, 6);
send(0x07, 7);
send(0x08, 8);
}
void cal_hex(uint add4) // 计算并显示数值X.XXX
{
add3 = add4 / 1000; // 计算千位
add2 = (add4 % 1000) / 100; // 计算百位
add1 = (add4 % 100) / 10; // 计算十位
add0 = add4 % 10; // 计算个位
}
void cal_ltc1684_hex(uint add4) // 计算并显示数值X.XXXx
{
ltc1684_hex[4] = add4 / 10000; // 计算万位
ltc1684_hex[3] = (add4 % 10000) / 1000; // 计算千位
ltc1684_hex[2] = (add4 % 1000) / 100; // 计算百位
ltc1684_hex[1] = (add4 % 100) / 10; // 计算十位
ltc1684_hex[0] = add4 % 10; // 计算个位
}
/*****************************以下为函数和子程序****************************/
//* 名称: LTC1684_read_io
//* 说明: IO模拟SPI数据AD转换单次采样
//* 功能: 16位AD转换单次采样
//* 调用: 无
//* 输入:
//* 返回值: 无
//***************************************************************************/
void LTC1684_read_io() //LTC1684 IO模拟驱动程序
{
uchar k;
adre_1684=0; //
sclk=1; conv=0; //空闲时时钟为1,开始转换过程
nop;conv=1;delayus(2); //需要至少3.2us的延时
conv=0; //使能1684数据传输
for (k=15;k>0;k--)
{
sclk=0;
nop;nop;nop;nop;nop;nop;nop;nop;//delay2us
sclk=1; //从第一个时钟的上升沿开始输出数据
adre_1684|=dout; //delay2us
adre_1684<<=1; //高位前移
}
sclk=0;
nop;nop;nop;nop;nop;nop;nop;nop;//delay2us
sclk=1; //第16个时钟不再移位了
adre_1684|=dout; //完成16位采样数据的寄存
conv=1; //关闭1684
}
//***************************************************************************/
//* 名称: LTC1684_init_io()
//* 说明: IO模拟驱动1684的初始化
//* 功能: 单片1684的初始化
//* 调用: 无
//* 输入: 无
//* 返回值: 无
//***************************************************************************/
void LTC1684_init_io(void)
{
conv=1; //关闭1684
sclk=1; //空闲时时钟为1
}
void Model_Test(void)
{
uchar k; // 定义变量 k
counter = 0; // 初始化计数器
/*
for (k = 50; k > 0; k--) // 基准电压5.12V的采样
{
LTC1684_read_io(); // 读取LTC1684转换结果
counter = counter + adre_1684; // 累加AD转换结果
}
cal_ltc1684_hex(counter >> 6); // 将ADC结果计算为十六进制格式并加小数点
TRISC0 = 1; // 设置RC0为输入
LTC1684_init_io(); // 初始化LTC1684的IO口
ltc1684_hex[0] = 0;
ltc1684_hex[1] = 0;
ltc1684_hex[2] = 0;
ltc1684_hex[3] = 0;
ltc1684_hex[4] = 0;
send(0x04, ltc1684_hex[4] + 128); // 发送格式化后的数据
send(0x05, ltc1684_hex[3]); // 发送LTC1684的高位
send(0x06, ltc1684_hex[2]); // 发送LTC1684的次高位
send(0x07, ltc1684_hex[1]); // 发送LTC1684的次低位
send(0x08, ltc1684_hex[0]); // 发送LTC1684的低位
*/
}
4、代码解析
该代码实现了一个基于PIC16F887微控制器和LTC1684模数转换器的系统,通过MAX7219显示驱动将电压转换结果显示在八位数码管上。程序的主要功能包括:
- 初始化系统配置、I/O端口和AD转换功能。
- 通过LTC1684进行16位AD转换,采集电压信号。
- 对AD转换结果进行处理,格式化为BCD格式。
- 使用MAX7219显示驱动将处理后的数据在数码管上显示。
- 主循环不断采集数据并更新显示。
5、硬件资源分配表
序号 | 引脚名称 | 类别 | 方向 | 功能定义 | 内容 | 相关的寄存器及配置 |
---|---|---|---|---|---|---|
1 | RE0 | 数字IO | 输出 | DIN | MAX7219数据输入 | TRISE=0; PORTE=0; |
2 | RE1 | 数字IO | 输出 | LOAD | MAX7219的片选信号 | TRISE=0; PORTE=0; |
3 | RE2 | 数字IO | 输出 | CLK | MAX7219时钟信号 | TRISE=0; PORTE=0; |
4 | RC0 | 数字IO | 输入 | dout | LTC1684的数据输出 | TRISC=1; |
5 | RC1 | 数字IO | 输出 | sclk | LTC1684的时钟信号 | TRISC=0; PORTC=0; |
6 | RC2 | 数字IO | 输出 | conv | LTC1684转换控制信号 | TRISC=0; PORTC=0; |
基于上述硬件资源分配,程序实现了以下主要功能:
- 实现对LTC1684模数转换器的16位AD数据采集。
- 通过MAX7219驱动实现数据在数码管上的显示。
- 持续监测输入信号并更新显示结果,适用于需要高精度电压测量和显示的场合。
6、仿真运行结果