简单信号发生器源程序C语言代码

合集下载

简易信号发生器

简易信号发生器

感谢我所在的小组,感谢集体,才能有这么个结晶。

希望大家多动手多实践。

这次设计所用仪器:唐都TDN-MI实验系统。

(80C51)体会最深的几点如下:1.一切得和实验设备联系起来,很多是唐都实验系统的限制,使得只有P1口既可以做输入口,又可以做输出口。

P2,P3,P4只能做输出口。

2.80C51的定时器和8253芯片定时器不同,必须每次都赋予初值。

3.程序开始后只要无跳转语句,就会依次往下执行,注意跳转语句,以控制程序正确流程。

4.启动了相应的中断,不能认为无中断程序就不执行中断,程序还会按中断的入口地址执行,所以不用的就不要设置它对应的IE位了。

5.为人民服务!^^6.出波的频率越高,效果越好。

故希望大家实现的频率应该从100Hz起。

中北大学硬件大型实验说明书:kai2094学号:院:电子与计算机科学技术学院专业:计算机科学与技术题目:简易信号发生器设计指导教师:乔志伟职称:2008年1月17日1.需求分析信号发生器是科学研究最常用电子仪器之一。

设计一简易信号发生器在平常教学、实验等精度要求不高的情况下,很有价值。

1.1功能需求:1、能产生方波、正弦波、三角波和锯齿波等。

2、产生的各种信号,要能改变其频率、和幅值。

3、可以产生以上三种信号波形的叠加(仅限于其频率相同)。

4、频率、幅值可以通过键盘设定。

5、在输出信号波形时,应显示其频率。

1.2实现过程:1、程序有两大部分:用户输入相关数据部分和依照设定输出相应波形部分。

故开启两个中断服务程序。

2、外部中断1服务程序用于用户输入相关数据部分。

通过键盘录入数据,LED数码管实时显示使系统有良好的人机交互界面。

根据用户输入,调用改变程序,改变系统出波的类型、频率、幅值。

3、定时器1中断服务程序中则会依照设定输出相应波形部分,同时显示其频率。

4、任何一个随时间变化的波形都可分解为许多离散的数据点,可设定一个周期可等分为50个点,每两点间时间间隔由定时器定时产生,通过改变定时器初值就可改变其频率;而幅值通过与波所能达到最大幅值成比例改变。

信号发生器程序

信号发生器程序
CJNE A,#0FFH,TRI3 ;判断第三象限是否输出完毕
TRI4: MOV DPTR,#9000H ;第四象限输出负值
MOV A,52H
MOVX @DPTR,A
DEC 52H ;输出值减1
MOVX @DPTR,A
ACALL WAVE_DELAY ;波形延时函数
MOV 51H,#00H ;51H单元用于存放方波的输出值
MOV DPTR,#9000H
MOV A,51H ;51H单元用于存放方波的输出值
GO2: CJNE R5,#02H,DIS_BOOT ;如果按下的是4按键就产生正弦波
AJMP SIN ;跳到正弦波发生函数
;锯齿波发生函数
SAW: MOV DPTR,#8004H ;8004H是数码管的段选地址
GO7: CJNE R5,#02H,SAW ;如果按下的是4按键就产生正弦波
AJMP SIN ;跳到正弦波发生函数
;方波发生函数
SQU: MOV DPTR,#8004H ;8004H是数码管的段选地址
ACALL KEY_EXAM ;在显示启动界面的同时检测键盘
JZ DIS_BOOT ;如果没有其他命令键按下就一直显示启动界面
ACALL DELAY
ACALL KEY_EXAM
JZ DIS_BOOT ;如果没有其他命令键按下就一直显示启动界面
GO0: CJNE R5,#05H,GO1 ;如果按下的是2按键就产生方波
AJMP SQU ;跳到方波发生函数
GO1: CJNE R5,#09H,GO2 ;如果按下的是3按键就产生三角波
AJMP TRI ;跳到三角波发生函数
MOVX @DPTR,A ;送段码值

DDS信号发生器设计源程序(DDSsignalgeneratordesignsource)

DDS信号发生器设计源程序(DDSsignalgeneratordesignsource)

DDS信号发生器设计源程序(DDS signal generator design source)Program codePrescaler module1, set number:LIBRARY IEEE;USE IEEE.STD_LOGIC_1164.ALL;USE IEEE.STD_LOGIC_ARITH.ALL;USE IEEE.STD_LOGIC_UNSIGNED.ALL;ENTITY Zhishu ISPORT (M:OUT STD_LOGIC_VECTOR (31, DOWNTO, 0));END ENTITY;ARCHITECTURE, func, OF, Zhishu, ISBEGINM < = "00000101010111100110001110111000";END ARCHITECTURE;Accumulation step control module2, step selection:LIBRARY IEEE;USE IEEE.STD_LOGIC_1164.ALL;USE IEEE.STD_LOGIC_ARITH.ALL;USE IEEE.STD_LOGIC_UNSIGNED.ALL;ENTITY bcxuanze ISPORT (bcxzmaichong:IN STD_LOGIC);Bc:BUFFER STD_LOGIC_VECTOR (19, DOWNTO, 0);END ENTITY;ARCHITECTURE, func, OF, bcxuanze, ISSIGNAL bc1:STD_LOGIC_VECTOR (19, DOWNTO, 0): = "00000000000000000001"";SIGNAL bc2:STD_LOGIC_VECTOR (19, DOWNTO, 0): = "00000000000000001010"";SIGNAL bc3:STD_LOGIC_VECTOR (19, DOWNTO, 0): = "00000000000000110010"";SIGNAL bc4:STD_LOGIC_VECTOR (19, DOWNTO, 0): = "00000000000001100100"";SIGNAL bc5:STD_LOGIC_VECTOR (19, DOWNTO, 0): = "00000000001111101000"";SIGNAL tmp:STD_LOGIC_VECTOR (19, DOWNTO, 0);BEGINPROCESS (bcxzmaichong)BEGINIF, bcxzmaichong'EVENT, AND, bcxzmaichong ='1', THENBC < = bc1;BC1 < = bc2;BC2 < = bc3;BC3 < = bc4;Bc4 < = bc5;Bc5 < = bc;END IF;END PROCESS;END ARCHITECTURE;3, cumulative controlLIBRARY IEEE;USE IEEE.STD_LOGIC_1164.ALL;USE IEEE.STD_LOGIC_ARITH.ALL;USE IEEE.STD_LOGIC_UNSIGNED.ALL;ENTITY kongzhi ISPORT (key:IN STD_LOGIC);Clr:IN STD_LOGIC;M:IN STD_LOGIC_VECTOR (19, DOWNTO, 0);Fout:BUFFER STD_LOGIC_VECTOR (19, DOWNTO, 0); END ENTITY;ARCHITECTURE, func, OF, kongzhi, ISBEGINPROCESS (key, CLR)BEGINIF CLR ='0'THENIF, key'EVENT, AND, key ='1', THEN IF fout > 10000 THENFout < = M;ELSEFout < = fout + M;END IF;END IF;ELSEFout < = "00000000000000000000"; END IF;END PROCESS;END ARCHITECTURE;Display module4 frequency displayLIBRARY IEEE;USE IEEE.STD_LOGIC_1164.ALL;USE IEEE.STD_LOGIC_ARITH.ALL;USE IEEE.STD_LOGIC_UNSIGNED.ALL;ENTITY Xianshi ISPORT (foutin:IN STD_LOGIC_VECTOR (19, DOWNTO, 0); Clk:IN STD_LOGIC;Num1:OUT STD_LOGIC_VECTOR (6, DOWNTO, 0);Num2:OUT STD_LOGIC_VECTOR (6, DOWNTO, 0);Num3:OUT STD_LOGIC_VECTOR (6, DOWNTO, 0);Num4:OUT STD_LOGIC_VECTOR (6, DOWNTO, 0);Num5:OUT STD_LOGIC_VECTOR (6, DOWNTO, 0);END ENTITY;ARCHITECTURE, func, OF, Xianshi, ISSIGNAL dec:INTEGER;BEGINDec CONV_INTEGER (foutin); PROCESS (CLK)BEGIN如果clk'event和时钟=“1”然后病例10当0=>num1 < =“1000000”;当1=>num1 < =“1111001”;当2=>num1 < =“0100100”;当3=>num1 < =“0110000”;当4=>num1 < =“0011001”;当5=>num1 < =“0010010”;当6=>num1 <=“00000 10”;当7=>num1 < =“1111000”;当8=>num1 < =“0000000”;当9=>num1 < =“0010000”;当别人= > num1 < =“1111111”;案例;案例(DEC REM 100)/ 10是当0=>num2 < =“1000000”;当1=>num2 < =“1111001”;当2=>num2 < =“0100100”;当3=>num2 < =“0110000”;当4=>num2 < =“0011001”;当5=>num2 < =“0010010”;当6 = > < =“00000 10”num2;当7=>num2 < =“1111000”;当8=>num2 < =“0000000”;当9=>num2 < =“0010000”;当别人= > num1 < =“1111111”;案例;案例(DEC REM 1000)/ 100是当0=>小键盘数字3 < =“1000000”;当1=>小键盘数字3 < =“1111001”;当2=>小键盘数字3 < =“0100100”;当3=>小键盘数字3 < =“0110000”;当4=>小键盘数字3 < =“0011001”;当5=>小键盘数字3 < =“0010010”;当6 = > < =“00000 10”小键盘数字3;当7=>小键盘数字3 < =“1111000”;当8=>小键盘数字3 < =“0000000”;当9=>小键盘数字3 < =“0010000”;当别人= > num1 < =“1111111”;案例;案例(DEC REM 10000)/ 1000是当0=>NUM4 < =“1000000”;当1=>NUM4 < =“1111001”;当2=>NUM4 < =“0100100”;当3=>NUM4 < =“0110000”;当4=>NUM4 < =“0011001”;当5=>NUM4 < =“0010010”;当6=>NUM4 <=”00000 10”;当7=>NUM4 < =“1111000”;当8=>NUM4 < =“0000000”;当9=>NUM4 < =“0010000”;当别人= > num1 < =“1111111”;案例;十二月10000日是当0=> num5 < =“1000000”;当1=> num5 < =“1111001”;当2=> num5 < =“0100100”;当3=> num5 < =“0110000”;当4=> num5 < =“0011001”;当5=> num5 < =“0010010”;当6=> num5 < =“00000 10”;当7=> num5 < =“1111000”;当8=> num5 < =“0000000”;当9=> num5 < =“0010000”;当别人= > num1 < =“1111111”;案例;最后如果;结束进程;端架构;波形存储模块5、提取高8位图书馆的IEEE;使用ieee.std_logic_1164.all;使用ieee.std_logic_arith.all;使用ieee.std_logic_unsigned.all;实体转换为端口(zh_in:在std_logic_vector(19到0);zh_out:出std_logic_vector(7到0));终端实体;是建筑功能的转换开始过程(zh_in)开始zh_out(7)< = zh_in(19);an _ out (6) < = zh _ in (18)._ out (5)) = zh _ in (17)._ out) (4) = zh _ in (16).an _ out (3) < = zh _ in (15)._.) (2) < = zh _ in (14)._ out) (1) < = zh _ in (13).an _ out (0) < = zh _ in (12).end process;end architecture.6、方波生成library ieee;use ieee.std _ logic _ 1164.all.use ieee.std _ logic _ arith.all.use ieee.std _ logic _ unsigned.all.the entity fangboport (fb _ in std _ logic.in _ fbclk std logic;for all _ out std _ logic _ vector (7 downto 0). end entity.the architecture of fangbo funcbeginprocess for _, fbclk)beginif fbclk'event and fbclk =' 1 '.for i in 0 to 7 loopfor _ out (i) < = fb _.end loop;end if;end process;end architecture.7、四路选通library ieee;use ieee.std _ logic _ 1164.all.use ieee.std _ logic _ arith.all. use ieee.std _ logic _ unsigned.all. the company xuanzeport (xzmaichong: in std _ logic.input1: in std _ logic _ vector (7 downto 0). input2: in std _ logic _ vector (7 downto 0). input3: in std _ logic _ vector (7 downto 0). input4: in std _ logic _ vector (7 downto 0). output: out std _ logic _ vector (7 downto 0). end entity.the architecture of xuanze funcsignal count: integer range 0 to 3).beginprocess (xzmaichong)beginif xzmaichong'event and xzmaichong =' 1 '. count = count + 1.end if;if count = 0 thenoutput = input1.elsif count = 1 then output = input2. elsif count = 2 then output = input3. elseoutput = input4.end if;end process;end architecture.。

函数信号发生器源程序

函数信号发生器源程序

