
关于这个问题,我觉得是你的单片机和AD芯片引脚电平不兼容引起的,AD芯片的高低门槛电压不同造成的,TLC2543输出0的电平高于AVR单片机判为0的电平,所以单片机读的数据始终为1,所以老是输出5V,我也遇到过同样的问题,但是现在解决了
你是程序的问题,单片机上电复位和按键复位,其程序的入口地址好像是不一样的,
这个我不大清楚了。
我建议是你把你的AD初始化程序和AD的转化程序都放到一起,
比如:你第一次采集电压,你先初始化AD,然后再采集电压。
下一次采集电压,也是要先初始化AD,然后在采集。
既然你的上电复位,能够正确的采集电压,可以说明你程序的时序,基本没有问题。可能是你的结构有问题。
这只是个保险的办法。
想要做好,就必须要完全弄懂AD的时序。看芯片的数据手册。
我这里有一个类似的程序:
#include<reg52h> //包含头文件,一般情况不需要改动,头文件包含特殊功能寄存器的定义
#include <intrinsh> //包含NOP空指令函数_nop_();
#include<LCD1602h>
#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>0;j--)
{
for(i=0;i<125;i++)
{;}
}
}
/------------------------------------------------
初始化定时器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=0;ADFlag=1;} //定时置位AD采样标志位
// P0=Display[count];//用于动态扫描数码管
// P2=count;
// count++;
// if(count==8) //表示扫描8个数码管
// count=0;
}
以上就是关于(急)(高分)求助呀!!AVR与TLC2543通讯问题全部的内容,包括:(急)(高分)求助呀!!AVR与TLC2543通讯问题、有关单片机AD转换的问题、求一个stc89C52单片机与TLC2543连接然后在LCD1602上显示的C语言程序,输入的模拟信号为0~5V电压,谢谢等相关内容解答,如果想了解更多相关内容,可以关注我们,你们的支持是我们更新的动力!
欢迎分享,转载请注明来源:内存溢出
微信扫一扫
支付宝扫一扫
评论列表(0条)