分享

“双核”示波器的硬件描述与程序设计

 共同成长888 2015-04-20

“双核”示波器的硬件描述与程序设计

作者 魏坤 来源 《无线电》杂志 

通过我的“蛊惑”,想必大家都想自制一台示波器玩玩,那就继续跟着我走吧!所有的电子设备都离不开硬件,首先让我来对它的硬件结构进行一下简述:总体电路的系统框图见图1,前面已讲过,为了提高性能,本电路采用“双核”结构,两片AVR单片机协同工作,MCU1用于控制和频率测量,MCU2用于数据处理和显示控制,两片单片机采用SPI总线通信。信号从探头输入,进入程控放大(衰减)电路进行放大(衰减),再对被放大(衰减)的信号进行电平调整后送入高速AD转换器对信号进行采样,采样所得的数据存入FIFO存储器中,当FIFO存满后通知MCU2,MCU2从FIFO存储器中读出数据进行处理,将波形显示在LCD模块上。时钟电路为高速AD转换器和FIFO存储器提供从600Hz~60MHz的8种不同的频率信号作为不同水平扫速时的采样时钟频率。从程控放大器输出的信号一路送入AD转换器,另一路送入整形电路对输入信号进行整形,作为测频率的待测信号送入MCU1的16位计数器外部触发引脚T1(PD5),进行频率测量,程控放大器的放大(衰减)倍数和时钟电路的输出频率均由MCU1控制。MCU1将被测信号的频率、程控放大器的放大倍数和时钟电路的输出频率等数据通过SPI总线发送给MCU2,MCU2以这些数据作为频率、水平扫速、灵敏度和峰峰值计算、显示的依据。

“双核”示波器的硬件描述与程序设计

下面就各个模块电路做一简单介绍。

1.程控放大电路和电源电路

将程控放大电路与电源电路放在一起讲,是因为他们不仅有着密切的联系,而且还是做在一块电路板上的。

程控放大器的作用是对输入信号进行衰减或放大调整,使输出信号电压在AD转换器输入电压要求范围内,达到最好的测量与观察效果,所以程控放大器电路在规定带宽内的增益一定要平坦,故对运算放大器的要求比较高,在本电路中我选用的是NS公司生产的高速运算放大器LM6172 双运放,带宽为100MHz,转换速率3000V/μs,每通道消耗电流2.3mA,输出电流可达50mA,完全满足本电路的要求,选择该芯片的另一个原因是价格,邮购价格为8元一片,相比ADI、MAX等公司几十元一片的高速运放芯片来说算是很廉价了,电源采用正、负双电源供电,由于整个电路总的电源输入为单8V,所以专门用一片DC/DC电路MC34063为其构成了负压转换器,再经稳压得到-5V电压,+5V通过对输入电压稳压得到。

