Ⅰ 51单片机与AD转换程序
/*
此程序通过对DAC0832操作,实现D/A转换。按INT1键DAC0832输出电压变高,按s3键DAC0832电压变低。
输出接口是"D/A OUT"
*/
#include<reg51.h>
//////////////////////
sbit le1=P1^0;/*ic1 74hc373使能端*/
sbit dac0832_cs=P3^7;
sbit dac0832_wr=P1^1;
sbit int1_k=P3^3;
sbit s3_k=P3^6;
sbit blight=P0^6;
void s_q00();
void s_q01();
void s_q02();
void s_q03();
void s_q04();
void s_q05();
void s_q06();
void s_q07();
void c_q00();
void c_q01();
void c_q02();
void c_q03();
void c_q04();
void c_q05();
void c_q06();
void c_q07();
//void delay1();
void delayms(unsigned int i);
void delay100us() ;
void initi_lcd();
void initi();
void c_rw();
void s_rw();
void c_e();
void s_e();
void c_rs(void);
void s_rs(void);
void display(unsigned int addr,char a);
void out_74ls164(unsigned char i);
unsigned char q1=0;
unsigned char da_out_74ls164=0,pwm1=0;
void d_to_a(unsigned char dat)//DAC0832写函数。
{
out_74ls164(dat);
//c_q14(); /*片选*/
dac0832_cs=0;
//c_q13(); /*写数据*/
//s_q13();
dac0832_wr=0;
dac0832_wr=1;
// s_q14();/*禁止转换*/
dac0832_cs=1;
}
main()
{
unsigned char dat=0;
initi_lcd();
display(0,'o');
display(1,'u');
display(2,'t');
display(3,'p');
display(4,'u');
display(5,'t');
display(6,':');
display(7,0x30+dat/100);display(8,0x30+dat%100/10);display(9,0x30+dat%10);
while(1)
{
if(int1_k==0) {dat++;display(7,0x30+dat/100);display(8,0x30+dat%100/10);display(9,0x30+dat%10);}
if(s3_k==0) {dat--;display(7,0x30+dat/100);display(8,0x30+dat%100/10);display(9,0x30+dat%10);}
blight=1;
d_to_a(dat);
delayms(60);
}
}
void display(unsigned int addr,char a)
{
s_e();
c_rs();
c_rw();
// P0=0x80+i;
out_74ls164(0x80+addr); /*写地址*/
c_e();
delay100us();
s_e();
s_rs();
//P0=a;
out_74ls164(a);/*写数据*/
c_e();
delay100us();
s_e();
}
void delayms(unsigned int i)
{
unsigned int j;
for(;i>0;i--)
for(j=100;j>0;j--);
}
void initi_lcd()
{
delayms(10);
c_rw();
s_e();
c_rs();
// P0=0x01;
out_74ls164(0x01);
c_e();
delayms(5);
s_e();
c_rs();
// P0=0x38;
out_74ls164(0x38);
c_e();
delayms(5);
s_e();
//P0=0x0f;
out_74ls164(0x0f);
c_e();
delayms(5);
s_e();
// P0=0x04;
out_74ls164(0x04);
c_e();
delayms(5);
s_e();
}
void out_74ls164(unsigned char i)
{
unsigned char j,i_tem;
// s_q27();
for(j=0;j<8;j++)
{
i_tem=i<<j;
if(i_tem&0x80)s_q01();/*74ls164数据*/
else c_q01();
c_q00();/*74ls164时钟*/
s_q00();
}
}
void s_rs(){s_q05();}
void c_rs(){c_q05();}
void s_rw(){s_q06();}
void c_rw(){c_q06();}
void s_e(){s_q07();}
void c_e(){c_q07();}
void delay100us() { unsigned int i=2; for(;i>0;i--); }
///////////////////////////////////////////////////////
//////////////////////////////////////////////////
/*74hc373扩展接口函数:s表示置1,c表示置0,q1表示ic1 74hc373 ,
q2表示ic2 74hc373 ,仅接着的数字表示相应输出Q的序号 */
void s_q00(){q1=q1|0x01; P0=q1; le1=1; le1=0; }
void s_q01(){q1=q1|0x02; P0=q1; le1=1; le1=0; }
void s_q02(){q1=q1|0x04; P0=q1; le1=1; le1=0; }
//void s_q03(){q1=q1|0x08; P0=q1; le1=1; le1=0; }
void s_q04(){q1=q1|0x10; P0=q1; le1=1; le1=0; }
void s_q05(){q1=q1|0x20; P0=q1; le1=1; le1=0; }
void s_q06(){q1=q1|0x40; P0=q1; le1=1; le1=0; }
void s_q07(){q1=q1|0x80; P0=q1; le1=1; le1=0; }
void c_q00(){q1=q1&(~0x01); P0=q1; le1=1; le1=0;}
void c_q01(){q1=q1&(~0x02); P0=q1; le1=1; le1=0;}
void c_q02(){q1=q1&(~0x04); P0=q1; le1=1; le1=0;}
//void c_q03(){q1=q1&(~0x08); P0=q1; le1=1; le1=0;}
void c_q04(){q1=q1&(~0x10); P0=q1; le1=1; le1=0;}
void c_q05(){q1=q1&(~0x20); P0=q1; le1=1; le1=0;}
void c_q06(){q1=q1&(~0x40); P0=q1; le1=1; le1=0;}
void c_q07(){q1=q1&(~0x80); P0=q1; le1=1; le1=0;}
一块实验板的例子,DA转换(DAC0832),自己详细分析一下就可以了
Ⅱ 单片机c52 用c语言编写的 要实现ad转换程序
#include <reg52.h>
#include <intrins.h>
#define uchar unsigned char
#define uint unsigned int
sbit CS=P3^0;
sbit CLK=P3^1; //时钟
sbit DIO=P3^2; //ADC0832输出引脚
sbit din=P0^7;
uchar code tab1[]={0xC0,0xF9,0xA4,0xB0,0x99,0x92,0x82,0xF8,0x80,0x90,0x88,0x83,0xA7,0xA1,0x86,0x8E}; //共阳数码表
uchar code tab[4]={0xfe,0xfd,0xfb,0xf7}; //数码管位选表
void delay(uint k)
{
uint i,j;
for(i=0;i<k;i++)
for(j=0;j<121;j++);
}
uint A_D() // A/D转换函数
{
unsigned char i,dat;
CS=0; //片选
CLK=0; //为第1个脉冲作准备
CLK=1; //第1个脉冲
DIO=1; // DI置1,规定的起始信号
_nop_();_nop_();
CLK=0; //第1个脉冲的下降沿
CLK=1; //第2个脉冲
DIO=1; // DI置1, 通道选择信号:1
_nop_();_nop_();
CLK=0; //第2个脉冲下降沿
CLK=0; //第3个脉冲
DIO=1; // DI置0,通道选择信号:0, 选通道0
_nop_();_nop_();
// CLK=0; //第3个脉冲下降沿,转换开始
// _nop_();_nop_();//第3个脉冲后,
// CLK=1;
for(i=0;i<8;i++) //高位在前
{
CLK=1; //第4个脉冲
if(DIO)
dat=(dat<<1)|0x80;//从高位至低位读取 "|"的优先级高于">>"
else
dat=(dat<<1)|0x00;
CLK=0;
}
for(i=0;i<8;i++) //高位在前
{
CLK=1; //第4个脉冲
if(DIO)
dat=(dat>>1)|0x80;//从高位至低位读取 "|"的优先级高于">>"
else
dat=(dat>>1)|0x00;
CLK=0;
}
CS=1;
CLK=1;
return dat;
}
void display(uint k)
{
P2=tab[1];
P0=tab1[k/100];
din=0;
delay(3);
P2=0xff;
P2=tab[2];
P0=tab1[k/10%10];
delay(3);
P2=0xff;
P2=tab[3];
P0=tab1[k%10];
delay(3);
P2=0xff;
}
void main(void) //主函数
{
uint temp;
while(1)
{
temp=A_D()*5.0/256*100; // 根据转换结果求出电压值
display(temp);
}
}
ADC0832程序 板子做出来 能用
Ⅲ pic单片机多路ad转换
我恰好做过一个PIC 4通道A/D,您先看看我的程序 有问题留言
#include <pic.h> //调用头文件,可以去PICC软件下去查找PIC16F873A单片机的头文件
#include <stdio.h> //调用头文件
#include <math.h> //调用头文件
__CONFIG(XT&PROTECT&WDTEN&PWRTEN); //定义配置字,晶振类型:XT,打开开门狗,代码保护
unsigned char count,count1,tunnel,t1s; //0.1s计时,1s计时,通道号,1s时间到标志
unsigned int result[4],s[4]; //转换电压结果、转换时间结果
unsigned char f[4]; //输入端口状态存储表
union{
struct{
unsigned b0:1; //通道1有输入标志
unsigned b1:1; //通道2有输入标志
unsigned b2:1; //通道3有输入标志
unsigned b3:1; //通道4有输入标志
unsigned b4:1; //通道1需要AD采样标志
unsigned b5:1; //通道2需要AD采样标志
unsigned b6:1; //通道3需要AD采样标志
unsigned b7:1; //通道4需要AD采样标志
}one;
unsigned char allbits;
}myflag; //共占一个字节的数据寄存器存储空间的标志位
#define b0 myflag.one.b0 //定义标志b0
#define b1 myflag.one.b1 //定义标志b1
#define b2 myflag.one.b2 //定义标志b2
#define b3 myflag.one.b3 //定义标志b3
#define b4 myflag.one.b4 //定义标志b4
#define b5 myflag.one.b5 //定义标志b5
#define b6 myflag.one.b6 //定义标志b6
#define b7 myflag.one.b7 //定义标志b7
#define in1 RB4 //定义1通道输入口为RB4端口
#define in2 RB5 //定义2通道输入口为RB5端口
#define in3 RB6 //定义3通道输入口为RB6端口
#define in4 RB7 //定义4通道输入口为RB7端口
#define out1 RC0 //定义1通道输出口为RC0端口
#define out2 RC1 //定义2通道输出口为RC1端口
#define out3 RC2 //定义3通道输出口为RC2端口
#define out4 RC3 //定义4通道输出口为RC3端口
//---------------------------------------
//名称: 定时器T0中断初始化函数
//-----------------------------------------
void T0init(void)
{
T0CS=0; //T0工作在定时器方式
PSA=0; //分频器给TMR0
PS0=1; //1:16分频
PS1=1;
PS2=0;
T0IF=0; //清零T0中断标志
T0IE=1; //清除T0中断使能
}
//---------------------------------------
//名称:RB口引脚电平变化中断初始化函数
//-----------------------------------------
void RBinit(void)
{
RBPU=1; //内部弱上拉禁止
RBIF=0; //中断标志清零
RBIE=1; //中断使能
PORTB=PORTB; //锁存旧值,为下次变化做准备
}
//---------------------------------------
//名称:RA口引脚A/D初始化函数
//-----------------------------------------
void ADinit(void)
{
ADCON1=0x00; //设置RA口所有为模拟输入,采取左对齐方式存放结果
ADCON0=0b11000001; //AD采样时钟为内部RC,默认第一次通道为RA0,启用转换模块
ADIE=0; //关闭中断使能禁止
}
//---------------------------------------
//名称: 主初始化函数
//-----------------------------------------
void init(void)
{
unsigned char i;
TRISA=0b00101111; //初始化AN0-AN5为输入
TRISC=0x00; //初始化C口为输出
TRISB=0xFF; //初始化RB0-RB7为输入
PORTC=0b00000000; //初始化输出
count=0; //初始化T0计数器
count1=0; //初始化T0计数器
tunnel=1; //初始化通道号为1
myflag.allbits=0x00; //初始化标志位
for(i=0;i<4;i++) //初始化延时量和输入端口状态
{s[i]=30;
f[i]=0;}
}
//---------------------------------------
//-----------------------------------------
//名称: 中断服务子函数
//-----------------------------------------
void interrupt ISR(void)
{
//全局中断屏蔽
if(RBIF&&RBIE) //RB边沿中断类型判别
{
PORTB=PORTB;
RBIF=0;
if(in1) //判断1通道状态
b0=1;
else
b0=0;
if(in2) //判断2通道状态
b1=1;
else
b1=0;
if(in3) //判断3通道状态
b2=1;
else
b2=0;
if(in4) //判断4通道状态
b3=1;
else
b3=0;
} //RB_int服务子程序1
if(T0IF&&T0IE) //定时器T0中断类型判别
{
TMR0=TMR0+8; //发生一次的时间为250*16=4ms
T0IF=0;
count+=1;
if(count==25) //计数基数25*16*250=0.1s
{
count=0;
count1+=1;
if(count1==5) //计数基数0.1s*5=0.5s
{
count1=0;
t1s=1; //1s时间到标志
}
}
} //Tmr0_int服务子程序3
//全局中断使能
}
//-----------------------------------------
//名称:delay延时
//-----------------------------------------
void delay()
{
unsigned int i;
for(i=0;i<10;i++);//采样延时160us
}
//-----------------------------------------
//-----------------------------------------
//名称:A/D转换选择子程序
//-----------------------------------------
void ADconvert(void)
{
switch(tunnel) //AD通道选择
{
case 1: //1通道AD采样转换
ADCON0=0b11000001; //设置1通道
delay(); //采样延时
#asm
clrf _STATUS ;
bsf _ADCON0,2 ;
btfsc _ADCON0,2 ;
goto $-1 ;
#endasm //结束采样
result[0]=ADRESH; //把结果保存
s[0]=result[0]*120>>8; //把结果转化为时间
if(s[0]<2) //限制最小值1s
s[0]=2;
else if(s[0]>120)
s[0]=120; //限制最大值60s
break; //跳出
case(2): //2通道AD采样转换
ADCON0=0b11001001; //设置2通道
delay(); //采样延时
#asm
clrf _STATUS ;
bsf _ADCON0,2 ;
btfsc _ADCON0,2 ;
goto $-1 ;
#endasm //结束采样
{result[1]=ADRESH;} //把结果保存
s[1]=result[1]*120>>8; //把结果转化为时间
if(s[1]<2) //限制最小值1s
s[1]=2;
else if(s[1]>120)
s[1]=120; //限制最大值60s
break; //跳出
case(3): //3通道AD采样转换
ADCON0=0b11010001; //设置3通道
delay();
#asm
clrf _STATUS ;
bsf _ADCON0,2 ;
btfsc _ADCON0,2 ;
goto $-1 ;
#endasm //结束采样
{result[2]=ADRESH;} //把结果保存
s[2]=result[2]*120>>8; //把结果转化为时间
if(s[2]<2) //限制最小值1s
s[2]=2;
else if(s[2]>120)
s[2]=120; //限制最大值60s
break; //跳出
case(4): //4通道AD采样转换
ADCON0=0b11011001; //设置4通道
delay(); //采样延时
#asm
clrf _STATUS ;
bsf _ADCON0,2 ;
btfsc _ADCON0,2 ;
goto $-1 ;
#endasm //结束采样
{result[3]=ADRESH;} //把结果保存
s[3]=result[3]*120>>8; //把结果转化为时间
if(s[3]<2) //限制最小值1s
s[3]=2;
else if(s[3]>120)
s[3]=120; //限制最大值60s
break; //跳出
default:break; //出错跳出
}
}
//---------------------------------------
//名称:deal通道处理
//-----------------------------------------
void deal(void)
{
unsigned char i;
if(t1s) //判断0.5秒时间是否到
{
asm("nop");
t1s=0; //0.5秒时间标志清零,等待下0.5秒
if(b0) //是第1通道吗
{
if(b4) //是第1通道有变化后的采样吗
{tunnel=1; //赋值AD通道号
ADconvert(); //开始AD转换
b4=0;} //没变化不再采样
if(!(s[0]--)) //延时计时开始
out1=1;} //继电器开始动作
else out1=0;
if(b1) //是第2通道吗
{
if(b5) //是第2通道有变化后的采样吗
{tunnel=2; //赋值AD通道号
ADconvert(); //开始AD转换
b5=0;} //没变化不再采样
if(!(s[1]--)) //延时计时开始
out2=1;} //继电器开始动作
else out2=0;
asm("clrwdt");
if(b2) //是第3通道吗
{
if(b6) //是第3通道有变化后的采样吗
{tunnel=3; //赋值AD通道号
ADconvert(); //开始AD转换
b6=0;} //没变化不再采样
if(!(s[2]--)) //延时计时开始
out3=1;} //继电器开始动作
else out3=0;
if(b3) //是第4通道吗
{
if(b7) //是第4通道有变化后的采样吗
{tunnel=4; //赋值AD通道号
ADconvert(); //开始AD转换
b7=0;} //没变化不再采样
if(!(s[3]--)) //延时计时开始
out4=1;} //继电器开始动作
else out4=0;
}
asm("nop"); //1秒时间没到继续检测
}
//-----------------------------------------
//名称:主函数
//-----------------------------------------
void main()
{
init(); //全局初始化
T0init(); //T0初始化
ADinit(); //A/D初始化
RBinit(); //RB初始化
asm("nop"); //稳定状态
asm("nop");
delay();
delay(); //耗时0.7ms
//-----------------------------------------
{ //开机初始化采样AD
tunnel=1;
ADconvert();
tunnel=2;
ADconvert();
tunnel=3;
ADconvert();
tunnel=4;
ADconvert();
} //开机1次AD,到此耗时2.4ms,这个时间前不要有触发
if(in1) //开机一次状态判断
{b0=1;
f[0]=in1;} //存储开机时1通道状态
if(in2)
{b1=1;
f[1]=in2;} //存储开机时2通道状态
if(in3)
{b2=1;
f[2]=in3;} //存储开机时3通道状态
if(in4)
{ b3=1;
f[3]=in4;} //存储开机时4通道状态
//-----------------------------------------
ei(); //打开全局中断
//-----------------------------------------
while(1) //主循环
{
asm("clrwdt"); //清看门狗
if(b0) //判断1通道状态
{
if(f[0]!=in1)
{f[0]=in1; //存储1通道状态
b4=1;} //1通道是否进行AD标志
} //设定1通道有效标志
else
{
b4=0;
f[0]=in1;} //设定1通道无效标志
if(b1) //判断2通道状态
{
if(f[1]!=in2)
{f[1]=in2; //存储2通道状态
b5=1;} //2通道是否进行AD标志
} //设定2通道有效标志
else
{
b5=0;
f[1]=in2;} //设定2通道无效标志
if(b2) //判断3通道状态
{
if(f[2]!=in3)
{f[2]=in3; //存储3通道状态
b6=1;} //3通道是否进行AD标志
} //设定3通道有效标志
else
{
b6=0;
f[2]=in3;} //设定3通道无效标志
if(b3) //判断4通道状态
{
if(f[3]!=in4)
{f[3]=in4; //存储4通道状态
b7=1;} //4通道是否进行AD标志
} //设定4通道有效标志
else
{
b7=0;
f[3]=in4;} //设定4通道无效标志
deal(); //最大循环时间不超过4ms,看门狗典型值18ms
asm("nop"); //中断检测
}
}
//---------------------------------------
Ⅳ 谁做过单片机和AD转换,多通道的AD,在两个通道该怎么切换并且用数码管显示的
单片机at89s51和ADC0809
1)汇编源程序:
CH EQU 30H
DPCNT EQU 31H
DPBUF EQU 33H
GDATA EQU 32H
ST BIT P3.0
OE BIT P3.1
EOC BIT P3.2
ORG 00H
LJMP START
ORG 0BH
LJMP T0X
ORG 30H
START: MOV CH,#0BCH
MOV DPCNT,#00H
MOV R1,#DPCNT
MOV R7,#5
MOV A,#10
MOV R0,#DPBUF
LOP: MOV @R0,A
INC R0
DJNZ R7,LOP
MOV @R0,#00H
INC R0
MOV @R0,#00H
INC R0
MOV @R0,#00H
MOV TMOD,#01H
MOV TH0,#(65536-4000)/256
MOV TL0,#(65536-4000) MOD 256
SETB TR0
SETB ET0
SETB EA
WT: CLR ST
SETB ST
CLR ST
WAIT: JNB EOC,WAIT
SETB OE
MOV GDATA,P0
CLR OE
MOV A,GDATA
MOV B,#100
DIV AB
MOV 33H,A
MOV A,B
MOV B,#10
DIV AB
MOV 34H,A
MOV 35H,B
SJMP WT
T0X: NOP
MOV TH0,#(65536-4000)/256
MOV TL0,#(65536-4000) MOD 256
MOV DPTR,#DPCD
MOV A,DPCNT
ADD A,#DPBUF
MOV R0,A
MOV A,@R0
MOVC A,@A+DPTR
MOV P1,A
MOV DPTR,#DPBT
MOV A,DPCNT
MOVC A,@A+DPTR
MOV P2,A
INC DPCNT
MOV A,DPCNT
CJNE A,#8,NEXT
MOV DPCNT,#00H
NEXT: RETI
DPCD: DB 3FH,06H,5BH,4FH,66H
DB 6DH,7DH,07H,7FH,6FH,00H
DPBT: DB 0FEH,0FDH,0FBH,0F7H
DB 0EFH,0DFH,0BFH,07FH
END
2)C语言源程序
#include
unsigned char code dispbitcode[]={0xfe,0xfd,0xfb,0xf7,
0xef,0xdf,0xbf,0x7f};
unsigned char code dispcode[]={0x3f,0x06,0x5b,0x4f,0x66,
0x6d,0x7d,0x07,0x7f,0x6f,0x00};
unsigned char dispbuf[8]={10,10,10,10,10,0,0,0};
unsigned char dispcount;
sbit ST="P3"^0;
sbit OE="P3"^1;
sbit EOC="P3"^2;
unsigned char channel="0xbc";//IN3
unsigned char getdata;
void main(void)
{
TMOD=0x01;
TH0=(65536-4000)/256;
TL0=(65536-4000)%256;
TR0=1;
ET0=1;
EA=1;
P3=channel;
while(1)
{
ST=0;
ST=1;
ST=0;
while(EOC==0);
OE=1;//片选
getdata=P0;
OE=0;
dispbuf[2]=getdata/100;
getdata=getdata%10;
dispbuf[1]=getdata/10;
dispbuf[0]=getdata%10;
}
}
void t0(void) interrupt 1 using 0
{
TH0=(65536-4000)/256;
TL0=(65536-4000)%256;
P1=dispcode[dispbuf[dispcount]];
P2=dispbitcode[dispcount];
dispcount++;
if(dispcount==8)
{
dispcount=0;
}
}