男生和女生一起生猴子还是

核心内容摘要

jmcomic.2.0.micios:指尖上的二次元宇宙,解锁无限可能
[中文][3d全彩]妈妈的教育方式

成人久久久精品推荐

4 软件程序解析

main.c源文件软件程序解析main.c的函数列表如表

所示。

int main(void)函数该函数在外设初始化后通过JTAG UART打印一串初始化信息接着依次对Flash的1023块进行擦除、写入并打印所有写入数据、读出并打印所有读出数据最后LED不停地闪烁。

该函数依次执行以下操作。

①打印初始化信息。

②擦除Flash的第1023块数据。

③读取并打印Flash第1023块首页数据。

④产生一组数据写入到Flash第1023块首页中。

⑤再次读取并打印Flash第1023块首页数据。

⑥LED循环闪烁。

flash.c源文件软件程序解析flash.c的函数列表如表

所示。

1void Flash_page_write(alt_u32 fpage,alt_u16 write_data_num)函数该函数实现Flash的页写操作。

该函数有两个入口参数fpage表示写入Flash的页地址write_data_num表示写入数据字节数。

flashdb为2048字节的全局数组在调用该函数前需要将写入Flash的数据预先缓存到该数组中。

该函数依次执行以下操作。

①读取状态寄存器判断并等待Flash处于忙状态。

②送Flash操作页地址。

③开启写使能。

④连续写数据1~2048 B。

⑤关闭写使能结束操作。

2void Flash_page_mcuread(alt_u32 fpage,alt_u16 write_data_num)函数该函数实现Flash的页读操作。

该函数有两个入口参数fpage表示写入Flash的页地址write_data_num表示读出数据字节数。

flashdb为2048字节的全局数组在调用该函数后Flash中读出的数据将被缓存到该数组中。

该函数依次执行以下操作。

①读取状态寄存器判断并等待Flash处于忙状态。

②送Flash操作页地址。

③开启读使能。

④读取状态寄存器判断并等待Flash处于忙状态。

⑤连续读数据1~2048 B。

⑥关闭读使能结束操作。

3void Flash_block_erase(alt_u16 fblock)函数该函数实现Flash的块擦除操作。

该函数只有一个入口参数fblock表示Flash的擦除块地址。

该函数依次执行以下操作。

①读取状态寄存器判断并等待Flash处于忙状态。

②送操作块地址。

③开启擦除操作。

④稍作延时1μs即可。

⑤结束擦除操作。

5 板级调试①打开“http://www.hzcourse.com/resource/readBook?path/openresources/teach_ebook/uncompressed/15714/OEBPS/Text/...\prj\vip_ex4”下的工程。

②使用Programmer将“http://www.hzcourse.com/resource/readBook?path/openresources/teach_ebook/uncompressed/15714/OEBPS/Text/...\prj\vip_ex4\output_files”文件夹下的vip.sof文件下载到VIP核心板中。

③打开EDS软件。

导入“http://www.hzcourse.com/resource/readBook?path/openresources/teach_ebook/uncompressed/15714/OEBPS/Text/...\prj\vip_ex4\software”文件夹下的软件工程包括应用工程和BSP工程。

④运行应用软件片刻后可以看到Nios II Console开始打印如图

和图

所示的数据。

完成打印后LED指示灯D1开始闪烁。

在打印窗口中我们可以看到本实例的软件执行了4个主要操作。

·擦除NAND Flash的第1023 Block的数据。

·读出刚刚执行完擦除操作的NAND Flash的第1023 Block的第1个Page数据。

刚擦除完都是0xff的数据。

·产生一组0到255递增的数据写入到NAND Flash的第1023 Block的第1个Page中。

·写入完成后读出这个Page的数据以此确认写操作是否正确执行。

工程实例5——多分辨率VGA显示驱动本章导读本章的工程实例设计一个简单的VGA驱动控制器产生Color bar。

有VGA基本知识的讲解、VGA驱动时序产生的原理讲解、代码解析以及与本工程实例相关的FPGA配置引脚复用设置。

尽管是一个简单的例程但是我们将仍然不遗余力地将更多的知识点传授给读者。

1 功能概述VGAVideo Graphics Array即视频图形阵列是IBM在1987年随PS/2PS/2原是“Personal System 2”的意思“个人系统2”是IBM公司在1987年推出的一种个人电脑。

PS/2电脑上使用的键盘鼠标接口就是现在的PS/2接口。

因为标准不开放PS/2电脑在市场中失败了。

只有PS/2接口一直沿用到今天一起推出的使用模拟信号的一种视频传输标准在当时具有分辨率高、显示速率快、颜色丰富等优点在彩色显示器领域得到了广泛的应用。