程控放大器电路如图2所示,被测信号从BNC插孔输入,K0继电器决定输入耦合方式,K0吸合为直流耦合方式,K0断开为交流耦合方式。信号通过交、直流耦合选择开关后被送入由R3~R5和C2~C4组成的 ×0.5/×0.05的衰减电路,衰减倍数由K1控制,当K1未吸合时接在“3”端,对应的衰减倍数为(R 4+R 5)/(R 3+R 4+R 5)=0.5,当K1吸合时接在“1”端,对应的衰减倍数为R5/(R3+R4+R5)=0.05,C2、C3对高频信号进行补偿。经过衰减的信号进入由高速运算放大器U1A组成的缓冲器缓冲,然后被送入由U1B组成的×-0.8/×-2/×-4的反相放大电路,放大倍数由K2和K3控制,当K2、K3均未吸合时对应的放大倍数为-(R9+R10)/R7=-2,当K2吸合K3未吸合对应的放大倍数为-R 9/R7=-0.8,当K3吸合则不用考虑K2的情况,但为降低功耗使K2断开,此时对应的放大倍数为-R 8/R 7=-4。输出信号又通过K4选择是否经由U2A组成的同相放大器放大,当K4未吸合,则不经过同相放大,当K4吸合,则信号被放大 (R 11+R 12)/R 11=10倍,最后信号被送入由U2B组成的放大倍数为-1倍的反相放大器来消掉由第一级反相放大器所带来的负号,与此同时U3A送来的反相基线电压由 U2B反相后作为AD转换器的输入中点电压被叠加在被测信号上送入AD转换器,因为ADS830E的模拟输入电压范围是1.5~3.5V,输入中点电压为 2.5V,所以基线电压应为2.5V。调节可变电位器RP1将调整基线电压的值,从而调整基线的位置。程控放大电路的放大倍数以及垂直电压灵敏度与 K1~K4的关系见表1。 “L”代表继电器未吸合,“H”代表继电器吸合,确定继电器的常闭触点和常开触点很重要,因为继电器的吸合需要消耗一定电流,我选用的继电器型号为 TO2-5V,吸合电流为15mA。在常用的3个灵敏度上(0.5V/div,0.2V/div,0.1V/div)最多只有一个继电器吸合,继电器的驱动由ULN2003AD担任。这种由运算放大器构成组合程控放大器的思想也可用于别的放大电路,平时多总结积累电路模型对提高电路设计能力非常有帮助,这个电路你记下了吗? 电源电路为整个示波器提供能源,作用非常重要!电路见如图3所示。

“双核”示波器的硬件描述与程序设计

“双核”示波器的硬件描述与程序设计

“双核”示波器的硬件描述与程序设计

该示波器电路中供电分为数字和模拟两部分。为避免相互干扰,将数字部分的供电与模拟部分的供电分开,分别用独立的稳压电路,并用电感与电容做成的滤波器隔离。数字部分需要单+5V电源,由一片LM7805CT对8V 电源电压稳压得到。模拟部分主要是程控放大器电路和AD转换器的模拟输入电路,程控放大器电路需要±5V双电源,AD转换电路的模拟部分需要+5V的单电源,+5V电压由LM317T对8V电源电压稳压得到,而-5V电压专门用一片DC/DC芯片MC34063AD将+8V转换成约-8.3V,DC/DC 输出电压由R30和R31决定,VOUT=(R30+R31)/R31×1.25V=-8.25V,输出的负电压由负压稳压芯片LM337T稳压得到-5V,为避免DC/DC电路对其他电路产生干扰,在其输入和输出端分别串联L4和L5进行隔离,在选择元件时蓄能电感L3选择磁罐封装带屏蔽的电感,使干扰降到最低。


2.高速AD转换与FIFO存储电路

数字示波器中最重要的电路是AD转换电路,它的作用是将被测信号采样并转换成数字信号存入存储器,说它是数字示波器的咽喉一点也不为过,因为它直接决定着数字示波器所能测量的最高频率。根据乃奎斯特定理,采样频率至少是被测信号最高频率的2倍才能复现出被测信号。

而在数字示波器中采样频率至少应该是被测信号频率的5~8倍才行,否则根本观察不到信号的波形。在本电路中我选用的AD 转换芯片为BB公司的8位高速AD转换器ADS830E,官方资料给出的采样频率为10kS/s~60MS/s,通过实验发现转换速率在1kHz以下工作也很正常,所以本示波器的最低采样频率为600S/s,要说明的一点是高速AD转换器一般都有高低端转换速率的限制,比如TLC5540,8位AD转换器,转换速率为5~40MS/s,我试过当转换频率降到2MHz以下时就不能正常工作,所以选择AD转换芯片时不仅要注意最高转换速率,还要关注最低转换速率,否则可能导致电路无法正常工作。有朋友也许会问8位转换精度会不会有点太低?其实8位转换器对于示波器来说是够用的,就拿这个电路来说,我选用的 LCD显示模块的分辨率为320×240,垂直分辨率为240格,而8位转换精度的分辨率为256格,比显示器的分辨率还高,所以绝对够用。还有就是价格及电路的设计,在最高采样率相同的情况下10位AD转换芯片的价格是8位AD转换芯片的几倍,而且位数的增加也使电路的复杂程度大大增加,将直接影响处理速度,导致屏幕刷新过慢,反而影响性能。所以本着够用的原则本示波器选用60MHz的8位AD转换芯片ADS830E。引脚排列见图7。

