硬件准备
ADSP-EDU-BF533:BF533开发板
AD-HP530ICE:ADI DSP仿真器
软件准备
Visual DSP++软件
硬件链接
代码实现功能
代码实现了将 SD 卡根目录下的所有文件进行文件列表,然后将 480*272 尺寸的 JPEG 文件进行 JPEG 解码,将解码后的数据显示到液晶屏上,延时后切换下一张图片,并且循环显示所有图片,实现电子相册功能。
代码使用说明
代码调用了一个 JPG 解码库,该解码库可以解 480*272 尺寸的 JPG 文件,将 JPG 文件解码为同尺寸的 RGB888 格式的数据文件,再将数据由 RGB888 转为 RGB565 送到屏上显示。
JPG 解码函数:
jpg_scaling_rgb24(DisplayBuffer,480,272,windowsBuffer_t);
将 windowsBuffer_t 内存中的 JPEG 数据解码后存入 DisplayBuffer 中,解码图像的尺寸为 480*272.
代码实验步骤
- 将 480*272 尺寸的“.jpg”以短文件名命名后存放在 SD 卡根目录下,将卡插入板卡SD卡接口
- 编译并运行代码
- 观察液晶屏上的图片显示
在液晶屏上看到循环显示的 JPEG 图片。
程序源码
cpu.c
#include <cdefBF533.h>
void Set_PLL(int pmsel,int pssel)
{
int new_PLL_CTL;
*pPLL_DIV = pssel;
asm(“ssync;”);
new_PLL_CTL = (pmsel & 0x3f) << 9;
*pSIC_IWR |= 0xffffffff;
if (new_PLL_CTL != *pPLL_CTL)
{
*pPLL_CTL = new_PLL_CTL;
asm(“ssync;”);
asm(“idle;”);
}
}
void Init_SDRAM(void)
{
*pEBIU_SDRRC = 0x00000817;
*pEBIU_SDBCTL = 0x00000013;
*pEBIU_SDGCTL = 0x0091998d;
ssync();
}
void Init_EBIU(void)
{
*pEBIU_AMBCTL0 = 0x7bb07bb0;
*pEBIU_AMBCTL1 = 0x7bb07bb0;
*pEBIU_AMGCTL = 0x000f;
}
void Init_Timers0(int dat)
{
*pTIMER0_CONFIG = 0x0019;
*pTIMER0_WIDTH = dat;
*pTIMER0_PERIOD = 2000;
}
void Enable_Timers0(void)
{
*pTIMER_ENABLE|= 0x0001;
asm(“ssync;”);
}
void Disable_Timers0(void)
{
*pTIMER_DISABLE |= 0x0001;
}
delay(int tem)
{
int i;
for(i=0;i<tem;i++);
}
diskio.c
#include “diskio.h”
#include <cdefBF533.h>
void MMC_HardwareInitial(void)
{
*pSPI_FLG = FLS2;
*pSPI_BAUD = 4;
*pSPI_CTL = 0x0000;
*pSPI_CTL = 0x0001 | MSTR ;
*pSPI_CTL = (*pSPI_CTL | SPE);
}
DSTATUS disk_initialize ()
{
MMC_HardwareInitial();
MMC_Init();
return 0;
}
DSTATUS disk_shutdown ()
{
return 0;
}
DSTATUS disk_status ()
{
return 0;
}
DRESULT disk_read (BYTE *buff, DWORD sect, BYTE cnt)//cnt = sector num
{
while(cnt--){
MMC_read_sector(sect,buff);
sect += 1;
buff += 512;
}
return 0;
}
#ifndef _READONLY
DRESULT disk_write (const BYTE* buff, DWORD sect, BYTE cnt)
{
while(cnt–){
MMC_Write_sector(sect,buff);
sect += 1;
buff += 512;
}
return 0;
}
#endif
main.c
#include <cdefbf53x.h>
#include “integer.h”
#include “ff.h”
section (“sdram0_bank2”)unsigned char windowsBuffer_t[234240];
section (“sdram0_bank2”)unsigned char TempBuffer[234240];
section (“sdram0_bank2”)unsigned char DisplayBuffer[272][1440] ;
extern unsigned char DisplayBuffer_565[272][1440] ;
unsigned char dir_name[50][12];
unsigned char file_name[100][12];
unsigned int file_count[1];
unsigned int dir_count[1];
unsigned int jpgfile_flag = 0;
int main()
{
FIL fp;
int i,j;
FRESULT retval = 0;
WORD lenth;
Set_PLL(16,4);
Init_EBIU();
SD_Enable();
f_mountdrv();
LCDBK_Disable();
InitDMA();
InitPPI();
InitTimer();
PPI_TMR_DMA_Enable();
LCD_Enable();
Init_Timers0(1999);//1~1999 控制背光亮度
Enable_Timers0();
LCDBK_Enable();
scan_files("/",file_name,file_count,dir_name,dir_count);
while(1)
{
for(i=0;i<file_count[0];i++)
{
for(j=0;j<12;j++)
{
if(file_name[i][j] == 0x2E)
{
if(file_name[i][j+1] == 0x4A || file_name[i][j+1] == 0x6A)
{
if(file_name[i][j+2] == 0x50 || file_name[i][j+2] == 0x70)
{
if(file_name[i][j+3] == 0x47 || file_name[i][j+3] == 0x67)
{
jpgfile_flag = 1;
break;
}
}
}
}
}
if(jpgfile_flag == 1)
{
jpgfile_flag = 0;
retval = f_open(&fp, file_name[i], FA_OPEN_ALWAYS | FA_READ);
if (retval != 0){
printf("can't open:%s\n",file_name[i]);
continue;
}
f_read(&fp, windowsBuffer_t, 0x200000, &lenth);
f_close(&fp);
jpg_scaling_rgb24(DisplayBuffer,480,272,windowsBuffer_t);
RGB888_RGB565(DisplayBuffer,391680,DisplayBuffer_565);
delay(100000);
}
}
}
}
lcd.c
#include <cdefBF533.h>
section (“sdram0_bank2”)unsigned char DisplayBuffer_565[272][1440] ;
void InitDMA(void)
{
int addr;
addr = &DisplayBuffer_565;
addr -= 1920;
*pDMA0_START_ADDR = addr;
*pDMA0_X_COUNT = 480;
*pDMA0_X_MODIFY = 2;
*pDMA0_Y_COUNT = 286;
*pDMA0_Y_MODIFY = 2;
*pDMA0_CONFIG = 0x1034;
}
void InitPPI(void)
{
*pPPI_CONTROL = 0x781e;
*pPPI_DELAY = 0;
*pPPI_COUNT = 479;
*pPPI_FRAME = 286;
}
void InitTimer(void)
{
*pTIMER1_PERIOD = 525;
*pTIMER1_WIDTH = 41;
*pTIMER1_CONFIG = 0x00a9;
*pTIMER2_PERIOD = 150150;
*pTIMER2_WIDTH = 5250;
*pTIMER2_CONFIG = 0x00a9;
}
void PPI_TMR_DMA_Enable(void)
{
*pDMA0_CONFIG |= 0x1;
asm(“ssync;”);
InitTimer();
*pPPI_CONTROL |= 0x1;
asm(“ssync;”);
*pTIMER_ENABLE|= 0x0006;
asm(“ssync;”);
}
void PPI_TMR_DMAR_Disable(void)
{
*pDMA0_CONFIG &= (~0x1);
*pPPI_CONTROL &= (~0x1);
}
void RGB888_RGB565(unsigned char *src, int src_len, unsigned char *dst)
{
int i = 0;
int j = 0;
if (src_len % 3 != 0)
{
return;
}
for (i = 0; i < src_len; i += 3)
{
dst[j+1] = src[i+2] &0xf8; //B
dst[j+1] |= ((src[i+1]>>5) & 0x07); //GH
dst[j] = ((src[i+1]<<3) & 0xe0); //GL
dst[j] |= ((src[i]>>3) &0x1f); //R
j += 2;
}
}
zoom.c
#include “bmp.h”
#include “data_type.h”
#include “zoom.h”
#include <string.h>
/***************************************************************************
//macro definition
**************************************************************************/
#define WIDTHBYTES(i) ((i+31)/324)
/***************************************************************************
TYPE DEFINITIONS
***************************************************************************/
struct bmp_info_
{
/0x424D,“BM”/
UINT16 bfType;
UINT16 bfSize;
UINT32 biWidth;
UINT32 biHeight;
UINT16 biBitCount;
};
typedef struct bmp_info_ bmp_info;
/***************************************************************************
GLOBAL
***************************************************************************/
static bmp_info bf;
static avctx_t bmp_avctx;
/***************************************************************************
PROTOTYPES
***************************************************************************/
int gain_bmp_info(UINT8 * buf);
int bmp_zoom(unsigned char * desc_buf,int desc_w,int desc_h,unsigned char * src_buf);
/***************************************************************************
jpg&jpeg file to rgb data
***************************************************************************/
int jpg_scaling_rgb24(UINT8 * output,int new_w,int new_h,UINT8 * input)
{
UINT32 w=480;
UINT32 h=272;
int color_components=1;
int file_len=MAXBUFFSIZE;
/*fill a jpg file data to inbuf and get len*/
JpegFileToRGB(output,&w,&h,&color_components,input,file_len);
return 0;
}
/***************************************************************************
bmp file to rgb data
***************************************************************************/
int bmp_scaling_rgb(UINT8 * output,int new_w,int new_h,UINT8 * input)
{
int data_size;
if(gain_bmp_info(input))
{
return -1;
}
bmp_decode_frame(&bmp_avctx, output, &data_size, input, MAXBUFFSIZE);
bmp_zoom(input,new_w,new_h,output);
gbrtorgb24(output,input,new_w,new_h);
return 0;
}
int gain_bmp_info(UINT8 * buf)
{
memcpy(&bf.bfSize,(buf),2);
if(bf.bfSize!=0x4d42)
{
printf(“This is not a bmp file!\n”);
return -1;
}
memcpy(&bf.bfSize,(buf+2),4);
if(bf.bfSize>MAXBUFFSIZE)
{
printf(“Can’t process bmp file more than %d bytes!\n”,MAXBUFFSIZE);
return -1;
}
memcpy(&bf.biWidth,(buf+0x12),4);
memcpy(&bf.biHeight,(buf+0x16),4);
memcpy(&bf.biBitCount,(buf+0x1c),2);
if(bf.biBitCount!=1 && bf.biBitCount!=2 && bf.biBitCount!=4 && bf.biBitCount!=8 && bf.biBitCount!=16 && bf.biBitCount!=24 && bf.biBitCount!=32)
{
printf(“Can’t process bmp of this color depth!\n”);
return -1;
}
return 0;
}
int bmp_zoom(unsigned char * desc_buf,int desc_w,int desc_h,unsigned char * src_buf)
{
UINT8 * lpPtr;
UINT8 * lpTempPtr;
int x0,y0,x1,y1;
float x_ratio,y_ratio;
int SrcBufSize,DstBufSize,LineBytes,DstLineBytes;
int i=0;
if(bf.biWidth==desc_w && bf.biHeight==desc_h)
{
memcpy(desc_buf,src_buf,bf.biWidth*bf.biHeight*(bf.biBitCount/8));
}
else
{
/*x1,y1表示新图像素坐标,与x0,y0在旧图中的坐标对应*/
/*num1=old/new=1/zoomRatio*/
x_ratio=(float) bf.biWidth/desc_w;
y_ratio=(float) bf.biHeight/desc_h;
//规范新图每行的宽度,4字节对齐
DstLineBytes=(UINT32)WIDTHBYTES(desc_w*bf.biBitCount);
LineBytes=(UINT32)WIDTHBYTES(bf.biWidth*bf.biBitCount);
SrcBufSize=LineBytes*bf.biHeight;
DstBufSize=DstLineBytes*desc_h;
for(y1=0;y1<desc_h;y1++)
{
for(x1=0;x1<desc_w;x1++)
{
x0= (UINT32)(x1*x_ratio);
y0= (UINT32)(y1*y_ratio);
if( (x0>=0) && (x0<bf.biWidth) && (y0>=0) && (y0<bf.biHeight))
{
/*lpPtr指向原图缓存*//*lpTempPtr指向新图缓存*/
/*SrcBufSize源图整个文件除去文件头信息的字节数*/
/*LineBytes每行字节数*/
lpPtr=(UINT8 *)src_buf+(SrcBufSize-LineBytes-y0*LineBytes)+(x0*bf.biBitCount/8);
lpTempPtr=(UINT8 *)desc_buf+(DstBufSize-DstLineBytes-y1*DstLineBytes)+(x1*bf.biBitCount/8);
for(i=0;i<bf.biBitCount;i++)
{
*lpTempPtr++=*lpPtr++;
}
}
}
}
}
return 0;
}
/***************************************************************************
bmp to rgb reference
*************************************************************************/
/-------------------------------------------------
gbrtorgb24 - 改变颜色排列顺序,翻转图像。
-------------------------------------------------/
/bmp_to_rgb将bmp的像素点阵转为rgb排列/
void gbrtorgb24(UINT8 * rgb_buf,UINT8 * bmp_buf,int width,int heigh)
{
int i,j;
int a,b;
for(i=0;i<heigh;i++)
{
for(j=0;j<width;j++)
{
a=bmp_buf[i*(width*3)+(j*3)];
b=bmp_buf[i*(width*3)+(j*3+2)];
bmp_buf[i*(width*3)+(j*3)]=b;
bmp_buf[i*(width*3)+(j*3+2)]=a;
}
}
for(i=0;i<heigh;i++)
{
for(j=0;j<(width*3);j++)
{
rgb_buf[i*(width*3)+j]=bmp_buf[(heigh-1-i)*(width*3)+j];
}
}
}
/-------------------------------------------------
reversal_pic - 翻转图像180度。
-------------------------------------------------/
void reversal_pic(UINT8 * rgb_buf,UINT8 * bmp_buf,int width,int heigh)
{
int i,j;
for(i=0;i<heigh;i++)
{
for(j=0;j<(width3);j++)
{
rgb_buf[i(width3)+j]=bmp_buf[(heigh-1-i)(width*3)+j];
}
}
}