ADI Blackfin DSP处理器-BF533的开发详解53:CMOS摄像头采集图像+LCD显示(含源码)

news2024/11/22 5:52:08

硬件准备

ADSP-EDU-BF533:BF533开发板
AD-HP530ICE:ADI DSP仿真器

软件准备

Visual DSP++软件

硬件链接

在这里插入图片描述
在这里插入图片描述

功能介绍

代码实现了摄像头拍摄一张 640480 大小,YUV422 格式的图片,然后将图片转成 RGB565 格式,裁剪为 480272尺寸,将其显示在液晶屏上。通过点击触摸屏,可以拍摄下一张图片显示在液晶屏上。

代码使用说明

摄像头采集到 YUV422 的图像后,通过以下函数将图像转为 480*272 尺寸的 RGB565 格式:

ConvertYUY2toRGB24(rgbdata_buffer,yuvdata_buffer, 640,480);
//将 YUV422 格式数据转为 RGB888 格式

size_convert(rgbdata_buffer,DisplayBuffer);
//将 640480 尺寸的数据裁剪为 480272 尺寸

RGB888_RGB565(DisplayBuffer, 391680,DisplayBuffer_565);
//将 RGB888 格式的数据转为 RGB565 格式

代码实验步骤

  1. 将板卡连接仿真器,将摄像头插入板卡 CMOS 接口,板卡上电,仿真器上电,运行 VDSP 软件并连接板卡。
  2. 将工程 BF53x_CMOS_CAMERA.dpj 载入 VDSP 软件。
  3. 编译并运行。

代码实验结果

待图像显示出一张拍摄到的图片时,点击触摸屏,可拍摄下一张图片,并显示到液晶屏上。

程序源码

cap.s

static int WIDTH;
static int HEIGHT;
static int IMG_SIZE;

static int fd_ppi;
unsigned char *in_buff;

typedef unsigned int dword_t;
typedef unsigned short word_t;
typedef unsigned char BYTE;

#define BI_RGB 0L
#define BI_RLE8 1L
#define BI_RLE4 2L
#define BI_BITFIELDS 3L

#pragma pack (1)

typedef struct tagRGBQUAD {
BYTE rgbBlue;
BYTE rgbGreen;
BYTE rgbRed;
BYTE rgbReserved;
} RGBQUAD;

#pragma pack (0)

#define BMP_WITH 640
#define BMP_HEGHT 480

#define Y_DATA 1
#define YUYV_DATA 2

typedef struct tagTABLE_YUV2RGB
{
unsigned short YtoR[256];
unsigned short YtoG[256];
unsigned short YtoB[256];
unsigned short UtoG[256];
unsigned short UtoB[256];
unsigned short VtoR[256];
unsigned short VtoG[256];
}TABLE_YUV2RGB;

TABLE_YUV2RGB table_yuv2rgb;

void Init()
{
long j = 0;
for (j = 0; j < 256; ++j)
{
table_yuv2rgb.YtoR[j] = table_yuv2rgb.YtoG[j] = table_yuv2rgb.YtoB[j] = (unsigned short)(j << 7);
table_yuv2rgb.VtoR[j] = j * 180;
table_yuv2rgb.VtoG[j] = j * 91;
table_yuv2rgb.UtoG[j] = j * 44;
table_yuv2rgb.UtoB[j] = j * 226;
}
}

void ConvertYUY2toRGB24(BYTE* pDst, BYTE* pSrc, int w, int h)
{

long m = 0;   
long k = 0;   
int   n=w/2;   
int   dec=w*4;   

int tmpR0 = 0;   
int tmpG0 = 0;   
int tmpB0 = 0;   
int tmpR1 = 0;   
int tmpG1 = 0;   
int tmpB1 = 0;   
int   i;
int   j;

k=(h-1)*w<<1;   
for(  i=h-1;i>-1;i--)   
{   
	
	for(j=0;j<n;j++)   
	{   
		tmpR0 = (table_yuv2rgb.YtoR[pSrc[k + 0]] + table_yuv2rgb.VtoR[pSrc[k + 3]] - 22906) >> 7;     
		
		tmpG0 = (table_yuv2rgb.YtoG[pSrc[k + 0]] - table_yuv2rgb.VtoG[pSrc[k + 3]] - table_yuv2rgb.UtoG[pSrc[k + 1]] + 17264) >> 7;   
		tmpB0 = (table_yuv2rgb.YtoB[pSrc[k + 0]] + table_yuv2rgb.UtoB[pSrc[k + 1]] - 28928) >> 7;   
		
		tmpR1 = (table_yuv2rgb.YtoR[pSrc[k + 2]] + table_yuv2rgb.VtoR[pSrc[k + 3]] - 22906) >> 7;     
		tmpG1 = (table_yuv2rgb.YtoG[pSrc[k + 2]] - table_yuv2rgb.VtoG[pSrc[k + 3]] - table_yuv2rgb.UtoG[pSrc[k + 1]] + 17264) >> 7;     
		tmpB1 = (table_yuv2rgb.YtoB[pSrc[k + 2]] + table_yuv2rgb.UtoB[pSrc[k + 1]] - 28928) >> 7;     
		
		if (tmpR0 > 255) tmpR0 = 255;   
		if (tmpG0 > 255) tmpG0 = 255;   
		if (tmpB0 > 255) tmpB0 = 255;   
		if (tmpR1 > 255) tmpR1 = 255;   
		if (tmpG1 > 255) tmpG1 = 255;   
		if (tmpB1 > 255) tmpB1 = 255;   
		
		if (tmpR0 < 0) tmpR0 = 0;   
		if (tmpG0 < 0) tmpG0 = 0;   
		if (tmpB0 < 0) tmpB0 = 0;   
		if (tmpR1 < 0) tmpR1 = 0;   
		if (tmpG1 < 0) tmpG1 = 0;   
		if (tmpB1 < 0) tmpB1 = 0;   
		
		pDst[m + 0] = tmpB0;   
		pDst[m + 1] = tmpG0;   
		pDst[m + 2] = tmpR0;   
		pDst[m + 3] = tmpB1;   
		pDst[m + 4] = tmpG1;   
		pDst[m + 5] = tmpR1;   
		
		k += 4;   
		m += 6;   
	}   
	k=k-dec;   
}

}

cmos.c

#include <cdefBF533.h>
#include"i2c.h"

#define OV9653_ADDRESS 0x60

static i2c_device mcu_i2c;

void init_OV9653(void);
int ov9653_write(unsigned char addr, unsigned char dat);
int ov9653_read(unsigned char addr, unsigned char * buf);
/****************************************************************************

  • 名称 :ov9653_write
  • 功能 : 写ov9653寄存器函数
  • 入口参数 :addr:寄存器偏移地址
    dat:寄存器配置值
  • 出口参数 :返回0
    /
    int ov9653_write(unsigned char addr, unsigned char dat)
    {
    int ret = -1;
    i2c_start(&mcu_i2c);
    //send slave address
    if(i2c_write(&mcu_i2c, OV9653_ADDRESS, 1)){
    i2c_stop(&mcu_i2c);
    return ret;
    }
    //send sub-address to device
    if(i2c_write(&mcu_i2c, addr, 1)){
    i2c_stop(&mcu_i2c);
    return ret;
    }
    //send data to device
    i2c_write(&mcu_i2c, dat, 1);
    i2c_stop(&mcu_i2c);
    return 0;
    }
    /
  • 名称 :ov9653_read
  • 功能 : 读ov9653寄存器函数寄存器偏移地址
  • 入口参数 :addr:
    buf:寄存器读取数据缓存
  • 出口参数 :返回0
    ****************************************************************************/
    int ov9653_read(unsigned char addr, unsigned char * buf)
    {
    unsigned char *p = buf;
    int ret = -1;
    i2c_start(&mcu_i2c);
    //send slave address
    if(i2c_write(&mcu_i2c, OV9653_ADDRESS, 1)){
    i2c_stop(&mcu_i2c);
    return ret;
    }
    //send sub-address of slave
    if(i2c_write(&mcu_i2c, addr, 1)){
    i2c_stop(&mcu_i2c);
    return ret;
    }
    i2c_stop(&mcu_i2c);
    i2c_start(&mcu_i2c);
    // send slave address (+1 read mode)
    if(i2c_write(&mcu_i2c, OV9653_ADDRESS+1, 1)){
    i2c_stop(&mcu_i2c);
    return ret;
    }
    if(i2c_wait_slave(&mcu_i2c, 1000)){
    i2c_stop(&mcu_i2c);
    return ret;
    }
    i2c_read(&mcu_i2c, p++, 1); // send ack
    i2c_stop(&mcu_i2c);
    return 0;
    }