这个标准对于现今的个人电脑市场已经十分过时。

即使如此VGA仍然是最多制造商所共同支持的一个标准个人电脑在加载自己的独特驱动程序之前都必须支持VGA的标准。

例如微软Windows系列产品的开机画面仍然使用VGA显示模式这也说明其在显示标准中的重要性和兼容性。

VGA最早指的是显示器640×480这种显示模式。

而今天的VGA其实已经不仅仅局限于640×480这种分辨率了通常情况下各种各样适用于VGA接口传输的分辨率都可以统称为VGA。

当然了严格来讲每个分辨率都会有自己的叫法如800×600就称作SVGA。

VGA接口如图

所示。

驱动VGA显示的接口主要有以下3种信号行同步信号HSYNC、场同步信号VSYNC和3条色彩电压传输信号R、G、B分别对应。

色彩信号的电压为0~

7V其同步是靠前面两个信号来协助的。

至于HSYNC、VSYNC和色彩信号之间以什么样的关系进行传输这都是相对固定的虽然VGA收发双方没有时钟信号做同步但我们通常会约定发送方有一个基本的时钟VSYNC、HSYNC和色彩信号都会按照这个时钟的节拍来确定状态。

VGA的接口时序如图

所示场同步信号VSYNC在每帧即送一次全屏的图像开始的时候产生一个固定宽度的高脉冲行同步信号HSYNC在每行开始的时候产生一个固定宽度的高脉冲色彩数据在某些固定的行和列交汇处有效。

VGA驱动基本时序如前所述我们通常以一个基准时钟驱动VGA信号的产生用这个基准时钟为时间单位来产生的时序如图

所示。

对于一个刷新频率为60Hz分辨率为640×480的标准VGA显示驱动若它的基准驱动时钟为25MHz则它的计数脉冲参数如表

所示。

注意列的单位为“行”而行的单位为“基准时钟周期数”即25MHz时钟脉冲数。

对于一个刷新频率为72Hz分辨率为800×600的SVGA显示驱动若它的基准驱动时钟为50MHz它的计数脉冲参数如表

所示。

注意列的单位为“行”而行的单位为“基准时钟周期数”即50MHz时钟脉冲数。

对于一个刷新频率为60Hz分辨率为1024×768的显示驱动若它的基准驱动时钟为65MHz则它的计数脉冲参数如表

所示。

注意列的单位为“行”而行的单位为“基准时钟周期数”即65MHz时钟脉冲数。

对于一个刷新频率为60Hz分辨率为1280×960的显示驱动若它的基准驱动时钟为108MHz则它的计数脉冲参数如表

所示。

注意列的单位为“行”而行的单位为“基准时钟周期数”即108MHz时钟脉冲数。

对于一个刷新频率为60Hz分辨率为1280×1024的显示驱动若它的基准驱动时钟为108MHz则它的计数脉冲参数如表

所示。

注意列的单位为“行”而行的单位为“基准时钟周期数”即108MHz时钟脉冲数。

对于一个刷新频率为60Hz分辨率为1920×1080的显示驱动若它的基准驱动时钟为130MHz则它的计数脉冲参数如表

所示。

注意列的单位为“行”而行的单位为“基准时钟周期数”即130MHz时钟脉冲数。

了解了VGA的基本驱动原理我们还要回来看看实际驱动电路的工作原理。

由于FPGA接口都是数字信号无法直接输出VGA色彩信号所需的0~

7V模拟电压所以需要使用专门的DAC芯片进行转换。

我们的SF-VGA子板就板载了一颗专用的3路DAC转换芯片ADV7123。

本实例连接VIP1核心板和SF-VGA子板进行实验。

VGA驱动时序产生模块通过宏定义实现VGA/SVGA/720p/1080p多分辨率显示驱动功能框图如图

所示。

2 装配说明VIP1核心板的OUTPPN插座P4连接到SF-VGA子板的P1。

SF-VIP1核心板和SF-VGA子板的连接示意如图

所示。

3 复用引脚设置在该实例中SF-VGA子板连接VIP核心板的插座P4。

在分配好引脚后若直接进行编译则将会出现如图

所示的错误。

这是怎么回事为什么Pin_F16有“multiple pins assigned to”即多个信号分配给这个引脚如图

所示pin assignment中并没有多个信号分配给Pin_F16这个引脚只有adv7123_sync_n分配给了它。

再来看看如图

所示的原理图这里的F16引脚FPGA的功能定义是“IO,DIFFIO_R4n,(nCEO)”。

问题就在这个“nCEO”上这是个配置相关的引脚默认情况下Quartus II工具认为它作为配置功能使用如果用户将它分配到信号上则编译时必定报错。

