最近比较丧,也不知道是担心未来还是担心这样的自己
SDx建工程,new—>SDx project,展开,src右键—>import(或者在文件夹内添加相应的.c文件)。
main.c:

#include <stdio.h>
#include <math.h>
#include "FFT.h"
#define N 256extern complex x[s];
extern complex *W;int main()
{unsigned int i; printf("start!\n");//输入序列的实部和虚部sfor(i = 0; i < N; i++)  {  x[i].real = i;x[i].img = i+1;}  FFT(x, W, N);for(i=0;i<N;i++){printf("%.4f",x[i].real);if(x[i].img>=0.0001)printf("+%.4fj\n",x[i].img);else if(fabs(x[i].img)<0.0001)printf("\n");elseprintf("%.4fj\n",x[i].img);}return 0;
}

FFT.c:

#include <stdio.h>
#include <math.h>
#include <stdlib.h>
#include "FFT.h"#define PI 3.1415926
#define s 1000complex x[s];
complex *W;void mul(complex a,complex b,complex *c);
void add(complex a,complex b,complex *c);
void sub(complex a,complex b,complex *c);void FFT(complex *x, complex *W, unsigned int N)
{  unsigned int i, j, tw, a, b, temp_a;unsigned int level_num, sample_num;complex temp, top,bottom,xw;/*旋转因子*/W = (complex *)malloc(sizeof(complex) * N);  //生成变换核for(tw = 0; tw < N; tw++){W[tw].real = cos(2 * PI / N * tw);   //计算旋转因子W[tw].img = -1 * sin(2 * PI / N * tw);}/*倒序*/for(a = 0; a < N; a++){temp_a = a;b = 0;for(temp_a = 0; temp_a < log(N)/log(2); temp_a++){b <<= 1;b |= (temp_a&1);temp_a >>= 1;}if(b > a){temp = x[a];x[a] = x[b];x[b] = temp;}}/*fft运算*/for(level_num = 0; level_num < log(N)/log(2); level_num++)        //级  {     //个数、蝶“距离”sample_num = 1 << level_num;  for(i = 0; i < N; i += 2*sample_num )     //组  {              for(j = 0; j < sample_num; j++)        //个  {         mul(x[i+j+sample_num],W[N*j/2/sample_num],&xw);  add(x[i+j],xw,&top);  sub(x[i+j],xw,&bottom);  x[i+j]=top;  x[i+j+sample_num]=bottom;  }  }  }
}void mul(complex a,complex b,complex *c)  //复数乘法的定义
{c->real=a.real*b.real-a.img*b.img;c->img=a.real*b.img+a.img*b.real;
}
void add(complex a,complex b,complex *c)  //复数减法的定义
{c->real=a.real+b.real;c->img=a.img+b.img;
}
void sub(complex a,complex b,complex *c)  //复数减法的定义
{c->real=a.real-b.real;c->img=a.img-b.img;
}

FFT.h:

#ifndef FFT__H_
#define FFT__H_#define s 1000typedef struct{double real;double img;}complex;
complex x[s];
complex *W;#pragma SDS data mem_attribute(a:PHYSICAL_CONTIGUOUS)
#pragma SDS data copy(a[0:s])
#pragma SDS data access_pattern(a:SEQUENTIAL)
#pragma SDS data sys_port(a:AFI)#pragma SDS data mem_attribute(b:PHYSICAL_CONTIGUOUS)
#pragma SDS data copy(b[0:s])
#pragma SDS data access_pattern(b:SEQUENTIAL)
#pragma SDS data sys_port(b:AFI)void mul(complex a,complex b,complex *c);
void add(complex a,complex b,complex *c);
void sub(complex a,complex b,complex *c);void FFT(complex *x, complex *W, unsigned int N);#endif

过程中一些语法和应用问题:

  • .c文件和.h文件在处理全局变量和结构体时的关系应用
    结构体是一种类型,定义一种类型最好是在.h定义,这样其他地方想用这个结构体,只需包含此.h文件即可,但是定义结构体变量的话,最好在.c文件中定义(为了防止重复定义,所以不建议在.c文件中定义变量),然后在.h里面extern声明,其他.c文件想用只需包含那个.h文件即可
