3 软件设计部分
3.1系统程序流程
硬件电路设计对系统的稳定性,抗干扰能力有很大的影响,但是软件程序设计对于系统的稳定性、准确性、响应速度也有很大的关系。本设计方案中对应硬件电路的程序包括:LED显示子程序、LCD初始化4x4矩阵键盘子程序、转换子程序、扫频子程序。主程序流程图如图3.4所示:
开始系统初始化开中断端口初始化AD9850复位初始化显示获取的键值等待NO判断是否有键按下Y判断是数字键还是命令键 命令键数字键将按下的键进行转换将按下的键进行转换输出控制命令给AD9850
图3.1 系统流程图
程序设计中通过4X4矩阵键盘输入我们需要产生的频率值,并在8位7段数码管上实时显示,对于我们输入的数值只需按下确认按钮,就能讲我们设定的频率值通过单片机传递给AD9850,使AD9850输出我们想要得到的频率值。
系统由初始化开始,对程序中用到的管脚定义进行声明,显示部分,键盘部分,参数变量,AD9850部分都进行初始化,以避免发生不确定因素,使程序跑飞。
在初始化结束后,程序就进入主函数部分。在主函数中首先打开总中断和外部中断0。然后将P0口的高四位付予高电平。这里应用外部中断作为中断的触发是因为系统中我们采用中断法来对键盘进行读取。这样做的好处是我们可以随时更改我们需要输入到系统中的数值,并且不会占用太多单片机的资源,提高效率。当然,要读取到4X4键盘上任一按键的中断请求,我们需要用到一个74LS21(四输入与门),将键盘的四行或则四列分别引到74LS21的输入端,然后将输出端引到单片机的P3.2(INT0)段,并将INT0设置成\,即下降沿触发方式。这样一旦有按键按下,74LS21就输出一个低电平,INT0就由高电平变成低电平,这样单片机就检测到有外部中断请求。P1、P2、P3口也要进行相应的初始化,为程序的后续执行做好准备。
AD9850的初始化主要是对AD9850进行复位。AD9850的各个功能管脚复位后,为后面的数据传输工作做好准备。
接下来是LED的显示。我们需要做到7段8位数码管的循环显示,并且在系统刚上电的时候我们是LED能够显示Fo=000Hz这样8个字符。对于8位数码管位选择控制,我们通过P1口的低3位,经过74HC138译码器输出选择信号。使8位数码管循环显示。
数码管的显示却又和键盘的输入息息相关。本系统采用4X4的矩阵键盘,对键盘进行逐行扫描,并结合中断法来判断是否有键按下。在读键盘期间,我们关闭外部中断,防止干扰带来的多次中断误判。在消抖处理方面,我们在按键按下后,采用延时十多毫秒再读取键值的办法。但是本系统不采用循环语句来判断,因为采用循环语句会使CPU占用系统资源,降低单片机的工作效率。因此这里我们采用定时器中断法,让定时器等待十多毫秒后触发定时器中断,提高了系统的工作效率。软件中对按键的不同功能也作了分类。有功能键和数字键两种。只有按下更改键后,才能向系统重新输入数值,按下确认键后,才能将数值传送给单片机。其它的功能键,按下后就能直接通过单片机控制AD9850执行相应的操作了。
若没有按键被按下,系统就只能执行当前的操作,直到有触发命令的到来。
3.2 AD9850程序
AD9850在此系统中采用串口方式,即利用D7端口今天传输数据。其他的端口还有复位端口,写始终端口,频率端口,在AD9850中都要对这些端口进行初始化。程序如下:
void ad9850_reset() {
ad9850_w_clk=0; ad9850_fq_up=0; //rest信号 ad9850_rest=0; ad9850_rest=1; ad9850_rest=0; //w_clk信号 ad9850_w_clk=0; ad9850_w_clk=1; ad9850_w_clk=0; //fq_up信号 ad9850_fq_up=0; ad9850_fq_up=1; ad9850_fq_up=0; }
在对AD9850进行复位后,就是向AD9850进行控制,这部分主要包括写数据与命令。最主要的还是控制字K在程序中的处理。K值在程序中用X来表示,并且要结合模块中使用的有源晶振的频率值。我们也可以对频率进行一定的修正,减小晶振带来的误差。在AD9850中,对于计数容量为2l的相位累加器和具有M个相位取样点的正弦波波形存储器,若频率控制字为K,输出信号频率fo为参考时钟频率为fc,则DDS系统输出信号的频率为:
fo=
K2L。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。 fc。
由奈奎斯特采样定理可知,DDS输出的最大频率为:
fo=
fc2。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。
则可得频率控制字为:
K=
fofc。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。 2。
l程序中我们为了使精度最大化,L取值为32,其程序如下: void ad9850_wr(unsigned char w0,double frequency) {
unsigned char i,w; long int y; double x;
x=4294795550/125;//修正频率使之更精确,减小晶振带来的误差 frequency=frequency/1000000;这里应该是单位统一为MHz frequency=frequency*x; y=frequency; //写w4数据 w=(y>>=0); for(i=0;i<8;i++) {
ad9850_bit_data=(w>>i)&0x01; ad9850_w_clk=1; ad9850_w_clk=0; }
//写w3数据 w=(y>>8); for(i=0;i<8;i++) {
ad9850_bit_data=(w>>i)&0x01; ad9850_w_clk=1; ad9850_w_clk=0; }
//写w2数据 w=(y>>16); for(i=0;i<8;i++) {
ad9850_bit_data=(w>>i)&0x01; ad9850_w_clk=1; ad9850_w_clk=0;
}
//写w1数据 w=(y>>24); for(i=0;i<8;i++)
{ad9850_bit_data=(w>>i)&0x01; ad9850_w_clk=1; ad9850_w_clk=0; }
//写w0数据 w=w0; for(i=0;i<8;i++) {
ad9850_bit_data=(w>>i)&0x01; ad9850_w_clk=1; ad9850_w_clk=0; }
//移入始能 ad9850_fq_up=1; ad9850_fq_up=0; }
3.3 4×4矩阵键盘子程序设计
4×4矩阵键盘工作原理及介绍已经在前面详细的给出,故这里不再重复。其程序流程图如图3.3.1所示: