当前位置:首页 >> 信息与通信 >>

基于FFPGA的图像压缩传输与解码系统


《sopc》课程报告之五

《基于 FFPGA 的图像压缩传输与解码系统》技术报告

院系:电子工程学院微电子学系 小组成员:郭从林 朱潮勇 杨欢 程亭 班级:电路 1103 班 组长:郭从林 学号:05116093 日期:2015 年 1 月 3 日

《基于 FFPGA 的图像压缩传输与解码系统》技术报告

>摘要
本文介绍了基于 SOPC 的通用嵌入式图像处理系统的实现方法,其中叙述 了 SOPC 及 NIOS ii 嵌入式处理器的特点和使用。分别具体说明了系统的硬件结 构设计和图像处理算法的流程及软件实现, 采用此系统可以大大简化图像处理系 统的硬件和软件设计,优化系统设计。 关键字:SOPC(可编程片上系统);嵌入式处理器;静止图像压缩

一、 引言
1)随着计算机和多媒体技术的发展,图像等多媒体信源的传输处理显得 日益重要,各种图像压缩处理的标准、协议也相继出现,其中 JPEG 静止 图像压缩编码是图像压缩的一项重要技术,也是图像压缩的一个基本指 标。 可编程片上系统 SOPC(System on a Programmable Chip)将处理器、存储 器、I/O 等系统模块集成到单片 FPGA,完成系统的功能设计,使整个系 统设计更加灵活,可扩充,可裁减,并且实现了软硬件的可编程,因此本 系统采用 NiosⅡ嵌入式处理器实现一个通用嵌入式图像处理系统。 2) 通过 UART 传输图像的压缩信息,在 sopc 中解压并传输到 VGA 显示 器显示 3)实现图像压缩传输,解压缩,显示。

二、 功能定义
功能:定义所开发项目软件与硬件功能; 硬件设计部分 1.使用 FPGA 普通端口作为 GPIO 使用。 2.使用 FPGA 开发板的 50MHZ 时钟分频后 25MHZ 作为 VGA 输出时钟。 3.时钟频率 25MHZ 完成行扫描信号计数。

4.时钟频率 25MHZ 完成祯扫描信号计数,并完成祯计数。 5.在行,场信号有效范围内进行 VGA 数据输出。 软件设计部分 1:用 matlab 取图像的 reb 值,将取出的 rgb 值写入文件。 2:读取 rbg 值,将十六进制数表示的 rgb 值转化为以该 asc||值对应的 字符(减少信息传输量),将转化后的的字符写入文件中。 3:对转化后的文件数据进行压缩,发送目标文件格式为,文件头信息, 发送文件的起始信息,用来判定开始发送数据,用三个字节,信息数据为 GCL,一个字节表示最后一个字节的有效位,最后一个字节有效位为 0bit8bit 之间,一个字节表示文件中 rgb 的种类,0-255,四字节,表示整个压 缩文件的大小,其后数据格式为,字符及字符对应的出现次数,即字符频 度信息,字符频度之后对应的是压缩信息。 性能指标:频率、功耗等各种与系统相关性能指标;

三、 系统验证方案
描述系统级的验证方案,要求测试案例覆盖所设计系统的全部功能。 测试案例 1:验证 Huffman 算法压缩解压缩可行性 1:编写最简单的 huffman 树,huffmancode,compress code。 2:显示软件统计字符及频度与最小模型是否一样。 3:显示软件生成的 huffmantab 与最小模型 huffmantab 是否一样。 4:显示软件递归生成的 huffmantab code 与最小模型 huffmantab code 是 否一样。 5 显示软件递归生成 compresse code 与最小模型 compress code 是否一样。

测试案例 2:验证 UART 传输的正确性 利用串口由文件中读取数据,nios 接收收据后将数据返回并显示,对比 发送接收过程是否有数据丢失。确保数据正常的传输。 软件功能定义 LCD 完成数据的显示。 LCD 的控制由 8bit 数据线, 1bit 的 RS 寄存器选 择端,1 数据寄存器,0 表示指令寄存器,EN 为 1bit 的使能端,值由 0

