全局变量:该变量在主函数外面定义

局部变量:在函数体内部定义

当子函数内部定义的变量,该变量的变量名和全局变量名相同并且类型相同时,在主函数调用该子函数时,该子函数的该变量有效,将全局变量屏蔽掉

D/A,数字量(Digital):例如直接从5V跳到0V;模拟量(Anolog):例如从5V缓慢变化到0V,有个变化的过程。

例子:1111 1111    对应    5v(或50mA)

1000 0000    对应    2.5v(或25mA)

0000 0000    对应    0v(或0mA)

当都接0时,从最右边的电阻依次并联算起,到最左边的2R电阻处再和右边全部的电阻(并联后也为2R)为R,所以Vref/R= I, Io2=1/2 I,Io1=0

当I7接0,其它接1时,I7处的电流为I7,I7右边的电流也为I7,所以Io2=1/2 I

当I7接1,当I6接1,先不看其它支路,Io1=(1/2 )*Vref/R+(1/2 *1/2 ) *Vref/R

以此类推,到最后全接1时Io1=Vref/R(1/2+1/2*1/2+……+1/2的八次方)

DAC0832,这里用直通方式,一种简单的方式会了其它方式照猫画虎就行

Vref为输入参考电压,这里IOUT2接地,IOUT1作为输出,当需要模拟电压时IOUT1接运算放大器并且连接Rfb(反馈电阻)

类似这样上面有横杠的表示低电平有效;上图中连线上连接与门的圆圈表示取反

CS表示片选信号,Chip Select

下载数据文档:Datasheet即数据文档网站:www.21ic.com-->左边的IC处填写”DAC0832”,“资料”-->下载Datasheet。www.alldatasheet.com

看资料芯片看串并行方式,接口说明,转换位数和转换速率,操作时序

www.maxim-ic.com,如果是并行的一次把数据都读走,但浪费I/O口

见dac0832资料,P5图,ts指不稳定的输出范围,之后稳定

选取DA时,要先知道设计的产品的运行速度,然后选取DA的转换速率,根据产品的精度选取DA的精度即位

串行MAX531的资料:DIN是数据输入端,SCLK是数据时钟,DOUT是输入电压,VDD是电源,VOUT是输出电压,REFIN是参考电压,AGND是接地

时序图中,网格表示无所谓高低电平,两个箭头包起来的数据表示有效数据,MAX531的资料P8中图Figure1:SCLK上升沿读走位(DIN)的数据,八个上升沿就读走八个位数据。

看这种资料主要看各个管脚怎么使用以及时序图

时序图中,阴影表示高低电平都可以;两个箭头包起来的数据表示有效数据,例如DIN

SCLK上升沿读走位(DIN)的数据,八个上升沿就读走八个位数据

DA资料中,看多少位,速度,管脚,时序图,有的接法不同,时序图就不同

找资料,根据资料设计电路,按资料上的器件接法连接,把资料上的电器件(如电阻的阻值,电容的法拉)都表示清楚,然后画Protel图,再做出PCB板子,拿到车间生产焊接再连接单片机就制作出来了。

见dac0832的PDF的P5,图中表示CS和ILE要先给低电平,然后WR给低电平,随后有效数据就传送过去,经过一小段时间稳定一下,IOUT1和IOUT2再进行有效输出

直通连接方式:直接送数据,IOUT1口就输出;结合TX-1C原理图看,赋给相应管脚低电平或高电平,结合DA接口.bmp看,DI0到DI7是数据口连接单片机的P0口,其它的为控制口或电源口,CSDA连接单片机的P3.2口(使用时要给低电平),WR连接单片机的P3.6口(使用时要给低电平);IOUT1口输出的P5的2和3用跳线帽(又叫短路子)短路,IOUT1输出的电流直接穿过发光二极管到地上,输出的数字量变化,那么输出的模拟量就变化,模拟量的变化体现在流过发光二极管上的电流,发光二极管就有明暗的变化可以判断有没有把DA操作起来,1口可以外接运算放大器;DA输出口的器件,当2和3短路后直接通过发光二极管接地