那么这个错误如何规避呢很简单大家在Quartus II菜单中执行Assignments→Device命令进入Device界面如图

所示。

找到“Device and Pin Options”按钮单击它。

此时弹出如图

所示的界面在Category下面的列表框中选择“Dual-Purpose Pins”然后找到右侧的“nCEO”一栏默认的设置是“Use as programming pin”双击它将其改为“Use as regular I/O”。

重新编译工程后不会再有错误信息。

同样的如果使用“Dual-Purpose Pins”遇到类似的问题可以通过类似的方式解决。

4 Verilog代码解析本实例有4个模块sys_ctrl.v和其下的pll_controller.v作为一个模块2个层级其层次结构如图

所示。

工程实例5代码层次图·vip.v是顶层模块其下例化了3个子模块即sys_ctrl.v模块、vag_ctrl.v模块和led_controller.v模块。

该模块仅仅用于子模块间的接口连接以及连接到FPGA外部接口的定义该模块中未作任何的逻辑处理。

·sys_ctrl.v二级子模块中例化了PLL模块并且对输入PLL的复位信号以及PLL锁定后的复位信号进行“异步复位同步释放”的处理确保系统的复位信号稳定可靠。

·vga_ctrl.v二级子模块产生多分辨率VGA显示驱动逻辑。

·led_controller.v二级子模块进行24位计数器的循环计数产生分频信号用于实现LED指示灯的闪烁。

Vip.v模块代码解析略。

Sys_ctrl.v模块代码解析略。

Led_controller.v模块代码解析略。

vga_ctrl.v模块代码详解vga_ctrl.v模块的设计代码产生最基本的VGA驱动和显示测试。

代码中因为我们的电路中使用了3路DAC驱动的芯片ADV7123进行VGA色彩信号电压的产生该芯片的驱动有两个用于同步数据的信号也需要在接口中产生相应的时序。

简单来看控制这颗DAC芯片的也就是一个用于数据锁存的时钟以及两个同步信号还有就是3组要送给VGA显示器的色彩数据R、G、B信号的数字值它们之间只要产生一组符合芯片手册要求的时序即可完成3路VGA所需的色彩电压。

此外为了让代码能够更好地在不同分辨率之间移植切换我们使用了预编译指令ifdef语法其实和C语言的预编译指令用法基本类似。

vga_ctrl.v模块的逻辑设计功能框图如图

所示。

①从接口来看vga_ctrl.v模块可以分为两大类一类是时钟和复位信号时钟都是PLL处理后输出的如下所示。

input clk_25m;input clk_50m;input clk_65m;input clk_108m;input clk_130m;input rst_n;另一类接口是ADV7123芯片的接口信号ADV7123是一颗3路DAC芯片用于将数字信号转换为VGA可以接收的RGB模拟电平。

接口如下所示。

output[4:0] vga_r;output[5:0] vga_g;output[4:0] vga_b;output reg vga_hsy,vga_vsy;output vga_clk;output adv7123_blank_n;output adv7123_sync_n;②我们先来看时钟信号驱动ADV7123的同步时钟只需要一个但为何引了这么多的时钟源进来呢我们不妨先看看源代码。

//-----------------------------------------------------------wire clk;assign vga_clk clk;//-----------------------------------------------------------//define VGA_640_480//define VGA_800_600//define VGA_1024_768//define VGA_1280_960//define VGA_1280_1024define VGA_1920_1080//-----------------------------------------------------------ifdef VGA_640_480//VGA Timing 640*480 25MHz 60Hzassign clk clk_25m;……endififdef VGA_800_600//VGA Timing 800*600 50MHz 72Hzassign clk clk_50m;……endififdef VGA_1024_768//VGA Timing 1024*768 65MHz 60Hzassign clk clk_65m;……endififdef VGA_1280_960//VGA Timing 1280*1024 108MHz 60Hzassign clk clk_108m;……endififdef VGA_1280_1024//VGA Timing 1280*1024 108MHz 60Hzassign clk clk_108m;……endififdef VGA_1920_1080//VGA Timing 1920*1080 130MHz 60Hzassign clk clk_130m;……endif这里的宏定义“define VGA_1920_1080”使得随后的众多“ifdefhttp://www.hzcourse.com/resource/readBook?path/openresources/teach_ebook/uncompressed/15714/OEBPS/Text/...endif”语句只有一个有效即ifdef VGA_1920_1080//VGA Timing 1920*1080 130MHz 60Hzassign clk clk_130m;……endif因此“assign vga_clkclk;”等效于“assign vga_clkclk_130m;”。