#include<reg52.h>#include<absacc.h>#define DAC0832 XBYTE[0x0fff]int pinlv=256; //改变频率的时延自变量sbit p20=P2^0;sbit p21=P2^1;sbit p22=P2^2;sbit p23=P2^3;sbit RS=P3^0;sbit RW=P3^1; //液晶显示的端口sbit E=P3^4;int j=0;unsigned char code TAB[]="0123456789msTIME:";unsigned char code TAB1[]="zhengxianbofangbo sanjiaobo jvchibo "; unsigned char table[4];float code table2[]={ //正弦波信号采点值0x80,0x83,0x85,0x88,0x8A,0x8D,0x8F,0x92,0x94,0x97,0x99,0x9B,0x9E,0xA0,0xA3,0 xA5,0xA7,0xAA,0xAC,0xAE,0xB1,0xB3,0xB5,0xB7,0xB9,0xBB,0xBD,0xBF,0xC1,0xC3,0xC5,0 xC7,0xC9,0xCB,0xCC,0xCE,0xD0,0xD1,0xD3,0xD4,0xD6,0xD7,0xD8,0xDA,0xDB,0xDC,0xDD,0 xDE,0xDF,0xE0,0xE1,0xE2,0xE3,0xE3,0xE4,0xE4,0xE5,0xE5,0xE6,0xE6,0xE7,0xE7,0xE7,0 xE7,0xE7,0xE7,0xE7,0xE7,0xE6,0xE6,0xE5,0xE5,0xE4,0xE4,0xE3,0xE3,0xE2,0xE1,0xE0,0 xDF,0xDE,0xDD,0xDC,0xDB,0xDA,0xD8,0xD7,0xD6,0xD4,0xD3,0xD1,0xD0,0xCE,0xCC,0xCB,0 xC9,0xC7,0xC5,0xC3,0xC1,0xBF,0xBD,0xBB,0xB9,0xB7,0xB5,0xB3,0xB1,0xAE,0xAC,0xAA,0 xA7,0xA5,0xA3,0xA0,0x9E,0x9B,0x99,0x97,0x94,0x92,0x8F,0x8D,0x8A,0x88,0x85,0x83,0 x80,0x7D,0x7B,0x78,0x76,0x73,0x71,0x6E,0x6C,0x69,0x67,0x65,0x62,0x60,0x5D,0x5B,0 x59,0x56,0x54,0x52,0x4F,0x4D,0x4B,0x48,0x47,0x45,0x43,0x41,0x3F,0x3D,0x3B,0x39,0 x37,0x35,0x34,0x32,0x30,0x2F,0x2D,0x2C,0x2A,0x29,0x28,0x26,0x25,0x24,0x23,0x22,0 x21,0x20,0x1F,0x1E,0x1D,0x1D,0x1C,0x1C,0x1B,0x1B,0x1A,0x1A,0x1A,0x19,0x19,0x19,0 x19,0x19,0x19,0x19,0x19,0x1A,0x1A,0x1A,0x1B,0x1B,0x1C,0x1C,0x1D,0x1D,0x1E,0x1F,0 x20,0x21,0x22,0x23,0x24,0x25,0x26,0x28,0x29,0x2A,0x2C,0x2D,0x2F,0x30,0x32,0x34,0 x35,0x37,0x39,0x3B,0x3D,0x3F,0x41,0x43,0x45,0x47,0x49,0x4B,0x4D,0x4F,0x52,0x54,0 x56,0x59,0x5B,0x5D,0x60,0x62,0x65,0x67,0x69,0x6C,0x6E,0x71,0x73,0x76,0x78,0x7B,0 x7D};void delay(unsigned char ms); //延时函数void write_com(unsigned char com); //液晶写指令void write_data(unsigned char dat); //液晶写数据void LCD1602_init(void) //液晶初始化{delay(15);write_com(0x38);delay(5);write_com(0x38);delay(5);write_com(0x38);write_com(0x38);write_com(0x08);write_com(0x01);write_com(0x06);write_com(0x0C);}void write_com(unsigned char com){E=0; //复位初始为高电平RS=0;RW=0;P1=com;delay(1);E=1;delay(1);E=0;}void write_data(unsigned char dat){E=0; //复位初始为高电平RS=1;RW=0;P1=dat;delay(1);E=1;delay(1);E=0;}void delay(unsigned char ms) //晶振12KHz {unsigned char i;while(ms--){for(i=0;i<=120;i++);}}void fang() //方波{DAC0832=0;delay(pinlv/2);DAC0832=0xff;delay(pinlv/2);}void jvchi() //锯齿波{unsigned char i;for(i=0;i<255;i++){DAC0832=i;delay(pinlv/256);}}void tran() //三角波{unsigned char i;for(i=0;i<255;i++){DAC0832=i;delay(pinlv/256);}for(i=255;i>0;i--){DAC0832=i;delay(pinlv/256);}}void sin() //正弦波{unsigned int i;for(i=0;i<255;i++){DAC0832=table2[i];delay(pinlv/256);}}void main(void) //主函数{IE=0x85; //外部中断设定改变频率TCON=0x05;LCD1602_init();table[0]=pinlv/1000; //计算周期作为输出table[1]=pinlv%1000/100;table[2]=pinlv%100/10;table[3]=pinlv%10;write_com(0x80+0x40); //设置待写入数据的地址,写LCD1602的第2行写出产生波形的周期for(j=12;j<17;j++){write_data(TAB[j]);delay(1);}for(j=0;j<4;j++){write_data(TAB[table[j]]);delay(1);}write_data(TAB[10]); //在周期后面加上“MS”write_data(TAB[11]);while(1){if(p20==0) //方波{write_com(0x80); //写LCD1602的第1行,写明产生的波形for(j=11;j<22;j++){write_data(TAB1[j]);}while(p20==0)fang();}if(p21==0) //锯齿波{write_com(0x80); //写LCD1602的第2行for(j=33;j<44;j++){write_data(TAB1[j]);}while(p21==0)jvchi();}if(p22==0) //三角波{write_com(0x80); //写LCD1602的第2行for(j=22;j<33;j++){write_data(TAB1[j]);}while(p22==0)tran();}if(p23==0) //正弦波{write_com(0x80); //写LCD1602的第2行for(j=0;j<11;j++){write_data(TAB1[j]);}while(p23==0)sin();}}}void int0(void) interrupt 0 //中断0 降频{pinlv=pinlv*2; //频率减半table[0]=pinlv/1000;table[1]=pinlv%1000/100;table[2]=pinlv%100/10;table[3]=pinlv%10;write_com(0x80+0x40); //设置代写入数据的地址,写LCD1602的第2行for(j=12;j<17;j++){write_data(TAB[j]);delay(1);}for(j=0;j<4;j++){write_data(TAB[table[j]]);delay(1);}write_data(TAB[10]);write_data(TAB[11]);}void int1(void) interrupt 2 //中断2 升频{pinlv=pinlv/2;table[0]=pinlv/1000;table[1]=pinlv%1000/100;table[2]=pinlv%100/10;table[3]=pinlv%10;write_com(0x80+0x40); //设置代写入数据的地址,写LCD1602的第1行for(j=12;j<17;j++){write_data(TAB[j]);delay(1);}for(j=0;j<4;j++){write_data(TAB[table[j]]);delay(1);}write_data(TAB[10]);write_data(TAB[11]);}。

基于单片机设计的简易信号发生器

基于单片机设计的简易信号发生器

辽东学院信息技术学院《单片机原理与接口技术》课程设计报告函数发生器设计学生姓名:学号: 0915110602班级: B1106专业:电子信息工程指导教师:2014年07月【摘要】本设计是一个基于单片机的简易函数发生器,函数信号发生器的设计方法有多种,利用单片机设计的函数信号发生器具有编程灵活、显示清楚等优点。

它能产生方波、正弦波、锯齿波和三角波四种波形。

在编程语言上,此处选择了简单易行的C语言程序。

经过不断改进,现在已实现了所有与其目标。

关键词:单片机函数发生波形 C语言目录绪论......................................................... .1 1系统工作原理. (2)1.1 功能说明 (2)1.2基本原理 (2)2 硬件设计 (3)2.1 单片机最小系统单元 (3)2.2波形产生模块设计 (7)2.3 独立式键盘模块设计 (9)3 软件设计 (10)3.1 主程序流程图 (11)4 结论 (11)5.调试 (15)参考文献........................................ 错误!未定义书签。

附录A 源程序 (16)附录B 系统原理图 (22)绪论1、单片机概述随着大规模集成电路技术的发展,中央处理器(CPU)、随机存取存储器(RAM)、只读存储器(ROM)、(I/O)接口、定时器/计数器和串行通信接口,以及其他一些计算机外围电路等均可集成在一块芯片上构成单片微型计算机,简称为单片机。

单片机具有体积小、成本低,性能稳定、使用寿命长等特点。

其最明显的优势就是可以嵌入到各种仪器、设备中,这是其他计算机和网络都无法做到的。

2、信号发生器的分类信号发生器应用广泛,种类繁多,性能各异,分类也不尽一致。

按照频率范围分类可以分为:超低频信号发生器、低频信号发生器、视频信号发生器、高频波形发生器、甚高频波形发生器和超高频信号发生器。

信号发生器参考程序

信号发生器参考程序