/****************************************************************************

  • 名称 :Init_OV9653

  • 功能 : CMOS 130万 内部寄存器配置信息

  • 入口参数 :无

  • 出口参数 :无
    ****************************************************************************/
    void init_OV9653(void)
    {
    mcu_i2c.sclk = PF0; //时钟PF脚
    mcu_i2c.sdata = PF1; //数据PF脚
    mcu_i2c.low_ns = 7000; //低电平延时 ns
    mcu_i2c.high_ns = 6000; //高电平延时 ns
    i2c_init(&mcu_i2c);

    ov9653_write(0x12,0x80);
    ov9653_write(0x12,0x80);
    ov9653_write(0x11,0x81);
    ov9653_write(0x6b,0x0a);
    ov9653_write(0x6a,0x3e);
    ov9653_write(0x3b,0x09);
    ov9653_write(0x13,0xe0);
    ov9653_write(0x01,0x80);
    ov9653_write(0x02,0x80);
    ov9653_write(0x00,0x00);
    ov9653_write(0x10,0x00);
    ov9653_write(0x13,0xe5);
    ov9653_write(0x39,0x43);
    ov9653_write(0x38,0x12);
    ov9653_write(0x37,0x00);
    ov9653_write(0x35,0x91);
    ov9653_write(0x0e,0x20);
    ov9653_write(0x1e,0x34);
    ov9653_write(0xA8,0x80);
    ov9653_write(0x12,0x40);
    ov9653_write(0x04,0x00);
    ov9653_write(0x0c,0x04);
    ov9653_write(0x0d,0x80);
    ov9653_write(0x18,0xc6);
    ov9653_write(0x17,0x26);
    ov9653_write(0x32,0xad);
    ov9653_write(0x03,0x00);
    ov9653_write(0x1a,0x3d);
    ov9653_write(0x19,0x01);
    ov9653_write(0x3f,0xa6);
    ov9653_write(0x14,0x1a);
    ov9653_write(0x15,0x02);
    ov9653_write(0x41,0x12);
    ov9653_write(0x42,0x08);
    ov9653_write(0x1b,0x00);
    ov9653_write(0x16,0x06);
    ov9653_write(0x33,0xe2);
    ov9653_write(0x49,0x60);
    ov9653_write(0x34,0x16);
    ov9653_write(0x96,0x04);
    ov9653_write(0x3a,0x00);
    ov9653_write(0x8e,0x00);
    ov9653_write(0x3c,0x77);
    ov9653_write(0x8B,0x06);
    ov9653_write(0x94,0x88);
    ov9653_write(0x95,0x88);
    ov9653_write(0x40,0xc1);
    ov9653_write(0x29,0x3f);
    ov9653_write(0x0f,0x42);
    ov9653_write(0x3d,0x92);
    ov9653_write(0x69,0x40);
    ov9653_write(0x5C,0xb9);
    ov9653_write(0x5D,0x96);
    ov9653_write(0x5E,0x10);
    ov9653_write(0x59,0xc0);
    ov9653_write(0x5A,0xaf);
    ov9653_write(0x5B,0x55);
    ov9653_write(0x43,0xf0);
    ov9653_write(0x44,0x10);
    ov9653_write(0x45,0x68);
    ov9653_write(0x46,0x96);
    ov9653_write(0x47,0x60);
    ov9653_write(0x48,0x80);
    ov9653_write(0x5F,0xe0);
    ov9653_write(0x60,0x8c);
    ov9653_write(0x61,0x20);
    ov9653_write(0xa5,0xd9);
    ov9653_write(0xa4,0x74);
    ov9653_write(0x8d,0xc2);
    ov9653_write(0x13,0xe7);
    ov9653_write(0x4f,0x3a);
    ov9653_write(0x50,0x3d);
    ov9653_write(0x51,0x03);
    ov9653_write(0x52,0x12);
    ov9653_write(0x53,0x26);
    ov9653_write(0x54,0x38);
    ov9653_write(0x55,0x40);
    ov9653_write(0x56,0x40);
    ov9653_write(0x57,0x40);
    ov9653_write(0x58,0x0d);
    ov9653_write(0x8C,0x23);
    ov9653_write(0x3E,0x02);
    ov9653_write(0xa9,0xb8);
    ov9653_write(0xaa,0x92);
    ov9653_write(0xab,0x0a);
    ov9653_write(0x8f,0xdf);
    ov9653_write(0x90,0x00);
    ov9653_write(0x91,0x00);
    ov9653_write(0x9f,0x00);
    ov9653_write(0xa0,0x00);
    ov9653_write(0x3A,0x01);
    ov9653_write(0x24,0x80);
    ov9653_write(0x25,0x70);
    ov9653_write(0x26,0xd3);
    ov9653_write(0x2a,0x10);
    ov9653_write(0x2b,0x40);
    ov9653_write(0x6c,0x40);
    ov9653_write(0x6d,0x30);
    ov9653_write(0x6e,0x4b);
    ov9653_write(0x6f,0x60);
    ov9653_write(0x70,0x70);
    ov9653_write(0x71,0x70);
    ov9653_write(0x72,0x70);
    ov9653_write(0x73,0x70);
    ov9653_write(0x74,0x60);
    ov9653_write(0x75,0x60);
    ov9653_write(0x76,0x50);
    ov9653_write(0x77,0x48);
    ov9653_write(0x78,0x3a);
    ov9653_write(0x79,0x2e);
    ov9653_write(0x7a,0x28);
    ov9653_write(0x7b,0x22);
    ov9653_write(0x7c,0x04);
    ov9653_write(0x7d,0x07);
    ov9653_write(0x7e,0x10);
    ov9653_write(0x7f,0x28);
    ov9653_write(0x80,0x36);
    ov9653_write(0x81,0x44);
    ov9653_write(0x82,0x52);
    ov9653_write(0x83,0x60);
    ov9653_write(0x84,0x6c);
    ov9653_write(0x85,0x78);
    ov9653_write(0x86,0x8c);
    ov9653_write(0x87,0x9e);
    ov9653_write(0x88,0xbb);
    ov9653_write(0x89,0xd2);
    ov9653_write(0x8a,0xe6);

    }