同理若在如下宏定义中任意且只有一个有效的情况下响应的“ifdefhttp://www.hzcourse.com/resource/readBook?path/openresources/teach_ebook/uncompressed/15714/OEBPS/Text/...endif”语句则有效那么时钟源就由此决定了。

//define VGA_640_480//define VGA_800_600//define VGA_1024_768//define VGA_1280_960//define VGA_1280_1024此外在“ifdefhttp://www.hzcourse.com/resource/readBook?path/openresources/teach_ebook/uncompressed/15714/OEBPS/Text/...endif”语句中定义的其他参数也由此确定。

③如图

所示对于一个液晶屏来说我们传输数据不可能一下全都送过去没有那么大的带宽。

我们只能一个像素点一个像素点地送色彩数据从方向上来看就是从左到右x轴方向从上到下y轴方向。

因此我们的代码中定义了两个12位的计数器即x轴计数器xcnt和y轴计数器ycnt。

xcnt随主时钟不停地计数ycnt在xcnt计数器完成一个周期计数时才会递增计数它也有自己的计数周期。

xcnt和ycnt的计数周期值都是由前面的参数定义好的。

xcnt和ycnt计数器的计数逻辑代码如下所示。

//-----------------------------------------------------------//x and y counterreg[11:0] xcnt;reg[11:0] ycnt;always (posedge clk or negedge rst_n)if(!rst_n) xcnt 12d0;else if(xcnt VGA_HTT) xcnt 12d0;else xcnt xcnt1b1;always (posedge clk or negedge rst_n)if(!rst_n) ycnt 12d0;else if(xcnt VGA_HTT) beginif(ycnt VGA_VTT) ycnt 12d0;else ycnt ycnt1b1;endelse ;④如图

所示实际的数据传输方式不是仅仅只有x轴和y轴的有效显示图像的数据而是在每一行或每一场即一整个屏幕的图像帧的开始和结束都有一些空闲的时间这个时间内的数据不显示在屏幕上可以用来产生一些同步信号避免行、场的错乱。

从实现上来看行同步信号vga_hsy和场同步信号vga_vsy分别在x轴计数和y轴计数的空闲时间产生一个高脉冲以此达到同步的目的。

逻辑代码如下。

//-----------------------------------------------------------//hsy and vsy generatealways (posedge clk or negedge rst_n)if(!rst_n) vga_hsy 1b0;else if(xcnt VGA_HST) vga_hsy 1b1;else vga_hsy 1b0;always (posedge clk or negedge rst_n)if(!rst_n) vga_vsy 1b0;else if(ycnt VGA_VST) vga_vsy 1b1;else vga_vsy 1b0;⑤对于显示的有效区域即x轴和y轴整个计数周期相互交叉的有效区域内我们是需要送像素色彩给显示器的显示有效区域标志信号产生的逻辑代码如下。

//-----------------------------------------------------------//vga valid signal generatereg vga_valid;always (posedge clk or negedge rst_n)if(!rst_n) vga_valid 1b0;else if((xcnt (VGA_HSTVGA_HBP)) (xcnt (VGA_HSTVGA_HBPVGA_HVT)) (ycnt (VGA_VSTVGA_VBP)) (ycnt (VGA_VSTVGA_VBPVGA_VVT)))vga_valid 1b1;else vga_valid 1b0;assign adv7123_blank_n vga_valid;assign adv7123_sync_n 1b0;⑥余下的逻辑在液晶屏有效显示区域内产生一个color bar的效果通过判断不同的x和y坐标位置送相应的色彩值来实现。

5 板级调试①连接好硬件VIP核心板SF-VGA子板VGA显示器通用电脑显示器并且给VIP核心板上电。

②打开“http://www.hzcourse.com/resource/readBook?path/openresources/teach_ebook/uncompressed/15714/OEBPS/Text/...\prj\vip_ex5”文件夹下的Quartus II工程。

③使用Programmer将“http://www.hzcourse.com/resource/readBook?path/openresources/teach_ebook/uncompressed/15714/OEBPS/Text/...\prj\vip_ex5\output_files”文件夹下的vip.sof文件下载到VIP核心板中此时VIP板上的指示灯D1开始闪烁。

并且在电脑显示器上出现了Color Bar默认代码的显示驱动分辨率是1920×1080大家可以尝试更改vga_ctrl.v模块中的宏定义使用不同分辨率驱动液晶屏显示。

1080p的显示效果如图

所示。

鲸鱼视频-鲸鱼视频应用

百度百家号客服电话人工服务

123 123 123 123 123 123 123 123 123 123 123 123 123 123 123 123 123 123 123 123 123 123 123 123 123 123 123 123 123 123 123 123 123 123 123 123 123 123 123 123 123