求一Mcs51单片机关于采集A/D转换数据的C程序

高分请分析下,求一Mcs51单片机关于采集A/D转换数据的C程序
最新回答
寄信给风

2024-09-17 13:27:49

89C52采集0809八位AD并显示出来的。现在估计没有人用了....
#include<reg52.h>
#include<absacc.h>
#define uchar unsigned char
#define uint unsigned int
#define LCDCOM XBYTE[0x8ffc] //LCD写命令寄存器地址
#define LCDDATA XBYTE[0x8ffd] //LCD写数据寄存器地址
#define LCDSTATUS XBYTE[0x8ffe] //LCD读状态寄存器地址
#define IN2 XBYTE[0x7ffa] //IN2通道地址

sbit ad_busy=P3^2;
sbit bflag=ACC^7;

//函数的声明部分
void delay1(uint x);
void lcd_busy();
void lcd_cmd(uchar lcd_cmd);
void lcd_data(uchar lcd_data);
void lcd_moveto(uchar position);
void init(void);
void ad0809(void);

uchar string[10]={"dianya is:"};
uchar temp[6]={0x00,0x0a,0x00,0x00,0x00,0x0b};
uchar code dis_buf[13]={0x30,0x31,0x32,0x33,0x34,0x35,0x36,0x37,0x38,0x39,0x2e,0x56,0x20};//为0到9的ASCLL码

void delay1(uint x) //延时1ms程序
{
uchar j;
while(x--)
{
for(j=0;j<125;j++)
{;}
}
}

void lcd_busy() //检测lcd忙程序
{
do
{
ACC=LCDSTATUS;
}
while(bflag==1); //当他忙的时候就不停的检测,直到空闲为止
}

void lcd_cmd(uchar lcd_cmd) //写命令函数
{
LCDCOM=lcd_cmd;
lcd_busy();
}

void lcd_data(uchar lcd_data) //写数据函数
{
LCDDATA=lcd_data;
lcd_busy();

}

void lcd_moveto(uchar position) //确定显示位置
{
uchar temp; //为显示位置对应的地址
if (position<16)
temp=(position+0x80-1); //为在第一行
else
temp=((position-16)+0xc0); //为第二行
lcd_cmd(temp);
}

void init(void) //lcd初始化
{
lcd_cmd(0x30); //置功能:1行,5*7字符
lcd_busy();
lcd_cmd(0x30); //置功能:1行,5*7字符
lcd_busy();
lcd_cmd(0x30); //置功能:1行,5*7字符
lcd_busy();
lcd_cmd(0x38); //置功能:2行,5*7字符
lcd_busy();
lcd_cmd(0x06); //置输入模式:地址增量,显示屏不移动
lcd_busy();
lcd_cmd(0x0c); //置显示开,不显示光标,光标不闪烁
lcd_busy();
lcd_cmd(0x01); //清显示
lcd_busy();
}

void ad0809(void)
{
uchar i;
uint a=0;
IN2=0;
i=i;
i=i;
while(ad_busy==0);
a=IN2;
a=a*200/255;
a=a*25;
temp[0]=a/1000;
temp[2]=a%1000/100;
temp[3]=a%100/10;
temp[4]=a%10;

}

void main(void)
{
uchar i,j;
P2=0xff;
P1=0xff;
P0=0xff;
delay1(20);
init();
while(1)
{
ad0809();
lcd_moveto(1);
for(j=0;j<10;j++)
{
lcd_data(string[j]);
}
lcd_moveto(16);
for(i=0;i<6;i++)
{
lcd_data(dis_buf[temp[i]]);
}

}

}
曾言河山

2024-09-17 01:13:04

/*******************************************
文件:MEGA16_AD.C
环境:编译为ICC AVR6.25A,仿真为AVR Studio4.10
硬件:ATMEGA16芯片
日期:2006年12月10日
功能:驱动MEGA16片上自带的AD转换器
备注:参考《AVR系列单片机C语言编程与应用实例》(清华大学出版社)
/******************************************/
#include <iom16v.h> //包含型号头文件
#include <macros.h> //包含"位"操作头文件
#include <stdio.h> //标准输入输出头文件
//#include <AVR_PQ1A.h> //包含自定义常量头文件
//#include "SMG.C" //包含数码管显示函数
#define uchar unsigned char
#define uint unsigned int
#define BITLK PA4 //数码管位选锁存器控制端
#define SEGLK PA3 //数码管段选锁存器控制端
#define LEDLK PA2 //LED锁存器控制端

#pragma data:code
const SEGMENT[16]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d, 0x07,
0x7f,0x6f,0x77,0x7c,0x39,0x5e,0x79,0x71};//将BCD码转换成数码管扫描码的数组