“双核”示波器的硬件描述与程序设计

“双核”示波器的硬件描述与程序设计

“双核”示波器的硬件描述与程序设计

“双核”示波器的硬件描述与程序设计

AD转换与FIFO存储电路见原理图4,由程控放大电路调整后的信号分成两路,一路进入AD转换电路进行采样, 采样所得的数据由74LVC574锁存缓冲后送入FIFO存储器。FIFO存储器是一种双口的SRAM,这种存储器没有地址线,随着写入或读取信号对数据地址指针进行递加或递减,来实现寻址。在AD转换器与MCU2之间加入FIFO的作用是起到高速数据缓冲的作用,因为AD转换器的最高工作频率为 60MHz,远高于MCU2的工作频率,所以让FIFO与AD转换器同步工作存储AD转换器的转换输出数据。FIFO存储器有3个标志位引脚,分别为 FF(满标志):当存储器存满后置位该标志,此时存储器忽略一切写数据操作。HF(半满标志):当存储器存满一半后置位该标志。EF(空标志):当存储器被读空时置位该标志,此时存储器忽略一切读数据操作。FIFO存储器结构图见图5。本电路中只用了该芯片的FF标志与MCU2的PB3相接,当FIFO存储器存满后FF引脚被拉高,通知MCU2进行数据读取,这时MCU2禁止AD转换器与FIFO存储器的时钟,FIFO的控制权交给MCU2(其实MCU2 只是禁止了FIFO存储器的写时钟,见图6,时钟信号通过U8C组成的缓冲器后直接加给了ADS830E,所以MCU2不能禁止AD转换时钟,只能通过由与门U8A组成的时钟控制开关禁止或使能FIFO存储器的时钟信号。因为实验中发现AD转换在启动后的几个时钟周期内的采样不可靠,所以就让AD转换器一直工作,通过控制FIFO存储器来控制AD采样。在AD转换电路与FIFO存储器中加入74LVC574的目的是锁存数据提高数据通道的稳定性)。

当MCU2读完数据并完成软件触发后使能AD转换器与FIFO存储器时钟,继续读取新的数据,同时MCU2对读取的数据进行处理、显示。

这儿再将高速数模转换器ADS830E的工作简单介绍一下,ADS830E的时序如图6所示,由图可知每个时钟周期进行一次数模转换,所以采样速率就是时钟频率,故可以很方便的通过控制采样时钟来控制采样频率,当前输出的采样数据是4个时钟周期以前采样电压的值,也就是说从采样到输出有4个时钟周期的延迟,这对我们所要做的电路并不重要,所以我们可以简单的理解为输入一个时钟脉冲转换一次,时钟脉冲的下降沿输出数据就行,应用非常方便。还有一点就是ADS830E的输入电压幅度是可以编程控制的,11脚(RSEL)为控制引脚,当11脚置高电平时,ADS830E的输入电压范围是1.5~3.5V,即2Vpp。当11脚置低电平时,输入电压范围是2~3V,即1Vpp。进行程控放大器设计时要考虑这个问题,本电路选用 2Vpp的输入电压范围。


3.时钟产生电路

