原创 AVR128学习笔记之ADC转换

2011-2-26 15:09 4321 8 8 分类: MCU/ 嵌入式

AVR128有一个10位的逐次逼近型ADC。ADC与一个8通道的模拟多路复用器连接,能对来自端口F的8路输入电压进行采样。单端电压输入以GND为基准。

代码实现功能:利用ADC0输入端口,将外部电压信号转换,在数码管上面显示,使用的是右对齐(也就是10位的精度,其中左对齐位8位)。显示范围是0--1024.

只要改变ADC多工选择寄存器ADMUX内的低5位MUX4..0的值即可选择不同的输入通道以及是否为差分或者选择运放,具体自己可以查看相关的技术文档。

详细的资料请点击:百度文库链接

代码如下:(编译环境:ICCAVR)内部晶振8M

#include<iom128v.h>
#include<macros.h>

#include"shumaguan.h"
#include"Mydelay.h"

#define uint  unsigned int
#define uchar unsigned char

#define ADC_PORT PORTF
#define ADC_DDR  DDRF

volatile unsigned int adc_rel=0;

/****************************************************************************
函数功能:ADC初始化函数
入口参数:
出口参数:
****************************************************************************/
void adc_init(void)
{
 ADC_DDR &= 0XFE;      //PORTF0设置为输入,即作为ADC0口输入模拟电压
 ADC_PORT &= 0XFE;  //PORTF0设置为输入低电平
 ADCSRA = 0x00;  //关ADC
 ADMUX = 0X00;       //采用Aref作为参考电压,ADC0单端输入,右对齐
 ADCSRA = (1<<ADEN)|(1<<ADSC)|(1<<ADFR)|(1<<ADIE)|(1<<ADPS1);
 //ADEN,启动ADC;ADSC,ADC开始转换;ADIE,ADC中断使能;ADPSx,设置分频因子4;ADRF连续转换
}

void init_devices(void)
{
 CLI(); //disable all interrupts
 HC_595_init();
 adc_init();
 SEI(); //re-enable interrupts
}
 
void main(void)
{
 init_devices();
 while(1)
 {
   Seg7_Led_display(adc_rel);
 }
}

/*函数功能:ADC中断函数
入口参数:
出口参数:
****************************************************************************/
#pragma interrupt_handler adc_isr:22
void adc_isr(void)

  adc_rel=ADC;
}

 

附:

(1):Mydelay.h

#ifndef __MYDELAY_H
#define __MYDELAY_H

void delay_1us(void)                 //1us延时函数
  {
   asm("nop");
  }

void delay_nus(unsigned int n)       //N us延时函数
  {
   unsigned int i=0;
   for (i=0;i<n;i++)
   delay_1us();
  }
 
void delay_1ms(void)                 //1ms延时函数
  {
   unsigned int i;
   for (i=0;i<1140;i++);
  }
 
void delay_nms(unsigned int n)       //N ms延时函数
  {
   unsigned int i=0;
   for (i=0;i<n;i++)
   delay_1ms();
  }

#endif

(2):shumaguan.h

#define OE_PORT PORTC
#define OE_PIN PINC
#define OE_DDR DDRC
#define OE 7

#define Seg7_Bitselect_PORT PORTB
#define Seg7_Bitselect_PIN  PINB
#define Seg7_Bitselect_DDR  DDRB

#define Seg7_Bit0 4
#define Seg7_Bit1 5
#define Seg7_Bit2 6
#define Seg7_Bit3 7

#define dp 7

#define Seg7_Bit0_En()  {Seg7_Bitselect_DDR|=(1<<Seg7_Bit0);Seg7_Bitselect_PORT|=(1<<Seg7_Bit0);}   
#define Seg7_Bit0_Dis() {Seg7_Bitselect_DDR|=(1<<Seg7_Bit0);Seg7_Bitselect_PORT&=~(1<<Seg7_Bit0);}
#define Seg7_Bit1_En()  {Seg7_Bitselect_DDR|=(1<<Seg7_Bit1);Seg7_Bitselect_PORT|=(1<<Seg7_Bit1);}
#define Seg7_Bit1_Dis() {Seg7_Bitselect_DDR|=(1<<Seg7_Bit1);Seg7_Bitselect_PORT&=~(1<<Seg7_Bit1);}
#define Seg7_Bit2_En()  {Seg7_Bitselect_DDR|=(1<<Seg7_Bit2);Seg7_Bitselect_PORT|=(1<<Seg7_Bit2);}
#define Seg7_Bit2_Dis() {Seg7_Bitselect_DDR|=(1<<Seg7_Bit2);Seg7_Bitselect_PORT&=~(1<<Seg7_Bit2);}
#define Seg7_Bit3_En()  {Seg7_Bitselect_DDR|=(1<<Seg7_Bit3);Seg7_Bitselect_PORT|=(1<<Seg7_Bit3);}
#define Seg7_Bit3_Dis() {Seg7_Bitselect_DDR|=(1<<Seg7_Bit3);Seg7_Bitselect_PORT&=~(1<<Seg7_Bit3);}

#define SS 0
#define SCK 1
#define MOSI 2
#define MISO 3

#define SS_H() PORTB|=(1<<SS)
#define SS_L() PORTB&=~(1<<SS)


volatile unsigned int countnum=0;
const unsigned char Seg7_Data[]={0x3F,0x06,0x5B,0x4F,0x66,             //0,1,2,3,4
                                 0x6D,0x7D,0x07,0x7F,0x6F,             //5,6,7,8,9
               0x77,0x7C,0x39,0x5E,0x79,0x71,0x00};              //a,b,c,d,e,f
volatile unsigned char Seg7_Led_Buf[4],point=0,point_pos=0;       //point是小数点标志1代表有小数点point_pos表示小数点位置


/************************************************
文件:spi.c
用途:SPI驱动
************************************************/
/*************************************************************************
** 函数名称: spi_init(void)
** 功能描述: SPI初始化
** 输 入:
** 输出  :
** 全局变量: 无
** 调用模块:
** 说明:
** 注意:
**************************************************************************/
void spi_init(void)
{
   DDRB |= (1<<MOSI)|(1<<SCK)|(1<<SS);//设置MOSI,SCK输出
   SPCR = (1<<SPE)|(1<<MSTR)|(1<<SPR0)|(1<<SPR1);//使能SPI,主机模式
}
/*************************************************************************
** 函数名称: SPI_MasterTransmit(char Data)
** 功能描述: SPI主机发送数据
** 输 入: Data 需要通过SPI传输的数据
** 输出  :
** 全局变量: 无
** 调用模块:
** 说明:
** 注意:
**************************************************************************/
void SPI_MasterTransmit(char Data)
{
   /* 启动数据传输 */
   SPDR = Data;
   /* 等待传输结束 */
   while(!(SPSR & (1<<SPIF)));
}

