高分求51单片机AD7731实现AD转换C程序代码

高分求51单片机AD7731实现AD转换C程序代码,第1张

#include <reg52h>#include <intrinsh>#define uchar unsigned char#define uint unsigned intsbit DS=P3^3; //定义DS18B20接口int temp; uchar flag1; void display(unsigned char lp,unsigned char lc);//数字的显示函数;lp为指向数组的地址,lc为显示的个数void delay();//延时子函数,5个空指令code unsigned char table[]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f,0xbf,0x86,0xdb,0xcf,0xe6,0xed,0xfd,0x87,0xff,0xef,0x40,0x39,0x00};//共阴数码管显示数的组成是 "0-9""0-9有小数点的" "-" "C" "空 表"unsigned char l_tmpdate[8]={0,0,10,0,0,0,0,0};//定义数组变量,并赋值1,2,3,4,5,6,7,8,就是本程序显示的八个数int tmp(void);void tmpchange(void);void tmpwritebyte(uchar dat);uchar tmpread(void);bit tmpreadbit(void);void dsreset(void);void delayb(uint count);void main() //主函数{uchar i;int l_tmp; while(1) { tmpchange(); //温度转换 l_tmp=tmp(); //读取温度值 if(l_tmp<0) l_tmpdate[0]=20; //判断温度为负温度,前面加"-" else { l_tmpdate[0]=l_tmp/1000; //显示百位,这里用1000,是因为我们之前乖以10了 if(l_tmpdate[0]==0) l_tmpdate[0]=22;//判断温度为正温度且没有上百,前面不显示,查表第12是空 }l_tmp=l_tmp%1000;l_tmpdate[1]=l_tmp/100;//获取十位l_tmp=l_tmp%100;l_tmpdate[2]=l_tmp/10;//获取个位再l_tmpdate[2]+=10;//加入小数点,查表可得出有小数点的排在后10位,所以加10l_tmpdate[3]=l_tmp%10;//获取小数第一位l_tmpdate[4]=21;for(i=0;i<10;i++){ //循环输出10次,提高亮度display(l_tmpdate,5); } }}void display(unsigned char lp,unsigned char lc)//显示{ unsigned char i; //定义变量 P2=0; //端口2为输出 P1=P1&0xF8; //将P1口的前3位输出0,对应138译门输入脚,全0为第一位数码管 for(i=0;i<lc;i++){ //循环显示 P2=table[lp[i]]; //查表法得到要显示数字的数码段 delay(); //延时5个空指令 if(i==7) //检测显示完8位否,完成直接退出,不让P1口再加1,否则进位影响到第四位数据 break; P2=0; //清0端口,准备显示下位 P1++; //下一位数码管 }}void delay(void) //空5个指令{_nop_();_nop_();_nop_();_nop_();_nop_();}void delayb(uint count) //delay{ uint i; while(count) { i=200; while(i>0) i--; count--; }答案补充

}void dsreset(void)//DS18B20初始化{ uint i; DS=0; i=103; while(i>0)i--; DS=1; i=4; while(i>0)i--;}bit tmpreadbit(void) // 读一位{ uint i; bit dat; DS=0;i++; //小延时一下 DS=1;i++;i++; dat=DS; i=8;while(i>0)i--; return (dat);}uchar tmpread(void) //读一个字节{ uchar i,j,dat; dat=0; for(i=1;i<=8;i++) { j=tmpreadbit(); dat=(j<<7)|(dat>>1); } return(dat); } 答案补充

void tmpwritebyte(uchar dat) { uint i; uchar j; bit testb; for(j=1;j<=8;j++) { testb=dat&0x01; dat=dat>>1; if(testb) { DS=0; i++;i++; DS=1; i=8;while(i>0)i--; } else { DS=0; i=8;while(i>0)i--; DS=1; i++;i++; } }}void tmpchange(void){ dsreset(); delayb(1); tmpwritebyte(0xcc); tmpwritebyte(0x44); }答案补充

int tmp() //获得温度{ float tt; uchar a,b; dsreset(); delayb(1); tmpwritebyte(0xcc); tmpwritebyte(0xbe); //发送读取数据命令 a=tmpread(); //连续读两个字节数据 b=tmpread(); temp=b; temp<<=8; temp=temp|a; //两字节合成一个整型变量。 tt=temp00625; //得到真实十进制温度值,因为DS18B20//可以精确到00625度,所以读回数据的最低位代表的是//00625度。 temp=tt10+05; //放大十倍,这样做的目的将小数点后第一位//也转换为可显示数字,同时进行一个四舍五入 *** 作。 return temp; //返回温度值}答案补充

