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]]); } } }
/******************************************* 文件: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); } }}