赋给低电平

输出最高电压,点亮DA的灯,一上电P0口到P3口就输出最大值,所以开始DA的灯就亮:

#include<reg52.h>

sbit csda=P3^2;//注意csda(数模)和csad(模数)相区别

sbit wr=P3^6;

void main()

{

csda=0;

wr=0;

P0=0xff;//输出最高电压,P0=0时,关闭DA灯

while(1);

}

我的随笔程序:证明按照AD的时序图来操作是可以的,可以让片选CSDA高低电平变化,并且WR高低电平的变化:

#include<reg52.h>

#define uint unsigned int

#define uchar unsigned char

sbit csda=P3^2;//注意csda(数模)和csad(模数)相区别

sbit wr=P3^6;

sbit dula=P2^6;

sbit wela=P2^7;

uchar aa;

void delay(uint z)

{

uint x,y;

for(x=z;x>0;x--)

for(y=110;y>0;y--);

}

void main()

{

while(1)

{

dula=0;

wela=0;

aa++;

if(aa==256)

aa=0;

csda=0;

wr=0;

P0=aa;//输出最高电压,P0=0时,关闭DA灯

delay(5);

wr=1;

csda=1;

delay(5);

}

}

DA灯由灭到逐渐变到最亮,时间2s,由最亮到逐渐变暗到灭,时间2s

我的程序:

#include<reg52.h>

#define uint unsigned int

#define uchar unsigned char

sbit csda=P3^2;

sbit wr=P3^6;

sbit wela=P2^7;

uchar flag;

int aa,bb,cc;

void init()

{

csda=0;

wr=0;

P0=0;

TMOD=0x01;

TH0=(65536-7812)/256;

TL0=(65536-7812)%256;

EA=1;

ET0=1;

TR0=1;

wela=1;

P0=0xff;

wela=0;

bb=255;

}

void main()

{

init();

while(1)

{

P0=cc;

}

}

void timer0() interrupt 1

{

if(flag==0)

{

TH0=(65536-7812)/256;

TL0=(65536-7812)%256;

aa++;

if(aa==256)

{

aa=0;

flag=1;

}

cc=aa;

}

if(flag==1)

{

TH0=(65536-7812)/256;

TL0=(65536-7812)%256;

bb--;

if(bb==-1)

{

bb=255;

flag=0;

}

cc=bb;

}

}

DA灯亮灭变化的同时发光二极管做加法变化:

#include<reg51.h>

sbit wela=P2^7;

sbit dula=P2^6;

sbit dawr=P3^6;

sbit csda=P3^2;

unsigned char a,j,k;

void delay(unsigned char i)

{

for(j=i;j>0;j--)

for(k=125;k>0;k--);

}

void main()

{

wela=0;

dula=0;//因为下面控制P1口,段选和位选给零,不让数码管干扰

csda=0;

a=0;

dawr=0;

while(1)

{

P0=a;

P1=~a;

delay(50);

a++;

}

}

A/D:例如把0到8V电压分成百位就是全部量化分配到0到255

用的最多的是逐次逼近式和双积分式

见PPT的P16:VIN模拟量的输入端,EOC(End Of Convert)转换结束(输出一个信号,告诉转换结束,可以把数据读走),倒三角是比较器,OE(Output Enable)是使能端,D/A转换器有A/D转换的功能

倒三角是比较器,倒三角上面的线(带圆圈的是上面)输出比下面高输出就是1,上面的线输出比下面低输出就是0;图中最右边,从右向左看,先将作为参考电压,这里将八位D/A转换器的最高位先置1,通过D/A转换器后的对应电压是 /2,输出电压为 /2,与 比较,如果大,则置1到N位寄存器最高位并传给D/A转换器,如果小,则置0到N位寄存器最高位并传给D/A转换器和锁存缓存器,再在D/A转换器的第二位置1,进行判断,如此类推,进行八次后,EOC口输出一个信号给单片机,告诉转换结束,单片机收到EOC信号后给OE一个低电平再将数据读走