时钟产生电路为AD转换器提供一系列的采样时钟信号,分别为600Hz、6kHz、60kHz、600kHz、 3MHz、6MHz、30MHz和60MHz,共8种,分别对应着不同的水平扫速,由MCU1控制,控制关系见表2。时钟产生电路见图8,基准时钟信号由一块60MHz的温度补偿型有源晶体模块提供,输出的60MHz信号一路直接作为60MHz采样时钟送入多路选择器74F151,另一路被送入由 74F74触发器组成的2分频器分频,得到30MHz的信号分为两路,一路送入多路选择器74F151,另一路送入由2-5-10分频器74LS390组成的5分频器进行分频,得到6MHz信号,再分为两路,一路继续分频,另一路送入多路选择器74F151,后面几级分频与以上相同。对60MHz信号进行第一次二分频没有用74LS390中的二分频器,而单独使用了一片74F74,是因为74LS390中的二分频器的最高输入频率为40MHz,所以在其前面用了一级独立的二分频器。8种时钟信号都被送入多路选择器,MUC1通过对74F151的S0、S1、S2三根选通信号线进行控制来选择所需的采样频率。

“双核”示波器的硬件描述与程序设计

“双核”示波器的硬件描述与程序设计

4.MCU2单片机显示处理电路

MCU2选用ATMEL公司的AVR单片机ATmega32-16AI,与51单片机相比AVR单片机具有更高的工作频率与更高效率的硬件结构,51单片机的指令周期是将晶体振荡器的振荡频率进行12分频后得到的,又有累加器Acc在高速执行指令时的瓶颈因素,而AVR单片机则不同,它的指令周期就是晶体振荡器的振荡周期,有32个类似与累加器Acc的寄存器直接和运算器相连,取址周期短,又可预取指令实现流水作业,故可高速执行指令。ATmega32-16AI的ROM容量为32KB,RAM为2KB,32个输入、输出口,官方给出的最高速度为16MHz,但在实际使用中工作在18~20MHz也很稳定,所以用该单片机做显示处理非常合适。在本电路中为了提高LCD显示器的屏幕刷新速率使其工作在18MHz,实际使用中电路工作十分正常。

MCU2电路见图9所示。PD0~PD7与LCD显示器8位并行数据端相连,PC1~PC5与LCD显示器的控制端相连用于驱动LCD显示器,PC0用于控制LCD背光,PC0=0有背光,PC0=1无背光。PB4、PB5与PB7作为SPI通信端口与MCU1相连进行两个单片机之间的通信。 PA0~PA7与FIFO存储器的数据输出端D0~D7相连接,PB0~PB3分别与FIFO存储器的使能(FIFO_EN)控制端、复位(FIFO_RES)控制端、读数据(FIFO_R)控制端和满标志(FIFO_FF)位相接。上电时,MCU2通过FIFO_RES端口对FIFO存储器进行复位,复位后存储器的读写指针都指向0,允许写数据,MCU2通过FIFO_EN端使能FIFO存储器,开始将AD转换器输出的数据写入存储器,当 FIFO存储器写满数据后FIFO_FF位被拉高通知MCU2读取采样数据,MCU2禁止FIFO存储器写入数据,然后从FIFO存储器中读数据,当数据读完并完成软件触发后使能FIFO存储器继续存储采样数据,然后从读取的数据中测出波形的峰峰值后将数据转换成波型与参数显示在LCD显示器上,峰峰值的测量是通过对一屏显示数据进行比较取出最大值与最小值与当前垂直电压灵敏度作为系数计算出来的。SPI通信通过中断的方式实现,MCU1每次给MCU2发送频率、水平扫速、垂直电压灵敏度等数据一共为9个字节,每发送一个字节MCU2中断一次,将接收到的数据存到一个数组中,直到9个字节全部发送完毕 MCU2才对接收到的数据进行处理显示。这样可以使MCU2在平时都工作在数据的处理和显示上,提高了数据的处理速度。

“双核”示波器的硬件描述与程序设计

5.MCU1单片机控制与信号整形电路