到 1 发生跳变,液晶执行指令,RW 为 1bit 的读写信号线,高电平执行读 的功能,低电平执行写的功能。lcd_on 为电源端,lcd_blon 为背光。 软件详细设计 1:LCD 写命令 void LCD_Write_Command(Boolean Command) { IOWR_ALTERA_AVALON_PIO_DATA(LCD_DATA_ADDRESS , Command); //写 数 IOWR_ALTERA_AVALON_PIO_DATA(LCD_RS_ADDRESS , 0); //指令 IOWR_ALTERA_AVALON_PIO_DATA(LCD_RW_ADDRESS IOWR_ALTERA_AVALON_PIO_DATA(LCD_EN_ADDRESS , , 0); 1); // // 写 入 使 能

IOWR_ALTERA_AVALON_PIO_DATA(LCD_EN_ADDRESS , 0); // usleep(2000);//2ms /*延时*/ } 2:LCD 写数据 void LCD_Write_data(Boolean Data) { IOWR_ALTERA_AVALON_PIO_DATA(LCD_DATA_ADDRESS , Data); //写数据 IOWR_ALTERA_AVALON_PIO_DATA(LCD_RS_ADDRESS , 1); IOWR_ALTERA_AVALON_PIO_DATA(LCD_RW_ADDRESS , 0); IOWR_ALTERA_AVALON_PIO_DATA(LCD_EN_ADDRESS , 1); /*延时 150ns*/ IOWR_ALTERA_AVALON_PIO_DATA(LCD_EN_ADDRESS , 0); // usleep(2000);//2ms /*延时*/ } 4:LCD 初始化 void LCD_Write_Command(Boolean Command) {IOWR_ALTERA_AVALON_PIO_DATA(LCD_DATA_ADDRESS , Command); // 往 数据 IOWR_ALTERA_AVALON_PIO_DATA(LCD_RS_ADDRESS , 0); //指令 IOWR_ALTERA_AVALON_PIO_DATA(LCD_RW_ADDRESS , 0); // 写入 // 数据 // 写入 // 使能

IOWR_ALTERA_AVALON_PIO_DATA(LCD_EN_ADDRESS , 1); // 使能 IOWR_ALTERA_AVALON_PIO_DATA(LCD_EN_ADDRESS , 0); // usleep(2000);//2ms /*延时*/ }

四、 系统顶层设计方案
1. 输入输出 1)输入输出管脚定义 信号名 iCLK_50 iCLRN oVGA_R oVGA_G oVGA_B oVGA_SYNC_N oVGA_BLANK_N oVGA_CLOCK oVGA_HS oVGA_VS 输 入 / 输 出 说明 /Inout 输入 1 位 输入 1 位 输出 10 位 输出 10 位 输出 10 位 输出 1 位 输出 1 位 输出 1 位 输出 1 位 输出 1 位 FPGA 系统时钟 50MHZ 保证整个系统复位 vga 数据输出 R 通道 10bit vga 数据输出 G 通道 10bit vga 数据输出 B 通道 10bit 低电频控制信号 控制 ADV7123 模拟信号 vga 输出时钟 25MHZ 行同步信号 场同步信号

2)输入输出时序图 vag 输入时钟 50mhz, 分频产生 25mhz,作为 vga 输出时钟, PLL 倍频, 200mhz 作为 cpu 时钟,UART 接收来自串口数据。软件读取数据,处理后,输出 数据。

2. 软件功能定义; 1)软件功能说明 获取发送数据。中断控制等 2)软件模块划分结构:画出模块图,说明每个模块的功能

3)软件测试用例说明 1:编写最简单的 huffman 树,huffmancode,compress code。 2:显示软件统计字符及频度与最小模型是否一样。 3:显示软件生成的 huffmantab 与最小模型 huffmantab 是否一样。 4: 显示软件递归生成的 huffmantab code 与最小模型 huffmantab code 是否一样。 5 显示软件递归生成 compresse code 与最小模型 compress code 是否

一样。 3. 硬件功能定义; 1)硬件功能说明 数据传输的收发接口,存储数据,VGA 显示器接口 2)硬件顶层模块划分 画出硬件模块的顶层设计结构,简单说明每个模块的功能。 3)硬件的测试用例说明

五、 硬件模块详细设计 1. VGA 接口模块详细设计
1). 每个子模块的功能 一,vga_640x480 模块,进行计时,来控制显示 二, vga_stripes 模块 这样每隔 16 行颜色交替为红色和绿色 (且在 vidon=1 时显示) 三,clkdiv 模块:进行时钟分频,得到该实验需要的 25MHZ 的时钟; 四,vga_stripes_top 模块:为主调用函数 五,test_vga 模块:激励模块

2). 每个子模块的输入输出与时序图
vga_stripes_top red

mclk

mclk clkdiv

Clk25 vga_stripes

green

Clk25 vga_640x480

Vidon hc vc