void readrom() //read the serial 读取温度传感器的序列号{ //本程序中没有用到此函数 uchar sn1,sn2; dsreset(); delayb(1); tmpwritebyte(0x33); sn1=tmpread(); sn2=tmpread();}void delay10ms() { uchar a,b; for(a=10;a>0;a--) for(b=60;b>0;b--);}哇!好累啊。。。这个可以用。。。用那个口自己看看就懂了,如果要汇编语言的去看:>

首先,不知道你的原理图中的 VCC的标号是怎么画的,我记得那个标号一般是GND的,你在确认一下

其次,‘P3=0x11; //为了验证是不是我初始设值的问题’,这里P3作为输入不建议做输出使用,P1口闲着可以随便用

然后,数码管动态显示应该预留足够的显示时间,程序中一次while循环一次

AD采集用到4个'delay (10) ', 数码管显示 有10个{delay (2)+delay (2)}

也就是说一个周期只有不到一半的时间在显示,那么做出来的效果数码管肯定不会太亮,建议适当增加数码管的显示时间(高级应用也可考虑用定时器中断定时更新数码显示)

还有就是‘uchar temp3; //temp3用作暂时储存P0’,这里没必要保留P0的数据,你在退出显示的时候已经把位选关了

最后,不知道你是按照什么样的步骤软件仿真的,建议使用断点观察配合单步调试来查找问题,可以先不考虑数码管显示,AD采集数据正常之后再考虑显示,一步一步来分块排查解决问题

兄弟:不知道你玩不玩32 ,有个32 的在工程上用过,直接刷程序,串口连接电脑就可以输出AD 转换的结果。如果不玩32 的话。

首先第一步排查: 排查单片机能不能正确显示 你测试到的 AD 信号,显示正确不?

比如给他 3V 电压 ,用数码管显示出来。

第二: 串口发送,找个能正确发送数据的代码 ,直接把 ,你检查的数值给这个变量,让串口发送,

一步一步找问题,你绝对能解决的。我把AD0809 的代码给你用数码管测试

#include <reg52h>

#define uint unsigned int

#define uchar unsigned char

uchar code LEDData[]=

{

0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f

};

sbit OE = P1^0;

sbit EOC = P1^1;

sbit ST = P1^2;

sbit CLK = P1^3;

void DelayMS(uint ms)

{

uchar i;

while(ms--)

{

for(i=0;i<120;i++);

}

}

void Display_Result(uchar d)

{

P2 = 0xf7;

P0 = LEDData[d%10];

DelayMS(5);

P2 = 0xfb;

P0 = LEDData[d%100/10];

DelayMS(5);

P2 = 0xfd;

P0 = LEDData[d/100];

DelayMS(5);

}

void main()

{

TMOD = 0x02;

TH0 = 0x14;

TL0 = 0x00;

IE = 0x82;

TR0 = 1;

P1 = 0x3f;

while(1)

{

ST = 0;

ST = 1;

ST = 0;

while(EOC == 0);

OE = 1;

Display_Result(P3);

OE = 0;

}

}

void Timer0_INT() interrupt 1

{

CLK = !CLK;

}

用c51单片机做AD转换,只要用一个简单的延时就可以,没必要动用定时器这么高级的东西,DMA就更别提了,我写了很多程序,还真没有人能用C51实现DMA,DMA一般在arm系列和FPGA等的高级嵌入式里面才会用到的。

方法1:将浮点数从小数点分开,分别向左、向右取两位数进行转换,在数据区里存贮,再取下一个两位,按顺序存贮,直到完成。如256345,第一次取值为56和34,第二次取值为5和50。最后转换的值是:05

34

22

32,共占用了4个字节。再使用时需要重新合成。只要有足够大的存贮区,就可以放置任意长度的数值。

方法2:设置2个4字节的数据块,分别放置小数的整数位和小数位,可以满足最大无符号十进制99999999的存放。

在你上面的程序中,因为16进制数是没小数点的,所以不能直接转换。

把300V电压,接到两个的电阻分电路上,电阻串联有分压作用。一端接地的电阻上分压为0~5V,假如电阻取10K,那么大电阻就应该是590K。电压分压比为300/5=60倍,所以,用AD采集0~5V电压,得到数字量,换算成电压为Ⅴd,再计算出被测电压Vx=60Vd。所以,写程序很简单,主要是A/D转换程序并转换为电压Vd。

以上就是关于高分求51单片机AD7731实现AD转换C程序代码全部的内容,包括:高分求51单片机AD7731实现AD转换C程序代码、51单片机在线等关于AD转换的、51单片机ad转换问题等相关内容解答,如果想了解更多相关内容,可以关注我们,你们的支持是我们更新的动力!

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

原文地址: http://outofmemory.cn/zz/9335570.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2023-04-27
下一篇 2023-04-27

发表评论

登录后才能评论

评论列表(0条)

保存