最近翻起读研期间在evernote中的一些琐碎记录,主要包括c语言,fpga和dsp开发的,那个时候还是初学者,犯了很多很弱的错误
—————————————————————————————————————————————————————————————————————————————
c语言
1
) 当一个变量存放的值为地址值时,想要取出该地址上的值,需要将该变量转化为指针变量。例如:pa=(int*)0xb000 0000,这里pa就是指向这个地址的指针并且地址上存放int值。也可以这么写uint32 pa=0xb000 0000,pa=(int*)pa
。
二级指针,如果pa = (int**) 0xb000 0000。pa存放地址0xb000 0000,*pa则取出0xb000
0000上的值但是编译器认为这个值是指向存放int值的地址。
错例:int *pa; void fun(int **a) {a = (int **)malloc(sizeof(int)*5);} fun(&pa);
这里形参a为指向指针pa的指针,这里a已经被赋值。fun函数中将malloc的申请空间的指针返回给a,注意这时a的值为指向malloc申请空间的指针,但是这里强制将其变为二级指针,意味着malloc的空间中存放的值,被认为是指向存放int数据空间的地址。
2)<<的优先级低于加减运算符,a<<1+3,相当于a<<4
3)C语言读文件,比如利用fscanf函数,读数据的单位是一个字节,单字节符号包括回车和空格等都会被逐个读出。
4)static数据类型和全局变量都被安排到静态区存储,但是static只能在单一源文件用,全局变量可以在其他源文件extern。
5)在c语言中%f 对应float,而double对应%lf,切记,经常出现用%f对应double导致错误。
6)#ifdef __cplusplus
extern "C" {
#endif
//一段代码
#ifdef __cplusplus
}
#endif
这个主要解决c与c++兼容的问题,c++支持函数重载,一个函数fun(int)在c++编译后的名字为 _fun_int,而c编译仅为_fun,因此重名(重载)函数在c中绝不容许,而c++可根据参数列表区分。
这段代码意义为:如果是在c++环境下用c编译代码,当然,如果当前环境就为c,那不做操作。
—————————————————————————————————————————————————————————————————————————————
FPGA
尽量在上升沿地址准备,下降沿写入数据。
FPGA FIFO向DSP发送数据存在如下疑问,
1)为何FIFO中数出列,要向EMIF总线0x0110h上执行写操作;可能是DSP读脉冲间隔太短,导致无法及时出数,需要一个写操作形成两个节拍;经过验证,确实是这样,而且只要执行一个不相关的操作(也可以称为是空操作),给FPGA响应留下一个节拍即可。[ft=rgb(255, 0, 0),,](这里还需要对持续时间,并且需要对每条指令执行用时加强分析)
2)以写操作为时钟,FPGA收到上升沿触发后即刻移动读地址,那么读地址为1,为什么首次读取为地址0;
代码如下:
always @(posedge(r_addr == 0x0110h))
ren<=1;
read_addr<=read_addr+1;
end
当访问EMIF总线 0x0110h 时,读使能ren 被使能,此时read_addr 为0,这时EMIF总线已经满足传数操作,于是将0处的数发送出去了。而且从FPGA整个文档中来看,ren的值一直为1,也就是说,只要访问总线,马上就能发送数据。
3)EMIF总线上杂数据出现是为什么。
串口调试,如下
FPGA=>MAX232芯片==>TTL电平==>MAX232芯片==>电脑(RS232)RS232 为负逻辑,可双向传输,全双工通讯,最高传输速率20kbps,
MAX232电平转换,TTL信号并行传输方式,由于信号不对称,有效传输距离不过10英尺,一般232电平很高正负15V,而FPGA的TTL电平才5V。
在这里我们选择RS232的传输速率为19200bps,选定每个字节的发送频率为
1/80的19200,需要FPGA每隔1/80的19200才接收一个byte;同时发送数的起始位为0,终止位为1,也就是发一个字节的数需要10位, 当FPGA接收到一个byte后在这个周期内需要10个脉冲分别发送这10bit数,FPGA发送1bit的速率为1/8的19200。
关于FIFO,读空标志和写空标志意义并不一样,如果用双口RAM模拟FIFO,就可以发现,由于用的是非阻塞赋值,每次读数和能读出来的数相差一个节拍,也就是说当你进行第二次读操作的时候,其实读出来的是第一个数的值。也就是说流程为:写=>读=>清零=>写,假定每个操作都只有一个DSPCLK,那么当最后一个写操作的时候,最后一个数要等到第一个读操作的时候才被放置到RAM中,那么进入流程的第一次读操作这个时候总线上的值为多少呢,应该是0,因为数据线要等到下一个读操作才会有值,最后一个读操作要等到下一个操作来的时候才将值放到数据总线上,也就是说此时我们没来的及将最后的一个数存放到DSP的缓冲区中,然后清零操作,当下一次写操作的时候,才真正清零,写的最后一个数要等到下一次读操作的时候才被放置在RAM上,这时读出来的数就是上一次读的最后一个数,它被保持在读的数据总线上。
————————————————————————————————————————————————————————————————————————————
DSP
1)一个最基本的DSP工程包括CMD文件,C源文件,C运行时库文件rts6400.lib。
2)DSP与外设进行数据交换必须要事先配置锁相环PLL,进行时钟倍频。
3)数据总线用来传递数据,数据是各种信息的数字化表示,emifa 64位的数据总线表示可以有8M的范围来发送信息,这就是说只要将数据放到这个范围内的任意地址上都可以发送数据。
地址总线用来发送地址,与数据总线不同,这里的数据变成地址,专门用来发送地址,20位地址总线表示有1M的范围来发送地址信息。