3). 子模块的进一步划分 4). 每个子模块的测试用例 test_vga `timescale 1ns/1ns module test_vga; reg mclk=0; reg [3:0]btn=0; vga_stripes_top sc(mclk,btn,hsync,vsync,red,green, blue); initial $monitor($time,"hsync = %d vsync = %d red = %d green = %d blue = %d", hsync,vsync,red,green, blue); initial begin mclk=0; #10 mclk=~mclk; end endmodule

5). 每个子模块的代码

2. 子模块 2 详细设计 .....

六、 软件子模块详细设计 1. 哈弗曼解压缩模块设计
1)子程序功能定义 将接收到的压缩数据进行解压缩 2)子程序输入输出说明 输入为 abc_code.txt-------编码文件; 输出为 abc_dcode.txt------译码文件。

3)子程序测试用例 4)子程序源代码

#include <stdio.h> #include <string.h> #define MaxNo 256 #define NULL 0

typedef struct { unsigned char symbol; int sweight; }syml_weit; syml_weit *sw; //存放符号及其权值

typedef struct { int weit; int lchd; int rchd; int part;

}hufmtree; hufmtree *htree; //存放 Huffman 树

int leafnode,totalnode; //叶子节点个数 和 整棵树的所有节点

unsigned char *DataBuf;

//存放文本文件数据的内存空间

unsigned char *CodeBook; //存放码本 unsigned char *CodeBuf; //存放编好的码 unsigned char *DCodeBuf; int CodeBookLen; int CodeLen; int DCodeLen; //码本长度 //码长度

void CountWeight(unsigned char *DataBuf,int FileLen); void BuildTree(); void HufmCode(unsigned char *DataBuf,int FileLen); void HufmDCode(unsigned char *CDataBuf,int CDataLen);

void main() { FILE *fp1,*fp2,*fp3,*fp4; char filepath[]="abc.txt"; int FileLen; // 读入的文件长度 //文件读取指针

DataBuf = new unsigned char[1024*1024];

printf("=====Huffman Code and Decode by LiYingle@NDSC==== \n\n");

if ((fp1=fopen(filepath,"rb"))==NULL) //读入文本文件 { printf("abc open error!");

} FileLen = fread(DataBuf,1,1024*1024,fp1);

CountWeight(DataBuf,FileLen); BuildTree(); HufmCode(DataBuf,FileLen); HufmDCode(CodeBuf,CodeLen);

//计算权值 // 建树 //编码 //译码

///// 输出码本文件和压缩率 if ((fp2=fopen("codebook.txt","w"))==NULL) { printf("abc_codebook open error!"); } fprintf(fp2,"ASCII WEIGHT for (int i=0;i<leafnode;i++) { fprintf(fp2,"0x%02x(%8.4f%%): ",*(CodeBook+i*(leafnode+1)), CODE\n");

100.0*sw[i].sweight/htree[totalnode-1].weit); for (int j=0;j<*(CodeBook+i*(leafnode+1)+1);j++) { fprintf(fp2,"%d",*(CodeBook+i*(leafnode+1)+2+j)); } fprintf(fp2,"\n"); } fprintf(fp2,"\n 压缩率:%.5f%%",100.0*CodeLen/8/FileLen);

///// 输出编码文件 if ((fp3=fopen("abc_code.txt","w"))==NULL) { printf("abc_code open error!");

} fwrite(CodeBuf,1,CodeLen,fp3);

///// 输出译码文件 if ((fp4=fopen("abc_dcode.txt","wb"))==NULL) { printf("abc_dcode open error!"); } fwrite(DCodeBuf,1,DCodeLen,fp4);

fclose(fp1); fclose(fp2); fclose(fp3); fclose(fp4);

delete[] DataBuf; delete[] CodeBook; delete[] CodeBuf; delete[] DCodeBuf; }

void CountWeight(unsigned char *DataBuf,int FileLen) {

int i=0,sum=0; int counter[MaxNo]={0x0};

for (i=0;i<FileLen;i++)//计算权值 { counter[DataBuf[i]]++;

}

for (i=0;i<MaxNo;i++) //计算叶子节点个数 { if (counter[i]) { leafnode++; } }

totalnode=(leafnode-1)+leafnode;//满树情况下的节点个数 sw = new syml_weit[leafnode]; //存放码字和权值

htree = new hufmtree[totalnode];//存放 huffman 树 int j=0; for (i=0;i<MaxNo;i++) { if (counter[i]) { sw[j].sweight = counter[i]; sw[j].symbol = i; htree[j].weit=counter[i]; htree[j].lchd = 0; htree[j].rchd = 0; htree[j++].part = 0; } } }

void BuildTree() {

int i=0; int j=leafnode;//非叶子节点的开始 int w1,w2;//两个最小的权值 int p1=-1,p2=-1;

for (int leaf=0;leaf<leafnode-1;leaf++) { /////////////////////////找权值最小的两个节点/////// for (i=0;i<totalnode;i++) { if(htree[i].part==0) { if (p1==-1) { p1 = i; w1 = htree[i].weit; } else if (p2==-1) { if (htree[i].weit>=w1) { p2 = i; w2 = htree[i].weit; } else { p2 = p1; w2 = w1; p1 = i;

w1 = htree[i].weit; } break; } } }

for (i=0;i<totalnode;i++) { if (htree[i].part==0 && i!=p1 && i!=p2) { if (htree[i].weit<w2) { if (htree[i].weit<w1) { w2 = w1; p2 = p1; w1 = htree[i].weit; p1 = i; } else { w2 = htree[i].weit; p2 = i; } } } } ///////////////////////////////////////////////////

//设置父节点 htree[j].weit = w1+w2; htree[j].lchd = p1; htree[j].rchd = p2; htree[j].part = 0; htree[p1].part = j; htree[p2].part = j; p1=-1; p2=-1; j++; } }

void HufmCode(unsigned char *DataBuf,int FileLen) { CodeBookLen = leafnode*(leafnode+1); CodeBook = new unsigned char[CodeBookLen];//存放编好的码字 unsigned char *codetemp = new unsigned char[leafnode];// 临时存放编好 的码字 int p; int CodLen;

for (int i=0;i<leafnode;i++) { CodLen = 0; *(CodeBook+i*(leafnode+1)) = sw[i].symbol; p=i; while (htree[p].part) {

if (p == htree[htree[p].part].lchd)//p 是左孩子 { codetemp[CodLen] = 0x0; } else//P 是右孩子 { codetemp[CodLen] = 0x1; } CodLen++; p = htree[p].part; } *(CodeBook+i*(leafnode+1)+1) = CodLen; for (int j=0;j<CodLen;j++) { *(CodeBook+i*(leafnode+1)+1+CodLen-j)=*(codetemp+j); } }

CodeBuf = new unsigned char [FileLen*(leafnode-1)]; for (int ii=0;ii<FileLen;ii++) { for (int jj=0;jj<leafnode;jj++) { if (*(DataBuf+ii)==*(CodeBook+jj*(leafnode+1))) { for (int kk=0;kk<*(CodeBook+jj*(leafnode+1)+1);kk++) { *(CodeBuf+CodeLen)= *(CodeBook+jj*(leafnode+1)+2+kk); CodeLen++; }

} } } }

void HufmDCode(unsigned char *CDataBuf,int CDataLen) { FILE *lp; int i=0; DCodeBuf = new unsigned char[1024*1024]; while (i<CDataLen) { int p=totalnode-1; while (p>=leafnode) { if (*(CDataBuf+i)==1) p=htree[p].rchd; else p=htree[p].lchd; i++; } *(DCodeBuf+DCodeLen) = sw[p].symbol; DCodeLen++; } }

2.UART 串口发射接收设计
1)子程序功能定义 该模块主要用于数据发送与接收,UART_RXD 作为接收端,UART_TXD 作为

发射端 1:初始化 UART,将 UART 设置为单字节触发模, UART->STATUS.BITS.RRDY = 0; UART->SIATUS.BITS.TRDY =0 ; UART->DIVISOR.WORD=(unsigned int)(ALT_CPU_FREQ/baudrate+0.5); 将接收寄存器和发射中断状态寄存器清零,避免初始值得影响。同时设置 发送速率,即波特率。 2: UART 接收模块, 当接到数据时, 中断寄存器置位, 进入中断服务程序, 读取接收 bufer 中的数据,并将 UART->STATUS.BITS.RRDY 清零, 3:UART 发射模块,将发送数据写入发送 bufer 中,当数据被发送成功 之后,发送数据的状态寄存器位 UART->SIATUS.BITS.TRDY 自动置 1,发送 下一个数据前,需要软件手动清零操作。

七、 系统测试结果
测试案例 1:验证 Huffman 算法压缩解压缩可行性 1:编写最简单的 huffman 树,huffmancode,compress code。 2:显示软件统计字符及频度与最小模型是否一样。 3:显示软件生成的 huffmantab 与最小模型 huffmantab 是否一样。 4:显示软件递归生成的 huffmantab code 与最小模型 huffmantab code 是 否一样。 5 显示软件递归生成 compresse code 与最小模型 compress code 是否一样。 测试文件 pic.txt. module vga( iCLK, iCLRN,

oVGA_R, oVGA_G, oVGA_B, oVGA_SYNC_N,

oVGA_BLANK_N, oVGA_CLOCK, oVGA_HS, oVGA_VS );

input iCLK; input iCLRN; output reg [9:0] oVGA_R = 10'b1111111111 , oVGA_G = 10'b1111111111, oVGA_B = 10'b1111111111; output oVGA_SYNC_N , oVGA_BLANK_N , oVGA_CLOCK; output oVGA_HS , oVGA_VS;

reg

vga_clk; V_count;

reg [9:0] H_count ,

wire video_out; parameter parameter parameter parameter parameter V_SYNC_CYC = V_SYNC_BACK = V_SYNC_ACT = V_SYNC_FRONT= V_SYNC_TOTAL= 2; 32; 480; 11; 525; // 2+32+480+11=525

parameter parameter parameter

H_SYNC_CYC = H_SYNC_BACK = H_SYNC_ACT =

96; 48; 640; //

parameter parameter

H_SYNC_FRONT= H_SYNC_TOTAL=

16; 800; // 96+48+640+16=800 row

parameter

X_START

=

H_SYNC_CYC+H_SYNC_BACK;

parameter // 2

Y_START + 32=34

=

V_SYNC_CYC+V_SYNC_BACK; 480

before

always @(posedge iCLK or negedge iCLRN) begin if(iCLRN == 0) vga_clk <= 1'b1; else vga_clk <= ~vga_clk; end

always @(posedge vga_clk or negedge iCLRN) begin if(iCLRN==0) H_count <= 10'd0; else if(H_count == H_SYNC_TOTAL) H_count <= 10'd0; else H_count = H_count + 10'd1;

end

always @(posedge vga_clk or negedge iCLRN)

begin if(iCLRN==0) V_count <= 10'd0; else if(H_count == H_SYNC_TOTAL) begin if(V_count == V_SYNC_TOTAL) begin V_count <= 10'd0; end else V_count = V_count + 10'd1; end end

assign video_out=((H_count>X_START)&&(H_count<X_START+H_SYNC_ACT))&&((V_ count>Y_START)&&(V_count<Y_START+V_SYNC_ACT));

assign oVGA_SYNC_N = 1'b0; assign oVGA_BLANK_N = oVGA_HS & oVGA_VS;

assign oVGA_CLOCK = vga_clk;

assign oVGA_HS = (H_count >= 10'd96); assign oVGA_VS = (V_count >= 10'd2);

always@(posedge iCLK) if( video_out) begin if(H_count> X_START &&H_count<

X_START+640&&V_count>Y_START&&V_count<Y_START+480) oVGA_R <= 1111111111 oVGA_G <=0; oVGA_B <=0; end ;

endmodule 测试结果 部分编码结果

编码中间生成部分结点

测试生成文件 pic.GCL

解码部分结果 生成 pic.txt

测试案例 2:验证 UART 传输的正确性 利用串口由文件中读取数据,nios 接收收据后将数据返回并显示,对比 发送接收过程是否有数据丢失。确保数据正常的传输。 软件功能定义 LCD 完成数据的显示。 LCD 的控制由 8bit 数据线, 1bit 的 RS 寄存器选

择端,1 数据寄存器,0 表示指令寄存器,EN 为 1bit 的使能端,值由 0 到 1 发生跳变,液晶执行指令,RW 为 1bit 的读写信号线,高电平执行读 的功能,低电平执行写的功能。lcd_on 为电源端,lcd_blon 为背光。 软件详细设计 1:LCD 写命令 void LCD_Write_Command(Boolean Command) { IOWR_ALTERA_AVALON_PIO_DATA(LCD_DATA_ADDRESS , Command); //写 数 IOWR_ALTERA_AVALON_PIO_DATA(LCD_RS_ADDRESS , 0); //指令 IOWR_ALTERA_AVALON_PIO_DATA(LCD_RW_ADDRESS IOWR_ALTERA_AVALON_PIO_DATA(LCD_EN_ADDRESS , , 0); 1); // // 写 入 使 能

IOWR_ALTERA_AVALON_PIO_DATA(LCD_EN_ADDRESS , 0); // usleep(2000);//2ms /*延时*/ } 2:LCD 写数据 void LCD_Write_data(Boolean Data) { IOWR_ALTERA_AVALON_PIO_DATA(LCD_DATA_ADDRESS , Data); //写数据 IOWR_ALTERA_AVALON_PIO_DATA(LCD_RS_ADDRESS , 1); IOWR_ALTERA_AVALON_PIO_DATA(LCD_RW_ADDRESS , 0); IOWR_ALTERA_AVALON_PIO_DATA(LCD_EN_ADDRESS , 1); /*延时 150ns*/ IOWR_ALTERA_AVALON_PIO_DATA(LCD_EN_ADDRESS , 0); // usleep(2000);//2ms /*延时*/ } 4:LCD 初始化 void LCD_Write_Command(Boolean Command) {IOWR_ALTERA_AVALON_PIO_DATA(LCD_DATA_ADDRESS , Command); // 往 数据 IOWR_ALTERA_AVALON_PIO_DATA(LCD_RS_ADDRESS , 0); //指令 // 数据 // 写入 // 使能

IOWR_ALTERA_AVALON_PIO_DATA(LCD_RW_ADDRESS , 0); // 写入 IOWR_ALTERA_AVALON_PIO_DATA(LCD_EN_ADDRESS , 1); // 使能 IOWR_ALTERA_AVALON_PIO_DATA(LCD_EN_ADDRESS , 0); // usleep(2000);//2ms /*延时*/ } 测试文件为 licence.txt 文件文件内容为 ALTERA PROGRAM LICENSE SUBSCRIPTION AGREEMENT

PLEASE REVIEW THE FOLLOWING TERMS AND CONDITIONS CAREFULLY BEFORE INSTALLING OR USING THE SOFTWARE PROVIDED TO YOU ON DVD, VIA A WEB-SITE, OR ON ANOTHER MEDIUM OR THROUGH ANOTHER DELIVERY MECHANISM. BY INSTALLING OR USING THIS SOFTWARE OR PAYING A SUBSCRIPTION FEE, YOU INDICATE YOUR ACCEPTANCE OF SUCH TERMS AND CONDITIONS, WHICH CONSTITUTE THE LICENSE AGREEMENT ("AGREEMENT") BETWEEN YOU AND ALTERA CORPORATION OR THE ALTERA CORPORATION SUBSIDIARY FROM WHICH YOU HAVE ACQUIRED THIS LICENSE (COLLECTIVELY "ALTERA"). HOWEVER, THIS SOFTWARE MAY CONTAIN PARTICULAR COMPONENTS, FILES OR PORTIONS WHICH ARE SUBJECT TO SEPARATE LICENSE AGREEMENTS WITH DIFFERENT TERMS AND CONDITIONS. IN EACH SUCH CASE, THE APPLICABLE TERMS AND CONDITIONS ARE SET FORTH IN A FILE (CALLED "LICENSE.TXT") IN A SEPARATELY MARKED SECTION, WHERE TERMS AND CONDITIONS SET FORTH EXCLUSIVELY GOVERN THE NAMED COMPONENTS. IN THE EVENT THAT YOU DO NOT AGREE WITH ANY OF THESE TERMS AND CONDITIONS, DO NOT DOWNLOAD, COPY, INSTALL OR USE THIS SOFTWARE; IF YOU HAVE RECEIVED A COPY ON COMPACT DISC OR ANOTHER MEDIUM, PLEASE PROMPTLY RETURN THE SOFTWARE UNUSED TO ALTERA.

IF YOU WISH TO PRINT OUT THIS PROGRAM LICENSE SUBSCRIPTION AGREEMENT, YOU SHOULD HIGHLIGHT THIS TEXT, RIGHT-CLICK, SELECT "COPY" THEN "PASTE" IT INTO A DOCUMENT IN YOUR WORD PROCESSING PROGRAM. 串口测试结果

文件传输功能正确

八、 开发环境
Quartusii 8.0 IDE Niosii Altera 公司 DE2-35 开发板

九、 人员分配
小组成员 郭从林 朱潮勇 程亭 杨欢 任务 Huffman 算法编解码实 现 VGA 接口实现, sdram 调 度 文件传输系统及接口实 现 LCD 测试 完成质量 基本完成 部分完成 基本完成 完成

十、 结束语
1)对技术报告进行总结;

本文主要研究 JPEG 静态图象压缩编码技术,并在 Nios 系统中完成了 图像压缩系 统。主要工作在于: (1)设计基于 SOPC 技术的 Huffman 编码解码系统 使用 FPGA 和一些比较通用的器件设计并实现了图像压缩系统,该压 缩系统在一块 FPGA 上实现了 vga 接口处理器。 (2)完成了图像压缩解码系统的编程 主要介绍了 Huffman 的解码原理和 Nios IDE 实现了该算法。 在软件设 计中配置完成了 Nios 操作系统,并完成了系统软件和一些外围硬件的驱 动。并且结合 Huffman 算法原理和 FPGA 的硬件平台和嵌入式编程环境, 较好地实现了 Huffman 算法的编码解码。 2)提出项目的改进; 希望在以后可以通过硬件实现 Huffman 算法 2)对开发过程出现的问题进行总结 特别是传输文件时的传输速度与解码的速度无法匹配,从而要调用 sdram。而在控制 sdram 时的时序调整有较大困难。

参考书 1.吕凤军.数字图像处理编程入门,清华大学出版社,1999, 287312. 2.林福宗.多媒体技术基础,清华大学出版社,2000, 178200.

BHASKARAN, V., KONSTANTINIDES, K. ((Image and Video Compression Standards Algorithms and Architectures 一 Second Edition)).Kluwer Academic Publishers, USA, 1999. 3.汪宇.JPEG 高速编码芯片的设计及其性能优化,西北工业大学硕士学位论文, 2006.2. 4.任爱锋,初秀琴等.基于 FPGA 的嵌入式系统设计.第一版.西安:西安电了科技大 学出版社,2004, 9 一 53 5.潘松,黄继业.EDA 技术实用教程.第一版.北京:科学出版社,2002,3254 6.任艳颖,土彬.IC 设计基础.西安电了科技大学出版社.2003.5:342.

7.吴继华,土诚.Altera FPGA/CPLD 设计(高级篇).人民邮电出版社.2005.7:1 }50.

VGA 模块代码 一,vga_640x480 module vga_640x480( input wire clk, input wire clr, output reg hsync, output reg vsync, output reg [9:0] hc, output reg [9:0] vc, output reg vidon ); //行像素点=800 parameter hpixels=10'b1100100000; //行数=521 parameter vlines=10'b1000001001; //行显示后延=144(128+16) parameter hbp=10'b0010010000; //行显示前沿=784(128+16+840) parameter hfp=10'b1100010000; //场显示后延=31(2+29) parameter vbp=10'b0000011111; //场显示前沿=511(2+29+480) parameter vfp=10'b0111111111; reg vsenable; //行同步信号计数器 always@(posedge clk or posedge clr) begin if(clr==1) hc<=0; else

begin if(hc==hpixels-1) begin hc<=0;//计数器复位 vsenable<=1;

end else begin hc<=hc+1; vsenable<=0; end end end //产生 hsync 脉冲 //当 hc 为 0--127 时,行同步脉冲为低电平 always@(*) begin if(hc<96) hsync=0; else hsync=1; end //场同步信号计数器 always@(posedge clk or posedge clr) begin if(clr==1) vc<=0; else if(vsenable==1)

begin if(vc==vlines-1) vc<=0; else vc<=vc+1;//场计数器+1 end end //产生 vsync 脉冲 //当 hc 为 0 或 1 时,场同步脉冲为低电平 always@(*) begin if(vc<2) vsync=0; else vsync=1;

end always@(*) begin if((hc<hfp)&&(hc>hbp)&&(vc<vfp)&&(vc>vbp)) vidon=1; else vidon=0; end endmodule

二,vga_stripes module vga_stripes( input wire vidon, input wire [9:0] hc,vc,

output reg [2:0] red,green, output reg [1:0] blue ); //输出 16 行宽的红绿条纹 always@(*) begin red=0; green=0; blue=0; if(vidon==1) begin red={vc[4],vc[4],vc[4]}; green=~{vc[4],vc[4],vc[4]}; end end endmodule

三,clkdiv module clkdiv( input wire mclk, input wire clr, output wire clk25 ); reg [24:0] q; always@(posedge mclk or posedge clr) begin if(clr==1) q<=0; else q<=q+1;

end

assign clk25=q[0];

endmodule

四,vga_stripes_top module vga_stripes_top( input wire mclk, input wire [3:0] btn, output wire hsync,vsync, output wire [2:0] red,green, output wire [1:0] blue );

wire clk25,clr,vidon; wire [9:0] hc,vc; assign clk=btn[3]; clkdiv U1(.mclk(mclk), .clr(clr), .clk25(clk25) ); vga_640x480 U2(.clk(clk25), .clr(clr), .hsync(hsync), .vsync(vsync), .hc(hc), .vc(vc), .vidon(vidon) );

vga_stripes U3(.vidon(vidon), .hc(hc), .vc(vc), .red(red), .green(green), .blue(blue) ); endmodule

inc.h #ifndef INC_H_ #define INC_H_ #include "system.h" #include "stdlib.h" #include "stdio.h" #include <unistd.h> #include <io.h> typedef struct { //接收数据寄存器

union{ struct{ volatile unsigned long int RECEIVE_DATA volatile unsigned long int NC }BITS; volatile unsigned long int WORD; :8; :24;

}RXDATA;

//发送寄存器

union{ struct{ volatile unsigned long int TRANSMIT_DATA volatile unsigned long int NC }BITS; volatile unsigned long int WORD; :8; :24;

}TXDATA;

//状态寄存器

union{ struct{ volatile unsigned long int volatile unsigned long int volatile unsigned long int PE FE BRK :1; :1; :1; :1; :1; :1; :1; :1; :1; :1; :1; :1; :1;

volatile unsigned long int ROE volatile unsigned long int TOE volatile unsigned long int TMT volatile unsigned long int TRDY volatile unsigned long int RRDY volatile unsigned long int E volatile unsigned long int NC volatile unsigned long int DCTS volatile unsigned long int CTS volatile unsigned long int EOP

volatile unsigned long int NC1 }BITS; volatile unsigned long int }STATUS;

:19;

WORD;

//控制寄存器 union{ struct{ volatile unsigned long int volatile unsigned long int volatile unsigned long int IPE IFE IBRK :1; :1; :1; :1; :1; :1; :1; :1; :1; :1; :1; :1; :1; :1; :19;

volatile unsigned long int IROE volatile unsigned long int ITOE volatile unsigned long int ITMT volatile unsigned long int ITRDY volatile unsigned long int IRRDY volatile unsigned long int IE //volatile unsigned long int NC volatile unsigned long int TBRK

volatile unsigned long int IDCTS volatile unsigned long int RTS volatile unsigned long int IEOP volatile unsigned long int NC }BITS; volatile unsigned long int }CONTROL; //波特率寄存器 union{ struct{ WORD;

volatile unsigned long int BAUD_RATE_DIVISOR :16; volatile unsigned long int NC }BITS; volatile unsigned long int }DIVISOR; }UART_STR; WORD; :16;

#define

UART

((UART_STR *) UART_BASE)

#endif /*INC_H_*/

Lcd.h #ifndef LCD_H_ #define LCD_H_

#include "system.h" #include <sys/alt_irq.h> #include "alt_types.h" #include <io.h>

#include "altera_avalon_pio_regs.h" #include "alt_types.h" #include <unistd.h> #include<string.h>

typedef unsigned char Boolean;

#define #define #define #define

LCD_DATA_ADDRESS LCD_RS_ADDRESS LCD_RW_ADDRESS LCD_EN_ADDRESS

LCD_DATA_BASE LCD_RS_BASE LCD_RW_BASE LCD_EN_BASE

/************************************************************** ********* * * rs 寄存器选择端 1 数据寄存器 0 指令寄存器 * en 使能端 由高到低的调变 液晶执行指令 * rw 读写信号线 高写 低读 * *************************************************************** ********/

void LCD_Write_Command(Boolean Command); //写命令 void LCD_Write_data(Boolean Data); void Init_LCD(void);

void Init_LCD(void) {

LCD_Write_Command(0X38); usleep(5000);//5ms //延时 5ms

//设置显示模式 16*2 显示 5*7 点阵

LCD_Write_Command(0x0F); //开光标 光标闪烁 usleep(5000);//5ms //延时 5ms LCD_Write_Command(0x01); usleep(5000);//5ms //延时 5ms LCD_Write_Command(0x06); usleep(5000);//5ms LCD_Write_Command(0X80); //首行 显示 usleep(5000);//5ms //延时 5ms //设置输入方式 //清除屏幕信息

}

void LCD_Write_data(Boolean Data) { IOWR_ALTERA_AVALON_PIO_DATA(LCD_DATA_ADDRESS , Data); //往数 据 IOWR_ALTERA_AVALON_PIO_DATA(LCD_RS_ADDRESS , 1); //shu ju

IOWR_ALTERA_AVALON_PIO_DATA(LCD_RW_ADDRESS , 0); // 写入 IOWR_ALTERA_AVALON_PIO_DATA(LCD_EN_ADDRESS , 1); // 使能 /*延时 150ns*/

IOWR_ALTERA_AVALON_PIO_DATA(LCD_EN_ADDRESS , 0); // usleep(2000);//2ms /*延时*/

}

void LCD_Write_Command(Boolean Command) { IOWR_ALTERA_AVALON_PIO_DATA(LCD_DATA_ADDRESS , Command); //往数据 IOWR_ALTERA_AVALON_PIO_DATA(LCD_RS_ADDRESS , 0); //指令 IOWR_ALTERA_AVALON_PIO_DATA(LCD_RW_ADDRESS , 0); // 写入 IOWR_ALTERA_AVALON_PIO_DATA(LCD_EN_ADDRESS , 1); // 使能 IOWR_ALTERA_AVALON_PIO_DATA(LCD_EN_ADDRESS , 0); // usleep(2000);//2ms /*延时*/

}

#endif /*LCD_H_*/

Uart.h #ifndef UART_H_ #define UART_H_

#include"lcd.h" #define UART ((UART_STR *) UART_BASE)

typedef struct {

HEAD

Boolean

Flag[4];

}HEAD;

#include "sys/alt_irq.h" #include "system.h" #include "stdlib.h"

#include "stdio.h" #include <unistd.h> #include <io.h>

#include"inc.h"

unsigned char receive_temp;//接收到的临时数据 unsigned char buffer[6]="ERROR"; #define BUFFER_SIZE 200 /*---------------------------------------------------------------* Define *---------------------------------------------------------------*/

typedef struct{ unsigned char mode_flag; //xmodem 1;uart 0; unsigned int receive_flag; unsigned int receive_count; unsigned char receive_buffer[BUFFER_SIZE]; int (* send_byte)(unsigned char data); void (* send_string)(unsigned int len, unsigned char *str); int (* init)(void); unsigned int (* baudrate)(unsigned int baudrate); }UART_T;

extern

UART_T

uart;

/*

*

====================================================

*

Filename: uart.c * Description: RS232 device driver * Version: * Created: * Revision: none * Compiler: Nios II IDE

* Author: AVIC * Company: * =================================================== */ /*-------------------------------------------------------------* Include *-------------------------------------------------------------*/

/*-------------------------------------------------------------* Function Prototype *--------------------------------------------------------------*/ static int uart_send_byte(unsigned char data); static void uart_send_string(unsigned int len, unsigned char *str); static int uart_init(void); static void uart_ISR(void); static int set_baudrate(unsigned int baudrate); //初始 uart 结构体,注意结构体初始化方式 UART_T uart={ .mode_flag=0, .receive_flag=0, .receive_count=0, .send_byte=uart_send_byte, .send_string=uart_send_string, .init=uart_init, .baudrate=set_baudrate }; /* * === FUNCTION ======================================== * Name: uart_send_byte * Description: 发送一个字节数据 * Description: 发送一个字节数据 */

static int uart_send_byte(unsigned char data) { //将发送的数据放到发送数据缓冲区内,等待数据寄存器 TRDY 置 1,当 TRDY 置 1,说明 //接收完毕 UART->TXDATA.BITS.TRANSMIT_DATA = data; while(!UART->STATUS.BITS.TRDY); UART->STATUS.BITS.TRDY = 0; return 0; } /* * === FUNCTION ======================================== * Name: uart_send_string * Description: 发送字符串数据 * ===================================================== */ static void uart_send_string(unsigned int len, unsigned char *str) { while(len--) { uart_send_byte(*str++); } } /* * === FUNCTION ======================================== * Name: uart_init * Description: 初始化程序 * ===================================================== */ static int uart_init(void) { //设置波特率为 115200 set_baudrate(9600);

// 对控制寄存器的 irrdy 进行置 1 ,表示当接收准备好后,中断使能 UART->CONTROL.BITS.IRRDY=1; //清除状态寄存器,这就是处理整个寄存器的方式 UART->STATUS.WORD=0; UART->STATUS.BITS.RRDY = 0; UART->STATUS.BITS.TRDY = 0 ; //注册 uart 中断,ISR 为 uart_ISR alt_irq_register(UART_IRQ, NULL, uart_ISR); return 0; } /* * === FUNCTION ======================================== * Name: uart_ISR * Description: 串口中断 * ===================================================== */ static void uart_ISR(void) { //static int count;

//等待状态寄存器的接收数据状态位 rrdy,当 rrdy 位为 1 时,说明新接收 的值传输到了接 //收数据寄存器 while(!(UART->STATUS.BITS.RRDY));

//reveive_buffer 为我们通过栈的方式在内存中开设的内存块, 将接受数据 寄存器中的 //数据放到这个内存块中

receive_temp=UART->RXDATA.BITS.RECEIVE_DATA;

uart_send_byte( receive_temp);

UART->STATUS.BITS.RRDY = 0;

} /* * === FUNCTION ======================================== * Name: set_baudrate * Description: 设置波特率 * ===================================================== */ static int set_baudrate(unsigned int baudrate) { //设置波特率有一个公式的,波特率=时钟频率/(divisor+1),转换以后就是 下面了。 UART->DIVISOR.WORD=(unsigned int)(ALT_CPU_FREQ/baudrate+0.5); return 0; }

#endif /*UART_H_*/

Main.c

#include"lcd.h" #include<malloc.h> #include"uart.h"

int {

main(void)

Init_LCD(); uart_init();

// lcd // uart

chu shi hua chu shi hua

char

* res = NULL;

LCD_Write_data('3');

*((unsigned char *)LED_BASE) = 0x55;

res = (char *)malloc(sizeof(int)*100); free(res);

while(1);

return 0;

}


相关文章:
基于FFPGA的图像压缩传输与解码系统
基于FFPGA的图像压缩传输与解码系统_信息与通信_工程科技_专业资料。基于FFPGA的图像压缩《sopc》课程报告之五 《基于 FFPGA 的图像压缩传输与解码系统》技术报告 ...
基于FPGA的图像压缩与解码
基于FPGA 的图像压缩传输与解码 硬件设计部分 一、硬件完成的功能定义 1.使用 ...FPGA 系统时钟 50MHZ 保证整个系统复位 vga 数据输出 R 通道 10bit vga 数据...
基于FPGA的图像处理现状分析
基于FPGA的图像处理现状分析_信息与通信_工程科技_...分编码方法, 在降低压缩比的同时提高了影像解码的...[17] Y.Q. Dong and S.F. Xu, “A New ...
基于DCT变换的图像压缩编码
处理和传输这 些图像数据,必须对其进行压缩,因此有必要...解码过程 第3页 《信息处理系统综合训练》报告 3....二维离散余弦变换可以写成矩阵式 (F(u,v))=(A)...
基于ADV212的雷达图像压缩传输系统
设计了一种新的基于 FPGA ADV212 的雷达图像压缩与传输系统,实现对 4 096...ADV212[5-7] 是一款单芯片 JPEG2000 编解码器, 针对视频高带宽图像压缩...
视频图像传输系统中接口电路的设计
视频图像传输系统中接口电路的设计 摘要: 视频传输系统解码器输出数据到计算机进行数据处理显示,为了 保证解码器输出数据传输带宽和传输质量, 文章采用 FPGA 作为...
基于FPGA的JPEG算法设计报告
基于FPGA的JPEG解码算法... 62页 1下载券 基于FPGA的JPEG图像压缩... 92页 ...F​G​P​A​ ​ ​J​P​E​G项目参与人员: 石滔 通信 ...
基于FPGA的视频图像处理系统
基于FPGA的视频图像处理系统_信息与通信_工程科技_...实时传送出去,必须采 用图像处理中的编码压缩技术来...公司的一种高集成度视频解码芯片1191,采用 CMOS ...
基于DCT变换的图像压缩及matlab仿真
无损压缩(冗余度压缩、可逆压缩) :是一种在解码时...三.编码压缩系统介绍 (1)编码压缩系统 基于 DCT ...表达图像,用f(x,y)表示8×8的图像块象素值,F(...
图像压缩
图像压缩_信息与通信_工程科技_专业资料。基于行程编码...图像编码压缩的目的是节省图像存储空间,减少传输信道...接收者通过对量化的 DCT 系数进行解码,并对每个图像...
更多相关标签:
fpga图像压缩 | opencv 图像压缩传输 | fpga 音频解码 | fpga解码 | fpga 音频解码 ip | fpga 视频解码 | h264解码器 fpga | fpga高速串行传输 |