//point.h
#ifndef POINT_H
#define POINT_H
struct POINT{
int x;
int y;
};
#endif//1.c
#include "point.h"
struct POINT p1,p2,p3;//1.h(#ifndef之类的略)
#include "point.h"
extern struct POINT p1,p2,p3;2.c
#include "point.h"
#include "1.h"
//后面就可以用p1,p2,p3了。以后每个.c都像这样用就可以了,变量在哪个.c里定义的,就在与之对应的.h里extern,以后要用到的每个头文件都include它。

参考:c语言头文件中定义全局变量的问题

画重点!这里引申出一个重要问题,不能在头文件中定义全局变量!就是说头文件中不可以放变量的定义!!!一般情况下头文件中只放变量的声明,因为头文件要被其他文件包含(即 #include),如果把定义放到头文件的话,就不能避免多次定义变量。就会报错为:multiple definition of
根据百度的搜索,有网友说:
原因有二:
一、跟踪难度大。如果工程小,跟踪其变化没有什么难度,如果工程很大,包含这个头文件的文件都有可能修改其值,出了问题不好排查。
二、c主要还是用于嵌入式,与硬件有关。许多嵌入式系统的内存不像电脑那么大,如果在头文件中声明全局变量,那么所有引用该头文件的文件都将为此变量非配内存,这样降低了内存的利用率,有时几K就是致命的。
也可参考:能不能在头文件中定义全局变量?
且,定义和声明并不是一个概念
extern的问题在于不知道这个关键词出现的时候到底是声明还是定义
1、函数的声明extern关键词是可有可无的,因为函数本身不加修饰的话就是extern。但是引用的时候一样需要声明的。

2、全局变量在外部使用声明时,extern关键字是必须的,如果变量没有extern修饰且没有显式的初始化,同样成为变量的定义,因此此时必须加extern,而编译器在此标记存储空间在执行时加载内并初始化为0。而局部变量的声明不能有extern的修饰,且局部变量在运行时才在堆栈部分分配内存。

3、全局变量或函数本质上讲没有区别,函数名是指向函数二进制块开头处的指针。而全局变量是在函数外部声明的变量。函数名也在函数外,因此函数也是全局的。

4、谨记:声明可以多次,定义只能一次。

5、

     extern int i; //声明,不是定义int i; //声明,也是定义
  • extern “C”的作用详解C++中为什么有时要使用extern "C"

  • #pragma once与 #ifndef的区别

  • strlen和sizeof的区别
    sizeof是运算符,在头文件中typedef为unsigned int,其值在编译时即计算好了,参数可以是数组、指针、类型、对象、函数等。
    它的功能是:获得保证能容纳实现所建立的最大对象的字节大小。具体而言,当参数分别如下时,sizeof返回的值表示的含义如下:数组——编译时分配的数组空间大小;指针——存储该指针所用的空间大小(存储该指针的地址的长度,是长整型,应该为4)。
    strlen是函数,要在运行时才能计算。参数必须是字符型指针。当数组名作为参数传入时,实际上数组就退化成指针了。
    它的功能是:返回字符串的长度。该字符串可能是自己定义的,也可能是内存中随机的,该函数实际完成的功能是从代表该字符串的第一个地址开始遍历,直到遇到结束符NULL。返回的长度大小不包括NULL。

  • struct和typedef struct区别
    1 、注意在C和C++里不同
        在C中定义一个结构体类型要用typedef:
        typedef struct Student
        {
        int a;
        }Stu;
        于是在声明变量的时候就可:Stu stu1;(如果没有typedef就必须用struct Student stu1;来声明)
        这里的Stu实际上就是struct Student的别名。Stu==struct Student
        另外这里也可以不写Student(于是也不能struct Student stu1;了,必须是Stu stu1;)
        typedef struct
        {
        int a;
        }Stu;
        但在c++里很简单,直接
        struct Student
        {
        int a;
        };    
        于是就定义了结构体类型Student,声明变量时直接Student stu2;
    2、在c++中如果用typedef的话,又会造成区别:
        struct Student
        {
        int a;
        }stu1;//stu1是一个变量
        
        typedef struct Student2
        {
        int a;
        }stu2;//stu2是一个结构体类型=struct Student
        
        使用时可以直接访问stu1.a,但是stu2则必须先 stu2 s2; 然后 s2.a=10;

  • C语言头文件和""的区别
    1.头文件#include <> :表示引用标准库头文件,编译器会从系统配置的库环境中去寻找
    2.头文件#include “”:一般表示用户自己定义使用的头文件,编译器默认会从当前文件夹中寻找,如果找不到,则到系统默认库环境中去寻找。

  • 包含指针的结构体作为函数的参数
    参考:结构体作为函数的参数
    后在build的时候发现报错,不论是结构体数组做函数参数还是指向结构体变量的指针做函数参数,在调用该函数时,其变量前均可不加取地址符(即&)。
    书上是这么说的:用指向结构体变量(或数组)的指针做实参是经常采用的一种办法。形参指针和实参指针都指向同一存储单元,形参值的改变会影响实参的值。这种特点为函数返回多个数据提供了途径。给出的代码如下:

#include <stdio.h>struct student
{int num;char *name;float score[3];
};float average(struct student *pstu)
{float aver;float sum = 0;for(int i = 0; i < 3; i++){sum += pstu -> score[i];}aver = sum/3;return aver;
}void main()
{struct student stu;float aver;stu.num = 1001;stu.name = "Mary";stu.score[0] = 87.6f;stu.score[1] = 78.2f;stu.score[2] = 84.1f;aver = average(&stu);printf("num = %d name = %s average = %f\n",stu.num,stu.name,aver);
}

这里的aver = average(&stu);中如果删除&就会报错如下:
但如果是在SDx这个工程的main.c里在调用FFT函数时在参数W(即指向结构体变量的指针)前加上这个&, build又会报错:
对于指针这个神奇的物种,有点迷但又很有趣,玩好了一定很有意思。这里可以再从指针的初衷去琢磨。(题外话,也不知道是什么时候开始,对编程的兴趣没以前那么大了,可能是后来觉得写什么都写不好,怎么写都有bug,虽然其中能学到很多以前不知道的。。。哎。。。不知道我这样的人到底能做好什么,大概也是我最近丧的很的原因。勉励自己,希望不要那么丧,抓紧时间和时机,找些有趣的函数或者算法去写去上板实现。加油啊。)

  • .c文件和.h文件的关系
    .c文件和.h文件的区别

  • SDS pragma
    过程均可参考官方文档:UG1027,也可参考github的sdx教程:SDSoC Environment Tutorial。build过了之后,根据上述文档或教程,添加SDS指令。这里有一篇博客,讲的还挺详细:SDS pragma,有SDS的指令简介。

  • 另外注意的是,教程里的系统是linux系统,平时自己搞点小事情是裸机在跑,所以一些相应的配置要改。

在project.sdx内将system configuration设置为standalone。
在debug configuration(工程名右键—>debug as—>debug configuration)里修改相应设置:
还有将板子上的跳帽位置改为JTAG模式,因为要下elf文件。

顺序大致就是build,连接开发板上电,debug。虽然指示灯看起来亮的正确,但SDx terminal里没有打印出任何信息,打开 secureCRT也显示没有串口信息,接的是UART串口,为啥没有打印出信息,搁置了几天也没有再研究。。。还是丧的很。。。

FPGA series # 基于SDx的fft函数加速相关推荐

  1. matlab fft(x dim),matlab的fft函数

    matlab中fft的用法及注意事项_调查/报告_表格/模板_实用文档.本文是笔者整理的如何使用matlab的fft函数及fftshift函数,希望对大家有所帮助!... C 语言.MATLAB 实现 ...

  2. 基于ppg和fft神经网络的光学血压估计【翻译】

    基于ppg和fft神经网络的光学血压估计 摘要 我们引入并验证了仅使用指尖的光体积描记图(PPG)信号的逐拍光学血压(BP)估计范式.该方案确定了主体对PPG信号的特定贡献,并通过适当的归一化去除其大 ...

  3. Matlab中fft函数的使用与原理

    快速傅里叶变换(Fast Fourier transform,FFT) 利用离散傅里叶变换(DTF)算法进行运算时,复数乘法运行次,复数加法运行次,计算量其实可以通过fft减小.1965年,首先由Co ...

  4. java 下载加速_一种基于Java的大文件下载加速方法与流程

    本发明涉及java/多线程技术领域,涉及一种加速文件下载装置,具体提供一种基于java的大文件下载加速方法. 背景技术: 现有的常用下载方式是基于浏览器的单线程下载.这种单线程下载的方式,是通过htt ...

  5. matlab函数fftshift,matlab中fft算法_matlab中fftshift函数_matlab中fft函数的用法(2)

    plot([0 : PointNum/2 - 1], x1(1:PointNum/2)); grid on subplot(3,1,2); % [REX IMX] am = sqrt(abs(REX. ...

  6. R语言window函数提取时序数据数据子集(subset):使用xts包将dataframe数据转化为时间序列数据(time series)、使用window函数从时间序列对象中提取数据子集

    R语言window函数提取时序数据数据子集(subset):使用xts包将dataframe数据转化为时间序列数据(time series).使用window函数从时间序列对象中提取数据子集 目录

  7. R行数据过滤基于dplyr包filter函数

    R行数据过滤基于dplyr包filter函数 目录 R行数据过滤基于dplyr包filter函数 筛选等于某个值的行 使用与操作筛选行

  8. 【numpy】几种fft函数的使用

    numpy下fft模块提供了丰富的fft函数,几种常用的在这里记录一下使用方式 fft 输入实数samples,如果输入的sample是带虚数部分的话,虚数部分会被默认删除. t=np.arange( ...

  9. 编写 matlab怎么调用 8 点和 16 点的 fft,8点基于DIT的FFT的实现

    七月份工作总结暨八月份营销方案 (10) X[m]?X1[m]?W8mX2[m],m?0,1,2,3,4,5,6,7 图1-4 16点蝶形运算图 2 程序代码 2.1 计算8点FFT代码 functi ...

最新文章

  1. 验证异常处理调用顺序
  2. ARC106E-Medals【hall定理,高维前缀和】
  3. c语言期末考试复习题
  4. 编辑器内容FCKeditor的js验证以及FCKeditor内容是否为空判断
  5. access数据库拆分的用途_在Access中手动拆分数据库
  6. 搜狗词库scel格式转txt文本
  7. 汉王考勤管理系统使用教程
  8. IOTQQ(OPQbot)—QQ机器人、部署在linux上(一步步实
  9. 西门子200PLC步进控制(入门)
  10. dnf喇叭怎么设置不显示服务器,《DNF》屏蔽广告喇叭方法 广告喇叭怎么关掉
  11. 如何使用linux command line 利用Entrez Direct下载NCBI数据
  12. PHP域名whois查询代码(数据源万网、新网)
  13. 【0704】HL普及组模拟赛题解及反思
  14. Java-Collection集合之单列集合List,以及遍历方式
  15. C语言snmp编程视频,使用net-snmp API编程_C语言教程_C++教程_C语言培训_C++教程培训_C/C++频道_中国IT实验室...
  16. Python中的字典该怎么用,看这一篇就够了(结尾有惊喜)
  17. [Angular2]eclipse中angular2开发环境的搭建
  18. 台达变频器485通讯接线图_台达变频器基本配线图
  19. a = a++ 与 a = ++a
  20. bc计算A股上市新股依次涨停股价

热门文章

  1. 又一国艺被日本偷师:抹茶在中国失传,却被日本人发扬光大
  2. 1919: kirito's 星爆气流斩 多重背包
  3. 多用途数据主导“物联网未来”的实施
  4. Nature Communications:使用连接组的嵌入向量表征映射大脑结构与功能之间的高阶关系
  5. Wps日期时间格式转文本、科学计数法转数字
  6. 谷歌浏览器访问抖音网页版白屏
  7. 洗牌-牛客 第一行一个数T(T ≤ 100),表示数据组数。对于每组数据,第一行两个数n,k(1 ≤ n,k ≤ 100),接下来一行有2n个数a1,a2,...,a2n(1 ≤ ai ≤ 1000
  8. 如何解决中小企业融资难问题
  9. python绘制笛卡尔直角坐标系
  10. 查看QQ空间秘密的发布时间