这是我很早之前做的,大家可以看看,附件中包含有完整的论文和源码.
采用基于DDS专用芯片AD9850作为信号产生模块,并以基于ARM7的微控制器ARM1138作为整个系统的控制核心。在ARM1138中嵌入UCOSII操作系统方便实现多任务处理。例如波形转换,频率调节,幅值调节,12864显示,I2C掉电保护等。本方案融合了如方案一频率合成的优点,并能发挥ARM控制器强大的系统管理能力。同时可利于分工合作,以最快的时间完成题目的所有要求。此方案比较灵活、可扩展性好,能完全达到设计要求,故采用此方案。
ARM微控制器从键盘获得控制信息,通过计算得到控制字并通过IO口送给DDS的频率和相位的控制端口,同时,将信息显示在LCD上。DDS输出信号由程序控制其预置频率和相位的正弦信号或方波信号,再通过放大倍数可调的运算放大系统来控制调幅。三角波则由方波信号经过一级方大后通过积分电路获得。掉电保护功能则由ARM1138内部AD把数据读回再通过I2C写入24C04来完成。结构图如图2-1。
2.2 DDS的实现设计 DDS的基本原理是利用采样定理,通过查表法产生波形,其基本架构如图2-2所示:
相位累加器由N位加法器与N位累加寄存器级联构成。 每来一个时钟脉冲fs,加法器将频率控制字k与累加寄存器输出的累加相位数据相加,把相加后的结果送至累加寄存器的数据输入端。累加寄存器将加法器在上一个时钟脉冲作用后所产生的新相位数据反馈到加法器的输入端,以使加法器在下一个时钟脉冲的作用下继续与频率控制字相加。这样,相位累加器在时钟作用下,不断对频率控制字进行线性相位累加。 由此可以看出, 相位累加器在每一个时钟脉冲输入时,把频率控制字累加一次,相位累加器输出的数据就是合成信号的相位,相位累加器的溢出频率就是DDS输出的信号频率。 用相位累加器输出的数据作为波形存储器(ROM)的相位取样地址,这样就可把存储在波形存储器内的波形抽样值 (二进制编码) 经查找表查出,完成相位到幅值转换。波形存储器的输出送到D/A转换器,D/A转换器将数字量形式的波形幅值转换成所要求合成频率的模拟量形式信号。低通滤波器用于滤除不需要的取样分量,以便输出频谱纯净的正弦波信号。 DDS在相对带宽、频率转换时间、高分辨力、相位连续性、 正交输出以及集成化等一系列性能指标方面远远超过了传统频率合成技术所能达到的水平,为系统提供了优于模拟信号源的性能。
系统测试 4.1测试条件 表1 仪器仪表 仪器仪表名称 | | | 数字示波器 | | | 函数信号发生器 | | | 直流稳压电源 | | | 万用表 | | |
4.2测试方案与测试结果 4.2.1观察示波器,记录频率值和输出电压峰-峰值。 表二 频率值和输出电压峰-峰值测量记录表 预置频率/Hz | | | | 50 | | | | 100 | | | | 500 | | | | 1k | | | | 5k | | | | 10k | | | | 15k | | | | 20k | | | |
4.2.2 观察示波器,记录步进频率值。 表三 步进频率值记录表 预置频率 (Hz) | | | | | 20 | | | | | 100 | | | | | 500 | | | | | 1k | | | | | 5k | | | | | 10k | | | | | 15k | | | | | 20k | | | | |
4.3测试结果分析 由实验调试结果及测试结果,该函数信号发生器达到了题目的所有指示要求,在选择波形与调节幅度频率试时采用LCD人机交互界面,界面友好方便,具有直观性。 五、结语 本次设计的低频三相信号源,主要运用了DDS基本原理,利用ARM1138作为仿真测试和实际测量(测量结果见上表)符合题目给定的基本要求。
本次软件设计流程如图3-1所示:程序初始化后进入初始界面,再判断KEY1是否被按下,按下KEY1是选择波形型号,按下KEY2选择频率递增,按下KEY3选择频率递减,按下KEY4选择幅值递增,按下KEY5选择幅值递减。本设计最大的优点就是能实现掉电保护,实时保存数据,防止电压过低或者突然断电造成的数据丢失。
源程序:
- /******************************/
- /******************************/
- #include <includes.h>
- #include "AD9850.h"
- #define SysCtlPeriEnable SysCtlPeripheralEnable
- #define SysCtlPeriDisable SysCtlPeripheralDisable
- #define GPIOPinTypeOut GPIOPinTypeGPIOOutput
- #define TASK_STK_SIZE 64
- /**************************************
- CONSTANTS 常量
- **************************************/
- /************************************
- VARIABLES 变量
- *************************************/
- uint16 now_color=0; //当前色
- uint16 state=0,flag=0; //状态
- uint16 frist_in=0; //初次进入标志
- unsigned char num=0,aa=1;
- unsigned int tt;
- unsigned long ulData = 0;
- unsigned char buff[5];
- unsigned char display[10];
- float temp=0;
- unsigned long dat= 0,dat2=0,dat3=0;
- unsigned char wan=0, qian=0,ge=0,shi=0,bai=0;
- unsigned char wan2=0, qian2=0,ge2=0,shi2=0,bai2=0;
- unsigned char wan3=0, qian3=0,ge3=0,shi3=0,bai3=0;
- static OS_STK GstkStart[TASK_START_STK_SIZE];//启动任务的堆栈
- static OS_STK GstkLED[TASK_LED_STK_SIZE];
- OS_STK Task1Stk[TASK_STK_SIZE];
- OS_STK Task2Stk[TASK_STK_SIZE];
- /*************************************
- FUNCTION PROTOTYPES 函数声明
- **************************************/
- static void taskStart (void *parg); //启动任务
- static void taskLED(void *parg); //任务0
- void Task1(void *data);
- void Task2(void *data);
- /***********************************************
- 功能:主程序
- ************************************************/
- int main (void)
- {
- OSInit(); // OS-II 初始化uC/OS-II的内核
- OSTaskCreate( taskStart,
- (void *)0,
- &GstkStart[TASK_START_STK_SIZE-1],
- TASK_START_PRIO );
- /* 初始化启动任务 */
- OSStart(); // 启动uC/OS-II*/
- return(0);
- }
- /****************************************
- ** Function name: Task_Start
- ** input parameters: *p_arg
- *****************************************/
- static void taskStart (void *parg)
- {
- (void)parg;
- targetInit(); // 初始化目标单片机
- #if OS_TASK_STAT_EN > 0
- OSStatInit(); // 使能统计功能
- #endif
-
- /* 在这里创建其他任务 */
- OSTaskCreate( taskLED,
- (void *)0,
- &GstkLED[TASK_LED_STK_SIZE-1],
- TASK_LED_PRIO ); // 建处理任务
- OSTaskCreate(Task1, (void *)2, &Task1Stk[TASK_STK_SIZE - 1],2);
- OSTaskCreate(Task2, (void *)3, &Task2Stk[TASK_STK_SIZE - 1], 3);
-
-
- KEY_Init(KEY1 | KEY2); //按键初始化
- LCDInit(); //LCD12864初始化 // LCD初始化
- clear_all(); // 清屏
-
- while (1)
- {
- /* 启动任务可在这里挂起 */
- OSTaskSuspend(OS_PRIO_SELF);
- }
- }
- /***********************************************
- 名称:任务0
- 功能:
- **********************************************/
- static void taskLED(void *parg)
- {
- (void)parg;
- Display(ulData);//开机显示
- for(;;)
- {
- if(KEY_Get(KEY1))//KEY1选波形型号
- {
- OSTimeDlyHMSM(0,0,0,150);
- if(KEY_Get(KEY1))
- {
- num++;
- if(num==4)
- {
- num=0;
- }
- }
- }
-
-
-
- if(num==1)////正弦波
- {
- LCD_ComdWrite(0x93);
- LCD_ComdWrite(0x0C);//关光标
- Displaysin();//正弦波
- dat=wan*10000+qian*1000+bai*100+shi*10;
- Write_9850(dat);
- display[4]=dat%100000/10000+0X30;//显示千位
- display[3]=dat%10000/1000+0X30;//显示千位
- display[2]=dat%1000/100+0X30;//显示百位
- display[1]=dat%100/10+0X30;//显示十位
- display[0]=dat%10+0X30;//显示个位
- if(display[4]==0x30)
- {
- display[4]=0x20;
- if(display[3]==0x30) //高位为0,不显示
- {
- display[3]=0x20;
- if(display[2]==0x30)//次高位为0,不显示
- {
- display[2]=0x20;
- if(display[1]==0x30)
- display[1]=0x20;
- }
- }
- }
- LCD_ComdWrite(0x9B);
- LCD_DataWrite(display[4]);
- LCD_DataWrite(display[3]);
- LCD_DataWrite(display[2]);
- LCD_DataWrite(display[1]);
- LCD_DataWrite(display[0]);
- LCD_DataWrite('H');
- LCD_DataWrite('Z');
- if(KEY_Get(KEY2))//KEY2光标移动
- {
- OSTimeDlyHMSM(0,0,0,100);
- if(KEY_Get(KEY2))
- {
- //LCD_ComdWrite(0x9c);
- //LCD_ComdWrite(0x0F);//开光标显示
- //LCD_DataWrite(aa+0x30);
- shi++;
- if(shi==10)
- {
- //aa=1;
- shi=0;
- bai++;
- if(bai==10)
- {
- bai=0;
- qian++;
- if(qian==10)
- {
- qian=0;
- wan++;
- if(wan==10)
- {
- wan=0;
- }
- dat=wan*10000+qian*1000+bai*100+shi*10;
- Write_9850(dat);
- }
- dat=wan*10000+qian*1000+bai*100+shi*10;
- Write_9850(dat);
- }
- dat=wan*10000+qian*1000+bai*100+shi*10;
- Write_9850(dat);
- }
-
- dat=wan*10000+qian*1000+bai*100+shi*10;
- Write_9850(dat);
-
- }
- display[4]=dat%100000/10000+0X30;//显示千位
- display[3]=dat%10000/1000+0X30;//显示千位
- display[2]=dat%1000/100+0X30;//显示百位
- display[1]=dat%100/10+0X30;//显示十位
- display[0]=dat%10+0X30;//显示个位
- if(display[4]==0x30)
- {
- display[4]=0x20;
- if(display[3]==0x30) //高位为0,不显示
- {
- display[3]=0x20;
- if(display[2]==0x30)//次高位为0,不显示
- {
- display[2]=0x20;
- if(display[1]==0x30)
- display[1]=0x20;
- }
- }
- }
- LCD_ComdWrite(0x9B);
- LCD_DataWrite(display[4]);
- LCD_DataWrite(display[3]);
- LCD_DataWrite(display[2]);
- LCD_DataWrite(display[1]);
- LCD_DataWrite(display[0]);
- LCD_DataWrite('H');
- LCD_DataWrite('Z');
- }
- }////正弦波
-
-
- if(num==2)// 显示方波
- {
- LCD_ComdWrite(0x93);
- LCD_ComdWrite(0x0C);//关光标
- Displayfang();// 显示方波
- dat2=wan2*10000+qian2*1000+bai2*100+shi2*10;
- Write_9850(dat2);
- display[4]=dat2%100000/10000+0X30;//显示千位
- display[3]=dat2%10000/1000+0X30;//显示千位
- display[2]=dat2%1000/100+0X30;//显示百位
- display[1]=dat2%100/10+0X30;//显示十位
- display[0]=dat2%10+0X30;//显示个位
- if(display[4]==0x30)
- {
- display[4]=0x20;
- if(display[3]==0x30) //高位为0,不显示
- {
- display[3]=0x20;
- if(display[2]==0x30)//次高位为0,不显示
- {
- display[2]=0x20;
- if(display[1]==0x30)
- display[1]=0x20;
- }
- }
- }
- LCD_ComdWrite(0x9B);
- LCD_DataWrite(display[4]);
- LCD_DataWrite(display[3]);
- LCD_DataWrite(display[2]);
- LCD_DataWrite(display[1]);
- LCD_DataWrite(display[0]);
- LCD_DataWrite('H');
- LCD_DataWrite('Z');
- if(KEY_Get(KEY2))//KEY2光标移动
- {
- OSTimeDlyHMSM(0,0,0,100);
- if(KEY_Get(KEY2))
- {
- //LCD_ComdWrite(0x9c);
- //LCD_ComdWrite(0x0F);//开光标显示
- //LCD_DataWrite(aa+0x30);
- shi2++;
- if(shi2==10)
- {
- //aa=1;
- shi2=0;
- bai2++;
- if(bai2==10)
- {
- bai2=0;
- qian2++;
- if(qian2==10)
- {
- qian2=0;
- wan2++;
- if(wan2==10)
- {
- wan2=0;
- }
- dat2=wan2*10000+qian2*1000+bai2*100+shi2*10;
- Write_9850(dat2);
- }
- dat2=wan2*10000+qian2*1000+bai2*100+shi2*10;
- Write_9850(dat2);
- }
- dat2=wan2*10000+qian2*1000+bai2*100+shi2*10;
- Write_9850(dat2);
- }
-
- dat2=wan2*10000+qian2*1000+bai2*100+shi2*10;
- Write_9850(dat2);
-
- }
- display[4]=dat2%100000/10000+0X30;//显示千位
- display[3]=dat2%10000/1000+0X30;//显示千位
- display[2]=dat2%1000/100+0X30;//显示百位
- display[1]=dat2%100/10+0X30;//显示十位
- display[0]=dat2%10+0X30;//显示个位
- if(display[4]==0x30)
- {
- display[4]=0x20;
- if(display[3]==0x30) //高位为0,不显示
- {
- display[3]=0x20;
- if(display[2]==0x30)//次高位为0,不显示
- {
- display[2]=0x20;
- if(display[1]==0x30)
- display[1]=0x20;
- }
- }
- }
- LCD_ComdWrite(0x9B);
- LCD_DataWrite(display[4]);
- LCD_DataWrite(display[3]);
- LCD_DataWrite(display[2]);
- LCD_DataWrite(display[1]);
- LCD_DataWrite(display[0]);
- LCD_DataWrite('H');
- LCD_DataWrite('Z');
- }
- }// 显示方波
-
-
-
- if(num==3)// 显示三角波
- {
- LCD_ComdWrite(0x93);
- LCD_ComdWrite(0x0C);//关光标
- Displaythree();// 显示三角波
- dat3=wan3*10000+qian3*1000+bai3*100+shi3*10;
- Write_9850(dat3);
- display[4]=dat3%100000/10000+0X30;//显示千位
- display[3]=dat3%10000/1000+0X30;//显示千位
- display[2]=dat3%1000/100+0X30;//显示百位
- display[1]=dat3%100/10+0X30;//显示十位
- display[0]=dat3%10+0X30;//显示个位
- if(display[4]==0x30)
- {
- display[4]=0x20;//高位为0,不显示
- if(display[3]==0x30) //高位为0,不显示
- {
- display[3]=0x20;
- if(display[2]==0x30)//次高位为0,不显示
- {
- display[2]=0x20;
- if(display[1]==0x30)
- display[1]=0x20;
- }
- }
- }
- LCD_ComdWrite(0x9B);
- LCD_DataWrite(display[4]);
- LCD_DataWrite(display[3]);
- LCD_DataWrite(display[2]);
- LCD_DataWrite(display[1]);
- LCD_DataWrite(display[0]);
- LCD_DataWrite('H');
- LCD_DataWrite('Z');
- if(KEY_Get(KEY2))//KEY2光标移动
- {
- OSTimeDlyHMSM(0,0,0,100);
- if(KEY_Get(KEY2))
- {
- //LCD_ComdWrite(0x9c);
- //LCD_ComdWrite(0x0F);//开光标显示
- //LCD_DataWrite(aa+0x30);
- shi3++;
- if(shi3==10)
- {
- shi3=0;
- bai3++;
- if(bai3==10)
- {
- bai3=0;
- qian3++;
- if(qian3==10)
- {
- qian3=0;
- wan3++;
- if(wan3==10)
- {
- wan3=0;
- }
- dat3=wan3*10000+qian3*1000+bai3*100+shi3*10;
- Write_9850(dat3);
- }
- dat3=wan3*10000+qian3*1000+bai3*100+shi3*10;
- Write_9850(dat3);
- }
- dat3=wan3*10000+qian3*1000+bai3*100+shi3*10;
- Write_9850(dat3);
- }
-
- dat3=wan3*10000+qian3*1000+bai3*100+shi3*10;
- Write_9850(dat3);
-
- }
- display[4]=dat3%100000/10000+0X30;//显示千位
- display[3]=dat3%10000/1000+0X30;//显示千位
- display[2]=dat3%1000/100+0X30;//显示百位
- display[1]=dat3%100/10+0X30;//显示十位
- display[0]=dat3%10+0X30;//显示个位
- if(display[4]==0x30)
- {
- display[4]=0x20;
- if(display[3]==0x30) //高位为0,不显示
- {
- display[3]=0x20;
- if(display[2]==0x30)//次高位为0,不显示
- {
- display[2]=0x20;
- if(display[1]==0x30)
- display[1]=0x20;
- }
- }
- }
- LCD_ComdWrite(0x9B);
- LCD_DataWrite(display[4]);
- LCD_DataWrite(display[3]);
- LCD_DataWrite(display[2]);
- LCD_DataWrite(display[1]);
- LCD_DataWrite(display[0]);
- LCD_DataWrite('H');
- LCD_DataWrite('Z');
- }
- } // 显示三角波
- }
- }
- /**********************************************************
- 名称:Task1()
- 功能:执行相应功能
- ***********************************************************/
- void Task1(void *pdata)
- {
- pdata=pdata;
- while(1)
- {
- if(state==0)
- {
- temp=4.8;
- tt=temp*10;
- buff[0]=tt/10+0x30;
- buff[1]=tt%10+0x30;
- LCD_ComdWrite(0x8B);
- LCD_DataWrite(buff[0]);
- LCD_DataWrite('.');
- LCD_DataWrite(buff[1]);
- LCD_DataWrite('V');
- //LED_Toggle(LED1);
- state=1;
- }
- }
- }
- /****************************************
- 名称:Task2()
- 功能:按键控制
- *****************************************/
- void Task2(void *pdata)
- {
- pdata=pdata;
-
- while(1)
- {
- if(flag==0)
- {
- LED_Toggle(LED3);
- flag=1;
- …………限于本文篇幅 余下代码请从51黑下载附件…………
复制代码
下载:
函数信号发生器多任务程序(完成2 24C02).rar
(220.1 KB, 下载次数: 21)
完整论文下载word格式:
函数信号发生器.doc
(340.5 KB, 下载次数: 18)
|