/*************************************************************************
** 函数名称:HC595初始化
** 功能描述:
** 输 入:
** 输出  :
** 全局变量:
** 调用模块:
** 说明:
** 注意:
**************************************************************************/
void HC_595_init(void)
{
 OE_DDR |= (1<<OE);
 OE_PORT &= (1<<OE);
 PORTB = 0x0F;
 spi_init();
 Seg7_Led_Buf[0]=16;
 Seg7_Led_Buf[1]=16;
 Seg7_Led_Buf[2]=16;
 Seg7_Led_Buf[3]=16;                   
}
/*************************************************************************
** 函数名称:HC595送数据
** 功能描述:
** 输 入:
** 输出  :
** 全局变量:
** 调用模块:
** 说明:
** 注意:
**************************************************************************/
void HC_595_OUT(unsigned char data)
{
   SS_L();
  SPI_MasterTransmit(data);
   SS_H();
}
/*************************************************************************
** 函数名称:HC595刷新显示
** 功能描述:
** 输 入:
** 输出  :
** 全局变量:
** 调用模块:
** 说明:
** 注意:
**************************************************************************/
void Seg7_Led_Update(void)
{
 HC_595_OUT(Seg7_Data[Seg7_Led_Buf[0]]);
 Seg7_Bit0_En();
 delay_nus(60);
 Seg7_Bit0_Dis();
 
 HC_595_OUT(Seg7_Data[Seg7_Led_Buf[1]]);
 if((point==1)&&(point_pos==1))
 HC_595_OUT((Seg7_Data[Seg7_Led_Buf[1]])|(1<<dp));
 Seg7_Bit1_En();
 delay_nus(60);
 Seg7_Bit1_Dis();
 
 HC_595_OUT(Seg7_Data[Seg7_Led_Buf[2]]);
 if((point==1)&&(point_pos==2))
 HC_595_OUT((Seg7_Data[Seg7_Led_Buf[2]])|(1<<dp));
 Seg7_Bit2_En();
 delay_nus(60);
 Seg7_Bit2_Dis();
 
 HC_595_OUT(Seg7_Data[Seg7_Led_Buf[3]]);
 if((point==1)&&(point_pos==3))
 HC_595_OUT((Seg7_Data[Seg7_Led_Buf[3]])|(1<<dp));
 Seg7_Bit3_En();
 delay_nus(60);
 Seg7_Bit3_Dis();
}
/*************************************************************************
** 函数名称:Hc595显示整形数据
** 功能描述:
** 输 入:0~9999
** 输出  :
** 全局变量:
** 调用模块:
** 说明:
** 注意:
**************************************************************************/
void Seg7_Led_display(unsigned int data)
{
 if(data>9999) //错误处理,超出显示范围则全亮
  {
  HC_595_OUT(0xFF);
  Seg7_Bitselect_PORT|=((1<<Seg7_Bit0)|(1<<Seg7_Bit1)|(1<<Seg7_Bit2)|(1<<Seg7_Bit3));
 }
 else if(data>999)
  {
  Seg7_Led_Buf[3]=data/1000;
   Seg7_Led_Buf[2]=(data%1000)/100;
   Seg7_Led_Buf[1]=(data%100)/10;
   Seg7_Led_Buf[0]=data%10;
  Seg7_Led_Update();
 }
 else if(data>99)
  {
  Seg7_Led_Buf[3]=16;                
   Seg7_Led_Buf[2]=(data%1000)/100;
   Seg7_Led_Buf[1]=(data%100)/10;
   Seg7_Led_Buf[0]=data%10;
  Seg7_Led_Update();
 }
 else if(data>9)
  {
  Seg7_Led_Buf[3]=16;
   Seg7_Led_Buf[2]=16;
   Seg7_Led_Buf[1]=(data%100)/10;
   Seg7_Led_Buf[0]=data%10;
  Seg7_Led_Update();
 }
 else
  {
  Seg7_Led_Buf[3]=16;
   Seg7_Led_Buf[2]=16;
   Seg7_Led_Buf[1]=16;
   Seg7_Led_Buf[0]=data%10;
  Seg7_Led_Update();
 }
}
/*************************************************************************
** 函数名称:HC595显示浮点数据
** 功能描述:
** 输 入:
** 输出  :
** 全局变量:
** 调用模块:
** 说明:
** 注意:
**************************************************************************/
void Seg7_Led_float(float data)
{
 unsigned int temp;
 /*
 重要说明:data+=0.00001;其中0.00001为容错值
 解决float数据类型在计算机内部存储的误差问题,可以解决显示问题
 但是会引入新的计算误差,如果精度要求大于0.00001建议更改容错值或者将此处注释掉
 */
 data+=0.00001;
 point=1;
 if(data>999) //错误处理,超出显示范围则全亮
  {
  HC_595_OUT(0xFF);
  Seg7_Bitselect_PORT|=((1<<Seg7_Bit0)|(1<<Seg7_Bit1)|(1<<Seg7_Bit2)|(1<<Seg7_Bit3));
 }
 else if(data>99)
  {
  temp=data*10;
  point_pos=1;
  Seg7_Led_Buf[3]=temp/1000;
   Seg7_Led_Buf[2]=(temp%1000)/100;
   Seg7_Led_Buf[1]=(temp%100)/10;
   Seg7_Led_Buf[0]=temp%10;
  Seg7_Led_Update();
 }
 else if(data>9)
  {
  temp=data*100;
  point_pos=2;
  Seg7_Led_Buf[3]=temp/1000;
   Seg7_Led_Buf[2]=(temp%1000)/100;
   Seg7_Led_Buf[1]=(temp%100)/10;
   Seg7_Led_Buf[0]=temp%10;
  Seg7_Led_Update();
 }
 else
  {
  temp=data*1000;
  point_pos=3;
  Seg7_Led_Buf[3]=temp/1000;
   Seg7_Led_Buf[2]=(temp%1000)/100;
   Seg7_Led_Buf[1]=(temp%100)/10;
   Seg7_Led_Buf[0]=temp%10;
  Seg7_Led_Update();
 }
 point=0;
}

文章评论0条评论)

登录后参与讨论
我要评论
0
8
关闭 站长推荐上一条 /2 下一条