求AD转换程序

求AD转换程序,第1张

仅供参考:

#include<reg52h> //52单片机头文件

#include<intrinsh> //内部库函数头文件

#define uchar unsigned char //变量宏定义

#define uint  unsigned int

//LCD

sbit CS1=P2^4; //片选1

sbit CS2=P2^3; //片选2

sbit DI=P2^2; //数据\指令选择

sbit RW=P2^1; //读\写选择

sbit E=P2^0; //读\写使能

sbit busy=P0^7; //忙标志位

//键盘

sbit jia=P1^0; //X+,X轴增加

sbit jian=P1^1; //X-,X轴减小

sbit jia1=P1^2; //Y+,Y轴增加

sbit jian1=P1^3; //Y-,Y轴减小

//ADC

sbit START=P2^7; //ADC转换启动

sbit OE=P2^6; //ADC输出使能

sbit EOC=P2^5; //ADC转换状态标志

//变量与数组

char a[107]; //ADC数据采样缓存

uint g=0,dianya=1; //采样频率,电压(信号幅度)

uchar code word[]= //汉字字模(楷体,右旋90,横向取码)

{

0x04,0x00,0x45,0x20,0x44,0xA8,0x2C,0x60,0x13,0xFE,0x1A,0x10,0x27,0x58,0x10,0x94,//数

0x0A,0x40,0x04,0x70,0x0B,0x4C,0x10,0xE0,0x30,0x20,0x20,0x20,0x20,0x00,0x00,0x00,

0x00,0x00,0x02,0x00,0x02,0x18,0x02,0x08,0x02,0x28,0x02,0x28,0x21,0x29,0x41,0x96,//字

0x3F,0x54,0x01,0x34,0x01,0x04,0x01,0x14,0x01,0x0C,0x01,0x00,0x00,0x00,0x00,0x00,

0x00,0x00,0x00,0x40,0x0C,0x40,0x07,0x40,0x00,0x44,0x00,0x44,0x10,0x44,0x3F,0xC4,//示

0x00,0x24,0x00,0x22,0x01,0x22,0x02,0x20,0x06,0x20,0x00,0x20,0x00,0x00,0x00,0x00,

0x00,0x00,0x18,0x20,0x0C,0x40,0x23,0x04,0x18,0x08,0x06,0x00,0x11,0xF0,0x11,0x10,//波

0x0A,0x90,0x04,0xFF,0x0A,0x88,0x11,0x88,0x30,0x18,0x20,0x00,0x20,0x00,0x00,0x00,

};

//ADC0808转换控制

uchar adc()

{

char AD; //读数变量

START=0; //拉低电平

START=1; //拉高电平,在上升沿清零所有内部寄存器

START=0; //拉低电平,在下降沿的时候,开始进行AD转换

while(EOC==0); //等待转换结束(EOC=1,表示转换结束)

OE=1; //使能输出,允许数据线输出数据

AD=P3; //读取端口

OE=0;   //停止输出

return AD;

}

//LCD忙检测

void checkstate()

{

E=0;DI=0;RW=1; //读指令寄存器

do //循环输出状态值

{ E=1;E=0; }

while(busy==1); //判断,仅当busy=0时,中断循环

}

//写命令到LCD

void writecommand(uchar command)

{

checkstate(); //查忙

E=0;DI=0;RW=0; //准备写指令

P0=command; //指令送端口

E=1; //使能写入

E=0; //停止写入

}

//写数据到LCD

void writedate(uchar date)

{

checkstate(); //查忙

E=0;DI=1;RW=0; //准备写数据

P0=date; //数据送端口

E=1; //使能写入

E=0; //停止写入

}

//左右屏选择

void selectscreen(uint ss)

{

if(ss==0)CS1=0,CS2=0; //参数0,选全屏

if(ss==1)CS1=0,CS2=1; //参数1,选左屏

if(ss==2)CS1=1,CS2=0; //参数2,选右屏

if(ss==3)CS1=1,CS2=1; //参数3,不选屏

}

//清屏

void clearscreen(uchar ss)

{

uchar i,j; //页,列变量

selectscreen(ss); //选屏

for(i=0;i<8;i++) //从0到7共8页

{

writecommand(0xb8+i); //写入页地址

writecommand(0x40); //首列地址

for(j=0;j<64;j++) //每页64列

writedate(0x00); //逐列写空字节,列地址自加1

}

}

//初始化LCD

void init_lcd()

{

selectscreen(0);

writecommand(0xc0); //设置起始行0行

writecommand(0x3f); //开显示

}

//us延时

void delayus(uint t)

{

while(t--);

}

//ms延时

void delayms(uint t)

{

uint i;

while(t--)

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

}

//显示汉字(按列纵向显示)

void displaychines(uchar ss,uchar page,uchar col,uchar dat,uchar n)