cpu.c

#include <cdefbf533.h>

/**********************************************************************************

  • 名称 :Set_PLL
  • 功能 :初始化内核时钟和系统时钟
  • 入口参数 :pmsel pssel 设置参数
  • 出口参数 :无
    ***********/
    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;”);
    }
    }
    /
  • 名称 :Setup_Flags
  • 功能 :初始化PF口
  • 入口参数 :无
  • 出口参数 :无
    ****************************************************************************/
    void Setup_Flags(void)
    {
    *pFIO_INEN = 0x0020;
    *pFIO_DIR = 0x001f;
    *pFIO_EDGE = 0x0000;
    *pFIO_MASKA_S = 0x0020;
    *pFIO_POLAR = 0x0020;
    }

/****************************************************************************

  • 名称 :Init_EBIU
  • 功能 :初始化并允许异步BANK存储器工作
  • 入口参数 :无
  • 出口参数 :无
    ****************************************************************************/

void Init_EBIU(void)
{
*pEBIU_AMBCTL0 = 0x7bb07bb0;
*pEBIU_AMBCTL1 = 0xffc0ffc0;
*pEBIU_AMGCTL = 0x000f;
}

/****************************************************************************

  • 名称 :Init_SDRAM
  • 功能 :初始化SDRAM
  • 入口参数 :无
  • 出口参数 :无
    ****************************************************************************/
    void Init_SDRAM(void)
    {
    *pEBIU_SDRRC = 0x00000817;
    *pEBIU_SDBCTL = 0x00000013;
    *pEBIU_SDGCTL = 0x0091998d;
    ssync();
    }

/****************************************************************************

  • 名称 : delay
  • 功能 : 延时函数
  • 入口参数 :无
  • 返回值 :无
    ****************************************************************************/
    void delay(unsigned int tem)
    {
    int i;
    for(i=0;i<tem;i++)
    asm(“nop;”);
    }

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;
}

i2c.c

#include <cdefBF533.h>
#include “i2c.h”

#define CORE_CLK_IN 25 * 1000 * 1000

#define SET_PF(pf)
do{
*pFIO_FLAG_S = (pf);
ssync();
}while(0)

#define CLR_PF(pf)
do{
*pFIO_FLAG_C = (pf);
ssync();
}while(0)

#define SET_PF_OUTPUT(pf)
do{
*pFIO_INEN &= ~(pf);
*pFIO_DIR |= (pf);
ssync();
}while(0)

#define SET_PF_INPUT(pf)
do{
*pFIO_DIR &= ~(pf);
*pFIO_INEN |= (pf);
ssync();
}while(0)

int get_core_clk(void)
{
int tempPLLCTL;
int _DF;
int VCO;
int MSEL1;

tempPLLCTL = *pPLL_CTL;


MSEL1 = ((tempPLLCTL & 0x7E00) >> 9);
_DF   =  tempPLLCTL & 0x0001;

VCO  = MSEL1 * __CORE_CLK_IN__;
if(_DF == 1)
	VCO /= 2;

return  VCO;

}
void delay_ns(unsigned int core_clock, unsigned long long count)
{
count *= core_clock;
count /= 1000000000;
while(count–);

}

int _get_sdata(i2c_device * dev)
{
return ((*pFIO_FLAG_D & dev->sdata) ? 1 : 0);
}