MCU1同MCU2一样也选用AVR单片机,型号为ATmega8-16,工作频率为16MHz,在电路中负责控制程控放大器和时钟发生电路,并负责测量被测信号频率,将各种参数通过SPI总线发送给MCU2。

MCU1电路见图10, PC2~PC5共4个I/O口接4个轻触开关S1~S4,S1、S2是两个复用键,用于控制水平扫速与垂直电压灵敏度,功能通过S4切换,当前功能状态显示在显示器上,如果当前的控制功能为控制水平扫速,则在显示器的右下边反显示“T”, 如果当前的控制功能为控制垂直电压灵敏度,则在显示器的右下边反显示“V”。S3是触发控制,当前状态显示在控制状态左边,箭头上升则自动触发,箭头向下则不触发。长按S3选择交直流耦合方式。该示波器现在只能实现基本功能,其他更多功能有待于广大爱好者共同努力。S0、S1、S2、S3、S4共5个端口分别连接PB4、PB0、PB1、PC0、PC1用于垂直电压灵敏度控制,控制数据见“程控放大电路”中的表1。 PB2、PB3、PB5作为SPI总线接口与MCU2通信,为了防止下载程序时两芯片SPI口冲突,在两单片机之间的SPI总线上串联了3只1kΩ的电阻,实验证明此法非常有效,电路工作稳定。PD0~PD2共3个I/O口用于时钟控制,控制数据见“时钟产生电路”中的表2。频率的测量使用了16位计数器,外部下降沿触发。程控放大器输出的信号送给由场效应管VT2和高频三极管VT3组成的高输入阻抗整形电路,整形后再由U17触发器74F74进行4分频,然后送入MCU1的T1(PD5)脚进行计数测频,在低水平扫速时(5ms/div和50ms/div)为了保证测频精度测频周期为1s,在高水平扫速时(小于5ms/div)测频周期为0.25s。测频的原理是通过记录1s或0.25s内计数器记录的脉冲数来换算频率,测频定时由中断完成,每测完一次频率就通过SPI总线向MCU2发送一次数据,所以在高水平扫速时每秒向MCU2发送4次数据,而在低水平扫速时每秒向MCU2发送1次数据,能较好地保证参数显示的实时性。


没有程序,那一堆堆电路起不到任何作用,完全是一堆废板子!就像一台没有操作系统的电脑一样,只能废电。程序设计是整个示波器制作中的难点,本文将详细讲解程序的设计。该示波器中的程序全部是用C语言编写的,开发环境为CodeVisionAVR C,源程序可到《无线电》网站(www.radio.com.cn )下载,下面就各个重要的子程序的设计一一叙述,其他程序见源程序。MCU2与MCU1的程序流程图分别见图1和图2。

“双核”示波器的硬件描述与程序设计
“双核”示波器的硬件描述与程序设计

同步触发的软实现

细心的朋友也许会发现这个示波器电路中缺少一部分电路,就是硬件触发电路。为了降低电路的复杂性,我没有做这个电路,而是用软件实现同步触发的。虽然这样做有个弊端,就是几乎无法实现单次触发,但是我基本不用这个功能。要用这个功能的朋友只需在程控放大器部分加上一个由高速比较器构成的迟滞比较器,然后将输出端接到一个外部中断的输入口即可。当然程序和电路就要作相应的变化,这里就不多讲了。软件触发的好处是触发条件更易调整,只需调整比较语句中的参数即可。保证可以用软件触发的条件是要有足够大的存储空间,显示一屏的数据为240个,但每次读进单片机的数据为500个,多余260个数据就是作为不满足触发条件的舍弃余量。为了以防万一,当从500个数据中已经读出超过260个数据但还没有符合触发条件的数据时,将跳出触发比较循环,重新从 FIFO存储器中读出500个数据,因为FIFO存储器为4K容量,最多可以这样重复读取8次数据,所以软触发可以非常稳定地工作,在该示波器的MCU2 中控制触发的语句见以下程序段:

