C51与ADS1112的I2C程序如下,请问,为什么总程序运行时,总死在write_ads1110(unsigned char outdat)函数

C51与ADS1112的I2C程序如下,请问,为什么总程序运行时,总死在write_ads1110(unsigned char outdat)函数,第1张

void write_ads1110(unsigned char outdat)

{

start_iic()

send_byte(0x90) // ED0 0x90 ED2 0x94

while(iic_ack(1)) //等待应答 你这里 相当于是while(1) 当然成岁轮了死循环

send_byte(outdat)

while(iic_ack(1)) //等待应答

stop_iic()

}

你的iic_ack(i)函数返回的值是一个固定液茄值。这里逻辑不对闹雀察,检查一下吧。

集成运放性能参数测试仪 一、集成运放性能参数测试仪性能指标 工作电压:±15V

VIO:测量范围:

0~40mV(<小于3%读数±1个字);

IIO:测量范围:

0~4μA(<3%读数±1个字);

AVD:测量范围:

60dB~120dB±3dB;

KCMR:测量范围:

60dB~120dB±3dB;

输出频率:5Hz

输出电压有效值:4 V

频率与电压值误差绝对值均小于1%; 二、设计思路: 本设计以单片机

STC89C52为控制核心,利用数模转换器ADS1110

以及继电器,为切换开关, 对被测量信号进行采样,通过单片机处

理完成对运算放大器LM741的UIO,IIO,AVC,KCMR等参数的测量。 并

通过系统显示接口,利用液晶显示装置将测试的结果进行显示,同时

本系统还能通过键盘进行人机交流,实现按下一个按键就可以对该运

放的某个参数进行测试。 三、系统结构图 四、方案比较与选择: 主控芯片部分

方案一:采用STC89C52单片机。优点是芯片结构简单,使用相

对容易;缺点是不带AD转换电路,需要外接AD转换芯片,测量精度

相对较低。

方案二:采用凌阳SPCE061A单片机。优点是做肆自带AD转换模块,

测量精度相对较高,能进行音频处理等多种智能化功能;缺点是结构

复杂,使用起来相对繁琐。

由于此方案的核心内容在测试电路部分,主控芯片的选择对结果

的影响相对较小,综合以上芯片的性能以及自身的情况,选择使用相

对简单的STC89C52单片机。

信号发生器的选择 方案一:利用传统的模拟分立元件或单片压控函数发生器

MAX038,可产生三角波、方波、正弦波,通过调整外围元件可以改

变输出频率、幅度,但采用模拟器件由于元件分散性太大,即使用单

片函数发生器,参数也与外部元件有关,外接电阻电容对参数影响很

大,因而产生的频率稳定度较差、精度低、抗干扰能力差、成本也较

高。

方案二:采用ICL8038芯片产生信号。优点是电路简单,波形好,

控制方便,缺点是频率有限。

由于需要的频率不宽,综合以上考戚胡梁虑,选择电路简单,波形好,

控制方便,精度和抗干扰能力更强的ICL8038作为信号发生器。

显示模块的选择

方案一:采用液晶显示模块SVM12864(LCD)。占用I/O口多,

控制复杂,但可以显示汉字和简单高运图形等,功能强大

方案二:采用液晶显示模块1602。占用I/O口少,控制简单,每

行可显示16个字符。

虽然SVM12864功能相对强大,但是采用1602更为合理。因为需

要显示的参数不多,且都是英文字母和数字,因此选择控制简单的

1602液晶显示模块。

五、测量原理 2.1 失调电压

Vios

理想运放当输入电压为零时,其输出电压也为零,但实际运放电路当输入电压为零时,其输出端仍有一个偏离零点的直流电压Vios。这是

由于运放电路参数不对称所引起的(在室温25度 和标准电源电压下)

为了使这一输出直流电压Vios 为零,必须先在输入端加一个直流电

压作为补偿电压! 以抵消偏离零点的输出电压。这个加在输入端的电

