一,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