第一部分、前言
1、效果图
2、选题原因
3、闲话
第二部分、AD9854的储备知识
1、AD9854用来干嘛的
2、AD9854的详细介绍
3、AD9854注意事项
第三部分、我的题目要求
1、题目文字描述
2、图片
3、思路
第四部分、我的工程代码
1、软核的搭建
2、顶层文件的代码
3、Ecplise代码
第五部分、总结
1、实现功能阐述
2、结果演示
3、接线图
4、完整工程
先来展示一波,是不是你想要的效果,我赌一定是,不是你发我一百块。
频率10KHz的正弦波图片对焦后图片周围就是黑的,可以看
频率20KHz的正弦波
频率100MHz的正弦波
《SOPC技术及应用》这门课程在13周全部结束了,从刚开始烧录第一个工程到自己搭建软核再到现在动手调试模块,其实时间很短,但是收获很多。也确实发现了老师开课说的第一句话:“STM32能做的FPGA都能做,FPGA能做的STM32绝对做不了!”的含义。
当然学完了,老师就要布置考试作业,然后昨天(11月28号)上午1-2节课就是抽签选题。老师的题库一共33道题,以抽签的方式决定选题。其中题库前五题是稍难题,后面题为一般题。老师选题时说:“前五题有自告奋勇的可以自己选”。以我的2G网速的脑资质,兄弟们当然懂了,我当时啪的一下就站起来了,很快啊,上去就是和老师说:“老师,我选第五题”。老师说:“很好!”
然后我在当天晚上6:45我就拍视频发给老师了。
这里还是想说一下,其实一开始做笔记,并不是自己的意愿,我是个学完就喜欢丢的人,但是因为同班上还有自己的❤,所以我就一步一步的把自己的操作过程记录下来,然后备注好发给她看。所以兄弟们,你们只是捡了个臭而已。
开个玩笑,因为后来发现写的还可以,但是有些地方还不够,然后我在复习周就从头又仔细搞了一遍,重新截图,很认真,浪费了我不少时间,就是为了方便兄弟们。(说这些话的目的就是就是想让看这篇文章的兄弟们点赞收藏评论!)最后,第一次写一个系列的教程,或者说学习笔记,还是希望你们好好体贴一下,让我坚持下去。
还有希望兄弟们加后面的群,群里面有耗子尾汁,能治颈椎病!
拿到一个模块,你先要看他的技术手册,明白它是干嘛用的。
首先AD9854是一个高速DDS模块,可以比喻成模块化的信号发生器,能产生频率在0~150MHz,幅值在0~500mV的正弦波,况且频率和幅值是通过程序控制的,高级不?简直是DDS模块界的马老师。
我说当然没有AD9854的模块手册说得好,资料在后面,但是先接着往下看,先别急着去找资料,默认你已经了解这个模块了。(注意:我后面所有的资料都放在一个文件夹哈。)
注意:我这里只说几个最重要的。
(1)模块供电: 7~9V(千万别烧了,模块很贵的,想想一个星期的饭钱)
(2)模块驱动电流: 600mA左右
(3)模块最大输出幅值: 500mVPP左右(正弦波, 可调, 频率越高, 最大输出电压越低),4.5VPP左右(方波, 不可调)
使用sopc技术调成功ad9854或者ad9851模块,能够在lcd上显示输出的正弦信号的频率。
这是从老师题库中截图过来的。我不知道题库能不能上传,我没问老师,所以就暂时不传。
AD9854拿到手,无非就是移植驱动代码,再控制几个PIO。然后驱动代码哪里有呢?巧了我之前用STM32调试过AD9854,我直接移植我之前的代码就可以了 “” “” “”。
关于STM32的工程我准备再出一个STM32的系列教程,如果这个系列的效果好,不然就算了,不想挨骂。嘿嘿!
这里面我一共定义六个PIO核,然后红色方框上面的是LCD的IP核等,我还是基于我开发板自带例程改的,关于自带例程怎么改,在哪里我前面的【NiosII学习】系列中详细的讲述了。回去看一下哈。
module AC620_GHRD(
input wire clk, // clk.clk
input wire reset_n, // reset.reset_n
output wire lcd_rst, // lcd_rst.export
output wire lcd_rd_n, // lcd_rd.export
output wire lcd_bl, // lcd_bl.export
output wire lcd_wr_n, // lcd_wr.export
output wire lcd_rs, // lcd_rs.export
output wire lcd_cs_n, // lcd_cs.export
inout wire [15:0] lcd_data, // lcd_db.export
output wire sdram_clk, // sdram_clk.clk
output wire [11:0] sdram_addr, // sdram.addr
output wire [1:0] sdram_ba, // .ba
output wire sdram_cas_n, // .cas_n
output wire sdram_cke, // .cke
output wire sdram_cs_n, // .cs_n
inout wire [15:0] sdram_dq, // .dq
output wire [1:0] sdram_dqm, // .dqm
output wire sdram_ras_n, // .ras_n
output wire sdram_we_n, // .we_n
input wire uart_0_rxd, // uart_0.rxd
output wire uart_0_txd, // .txd
output wire epcs_dclk, // epcs.dclk
output wire epcs_sce, // .sce
output wire epcs_sdo, // .sdo
input wire epcs_data0, // .data0
output wire [13:0] pio_c,
output wire rst,
output wire uclk,
output wire wd,
output wire rd,
output wire osk,
output wire fsk
);
mysystem u0 (
.clk_clk (clk), // clk.clk
.reset_reset_n (reset_n), // reset.reset_n
.uart_0_rxd (uart_0_rxd), // uart_0.rxd
.uart_0_txd (uart_0_txd), // .txd
.epcs_dclk (epcs_dclk), // epcs.dclk
.epcs_sce (epcs_sce), // .sce
.epcs_sdo (epcs_sdo), // .sdo
.epcs_data0 (epcs_data0), //
.lcd_rst_export (lcd_rst), // lcd_rst.export
.lcd_bl_export (lcd_bl), // lcd_bl.export
.lcd_wr_n (lcd_wr_n), // lcd.wr_n
.lcd_rd_n (lcd_rd_n), // .rd_n
.lcd_data (lcd_data), // .data
.lcd_rs (lcd_rs), // .rs
.lcd_cs_n (lcd_cs_n), //
.sdram_clk_clk (sdram_clk), // sdram_clk.clk
.altpll_0_phasedone_conduit_export (), // altpll_0_phasedone_conduit.export
.altpll_0_locked_conduit_export (), // altpll_0_locked_conduit.export
.altpll_0_areset_conduit_export (), // altpll_0_areset_conduit.export
.sdram_addr (sdram_addr), // sdram.addr
.sdram_ba (sdram_ba), // .ba
.sdram_cas_n (sdram_cas_n), // .cas_n
.sdram_cke (sdram_cke), // .cke
.sdram_cs_n (sdram_cs_n), // .cs_n
.sdram_dq (sdram_dq), // .dq
.sdram_dqm (sdram_dqm), // .dqm
.sdram_ras_n (sdram_ras_n), // .ras_n
.sdram_we_n (sdram_we_n), // .we_n
.pio_c_export (pio_c), // pio_c.export
.rst_export (rst), // rst.export
.uclk_export (uclk), // uclk.export
.wd_export (wd), // wd.export
.rd_export (rd), // rd.export
.osk_export (osk), // osk.export
.fsk_export (fsk) // fsk.export
);
endmodule
/*
* main.c
*
* Created on: 2020年11月28日
* Author: dpt
*/
#include "lcd9341.h"
#include "unistd.h"
#include "stdint.h"
#include "system.h"
#include "alt_types.h"
#include "altera_avalon_pio_regs.h"
#include
#include "io.h" //函数类型
//函数声明
void AD9854_WR_Byte(alt_u32 addr,alt_u32 dat);
void AD9854_Init(void);
void AD9854_SetSine_double(double Freq,u_int Shape);
//12倍倍频
#define CLK_Set 12
const unsigned long Freq_mult_ulong = 1172812;
const double Freq_mult_doulle = 1172812.402961067;
alt_u32 dat1,dat2;
//AD9854的写寄存器
void AD9854_WR_Byte(alt_u32 addr,alt_u32 dat)
{
dat1= dat|(addr<<8);
IOWR_ALTERA_AVALON_PIO_DATA(PIO_C_BASE, (dat1&0x3fff)|((dat1^0x3fff)<<16));
IOWR_ALTERA_AVALON_PIO_DATA(WD_BASE, 0);
IOWR_ALTERA_AVALON_PIO_DATA(WD_BASE, 1);
}
//AD9854的初始化
void AD9854_Init(void)
{
IOWR_ALTERA_AVALON_PIO_DATA(WD_BASE, 1);//将读、写控制端口设为无效
IOWR_ALTERA_AVALON_PIO_DATA(RD_BASE, 1);
IOWR_ALTERA_AVALON_PIO_DATA(UCLK_BASE, 0);
IOWR_ALTERA_AVALON_PIO_DATA(RST_BASE, 1);//复位AD9854
IOWR_ALTERA_AVALON_PIO_DATA(RST_BASE, 0);
AD9854_WR_Byte(0x1d,0x00); //关闭比较器
AD9854_WR_Byte(0x1e,CLK_Set); //设置系统时钟倍频
AD9854_WR_Byte(0x1f,0x00); //设置系统为模式0,由外部更新
AD9854_WR_Byte(0x20,0x60); //设置为可调节幅度,取消插值补偿
IOWR_ALTERA_AVALON_PIO_DATA(UCLK_BASE, 1);//更新AD9854输出
IOWR_ALTERA_AVALON_PIO_DATA(UCLK_BASE, 0);
}
//频率转换函数
alt_u8 FreqWord[6];
void AD9854_SetFreq_double(double Freq)
{
unsigned long Low32;
unsigned int High16;
double Temp=Freq_mult_doulle; //23ca99为2的48次方除以120M
Freq*=(double)(Temp);
High16 =(int)(Freq/4294967295); //2^32 = 4294967295
Freq -= (double)High16*4294967295;
Low32 = (unsigned long)Freq;
FreqWord[0]=Low32;
FreqWord[1]=Low32>>8;
FreqWord[2]=Low32>>16;
FreqWord[3]=Low32>>24;
FreqWord[4]=High16;
FreqWord[5]=High16>>8;
}
//设置想要产生正弦波的函数
void AD9854_SetSine_double(double Freq,unsigned int Shape)
{
u_char count=0;
u_char Adress;
Adress=0x04; //选择频率控制字1地址的初值
AD9854_SetFreq_double(Freq); //频率转换
for(count=6;count>0;) //写入6字节的频率控制字
{
AD9854_WR_Byte(Adress++,FreqWord[--count]);
}
AD9854_WR_Byte(0x21,Shape>>8); //设置I通道幅度
AD9854_WR_Byte(0x22,(u_char)(Shape&0xff));
AD9854_WR_Byte(0x23,Shape>>8); //设置Q通道幅度
AD9854_WR_Byte(0x24,(u_char)(Shape&0xff));
IOWR_ALTERA_AVALON_PIO_DATA(UCLK_BASE, 1);//更新AD9854输出
IOWR_ALTERA_AVALON_PIO_DATA(UCLK_BASE, 0);
}
int main()
{
int fre = 10000;//频率范围1Hz~120MHz
int Vpp = 200; //幅值0~500mv
char a1[10]={};
LCD9341_Init();
AD9854_Init();
AD9854_SetSine_double(fre,8.19*Vpp);
sprintf(a1,"%d",fre);
while(1)
{
POINT_COLOR=RED;
LCD_ShowString(20,50,"frequency = ");
LCD_ShowString(116,50,a1);
LCD_ShowString(188,50,"Hz");
usleep(2000000);
}
}
我可以通过FPGA控制我想产生的正弦波频率和幅值。
结果演示视频我已经拍好视频和其他文件夹打包放在一起,你也可以点击这里看一下演示效果(https://live.csdn.net/v/121225)这里只放图片。
我FPGA(小梅哥AC620)上面引脚的接法。
啪的一下,很快啊,又到了嫖嫖怪的时间了。然后所有的文件我都放在同一个文件夹,包括我看的资料,我的工程,我参考的工程,视频演示等。有需要的小伙伴扫码进群下载、或者直接留下邮箱我悄悄发给你、或者点击这个链接下载(【NiosII训练】第一篇、FPGA驱动AD9854基础篇:https://download.csdn.net/download/Learning1232/13693204),老板大气。