#include "C8051F020.h"#include "sysinit.h"#include "keyscan.h"#include "dac.h"#include "lcd1602.h"#include <stdio.h> //sprintf函数需要用到的头文件#include <math.h>void f_sine(void);void f_square(void);void f_triangle(void);void f_sine(void); //定义波形函数void f_square(void);void f_triangle(void);void ADD(void);void SUBB(void);void delay(int);void delay(int);extern unsigned int code sine[]; //正弦波波形extern unsigned int code square[]; //方波波形extern unsigned int code triangle[]; //三角波波形extern unsigned int code sine[]; //正弦波波形extern unsigned int code square[]; //方波波形extern unsigned int code triangle[]; //三角波波形unsigned int scan=0; //波形查表计数unsigned int flag=0; //标志位unsigned int biaozi=0; //运用在加减时的小数点后几位unsigned int digit=0; //记录光标的位置unsigned int flag_1=0; //运用在加减时的标志位unsigned int jianzhi=0; //键按下标志unsigned int key_ad=0;unsigned int conter=0;unsigned char key_value=0xff,lcd_i=6;unsigned char key_m=0;unsigned char wxh=0;unsigned char lcd_buff0[16]={"print: Hz "};//1602显示缓冲区unsigned char lcd_buff1[16]={"frequ: Hz "};unsigned int degree=0; //用与记录小数点后几位,然后用来计算小数点bit key_f=0;int key_v1=0;int key_cd=0;int frequency=100; //频率float decimals=0; //小数点后位初值float fre=0;void main(void){CloseWDT(); //关闭看门狗SysClkInit(); //配置系统时钟,使用外部晶振,系统上电默认使用内部2M时钟PortInit(); //I/O端口配置LCD1602_Init(); //lcd1602初始化DAC0_Init(); //DAC0初始化DAC1_Init(); //DAC1初始化CKCON = 0x20; //将定时器0、1、2、4的时钟选择为系统时钟24M 不分频T2CON = 0x00; //将定时器2配置为16位自动装载定时模式TH2 = 0xFE; //装初始值,在24M时钟下,中断时间为15.25uSTL2 = 0x92; //装初始值RCAP2H = 0xFE; //重载寄存器高位初始值RCAP2L = 0x92; //重载寄存器低位初始值ET2 = 1; //允许定时器2中断EA = 1; //中断总允许TR2 = 1; //启动定时器2TMOD=0x01;TH0=0xB1;TL0=0xE0;ET0=1;DAC0_Out_V(1.250); //DAC0输出1.25VDAC1_Out_V(2.500); //DAC1输出2.5Vwhile(1){key_value = Get_Key(); //扫描键盘if(TR0==1) //判断1S时间有没有到{key_value = Get_Key();//长按键扫描delay(5000);//延时0.25秒的间隔延时加上下面必要执行的0.25秒延时刚好是0.5秒的延时}else{delay(2500);}if(key_value != 13&&key_value!=14){TR0=0;conter=0;}if(key_value != 0xff){if(lcd_i==11) //当显示的值已经超过了显示的范围则直接将此次显示的值改为确认值key_value=11;switch(key_value) //用与调整频率{case 0:if(flag==0) //判断是否有按下小数点,当flag为1时有小数点被按下{fre *= 10; fre += 1; lcd_buff0[lcd_i] = 1+0x30; lcd_i++;}//按下1else{degree += 1;decimals *= 10;decimals += 1;lcd_buff0[lcd_i] = 1+0x30; lcd_i++; //当有小数点被按下时对小数点进行操作} break;case 1:if(flag==0){fre *= 10; fre += 4; lcd_buff0[lcd_i] = 4+0x30; lcd_i++;}//按下4else{degree += 1;decimals *= 10;decimals += 4;lcd_buff0[lcd_i] = 4+0x30; lcd_i++;}break;case 2: if(flag==0){fre *= 10; fre += 7; lcd_buff0[lcd_i] = 7+0x30; lcd_i++;}//按下7else{degree += 1;decimals *= 10;decimals += 7;lcd_buff0[lcd_i] = 7+0x30; lcd_i++;}break;case 3: fre = 0; lcd_i = 6; flag=0;decimals=0;degree=0;scan = 0; //按下* 取消取消之前按的的键值lcd_buff0[6] = 0x20; lcd_buff0[7] = 0x20; lcd_buff0[8] = 0x20;lcd_buff0[9] = 0x20; lcd_buff0[10] = 0x20; lcd_buff0[11] = 0x20;break;case 4: if(flag==0){fre *= 10; fre += 2; lcd_buff0[lcd_i] = 2+0x30; lcd_i++;}//按下2else{degree += 1;decimals *= 10;decimals += 2;lcd_buff0[lcd_i] = 2+0x30; lcd_i++;} break;case 5: if(flag==0){fre *= 10; fre += 5; lcd_buff0[lcd_i] = 5+0x30; lcd_i++;}//按下5else{degree += 1;decimals *= 10;decimals += 5;lcd_buff0[lcd_i] = 5+0x30; lcd_i++;} break;case 6: if(flag==0){fre *= 10; fre += 8; lcd_buff0[lcd_i] = 8+0x30; lcd_i++;}//按下8else{degree += 1;decimals *= 10;decimals += 8;lcd_buff0[lcd_i] = 8+0x30; lcd_i++;}break;case 7: if(flag==0)//按下0{fre *= 10; fre += 0; lcd_buff0[lcd_i] = 0+0x30; lcd_i++;}else{degree += 1;decimals *= 10;decimals += 0;lcd_buff0[lcd_i] = 0+0x30; lcd_i++;}break;case 8: if(flag==0){fre *= 10; fre += 3; lcd_buff0[lcd_i] = 3+0x30; lcd_i++;}//按下3else{degree += 1;decimals *= 10;decimals += 3;lcd_buff0[lcd_i] = 3+0x30; lcd_i++;}break;case 9: if(flag==0){fre *= 10; fre += 6; lcd_buff0[lcd_i] = 6+0x30; lcd_i++;}//按下6else{degree += 1;decimals *= 10;decimals += 6;lcd_buff0[lcd_i] = 6+0x30; lcd_i++;} break;case 10:if(flag==0){fre *= 10; fre += 9; lcd_buff0[lcd_i] = 9+0x30; lcd_i++;}//按下9else{degree += 1;decimals *= 10;decimals += 9;lcd_buff0[lcd_i] = 9+0x30; lcd_i++;} break;case 15:if(flag==0)//按下小数点{if(fre==0)//当开始时没有按下整数部位而直接按下小数点,则直接给整数部位致1{lcd_i = 6;lcd_buff0[lcd_i]=0+0x30;lcd_i++;}lcd_buff0[lcd_i] = 14+0x20; lcd_i++;flag=1;//显示小数点并给标志位flag致1} break;case 11: if(fre||flag==1) //按下# 确定将之前按下的键值组成一个数作为频率{if(flag==1) //当有小数部位时对小数先进行操作根据四舍五入原则{decimals /= pow(10,degree);if(decimals>=0.5){fre += decimals;fre +=1;}else{fre += decimals;}}frequency = fre; fre = 0;scan = 0;flag_1=flag;flag=0;biaozi=degree;degree=0;dec imals=0; //重新赋初值lcd_buff1[6] = lcd_buff0[6]; lcd_buff1[7] = lcd_buff0[7];lcd_buff1[8] = lcd_buff0[8]; lcd_buff1[9] = lcd_buff0[9];lcd_buff1[10] = lcd_buff0[10];lcd_buff1[11] = lcd_buff0[11]; lcd_buff0[6] = 0x20;//清除第一行的显示频率值lcd_buff0[7] = 0x20; lcd_buff0[8] = 0x20;lcd_buff0[9] = 0x20; lcd_buff0[10] = 0x20;lcd_buff0[11] = 0x20;digit=lcd_i;lcd_i = 6;}break;case 12: if(key_m<3) key_m++; //按下A正弦→方波→三角波,切换波形else key_m = 1; //默认为正弦scan = 0; break;case 13: lcd_i = digit; //加法TR0=1;ADD(); //加法操作lcd_i=6;break;case 14:lcd_i = digit;//减法TR0=1;SUBB(); //减法操作lcd_i=6;break;default: break;}}LCD_SET_CURSOR(1,1); //设置1602显示坐标在第一行第一个字Print(lcd_buff0,16); //LCD1602显示第一行LCD_SET_CURSOR(2,1); //设置1602显示坐标在第二行第一个字Print(lcd_buff1,16); //LCD1602显示第二行}}void delay0(void) interrupt 5{TF2 = 0; //清除中断标志位if(key_m == 1) f_sine();if(key_m == 2) f_square();if(key_m == 3) f_triangle();}void f_sine(void) //正弦{lcd_buff0[0]='s';lcd_buff0[1]='i';lcd_buff0[2]='n';lcd_buff0[3]=0x20;lcd_buff0[4]=0x20;scan += frequency;DAC0L = sine[(unsigned char)(scan>>8)];//取scan的高八位数据然后从sine数组中取出低八位数据(直接赋值只能赋值8位)DAC0H = sine[(unsigned char)(scan>>8)]>>8;//取scan的高八位数据然后从sine数组中取出高四位(sine数组中含有的是12位数字右移8位达到取高4位数字的目地)}void f_square(void) //方波{lcd_buff0[0]='s';lcd_buff0[1]='q';lcd_buff0[2]='u';lcd_buff0[3]='a';lcd_buff0[4]='r';lcd_buff0[5]=0 x20;scan += frequency;DAC0L = square[(unsigned char)(scan>>8)];DAC0H = square[(unsigned char)(scan>>8)]>>8;}void f_triangle(void) //三角波{lcd_buff0[0]='t';lcd_buff0[1]='r';lcd_buff0[2]='i';lcd_buff0[3]='a';lcd_buff0[4]='n';lcd_buff0[5]=0 x20;scan += frequency;DAC0L = triangle[(unsigned char)(scan>>8)];DAC0H = triangle[(unsigned char)(scan>>8)]>>8;}key_value1=Get_Key( );while(key_value==key_value1){key_value1=Get_Key();if(key_value==key_value1)//&&key_cd==1) //定时0.5s,每隔0.5秒自动加10{ADD();LCD_SET_CURSOR(1,1); //设置1602显示坐标在第一行第一个字Print(lcd_buff0,16); //LCD1602显示第一行LCD_SET_CURSOR(2,1); //设置1602显示坐标在第二行第一个字Print(lcd_buff1,16); //LCD1602显示第二行delay(20000);jianzhi=1;}}void time(void)interrupt 1 //只是起到了标志执行加减操作为键盘扫描是否长按无效做准备{TF0=0;TH0=0xB1;TL0=0xE0;}void ADD(void){conter++;if(conter == 2){delay(10000);key_value = Get_Key();}if( key_value==13){if(fre!=wxh){if(wxh!=0){while(fre>10){fre -=10;}wxh=fre;}else{wxh=fre;}}else{wxh=fre;}if(wxh<=10){if(wxh==10){if(flag_1==1) //判断要操作的数是否是小数,因为有小数的找十位光标的方法和没小数的有区别{lcd_i = lcd_i-biaozi-3; //当有小数点时应该用当前的光标值减去小数位数加1然后减去小数点和个位}else{lcd_i -=2; //当是整数时直接后退两位找到光标}if(frequency<10000) //判断平率是否小于10000,小于10000进行加操作{frequency += 10; //频率加10if(lcd_buff1[lcd_i]<9+0x30)//当十位小于9并且不为冒号时{lcd_buff1[lcd_i] +=1;//十位加1}else if(lcd_buff1[lcd_i] ==':') //如果数小于10右移显示后在最前面显示1{lcd_buff1[11] = lcd_buff1[10];lcd_buff1[10] = lcd_buff1[9];lcd_buff1[9] = lcd_buff1[8];lcd_buff1[8]=lcd_buff1[7];lcd_buff1[7] = '0';lcd_buff1[6] = '1';digit++;}else if(lcd_buff1[lcd_i]==9+0x30)//如果十位等于9则判断高位是否等于9,如果高位不为9则高位加1十位清0,当高位也为9时继续判断高高位如果一直为9则继续直到符合情况并且小于10000{if (lcd_buff1[lcd_i-1]<9+0x30){lcd_buff1[lcd_i]='0';lcd_buff1[lcd_i-1] +=1;}else if(lcd_buff1[lcd_i-1] ==':'){lcd_buff1[11] = lcd_buff1[10];lcd_buff1[10] = lcd_buff1[9];lcd_buff1[9] = lcd_buff1[8];lcd_buff1[8]=lcd_buff1[7] ;lcd_buff1[7] = '0';lcd_buff1[6] = '1';digit++;}else if(lcd_buff1[lcd_i-1]==9+0x30){if (lcd_buff1[lcd_i-2]<9+0x30){lcd_buff1[lcd_i-1]='0';lcd_buff1[lcd_i-2] +=1;}else if(lcd_buff1[lcd_i-2] ==':'){lcd_buff1[11] = lcd_buff1[10];lcd_buff1[10] = lcd_buff1[9];lcd_buff1[9] = lcd_buff1[8];lcd_buff1[8]=lcd_buff1[7];lcd_buff1[7] = '0';lcd_buff1[6] ='1';digit++;}else if(lcd_buff1[lcd_i-2]==9+0x30){lcd_buff1[11]=0x20;lcd_buff1[10] = '0' ;lcd_buff1[9] = '0';lcd_buff1[8]='0';lcd_buff1[7] = '0';lcd_buff1[6] ='1';digit++;}}}}} //操作一步加10if(wxh<10){if(flag_1==1) //判断要操作的数是否是小数,因为有小数的找十位光标的方法和没小数的有区别{lcd_i = lcd_i-biaozi-2; //当有小数点时应该用当前的光标值减去小数位数加1然后减去小数点和个位}else{lcd_i -=1; //当是整数时直接后退两位找到光标}if(frequency<10000) //判断平率是否小于10000,小于10000进行加操作{frequency += wxh; //频率加freif(lcd_buff1[lcd_i]+fre<=9+0x30)//当十位小于9并且不为冒号时{lcd_buff1[lcd_i] +=wxh;//个位加1}else if(lcd_buff1[lcd_i]+wxh>9+0x30){if(lcd_buff1[lcd_i-1]<9+0x30){lcd_buff1[lcd_i-1] += 1;lcd_buff1[lcd_i] = lcd_buff1[lcd_i]+(fre-10);}else if(lcd_buff1[lcd_i-1]==':'){lcd_buff1[lcd_i] = lcd_buff1[lcd_i]+(fre-10);lcd_buff1[11] = lcd_buff1[10];lcd_buff1[10] = lcd_buff1[9];lcd_buff1[9] = lcd_buff1[8];lcd_buff1[8]=lcd_buff1[7];lcd_buff1[7] = lcd_buff1[6];lcd_buff1[6] = '1';digit++;}else if(lcd_buff1[lcd_i-1] == 9+0x30){lcd_buff1[lcd_i] = lcd_buff1[lcd_i]+fre-10;lcd_buff1[lcd_i-1] = '0';if(lcd_buff1[lcd_i-2] <9+0x30){lcd_buff1[lcd_i-2] += 1;}else if(lcd_buff1[lcd_i-2]==':' ){lcd_buff1[11] = lcd_buff1[10];lcd_buff1[10] = lcd_buff1[9];lcd_buff1[9] = lcd_buff1[8];lcd_buff1[8]=lcd_buff1[7];lcd_buff1[7] = lcd_buff1[6];lcd_buff1[6] = '1';digit++;}else if(lcd_buff1[lcd_i-2]==9+0x30 ){lcd_buff1[lcd_i-2]='0';if(lcd_buff1[lcd_i-3] <9+0x30 ){lcd_buff1[lcd_i-3] += 1;}else if(lcd_buff1[lcd_i-3]==':'){lcd_buff1[11] = lcd_buff1[10];lcd_buff1[10] = lcd_buff1[9];lcd_buff1[9] = lcd_buff1[8];lcd_buff1[8]=lcd_buff1[7];lcd_buff1[7] = lcd_buff1[6] ;lcd_buff1[6] = '1';digit++;}else if(lcd_buff1[lcd_i-3]==9+0x30){lcd_buff1[11]=0x20;lcd_buff1[10] = '0' ;lcd_buff1[9] = '0';lcd_buff1[8]='0';lcd_buff1[7] = '0';lcd_buff1[6] ='1';digit++;}}}}}}}}void SUBB(void){conter++;if(conter== 2)//判断是否是延时1秒的时间的长按{delay(10000);key_value = Get_Key();}if( key_value==14){if(fre!=wxh){if(wxh!=0){while(fre>10)fre -=10;}wxh=fre;}else{wxh=fre;}}else{wxh=fre;}if(wxh<=10){if(wxh==10){if(flag_1==1) //将光标指到十位{lcd_i = lcd_i-biaozi-3;}else{lcd_i -=2;}if(frequency>=10)//判断频率是否大于10 只有在大于10 的情况下再进行减10操作{frequency -= 10;//对频率进行减10操作if(lcd_buff1[lcd_i]!= '0')//判断十位是否为0如果不为零则直接对十位数进行操作,如果为0则需要进行借位{lcd_buff1[lcd_i] -= 1;if(lcd_buff1[lcd_i]=='0'&&lcd_buff1[lcd_i-1]==':')//当减10后最高为为0则需要将数据不包括最最高位左移{lcd_buff1[6] = lcd_buff1[7];lcd_buff1[7] = lcd_buff1[8];lcd_buff1[8] = lcd_buff1[9];lcd_buff1[9] = lcd_buff1[10];lcd_buff1[10] = lcd_buff1[11];digit--;}}else if(lcd_buff1[lcd_i] == '0') //当十位为10时进行借位{lcd_buff1[lcd_i] = '9';if(lcd_buff1[lcd_i-1]!='0'){lcd_buff1[lcd_i-1] -= 1;if(lcd_buff1[lcd_i-1]=='0'&&lcd_buff1[lcd_i-2]==':')//当减10后最高为为0则需要将数据不包括最最高位左移{lcd_buff1[6] = lcd_buff1[7];lcd_buff1[7] = lcd_buff1[8];lcd_buff1[8] = lcd_buff1[9];lcd_buff1[9] = lcd_buff1[10];lcd_buff1[10] = lcd_buff1[11];digit--;}}else if(lcd_buff1[lcd_i-1]=='0'){if(lcd_buff1[lcd_i-2]!='0'){lcd_buff1[lcd_i-2] -= 1;lcd_buff1[lcd_i-1]='9';if(lcd_buff1[lcd_i-2]=='0'&&lcd_buff1[lcd_i-3]==':') //当减10后最高为为0则需要将数据不包括最最高位左移{lcd_buff1[6] = lcd_buff1[7];lcd_buff1[7] = lcd_buff1[8];lcd_buff1[8] = lcd_buff1[9];lcd_buff1[9] = lcd_buff1[10];lcd_buff1[10] = lcd_buff1[11];digit--;}}else if(lcd_buff1[lcd_i-2]=='0'){lcd_buff1[11]=0x20; lcd_buff1[10]=0x20;lcd_buff1[9] = '0';lcd_buff1[8]='9';lcd_buff1[7] = '9';lcd_buff1[6] ='9';digit--;}}}}}//减10if(wxh<10){if(flag_1==1) //将光标指到十位{lcd_i = lcd_i-biaozi-2;}else{lcd_i -= 1;}if(frequency >fre) //判断频率是否大于0 只有在大于10 的情况下再进行减10操作{frequency -= wxh;if(lcd_buff1[lcd_i]-wxh>='0'){lcd_buff1[lcd_i]-= wxh;}else if(lcd_buff1[lcd_i]-wxh<'0'){if(lcd_buff1[lcd_i-1]>'0'){lcd_buff1[lcd_i]=lcd_buff1[lcd_i]+10-fre;lcd_buff1[lcd_i-1] -= 1;if(lcd_buff1[lcd_i-2]==':'&&lcd_buff1[lcd_i-1]=='0'){lcd_buff1[6]=lcd_buff1[7];lcd_buff1[7]=lcd_buff1[8];lcd_buff1[8]=lcd_buff1[9];lcd_buff1[9]=lc d_buff1[10];lcd_buff1[10]=lcd_buff1[11];digit--;}}else if(lcd_buff1[lcd_i-1]==0x30){if(lcd_buff1[lcd_i-2]>0x30){lcd_buff1[lcd_i-2] -= 1;lcd_buff1[lcd_i-1] = '9';lcd_buff1[lcd_i]=lcd_buff1[lcd_i]+10-fre;if(lcd_buff1[lcd_i-3]==':'&&lcd_buff1[lcd_i-2]=='0'){lcd_buff1[6]=lcd_buff1[7];lcd_buff1[7]=lcd_buff1[8];lcd_buff1[8]=lcd_buff1[9];lcd_buff1[9]=lc d_buff1[10];lcd_buff1[10]=lcd_buff1[11];digit--;}}else if (lcd_buff1[lcd_i-2]==0x30){lcd_buff1[lcd_i-2] = '9';lcd_buff1[lcd_i-1] = '9';lcd_buff1[lcd_i]=lcd_buff1[lcd_i]+10-fre;if(lcd_buff1[lcd_i-3]>0x30){lcd_buff1[lcd_i-3] -= 1;if(lcd_buff1[lcd_i-4]==':'&&lcd_buff1[lcd_i-3]=='0'){lcd_buff1[6]=lcd_buff1[7];lcd_buff1[7]=lcd_buff1[8];lcd_buff1[8]=lcd_buff1[9];lcd_buff1[9]=lc d_buff1[10];lcd_buff1[10]=lcd_buff1[11];digit--;}}else if(lcd_buff1[lcd_i-3]==0x30){lcd_buff1[lcd_i-3] = '9';lcd_buff1[6]=lcd_buff1[7];lcd_buff1[7]=lcd_buff1[8];lcd_buff1[8]=lcd_buff1[9];lcd_buff1[9]=lc d_buff1[10];lcd_buff1[10]=lcd_buff1[11];digit--;}}}}}}}}}void delay( int x){int i,j;for(i=0;i<x;i++)for(j=0;j<60;j++);}。

