IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> 嵌入式 -> 郭天祥的10天学会51单片机_第六节 -> 正文阅读

[嵌入式]郭天祥的10天学会51单片机_第六节

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

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

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

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板子,拿到车间生产焊接再连接单片机就制作出来了。

dac0832PDFP5,图中表示CSILE要先给低电平,然后WR给低电平,随后有效数据就传送过去,经过一小段时间稳定一下,IOUT1IOUT2再进行有效输出

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

赋给低电平

输出最高电压,点亮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例如把08V电压分成百位就是全部量化分配到0255

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

PPTP16VIN模拟量的输入端,EOCEnd Of Convert)转换结束(输出一个信号,告诉转换结束,可以把数据读走),倒三角是比较器,OEOutput 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给低电平,WRCS低电平期间给个低脉冲,即在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转换器的数据口接在DB1DB8上,DB1DB8连在发光二极管上,所以A/D转换器的数据口有数据输出,发光二极管也会亮

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

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

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

课件练习:

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

我的程序:

#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();?????????????

?????? }

}

  嵌入式 最新文章
基于高精度单片机开发红外测温仪方案
89C51单片机与DAC0832
基于51单片机宠物自动投料喂食器控制系统仿
《痞子衡嵌入式半月刊》 第 68 期
多思计组实验实验七 简单模型机实验
CSC7720
启明智显分享| ESP32学习笔记参考--PWM(脉冲
STM32初探
STM32 总结
【STM32】CubeMX例程四---定时器中断(附工
上一篇文章      下一篇文章      查看所有文章
加:2021-10-19 12:03:02  更:2021-10-19 12:03:11 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/26 6:45:26-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码