见dac0832资料P1的典型管脚连线图,11到18管脚是数据口(TX-1C型单片机实验板原理图中的DB1到DB8),用来送数据,接单片机的P1口;INTR是中断口,当芯片转换完给单片机一个中断,要接单片机的外部中断(P3.2口或P3.3口),开发板中AD转换器没;使用中断,就是过段时间去读,肯定能转换完;RD和WR接单片机的RD和WR,即单片机的P3.6口和P3.7口;CS即片选,接锁存器(控制数码管位选的那个锁存器)的CSAD;VCC接5V电压;CLK R和CLK IN接管脚19和4是一个RC振荡电路,作用是提供频率让A/D转换;VIN(+)和VIN(-)采集电压,组成差分电路,输出差分信号,两条电路用来比较,可以采集桥式电路(见下图,可以做电子秤,上面的支路的第一个电阻是滑动电阻,两条并联的支路的两个电阻之间的导线连在VIN(+)和VIN(-)上,得到的压差来得出压力值);A GND表示模拟电压地端,D GND表示数字电压地端,之所以分开是防止它俩有干扰;Processor是处理器,即单片机(51,arm等);AD转换器在开发板中的电源灯下面,ADIN在AD转换器的左侧,即有跳线帽的,为了扩展,可能接模拟输入端,开发板中将其1和2短路,上面的滑动变阻器对应开发板中AD转换器的右边,可以调节上面的旋钮,ADIN的1连接着AD转换器的6管脚,6管脚下面的7管脚接地,所以6管脚就能检测到0到5伏之间的变化,ADIN的1管脚和AD转换器的6管脚之间的10k电阻是限流电阻,保护不被击穿,但电压是不会变的;AD转换器的9管脚是, ,开发板上用两个1K电阻分成2.5V

见P5的时序图,第一个图是开始转换,CS给低电平,WR在CS低电平期间给个低脉冲,即在CS给低电平之后稍过一段时间WR给个低脉冲,实际内部转换状态(Actual Internal Status Of The Converter)的BUSY表示AD转换过程,转换完INTR给个低电平通知中断,实际内部转换状态和INTR可以不用程序实现,只是表示转换过程;第二个图是读取数据,如果要AD转换器一直工作就让CS一直置0;中断INTR通知后,给RD一个低电平,在RD低电平到高电平变化的瞬间把数据读走,开发板上不用中断,所以不用考虑中断;程序中就让RD为高,变低,再为高,读走数据,即送到P1口;AD转换器的CSAD连接着锁存器,程序中直接控制锁存器就行

开发板中的AD转换器的数据口也连接着发光二极管,设计一个程序,就不停的启动读,数字量变化八个发光二极管就亮灭变化

见ad0804的PDF的P18,是内部工作频率,八个数据全转换完需要八个,R=10K,C=145PF,由公式可得,开发板上的C很大,所以程序启动后要等一会再读数字

利用AD转换器动态显示发光二极管:

#include<reg52.h>

#define uchar unsigned char

#define uint unsigned int

sbit wr=P3^6;

sbit rd=P3^7;

void delay(uint z)

{

uint x,y;

for(x=z;x>0;x--)

for(y=110;y>0;y--);

}

void init();

void start();

void main()

{

init();

while(1)

{

start();

delay(20);

rd=0;//rd低电平才能读数据,见时序图

delay(10);//一定要延时一会将数据读走再将rd变高电平,见上面的总结

rd=1; //rd高电平为了下次变低电平后读数据

delay(10);

}

}

void init()

{

P0=0;//即将csad赋给0,A/D转换器被选用

}

void start()

{

wr=1;//见0804的资料上的时序图,启动AD转换

wr=0;

wr=1;

}

A/D转换器的数据口接在DB1到DB8上,DB1到DB8连在发光二极管上,所以A/D转换器的数据口有数据输出,发光二极管也会亮

旋转AD转换器右边的电位器的旋钮,发光二极管的亮度会变化。

