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条评论)
登录后参与讨论