void i2c_init(i2c_device * dev)
{
dev->core_clock = get_core_clk();
dev->delay_ns = delay_ns;
*pFIO_DIR |= dev->sclk | dev->sdata;
ssync();
}

void i2c_deinit(i2c_device * dev)
{
dev->sclk = 0;
dev->sdata = 0;

*pFIO_DIR &=  ~(dev->sclk | dev->sdata);
ssync();

}

void i2c_start(i2c_device * dev)
{
SET_PF_OUTPUT(dev->sdata);
SET_PF_OUTPUT(dev->sclk);

SET_PF(dev->sdata);
SET_PF(dev->sclk);
delay_ns(dev->core_clock, dev->high_ns);

CLR_PF(dev->sdata);
delay_ns(dev->core_clock, dev->low_ns);

CLR_PF(dev->sclk);
delay_ns(dev->core_clock, dev->low_ns);

}

void i2c_stop(i2c_device * dev)
{
CLR_PF(dev->sclk);
delay_ns(dev->core_clock, dev->low_ns);

SET_PF_OUTPUT(dev->sdata);
CLR_PF(dev->sdata);
delay_ns(dev->core_clock, dev->low_ns);

SET_PF_INPUT(dev->sclk);
delay_ns(dev->core_clock, dev->high_ns);

SET_PF_INPUT(dev->sdata);
delay_ns(dev->core_clock, dev->high_ns);

}

int i2c_read_ack(i2c_device * dev)
{
int ret = 0;

SET_PF_INPUT(dev->sdata);
delay_ns(dev->core_clock, dev->high_ns/3);

SET_PF(dev->sclk);
delay_ns(dev->core_clock, dev->high_ns/3);

ret = _get_sdata(dev);

delay_ns(dev->core_clock, dev->high_ns/3);
CLR_PF(dev->sclk);

delay_ns(dev->core_clock, dev->low_ns);

SET_PF_OUTPUT(dev->sdata);
return ret;

}

int i2c_wait_slave(i2c_device * dev, unsigned int time_out)
{
int ret;
int count = time_out * 2 / dev->high_ns;

SET_PF_INPUT(dev->sclk);
delay_ns(dev->core_clock, dev->high_ns/2);

do{
	ret = *pFIO_FLAG_D & dev->sclk;
	if(ret)
	   break;
	delay_ns(dev->core_clock, dev->high_ns/2);
}while(count--);

SET_PF_OUTPUT(dev->sclk);
return !ret;

}

void i2c_write_ack(i2c_device * dev)
{
SET_PF_OUTPUT(dev->sdata);
CLR_PF(dev->sdata);
delay_ns(dev->core_clock, dev->high_ns/2);
SET_PF(dev->sclk);
delay_ns(dev->core_clock, dev->high_ns);

CLR_PF(dev->sclk);
delay_ns(dev->core_clock, dev->low_ns);

}

int i2c_write(i2c_device * dev, unsigned char value, int need_ack)
{
int ret = -1;
unsigned char index;

SET_PF_OUTPUT(dev->sdata);

//send 8 bits to slave
for(index = 0; index < 8; index++){
	//send one bit to the i2c bus
	if((value<<index) & 0x80){
		SET_PF(dev->sdata);
	} else {
		CLR_PF(dev->sdata);
	}
	
	delay_ns(dev->core_clock, dev->low_ns/2);
	
	SET_PF(dev->sclk);
	delay_ns(dev->core_clock, dev->high_ns);
	
	CLR_PF(dev->sclk);
	delay_ns(dev->core_clock, dev->low_ns/2);
}

if(need_ack){
	ret = i2c_read_ack(dev);
}
return ret;

}

int i2c_read(i2c_device * dev, unsigned char * value, int send_ack)
{
unsigned char index;
*value = 0x00;

SET_PF_INPUT(dev->sdata);
delay_ns(dev->core_clock, dev->high_ns/2);

//get 8 bits from the device
for(index = 0; index < 8; index++){
	SET_PF(dev->sclk);
	delay_ns(dev->core_clock, dev->high_ns/2);
	
	*value <<= 1;
	*value |= _get_sdata(dev);
	
	delay_ns(dev->core_clock, dev->high_ns/2);
	
	CLR_PF(dev->sclk);
	delay_ns(dev->core_clock, dev->low_ns);
}

// send ack to slave
if(send_ack){
	i2c_write_ack(dev);
}
return *value;

}

int.c

#include <cdefBF533.h>
#include <sys\exception.h>
#include “cpld.h”