TX-1C型单片机实验板原理图中单片机和数码管中间的是USB设备开发芯片,右边是USB下载接口,晶振下面是复位电路,复位电路下面是DS18B20是数字温度传感器,DS18B20下面是串口,串口那,电容处的104表示10* PF(皮法),103是10*PF,180是18*;电阻4K7是4.7K,5R8是5.8欧姆;封装(电阻,电容封装方式):0805,还有1206封装,3216封装,0604封装,0302封装(数字越小封装越小);键盘下面的P6到P9是扩展口(下面标明了对应的P0、P1、P2和P3),即开发板上单片机左右的两排针;扩展口的右边是EEPROM,再右边是1602液晶接口,再右边是1280液晶接口;晶振右边是下载程序的指示灯,键盘上面是AD转换器

开发板上,黄色的是电容,黑色的是电阻

课件练习:

将AD模拟数字的模拟量读回来,转换成十进制数显示在数码管的前三位上,0到255:

我的程序:

#include<reg52.h>

#define uint unsigned int

#define uchar unsigned char

uchar bai,shi,ge,temp;

sbit dula=P2^6;

sbit wela=P2^7;

sbit wr=P3^6;

sbit rd=P3^7;

uchar code table[]={

0x3f,0x06,0x5b,0x4f,

0x66,0x6d,0x7d,0x07,

0x7f,0x6f,0x77,0x7c,

0x39,0x5e,0x79,0x71,

0x76,0x79,0x38,0x3f,0

};

void delay(uint z)

{

uint x,y;

for(x=z;x>0;x--)

for(y=110;y>0;y--);

}

void start()

{

wela=1;

P0=0;

wr=0;//下面不能加延时程序delay(10),一旦加入延时,wela=1;P0=0;这两句就把数码管//打开,让八个数码管一起显示,而没有延时,刚打开数码管就wela=0关闭就不会出现八个//数码管一起显示

wr=1;

P0=0xff;

delay(10);

wela=0;

}

void display(uchar aa,uchar bb,uchar cc)

{

dula=1;

P0=table[aa];

dula=0;

P0=0xff;

wela=1;

P0=0xfe;

wela=0;

delay(10);

dula=1;

P0=table[bb];

dula=0;

P0=0xff;

wela=1;

P0=0xfd;

wela=0;

delay(10);

dula=1;

P0=table[cc];

dula=0;

P0=0xff;

wela=1;

P0=0xfb;

wela=0;

delay(10);

}

void init()

{

P0=0;

}

void main()

{

init();

while(1)

{

start();

delay(20);

wela=1;//必须有这句,否则会出错,现象是只显示255,因为上次存储器锁存的是//P0=0xff,如果不打开wela,锁存器仍然锁存0xff,而不会把新的P0值存入并显示

P1=0xff;

P0=0;

rd=0;

temp=P1;

rd=1;

P0=0xff;

P1=temp;

delay(20);

display(temp/100,temp%100/10,temp%10);

}

}

课件的程序:

#include<reg51.h>

#include <intrins.h>

#define uint unsigned int

#define uchar unsigned char

sbit adrd=P3^7;                          //IO口定义

sbit adwr=P3^6;

sbit diola=P2^5;

sbit dula=P2^6;

sbit wela=P2^7;

unsigned char j,k,adval;

void delay(unsigned char i)          //延时程序

{

for(j=i;j>0;j--)

for(k=125;k>0;k--);

}

uchar code table[]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,                            //数码管编码

0x07,0x7f,0x6f,0x77,0x7c,0x39,0x5e,0x79,0x71};

void display(uchar bai_c,uchar sh_c,uchar g_c)                 //显示程序

{

P0=table[bai_c];             //显示百位

dula=1;

dula=0;

P0=0xfe;

wela=1;

wela=0;

delay(5);

dula=0;

P0=table[sh_c];        //显示十位

dula=1;

dula=0;

wela=0;

P0=0xfd;

wela=1;

wela=0;

delay(5);

P0=table[g_c];         //显示个位

dula=1;

dula=0;

P0=0xfb;

wela=1;

wela=0;

delay(5);

}