压即为输入失调电压Vios(显然Vios越小,说明运算放大器参数的对

称性越)

2.2 失调电流Iio

运放的输入偏置电流是指运放输入级差分对管的基极电流IB1,IB2,

其中IB1指同相输入端基极电流,IB2指反相输入端基极电流运放的输

入失调电流是指当运放输出电压为零时,两个输入端静态电流的差

值,即Iio=IB1- IB2"(显然:Iio的存在将使输出端零点偏移! 信号

源阻抗越高,失调电流的影响越严重)

2.3 共模抑制比K C M R

表征运放对共模信号抑制能力的参数叫共模抑制比! 用KCMR表示。

KCMR定义为差模电压增益Avd 和共模电压增益Avc 之比,即KCMR =

Avd/Avc。运放对共模信号有很强的抑制能力。

2.4 开环放大倍数的测量

即输出电压与输入电压的比值。

六、电路设计 3.1 失调电压

VIO测量电路

输入失调电压的测量原理如图1所示:图中直流电路通过RI和RF接成闭合环路, 通常RI的取值不超过100欧

测量电路:

测量方法:

根据输入失调电压的定义得:

3.2 失调电流IIO测量电路

测量电路:

和上面一样, 则:

3.3 共模抑制比KCMR 测量电路

测试原理如图所示,由于RF>>RI,电路对差模信号的增益很大,该闭

环电路对差模信号的增益AvD= RF/RI。共模信号的增益AvC=

(VO/VS)。因此,只要从电路上测出VO 和VS,即可求出共模抑制比

KCMR = Avd/Avc

3.4 开环放大倍数的测量

测量电路如图。

实际的测量电路:由于考虑到输出处会有自激震荡产生,因此在OP177的输出口和正向

输入端加上一个电容,用以消除自激震荡的影响。

实现各个测量电路的转换,我使用继电器、通过单片机对引脚的

置位来改变开关的通断以及接通的相应电路。

S1、S2闭合,S3、S4接地时,测量失调电压;

S1、S2断开,S3、S4接地时,测量失调电流;

S1、S2闭合,S3接信号源,S4接地时,测量共模抑制比;

S1、S2闭合,S3接地,S4接信号源时,测量开环放大倍数。

以下为其他模块的电路:

1.整流转换电路:

2.单片机控制及液晶显示模块电路:

3.信号发生电路

电路总图:

画图原理图中存在的问题:

由于原理图的元件库中没有ADS1110、继电器、ICL8038等元件,因此这些元件都需要自己手动画元件,这也是画图中存在的最大问

题。要将该元件的引脚与实际元件的引脚要对应。可以说,在画原理

图的过程中没有存在很大的障碍。 六、软件仿真 仿真软件使用的是multisim2001。

在明确了软件以后,就着手进行各个部件的仿真。由于集成运

放性能参数测试仪的核心内容为测量电路部分,控制以及整流部分对

于电路来说只是起到一个辅助和提高测量准确度的作用,因此,仿真

内容的重点也在于此。本次仿真只针对测量电路进行,验证测量电路

方案的准确与否。下面就对四部分测量电路进行仿真。仿真内容中的

被测量集成运算放大器为LM741,将测量结果与LM741元件的提供参

数作对比,即可以对比测量的参数与元件所给的参数是否相同或接

近,从而确定测量电路是否正确,以及电路测试参数的准确性。下面

开始仿真。

1.输入失调电压的仿真:

如图所示,即为输入失调电压的仿真电路以及输出量。

输出电压为VE=0.513V,Ri=100欧,Rf=51K欧

则根据输入失调电压计算公式:

(VE即为如图所示的输出电压)

输入失调电压为1.00mV 。LM741的元件手册提供的输入失调电

压的标准值为1mV,则测量结果在LM741提供的参数范围之内。可以采

用这个测量电路测量输入失调电压。

2.输入失调电流仿真:

如图所示,即为输入失调电流的仿真结果以及输出量

根据输出失调电流的测量公式