EX_INTERRUPT_HANDLER(FlagA_ISR);
EX_INTERRUPT_HANDLER(DMA0_PPI_ISR);

void Init_Flags(void)
{
*pFIO_INEN = 0x0001;
*pFIO_DIR = 0x0000;
*pFIO_EDGE = 0x0001;
*pFIO_POLAR = 0x0001;
*pFIO_MASKA_D = 0x0001;
}

void Init_Interrupts(void)
{
*pSIC_IAR0 = 0xffffffff;
*pSIC_IAR1 = 0xfffffff1;
*pSIC_IAR2 = 0xffff5fff;
register_handler(ik_ivg8, DMA0_PPI_ISR);
register_handler(ik_ivg12, FlagA_ISR);
*pSIC_IMASK = 0x00000100;
}
int cmos_flag;
EX_INTERRUPT_HANDLER(FlagA_ISR)
{
unsigned char interrupt=0;

interrupt = (~*pINTERRUPT_DAT&0x7f);	

if(interrupt&0x02)
{
	*pSIC_IMASK = 0x00000100;
    LCDBK_Disable();
    PPI_TMR_DMAR_Disable();
    
	delay(1000000);
	
    CMOS_Enable();
   	delay(1000000);
   	*pPPI_CONTROL = 0;
	*pDMA0_CONFIG = 0;
	Video_Frame_Capture();
}
*pFIO_FLAG_C = 0x0001;	

}

main.c

#include <cdefBF533.h>

/****************************************************************************

  • 名称 :main
  • 功能 :初始化各函数,实现图象捕捉
  • 入口参数 :无
  • 出口参数 :无
    ****************************************************************************/
    void main()
    {
    Set_PLL(16,4) ;
    Setup_Flags();
    Init_EBIU();
    Init_SDRAM();
    Init_Interrupts();
    IIC_Enable();
    init_OV9653();
    CMOS_Enable();
    Video_Frame_Capture();
    while(1);
    }

ppi.c

#include <cdefBF533.h>
#include <sys\exception.h>

unsigned char yuvdata_buffer[4801280];
unsigned char rgbdata_buffer[480
1920];

unsigned char DisplayBuffer[2721440] ;
unsigned char DisplayBuffer_565[272
960] ;

EX_INTERRUPT_HANDLER(DMA0_PPI_ISR);

void size_convert(unsigned char src, unsigned char dst)
{
int i;
int j;
for(i=0;i<272;i++)
{
for(j=0;j<1920;j++)
{
dst[((i
480
3)+j)]=src[(271-i)6403+j];
}
}
}

/****************************************************************************

  • 名称 :Video_Frame_Capture
  • 功能 : 初始化PPI控制器 初始化DMA0控制器
  • 入口参数 :无
  • 出口参数 :无
    ****************************************************************************/
    void Video_Frame_Capture(void)
    {
    *pPPI_FRAME = 480;
    *pPPI_COUNT = 1279;
    *pPPI_DELAY = 0;
    *pPPI_CONTROL = 0x01AC;
    *pDMA0_START_ADDR = &yuvdata_buffer[0];
    *pDMA0_X_COUNT = 640;
    *pDMA0_X_MODIFY = 0x2;
    *pDMA0_Y_COUNT = 480;
    *pDMA0_Y_MODIFY = 0x2;
    *pDMA0_PERIPHERAL_MAP = 0x0;
    *pDMA0_CONFIG = WNR | WDSIZE_16| DMA2D | RESTART | DI_EN;
    *pDMA0_CONFIG |= DMAEN;
    ssync();
    *pPPI_CONTROL |= PORT_EN;
    ssync();
    }

/****************************************************************************

  • 名称 :EX_INTERRUPT_HANDLER
  • 功能 : 中断函数 清 DMA 中断标志,关PPI
  • 入口参数 :无
  • 出口参数 :无
    ****************************************************************************/

int img_count = 0;

EX_INTERRUPT_HANDLER(DMA0_PPI_ISR)
{
*pDMA0_IRQ_STATUS = 0x1;
img_count++;

if(img_count<10)
{
	  Video_Frame_Capture();
}
else
{
	img_count = 0;
	*pPPI_CONTROL &= 0xfffe;
	*pSIC_IMASK = 0x00000000;    

	Init();
	ConvertYUY2toRGB24(rgbdata_buffer,yuvdata_buffer, 640,480);
	size_convert(rgbdata_buffer,DisplayBuffer);
	RGB888_RGB565(DisplayBuffer, 391680,DisplayBuffer_565);

	*pPPI_CONTROL = 0;
	*pDMA0_CONFIG = 0;

	InitDMA();
    InitPPI();
    InitTimer();
	PPI_TMR_DMA_Enable();
	LCD_Enable();
	Init_Timers0(1999);//1~1999 控制背光亮度
	Enable_Timers0();
	LCDBK_Enable();	
		
	*pSIC_IMASK = 0x00080000;
	
}

}