void main()           //     主程序

{

uchar a,A1,A2,A2t,A3;

while(1)

{

wela=1;

P0=0;                       //选通ADCS

adwr=0;                //AD写入(随便写个什么都行,主要是为了启动AD转换)

_nop_();

adwr=1;

P0=0xff;                    //关闭ADCS

delay(10);

wela=0;                     //关闭有AD片选信号锁存器的锁存端以防止在操作数

//码管时使AD的片选发生变化

for(a=20;a>0;a--)        //需要注意的是ADC0804在写和读之间的时间间隔要足够//长否则无法读出数据

{                           //这里把显示部分放这里的原因也是为了增加写读之间//的时间间隔

display(A1,A2,A3);

}    //送去显示各位。

wela=1;                   //重新打开有AD片选信号锁存器的锁存端

P1=0xff;                    //读取P1口之前先给其写全1

P0=0;                       //选通ADCS

adrd=0;                     //AD读使能

adval=P1;                   //AD数据读取赋给P1口

adrd=1;

P0=0xff;                     //关闭ADCS

adwr=0;

P1=adval;                    //同时把AD的值送八个发光二极显示

A1=adval/100;            //分出百,十,和个位

A2t=adval%100;

A2=A2t/10;

A3=A2t%10;

};

}

将AD的值读回来,赋给DA,即调节AD的电位器时,DA对应的发光二极管也会发生变化:

我的程序:

#include<reg52.h>

#define uint unsigned int

#define uchar unsigned char

sbit adwr=P3^6;

sbit adrd=P3^7;

sbit dula=P2^6;

sbit wela=P2^7;

sbit csda=P3^2;

uchar temp;

void delay(uchar z)

{

uchar x,y;

for(x=z;x>0;x--)

for(y=110;y>0;y--);

}

void init()

{

temp=0;

P0=0;

}

void start()

{

P0=0;

adwr=0;

adwr=1;

P0=0xff;

}

void admode()

{

csda=0;

adwr=0;

//temp=P1;

delay(1);//调试的时候,由于我不能确定P0是否被赋值为temp,这里可以添加一句//temp=0xfd,再调试中下面的语句csda=1加断点,看看P0是否等于temp,如果是说明AD

//转换器的输出值temp确实被DA转换器读入,并将此值送给P0来控制DA转换器的发光//二极管

P0=temp;

csda=1;

delay(10);

}

void main()

{

init();

while(1)

{

start();

delay(10);

P1=0xff;

P0=0;

adrd=0;

temp=P1;

adrd=1;

P0=0xff;

delay(20);

P1=temp;//发光二极管亮,可以判断AD转换器是否起作用

admode();

}

}

