基于AVR单片机的电压电流测量
电压电流测量
摘要:本产品以AVR系列单片机ATMEGA16为控制核心,采用自带的AD
模数转换器,按键控制电压电流测量转换,四位LED数码管显示。
关键词:ATMEGA16,ADC,LED
Abstract:Thisdesign, with the ATMEGA16 of the avr sery
singlechipas the controling core, uses the own analog-digital
converter.A key alternates the voltage and electric current
measurement.What’s more, four-byte Leds display the measurement
Keywords: ATMEGA16, ADC,LEDresult.
2、系统设计
AD转换器将电压电流转化为数字信号,使用单片机与AD进行数据传输,在单片机的内
部进行处理后,在LED或者LCD上进行显示。可设计出一个选择开关,选择是进行电压还是
电流的测量.可测电压电流的范围和精度取决于AD的精度,分辨率越高,精度越高.
-
电压或电流
单片机
显示电路
按键控制
1.2.1 总体框图
二、方案论证
根据本题目要求,我们对本产品各个部分进行设计论证如下:
1、控制器模块方案选择:
方案一:采用凌阳公司生产的SPEC061A单片机。单片机算术运算能力强,
软件编程灵活,自由度大,可用软件编程实现各种算法和逻辑控制功耗小,技术比较成熟,成本较低,I/O口较多容易实现外扩,响应速度完全达到系统要求。
但是根据本题目的实际要求,使用61单片机过于浪费资源,而且增加成本。
方案二:采用传统的8位的51系列单片机作为系统控制器。P89C51RD2单片机是一款具有ISP/IAP功能的单片机,它的片内具有64K字节Flash程序存储器、1K字节数据存储器、3个16位定时/计数器,6个中断、1个全双工串行口从内部构造还是编程方面51系列单片机都相对简单,容易掌握和使用,等资源。
价格也相对低廉。但是使用51单片机的话还需要外界的ADC。
方案三,采用PIC18F4620单片机,PIC18F4620采用哈佛结构,以及RISC指令系统单片机,其具有1KRAM,64K FLASH,丰富的I/O口资源,内置A/D,内置EEPROM,看门狗电路,倍频电路等丰富的外围模块,一个指令周期是四个机器周期,价格比较高,购买不方便,使用不广泛,放弃此方案。运算速度快,完全能够满足我们的系统要求。但由于其不是主流单片机,
面的内容,而且现在市场上ARM比较少见,价格也比较昂贵。
方案五:ATmega16是基于增强的AVRRISC结构的低功耗8位CMOS微控制器。由于其先进的指令集以及单时钟周期指令执行时间,ATmega16的数据吞吐率高达1MIPS/MHz,从而可以缓减系统在功耗和处理速度之间的矛盾。ATMEGA16单片机自带ADC模数转换器,方便使用。AVR系列单片机容易掌握和使用,JTAG等方便容易上手。
经过各种方案论证和取材的方便程度,我们选择了ATMEGA16作为控制核心。
2、电压电流测量模块选择:
方案一:选用外部ADC,如AD0809,AD574等,测量精度和位数等可以选择,分辨率、串行并行可以选择各种芯片。A/D转换器按照输出代码的有效位数分为4位、6位、8位、10位、12位、14位、16位和BCD码输出的3位、4位、5位等多种;按照转换速度可以分为超高速(转换时间≤1ns)、高速(转换时间≤1us)中速(转
换时间≤1ms)、低速(转换时间≤1s)等几种不同转换速度的芯片;为适应系统集成的需要,有些转换器还将多路转换开关、时钟电路、基准电压源、二/十进制译码器和转换电路集成在一个芯片内,超越了单纯的A/D转换功能。
方案二:ATmega16有一个10位的逐次逼近型ADC。ADC与一个8通道的模拟多路复用器连接,能对来自端口A的8路单端输入电压进行采样。单端电压输入以0V(GND) 为基准。器件还支持16路差分电压输入组合。两路差分输入(ADC1、ADC0与ADC3、ADC2)有可编程增益级,在A/D转换前给差分输入电压提供0dB(1x)、20dB(10x)或46dB(200x)的放大级。七路差分模拟输入通道共享一个通用负端(ADC1),而其他任何ADC输入可做为正输入端。如果使用1x或10x增益,可得到8位分辨率。如果使用200x增益,可得到7位分辨率。ADC包括一个采样保持电路,以确保在转换过程中输入到ADC的电压保持恒定。使用方便,功能强大。
经过选择,在精度要求不高的情况下,采用自带的ADC。
3、显示器模块方案选择:方案一:使用液晶显示屏显示键盘输入及计算结果。液晶显示屏(LCD)具有
是编程工作量较大,控制其占用资源较多,而且成本较高。
方案二:采用LED显示,是由发光二极管构成的最为常用的显示器件,数字LED显示器利用7个发光二极管显示数字,另外还有一个圆点发光二极管,用于显示小数点。利用多个数字LED显示器可以显示多位数字,其优点是编程简单,显示数字方便。数码管(LED)对环境因素要求较低,显示明亮,采用BCD编码显示数字。完全能够满足本实验的要求。
因此,经过选择,显示器模块选用方案二。
4、按键选择:
方案一:采用普通按键实现电压电流测量转换,按下即松,但是编程时比较
麻烦。 方案二:采用带锁开关,按下后不自动弹起,除非再次按下。这样编程时比
较简单。所以,经过选择,决定采用带锁开关。
三、各模块单独论证
1、显示模块
(1)静态显示
静态显示的优点是编程容易,管理简单,亮度较高。但是占用口线资源较多。
(2)动态显示
动态显示—就是一位一位地轮流点亮显示器各个位(扫描),对于显示器的每一位来说,每隔一段时间点亮一次。显示器的亮度既与导通电流有关,也与点 调整电流和时间参数,可实现亮度较高较稳定的亮时间和间隔时间的比例有关。
显示。
扫描显示方式,即在某一时刻,只让某一位的位选线处于选通状态,而其它各位的位选线处于关闭状态,同时,段选线上输出相应位要显示字符的字型码,这样同一时刻,4位LED中只有选通的那一位显示出字符,而其它三位则是熄灭的。由于人眼有视觉暂留现象,只要每位显示间隔足够短,则可造成多位同时亮的假象,达到显示的目的。
由于AD电压转化非常快,采用动态显示即可以实现不闪烁。所以显示模块
2、电源部分 采用动态显示。
3.AD 模块ADC 通过逐次逼近的方法将输入的模拟电压转换成一个10位的数字量。
最小值代表入GND,最大值代表AREF引脚上的电压再减去1LSB。通过写ADMUX
寄存器的REFSn位可以把AVCC或内部2.56V 的参考电压连接到AREF引脚。
在AREF上外加电容可以对片内参考电压进行解耦以提高噪声抑制性能。模拟输通道与差分增益可以通过写ADMUX寄存器的MUX 位来选择。任何ADC输入引脚,像GND及固定能隙参考电压,都可以作为ADC的单端输入。ADC输入引脚可选做差分增益放大器的正或负输入。如果选择差分通道,通过选择被选输入信号对的增益因子得到电压差分放大级。然后放大值成为ADC的模拟输入。如果使用单端通道,将绕过增益放大器。通过设置ADCSRA寄存器的ADEN 即可启动ADC。只有当ADEN置位时参考电压及输入通道选择才 生效。ADEN清零时ADC并不耗电,因此建议在进入节能睡眠模式之前关闭ADC。ADC转换结果为10位,存放于ADC数据寄存器ADCH及ADCL中。默认情
况下转换结果为右对齐,但可通过设置ADMUX寄存器的ADLAR变为左对齐。
如果要求转换结果左对齐,且最高只需8位的转换精度,那么只要读取ADCH就足够了。否则要先读ADCL,再读ADCH,以保证数据寄存器中的内容是同一次转换的结果。一旦读出ADCL,ADC对数据寄存器的寻址就被阻止了。也就是说,读取ADCL之后,即使在读ADCH之前又有一次ADC转换结束,数据寄存器的数据也不会更新,从而保证了转换结果不丢失。ADCH被读出后,ADC即可再次访问ADCH及ADCL寄存器。ADC转换结束可以触发中断。即使由于转换发生在读取ADCH与ADCL之间而造成ADC无法访问数据寄存器,并因此丢失了转换数据,中断仍将触发。
ADC基准电压源
ADC的参考电压源(VREF)反映了ADC的转换范围。若单端通道电平超过了VREF,其结果将接近0x3FF。VREF可以是AVCC、内部2.56V基准或外接于AREF引脚的电压。AVCC通过一个无源开关与ADC相连。片内的2.56V参考电压由能隙基准源(VBG)通过内部放大器产生。无论是哪种情况,AREF都直接与ADC 相连,通过在AREF与地之间外加电容可以提高参考电压的抗噪性。VREF可
他的基准源了,因为这会导致片内基准源与外部参考源的短路。如果AREF引
脚没有联接任何外部参考源,用户可以选择AVCC或1.1V作为基准源。参考源改变后的第一次ADC转换结果可能不准确,建议用户不要使用这一次的转换结果。
转化结果
转换结束后(ADIF为高),转换结果被存入ADC结果寄存器(ADCL,ADCH)。
单次转换的结果如下:ADC=VIN*1024/VREF
式中,VIN为被选中引脚的输入电压,VREF为参考电压。0x000代表模拟地电平,0x3FF代表所选参考电压的数值减去1LSB。
如果使用差分通道,结果是:
ADC=(VPOS– VNEG) * GAIN* 512 / VREF
式中,VPOS为输入引脚正电压,VNEG为输入引脚负电压,GAIN为选定的增益因子,且VREF为参考电压。结果用2的补码形式表示,从0x200(-512d)
到0x1FF(+511d)。如果用户希望对结果执行快速极性检测,它充分读结果MSB(ADCH 中ADC9)。如果该位为1,结果为负;该位为0,结果为正。
4.ATMEGA16单片机
输入通道与增益选择
MUX4..0单端输入正差分输入负差分输入增益
00000ADC0
00001 ADC1
00010 ADC2
00011 ADC3 N/A
00100ADC4
00101 ADC5
00110 ADC6
01001 ADC1 ADC0 10x
01010(1) ADC0 ADC0 200x
01011(1) ADC1 ADC0 200x
01100ADC2 ADC2 10x
01101 ADC3 ADC2 10x
01110(1) ADC2 ADC2 200x
01111(1) ADC3 ADC2 200x
10000 ADC0 ADC1 1x 10001 ADC1 ADC1 1x
10010 N/A ADC2 ADC1 1x
10011 ADC3 ADC1 1x
10100 ADC4 ADC11x
10101 ADC5 ADC1 1x
10110 ADC6 ADC1 1x
10111 ADC7ADC1 1x
11000 ADC0 ADC2 1x
11001 ADC1 ADC2 1x
11010ADC2 ADC2 1x
11011 ADC3 ADC2 1x
11100 ADC4 ADC2 1x
11111 0 V (GND)
4.总体电路图
在范例中选用内部2.56V电压基准作Vref,差分通道10倍放大
则单端电压测量范围 02.56V,分辨率2.5mV
差分电压测量范围+/-256mV 分辨率0.5mV
电流分辨率=50uA@10 欧姆电流采样电阻
电流分辨率=500uA@1 欧姆电流采样电阻
程序中需要把实测的基准电压代入常量Vref中,以获得更准确地结果
我手中的样片实测为 2.556V@Vcc=5.0V
2.550V@Vcc=3.3V
本电路仅供参考,没有考虑抗干扰方面的要求
关中断
按键状态
-
Y
=1?
N
主程序初始化
-
数字值转化
为电压数字值转化为电
流
开外部中断
开中断,中断
返回
循环显示
中断处理程序(见右)五、系统测试
2.测试方法
首先是对各个模块进行单个的测试。我们测试的顺序依次为LED显示模块、
电压测量模块、电流测量模块、按键模块。
LED依次对数字、小数点的显示作了测试。
电压测量时使用变阻器测量了电压。
电流测量时使用了个简单的电路。
按键主要是切换电压电流,没有错误。
在测试完各个模块没有错误时,我们把他们进行组合,组成整个系统进行测试。此时虽然有遇到了一些困难,中间过程中误差达到不可以忽略的地步,
经过调整后得到了改善。3.测试结果总结
由于采用内部基准电压源,电压测量的范围为0-2.56v,电流的测量范围为MA级的,大约为0-10MA。
七、总结
本学期实时测量技术实验以电子设计大赛的形式,老师命题,学生可以选择老师的题目也可以自己命题,并且组队操作其他的事情(包括设计总体方案、硬件电路、软件设计、焊接、调试等工作)。趣味性强,同时也可以学到很多东西。
我们认为,在这学期的实验中,在收获知识的同时,还收获了阅历,收获了成熟,在此过程中,我们通过查找大量资料,请教老师,以及不懈的努力,不仅培养了独立思考、动手操作的能力,在各种其它能力上也都有了提高。更重要的是,在实验课上,我们学会了很多学习的方法。而这是日后最实用的,真的是受益匪浅。要面对社会的挑战,只有不断的学习、实践,再学习、再实践。
之所以使用AVR单片机作为我们的执行核心,不仅是因为老师说AVR现在是社会上应用比较多的单片机,也因为想通过使用AVR锻炼自己的C 语言编程能力,养成良好的C语言编程风格。不管怎样,这些都是一种锻炼,一种
是最重要的。
而且,这对于我们的将来也有很大的帮助。以后,不管有多苦,我想我们都能变苦为乐,找寻有趣的事情,发现其中珍贵的事情。就像中国提倡的艰苦奋斗一样,我们都可以在实验结束之后变的更加成熟,会面对需要面对的事情。
与队友的合作更是一件快乐的事情,只有彼此都付出,彼此都努力维护才能将作品做的更加完美。而团队合作也是当今社会最提倡的。曾经听过,MBA之所以最近不受欢迎就是因为欠缺团队合作的精神和技巧。
电压电流测量装置虽然结束了,也留下了很多遗憾,因为由于时间的紧缺和许多课业的繁忙,并没有做到最好,但是,最起码我们没有放弃,它是我们的骄傲!相信以后我们会以更加积极地态度对待我们的学习、对待我们的生活。我们的激情永远不会结束,相反,我们会更加努力,努力的去弥补自己的缺点,发展自己的优点,去充实自己,只有在了解了自己的长短之后,我们会更加珍惜拥有
的,更加努力的去完善它,增进它。只有不断的测试自己,挑战自己,才能拥有更多的成功和快乐!Tous, happiness equals success!快乐至上,享受过程,而不是结果!认真对待每一个实验,珍惜每一分一秒,学到最多的知识和方法,锻炼自己的能力,这个是我们在实时测量技术试验上学到的最重要的东西,也是以后都将受益匪浅的!
对本学期实验的评价
趣味性强,不仅锻炼能力,而且可以学到很多东西,在与老师和同学的交流过程中,互动学习,将知识融会贯通。老师提出的革新非常的好,认为本学期的实验模式非常实用。但是提议可以申请将课程浓缩,在一定时间内只做这个,只有高度的集中才能作出好的东西。时间的紧缺成为一个很大的问题。也希望老师 如果可以让每个人都有动手焊接以及参与可以为我们知道一下以后的发展方向。
其他的各个流程,有专门的知道就更好了。
电压电流测量的遗憾 如果可以制作出多量程的电压电流测量并且使用更高精度的装置就更好了。
八、参考文献
1、潘新民、王燕芳。微型计算机控制技术。电子工业出版社。2003年1 月
2、RichardBarnett,Larry O‘Cull,SarahCox.嵌入式C 编程与ATMELAVR。清华大学出
版社。2003年9 月
3、薛钧义、张彦斌。MCS—51系列单片微型计算机及其应用。西安交通大学出版社。2005
年1月
4、全国大学生电子设计竞赛组委会.全国大学生电子设计竞赛获奖作品汇编
:第 一届~第五届.北京:北京理工大学出版社,2004年8 月
5、
6、
附录1:程序清单
//ICC-AVRapplication builder : 2006-12-1 19:39:10 // Target : M16
//Crystal: 1.0000Mhz
#include<iom16v.h>
#include<macros.h>
typedefunsigned char uchar;
const | uchar | dispcode[]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07, |
0x7f,
0x6f,0x77,0x7c,0x39,0x5e,0x79,0x71,0x3E};//0-f,U
constuchar dispbitcode[]={0xef,0xdf,0xbf,0x7f}; //位选信号uchartable[]={0,0,0,0};//存放数码管的显示数字
//uchar avflag; unsigned int value; float value1;
{ PORTA = 0x00; DDRA = 0x00;
PORTB = 0xFF;
DDRB = 0xFF;
PORTC = 0xFF; //m103 output only
DDRC = 0x00;
PORTD =0xFF;
DDRD = 0xF0;
}
//ADCinitialize
voidadc_init(void)
{
ADCSR= 0x00; //disable adc
if(PIND&0x01)//检测是否有按键控制电压电流选择 {
ADMUX = 0xC2;//|(1<<ADLAR);/ 2.56v 基准电压/select adc input 2
}
else
{
ADMUX=0Xd0;//10倍增益,ADC1-ADC0输入
}
ACSR= 0x80; // 使能adc可用,不用修改
ADCSRA= 0xAB; // ADC使能,连续转换模式,自动触发使能,中断使能,分频因子为2SFIOR=00;
}
//callthis routine to initialize all peripherals void init_devices(void)
{
//stop errant interrupts until set up
CLI(); //disable all interrupts
port_init();
adc_init();
MCUCR = 0x00; GICR TIMSK = 0x00; //timer interrupt sources =0x00;
}
voiddelay1ms()//延时程序,不精确
{
unsigned int i;
for(i=332;i>0;i--);
}
voiddisplay(void)//显示程序,循环扫描五次
{
uchar i,j;
for(j=255;j>0;j--)
{
PORTD=dispbitcode[3];
PORTB=dispcode[table[3]]|0x80;//小数点显示
delay1ms();
for(i=0;i<3;i++)
{
PORTD=dispbitcode[i];
PORTB=dispcode[table[i]];
delay1ms();
}
}
ADCSRA|=(1<<ADIE);//开中断
}
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~主函数voidmain(void)
{
init_devices();//初始化程序的调用
ADCSRA|=(1<<ADSC);//开始转换,扫描几次动态显示电路即开中断,使能AD转换
while(1)
display();
}
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~AD 转换结束中断程序
{ float ohm;//电阻值,有数量级
ADCSRA|= (1<<ADIF);//ADIF 标志清零
ADCSRA&=~(1<<ADIE);//关中断
value=ADCL; //Read 8 low bits first
value|=(int)ADCH << 8; //read 2high bits and shift into top byt
if(PIND&0x01)
{ //value=(value*2.56)/1024;
value=value/4;//电压
table[3]=value/100;
table[2]=value%100/10;
table[1]=value%100%10;
table[0]=0x10;
ADMUX=0xC2;//|(1<<ADLAR);/ 2.56v 片内基准电压/selectadc input 2
}
else //电流测量选择
{
if(value>0x200) //负数要变换,正数不用
{
value|=0xFC00;//变换成16位无符号整数 }
value=value/2;
ohm=(float)(500-value)/value;
value1=50000/ohm;//浮点数计算更加精确
//value*=100;
table[3]=(unsigned int)value1/1000;
table[2]=(unsignedint)value1%1000/100;
table[1]=(unsignedint)value1%1000%100/10;
table[0]=(unsignedint)value1%1000%100%10;//MA 档显示毫安的数值
ADMUX=0Xd0;
//0---10ma
/*(vpos-vneg)=adc*2.56/(gain*512)将VNEG设为零
*/
}
}