lcd.c

#include <cdefBF533.h>

extern unsigned char DisplayBuffer_565[272*960] ;

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);
*pTIMER_DISABLE|= 0x0006;

}

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] &0xf8; //B 
     dst[j+1] |= ((src[i+1]>>5) & 0x07);//GH
     dst[j] = ((src[i+1]<<3) & 0xe0);  	//GL  
     dst[j] |= ((src[i+2]>>3) &0x1f); 	//R
    j += 2;  
    
}

}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/91760.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Latex 中插入 Matlab 代码

这篇文章将介绍如何在 Latex 排版过程中添加 Matlab 代码 功能效果 主要有如下排版功能&#xff1a; 语法高亮自动添加边框自动添加行号 先上图&#xff0c;大家感受一下效果&#xff1a; 而实现这些只需要一行代码加一个包&#xff01; 插入代码块 \usepackage{listings…

JavaScript刷LeetCode拿offer-二叉树层序遍历篇

前言 博主最近在刷leetcode&#xff0c;做到二叉树套题的时候发现很多题的解题思路都是基于二叉树的层序遍历来完成的&#xff0c;因此写下这篇文章&#xff0c;记录一下二叉树层序遍历这件"神器"在实战的运用。 [leetcode] 102.二叉树的层序遍历 二叉树的层序遍历…

[附源码]Python计算机毕业设计高校宿舍管理系统Django(程序+LW)

该项目含有源码、文档、程序、数据库、配套开发软件、软件安装教程 项目运行 环境配置&#xff1a; Pychram社区版 python3.7.7 Mysql5.7 HBuilderXlist pipNavicat11Djangonodejs。 项目技术&#xff1a; django python Vue 等等组成&#xff0c;B/S模式 pychram管理等…

Vue渲染器(五):快速diff算法

渲染器&#xff08;五&#xff09;&#xff1a;快速diff算法 这章开始讨论第三种用于比较新旧vnode的方式&#xff1a;快速diff算法。跟它的名字一样&#xff0c;它很快。Vue3采用的就是这种算法&#xff0c;Vue2采用的是上一章中的双端diff算法。 接下来就来着重了解它的实现…

宝塔部署前后端分离项目(Vue+SpringBoot)

目录 后端部分 配置Redis 前端部分 后端部分 1 先修改自己的speingboot配置文件&#xff0c;我的是yml文件 保证宝塔上建的数据库和自己代码里&#xff0c;就是配置文件中所建的数据库的名字是一致的密码也要保持一致&#xff0c;Redis也一样&#xff0c;如果有的话 2 记录…

关注电动汽车能效水平 提高续航能力

电动汽车&#xff08;EV&#xff09;近些年发展迅猛&#xff0c;已被汽车业内普遍认为是未来汽车发展的新方向&#xff0c;但是现如今电动汽车仍然存在一些短板&#xff0c;导致其还无法替代传统燃油车。对此&#xff0c;先想到的是电动车的续航问题。其实解决电动车续航问题主…

python 插值处理一维数据 interpolate

scipy库&#xff1a; 原码&#xff1a; https://docs.scipy.org/doc/scipy/reference/generated/scipy.interpolate.interp1d.html kind可选“linear”、“nearest”、“nearest-up”、“zero”、“slinear”、“quadratic”、“cubic”、“previous”或“next”之一。 “zero…

JSP sshOA办公系统myeclipse开发oracle数据库MVC模式java编程计算机网页设计

一、源码特点 JSP sshOA办公系统是一套完善的web设计系统&#xff08;系统采用ssh框架进行设计开发&#xff09;&#xff0c;对理解JSP java编程开发语言有帮助&#xff0c;系统具有完整的源代码和数据库&#xff0c;系统主要采用B/S模式开 发。开发环境为TOMCAT7.0,Myecl…

音视频编解码流程与如何使用 FFMPEG 命令进行音视频处理

一、前言 FFMPEG 是特别强大的专门用于处理音视频的开源库。你既可以使用它的 API 对音视频进行处理&#xff0c;也可以使用它提供的工具&#xff0c;如 ffmpeg, ffplay, ffprobe&#xff0c;来编辑你的音视频文件。 本文将简要介绍一下 FFMPEG 库的基本目录结构及其功能&#…

