DIY编程器网

 找回密码
 注册

QQ登录

只需一步,快速开始

扫一扫,访问微社区

查看: 1757|回复: 0
打印 上一主题 下一主题

[待整理] 函数信号发生器和示波器二合一仪器设计,提供源码

[复制链接]
跳转到指定楼层
楼主
发表于 2015-4-27 16:20:17 | 只看该作者 |只看大图 回帖奖励 |倒序浏览 |阅读模式
1.总体设计方案
       

         

          1.1 主控制模块
          方案一:采用单片机。单片机的应用较为广泛,但是单片机的处理频率达不到我们的要求。所以我们只能够使用处理速度较快的处理器。
           
          方案二:采用Xilinx的FPGA来实现主控制器。Xilinx的FPGA的内部IP核可以方便的产生DDS波形,这样就方便我们能够更好的产生想要的波形。
           
          所以采用方案二。
           
          1.2显示模块
          方案一:使用TFT触摸屏。彩屏有这样明显的优点:微功耗,尺寸小,超薄轻巧,显示信息量大,字迹美观,视觉舒适,但是对于FPGA来说,其实现对触摸屏的控制不能够较好的完成控制要求。
           
          方案二:使用VGA显示。FPGA可以实现对VGA的控制。VGA的使用较为广泛,且价格在接收的范围之内。而且,对于FPGA来说,实现对VGA接口的控制比控制其他的显示器更加的方便和快捷。这就节省了我们的设计麻烦。
           
          所以采用方案二。
       

         
          1.3 输入模块
          方案一:使用矩阵键盘。矩阵键盘的编码较为简答,且可以实现较为复杂的控制。但是矩阵键盘的按键过少,不能够实现更多数据的输入。
           
          方案二:使用PS2键盘。PS2键盘的控制更为简单,我们可以通过两根数据线精心数据的读取,且PS2键盘的设计更加符合我们设计要求,这就决定了PS2在本设计中的优势。
           
          故采用方案二。
       

         

          1.4 AD输出模块
          ADS7822是一种单片高速12位逐次比较型A/D转换器, ADS7822内置双极性电路构成的混合集成转换显片,具有外接元件少,功耗低,精度高等特点,并且具有自动校零和自动极性转换功能,只需外接少量的阻容件即可构成一个完整的A/D转换器。所以该方案采用ADS7822作为AD输入的元器件。
       

         

          1.5 DA输出模块
          DAC7513是8分辨率的D/A转换集成芯片。与微处理器完全兼容。这个DA芯片以其价格低廉、接口简单、转换控制容易等优点,在单片机应用系统中得到广泛的应用。D/A转换器由8位输入锁存器、8位DAC寄存器、8位D/A转换电路及转换控制电路构成。
       

               
          2.程序设计
          2.1 AD输出
       

         
          --**********************分频进程*************************
          process(clk)
                 variable cnt1 : integer range 0 to 100;
                 variable cnt2 : integer range 0 to 20;
                 begin
                        if clk'event and clk='1' then
                        if cnt1=100 then
                               cnt1:=0;
                               if cnt2=20 then
                                      cnt2:=0;
                                      clock<=not clock;
                                      if(cnt=3)then
                                             cnt<=0;
                                      else
                                             cnt<=cnt+1;
                                      end if;
                               else
                                      cnt2:=cnt2+1;
                               end if;
                        else
                               cnt1:=cnt1+1;
                        end if;
                 end if;
          end process;
          --**************状态驱动进程**********************
           sync :process(clock,reset)
           begin
            if(reset = '0') then
             current_state <= start;
            elsif(clock'event and clock='1') then
             current_state <= next_state;
            end if;
           end process sync;
          --***************adc驱动进程*******************
           comb :process(current_state, intr)
           begin
            case current_state is
             when start =>                        --启动状态
              next_state <= convert;
              cs <= '0';
              wr <= '0';
              rd <= '1';
              read_data <= '0';
             when convert =>--初始化
              if(intr = '0') then
               next_state <= read1;
              else
               next_state <= convert;
              end if;
              cs <= '1';
              wr <= '1';
              rd <= '1';
              read_data <= '0';
             when read1 =>--读状态1
              next_state <= read2;
              cs <= '0';
              wr <= '1';
              rd <= '0';
              read_data <= '1';
             when read2 =>--读状态2
              next_state <= start;
              cs <= '1';
              wr <= '1';
              rd <= '1';
              read_data <= '0';
             when others =>--其他状态
              next_state <= start;
            end case;
           end process comb;
          --****************读取AD数据********************
           get_data: process(clock,reset)
           begin
            if(reset = '0') then
             p<=0;
            elsif(clock'event and clock='1') then
             if(read_data = '1') then
              p<=conv_integer(data_i);
             end if;
            end if;
           end process;
         
          2.2 DA输出
           
           
       

         

          --*********************65536Hz分频进程************************
          process(clk)
                 variable cnt1 : integer range 0 to 762;
                 begin
                        if clk'event and clk='1' then
                         case cnt1 IS
                     WHEN 381 =>
                       cp_65k<='1';                                             
                                cnt1:=cnt1+1;
                     WHEN 762=>
                       cnt1:=0;                                                   
                                cp_65k<='0';                                          
                                cp_wr<='0';
                           WHEN 20=>
                                cp_wr<='1';                                            
                                cnt1:=cnt1+1;
                     WHEN OTHERS=>
                       cnt1:=cnt1+1;
                   end case;
                        end if;
          end process;
           --*********************1kHz分频进程************************
          process(cp_65k)
                 variable cnt1 : integer range 0 to 64;
                 begin
                        if cp_65k'event and cp_65k='1' then
                               case cnt1 is
                                      when 32=>cp_1k<='1';
                                                     cnt1:=cnt1+1;
                                      when 64=>cnt1:=0;
                                                     cp_1k<='0';
                                      when others=>cnt1:=cnt1+1;
                               end case;
                      end if;
          end process;  
           --**************DDS地址累加器进程**********************
            PROCESS(cp_65k)
            BEGIN
             IF(cp_65k'EVENT AND cp_65k='1') THEN
              --DDS累加器循环累加dds_m
                 IF dds_add<65535 THEN
                   dds_add<=dds_add+dds_m;
               ELSE
                dds_add<=dds_add+dds_m-65536;
              END IF;
             END IF;
            END PROCESS;
          --***********************频率加减控制进程***************************
          process(cp_1k)
             VARIABLE keys:INTEGER RANGE 0 TO 127 :=0;        --消抖累加器
                 begin
                     if cp_1k='1' then
                           case key is
                               when "10"=>                                                   --频率加
                                      if keys=127 then
                                          keys:=0;
                                             bell<='1';
                                             if dds_m=1000 then
                                                    dds_m<=1;
                                             else
                                                    dds_m<=dds_m+1;
                                             end if;
                                      else
                                             keys:=keys+1;
                                      end if;
                                when "01"=>                                           --频率减
                                             if keys=127 then
                                                 keys:=0;
                                                    bell<='1';
                                                    if dds_m=1000 then
                                                           dds_m<=1;
                                                    else
                                                           dds_m<=dds_m-1;
                                                    end if;
                                             else
                                                    keys:=keys+1;
                                             end if;
                              when others=>bell<='0';
                               end case;
                        end if;                  
          end process;  
          end dac;
         
          2.3 VGA显示
       

           
          3.性能指标

        DA输出的波形

         

          4.总结
          经过了多日的努力,我们在本设计中基本实现了上述要求,并在有些功能方面提出了改进,使系统设计更加完善。在该设计中我们使用了FPGA作为主控器,但由于时间及器材条件的限制,本设计也存在不足,例如,测量范围不能达到更高的要求,测量精度也存在很大的提升空间。我们会在以后的学习中不断地弥补这些不足,完善测量系统设计。
分享到:  QQ好友和群QQ好友和群 QQ空间QQ空间 腾讯微博腾讯微博 腾讯朋友腾讯朋友 微信微信
收藏收藏 分享分享 支持支持 反对反对
您需要登录后才可以回帖 登录 | 注册

本版积分规则

小黑屋|文字版|手机版|DIY编程器网 ( 桂ICP备14005565号-1 )

GMT+8, 2025-5-30 21:25 , 耗时 0.091630 秒, 21 个查询请求 , Gzip 开启.

各位嘉宾言论仅代表个人观点,非属DIY编程器网立场。

桂公网安备 45031202000115号

DIY编程器群(超员):41210778 DIY编程器

DIY编程器群1(满员):3044634 DIY编程器1

diy编程器群2:551025008 diy编程器群2

QQ:28000622;Email:libyoufer@sina.com

本站由桂林市临桂区技兴电子商务经营部独家赞助。旨在技术交流,请自觉遵守国家法律法规,一旦发现将做封号删号处理。

快速回复 返回顶部 返回列表