51单片机开发 四通道AD转化电压实验与DA转化波形(正弦、三角、矩形)实验及proteus仿真
文章目录
实验内容
设计一个四通道电压采集系统,所有通道数据通过显示终端显示采集到的模拟数据,同时通过万用表监视被测点电压值,当电压值超过某个值时就用蜂鸣器或扬声器报警。
设计一个电路通过按键或者开关选择相应波形输出,提供三种波形输出:方波、正弦波和三角波,波形频率和幅度可以调整,波形用示波器监视。
51单片机开发 四通道AD转化电压实验与DA转化波形(正弦、三角、矩形)实验及proteus仿真
1.仿真图
2.代码
#include "reg52.h"
#include "absacc.h"
#include <intrins.h>
#include <math.h>
#define PA8255 XBYTE[0xff7c] //0xff7c为82C55PA端口地址
#define PB8255 XBYTE[0xff7d] //0xff7d为82C55PB端口地址
#define PC8255 XBYTE[0xff7e] //0xff7e为82C55PC端口地址
#define COM8255 XBYTE[0xff7f] //0xff7f为82C55控制寄存器地址
#define DAC_PORT P2 //DAC0832连接端口
#define K_SQU 1 // 方波标志
#define K_TRI 2 //三角波标志
#define K_SAW 3 //正弦波标志
typedef unsigned char u8;
typedef unsigned int u16;
typedef unsigned long u32;
sbit rst_8255=P3^5;
sbit START = P1^4;
sbit OE = P1^3;
sbit add_a = P1^2;
sbit add_b = P1^1;
sbit add_c = P1^0;
sbit DAC_CS_WR=P3^0;
sbit K1=P3^1;
sbit K2=P3^2;
sbit K3=P3^3;
sbit Func=P3^4;
u8 code Duanma[]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f,0x77,0x7c,0x39,0x5e,0x79,0x71};/*0123456789abcdef*/
u8 code Weima[] ={0xfe,0xfd,0xfb,0xf7,0xef,0xdf,0xbf,0x7f};/*自左向右*/
u8 TempData[8];
u16 addata=0,addata1=0,addata2=0,addata3=0,addata4=0,i,adcflag=0,dacflag=0;
u8 mode; //模式:
u16 freq; //频率
u8 time; //计次参数
u8 AM; //调幅
u8 PI=3.141592653589793;
void DAC_Init();
void ADC_Init();
void scanKey(void);
void Display(u8 FirstBit,u8 Num);
void Gain(void);
void squ_wave(u8 location);
void tri_wave(u8 location);
void tra_wave(u8 location);
void saw_wave(u8 location);
void delayms(u16 j);
int main(void)
{
while(1)
{
while(Func==1)
{
if(dacflag==0)
{
DAC_Init();
dacflag=1;
}
scanKey();
}
while(Func==0)
{
if(adcflag==0)
{
ADC_Init();
adcflag=1;
}
Gain();
Display(0,8);
}
}
}
void DAC_Init()
{
time=0;
DAC_CS_WR=0;
DAC_PORT=0;
mode=0;
freq=100;
AM=255;
TMOD &= 0xF0;
TMOD |= 0x02;
TL0 = 0x9C;
TH0 = 0x9C;
TF0 = 0;
TR0 = 1;
EA = 1;
ET0 = 1;
}
void ADC_Init(void)
{
rst_8255=1;
delayms(1);
rst_8255=0;
COM8255=0x90;
}
void Display(u8 FirstBit,u8 Num)
{
static u8 i=0;
PB8255=0xff;
PC8255=0x00;
PB8255=Weima[i+FirstBit];
if(i==1||i==5)
{
PC8255=TempData[i]+128;
}
else
PC8255=TempData[i];
//delayms(1);
i++;
if(i==Num)
i=0;
}
void Gain(void)
{
START=0;
add_a=0; //采集第一路信号
add_b=0;
add_c=0;
START=1; //根据时序图启动ADC0808的AD程序
START=0;
OE=1; //转换结果允许输出
addata1=PA8255;
OE=0;
START=0;
add_a=1;
add_b=0;
add_c=0;
START=1;
START=0;
OE=1;
addata2=PA8255;
OE=0;
START=0;
add_a=0;
add_b=1;
add_c=0;
START=1;
START=0;
OE=1;
addata3=PA8255;
OE=0;
START=0;
add_a=1;
add_b=1;
add_c=0;
START=1;
START=0;
OE=1;
addata4=PA8255;
OE=0;
addata=(addata1+addata2+addata3+addata4)*1.96/4;
Display(0,8);
TempData[3]=Duanma[addata%10];
TempData[2]=Duanma[addata/10%10];
TempData[1]=Duanma[addata/100%10];
TempData[0]=Duanma[addata/1000];
}
void scanKey(void)
{
if(K1==0)
{
mode=1;
}
if(K2==0)
{
mode=2;
}
if(K3==0)
{
mode=3;
}
}
void squ_wave(u8 location)
{
if(location<50){
DAC_PORT=AM;
}
else{
DAC_PORT=0x00;
}
}
void tri_wave(u8 location)
{
u8 y;
if(location<50)
y=(50-location)*AM/50;
else
y=(location-50)*AM/50;
DAC_PORT=y;
}
void saw_wave(u8 location)
{
DAC_PORT=location*AM/100;
}
void sine_wave(u8 location)
{
double x=(double)location/50*PI;//
u8 y=(sin(x)*(AM/2)+(AM/2));//
DAC_PORT=y;
}
void Timer0Work() interrupt 1 //中断服务函数
{
switch(mode)
{
case K_SQU:squ_wave((u8)(time*freq/100));break;
case K_TRI:tri_wave((u8)(time*freq/100));break;
case K_SAW:sine_wave((u8)(time*freq/100));break;
}
time++;
if(time>=100)//计数100次
time=0;
}
void delayms(u16 j)
{
u8 i;
for(;j>0;j--)
{
i=250;
while(--i);
i=249;
while(--i);
}
}
总结
大佬们,可以支持一下。谢谢!!!
四通道AD转化电压实验与DA转化波形(正弦、三角、矩形)实验及proteus仿真