郭天祥的10天学会51单片机_第六节相关推荐

  1. 郭天祥的10天学会51单片机_第七节

    串行通信:从D0位一位一位发发到D7位 十个位为一帧如:0101000100,表示一个字符 起始位低电平有效,停止位高电平有效,单片机是异步通信 宽带网线是八根线,组成两队差分信号,分别是TXD1(发 ...

  2. 郭天祥的10天学会51单片机_第十三节

    AD软件: AD软件可以编译C语言和VHDL语言等:AD软件的工具栏上面可以输入网络地址进行浏览网页:AD软件可以布差分信号,即可以两条线可以一起布 按住Shift键和左键可以向左移动,按住Shift ...

  3. 郭天祥的10天学会51单片机_第三节

    单片机管脚,P3口有两个功能,上电默认情况下就使用P3口的普通IO口,当对单片机内部的某些寄存器设置时就启用P3口的第二个功能 P3^4和 P3^5可以作为计时器或定时器使用,给这两个口输入方波,进行 ...

  4. 10.4.4 51单片机控制系统8个LED“跑马灯”实验

    10.4.4 51单片机控制系统8个LED"跑马灯"实验 仿真+代码 方法一 利用数组 #include"reg52.h"#define u8 unsigned ...

  5. 51单片机学习笔记(郭天祥版)(1)——单片机基础和点亮LED灯

    关于单片机型号的介绍: STC89C52RC40C-PDIP 0721CV4336..... STC:STC公司 89:89系列 C:COMS 52(还有51,54,55,58,516,):2表示存储 ...

  6. 红外测距模块 51单片机_[51单片机] HC-SR04超声波测距仪

    1.HC-SR04超声波模块工作原理 (1)采用IO口触发测距,给至少10us高电平脉冲: (2)模块自动发送八个40khz方波,并自主检测是否有电波返回: (3)当有信号返回时,通过IO口输出一个高 ...

  7. 51单片机(十六)AD/DA

    ❤️ 专栏简介:本专栏记录了从零学习单片机的过程,其中包括51单片机和STM32单片机两部分:建议先学习51单片机,其是STM32等高级单片机的基础:这样再学习STM32时才能融会贯通. ☀️ 专栏适 ...

  8. 2440 8字数码管 显示0到10 c语言,51单片机对8位数码管依次显示0-7的设计

    共阳极数组0~9:display[]={0xC0,0xF9,0xA4,0xB0,0x91,0xA2,0x82,0xF8,0x80,0x90} 共阳极数组A~F:display[]={0x88,0x83 ...

  9. 单片机c语言二进制转10进制,51单片机用C语言怎么样把八位二进制转换成十进制...

    满意答案 sunzhaoming 2013.07.06 采纳率:41%    等级:12 已帮助:8866人 //******************************************* ...

  10. 51单片机_动态数码管显示

    动态数码管显示(延时函数) 编程原理 利用延迟函数,每秒钟数码管加1显示,一直加到250.延时函数精度不高,最好使用定时器中断. 数码管动态显示原理 动态数码管显示有段选和位选.段选是单个数码管显示的 ...

最新文章

  1. 0x33.数学 - 同余
  2. 安装python爬虫scrapy踩过的那些坑和编程外的思考
  3. java的异常机制面试题(转)
  4. 在mac上用文本编辑器写python_Mac开源文本编辑器CotEditor
  5. android显示通知栏Notification以及自定义Notification的View
  6. mysql无法添加或更新子行_MYSQL:错误:无法添加或更新子行:外键约束失败
  7. 正襟危坐说--操作系统(肆):线程
  8. 记录一下:new的几种用法
  9. DOS批处理高级教程:第七章 DOS批处理编程高级技巧(转)
  10. editplus更改编码
  11. 怎么用软件测试PSP硬件,PSP适用FC模拟器从安装到使用全面教程
  12. Mysql 超键 候选键 主键 外键之间关系
  13. 古风一棵桃花树简笔画_唯美意境桃花古风句子
  14. oracle创建数据库的先决条件,Oracle数据库安装先决条件检查失败解决方案
  15. 能量谷算法Energy Valley Optimizer (EVO)附matlab代码
  16. 用计算机解决问题时 为什么要用计算思维,在亲历计算机解决问题的全过程中发展计算思维...
  17. 问题分析报告--简单SQL启动MR
  18. 恶习为什么难戒?因为你在HALT状态
  19. 奥特曼宇宙英雄服务器维修,奥特曼宇宙英雄1.1.7版本
  20. Vagrant安装到其它盘(除C)

热门文章

  1. 在线制作ico矢量图标
  2. 教你如何挑选趁手的笔记本电脑!
  3. 知识蒸馏 | 知识蒸馏的算法原理与其他拓展介绍
  4. python模拟微信登录公众号_PYTHON 微信公众平台模拟登陆
  5. 百度竞价推广之关键词的选择策略
  6. 分享一个好用的抠图网站
  7. 制作Lightbox效果
  8. xp系统计算机怎么连接到网络打印机,windows xp系统如何连接不同网段共享打印机...
  9. UVA 177 PaperFolding 折纸痕 (分形,递归)
  10. autocad ios 虚线_教大家AutoCAD2020怎么画虚线的方法