Ri=100欧,Rf=51K欧,VE2就是图中电压表所示的电压值。VE2也为测量的值,11.979V

VE1为输入失调电压测试电路中的输出值。VE1=0.513V

计算得输入失调电流Iio=44.0nA。LM741的元件手册提供的输入

失调电流的范围20nV-200nV,则测量结果44.0nA在LM741提供的参数

范围之内。可以采用这个测量电路测量输入失调电流。

3.开环电压增益的仿真。

电路如图:

根据开环放大倍数的计算公式

计算结果在误差范围内。Vs为输入信号的电压值,VE为输出的

电压值,R1=R2=30K欧,Ri=100欧,Rf=51K欧。Vs=4V,VE=6.548mV。

由于输入信号电压显示的是最大值,因此计算时必须将它转化为有效

值,则Vs=2.83V。

代入公式计算后,计算得AVD=106.88db LM741的元件手册提供的开环放大倍数的范围50db-200db,则测

量结果106.88db在LM741提供的参数范围之内。可以采用这个测量电

路测量开环放大倍数。

4.共模抑制比测量仿真

测量结果如图

根据共模抑制比的测量公式:

Vs有效值为2.83V,Ri=100欧,Rf=51K欧。

代入公式,计算得KCMR=93.1db

LM741的元件手册提供的共模抑制比的最小值为70db,标准值为

90db,则测量结果93.1db接近标准值,在LM741提供的参数范围之内。

可以采用这个测量电路测量开环放大倍数。

仿真过程中存在的问题:在开始时,我碰到了电阻参数不匹配的问题,一级运放的电阻原来为100K欧,但是仿真结果与指标差别很

大,因此我就将该电阻减小为51K欧,并将其他相关电阻均减小1倍,

之后得出的参数就符合指标了。由于没有考虑到输出处会有自激震荡

产生,结果造成共模抑制比的测量中存在了很大误差,在多次测试,

最后决定在OP177的输出口和正向输入端加上一个电容,消除了自激

震荡的影响,保证了输出结果的准确性。

电路仿真的心得:通过对上述四个测量电路的仿真,我得出的

结论是,这些测量电路测量出来的结果符合设计要求。可以说,此测

试仪的最核心部分测试电路完全可以采用上面所述的四个测量电路

的方案。但是,在测试过程中也存在一些小问题,通过仿真也发现了

原先测量电路中存在的不足之处,例如:由于没有考虑到输出处会有

自激震荡产生,结果造成共模抑制比的测量中存在了很大误差,最后

在OP177的输出口和正向输入端加上一个电容,消除了自激震荡的影

响,保证了输出结果的准确性。通过对电路的仿真,我得以修正和优

化原先的测量电路,使得测量电路更加完整、精确,为成功做板以及

硬件和软件的调试打下坚实的基础! 七.元件清单 下列元件为需要购买的元件清单

王凯的元件清单

中文名称 功能 英文名称 封装 数量 备注

串行模数转16位AD转ADS1110 SOT23 1 换器 化

51单片机 单片机 STC89C52R2 DIP40 1

可调三端稳

压集成电路

三端稳压 LM337 TO-220 1

可调三端稳

压集成电路

三端稳压 LM317 TO-220 1

波形发生器 波形发生

ICL8038 DIP14 1

运算放大器 放大 OP177 DIP8 1

继电器 开关 5 直流吸合

电压5V

三极管 放大 8050 TO-92B 5

按键 按键 4*3mm 5

100欧电阻 电阻 0.25W AXIAL0.4 2

510K欧电阻 电阻 0.25W AXIAL0.4 2

51K欧电阻 电阻 0.25W AXIAL0.4 2

30K欧电阻 电阻 0.25W AXIAL0.4 2

15K欧电阻 电阻 0.25W AXIAL0.4 1

82K欧电阻 电阻 0.25W AXIAL0.4 1

200K可调欧

电阻

电阻 0.25W AXIAL0.4 1

10K欧电阻 电阻 0.25W AXIAL0.4 8 10K欧可调

