仅供参考:
#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语言程序,解释详细点等相关内容解答,如果想了解更多相关内容,可以关注我们,你们的支持是我们更新的动力!
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)