#include<reg52.h> //包含头文件,一般情况不需要改动,头文件包含特殊功能寄存器的定义
#include <intrins.h>//包含NOP空指令函数_nop_()
#include<LCD1602.h>
#define AddWr 0x90 //写数据地址
#define AddRd 0x91 //读数据地址
sbit RST=P2^4 //时钟 加上后可以关掉DS1302芯片输出
sbit Sda=P2^0 //定义总线连接端口
sbit Scl=P2^1
sbit dula=P2^6
sbit wela=P2^7
bit ADFlag //定义AD采样标志位
unsigned char code Datatab[]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f}//7段数共阴码管段码表
data unsigned char Display[8]//定义临时存放数码管数值
/*------------------------------------------------
延时程序
------------------------------------------------*/
void mDelay(unsigned char j)
{
unsigned int i
for(j>0j--)
{
for(i=0i<125i++)
{}
}
}
/*------------------------------------------------
初始化定时器1
------------------------------------------------*/
void Init_Timer1(void)
{
TMOD |= 0x10
TH1=0xff /* Init value */
TL1=0x00
//PT1=1 /* 优先级*/
EA=1 /* interupt enable */
ET1=1/* enable timer1 interrupt */
TR1=1
}
/*------------------------------------------------
启动IIC总线
------------------------------------------------*/
void Start(void)
{
Sda=1
_nop_()
Scl=1
_nop_()
Sda=0
_nop_()
Scl=0
}
/*------------------------------------------------
停止IIC总线
------------------------------------------------*/
void Stop(void)
{
Sda=0
_nop_()
Scl=1
_nop_()
Sda=1
_nop_()
Scl=0
}
/*------------------------------------------------
应答IIC总线
------------------------------------------------*/
void Ack(void)
{
Sda=0
_nop_()
Scl=1
_nop_()
Scl=0
_nop_()
}
/*------------------------------------------------
非应答IIC总线
------------------------------------------------*/
void NoAck(void)
{
Sda=1
_nop_()
Scl=1
_nop_()
Scl=0
_nop_()
}
/*------------------------------------------------
发送一个字节
------------------------------------------------*/
void Send(unsigned char Data)
{
unsigned char BitCounter=8
unsigned char temp
do
{
temp=Data
Scl=0
_nop_()
if((temp&0x80)==0x80)
Sda=1
else
Sda=0
Scl=1
temp=Data<<1
Data=temp
BitCounter--
}
while(BitCounter)
Scl=0
}
/*------------------------------------------------
读入一个字节并返回
------------------------------------------------*/
unsigned char Read(void)
{
unsigned char temp=0
unsigned char temp1=0
unsigned char BitCounter=8
Sda=1
do
{
Scl=0
_nop_()
Scl=1
_nop_()
if(Sda)
temp=temp|0x01
else
temp=temp&0xfe
if(BitCounter-1)
{
temp1=temp<<1
temp=temp1
}
BitCounter--
}
while(BitCounter)
return(temp)
}
/*------------------------------------------------
写入DA数模转换值
------------------------------------------------*/
void DAC(unsigned char Data)
{
Start()
Send(AddWr)//写入芯片地址
Ack()
Send(0x40) //写入控制位,使能DAC输出
Ack()
Send(Data) //写数据
Ack()
Stop()
}
/*------------------------------------------------
读取AD模数转换的值,有返回值
------------------------------------------------*/
unsigned char ReadADC(unsigned char Chl)
{
unsigned char Data
Start() //写入芯片地址
Send(AddWr)
Ack()
Send(0x40|Chl)//写入选择的通道,本程序只用单端输入,差分部分需要自行添加
//Chl的值分别为0、1、2、3,分别代表1-4通道
Ack()
Start()
Send(AddRd) //读入地址
Ack()
Data=Read() //读数据
Scl=0
NoAck()
Stop()
return Data //返回值
}
void cmg(void)//数码管锁存函数 关时钟DS1302
{
dula=1
P0=0x00
dula=0
wela=1
P0=0x00
wela=0
RST=0 // 关时钟DS1302
}
/*------------------------------------------------
主程序
------------------------------------------------*/
void main()
{
unsigned char num //DA数模输出变量
unsigned char ADtemp //定义中间变量
InitLcd()
mDelay(20)
Init_Timer1()
cmg() //数码管锁存
while(1)
{
DAC(num) //DA输出,可以用LED模拟电压变化
num++ //累加,到256后溢出变为0,往复循环。显示在LED上亮度逐渐变化
mDelay(20)//延时用于清晰看出变化
if(ADFlag) //定时采集输入模拟量
{
ADFlag=0
ADtemp=ReadADC(0)
TempData[0]=(ReadADC(0))/50//处理0通道电压显示
TempData[1]=((ReadADC(0))%50)/10
ADtemp=ReadADC(1)
TempData[2]=(ReadADC(1))/50//处理1通道电压显示 此通道暂时屏蔽,可以自行添加
TempData[3]=((ReadADC(1))%50)/10
ADtemp=ReadADC(2)
TempData[4]=(ReadADC(2))/50//处理1通道电压显示 此通道暂时屏蔽,可以自行添加
TempData[5]=((ReadADC(2))%50)/10
ADtemp=ReadADC(3)
TempData[6]=(ReadADC(3))/50//处理1通道电压显示 此通道暂时屏蔽,可以自行添加
TempData[7]=((ReadADC(4))%50)/10
disp()
}
}
}
/*------------------------------------------------
定时器中断程序
------------------------------------------------*/
void Timer1_isr(void) interrupt 3 using 1//定时器1执行数码管动态扫描
{
static unsigned int j
TH1=0xfb //重新赋值
TL1=0x00
j++
if(j==200)
{j=0ADFlag=1} //定时置位AD采样标志位
// P0=Display[count]//用于动态扫描数码管
// P2=count
// count++
// if(count==8) //表示扫描8个数码管
// count=0
}
你可以吧AD1674输出的12位数据转换成两个8位数据,就像你写的这个程序一样,应该是可以的。计算机接收到的数据不是很直观了,如果你使用的是串口调试助手,只能这样了,如果你会上位机程序,那就在上位机程序中处理一下就OK拉;另外,不知你用的单片机晶振是多少,一般51/52是12M/或11.0592M,这样的话,你设置的波特率为12000,你使用串口调试助手看数据时,要将串口调试助手的波特率设置为12000.1. 概述A/D、D/A转换器是过程及仪器仪表、设备等检测与控制装置中应用比较广泛的器件。随着大规模集成电路技术的发展,各种高精度、低功耗、可编程、低成本的A/D转换器不断推出,使得微机控制系统的电路更加简洁,可靠性更高。
TLC2543与外围电路的连线简单,三个控制输入端为CS(片选)、输入/输出时钟(I/O CLOCK)以及串行数据输入端(DATA INPUT)。片内的14通道多路器可以选择11个输入中的任何一个或3个内部自测试电压中的一个,采样-保持是自动的,转换结束,EOC输出变高。
TLC2543的主要特性如下:
●11个模拟输入通道
●66ksps的采样速率
●最大转换时间为10μs
●SPI串行接口
●线性度误差最大为±1LSB
●低供电电流(1mA典型值)
●掉电模式电流为4μA。
2. TLC2543引脚功能与接口时序
2.1 TLC2543引脚排列
TLC2543的引脚排列如图1所示。引脚功能说明如下:
AIN0~AIN10:模拟输入端,由内部多路器选择。对4.1MHz的I/O CLOCK,驱动源阻抗必须小于或等于50Ω
CS:片选端,CS由高到低变化将复位内部计数器,并控制和使能DATA OUT、DATA INPUT和I/O CLOCK。CS由低到高的变化将在一个设置时间内禁止DATA INPUT和I/O CLOCK
DATA INPUT:串行数据输入端,串行数据以MSB为前导并在I/O CLOCK的前4个上升沿移入4位地址,用来选择下一个要转换的模拟输入信号或测试电压,之后I/O CLOCK将余下的几位依次输入
DATA OUT:A/D转换结果三态输出端,在CS为高时,该引脚处于高阻状态当CS为低时,该引脚由前一次转换结果的MSB值置成相应的逻辑电平EOC:转换结束端。在最后的I/O CLOCK下降沿之后,EOC由高电平变为低电平并保持到转换完成及数据准备传输
VCC、GND:电源正端、地
REF+、REF-:正、负基准电压端。通常REF+接VCC,REF-接GND。最大输入电压范围取决于两端电压差
I/O CLOCK:时钟输入/输出端。
2.2 TLC2543的工作时序
TLC2543每次转换和数据传送使用16个时钟周期,且在每次传送周期之间插入CS的时序。时序如图2所示。
从时序图可以看出,在TLC2543的CS变低时开始转换和传送过程,I/O CLOCK的前8个上升沿将8个输入数据位键入输入数据寄存器,同时它将前一次转换的数据的其余11位移出DATA OUT端,在I/O CLOCK下降沿时数据变化。当CS为高时, I/O CLOCK和DATA INPUT被禁止,DATA OUT为高阻态。
3. TLC2543与80C31的连接
3.1 硬件接口
由于MCS-51系列单片机不具有SPI或相同能力的接口,为了便于与TLC2543接口,采用软件合成SPI *** 作,为减少数据传送速受微处理器的时钟频率的影响,尽可能选用较高时钟频率。接口电路如图3所示。
TLC2543的I/O时钟、数据输入、片选信号由P1.0、P1.1、P1.3提供,转换结果由P1.2口串行读出。
3.2 接口程序
设通道/方式控制字存放在R4中,程序在读出前一次转换结果的同时,将该通道/方式控制字发送到TLC2543中去,转换结果存放在相邻地址的存储器中。存储器地址从30H~45H,且高字节在前,低字节在后。
ORG 100H
START: MOV SP,#50H 堆栈指针初始化
MOV P1,#04H P1口引脚初始化
CLR P1.0
SETB P1.3
ACALL TLC2543
ACALL STORE
JMP START
TLC2543:MOV A,R4
CLR P1.3
JB ACC.1,LSB 如果A的位1为1,先做低字节
MSB: MOV R5,#08
LOOP1: MOV C,P1.2 数据位读入进位位RLC A
MOV P1.1,C 输出方式/通道位
SETB P1.0 产生I/O时钟
CLR P1.0
DJNZ R5,LOOP1 输入/输出另一位
MOV R2,A 高字节送入R2
MOV A,R4
JB ACC.1,RETURN
LSB: MOV R5,#08
LOOP2:MOV C, P1.2
RLC A
MOV P1.1,C
SETB P1.0
CLR P1.0
DJNZ R5,LOOP2
MOV R3,A
MOV A,R4
JB ACC.1,MSB
RETURN:RET
STORE:MOV A,R4
ANL A,#0F0H
SWAP A
MOV B,#02
MUL AB
ADD A,#030H
MOV R1,A
MOV A,R2
MOV @R1,A
INC R1
MOV A,R3
MOV @R1,A
RET
END
以上程序用累加器和带进位的左循环移位的指令来合成SPI功能,读入转换结果的第一个字节的第一位到进位(C)位。累加器内容通过进位位左移,通道选择和方式数据的第一位通过P1.1输出。然后由P1.0先高后低的翻转来提供串行时钟。这个时序再重复7次,完成转换数据的第一个字节的传送。第二个字节由重复8次时钟脉冲和数据传送的整个序列来传送。
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)