“双核”示波器的硬件描述与程序设计
“双核”示波器的硬件描述与程序设计

程序的意思是只有当此时采样信号的数值是m且为上升沿时才可以触发,改变触发沿只需改变运算符,改变触发电压只需改变m的值即可,m的取值范围是0~255。

从采样数据中测信号峰峰值

本示波器能够测量输入信号电压的峰峰值,并显示在屏幕上。这个功能由峰峰值测量子程序完成,见下面的程序段。 
在程序开始时给a中赋值128,即基线电压值。因为一屏幕的显示数据为240个,所以用for()循环将if…else…判断语句执行240次,在a中存放最大值,在b中存放最小值。对每个数据进行比较,如果该数据比a大则将这个数据存入a,如果小于a,则将这个数据与b进行比较,比b大则抛弃,比b小则存入b。故当240个循环执行完后,a中存放的是这一屏幕数据中的最大值,b中存放的是这一屏幕显示数据中的最小值。在比较完后用a减去b,得到差值存入c 中,则c中保存的值就是电压的峰峰值,调用电压计算显示子程序,根据当前的垂直灵敏度给c乘以不同的倍数,得到实际的峰峰值。当前垂直灵敏度的判断由一个 switch()选择结构完成。biao寄存器中的数据是当前的垂直灵敏度,case 4:后面没有运算是因为程控放大器在此状态下的放大倍数为1,即没有放大也没有衰减。

在计算完峰峰值后,设置LCD显示器,使其工作在文本模式(因为只有在文本模式下对字库的调用才有效),然后设置屏幕上显示电压峰峰值的坐标(对该LCD模块的控制是先送命令,后送参数。例如设置X坐标“SdCmd(0x60);SdCmd(30);”中,第一个 SdCmd()送的0x60是设置X坐标的命令,第二个SdCmd()送的30是X轴的坐标,其他设置相同。具体见光盘中LCD显示屏的资料。),在设置完LCD后约定显示格式,小数点后保留2位有效数字,显示单位为Vpp,显示完毕后需重新设置LCD工作状态,使其工作在图形模式用于波形显示。

“双核”示波器的硬件描述与程序设计
“双核”示波器的硬件描述与程序设计

将采样数据转换成显示数据

LCD 显示屏为320×240点阵的图形显示模块,内置RA8803 控制器。模块不仅可以显示单一的文本、图形,而且可以实现双图层的(“或”、“异或”、 “同或”、“与”四种逻辑关系)合成显示。在本示波器中方格线与波形是在不同的层上显示,显示关系为“或”,画方格线的程序见原程序,比较简单就不多说了,这里着重解释一下如何将采样数据转换成显示数据。

显示屏的地址结构见图3,由图可知对显示数据的操作最小单位为字节,因为 ATmega32的内存为2K字节,显示波形的区域为240×240,显示一屏波形所需处理的数据为7.2K,故ATmega32不可能同时处理一屏波形的全部数据,所以将一屏波形按字节分为30列,每次处理一列,处理完后直接显示,然后处理下一列。将AD转换所得的数据作为给LCD显示器写数据的列地址,因为一列数据位240字节,所以定义一个容量为240字节的数组lcd_buffer[240],lcd_buffer[ ]在初始时数据全为 00H,因为每次对数据的操作至少是一个字节,而每次处理的数据是所显示的一个点,所以对每列数据处理8次,定义一个变量m,在一列数据处理之前将其赋值为m=10000000B,处理该列第1个点时让该点垂直地址所对应的数组中的数据(00H)与m相或,并将结果存入数组,再将变量m右移一位,即 m=01000000B。让第2点垂直地址所对应的数组中的数据与m相或,并将结果存入数组,再将变量m右移一位,即m=00100000B ……这样直到一列数据中的8个点全处理完,重新给m赋值为m=10000000B,然后送显示。为了有较好显示效果,将显示相邻的点用线连接起来,在处理第一个点时预读出第二个点的垂直坐标,与第一个点的垂直坐标进行比较,如果比第一个点的垂直坐标小则从第一个点向第二个点拉线,如果比第一个点的垂直坐标大则从第二个点向第一个点拉线。具体程序如下:

