一,TLC549简介
TLC549是美国德州仪器公司生产的8位串行A/D转换器芯片,可与通用微处理器、控制器通过CLK、CS、DATAOUT三条口线进行串行接口。具有4MHz片内系统时钟和软、硬件控制电路,转换时间最长17μs,TLC549为40000次/s。总失调误差最大为±0.5LSB,典型功耗值为6mW。采用差分参考电压高阻输入,抗干扰,可按比例量程校准转换范围,VREF-接地,VREF+-VREF-≥1V,可用于较小信号的采样。
引脚定义:
- REF+:正基准信号输入端
- ANALOG IN:模拟信号输入端
- REF-:负基准电压输入端
- GND:接地端
- #CS:片选信号,低电平有效
- DATA OUT:转换结果串行输出端
- I/O CLOCK:外接时钟输入端
- VCC:电源输入端
通信协议:
TLC549均有片内系统时钟,该时钟与I/O CLOCK是独立工作的,无需特殊的速度或相位匹配。其工作时序如图2所示。当CS为高时,数据输出(DATA OUT)端处于高阻状态,此时I/O CLOCK不起作用。当CS为低时,AD前一次转换的数据A的最高位A7立马出现在数据线DATA OUT上,其余七位在I/O CLOCK的下降沿依次由时钟同步输出,,因此可在I/O CLOCK的上升沿读取数据,其中值得注意的是:1.图中他tsu(cs)至少要1.4us;2.I/O CLOCK不能超过1.1MHz。读完8位数据后,AD开始转换这一次转换的采样数据B,以便下一次读取转换时,片选信号CS置高,每次转换不超过17us,开始于CS拉低后的第八个I/O CLOCK的下降沿,没有转换完成标志,没有启动控制端,只要读取前一次数据后就马上可以开始新的AD转换,转换完成进入保持状态。
(翻译-摘自TLC549官方芯片参考手册)
二,Proteus仿真图
Proteus连线图
三,程序源代码
/*
*@brief: 51系列单片机+TLC549制作简单的电压采集系统
*@author: 逗比小憨憨
*@website: https://space.bilibili.com/314404732
*/
#include < reg52.h >
#include < intrins.h >
#define uchar unsigned char
#define uint unsigned int
sbit dout=P1^0;//数据输出端
sbit clock=P1^2;//时钟线
sbit cs=P1^1;//片选(低电平有效)
uchar TLC549_Obtain(void);
uchar TLC549_Read(void);
void Display_Data(uchar dat);
void Uart_Init(void);
void delay_xms(uint t);
void delay_xms(uint xms)
{
uint i,j;
for(i = 0; i < xms; i++)
for(j = 0; j < 115; j++);
}
void main(void)
{
uchar TLC549_Data;
Uart_Init();
while(1)
{
TLC549_Data = TLC549_Obtain();
Display_Data(TLC549_Data);
delay_xms(500);
}
}
void Uart_Init(void)
{
TMOD |= 0X20;
TL1 = 0XFD;
TH1 = 0XFD;
SCON = 0x50;
PCON = 0;
EA = 1;
PS = 1;
TR1 = 1;
}
uchar TLC549_Read(void)
{
uchar n=0, tmp;
cs = 1; //CS置高,片选无效
clock = 0;
cs = 0; //CS置低,片选有效,同时DO输出高位
_nop_();
_nop_(); //适当延迟时间1.4us Setup Time
for(n = 0; n < 8; n++) //串行数据移位输入
{
tmp < <= 1;
tmp |= dout;
clock = 1; //0.4us
_nop_(); //延迟0.1us
clock = 0; //0.4us
}
cs = 1; //CS置高,片选无效
for(n = 17; n != 0; n--)
_nop_(); //下一次转换需要延迟17us
return tmp;
}
/*
* TLC549数据获取
*/
uchar TLC549_Obtain(void)
{
uchar dat;
dat=TLC549_Read();
return dat;
}
void Display_Data(uchar dat)
{
int disdat;
uchar dis[4];
uchar i = 0;
disdat = (int)(5.0*dat / 256 * 100);
dis[0] = disdat/100+'0';
dis[1] = 0x2e;
dis[2