电阻

电阻 0.25W AXIAL0.4 1

1K欧电阻 电阻 0.25W AXIAL0.4 1

电容 无极电容 100nF RAD0.1 1

电容 无极电容 30pF RAD0.1 2

电容 无极电容 3300pF RAD0.1 1

电容 有极电容 1uF RB.2/.4 2

电容 有极电容 100uF RB.2/.4 1

电容 有极电容 0.1uF RB.2/.4 1

6MHz晶体震

荡器

晶体震荡

6MHz XTAL1 1

二极管 二极管 1N4148 DIODE0.4 2

液晶显示模

液晶显示 1602 1

插针 插针 40颗

芯片插座 插芯片 DIP40 1

三端稳压集

成块

稳压 7805 TO-220 1

三端稳压集

成块

稳压 7812 TO-220 1

三端稳压集

成块

稳压 7912 TO-220 1 精密可调电

位器

5K可调电

位器

SIP3 1

运算放大器 放大 OP07 DIP8 2

八.系统硬件设计 电路的PCB设计 测量电路模块

主要芯片为两块集成运放(其中一块为待测的运放)和四个继电器。 电源模块

主要部分是稳压器7805、7812、7912以及6个电解电容。 液晶显示和控制模块 主要部分为单片机、液晶显示1602和四个控制按键五个三极管等。 信号发生模块 主要芯片是波形发生器ICL8038,运放。 整流转换模块

主要部分是ADS1110和一块运放。 PCB总图

PCB板的设计心得:我的这块板的大小为12.5CM×12.2CM,和

其他同学的分模块制板再通过连线连接的方案相比,我的这块板要小

很多。对于元件的排列和布置,我本着“属于同一模块的元件尽量排

列在一起”的原则布置,最后再将四个模块靠近,这样不仅做到了各

模块排列清晰,一目了然,而且这样排列更能方便各模块的分开调试。

图中,左下角为液晶显示和电路控制模块,右上角为测量电路模块,

右边为整流转换模块,右下角为信号发生电路,上方为电源稳压模块。

我的PCB方案将所有元件和模块集成在一块板上,避免了各个模块间

的连线调试以及模块间协同工作的可靠性的问题,做到了实用性和美

观的统一。因为不需要考虑高频信号的干扰,所以元件间的距离间隔可以尽量调小,并且大胆使用了一定量的跳线。最后,我在板的地线

上覆铜,不仅进一步减少了干扰,而且使板更为美观,同时也为焊板

降低了一定的难度。以实际做出来的板的效果来看,总体说来,我所

画的这块PCB板的效果还是很好的,在调试过程中出现的问题也不多,

而且只要简单修改就可以正常工作,我对此很满意的。

画板过程中碰到的问题:有些元件的封装,例如ADS1110、继电

器,在封装库内并没有给出;另外还有一些元件封装在封装库内没有

合适的,例如部分电解电容,所以这些元件的封装都需要自己另外画。

元件引脚的位置、焊盘的大小必须与实际元件一致,否则会造成元件

无法安插的板上的问题,而且焊盘的大小要适当加大,在布线的过程

中,应尽量把线布粗,电源线和地线还要另外加粗。另外,为了能将

板尽量地做小,我将原理图中的四个模块紧密排列,全部集成在一块

板上。由于所有的模块都集成在一块板上,所以做出的这块板还是存

在一点的不方便,比如,一旦某个模块出现问题,要做出修改就要相

对麻烦一些,有时甚至会涉及到其他模块,在实际的电路调试中我就

尽量少地把改动涉及到其他模块。

九.系统的软件设计 1.程序设计流程图:

2.程序清单:

程序采用C语言编译,根据单片机的特性,我尽量不使用浮点数。

#include<reg51.h>

sbit K0=P2^4//定义开关K0的引脚编号

sbit K1=P2^5//定义开关K1的引脚编号

sbit K2=P2^6//定义开关K2的引脚编号

sbit K3=P2^7//定义开关K3的引脚编号