OpenWrt 安装 WireGuard

下载 img镜像 https://downloads.openwrt.org/releases/22.03.2/targets/x86/generic/openwrt-22.03.2-x86-generic-generic-squashfs-combined-efi.img.gz解压 转化格式我的是Linux # 解压 gzip -d openwrt-22.03.2-x86-generic-generic-squashfs-combined-efi.img.gz #vmwa…

如何将数学曲线变为机器人轨迹-花式show爱心代码-turtlesim篇

第一步&#xff1a;找到曲线数学描述的网址。 阅读后了解曲线所对应的xy函数。 不要选太复杂的&#xff0c;毕竟先复现出来最重要的。 第二步&#xff0c;这个函数转为C代码。 //Lovegoal_x5.54.0*pow(sin(curve_t/200.0),3);goal_y5.5((13.0*cos(curve_t/200.0)-5.0*cos(curv…

网络工程师备考6章

6.1 OSI参考模型概述 计算机的整套理论是图灵提出来的,自此创办图灵奖(计算机类最高奖项)。科学远远比技术更重要。 OSI七层模型就是科学,就是理论,所以非常重要! 注:ISO是一个机构,OSI是一个协议:分别七层 6.2 OSI参考模型 注:在传输层中,什么是端到端,例如A,…

jsp+ssm计算机毕业设计ssm校园贫困补助系统【附源码】

项目运行 环境配置&#xff1a; Jdk1.8 Tomcat7.0 Mysql HBuilderX&#xff08;Webstorm也行&#xff09; Eclispe&#xff08;IntelliJ IDEA,Eclispe,MyEclispe,Sts都支持&#xff09;。 项目技术&#xff1a; JSPSSM mybatis Maven等等组成&#xff0c;B/S模式 Mave…

使用vite构建vue3项目与官网构建区别

使用vite构建vue3项目 一、vue3官网文档的 https://www.javascriptc.com/vue3js/guide/installation.html#命令行工具-cli npm init vite-app cd npm installnpm run dev 二、vite官网文档的 https://cn.vitejs.dev/guide/#trying-vite-online 1 对应路径cmd 输入 npm create…

Grad-CAM简介-网络 热力图分析

论文名称&#xff1a;Grad-CAM: Visual Explanations from Deep Networks via Gradient-based Localization 论文下载地址&#xff1a;https://arxiv.org/abs/1610.02391 推荐代码&#xff08;Pytorch&#xff09;&#xff1a;https://github.com/jacobgil/pytorch-grad-cam bi…

流媒体开源服务 MediaSoup 初识

目录 前言 正文 一、简单介绍 二、关键特色 1. 超强 SFU 功能 2. Node.js 模块 3. 客户端 SDK 三、架构组成 1. 关键实例 2. 重要模块 四、发展现状 前言 最近收看了一期微软&#xff08;中国&#xff09;关于云原生、大数据、AI 领域的开源服务创新的线上圆桌论坛&…

垃圾回收算法

1.种类 垃圾回收算法通常意义上有两种&#xff1a; 引用计数式垃圾收集追踪式垃圾收集 追踪式垃圾收齐又称“间接垃圾收集”&#xff0c;现在有很多算法大都遵循了分代收集理论&#xff0c;而分代收集理论的基础&#xff0c;却是以下俩个分代假说&#xff1a; 强分代假说&am…

MyPerf4J一个高性能、无侵入的Java性能监控和统计工具,有点东西!

背景 随着所在公司的发展&#xff0c;应用服务的规模不断扩大&#xff0c;原有的垂直应用架构已无法满足产品的发展&#xff0c;几十个工程师在一个项目里并行开发不同的功能&#xff0c;开发效率不断降低。 于是公司开始全面推进服务化进程&#xff0c;把团队内的大部分工程…

软件测试之移动app测试框架有哪些?

一、适用于Android的移动app测试框架 1.Espresso 十分流行的一款谷歌开发的Android测试框架&#xff0c;具备高性能性。可以创建非常简单直接的测试&#xff0c;而不必担心app的基础架构。此外&#xff0c;它是开源的&#xff0c;这使开发人员能够自定义框架。 2.Selendroid…

DOM算法系列003-获取节点A相对于节点B 的位置

UID: 20221214170009 aliases: tags: source: cssclass: created: 2022-12-14 1. 节点位置关系 两个节点A、B之间的位置关系总共有几种&#xff1f;我们第一时间能想到的&#xff1a; 节点A在节点B之后节点A在节点B之前节点A包含节点B节点A被节点B包含 除此之外&#xff0c;…