{

uchar k,y,x; //汉字显示变量:字数,页,列,

for(k=0,y=0;k<n;k++,y+=2) //写入4个汉字,每写入一个汉字,页码+2

{

selectscreen(ss); //选屏

writecommand(0xb8+page+y); //写上半字页地址0页(0~2~4~6)

writecommand(0x40+col); //首列地址112列(右屏48列),自动加1

for(x=0;x<16;x++) //循环16次, 写上半字16个编码字节

{

writedate(dat[2x+1+32k]); //依次读取字符编码:1,3,515写入

}

writecommand(0xb8+page+y+1); //写下半字页地址1页(1~3~5~7)

writecommand(0x40+col); //首列地址112列(右屏48列),自动加1

for(x=0;x<16;x++) //循环16次, 写下半字16个编码

{

writedate(dat[2x+32k]); //依次读取字符编码:0,2,414写入

}

}

}

//按键 *** 作

void keyscan()

{

while(jia==0) //如果 X+ 键被按下

{

while(jia==0); //等待键松开后

if(g>0)g-=10; //若g 不为0则减1(采样频率减小)

}

while(jian==0) //如果 X- 键被按下

{

while(jian==0); //等待键松开后

if(g<100)g+=10; //g自加1  (采样频率增大)

}

while(jia1==0) //如果 Y+ 键被按下

{

while(jia1==0); //等待键松开后

if(dianya>1)dianya-=2; //若电压值不为0 则-1(幅度增大)

}

while(jian1==0) //如果 Y- 键被按下

{

while(jian1==0); //等待键松开后

if(dianya<12)dianya+=2; //电压值自+1  (幅度减小)

}

}

//在指定坐标(x,y)上描点函数(逐点绘图)

void lcd_pixel(uchar x,char y) //x水平坐标,y垂直坐标,Vect矢量绘图参数

{

char dat[8];   //定义列字节数组

uchar j;   //循环变量

// y=63-y; //更改y坐标为习惯方式

for(j=0;j<8;j++) dat[j]=0x00;     //数组元素赋初值 0x00

dat[y>>3]|=0x01<<(y&0x07); //y值所在字节对应位置 1

if(x<64) //列坐标小于64

selectscreen(1); //选择左半屏

else   //列坐标大于等于64

{selectscreen(2);x-=64;} //选择右半屏,列坐标调整为0~63

for(j=0;j<8;j++)   //每屏8页(0~7),8个字节

{

writecommand(0xb8+j);     //写页地址

writecommand(0x40+x);     //写列地址

writedate(dat[j]); //写字节数据

}

}

//主程序

void main()

{

uchar i; //定义变量

char U;

init_lcd(); //初始化LCD

clearscreen(0); //清屏

while(1)

{

displaychines(2,0,48,word,4); //显示汉字:数字示波

keyscan(); //按键扫描

for(i=0;i<107;i++) //ADC采样(取94个读数值)

{

a[i]=adc()/4; //读取AD值存入缓存数组

delayus(g); //延时g us,控制采样频率

}

for(i=0;i<107;i++ ) //循环94次,读取缓存数组中数据

{

U=a[i]/dianya; //计算在12864中的幅值

lcd_pixel(i,U); //定位描点显示波形

}

delayms(2000);

clearscreen(0);

}

}

芯片厂商

芯片资料

ad精度

一个字都不说这没人帮得了你。。。

我说个大概吧:

用ad芯片和其他芯片一样

片选给上去。输入数据的时钟和mcu的输出连起来,输入数据端和数据总线连起来。同步时钟一般用个特定频率的晶振,如果频率低就用mcu的定时器做分频。

要让ad工作一般需要首先往ad的设置寄存器里写设置数据,定义ad使用哪个通道,增益是多少,频率是多少等。

然后向设置好的ad芯片发送实际需要读取哪个通道。

最后再写回读函数,将dataout脚上的数据传回mcu进行之后的 *** 作。

例程的话百度文库里有很多。

#include "stc12c5a56s2h"

#include "intrinsh"

#define FOSC 11059200L

#define BAUD 9600

typedef unsigned char BYTE;

typedef unsigned int WORD;

/Declare SFR associated with the ADC /

//sfr ADC_CONTR = 0xBC; //ADC control register

//sfr ADC_RES = 0xBD; //ADC high 8-bit result register

//sfr ADC_LOW2 = 0xBE; //ADC low 2-bit result register

//sfr P1ASF = 0x9D; //P1 secondary function control register

/Define ADC operation const for ADC_CONTR/

#define ADC_POWER 0x80 //ADC power control bit

#define ADC_FLAG 0x10 //ADC complete flag

#define ADC_START 0x08 //ADC start control bit

#define ADC_SPEEDLL 0x00 //420 clocks

#define ADC_SPEEDL 0x20 //280 clocks

#define ADC_SPEEDH 0x40 //140 clocks

#define ADC_SPEEDHH 0x60 //70 clocks

extern void InitADC();

extern BYTE GetADCResult(BYTE ch);