sbit SD0=P0^0//对应继电器1的输出口引脚

sbit SD1=P0^1//对应继电器2的输出口引脚

sbit SD4=P0^2//对应继电器5的输出口引脚

sbit SD2=P0^3//对应继电器3的输出口引脚 sbit SD3=P0^4//对应继电器4的输出口引脚

sbit SCL=P0^5

sbit SDA=P0^6

sbit E=P3^0

sbit RW=P3^1

sbit RS=P3^2

unsigned char code

JP[]={0xc6,0xce,0xdd,0xbc,0xde,0xdd,0xa4,0xbc,0xdd,0xc3,0xd

e,0xb8,0xda,0x21,0x00}

unsigned char code EN[]="zaku,kohaku"

unsigned char code SRSTDY[]="V_offset="

unsigned char code SRSTDL[]="I_offset="

unsigned char code KHZY[]="A_ol="

unsigned char code GMYZB[]="CCMR="

void initial(void)

void clear(void)

void display(unsigned char pos,unsigned char word)

void set(unsigned char cmd)

void delay(unsigned char t)

void k0(void)

void k1(void)

void k2(void)void k3(void)

unsigned char c

void main(void)

{

unsigned char i

P2=0xff

c=0x80

initial()

i=0

while(JP[i])

{

display(0x80+i,JP[i])

i++

}

i=0

while(EN[i])

{

display(0xc0+i,EN[i])

i++

}

while(K0&K1&K2&K3)

clear()L:if(K0&K1&K2&K3) //检测是否有按键按下

{

delay(0xff)

delay(0xff)

if(!K0)

k0()

if(!K1)

k1()

if(!K2)

k2()

if(!K3)

k3()

}

goto L

}

void initial() //液晶模块初始化

{

clear()

set(0x38)

set(0x0c)

set(0x10)

clear()}

void clear(void) //复位子程序

{

unsigned char t0

t0=0x40

P1=0x01

RS=0

RW=0

E=0

while(t0--)

delay(0xff)

E=1

}

void display(unsigned char pos, unsigned char word) //

液晶显示子程序

{

set(pos)

P1=word

RS=1

RW=0

E=0 delay(16)

E=1

}

void set(unsigned char cmd)

{

P1=cmd

RS=0

RW=0

E=0

delay(16)

E=1

}

void delay(unsigned char t) //延时子程序

{

while(t--)

}

void k0(void) //测量失调电压

{ unsigned char i

delay(0xff)

SD0=1

SD1=1 SD2=1

SD3=1

SD4=0

while(SRSTDY[i])

{

display(0x80+i,SRSTDY[i])

i++

}

{int a,b,c

c=100*a

b=c/(51000+100)

display (0xc0,b)}//在第二行显示输入失调电压

}

void k1(void) //测量失调电流

{ unsigned char i

delay(0xff)

while(SRSTDL[i])

{ display(0x80+i,SRSTDL[i])

i++

}

SD0=1

SD1=1

SD2=0

SD3=0

SD4=0

delay(0xffff)

SD0=1

SD1=1

SD2=0

SD3=0

SD4=1

{int a,b,c,d,e

d=100*a

e=100*b

c=(d-e)/(51000+100)

display (0xc0,c)}//在第二行显示输入失调电流的结果

} void k2(void)//测量开环增益

{ unsigned char i

delay(0xff)

while(KHZY[i])

{

display(0x80+i,KHZY[i])

i++

}

SD0=0

SD1=1

SD2=1

SD3=1

SD4=0

{int a,b,d,c

c=a*100

b=511*c/283

//d=20*log 10 b

display (0xc0,d)}//在第二行显示开环增益的结果

} void k3(void) //测量共模抑制比