嵌入式系统及应用——简易信号发生器

嵌入式系统及应用——简易信号发生器

嵌入式系统及应用实验报告简易信号发生器作者:学号:班级:电子1001学院:电子信息工程学院作者:学号:班级:电子1003学院:电子信息工程学院简易信号发生器北京交通大学.北京.100044摘要:本实验所设计的“简易信号发生器”在硬件上是基于“嵌入式开发平台”实验箱,其上搭载有ST公司的基于ARM Cortex-M3内核的微控制器芯片 STM32 F103 ZET6 。

方案中使用此芯片作为主控芯片,控制矩阵键盘进行输入操作,同时控制LCD液晶进行图形用户界面的显示以及控制DAC芯片进行模拟波形的输出,除此之外使用MCU内部输出PWM 波形,从而输出方波。

软件编程使用IAR编程环境,对实验平台上的硬件编写相应的初始化函数和驱动函数等。

最后使用示波器对输出的波形进行测量与评估。

关键词:嵌入式开发;ARM;简易信号发生器;DAC;中图分类号:文献标志码:A信号发生器是一种能够产生多种波形,如三角波、锯齿波、矩形波(含方波)、正弦波的仪器。

函数信号发生器在电路实验和设备检测中具有十分广泛的用途。

通过对函数波形发生器的原理以及构成分析,可设计一个能变换出三角波、正弦波、方波的函数波形发生器。

本方案所设计的“简易信号发生器”能够产生三角波、锯齿波、矩形波(含方波)、正弦波。

方案中,主要通过定时器产生一定的时延来触发 DMA ,将一个已编好的“波形数组”通过 DMA 传送给 DAC 芯片产生模拟波形输出。

程序中通过改变定时器的时延,即可改变输出波形的频率。

此外,还编写了用户图形界面——基于 LCD 液晶的显示操作界面。

1 系统总体设计本章阐述“简易信号发生器”的整体设计方案,包括系统概述、设计要求、整体框图等。

1.1 系统概述本方案所设计的“简易信号发生器”所使用的硬件资源主要为实验室的“嵌入式开发平台”实验箱,其上搭载有ST公司的基于ARM Cortex-M3内核的微控制器芯片 STM32 F103 ZET6 。

信号发生器单片机程序PCF8591

信号发生器单片机程序PCF8591