“双核”示波器的硬件描述与程序设计
“双核”示波器的硬件描述与程序设计

用MCU1频率测量

用ATmega8测量频率使用了其中的两个计数器/定时器。设置TCCR1B=6使16位计数器/定时器T/C1工作在计数器方式,对外部T1(PD5)引脚输入的脉冲信号进行计数(下降沿触发)。

“双核”示波器的硬件描述与程序设计

“双核”示波器的硬件描述与程序设计

设置TCCR2=15使T/C2工作在CTC模式,内部时钟 1024分频(16M/1024=15.625kHz),设置OCR2=124,使中断时间为(124+1)/15.625=8ms,在低水平扫速时每隔 8ms中断一次,在高水平扫速时通过重新设置TCCR2=14,则每隔2ms中断一次,在这里以低水平扫速时为例,每次T/C2的中断中都首先记录下T /C1寄存器TCNT1当前的计数值,因此前后两次寄存器TCNT1的差值(time1_new-time1_old)或(65536- time1_old+time1_new)就是8ms时间内T1引脚输入的脉冲个数,为了提高测量精度程序对125个8ms内的脉冲个数进行累计,将累计值存入变量freq中,即可知限定时间为1s内有多少个脉冲,这样就将T1脚上的脉冲频率测量出来了,而T1脚上的频率是经过4分频后的,所以真正的频率是将测量的频率的4倍。具体程序如下:

“双核”示波器的硬件描述与程序设计
“双核”示波器的硬件描述与程序设计

将两个单片机联系起来

将两个单片机联系起来就是实现两个单片机之间的通信,在这里实际就是让MCU1控制MCU2,为了完成这一功能使用SPI通信。

首先介绍一下SPI的通信协议:SPI(串行外设接口)总线系统是一种同步串行外设接口,允许MCU与各种外围设备以串行方式进行通信、数据交换,广泛应用于各种工业控制领域。基于此标准,SPI系统可以直接与各个厂家生产的多种标准外围器件直接接口。SPI接口通常包含有4根线:串行时钟(SCK)、主机输入/从机输出数据线(MISO)、主机输出/从机输入数据线(MOSI)和低电平有效的从机选择线SS。在从机选择线SS使能的前提下,主机的SCK脉冲将在数据线上传输主/从机的串行数据。主/从机的典型连接图如图4所示。

串行外设接口SPI允许AVR单片机和外设之间进行高速的同步数据传输。AVR单片机SPI的特点如下:全双工,3线同步数据传输,主/从机操作,LSB首先发送或MSB首先发送,7种可编程的比特率,传送中断结束,写碰撞标志检测,可以从闲置模式唤醒。SPI主机-从机的互连如图5所示,系统包括两个移位寄存器和一个主时钟发生器。通过将需要的从机的 SS引脚拉低,主机启动一次通信过程。主机和从机将需要的数据放到相应的移位寄存器,主机在SCK引脚上产生时钟脉冲以交换数据。主机的数据从MOSI移出,从从机MISO移入。从机的数据从MISO移出,从从机MOSI移入。主机通过将从机的SS拉高实现与从机的同步。


下面将介绍SPI的几个特殊寄存器:

(1) SPI的控制寄存器—SPCR(见图6)

“双核”示波器的硬件描述与程序设计

SPIE为SPI中断使能,置位后,只要SPSR寄存器的SPIF和SREG寄存器的全局中断使能位置位,就会引发SPI中断。SPE置位将使能SPI,DORD置位时数据的LSB首先发送;否则数据的MSB 首先发送。MSTR置位时选择主机模式,否则为从机。CPOL置位表示空闲时SCK为高电平;否则空闲时SCK为低电平。CPHA决定数据是在SCK的起始沿采样还是在SCK的结束沿采样。通过对SPR1、SPR0进行设计,确定主机的SCK速率。