/*******************************************
函数名称: Delayms
功 能: 延时指定毫秒(8M晶振)
参 数: MS--延时的毫秒数
返回值 : 无
/********************************************/
void Delayms(uint MS)
{
uint i,j;
for( i=0;i<MS;i++)
for(j=0;j<1141;j++); //1141是在8MHz晶振下,通过软件仿真反复实验得到的数值
}
/*******************************************
函数名称: Delayus
功 能: 延时指定微秒(8M晶振)
参 数: US--延时的微秒数(大约,不是很精确,MS越大越准确)
返回值 : 无
/********************************************/
void Delayus(uint US)
{
uint i;
US=US*5/4; //5/4是在8MHz晶振下,通过软件仿真反复实验得到的数值
for( i=0;i<US;i++);
}

/*******************************************
函数名称: Board_init
功 能: 初始化实验板,关闭全部功能
参 数: 无
返回值 : 无
/********************************************/
void Board_init(void)
{
DDRA=0xFF; //将四个IO口全部配置为输出
DDRB=0xFF;
DDRC=0xFF;
DDRD=0xFF;

SPCR=0x00; //还原SPI口,使其为正常端口

PORTA|=BIT(PA6);//(BEEP)关闭蜂鸣器
PORTC&=~BIT(PC6); //(RELAY)初始化继电器为常闭连接状态
PORTA&=~BIT(PA1); //关闭SPI总线DA
PORTB=0xFF; //关闭LED
PORTA|=BIT(LEDLK); //锁存数据,使LED熄灭
Delayus(5);
PORTA&=~BIT(LEDLK);

PORTB=0x00; //输出段选
PORTA|=BIT(SEGLK);
Delayus(50);
PORTA&=~BIT(SEGLK);

PORTB=0xFF; //输出位选
PORTA|=BIT(BITLK);
Delayus(50);
PORTA&=~BIT(BITLK);

PORTD=0xFF;
PORTA|=BIT(PA7);
Delayus(50);
PORTA&=~BIT(PA7);

}

/*******************************************
函数名称: One_smg_display
功 能: 指定的数码管显示指定的内容
参 数: data--显示的内容(0-15)
number--指定的数码管(1-6)
返回值 : 无
/********************************************/
void One_smg_display(uchar data,uchar number)
{
PORTB|=0x3F; //输出位选
PORTA|=BIT(BITLK); //更新位选
Delayus(50); //调整时序
PORTA&=~BIT(BITLK); //锁存位选

PORTB=SEGMENT[data]; //输出段选
PORTA|=BIT(SEGLK); //更新段选
Delayus(50); //调整时序
PORTA&=~BIT(SEGLK); //锁存段选

number=~BIT(number-1); //调整位选(指定时是1~6,而操作的时候是0~5)
PORTB=number; //输出位选
PORTA|=BIT(BITLK); //更新位选
Delayus(50); //调整时序
PORTA&=~BIT(BITLK); //锁存位选
}

/*******************************************
函数名称: Mega16_ad
功 能: 对指定的通道进行模数转换
参 数: chl--指定的通道(本开发板只用了通道0)
返回值 : addata--10位数据输出
/********************************************/
uint Mega16_ad(uchar chl)
{
uint addata;
DDRA&=~(BIT(PA0)|BIT(PA1)); //转换口设置为输入、无上拉
PORTA&=~(BIT(PA0)|BIT(PA1));
ADMUX=0; //采用外部参考电压,输出数据右对齐
ADMUX|=chl; //设置指定的通道
ADCSR=0x80; //采用单次转换,查询模式,2分频
ADCSR|=BIT(ADSC); //启动转换
while(!(ADCSR&(BIT(ADIF)))); //等待转换结束
addata=ADCL; //读取低8位数据
addata+=ADCH*256; //读取高2位数据
return addata; //返回10位数据
}
/*******************************************
函数名称: Num_BCD
功 能: 将一个字节的整数转换成三位BCD码
参 数: num--需要转换的整数
返回值 : chr--三位BCD码数组指针
/********************************************/
uchar* Num_BCD(uchar num)
{
uchar i,chr[3];
uchar *rept;
rept=&(chr[0]); //返回指针指向BCD码数组
for(i=0;i<3;i++)
{
chr[2-i]=num%10; //对10取余数(其实是求模,但是对于正数,取余与求模是相等的)
num/=10; //除以10,为取出下一位做准备
}
return rept; //返回指针
}
/*******************************************
函数名称: main
功 能: 驱动MEGA16的AD,并在数码管上显示采集值
参 数: 无
返回值 : 无
/********************************************/
void main(void)
{
uchar *adpt; //定义一个接受返回指针的指针变量
uchar i,ad0[3];
Board_init( ); //初始化开发板
while(1)
{
adpt=Num_BCD(Mega16_ad(0)/4); //启动AD转换通道0,同时将数值转换成BCD码
for(i=0;i<3;i++) //将转换后的BCD码存入显示数组
{
ad0[i]=*(adpt+i);
}
for(i=0;i<3;i++) //显示转换的数值
{
One_smg_display(ad0[i],i+1);
Delayms(2);
}
}
}