/*置时钟线为高使数据线上数据有效*/
_Nop();
_Nop();
retc=retc<<1;
读数据位 接收的数据位放入 中 if(SDA==1)retc=retc+1; /*
,
retc */
_Nop();
_Nop();
}
SCL=0;
_Nop();
_Nop();
return(retc);
}
/********************************************************************
信号发生器程序信号发生器程序信号发生器程序信号发生器程序includereg52hincludeincludeunsignedcharcodesin1001280013597143921518015958167251747518918196052026520895214942205822586230752352323929242912460824878251012527525400254752550025475254002527525101248782429123929235232307522586220582149420895202651960518918182071747516725159581518014392135971280012003112081042096428875812573936682599553354705410635423014252520771671130999272249932520012510012520032549972299213091671207725253014354241064705533559956682739381258875964210420112081200312800sbitp14p14

afg3021c信号发生器编程指令

afg3021c信号发生器编程指令

一、概述afg3021c信号发生器是一种用于产生各种类型信号的仪器,它可以应用于电子电路测试、通信设备测试、传感器测试等多个领域。

在使用afg3021c信号发生器时,编程指令是非常重要的,它可以帮助用户实现自动化控制和快速测试。

本文将详细介绍afg3021c信号发生器的编程指令,帮助用户更好地使用该仪器。

二、基本概念1.1 仪器介绍afg3021c信号发生器是一种多功能、高性能的信号发生器。

它具有丰富的输出波形、快速的输出响应速度、灵活的调制功能等特点,适用于广泛的测试需求。

1.2 编程指令afg3021c信号发生器支持各种编程接口,包括GPIB、USB和LAN 接口。

用户可以通过这些接口发送指令给信号发生器,实现对仪器的控制和配置。

三、编程指令操作2.1 连接方式选择在使用afg3021c信号发生器编程指令之前,首先需要选择合适的连接方式。

用户可以根据实际情况选择GPIB、USB或LAN接口进行连接,确保信号发生器与控制设备之间的正常通信。

2.2 编程环境设置在进行编程指令操作之前,用户需要根据信号发生器的实际参数和要求进行编程环境设置。

包括波形选择、频率设置、幅度调整、相位设置等,确保编程指令操作的准确性和有效性。

2.3 编程指令格式afg3021c信号发生器的编程指令格式通常遵循特定的语法和规范,用户需要按照指定的格式来编写和发送指令。

在具体操作时需要注意指令的起始符、命令符、参数设置等信息。

2.4 指令发送与执行用户编写完编程指令后,可以通过相应的编程接口将指令发送给afg3021c信号发生器。

信号发生器接收到指令后将执行相应的操作,包括设置波形、调整频率、改变幅度等。

2.5 指令返回与确认在发送指令后,用户可以通过编程接口获取信号发生器的返回信息,以确认指令是否执行成功。

如果指令执行出现异常,用户可以根据返回信息进行相应的调试和处理。

四、实际应用3.1 单个指令操作afg3021c信号发生器的编程指令可以实现单个指令的操作,如设置特定波形、调整频率、改变幅度等。

信号发生器的编程资料

信号发生器的编程资料

Fo(MHz)=I IN(uA)/C F(PF)to= C F(PF)/ I IN(uA)V FADJ=-0.0343*DxV FADJ=3.34*(tx-to)/txFx=Fo*(1-[0.2915*V FADJ])V FADJ=(Fo-Fx)*(0.2915*Fo)I IN的最佳取值为100uA(取值范围为20uA~300uA)Dx为相对Fo变化的百分比V FADJ的电压允许变动的范围为(-2.4~+2.4V)Fx为输出频率Fo为当V FADJ=0V时的输出频率to为当V FADJ=0V时输出信号的周期tx为输出周期V DADJ=(50%-dc)*0.0575V DADJ=(0.5-[t ON/to])*5.75dc为占空比t ON为高电平在一个周期里的时间微调对频率的调节范围可以从0.3004倍调节到1.6996倍电容的单位为F 、uF(-6)、nF(-9)、pF(-12)。

缩小到0.3004倍的时候可以调节频率到2.7309Hz20uA 对9.0909Hz(-6) 2.2uF300uA 对136.3636Hz (-6) 2.2uF扩大到1.6996倍后可调节频率到231.7676Hz缩小到0.3004倍的时候可以调节频率到154.0512Hz20uA 对512.8205Hz(-6) 39nF300uA 对7692.3076Hz(-6) 39nF扩大到1.6996倍后可调节频率到13073.846Hz缩小到0.3004倍的时候可以调节频率到12782.9787Hz 20uA 对42553.1914Hz 470pF300uA 对638297.8723Hz 470pF扩大到1.6996倍后可调节频率到1084851.0638Hz缩小到0.3004倍的时候可以调节频率到0.858285M20uA 对 2.8571428M 7pF300uA 对42.857142M 7pF扩大到1.6996倍后可调节频率到72.84M标签:无标签电阻电容标准值电阻电容标准值E3 10 22 47 E6 10 15 22 33 47 68 E12 10 12 15 18 22 27 33 39 47 56 68 82E24 10 11 12 13 15 16 18 20 22 24 27 30 33 36 39 43 47 51 56 62 68 75 82 91E96 100 102 105 107 110 113 115 118 121 124 127 130 133 137 140 143 147 150 154 158 162 165 169 174 178 182 187 191 196 200 205 210 215 221 226 232 237 243 249 255 261 267 274 280 287 294 301 309 316 324 332 340 348 357 365 374 383 392 402 412 422 432 442 453 464 475 487 499 511 523 536 549 562 576 590 604 619 634 649 665 681 698 715 732 750 768 787 806 825 845 866 887 909 931 953 976。

基于msp430单片机的信号发生器设计 程序

基于msp430单片机的信号发生器设计 程序

/***************此程序与00程序的不同在于P0中断程序中去掉了开、关中断的操作***************///显示方面只显示第一次按键的显示要求#include <msp430x14x.h>#include <math.h>#include "BoardConfig.h"#define uchar unsigned char/***************显示模块的定义***************/#define DataDir P4DIR#define DataPort P4OUT#define Busy 0x80#define CtrlDir P3DIR#define CLR_RS P3OUT &= ~BIT0; //RS = P3.0#define SET_RS P3OUT |= BIT0;#define CLR_RW P3OUT &= ~BIT1; //RW = P3.1#define SET_RW P3OUT |= BIT1;#define CLR_EN P3OUT &= ~BIT2; //EN = P3.2#define SET_EN P3OUT |= BIT2;/***************DA转换模块的定义***************/#define SCL_H P1OUT |= BIT1#define SCL_L P1OUT &= ~BIT1#define SDA_H P1OUT |= BIT0#define SDA_L P1OUT &= ~BIT0#define SCL_out P1DIR |= BIT1 //SCL设置为输出模式#define SDA_in P1DIR &= ~BIT0 //SDA改成输入模式#define SDA_out P1DIR |= BIT0 //SDA变回输出模式#define SDA_val P1IN&BIT0 //SDA的位值#define TRUE 1#define FALSE 0#define pai 3.14/***************按键模块全局变量***************/uchar key_Pressed; //按键是否被按下:1--是,0--否uchar key_val; //存放键值uchar key_Flag; //按键是否已放开:1--是,0--否//设置键盘逻辑键值与程序计算键值的映射uchar key_Map[] = {1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16};uchar s1[] = {"zhengxian:"};uchar s2[] = {"fangbo:"};uchar s3[] = {"juchi:"};uchar s4[] = {"sanjiao:"};/***************调节模块全局变量***************/uchar fuzhi;uchar pinlv;unsigned int time; //定时int vcc; //da上加的电压uchar boxing;double bianliang;uchar biaozhi;int pianyi;int shuchu;/***************总体定义模块***************//***************总体定义模块***************/void xianshi(void);void DispNChar(uchar x,uchar y, uchar n,uchar *ptr);void LocateXY(uchar x,uchar y) ;void Disp1Char(uchar x,uchar y,uchar data);void LcdReset(void) ;void LcdWriteCommand(uchar cmd,uchar chk) ;void LcdWriteData( uchar data );void WaitForEnable(void);void Set_IO(void);void start(void);void stop(void);uchar check(void);void write1(void);void write0(void);void write1byte(uchar wdata);uchar Write_DAC(uchar wdata);void Init_Keypad(void);void Check_Key(void);void Key_Event(void);void zhengxian(void);void chansheng1(void);void fangbo(void);void chansheng2(void);void juchi(void);void chansheng3(void);void sanjiao(void);void chansheng4(void);void zengfu(void);void jiaofu(void);void zengpin(void);void jianpin(void);void delay100us(void);void delay5ms(void);void delay15ms(void);void delay400ms(void);/***************总体显示模块***************//***************总体显示模块***************//***********************************函数名称:xianshi功能:让液晶显示程序中液晶显示的主框架参数:返回值:***********************************************/void xianshi(void){LcdWriteCommand(0x01, 1); //清除显示Disp1Char(0,1,0x46); //显示FDisp1Char(1,1,0x3d); //显示=Disp1Char(3,1,0x56); //0x56是字符V的ASCII码值Disp1Char(5,1,0x50); //显示PDisp1Char(6,1,0x3d); //显示=Disp1Char(9,1,0x48); //0x48是字符H的ASCII码值Disp1Char(10,1,0x5a); //0x5a是字符Z的ASCII码值}/*******************************************函数名称:DispNchar功能:让液晶从某个位置起连续显示N个字符参数:x--位置的列坐标y--位置的行坐标n--字符个数ptr--指向字符存放位置的指针返回值:无********************************************/void DispNChar(uchar x,uchar y, uchar n,uchar *ptr){uchar i;for (i=0;i<n;i++){Disp1Char(x++,y,ptr[i]);if (x == 0x0f){x = 0;y ^= 1;}}}/******************************************* 函数名称:LocateXY功能:向液晶输入显示字符位置的坐标信息参数:x--位置的列坐标y--位置的行坐标返回值:无********************************************/ void LocateXY(uchar x,uchar y){uchar temp;temp = x&0x0f;y &= 0x01;if(y) temp |= 0x40; //如果在第2行temp |= 0x80;LcdWriteCommand(temp,1);}/******************************************* 函数名称:Disp1Char功能:在某个位置显示一个字符参数:x--位置的列坐标y--位置的行坐标data--显示的字符数据返回值:无********************************************/ void Disp1Char(uchar x,uchar y,uchar data) {LocateXY( x, y );LcdWriteData( data );}/*******************************************函数名称:LcdReset功能:对1602液晶模块进行复位操作参数:无返回值:无********************************************/void LcdReset(void){CtrlDir |= 0x07; //控制线端口设为输出状态 DataDir = 0xFF; //数据端口设为输出状态LcdWriteCommand(0x38, 0); //规定的复位操作delay5ms();LcdWriteCommand(0x38, 0);delay5ms();LcdWriteCommand(0x38, 0);delay5ms();LcdWriteCommand(0x38, 1); //显示模式设置LcdWriteCommand(0x08, 1); //显示关闭LcdWriteCommand(0x01, 1); //显示清屏LcdWriteCommand(0x06, 1); //写字符时整体不移动LcdWriteCommand(0x0c, 1); //显示开,不开游标,不闪烁}/*******************************************函数名称:LcdWriteCommand功能:向液晶模块写入命令参数:cmd-- chk--是否判忙的标志,1:判忙,0:不判返回值:无********************************************/void LcdWriteCommand(uchar cmd,uchar chk){if (chk) WaitForEnable(); // 检测忙信号?CLR_RS;CLR_RW;_NOP();DataPort = cmd; //将命令字写入数据端口_NOP();SET_EN; //产生使能脉冲信号_NOP();_NOP();CLR_EN;}/*******************************************函数名称:LcdWriteData功能:向液晶显示的当前地址写入显示数据参数:data--显示字符数据返回值:无********************************************/void LcdWriteData( uchar data ){WaitForEnable(); //等待液晶不忙SET_RS;CLR_RW;_NOP();DataPort = data; //将显示数据写入数据端口 _NOP();SET_EN; //产生使能脉冲信号_NOP();_NOP();CLR_EN;}/*******************************************函数名称:WaitForEnable功能:等待1602液晶完成内部操作参数:无返回值:无********************************************/void WaitForEnable(void){P4DIR &= 0x00; //将P4口切换为输入状态CLR_RS;SET_RW;_NOP();SET_EN;_NOP();_NOP();while((P4IN & Busy)!=0); //检测忙标志CLR_EN;P4DIR |= 0xFF; //将P4口切换为输出状态}/***************总体DA转换模块***************//***************总体DA转换模块***************//*******************************************函数名称:Set_IO功能:设置IIC对应IO为输出方向并输出高电平参数:无返回值:无********************************************/void Set_IO(void){SCL_out;SDA_out;SCL_H;SDA_H;}/*******************************************函数名称:start功能:完成IIC的起始条件操作参数:无返回值:无********************************************/void start(void){SCL_H;SDA_H;delay100us();SDA_L;delay100us();SCL_L;delay100us();}/*******************************************函数名称:stop功能:完成IIC的终止条件操作参数:无返回值:无********************************************/ void stop(void){SCL_H;SDA_L;delay100us();SDA_H;delay100us();}/******************************************* 函数名称:check功能:检查从机的应答操作参数:无返回值:从机是否有应答:1--有,0--无********************************************/ uchar check(void){uchar slaveack;SDA_in;SCL_H;delay100us();slaveack = SDA_val; //读入SDA数值SCL_L;delay100us();SDA_out;if(slaveack) return FALSE;else return TRUE;}/****函数名称:write1功能:向IIC总线发送一个1参数:无返回值:无********************************************/ void write1(void){SDA_H;delay100us();SCL_H;delay100us();SCL_L;delay100us();}/******************************************* 函数名称:write0功能:向IIC总线发送一个0参数:无返回值:无********************************************/ void write0(void){SDA_L;delay100us();SCL_H;delay100us();SCL_L;delay100us();}/******************************************* 函数名称:write1byte功能:向IIC总线发送一个字节的数据参数:wdata--发送的数据返回值:无********************************************/ void write1byte(uchar wdata){uchar i;for(i = 8;i > 0;i--){if(wdata & 0x80) write1();else write0();wdata <<= 1;}}/******************************************* 函数名称:Write_DAC功能:向DAC中写入输出电压数据参数:无返回值:写入结果:1--成功,0--失败********************************************/uchar Write_DAC(uchar wdata){start();write1byte(0x98); //DAC的设备地址if(check()) write1byte(wdata>>4); //写控制模式和电压数据的高四位else return 0;if(check()) write1byte(wdata<<4); //写电压数据的低四位else return 0;if(check()) stop();else return 0;return 1;}/***************总体按键模块***************//***************总体按键模块***************//*******************************************函数名称:Init_Keypad功能:初始化扫描键盘的IO端口参数:无返回值:无********************************************/void Init_Keypad(void){P1DIR = 0xf0; //P1.0~P1.3设置为输入状态, P1.4~P1.7设置为输出状态P1OUT |= 0x0f; //P1.4~P1.7输出低电平P1IES = 0x0f; //P1.0~P1.3下降沿触发中断P1IE = 0x0f; //P1.0~P1.3允许中断key_Flag = 0;key_Pressed = 0;key_val = 0;}/*******************************************函数名称:Check_Key功能:扫描键盘的IO端口,获得键值参数:无返回值:无********************************************/void Check_Key(void){uchar row ,col,tmp1,tmp2;tmp1 = 0x80;for(row = 0;row < 4;row++) //行扫描{P1OUT = 0xf0; //P1.4~P1.7输出全1P1OUT -= tmp1; //P1.4~p1.7输出四位中有一个为0tmp1 >>=1;if ((P1IN & 0x0f) < 0x0f) //是否P1IN的P1.0~P1.3中有 { tmp2 = 0x01; // tmp2用于检测出那一位为0for(col = 0;col < 4;col++) // 列检测{if((P1IN & tmp2) == 0x00) // 是否是该列,等于0为是{key_val = key_Map[row * 4 + col]; // 获取键值return; // 退出循环}tmp2 <<= 1; // tmp2右移1位}}}}/*******************************************函数名称:Key_Event功能:检测按键,并获取键值参数:无返回值:无********************************************/void Key_Event(void){uchar tmp;P1OUT &= 0x00; // 设置P1OUT全为0,等待按键输入tmp = P1IN; // 获取 p1INif ((key_Pressed == 0x00)&&((tmp & 0x0f) < 0x0f)) //如果有键按下{key_Pressed = 1; // 如果有按键按下,设置key_Pressed标识delay15ms(); //消除抖动Check_Key(); // 调用check_Key(),获取键值}else if ((key_Pressed == 1)&&((tmp & 0x0f) == 0x0f)) //如果按键已经释放{key_Pressed = 0; // 清除key_Pressed标识key_Flag = 1; // 设置key_Flag标识}else{_NOP();}}/***************总体波形及显示模块***************//***************总体波形及显示模块***************//*******************************************函数名称:zhengxian功能:输出正弦波参数:无返回值:无********************************************/void zhengxian(void){biaozhi = 0;boxing = 1;xianshi();DispNChar(0,0,10,s1); //显示正弦波CCTL0 = CCIE;CCR0 = time / 12;TACTL = TASSEL_1 + MC_1;_EINT(); //打开中断while(1){Disp1Char(2,1,0x30 + fuzhi); //显示幅值数字的ASCII码值等于其本身数值加上0x30Disp1Char(7,1,0x30 + pinlv / 10); //显示频率十位Disp1Char(8,1,0x30); //显示频率各位}}/*******************************************函数名称:chansheng1功能:输出正弦波参数:无返回值:无********************************************/void chansheng1(void){if(biaozhi == 12){biaozhi = 0;}if(biaozhi < 12){biaozhi += 1;}shuchu = 0xff * (fuzhi * sin(biaozhi * bianliang)+1.5) / vcc;Write_DAC(shuchu); //写入DAC}/*******************************************函数名称:fangbo功能:输出显示参数:无返回值:无************************void fangbo(void){boxing = 2;biaozhi = 1;time = time / 2;xianshi();DispNChar(0,0,7,s2); //显示方波CCTL0 = CCIE;CCR0 = time;TACTL = TASSEL_1 + MC_1;_EINT(); //打开中断while(1){Disp1Char(2,1,0x30 + fuzhi); //显示幅值数字的ASCII码值等于其本身数值加上0x30Disp1Char(7,1,0x30 + pinlv / 10); //显示频率十位Disp1Char(8,1,0x30); //显示频率各位shuchu = 0xff * fuzhi / vcc; //确定输出值的大小}}/*******************************************函数名称:chansheng2功能:输出方波参数:无返回值:无********************************************/void chansheng2(void){ if(biaozhi != 0){Write_DAC(shuchu); //写入DAC}else{Write_DAC(0); //写入DAC}}/*******************************************函数名称:juchi功能:输出显示参数:无返回值:无********************************************/void juchi(void){boxing = 3;xianshi();shuchu = 0;DispNChar(0,0,6,s3); //显示锯齿波Write_DAC(shuchu); //写入DACCCTL0 = CCIE;CCR0 = time / 10;TACTL = TASSEL_1 + MC_1;_EINT(); //打开中断while(1){ Disp1Char(2,1,0x30 + fuzhi); //显示幅值数字的ASCII码值等于其本身数值加上0x30Disp1Char(7,1,0x30 + pinlv / 10); //显示频率十位Disp1Char(8,1,0x30); //显示频率各位}}/*******************************************函数名称:chansheng3功能:输出锯齿波参数:无返回值:无********************************************/void chansheng3(void){shuchu += pianyi;Write_DAC(shuchu); //写入DACif(shuchu >= pianyi * 10)shuchu = 0;}/*******************************************函数名称:sanjiao功能:输出显示参数:无返回值:无********************************************/void sanjiao(void){shuchu = 0;biaozhi = 0;boxing = 4;xianshi();DispNChar(0,0,8,s4); //显示三角波CCTL0 = CCIE;CCR0 = time / 10;TACTL = TASSEL_1 + MC_1;_EINT();while(1){Disp1Char(2,1,0x30 + fuzhi); //显示幅值数字的ASCII码值等于其本身数值加上0x30Disp1Char(7,1,0x30 + pinlv / 10); //显示频率十位Disp1Char(8,1,0x30); //显示频率各位}}/*******************************************函数名称:chansheng4功能:输出三角波参数:无返回值:无********************************************/void chansheng4(void){ if(biaozhi == 10){biaozhi = 0;}if(biaozhi >= 5 && biaozhi {biaozhi += 1;shuchu -= pianyi;}if(biaozhi < 5){biaozhi += 1;shuchu += pianyi;}Write_DAC(shuchu); //写入DAC}/*******************************************函数名称:zengfu功能:增加波形幅值参数:无返回值:无********************************************/ void zengfu(void){_EINT(); //打开中断if(fuzhi < 3){fuzhi += 1; } //幅值加1}/******************************************* 函数名称:jiaofu功能:减小波形幅值参数:无返回值:无********************************************/ void jiaofu(void){_EINT(); //打开中断if(fuzhi > 1){fuzhi -= 1; } //幅值减1}/******************************************* 函数名称:zengpin功能:增加波形频率参数:无返回值:无********************************************/ void zengpin(void){_EINT(); //打开中断pinlv = 20;switch(boxing){case 1: time = 136; break;case 2: time = 819; break;case 3: time = 164; break;case 4: time = 164; break;}CCR0 = time;}/******************************************* 函数名称:jianpin功能:减小波形频率参数:无返回值:无********************************************/ void jianpin(void){_EINT(); //打开中断pinlv = 10;switch(boxing){case 1: time = 273; break;case 2: time = 1638; break;case 3: time = 327; break;case 4: time = 327; break;}CCR0 = time;}/***************总体延时模块***************//***************总体延时模块***************//*******************************************函数名称:delay100us功能:延时约100us的时间参数:无返回值:无********************************************/void delay100us(void){uchar i;for(i = 0;i < 15;i++)_NOP();}/*******************************************函数名称:delay5ms功能:延时约5ms参数:无返回值:无********************************************/void delay5ms(void){int i = 4000;while (i != 0){i--;}}/*******************************************函数名称:delay15ms功能:延时约15ms,完成消抖功能参数:无返回值:无********************************************/void delay15ms(void){int tmp;for(tmp = 12000;tmp > 0;tmp--);}/*******************************************函数名称:delay400ms功能:延时约400ms参数:无返回值:无********************************************/void delay400ms(void){uchar i = 50;int j;while(i--){j = 7269;while(j--);}}void main(void){ WDTCTL = WDTPW + WDTHOLD; //关闭看门狗BoardConfig(0xb8); //关闭数码管、流水灯和电平转换 vcc = 3; //da上加的电压bianliang = 2 * pai / 12;fuzhi = 0x02;pinlv = 10;time = 3276;LcdReset(); //初始化LCDInit_Keypad(); //初始化键盘端口_EINT(); //打开中断while(1);}/*******************************************函数名称:Port1_ISR功能:端口P1的中断服务函数参数:无返回值:无********************************************/#pragma vector=PORT1_VECTOR__interrupt void Port1_ISR(void){ while(1){Key_Event(); //检测按键,并获取键值P1IFG = 0; P1OUT = 0; //清中断标志switch(key_val){ case 1: zhengxian(); break; //输出正弦波 case 2: fangbo(); break; //输出方波case 3: juchi(); break; //输出锯齿波 case 4: sanjiao(); break; //输出三角波 case 5: zengfu(); break; //增加幅值case 6: jiaofu(); break; //减小幅值case 7: zengpin(); break; //增大频率即选择20hzcase 8: jianpin(); break; //减小频率即选择10hzdefault: break;}break;}}/*******************************************函数名称:TIMERA0_VECTOR功能:定时器A的中断服务函数参数:无返回值:无********************************************/#pragma vector=TIMERA0_VECTOR__interrupt void Timer_A (void){switch(boxing){case 1:chansheng1();break;case 2:biaozhi = ~biaozhi;chansheng2();break;case 3:pianyi = 0xff * fuzhi / vcc / 10; //确定偏移量的大小 chansheng3();break;case 4:pianyi = 0xff * fuzhi / vcc / 5; //确定偏移量的大小; chansheng4();break;}}。

