如下是atmega8的ad转换:
PC0为模拟电压输入端0-5V,
四位共阴数码管显示0000-1024数值。
*******************************************************/
#include <iom8v.h>
#include <macros.h>
/***********宏定义*************/
#define uchar unsigned char
#define uint unsigned int
#pragma data:code
const table[]={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82, 0xf8,
0x80,0x90,0x88,0x83,0xc6,0x98,0x86,0x8e};
#pragma data:data
//设置数据区回到数据存储区
/***************************************************
宏定义名称:IO端口操作宏定义。
功 能:实现数码管的位选。
***************************************************/
#define SET_WEI1 PORTC|=BIT(1)
#define SET_WEI2 PORTC|=BIT(2)
#define SET_WEI3 PORTC|=BIT(4)
#define SET_WEI4 PORTC|=BIT(5)
#define CLR_WEI1 PORTC&=~BIT(1)
#define CLR_WEI2 PORTC&=~BIT(2)
#define CLR_WEI3 PORTC&=~BIT(4)
#define CLR_WEI4 PORTC&=~BIT(5)
#define CLR_ALL PORTC&=0XC9
/*******************************************
函数名称: IO口初始化程序
功 能: 实现IO初始化
参 数: 无
返 回 值: 无
/********************************************/
void port_init(void)
{
PORTC = 0x00;
DDRC = 0x36; //PC0作为AD的输入
PORTB = 0xFF;
DDRB = 0xFF;
}
/************************************
用 途:adc初始化
target :atmega8
crystal :8M
介 绍:ADC0端口输入
10位精度,最高为5V
入口参数:
出口参数:
*************************************/
void adc_init()
{
ACSR=0x80;//关掉模拟比较器的电源(禁用模拟比较器)
ADMUX=(1<<REFS0);
//ADMUX=7,6参考电源选择,5左对齐选择,3-0输入端口选择
ADCSRA=(1<<ADEN);//这里选择的是连续模式
//ADCSRA=7,adc使能,6,adc开始转换,5,连续转换模式选择
//4,中断标志,3,中断允许,2-0,预分频选择
SFIOR=0x00;//4,adc高速模式选择
}
/*******************************************
函数名称: 设备初始化函数
功 能: 对AVR单片机进行初始化
参 数: 无
返 回 值: 无
/********************************************/
void init_devices(void)
{
MCUCR = 0x00;
GICR = 0x00;
TIMSK = 0x00; //timer interrupt sources
SEI(); //re-enable interrupts
adc_init();
}
/*******************************************
函数名称: 软件延时函数
功 能: 实现软件延时
参 数: ms--延时的毫秒数
返 回 值: 无
/********************************************/
void Delay_ms(uint ms)
{
unsigned int i,j;
for(i=0;i<ms;i++)
for(j=0;j<1141;j++);//1141是在8MHz晶振下,通过软件仿真反复实验得到的数值
}
/*************************************************************
函数名称: 数码管显示函数。
功 能: 实现在某位数码管上显示要显示的数值。
参 数: value--数码管上要显示的值;wei--在哪一位数码管上显示
返 回 值: 无
/************************************************************/
void disp_smg(uchar value,uchar wei)
{
PORTB=value;//给数码管赋值
switch(wei)
{
case 1:SET_WEI1;break;
case 2:SET_WEI2;break;
case 3:SET_WEI3;break;
case 4:SET_WEI4;break;
default:break;
}
Delay_ms(1);//延时2ms
CLR_ALL;//关显示
}
/*************************************************************
函数名称: AD采样函数。
功 能: 实现电压的AD采样。
参 数: 无
返 回 值: addata--AD采样的值。
/************************************************************/
uint mega48_ad(void)
{
uint addata;
ADCSRA = 0x00; //disable ad
ADMUX=0x40;//选择外部参考电压
ACSR=0X80;
ADCSRA = 0xC7;
while((ADCSRA&0x40)==0x40);
addata=ADCL;
addata=addata+ADCH*256;
ADCSRA = 0x00;
return addata;
}
/********************************************
函数名称: 主函数
功 能: 实现AD采样并将结果显示在数码管上。
参 数: 无
返 回 值: 无
********************************************/
void main(void)
{
uint ada,i,ad[4];
port_init();
init_devices();
while(1)
{
ada=mega48_ad(); //读出AD的采样值
for(i=0;i<4;i++)
{
ad[i]=ada%10;
ada=ada/10;
}
for(i=0;i<4;i++) disp_smg(table[ad[i]],4-i); //在四位数码管上显示四位AD采样值
}
}
-----------------------------------------------------------
请教各位大神,如何修改,当串口只有收到特定的代码时,才将adc数值发送至串口? 这应该是一个不错的ad数值采集,能用一个单片机发送查询命令,从而收到多个单片机返送的数值。
|