(2)SPI的状态寄存器—SPSR(见图 7)SPIF为中断标志位,串行发送结束后,SPIF置位。若此时寄存器 SPCR的SPIE和全局中断使能位置位,SPI中断即产生。进入中断例程后 SPIF将自动清零。在发送当中对SPI数据寄存器SPDR写数据将置位WCOL,SPI2X置位后SPI的速度加倍。

(3)SPI的数据寄存器—SPDR(见图8)SPDR数据寄存器为读/写寄存器,用来在寄存器文件SPI移位寄存器之间传输数据。写寄存器将启动数据传输,读寄存器将读取寄存器的接收缓冲器。SPI系统的发送方向只有一个缓冲器,而在接收方向有两个缓冲器。也就是说,在发送数据时一定要等到移位过程全部结束后才能对SPI数据寄存器执行写操作。而在接收数据时,需要在下一个字符移位过程结束之前通过访问SPI数据寄存器读取当前接收到的字符。否则第一个字节将丢失。

本示波器中只用MCU1控制MCU2,所以MCU1只用于发送控制数据,而MCU2只用于接收控制数据,所以将 MCU1配制成SPI主机,将MCU2配制成SPI从机即可。在实际的程序设计中由于MCU1启动SPI通信是在中断服务程序中完成,所以在执行完后相应寄存器会被清零,导致数据错误,所以MCU1并没有使用其中的SPI控制器,而是使用一个子程序模拟SPI通信,解决了控制寄存器被清零的问题。MCU2 则使用了本身的SPI控制器进行数据接收。具体程序见以下程序段 : MCU1模拟SPI主机程序段spi_out()为SPI发送子程序,带有参数j,即j为要发送的数据,发送数据时先拉低ss,让从机开始接收数据,然后用for()循环将数据按由左至右的顺序(即高位先发送)发送给从机,具体方法是将j与0b10000000相与,屏蔽低7位,是1则将dat拉高,否则置低,然后拉高clk,延时1us再置低clk,模拟时钟信号,再将j左移一位,再与0b10000000相与,然后判断发送……直到8位数据发送完毕,拉高ss告诉从机数据发送完毕进行数据存储。发送数据时约定数据格式,即两个单片机之间的通信协议:每次发送9个字节,前4个字节是测得的频率数据,且高位在前;第5个字节为垂置灵敏度数据;第6个字节为触发控制数据;第7个字节为同步控制数据;第8个字节为水平扫速数据;第9个字节为功能复用键的当前功能标志。从机再接收到数据后按照这样的顺序对数据进行处理,实现相应的功能。spi_out()这个子程序还可以用于其他需要SPI控制的芯片,只需在调用前对I/O口进行定义即可。

“双核”示波器的硬件描述与程序设计
“双核”示波器的硬件描述与程序设计
“双核”示波器的硬件描述与程序设计
“双核”示波器的硬件描述与程序设计
“双核”示波器的硬件描述与程序设计

(2)MCU2从机SPI程序段
init_spi() 函数是将MCU2配制成SPI从机,每接收一个字节的数据中断一次,中断服务程序中将接收到的数据存入数组,并将数组地址加1,然后判断9个字节是否接收完毕,若没接收完则继续等待接收,接收完后则将数据按约定格式处理显示。大家可以根据自己的需求改变这些格式为其增加新的功能。

    本站是提供个人知识管理的网络存储空间,所有内容均由用户发布,不代表本站观点。请注意甄别内容中的联系方式、诱导购买等信息,谨防诈骗。如发现有害或侵权内容,请点击一键举报。
    转藏 分享 献花(0

    0条评论

    发表

    请遵守用户 评论公约

    类似文章 更多