{ unsigned char i

delay(0xff)

while(GMYZB[i])

{

display(0x80+i,GMYZB[i])

i++

}

SD0=1

SD1=0

SD2=1

SD3=1

SD4=0

{int a,b,c

c=1000*a

b=(51000+100)*c/283000

display (0xc0,b)}//在第二行显示共模抑制比 十.系统调试 根据方案要求,系统调试分三大过程,硬件调试、软件调试、软

件和硬件联调。 1. 硬件调试:

由于电路的各个模块都集成于一块板上,为方便电路中各

模块的调试,我采用焊一个模块调一个模块的方法,以达到各个

模块调节的目的。

2. 软件调试

本系统的软件系统采用C语言编写,调试也是分模块调试。

3. 软硬联调

硬件和软件分别调试成功后再用系统的程序测试,调试。

十一.设计总结 通过本次课程设计,让我深入了解了AT89S52的内部结构和运行

原理以及集成运放的性能参数指标。更让我明白了要灵活运用我们所

学的知识去发现问题、分析问题和解决问题。这次的设计从硬件设计

到软件设计以及相应的调试都花费了不少心思,也碰到了不少问题,

但都解决了,积累了宝贵的经验,现总结如下:

1. 我做板的经验少,在排列元件的时候没有注意到整洁

美观的问题,排得比较辛苦,只有多练才能做地更好。

2. 设计电路要考虑实际中的问题,比如继电器等元件的

封装都要自己做。

3. 在PCB板放置元件,要考虑元件间的干扰问题,还有布

线宽度,电源线加粗,地线覆铜,管脚和焊盘要足够

大。 4. 制板要让板的布线清晰,打洞要准,总之做板要工整。

5. 编程尽量要使用AT89S52芯片的硬件设备。

我不是神人,但我希望可以帮你解决问题,呵呵……

首先,我有个小问题,你要求算的是2+4+8+……+100,是不是2的1次方,2次方,3次方?如果是,那应该是2+4+8+16+32+64,怎么有还加100呢?或者你笔误,应该是2—100之间的偶数相加呢?

好,下面来解决你的问题:

1.用ADS1.2运行你的加法程序,要注意一点就是ADS不能直链接运行C遍出来的程序,要用汇编代码启动。下面是启动代码startup.s文件(我空间有关于这个代码的分析,你可以去看看):

IMPORT |Image$$RO$$Limit|

IMPORT |Image$$RW$$Base|

IMPORT |Image$$ZI$$Base|

IMPORT |Image$$ZI$$Limit|

IMPORT Main 声明C程序中的Main()函数

AREA Start,CODE,READONLY 声明代码段Start

ENTRY标识程序入口

CODE32声明32位ARM指令

Reset LDR SP,=0x40003F00

初始化C程序的运行环境

LDR R0,=|Image$$RO$$Limit|

LDR R1,=|Image$$RW$$Base|

LDR R3,=|Image$$ZI$$Base|

CMP R0,R1

BEQ LOOP1

LOOP0 CMP R1,R3

LDRCC R2,[R0],#4

STRCC R2,[R1],#4

BCC LOOP0

LOOP1 LDR R1,=|Image$$ZI$$Limit|

MOV R2,#0

LOOP2 CMP R3,R1

STRCC R2,[R3],#4

BCC LOOP2

B Main 跳转到C程序代判差码Main()函数

END

2. 启动代码写好后,再编写C代码,运行你的程序(按你的意思算)

#define uint8 unsigned char //这两个宏定义是ADS里面防止数据溢迹冲好出带的

#define uint32 unsigned int

#define N 100

uint32 sum

// 使用加法运算来计算2+4+8+……+N的值。

void Main(void)

{ uint32 i

sum = 0

for(i=0i<=Ni=i*2)

{ sum += i

}

while(1)

}

3. 这两个程序合在一起才是是完整的ADS实现程序,希望可以解决你的困惑。姿铅

祝你进步!


欢迎分享,转载请注明来源:内存溢出

原文地址:https://54852.com/yw/12541080.html

(0)
打赏 微信扫一扫微信扫一扫 支付宝扫一扫支付宝扫一扫
上一篇 2025-08-26
下一篇2025-08-26

发表评论

登录后才能评论

评论列表(0条)

    保存