void Delay1(WORD n);

/----------------------------

Get ADC result

----------------------------/

BYTE GetADCResult(BYTE ch)

{

ADC_CONTR = ADC_POWER | ADC_SPEEDLL | ch | ADC_START;

_nop_(); //Must wait before inquiry

_nop_();

_nop_();

_nop_();

while (!(ADC_CONTR & ADC_FLAG));//Wait complete flag

ADC_CONTR &= ~ADC_FLAG; //Close ADC

return ADC_RES; //Return ADC result

}

/----------------------------

Initial ADC sfr

----------------------------/

void InitADC()

{

P1ASF = 0xff; //Open 8 channels ADC function

ADC_RES = 0; //Clear previous result

ADC_CONTR = ADC_POWER | ADC_SPEEDLL;

Delay1(2); //ADC power-on and Delay1

}

/----------------------------

Software Delay1 function

----------------------------/

void Delay1(WORD n)

{

WORD x;

while (n--)

{

x = 5000;

while (x--);

}

}

具体的寄存器,参考PDF文档。这种应用的,仔细看文档就行了

;

;芯片 STC12C5412AD

; 十位A/D转换

; A/D输入端=P10口

;

;

AJMP P10

ORG 33H

P10: NOP

MOV 091H,#01H;---置p10为高阻输入

MOV 092H,#00H

MOV 0C6H,#00H;---结果位清零

MOV 0BEH,#00H

MOV 0C5H,#0E8H;---开始ADC转换

P20: MOV A,#010H;---判断ADC转换完成否

ANL A,0C5H

JZ P20

MOV 0C5H,#00H;结束ADC转换

;

;整理检测到的A/D十位二进制数

MOV A,0C6H

ANL A,#0C0H

SWAP A

CLR C

RRC A

CLR C

RRC A

MOV R6,A

MOV A,0C6H

CLR C

RLC A

CLR C

RLC A

MOV R7,A

MOV A,0BEH

ANL A,#03H

ORL A,R7

MOV R7,A

RET

END

你好!

dispbuf[8]={10,10,10,10,10,0,0,0};

这里面的数字,是用于显示的。

其中的10,将在七段码表中取出第10个代码0x00,显示后将是“暗”,即不显示。

其中的0,将在七段码表中取出第10个代码0x3F,显示后将是“0”。

如有疑问,请追问。

1,什么是ad转换?

a是模拟信号的意思,d是数字信号的意思,ad转换就是模数转换,顾名思义,就是把模拟信号转换成数字信号,例如把电压值转化为数字信号。

2,为什么要ad转换?

单片机(以及其他处理器)只能处理数字信号,当单片机想要获取电路上某一点的电压值时,就得用到ad转换了,如果你直接把单片机的引脚接到电路这个点上,单片机只知道这个点的电压是低电平还是高电平,又怎么能得到他的电压值呢?例如数字式的万用表,它测量电压时,先有一个ad转换电路,把电压值转换成一个数值,然后把这个值送个单片机(当然万用表里的用的处理芯片不是单片机),单片机经过计算处理后,再把这电压值显示到显示到屏幕上。

不过现在有一些比较强的单片机,其内部已经集成了ad转换器,不需要你再外接ad转换芯片。

3,8位16位的ad转换芯片是什么意思?

8位,16位就代表了ad转换芯片的转换分辨率,数字越大,分辨率越高,同时也反映了它的精度,数字越大,精度相对也越高。8位算是最低了,有些单片机里集成的ad转换器一般是10位的。12位和16位的芯片价格就比较贵了。

4,分辨率?

举个简单的例子,8位芯片只能转换最小到001v的电压,而12位的芯片却能转换最小到0001v的电压,如果一个电压为3359v,8位芯片转出来后的数值是335v,12位芯片转换出来后是3359v,精度比8位就高一个档次了。(注:这里数值不是正确的数值,举例用,切勿实际使用)

5,采样?

采样是ad转换的速度性能指标,通俗的说就是每秒里能采样多少次,采样次数越高芯片性能越好。如果对采样不理解,也可以用另一种方式理解,就是一个ad转换芯把电压值转换成数字值这个过程所需要的时间,时间越短越好。

6,精度?

精度是ad芯片的一个重要参数,表示采集到的数据和真实值之间的相差的程度。例如单片机转换出来的结果是03v,而实际可能是031v,这样就相差了001v。这种误差是不可避免无法消除的。这和在第3点中提到的位数有关,位数越高,这样的误差越小。

7,这些知识点在“数字电路基础”一书中有详细解释,说明你数字电路没学好,自己好好加油了。

以上就是关于求AD转换程序全部的内容,包括:求AD转换程序、ad芯片转换程序、求STC12C5A60S2 AD转换C语言程序,解释详细点等相关内容解答,如果想了解更多相关内容,可以关注我们,你们的支持是我们更新的动力!

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

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

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

发表评论

登录后才能评论

评论列表(0条)

保存