收藏 分销(赏)

正弦电压信号的产生与有效值测量.doc

上传人:仙人****88 文档编号:9313286 上传时间:2025-03-21 格式:DOC 页数:15 大小:333.50KB 下载积分:10 金币
下载 相关 举报
正弦电压信号的产生与有效值测量.doc_第1页
第1页 / 共15页
正弦电压信号的产生与有效值测量.doc_第2页
第2页 / 共15页


点击查看更多>>
资源描述
第四届电子设计竞赛复试实验报告 正弦电压信号的产生与有效值测量 ********************************************************************* 复试题目: 设计一个频率为1000Hz的正弦波信号发生器,输出幅值为1V左右。用单片机搭建一个系统,精确地测量该信号的有效值。并通过串口送到PC机中,通过串口调试助手软件显示该有效值。 题目要求: 1、设计一个1000Hz的正弦波振荡器,输出幅度转换为1V。 2、用单片机自带10位AD作为模数转换芯片,不允许扩展其它AD。 3、串口以9.6K波特率向PC机传输数据,在串行调试助手中,以10进制格式显示该正弦波的有效值。 ******************************************************************** ******************************************************************** 摘要:通过一RC振荡电路,产生1KHz的正弦波,然后经过峰值检波电路,得到其峰值送入Atmega16单片机,由其内部自带ADC处理,并在软件中得到其有效值,经串口发给PC机,并在串口调试助手上显示电压有效值。 关键字:峰值检波 有效值 ADC 串口 ********************************************************************* ********************************************************************* *******************************论文正文****************************** ********************************************************************* 一、正弦波发生电路 正弦波发生电路需要四部分: 放大电路:保证电路能够有从起振到动态平衡的过程,使电路获得一定幅值的输出量,实现能量的控制。 选频网络:确定电路的振荡频率,使电路产生单一频率的振荡,即保证电路产生正弦波振荡。 正反馈网络:引入正反馈,作用是使输入信号等于反馈信号。 稳幅环节:也就是非线性环节,作用是使输出信号幅值稳定。 在电路中,可将选频网络和正反馈网络“合二为一”;而且,一般电路中也没有另加稳幅环节,而是依靠运放等的非线性起到稳幅作用。 振荡电路可以有以下三种方案: 方案一:RC桥式正弦波振荡电路 实用的RC正弦波振荡电路有多种多样,我们选择了最典型的RC桥式正弦波振荡电路。此方法简单实用,容易选择器件和电路的调试。它适用于低频振荡,一般用于生产1Hz~1MHz的低频信号。易于起振,成本低廉。我们考虑到题目的要求,所以采用了此方法。 方案二:LC并联谐振回路 采用LC谐振回路作为选频网络的振荡电路称为LC振荡电路,它主要用来生产高频正弦振荡信号,一般在1MHz以上。根据反馈形式的不同,LC振荡电路可分为变压器反馈式和三点式振荡电路。它产生的是高频信号,我们不予考虑。 方案三:石英晶体正弦波振荡电路 当晶片产生振动时,机械振动的惯性等效为电感。考虑题目要求,我们在这里就不讨论了。 综上所述,我们的振荡电路选择了RC桥式正弦波振荡电路。 RC桥式正弦波振荡电路: 本电路中,C1、C2、R3、R4组成选频网络和正反馈网络,正弦波振荡频率1/(2*PI*R*C),33K电阻和4700pF电容均为标准值。振荡出的峰值由VCC的不同而不同,然后靠R5和R6两者适当的分压来得到1V的1000Hz的正弦信号。R1和(R2+R7)组成放大电路,放大倍 数Au=1+(R2+R7)/R1,通过调节R7,可以满足振荡电路放大要求。 二、信号处理电路 要得到正弦信号的有效值可以有以下三种方案: 方案一:得到其峰值,由单片机对其进行处理,即可得到其有效值: 方案二:对正弦波进行整流、滤波处理,使其变成直流,送入单片机自带的A/D进行处理,得到其有效值。由于本题目中的信号幅值较小,仅为1V,因此不能用普通的整流桥电路。但整流后的的直流与有效值的关系难以确定。 方案三:直接把正弦信号送入单片机进行处理。本题目中信号为1KHz,一个周期内采128个点,则AD采样速率须达到128K,单片机内部AD速度达不到。 综上所述,采用峰值检波电路。 峰值检波电路: 如图所示,Ui为1KHz的1V正弦波电压信号输入。电路原理如下: 输出初始值为0,当待测信号幅度高于0时,前级的运放输出高(相当于比较器),二极管导通。后级运放相当于跟随器,输出跟随输入的增大,同时电容充电。当待测信号幅度大于输出时,二极管导通,输出跟随输入,电路工作在“跟随状态”。当待测信号幅度小于输出时,二极管截止,但由于电容之前充电,存储的能量是之前最大幅度时的,因此后级跟随器依然保持之前的最大幅度,电路工作在“保持状态”。 实际中要注意的问题: 1、由于二极管导通电压的存在,最后的峰值要加上导通电压才准确; 2、运算放大器的带宽决定了输入信号的最大频率; 3、由于电容在此处起电能储存的作用,因此要求电容贮能好,简易使用CBB电容,而不应采用像电解电容之类漏电较大的,或者至少采用瓷片电容等。 4、要在外反馈环加电阻R1,否则有时候会产生问题。 5、为了能够进行放电,故并入电阻R2,但选值时要慎重,权衡时间常数。 三、单片机电路 本单片机系统采用外部晶振,使用ISP下载方式,配有具有上电复位和手动复位的复们电路。一般来说,微处理器的电源接入处都加一滤波电容以去除干扰。由于单片机所用为TTL电平,而PC机为RS232电平,因些需用一SP232(或MAX232)电平转换芯片将mega16的串口与PC机的串口相连。 四、软件编程处理 1、Atmega16内部ADC特点: 10位精度;0.5 LSB的非线性度;±2 LSB的绝对精度;65 - 260 µs的转换时间;最高分辨率时采样率高达15 kSPS;8路复用的单端输入通道;7路差分输入通道;2路可选增益为10x与200x的差分输入通道;可选的左对齐ADC读数;0 - VCC的ADC输入电压范围;可选的2.56V ADC参考电压;连续转换或单次转换模式;通过自动触发中断源启动ADC转换;ADC转换结束中断;基于睡眠模式的噪声抑制器。 2、由于本次处理数据为峰值为1V的电压信号,故可考虑使用ADC内部基准,但有一点要注意,为了增加内部VREF的稳定性,就在32管脚VREF处接一电容,如单片机电路图。 以下是采用ADC0通道进行A/D转换的功能函数: unsigned int mega16_ad() { unsigned int addata; DDRA&=~BIT(PA0);//设PA0口为输入 PORTA&=~BIT(PA0);//不带上拉 ADMUX=0XC0;//使用片内基准电压源,右对齐,选用ADC0通道 ADCSRA=0X80;// ADCSRA|=BIT(ADSC);//启动AD while(!(ADCSRA&(BIT(ADIF))));//等待AD转换结束 //读数据寄存器的值 addata=ADCL; addata=addata+ADCH*256;//0000 00 00 0000 0000 return addata; } 3、串口发送有两种方式,一种是轮询,一种是中断;考虑到本题目的实际情况和实时性的要求,可采用轮询发送,每隔1秒单片机向PC机发一次数据。串口初始化的程序可以使用用ICCAVR开发环境自带的编程向导完成。 4、考虑到题目对实时性要求不强,因此可以每隔1秒单片机向PC机发一次数据;可以采取两种方案:1)在程序中加1000ms的延时函数,但这样占用太多的CPU资源;2)在程序中,采用单片机的定时器1进行数据发送的控制,这样虽然占用中断资源,但不影响CPU的工作,程序中我们采用此方案。 5、程序流程大致辞如下:单片机ADC接收外部电压信号并进行处理,为了更加精确将多个数据进行平均,当到1秒时产生定时器中断,在Timer1中断服务程序里将ADC处理得到的数据能过串口发送程序发送。具体程序详见附录。 五、误差分析 1、正弦波信号振荡频率和幅值 (1)本电路中正弦波信号频率由公式:1/(2*PI*R*C)决定,电阻电容本身的不准确性将会使振荡频率有误差,但考虑到本题目对精度的要求,频率误差可以不予考虑。 (2)由于振荡电路产生的幅值与运算放大器所加的电源电压有关(运放电源为±5V或±12V,故振荡出的正弦波幅值肯定大于1V,所以应该降压),因此我们用一简单而实用的电阻分压电路对其进行处理得到1V的正弦波。在实际电路中,图一中的R5为1KΩ电阻,R6为1KΩ的滑线变阻器。 2、在峰值检波电路中,二极管会造成一定的电压损耗,这一点可以在软件编程时进行补偿;而在硬件中,也加入了R1反馈回路以减小误差。 3、如图二中,R2和C1构成一放电回路,电路中R2=10KΩ,C1=10µF,其时间常数τ=R2*C1=0.1S。 4、由于检波电路所得电压仍有一定的脉动,因此在软件中进行了多次采样,求平均值以减小波动的思想。由前所述,内部ADC的转换时间为65 - 260 µs, 而所采信号是1KHz的正弦信号进行峰值检波得到了,脉动的周期也应为1KHz,即周期为1ms,我们可以采100次后求期平均(100次连续转换时间为6.5ms-26ms),得到较为稳定的输出,然后再由串口发送。 5、实际电路中,图二中的C1用的是10uF的电解电容,电解电容泄露较大,会给峰值检波结果带来影响。 六、方案的改进 电路如图所示: 我们在前级运放的输出端加一个二极管,与运放的负输入端相连, 1、由于A2是跟随器,正负两个输入端电位是相等的,Rf等于把被充在C1上的电压反馈回了A1的负输入端,跟Ui做比较。 2、当Ui过了峰值,低于C1电压时,D2导通让A1成了跟随器。没有D2的话 A1就成了纯粹的比较器,当Ui低于峰值时输出负电压,给D1造成很大的反压,而D1会在反压下增加漏电流,使得C1的峰值保持性能下降。 3、D1截止时(Ui不一定是负,只是低于峰值而已)C1上的电荷因无处释放,峰值电压将被保持,通过跟随器A2对外输出。所谓“减小D1的非线性误差”想必是相对于把Rf从A1输出引入的做法而言的,这时C1上的电压值比Ui少了D1的正向压降,而且这个压降是非线性的。如果不接D2,也就是A1开环后,当Ui低于峰值时A1输出为负饱和,一则给D1造成很大的反压造成漏电流,对C1保持峰值不利,二则当Ui再度上升至峰值时运算退出饱和状态需有个恢复时间,动作上会产生瞬间脱节。 七、测试数据分析 我们首先对峰值进行了AD采样测试, 实际峰值(V) 0.82 0.90 1.01 1.10 1.22 串口显示(V) 0.71 0.81 0.92 0.99 1.12 差值(V) 0.11 0.09 0.09 0.11 0.10 由上表可以看出,AD采到的峰值比实际峰值小0.1V左右,因此在最终我们编写程序计算有效值时人为的对峰值加了0.1进行了软件修订,以使结果更加准确。 【参考文献】 [1]Atmel Corp.Atmega16 Data Book. [2]童诗白、华成英.模拟电子技术基础(第三版).北京:高等教育出版社,2001 [3]马潮.高档8位单片机Atmega128原理与开发应用指南(上).北京:北京航空航天大学出版社,2004 [4]百度搜索引擎: 【附:原程序】 //ICC-AVR application builder : 2009-5-26 9:52:27 // Target : M16 // Crystal: 11.059Mhz #include <iom16v.h> #include <macros.h> #include <math.h> unsigned char table[]="0123456789"; float adc0;//保存有效值 void delay_1ms(void) { unsigned int i; for (i=0;i<1580;i++);//143*crystal-2 } void delay(unsigned int n) { unsigned int i=0; for (i=0;i<n;i++) delay_1ms(); } void port_init(void) { PORTA = 0x00; DDRA = 0x00; PORTB = 0x00; DDRB = 0x00; PORTC = 0x00; //m103 output only DDRC = 0x00; PORTD = 0x00; DDRD = 0x03; } //UART0 initialize // desired baud rate: 9600 // actual: baud rate:9600 (0.0%) // char size: 8 bit // parity: Disabled void uart0_init(void) { UCSRB = 0x00; //disable while setting baud rate UCSRA = 0x00; UCSRC = BIT(URSEL) | 0x06; UBRRL = 0x47; //set baud rate lo UBRRH = 0x00; //set baud rate hi UCSRB = 0x18; } void uart_sendB(unsigned char data)//发送数据程序 { while(!(UCSRA&(BIT(UDRE)))) ;//查询寄存器是否为空 UDR=data; while(!(UCSRA&(BIT(TXC))));//查询发送是否结束 UCSRA|=BIT(TXC);//清零 } unsigned int mega16_ad() { unsigned int addata; DDRA&=~BIT(PA0);//设PA0口为输入 PORTA&=~BIT(PA0);//不带上拉 ADMUX=0XC0;//使用片内基准电压源,右对齐,选用ADC0通道0100 0000 ADCSRA=0X80;// ADCSRA|=BIT(ADSC);//启动AD while(!(ADCSRA&(BIT(ADIF))));//等待AD转换结束 //读数据寄存器的值 addata=ADCL; addata=addata+ADCH*256;//0000 00 00 0000 0000 return addata; } //TIMER1 initialize - prescale:256 // WGM: 0) Normal, TOP=0xFFFF // desired value: 1Hz // actual value: 1.000Hz (0.0%) void timer1_init(void) { TCCR1B = 0x00; //stop TCNT1H = 0x57; //setup TCNT1L = 0x41; OCR1AH = 0xA8; OCR1AL = 0xBF; OCR1BH = 0xA8; OCR1BL = 0xBF; ICR1H = 0xA8; ICR1L = 0xBF; TCCR1A = 0x00; TCCR1B = 0x04; //start Timer } #pragma interrupt_handler timer1_ovf_isr:9 void timer1_ovf_isr(void) { unsigned int adc[5],i,k1,k2,k3; //TIMER1 has overflowed TCNT1H = 0x57; //reload counter high value TCNT1L = 0x41; //reload counter low value //发送实际的电压 k1=(int)adc0; adc[0]=table[k1]; adc[1]='.'; k2=(int)((adc0-k1)*10); adc[2]=table[k2]; k3=(int)((adc0-k1-k2*0.1)*100); adc[3]=table[k3]; adc[4]='V'; for(i=0;i<5;i++) uart_sendB(adc[i]); uart_sendB(0x0D); uart_sendB(0x0A); //结尾发送回车换行 } //call this routine to initialize all peripherals void init_devices(void) { //stop errant interrupts until set up CLI(); //disable all interrupts port_init(); timer1_init(); uart0_init(); MCUCR = 0x00; GICR = 0x00; TIMSK = 0x04; //timer interrupt sources SEI(); //re-enable interrupts //all peripherals are now initialized } // void main(void) { unsigned char i,k1,k2,k3,ad; float adc1[100],sum=0; init_devices(); //insert your functional code here... while(1) { for(i=0;i<100;i++) { ad=mega16_ad();//读取ADC0的电压 adc1[i]=ad*2.56/1024;//得到峰值 sum+=adc1[i];//累加100次的峰值,以备在后面求平均 } adc0=(sum/100+0.1)/sqrt(2);//对结果进行修正,并得到有效值 sum=0; } }
展开阅读全文

开通  VIP会员、SVIP会员  优惠大
下载10份以上建议开通VIP会员
下载20份以上建议开通SVIP会员


开通VIP      成为共赢上传

当前位置:首页 > 教育专区 > 小学其他

移动网页_全站_页脚广告1

关于我们      便捷服务       自信AI       AI导航        抽奖活动

©2010-2026 宁波自信网络信息技术有限公司  版权所有

客服电话:0574-28810668  投诉电话:18658249818

gongan.png浙公网安备33021202000488号   

icp.png浙ICP备2021020529号-1  |  浙B2-20240490  

关注我们 :微信公众号    抖音    微博    LOFTER 

客服