信号发生器程序

信号发生器程序
int key,keyz,keyzz;
long int a=0,b1=20,b2=20,c=2,d=0,e=0,f=0,g=0,h=0,t1,t2,t3,t4,m=1,n=0,flag=0,q=0,r=0,s=0,u=0;
//...............................................................................
return 0;
}
//...............................................................................
void delay(int ms)
{
while(ms--)
{
for(i=0;i<=1600;i++);
P1IES|= BIT0;
P1IE |= BIT1;
P1IES|= BIT1;
P1IE |= BIT2;
P1IES|= BIT2;
P1IE |= BIT3;
P1IES |= BIT3;
void lcd_init()
{
lcd_wcmd(0x38); //function set
delay(10);
lcd_wcmd(0x38); //function set
delay(10);
BCSCTL1 = CALBC1_16MHZ; //设定DCO为1MHZ
DCOCTL = CALBC1_16MHZ;
P1DIR&=~0x0f;
P1DIR|=0xf0;// 将P1.4 P1.5 P1.6 P1.7设置为输出方向

[整理版]正弦信号发生器C程序及解释

[整理版]正弦信号发生器C程序及解释

正弦信号发生器C程序及解释/*1 、可通过按键实现频率输出步进加减;步进频率范围0~10MHz;2、步进值有六种选择:10Hz、100Hz、1000Hz、10KHz、100KHz、1000KHz3、采用1602液晶显示屏,可以实时显示输出频率值,显示当前步进值,显示频率的单位都为Hz。

*///基本功能全部实现;2009041407#include <reg52.h> //调用头文件(单片机内部的寄存器定义)#define uchar unsigned char#define uint unsigned int/******本段为硬件I/O口定义********/sbit LCD_E = P1^1;//定义1602液晶的使能管脚;sbit LCD_RW = P1^2;//定义1602液晶的读写管脚;sbit LCD_RS = P1^3;//定义1602液晶的选通管脚;sbit reset = P1^4; //ad9850的复位引脚;//sbit w_clk = P1^7; //ad9850的时钟引脚;//sbit fqud = P1^6; //ad9850的输出更新引脚;sbit w_clk = P3^1; // ad9850 w_clk;sbit fqud = P3^0; //ad9850 fqud;#define LCD_DATA P2 //向1602液晶传送数据的端口,这里用的是P2口;#define LCD_BUSY 0x80 // 用于检测LCD的忙标识(本程序中用的是延时,未检测)//LCD显示内容,定义到代码段;unsigned char code LcdBuf1[]= {"FRQ: Hz"};unsigned char code LcdBuf2[]= {"Step:"};double Con_Word_1 = 0x00;//定义了一个浮点变量,用于计算控制字;double Con_Word_2 = 0x00;//定义了一个浮点变量,用于计算控制字;long uint ConTrol_Word = 0x00;//用来存储控制字的数值;long uint Frequency_Out;//设置的频率值;uchar a,b,c,d,e,f,g,h; //为了向1602写入频率值,首先将频率值拆分存于这8个变量中;sbit Light = P1^0; //程序状态指示灯,它与单片机对9850控制无关,只是调试程序的时候使用!//定义按键;2X3矩阵键盘;sbit P3_3 = P3^3;sbit P3_4 = P3^4;sbit P3_5 = P3^5;sbit P3_6 = P3^6;sbit P3_7 = P3^7;uchar dat = 0;//键盘子程序处理过程中使用的中间变量;uchar keyzhi = 0x00;//键值;键盘扫描子程序的返回值存于该变量中;//函数声明void lcd_init(void);//1602液晶初始化子程序;void display_string(unsigned char x,unsigned chary,unsigned char *s);//显示字符子程序;x、y是坐标;x:从左边数起第几个字符:y:是第一行还是第二行;/**************************************************** 函数名称: delay** 入口参数:h(unsigned int型)** 出口参数:无** 功能描述: 短暂延时,使用11.0592晶体,约0.01MS****************************************************/void delay(long unsigned int h){while(h--); //延时子程序}/**************************************************** 函数名称: WriteDataLcd** 入口参数:wdata(unsigned char型)** 出口参数:无** 功能描述: 写数据到LCD****************************************************/void WriteDataLcd(unsigned char wdata)//向1602液晶写入数据;{LCD_RS=1;LCD_RW=0;LCD_E=0;LCD_E=1;LCD_DATA=wdata;delay(100); //短暂延时,代替检测忙状态LCD_E=0;}/**************************************************** 函数名称: WriteCommandLcd** 入口参数:wdata(unsigned char型)** 出口参数:无** 功能描述: 写命令到LCD****************************************************/void WriteCommandLcd(unsigned char wdata)//向1602液晶写入命令;{LCD_RS=0;LCD_RW=0;LCD_E=0;LCD_E=1;LCD_DATA=wdata;delay(100); //短暂延时,代替检测忙状态LCD_E=0;}//LCD初始化void lcd_init(void){LCD_DATA = 0;delay(1000);WriteCommandLcd(0x38);delay(500);WriteCommandLcd(0x38); //显示模式设置delay(500);WriteCommandLcd(0x38); //显示模式设置delay(500);WriteCommandLcd(0x01); //关闭显示WriteCommandLcd(0x38); //显示清屏WriteCommandLcd(0x0c); //显示光标移动设置WriteCommandLcd(0x06); //显示开及光标移动设置}/**************************************************** 函数名称: display_xy** 入口参数:x(unsigned char型),y(unsigned char型)** 出口参数:无** 功能描述: 设置光标位置, x是行号,y是列号****************************************************/void display_xy(unsigned char x,unsigned char y){if(y==0x01){x = x + 0x40 + 0x80;}else{x = x+0x80;}WriteCommandLcd(x);}/********************************************************** ************* 函数名称: display_string** 入口参数:x(unsigned char型),y(unsigned char型),s(指针型)** 出口参数:无** 功能描述: 在具体位置显示字符串,以/0结束,x是列号,y是行号*********************************************************** ***********/void display_string(unsigned char x,unsigned chary,unsigned char *s){display_xy(x,y);while(*s){WriteDataLcd(*s);s++;}}Qu_Chu_Shu_Ma_Ge_Wei() //取出要显示的每一位数据;{a = Frequency_Out % 10;b = (Frequency_Out % 100)/10;c = (Frequency_Out % 1000)/100;d = (Frequency_Out % 10000)/1000;e = (Frequency_Out % 100000)/10000;f = (Frequency_Out % 1000000)/100000;g = (Frequency_Out % 10000000)/1000000;h = (Frequency_Out % 100000000)/10000000;}display_data() //显示数据子程序{Qu_Chu_Shu_Ma_Ge_Wei();//取出要显示的每一位数据;display_string(1,0,LcdBuf1);//显示第一行,从第2个位置开始WriteCommandLcd(0x85);//显示数值的话,用其真实的地址,如0x83等,WriteDataLcd(0x30+h); //如果要显示字符的话,暂时用x、y坐标的方式WriteDataLcd(0x30+g);//以下都是送显示数据;WriteDataLcd(0x30+f);WriteDataLcd(0x30+e);WriteDataLcd(0x30+d);WriteDataLcd(0x30+c);WriteDataLcd(0x30+b);WriteDataLcd(0x30+a);}////////////////////////////20081207scan_KEY(void) //键值处理子程序{uchar key = 0;key = P3;key = key & 0xf8;switch(key){case 0xb0:keyzhi = 3 ;break;case 0xa8:keyzhi = 2 ;break;case 0x98:keyzhi = 1 ;break;case 0x70:keyzhi = 6 ;break;case 0x68:keyzhi = 5 ;break;case 0x58:keyzhi = 4 ;break;default:keyzhi=0;}return(keyzhi);}keychuli()//键盘扫描子程序{P3_3 = 0x01;P3_5 = 0x01;P3_4 = 0x01;P3_6 = 0x00;P3_7 = 0x00;delay(100);if((P3_3&P3_4&P3_5) == 0x00){if((P3_3&P3_4&P3_5) == 0x00){P3_6 = 0x00;P3_7 = 0x01;dat = scan_KEY();if(dat == 0x00){P3_6 = 0x01;P3_7 = 0x00;dat = scan_KEY();}}else{dat = 0x00;goto down;//无键按下}}down:return(dat);}Calculate_Control_Word(long uint Frequency_Out){Con_Word_1 = Frequency_Out * 42;Con_Word_2 = Frequency_Out *0.94967296;//100MHz计算方法//首先有源晶体是100MHz的,然后用2的32次方减1,再除以100MHz得到的;//Con_Word_1 = Frequency_Out * 85;//Con_Word_2 = Frequency_Out *0.89934592;//100MHz计算方法//首先有源晶体是100MHz的,然后用2的32次方减1,再除以100MHz得到的;Con_Word_2 = Con_Word_2 + 0.5;//小数部分四舍五入;Con_Word_1 = Con_Word_1 + Con_Word_2;//根据设定的频率以浮点形式计算控制字ConTrol_Word = Con_Word_1 / 1;//将控制字换算成整数形式 }Send_Control_Word(long uint ConTrol_Word)//向AD9850送入频率控制字;{long uint ConTrol_Word_Temporary ;uchar data_word ;w_clk = 0x00; //根据时序图fqud = 0x00; //根据时序图//data_word = 0x00; //设置AD9851相位、掉电等相关控制字data_word = 0x00; //设置AD9850相位、掉电等相关控制字P2 = data_word;delay(200);w_clk=1;delay(200);w_clk=0;ConTrol_Word_Temporary = ConTrol_Word;ConTrol_Word = ConTrol_Word >> 24;data_word = ConTrol_Word % 256;//取出W1,频率控制字中的最高字节;P2 = data_word;delay(200);w_clk=1;delay(200);w_clk=0;ConTrol_Word = ConTrol_Word_Temporary;ConTrol_Word = ConTrol_Word >> 16;data_word = ConTrol_Word % 256;//取出W2,频率控制字中的次高字节;P2 = data_word;delay(200);w_clk=1;delay(200);w_clk=0;ConTrol_Word = ConTrol_Word_Temporary;ConTrol_Word = ConTrol_Word >> 8;data_word = ConTrol_Word % 256;//取出W3,频率控制字中的第三字节;P2 = data_word;delay(200);w_clk=1;delay(200);w_clk=0;ConTrol_Word = ConTrol_Word_Temporary;data_word = ConTrol_Word % 256;//取出W4,频率控制字中的最后一个字节;P2 = data_word;delay(200);w_clk=1;delay(200);w_clk=0; //根据时序图fqud=1; //根据时序图}/************主程序**************/main(){unsigned char i = 0x00;uint Step_Bian_Liang = 0x00;//步进变量;long uint Step_Data = 1;//默认为1Hz;long unsigned int Step_Data_Xian_Shi = 0x00;reset = 1; //复位AD9850;delay(1000);reset = 0; //使AD9850进入正常的工作状态;lcd_init(); //初始化子程序;Frequency_Out = 0;//开机默认的频率;Calculate_Control_Word(Frequency_Out);//根据设置的频率换算成将要送入AD9850中的整数值;Send_Control_Word(ConTrol_Word); //向AD9850送出频率控制字;display_data(); //显示数据;display_string(0,1,LcdBuf2); //显示第二行,从第0个位置开始;WriteCommandLcd(0xc5);//从第二行第六个开始显示数据;WriteDataLcd(0x30+(Step_Data/1000));//送出显示数据;WriteDataLcd(0x30+(Step_Data/100)%10);//送出显示数据;WriteDataLcd(0x30+(Step_Data/10)%10);//送出显示数据;WriteDataLcd(0x30+(Step_Data%10));//送出显示数据;display_string(9,1,"Hz");//显示Hz;while(1){keychuli();//键处理子程序if(dat == 0x01)//键值为1;步进加{dat = 0x00;delay(5000);Frequency_Out = Frequency_Out + Step_Data;if(Frequency_Out > 1000000){Frequency_Out = Frequency_Out - Step_Data;}Light =~Light;display_data();Calculate_Control_Word(Frequency_Out);//根据设置的频率换算成将要送入AD9850中的整数值;Send_Control_Word(ConTrol_Word); //向AD9850送出频率控制字;}if(dat == 0x04)//键值为4;步进减{dat = 0x00;delay(5000);if(Frequency_Out >= Step_Data){Frequency_Out = Frequency_Out - Step_Data;if(Frequency_Out < 20){Frequency_Out = Frequency_Out + Step_Data;}}Light =~Light;display_data();Calculate_Control_Word(Frequency_Out);//根据设置的频率换算成将要送入AD9850中的整数值;Send_Control_Word(ConTrol_Word); //向AD9850送出频率控制字;}if(dat == 0x06)//步进选择;这里有六种选择 {dat = 0x00;delay(10000);Light =~Light;Step_Bian_Liang++;Step_Bian_Liang = Step_Bian_Liang%6;if(Step_Bian_Liang == 0x00){Step_Data = 1;//步进1}if(Step_Bian_Liang == 0x01){Step_Data = 10;}if(Step_Bian_Liang == 0x02){Step_Data = 100;}if(Step_Bian_Liang == 0x03){Step_Data = 1000;}if(Step_Bian_Liang == 0x04){Step_Data = 10000;}if(Step_Bian_Liang == 0x05){Step_Data = 100000;}if(Step_Data <= 1000){WriteCommandLcd(0xc5);//参考上面类似的部分WriteDataLcd(0x30+(Step_Data/1000));WriteDataLcd(0x30+(Step_Data/100)%10);WriteDataLcd(0x30+(Step_Data/10)%10);WriteDataLcd(0x30+(Step_Data%10));display_string(9,1,"Hz ");}else{Step_Data_Xian_Shi = Step_Data/1000;WriteCommandLcd(0xc5);//参考上面类似的部分WriteDataLcd(0x30+(Step_Data_Xian_Shi/1000)); WriteDataLcd(0x30+(Step_Data_Xian_Shi/100)%10); WriteDataLcd(0x30+(Step_Data_Xian_Shi/10)%10); WriteDataLcd(0x30+(Step_Data_Xian_Shi%10));display_string(9,1,"kHz");}}}}。

基于MSP430实现的简易信号发生器及源程序

基于MSP430实现的简易信号发生器及源程序

MSP430G2系列Launchpad开发板应用实例作品基于MSP430G2211实现的简易信号发生器第二章作品硬件系统设计第一节MSP430G2系列Launchpad开发板介绍TI的MSP430G2系列Launchpad开发板是一款适用于TI 最新MSP430G2xx 系列产品的完整开发解决方案。

其基于USB 的集成型仿真器可提供为全系列MSP430G2xx 器件开发应用所必需的所有软、硬件。

LaunchPad 具有集成的DIP目标插座,可支持多达20 个引脚,从而使MSP430 Value Line器件能够简便地插入LaunchPad电路板中。

此外,其还可提供板上Flash 仿真工具,以直接连接至PC 轻松进行编程、调试和评估。

此外,它还提供了从MSP430G2xx 器件到主机PC 或相连目标板的9600 波特UART 串行连接。

其实物图如图2.1所示。

图2.1 MSP430G2系列Launchpad开发板实物图MSP430G2系列Launchpad开发板的特性:●USB 调试与编程接口无需驱动即可安装使用,且具备高达9600 波特的UART 串行通信速度●支持所有采用PDIP14 或PDIP20 封装的MSP430G2xx 和MSP430F20xx 器件●分别连接至绿光和红光LED 的两个通用数字I/O 引脚可提供视觉反馈●两个按钮可实现用户反馈和芯片复位●器件引脚可通过插座引出,既可以方便的用于调试,也可用来添加定制的扩展板●高质量的20引脚DIP插座,可轻松简便地插入目标器件或将其移除本作品中所使用的MSP430G2211单片机的资源和功能:◆16位RISC指令集处理器◆128字节RAM(数据)+2K字节Flash存储器(代码)◆一个16位TA定时器◆内置数控振荡器(DCO),最高频率可达21MHz◆9个双向I/O口,每个I/O口都可以作为中断源◆自带BOR检测电路,能自动避开上电瞬间的毛刺并产生可靠的复位信号◆内置低功耗低频振荡器(VLO)◆可通过软件配置的8通道比较器第二节方案论证、比较与选择方案一:控制部分由MSP430G2211实现,波形产生采用低温漂、低失真、高线性单片压控函数发生器(如ICL8038、MAX038等)。

信号发生器(正弦波,方波,三角波)51单片机C语言代码

信号发生器(正弦波,方波,三角波)51单片机C语言代码

/**************************************//* 信号发生器(正弦波,方波,三角波)*/ /*************************************/#include<reg52.h>#include <intrins.h>#define uchar unsigned char#define uint unsigned intsbit cs=P2^0;sbit clk=P2^1;sbit din=P2^2;sbit key1=P1^0;sbit key2=P1^1; uchar keydat;uchar flag;被置零立马停止发信号//tlc5615 片选端口//tlc5615 时钟线//tlc5615 传输端口//按键的单片机接口//波形发生终止信号的标志位一旦uchar m,num; uchar dat=0xff;uchar code tosin[141]={//正弦波的编码0x00,0x01,0x02,0x02,0x03,0x04,0x05,0x06,0x07,0x08, 0x09,0x0a,0x0b,0x0d,0x0e,0x10,0x11,0x13,0x15,0x16, 0x18,0x1a,0x1c,0x1e,0x20,0x22,0x25,0x27,0x29,0x2b, 0x2e,0x30,0x33,0x35,0x38,0x3a,0x3d,0x40,0x43,0x45, 0x48,0x4c,0x4e,0x51,0x55,0x57,0x5a,0x5d,0x60,0x63, 0x66,0x69,0x6c,0x6f,0x70,0x71,0x72,0x73,0x74,0x75, 0x76,0x77,0x78,0x79,0x7a,0x7b,0x7c,0x7d,0x7e,0x7e, 0x7f,0x80,0x7f,0x7e,0x7e,0x7d,0x7c,0x7b,0x7a,0x79, 0x78,0x77,0x76,0x75,0x74,0x73,0x72,0x6f,0x6c,0x69, 0x66,0x63,0x60,0x5d,0x5a,0x57,0x55,0x51,0x4e,0x4c, 0x48,0x45,0x43,0x40,0x3d,0x3a,0x38,0x35,0x33,0x30, 0x2e,0x2b,0x29,0x27,0x25,0x22,0x20,0x1e,0x1c,0x1a, 0x18,0x16,0x15,0x13,0x11,0x10,0x0e,0x0d,0x0b,0x0a, 0x09,0x08,0x07,0x06,0x05,0x04,0x03,0x02,0x02,0x01, 0x00};uchar flagsqu; 中断控制)// 方波高低电平控制为 (运用定时器 1void delay(uchar z) //延时函数{uchar x,y;for(x=0;x<110;x++)for(y=z;y>0;y--);}void prepare() {cs=1;din=1;clk=0;cs=0; 为低时进? //tlc5615 的初始化//cs 的上升沿和下降沿必须在clk}/* 用中断来产生方波void Squtranslator(){TR1=1;的持续时间占空比//启动定时器 1 控制高低电平do{do{_wave=0;}while((!flagsqu) && flag==1);// 如果一旦终止信号的//产生可以立马退出循环flagsqu=0;do{_wave=1;}while((!flagsqu) && flag==1); flagsqu=0; }while(flag);flag=1;TR1=0;}*/void Squtranslator() //方波函数{uchar j;uchar dat1=0x7f;while(flag){do{}prepare();dat=dat1;for(j=0;j<12;j++) { din=(bit)(dat>>7);clk=1;dat=dat<<1; clk=0;}cs=1;为低时进行delay(200);if(dat1==0)dat1=0x7f;elsedat1=0;}while(flag);}//将数据的最高位赋给din//一位位的传输//cs 的上升沿和下降沿必须在//使高低电平持续一段时间//完成了0和0x7f 之间的替换clkvoid Tratranslator() //锯齿波的发生函数{uchar j;uchar dat1=0x7f;while(flag){do{prepare();dat=dat1;for(j=0;j<12;j++){din=(bit)(dat>>7);clk=1;dat=dat<<1;clk=0;}cs=1;为低时进行delay(2);dat1--;}while(flag && dat1);do{//将数据的最高位赋给din//一位位的传输//cs 的上升沿和下降沿必须在//稍加延时//一旦有终止信号就可以停止clk{uchar i,j;prepare(); dat=dat1; for(j=0;j<12;j++){din=(bit)(dat>>7); //将数据的最高位赋给 dindelay(2); dat1++;}while(flag && (!(dat1==0x7f)));}}void Sintranslator(uchar wave[],uchar num )//正弦波的转换函数clk=1; dat=dat<<1; clk=0;}cs=1;为低时进行//一位位的传输//cs 的上升沿和下降沿必须在clk//稍加延时uchar dat1;do{for(i=0;i<num;i++){prepare();dat1=wave[i]; //打开片选开始工作for(j=0;j<12;j++){din=(bit)(dat1>>7); //将数据的最高位赋给dinclk=1;dat1=dat1<<1; //一位位的传输clk=0;if(flag==0)break;}cs=1; //cs 的上升沿和下降沿必须在clk 为低时进行delay(1); //稍加延时if(flag==0)break;}}while(flag); //等待控制键的暂停}void keyscan() //切换功能按键返回键值函数{uchar i;for(i=0;i<4;i++){if(key1==0){delay(10);if(key1==0){keydat++;do{}while(!key1); //松手检测if(keydat==4)keydat=1;//加满回零处理}}}}void keycountrl() // 切断输出控制函数{if(key2==0){delay(10);{case 1:if(key2==0)flag=0;do{}while(!key2); //松手检测}}}void main (){uchar temp;TMOD=0x01;TH0=(65536-50000)/256;TL0=(65536-50000)%256;EA=1;ET0=1;TR0=1;while(1){do{switch(keydat)//确定定时器的工作方式 //给定时器 0 赋予初值 //开总中断 //开启定时器 0 中断flag=1;do{Sintranslator(tosin,141);}while(flag);break;case 2: flag=1;do{Tratranslator();}while(flag);break;case 3: flag=1;do{Squtranslator();}while(flag);break;default:break;}}while(flag);temp=keydat; // 装载键值while(keydat==temp); // 在这里等待键值的改变}}void Time0() interrupt 1{TH0=(65536-50000)/256; //定时器0 用来扫描按键不断地扫描dTL0=(65536-50000)%256;num++;if(num==4){keyscan();keycountrl();num=0;}}。

基于单片机的多功能信号发生器的源程序及电路图

基于单片机的多功能信号发生器的源程序及电路图

程序源代码#include <REGX52.H>#include <lcd1602.H>#include <AD9833_Serial.H>void Delay1ms(WORD count);//软件延时函数void display_freq(void); //更新频率函数BYTE code Cursor[]={0xC3,0XC4,0XC6,0XC7,0XC8,0XCA,0XCB,0XCC,0x85};//换算光标位置unsigned int a; //控制长时间不操作隐藏光标unsigned char step=4;//移动光标bit flag=0;//控制光标闪烁unsigned long int code Data []={10000000,1000000,100000,10000,1000,100,10,1}; //换算加减值unsigned long int Freqency_Out=1000; //初始化频率输出值unsigned char Wave_Out=1;unsigned char data DY[3] = {0x00,0x00,0x00} ;unsigned char DA;unsigned long int XS;sbit KEY1 = P1^0;sbit KEY2 = P1^1;sbit KEY3 = P1^2;sbit KEY4 = P1^3;sbit KEY5 = P1^4;sbit KEY6 = P1^5;sbit BEEP = P3^7;sbit din = P3^4;sbit clk = P3^5;sbit cs = P3^6;/*us级延时函数*//*******************************************************************/void DelayuS(unsigned int num){while( --num ) ;}/* 软件延时1*m毫秒*/void Delay1ms(WORD count){BYTE i, j;for( ; count>0; count--)for(i=2; i>0; i--)for(j=248; j>0; j--);}void display_freq(void) //显示频率{unsigned char j;unsigned long int temp;temp=Freqency_Out;tab2[3]=temp/10000000+0x30;//tab2[4]=temp%10000000/1000000+0x30;tab2[6]=temp%10000000%1000000/100000+0x30;tab2[7]=temp%10000000%1000000%100000/10000+0x30;tab2[8]=temp%10000000%1000000%100000%10000/1000+0x30;tab2[10]=temp%10000000%1000000%100000%10000%1000/100+0x30;tab2[11]=temp%10000000%1000000%100000%10000%1000%100/10+0x30;tab2[12]=temp%10000000%1000000%100000%10000%1000%100%10+0x30;WriteLCD(0,0xC0);// 设置显示位置为第二行第一个字for(j=0; j<15; j++){WriteLCD(1,tab2[j]);}switch(Wave_Out){case 1:Load_wave(0x2000,Freqency_Out,0xD000);break;case 2:Load_wave(0x2002,Freqency_Out,0xD000);break;case 3:Load_wave(0x2028,Freqency_Out,0xD000);break;}}void display_Wave(void) //变换波形{unsigned char j;switch(Wave_Out){case 1:WriteLCD(0,0x80);Load_wave(0x2000,Freqency_Out,0xD000);for(j=0; j<10; j++){WriteLCD(1,tab1_1[j]);}break;case 2:WriteLCD(0,0x80);Load_wave(0x2002,Freqency_Out,0xD000);for(j=0; j<10; j++){WriteLCD(1,tab1_2[j]);}break;case 3:WriteLCD(0,0x80);Load_wave(0x2028,Freqency_Out,0xD000);for(j=0; j<10; j++){WriteLCD(1,tab1_3[j]);}break;}// 设置显示位置为第二行第一个字}void initTimer(void) //定时器初始化初值{TMOD=0x2; //方式二TH0=0x49; //200usTL0=0x49;}/*******************************************************************/ /* 蜂鸣器响一声*//*******************************************************************/ void beep(){unsigned char y ;for (y=0 ;y<100 ;y++){DelayuS(60) ;BEEP=!BEEP ; //BEEP取反}BEEP=1 ; //关闭蜂鸣器DelayuS(40000) ;}void TLC5615(DA){unsigned char y;DA<<=6; //舍弃前6 位for(y=0;y<12;y++) //从高到低发送{if((DA&0x8000)==0)din=0;else din=1;//din = x&0x8000; //此处不能用din = x&0x8000;cs=0;clk=1;;;;clk=0;DA = DA<<1;}cs=1;}/* 电压转换与显示*//*******************************************************************/Disp_dianya(){DY[2]=XS/100+0x30 ;DY[0]=XS%100 ;DY[1]=DY[0]/10+0x30 ;DY[0]=DY[0]%10+0x30 ;WriteLCD(0,0x8B);WriteLCD(1,DY[2]);//十位数显示WriteLCD(0,0x8D);WriteLCD(1,DY[1]);//个位数显示WriteLCD(0,0x8E);WriteLCD(1,DY[0]);//小数显示}void main(void) //主函数{unsigned char i;initTimer();//定时器初始化TR0=1;ET0=1;DA=175;//DA初始电压XS=5;//显示初始电压TLC5615(DA);LCD_Initial(); //液晶初始化WriteLCD(0,0x80);// 设置显示位置为第一行第一个字for(i=0; i<16; i++){WriteLCD(1,tab1_1[i]);}//每行16个字,且光标自动右移WriteLCD(0,0xC0);// 设置显示位置为第二行第一个字for(i=0; i<16; i++){WriteLCD(1,tab2[i]);} //每行16个字,且光标自动右移Disp_dianya();DDSIni();//初始化AD9833Load_wave(0x2000,Freqency_Out,0xD000);//1KHz正弦信号display_freq();EA=1; //开启总中断WriteLCD(0,Cursor[step]);// 设置显示位置为第二行第一个字while(1){if(KEY2==0)//Right 光标右移{Delay1ms(50);if(KEY2==0){if(a!=0)//在没有光标时,第一次按下向左,向右按键时,光标不移动,只是显示出光标,并闪烁{step++;if(step==9) step=0;}WriteLCD(0,0x0F); // 开显示,开光标,闪烁WriteLCD(0,Cursor[step]);//显示出当前光标的位置EA=1;a=0; //当有按键按下时,开启定时器,计时开始。

简易多路信号发生器设计报告(含程序、总电路,调试无误)

简易多路信号发生器设计报告(含程序、总电路,调试无误)

简易多路信号发生器班级:专业:设计者:学号:实习日期:东华理工大学2012年月日简易多路信号发生器摘要:简易多路信号发生器利用单片机控制和DAC0832进行数模转换,通过硬件电路和软件程序相结合,可正弦波、方波、三角波、梯形波及其他任意波形,波形的频率和幅度在一定范围内可改变。

波形和频率的改变通过软件控制,幅度的改变通过硬件实现。

该信号发生器具有体积小、价格低、性能稳定的优点。

多路信号发生器有两个按键,一个按键控制信号类型,按下键一依次改变信号类型和停止产生波形;另一个按键改变信号频率。

一、设计内容及要求:1、设计内容:本课题要求设计一个简易多路信号发生器。

2、设计要求:1.通过单片机控制74LS138译码器,对DAC0832进行片选控制;2.能够产生正弦波、矩形波、锯齿波等基本波形信号,并通过修改程序能够产生任意波形的信号;3.通过两个按键控制波形类型和频率,一个按键控制信号类型,按下键一依次改变信号类型和停止产生波形;另一个按键改变信号频率;4. 有一个LED 显示是否有波形输出;灯亮为有波形输出,灯灭表示无波形输出;二、电路工作原理:电路由单片机最小系统、译码电路、DAC 转换电路、放大输出电路、LED 显示电路、按键组成。

当启动电源时,系统正常工作,通过最小系统控制DAC 转换电路片选信号,正常产生波形信号。

当按下按键1时依次切换输出波形类型和停止转换,按下按键2可在一定频率范围内改变波形频率。

三、选定系统设计方案,画出系统框图四、 单元电路设计参数计算及元器件选择1. 单片机最小系统51单片机最小系统复位电路的极性电容C1的大小直接影响单片机的复位时间,一般采用10~30uF ,51单片机最小系统单片机 89C51按键74LS138 译码电路DAC0832 数模转换电路放大输出电路LED 显示容值越大需要的复位时间越短。

●51单片机最小系统晶振Y1采用11.0592MHz,在正常工作的情况下可以采用更高频率的晶振,51单片机最小系统晶振的振荡频率直接影响单片机的处理速度,频率越大处理速度越快。

基于C语言的信号发生器的设计

基于C语言的信号发生器的设计

基于C语言的信号发生器的设计摘要:本文首先对信号发生器的设计方案进行了论证,接着提出了系统的整体设计框图,重点论述了由DDFS芯片AD9833构成的信号发生模块的设计。

并给出了C语言设计的信号产生程序。

较好的实现了C语言在单片机上的应用。

关键词:信号发生器;频率 Design of the Signal Generator Based On C-language Wan Huan,Geng Jian (Electronic&Information Institute of Nanchang TechnologyCollege,Nanchang 330044,China) Abstract:This article firstly demonstrated the Formula of the signal generator,then give the overall diagram of system.We focuses on the signal modules of the composition of the DDFS chip AD9833.A signal generate program based on C language is given.It achieved good results for C language using in the MCU application. Keywords:Signal Generator;Frequency 一、方案论证目前,市面上使用的信号发生器主要有两种:一种是是采用晶体管、运放和IC等通用器件制作,更多的则是用诸如L8038/BA205/XR2209等专门的信号发生IC来实现。

该设计方法设计出来的信号发生器,确实能够输出较完整且不失真的波形,但是输出波形的精度不高,频率的上限值也只有300kHz左右,如勉强使其输出较高频率的波形的话,我们会发现输出信号的幅度有明显下降。

  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。

简单信号发生器源程序C语言代码
#include
#include
#include
#define DA0832 XBYTE[0Xa000]
#define uchar unsigned char
#define S1 XBYTE[0X0000]
#define S2 XBYTE[0X2000]
#define S3 XBYTE[0X4000]
uchar code tab[10]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f}; uchar code
tosin[256]={0x80,0x83,0x86,0x89,0x8d,0x90,0x93,0x96,0x99,0x9c,0x9f,0x
a2,0xa5,0xa8,0xab,0xae,0xb1,0xb4,0xb7,0xba,0xbc,0xbf,0xc2,0xc5
,0xc7,0xca,0xcc,0xcf,0xd1,0xd4,0xd6,0xd8,0xda,0xdd,0xdf,0xe1,0xe3,0xe 5,0xe7,0xe9,0xea,0xec,0xee,0xef,0xf1,0xf2,0xf4,0xf5
,0xf6,0xf7,0xf8,0xf9,0xfa,0xfb,0xfc,0xfd,0xfd,0xfe,0xff,0xff,0xff,0xf f,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xfe,0xfd
,0xfd,0xfc,0xfb,0xfa,0xf9,0xf8,0xf7,0xf6,0xf5,0xf4,0xf2,0xf1,0xef,0xe e,0xec,0xea,0xe9,0xe7,0xe5,0xe3,0xe1,0xde,0xdd,0xda
,0xd8,0xd6,0xd4,0xd1,0xcf,0xcc,0xca,0xc7,0xc5,0xc2,0xbf,0xbc,0xba,0xb 7,0xb4,0xb1,0xae,0xab,0xa8,0xa5,0xa2,0x9f,0x9c,0x99
,0x96,0x93,0x90,0x8d,0x89,0x86,0x83,0x80,0x80,0x7c,0x79,0x76,0x72,0x6 f,0x6c,0x69,0x66,0x63,0x60,0x5d,0x5a,0x57,0x55,0x51
,0x4e,0x4c,0x48,0x45,0x43,0x40,0x3d,0x3a,0x38,0x35,0x33,0x30,0x2e,0x2 b,0x29,0x27,0x25,0x22,0x20,0x1e,0x1c,0x1a,0x18,0x16
,0x15,0x13,0x11,0x10,0x0e,0x0d,0x0b,0x0a,0x09,0x08,0x07,0x06,0x05,0x0 4,0x03,0x02,0x02,0x01,0x00,0x00,0x00,0x00,0x00,0x00
,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x02 ,0x02,0x03,0x04,0x05,0x06,0x 07,0x08,0x09,0x0a,0x0b,0x0d,0x0e,0x10,0x11,0x13,0x15
,0x16,0x18,0x1a,0x1c,0x1e,0x20,0x22,0x25,0x27,0x29,0x2b,0x2e,0x30,0x3 3,0x35,0x38,0x3a,0x3d,0x40,0x43,0x45,0x48,0x4c,0x4e
,0x51,0x55,0x57,0x5a,0x5d,0x60,0x63,0x66 ,0x69,0x6c,0x6f,0x72,0x76,0x 79,0x7c,0x80 };
uchar fun=0,b=0,c=0,d=0,tl,th;
void key1(void);
void key2(void);
void key3(void);
void key4(void);
void judge(void);
void main(void)
{
TMOD=0X01;
TR0=1;
th=0xff;
tl=0xd0;
TH0=th;
TL0=tl;
ET0=1;
EA=1;
while(1)
{
judge();
}
}
void judge(void)
{
uchar line,row,de1,de2,keym;
P1=0x0f;
keym=P1;
if(keym==0x0f)return;
for(de1=0;de1<200;de1++)
for(de2=0;de2<125;de2++){;}
P1=0x0f;
keym=P1;
if(keym==0x0f)return;
P1=0x0f;
line=P1;
P1=0xf0;
row=P1;
line=line+row;/*存放特征键值*/
if(line==0xde)key1();
if(line==0x7e)key2();
if(line==0xbd)key3();
if(line==0x7d)key4();
}
void key1(void) //1键选择发波类型,1为正弦波,2为三角波,3为方波{
fun++;
if(fun==4)fun=0x00;
}
void key2(void) //2键加大频率
{
tl++;
if(tl==0x1f)th++;
}
void key3(void) //3键减小频率
{
tl--;
if(tl==0x00)th--;
}
void key4(void) //4键显示频率
{
double t;
int f;
TR0=0;//ET0的区别
t=(65535-th*256-tl)*0.4;
f=(int)(1000/t);
S3=tab[f%10];
f=f/10;
S2=tab[f%10];
f=f/10;
if(f==0)S1=0;
else S1=tab[f];
TR0=1;
}
void time0_int(void) interrupt 1 //中断服务程序{
TR0=0;
if(fun==1)
{
DA0832=tosin; //正弦波
b++;
}
else if(fun==2) //三角波
{
if(c<128)DA0832=c;
else DA0832=255-c;
c++;
}
else if(fun==3) // 方波
{
d++;
if(d<=128)DA0832=0x00; else DA0832=0xff;
}
TH0=th;
TL0=tl;
TR0=1;
}。

相关文档
最新文档