ADI Blackfin DSP处理器-BF533的开发详解37:图像处理专题-YUV420 转 RGB565(含源代码)

news2024/11/17 7:27:49

硬件准备

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

软件准备

Visual DSP++软件

硬件链接

在这里插入图片描述

功能介绍

代码实现了将 YUV420 数据格式转为 RGB565 格式。YUV420 的数据格式必须是两度和色度分离的。

板卡液晶屏和 VDSP 软件商 Image Viewer 工具上的 RGB565 格式不同,其区别是 RGB 数据格式的位置,在液晶屏上,R 的数据位置位于低 5 位,B 数据位置位于高 5 位。在 Image Viewer 工具上,R 数据位于高 5 位,B 数据位于低 5 位。

为了方便查看,在代码中将这两种转换函数都列出,方便查看。

代码使用说明

YUV420 转 RGB565 函数:
static void yuv420_to_rgb565(int width, int height, const unsigned char *src, unsigned short *dst)

int width:图像宽度
int height:图像高度
const unsigned char *src:YUV420 数据入口
unsigned short *dst:RGB565 数据出口

代码调试步骤

  1. 将板卡连接仿真器,运行 VDSP 软件并连接板卡。
  2. 将工程 BF53x_YUV420_TO_RGB565.dpj 载入 VDSP 软件,编译并运行。
  3. 待代码停止,用 VDSP 下的 Image Viewer 工具以 RGB565 格式查看图像。其配置如下:

在这里插入图片描述

代码调试结果

在 Image View 窗口中可看到图像:

在这里插入图片描述

程序源码

#include <cdefBF533.h>

//#define LCD_FORMAT 1

unsigned char in_buffer[391680]=
{
#include"YUV420_320_240.dat"
};

unsigned short out_buffer[391680];

void Set_PLL(unsigned int pmsel,unsigned int pssel)
{
unsigned 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_EBIU(void)
{
*pEBIU_AMBCTL0 = 0x7bb07bb0;
*pEBIU_AMBCTL1 = 0xffc07bb0;
*pEBIU_AMGCTL = 0x000f;
}

#ifdef LCD_FORMAT
static void yuv420_to_rgb565(int width, int height, const unsigned char *src, unsigned short *dst)
{
int line, col, linewidth;
int y, u, v, yy, vr, ug, vg, ub;
int r, g, b;
const unsigned char *py, *pu, *pv;

linewidth = width >> 1;
py = src;
pu = py + (width * height);
pv = pu + (width * height) / 4;

y = *py++;
yy = y << 8;
u = *pu - 128;
ug = 88 * u;
ub = 454 * u;
v = *pv - 128;
vg = 183 * v;
vr = 359 * v;

for (line = 0; line < height; line++) {
for (col = 0; col < width; col++) {
r = (yy + vr) >> 8;
g = (yy - ug - vg) >> 8;
b = (yy + ub ) >> 8;

  if (r < 0) r = 0;
  if (r > 255) r = 255;
  if (g < 0) g = 0;
  if (g > 255) g = 255;
  if (b < 0) b = 0;
  if (b > 255) b = 255;
  
  *dst = (((unsigned short)b>>3)<<11) | (((unsigned short)g>>2)<<5) | (((unsigned short)r>>3)<<0); 
	dst ++;
  y = *py++;
  yy = y << 8;
  if (col & 1) {
pu++;
pv++;

u = *pu - 128;
ug = 88 * u;
ub = 454 * u;
v = *pv - 128;
vg = 183 * v;
vr = 359 * v;
  }
} 
if ((line & 1) == 0) { 
  pu -= linewidth;
  pv -= linewidth;
}

}
}
#else
static void yuv420_to_rgb565(int width, int height, const unsigned char *src, unsigned short *dst)
{
int line, col, linewidth;
int y, u, v, yy, vr, ug, vg, ub;
int r, g, b;
const unsigned char *py, *pu, *pv;

linewidth = width >> 1;
py = src;
pu = py + (width * height);
pv = pu + (width * height) / 4;

y = *py++;
yy = y << 8;
u = *pu - 128;
ug = 88 * u;
ub = 454 * u;
v = *pv - 128;
vg = 183 * v;
vr = 359 * v;

for (line = 0; line < height; line++) {
for (col = 0; col < width; col++) {
r = (yy + vr) >> 8;
g = (yy - ug - vg) >> 8;
b = (yy + ub ) >> 8;

  if (r < 0) r = 0;
  if (r > 255) r = 255;
  if (g < 0) g = 0;
  if (g > 255) g = 255;
  if (b < 0) b = 0;
  if (b > 255) b = 255;
  *dst = (((unsigned short)r>>3)<<11) | (((unsigned short)g>>2)<<5) | (((unsigned short)b>>3)<<0); 
	dst ++;
  y = *py++;
  yy = y << 8;
  if (col & 1) {
pu++;
pv++;

u = *pu - 128;
ug = 88 * u;
ub = 454 * u;
v = *pv - 128;
vg = 183 * v;
vr = 359 * v;
  }
} 
if ((line & 1) == 0) { 
  pu -= linewidth;
  pv -= linewidth;
}

}
}
#endif

void main(void)
{
Set_PLL(16,4);
Init_EBIU();
yuv420_to_rgb565(320,240,in_buffer,out_buffer);
}

YUV420-RGB565

// blackfin-edinburgh-core
#include <sys/platform.h>
#include <sys/anomaly_macros_rtl.h>

/
// standard
#define IVBh (EVT0 >> 16)
#define IVBl (EVT0 & 0xFFFF)
#define UNASSIGNED_VAL 0x8181
#define INTERRUPT_BITS 0x400 // just IVG15
#define SYSCFG_VALUE 0x30

.section/DOUBLEANY program;
.file_attr requiredForROMBoot;
.align 2;

start:

/* V D S G < i n s e r t − c o d e − v e r y − b e g i n n i n g > ∗ / . s t a r t o f u s e r c o d e v e r y b e g i n n i n g : / / I n s e r t a d d i t i o n a l c o d e t o b e e x e c u t e d b e f o r e a n y o t h e r S t a r t u p C o d e h e r e . / / T h i s c o d e i s p r e s e r v e d i f t h e C R T i s r e − g e n e r a t e d . . e n d o f u s e r c o d e v e r y b e g i n n i n g : / ∗ VDSG<insert-code-very-beginning> */ .start_of_user_code_very_beginning: // Insert additional code to be executed before any other Startup Code here. // This code is preserved if the CRT is re-generated. .end_of_user_code_very_beginning: /* VDSG<insertcodeverybeginning>/.startofusercodeverybeginning://InsertadditionalcodetobeexecutedbeforeanyotherStartupCodehere.//ThiscodeispreservediftheCRTisregenerated..endofusercodeverybeginning:/VDSG */

/
// blackfin-edinburgh-core
#if WA_05000109
// Avoid Anomaly 05-00-0109
R1 = SYSCFG_VALUE;
SYSCFG = R1;
#endif

/
// standard
#if WA_05000229
// Avoid Anomaly 05-00-0229: DMA5_CONFIG and SPI_CTL not cleared on reset.
R1 = 0x400;
#if defined(ADSPBF538) || defined(ADSPBF539)
P0.L = SPI0_CTL & 0xFFFF;
P0.H = SPI0_CTL >> 16;
W[P0] = R1.L;
#else
P0.L = SPI_CTL & 0xFFFF;
P0.H = SPI_CTL >> 16;
W[P0] = R1.L;
#endif
P0.L = DMA5_CONFIG & 0xFFFF;
P0.H = DMA5_CONFIG >> 16;
R1 = 0;
W[P0] = R1.L;
#endif
// Clear loop counters to disable hardware loops
R7 = 0;
LC0 = R7;
LC1 = R7;

// Clear the DAG Length regs, to force linear addressing
L0 = R7;
L1 = R7;
L2 = R7;
L3 = R7;

// Clear ITEST_COMMAND and DTEST_COMMAND registers
I0.L = (ITEST_COMMAND & 0xFFFF);
I0.H = (ITEST_COMMAND >> 16);
I1.L = (DTEST_COMMAND & 0xFFFF);
I1.H = (DTEST_COMMAND >> 16);
[I0] = R7;
[I1] = R7;
CSYNC;

// Initialise the Event Vector table.
P0.H = IVBh;
P0.L = IVBl;

// Install __unknown_exception_occurred in EVT so that
// there is defined behaviour.
P0 += 2*4;		// Skip Emulation and Reset
P1 = 13;
R1.L = __unknown_exception_occurred;
R1.H = __unknown_exception_occurred;
LSETUP (.ivt,.ivt) LC0 = P1;

.ivt: [P0++] = R1;

// Set IVG15's handler to be the start of the mode-change
// code. Then, before we return from the Reset back to user
// mode, we'll raise IVG15. This will mean we stay in supervisor
// mode, and continue from the mode-change point, but at a
// much lower priority.
P1.H = supervisor_mode;
P1.L = supervisor_mode;
[P0] = P1;

/
// standard
// Initialise the stack.
// Note: this points just past the end of the section.
// First write should be with [–SP].
SP.L=ldf_stack_end;
SP.H=ldf_stack_end;
usp = sp;

// We're still in supervisor mode at the moment, so the FP
// needs to point to the supervisor stack.
FP = SP;

// Make space for incoming "parameters" for functions
// we call from here:
SP += -12;

R0 = INTERRUPT_BITS;
R0 <<= 5;	// Bits 0-4 not settable.

/
// install-default-handlers
CALL.X __install_default_handlers;

.extern __install_default_handlers;
.type __install_default_handlers,STT_FUNC;

/
// standard
R1 = SYSCFG;
R4 = R0; // Save modified list
BITSET(R1,1);
SYSCFG = R1; // Enable the cycle counter

/
// blackfin-edinburgh-core
#if WA_05000137 || WA_05000162
// Avoid Anomaly 02-00-0137
// Set the port preferences of DAG0 and DAG1 to be
// different; this gives better performance when
// performing daul-dag operations on SDRAM.
P0.L = DMEM_CONTROL & 0xFFFF;
P0.H = DMEM_CONTROL >> 16;
R0 = [P0];
BITSET(R0, 12);
BITCLR(R0, 13);
[P0] = R0;
CSYNC;
#endif

/* V D S G < i n s e r t − c o d e − e a r l y − s t a r t u p > ∗ / . s t a r t o f u s e r c o d e 1 : / / I n s e r t a d d i t i o n a l c o d e t o b e e x e c u t e d b e f o r e m a i n h e r e . / / T h i s c o d e i s p r e s e r v e d i f t h e C R T i s r e − g e n e r a t e d . . e n d o f u s e r c o d e 1 : / ∗ VDSG<insert-code-early-startup> */ .start_of_user_code1: // Insert additional code to be executed before main here. // This code is preserved if the CRT is re-generated. .end_of_user_code1: /* VDSG<insertcodeearlystartup>/.startofusercode1://Insertadditionalcodetobeexecutedbeforemainhere.//ThiscodeispreservediftheCRTisregenerated..endofusercode1:/VDSG */

/
// standard
// Enable interrupts
STI R4; // Using the mask from default handlers
RAISE 15;

// Move the processor into user mode.
P0.L=still_interrupt_in_ipend;
P0.H=still_interrupt_in_ipend;
RETI=P0;
NOP;		// Purely to prevent a stall warning

still_interrupt_in_ipend:
// execute RTI until we’ve finished servicing all
// interrupts of priority higher than IVG15. Normally one
// would expect to only have the reset interrupt in IPEND
// being serviced, but occasionally when debugging this may
// not be the case - if restart is hit when servicing an
// interrupt.
//
// When we clear all bits from IPEND, we’ll enter user mode,
// then we’ll automatically jump to supervisor_mode to start
// servicing IVG15 (which we will ‘service’ for the whole
// program, so that the program is in supervisor mode.
// Need to do this to ‘finish’ servicing the reset interupt.
RTI;

supervisor_mode:
[–SP] = RETI; // re-enables the interrupt system
R0.L = UNASSIGNED_VAL;
R0.H = UNASSIGNED_VAL;

// Push a RETS and Old FP onto the stack, for sanity.
[--SP]=R0;
[--SP]=R0;
// Make sure the FP is sensible.
FP = SP;
// Leave space for incoming "parameters"
SP += -12;

/* V D S G < i n s e r t − c o d e − b e f o r e − d e v i c e − i n i t i a l i z a t i o n > ∗ / . s t a r t o f u s e r c o d e 2 : / / I n s e r t a d d i t i o n a l c o d e t o b e e x e c u t e d b e f o r e d e v i c e i n i t i a l i z a t i o n h e r e . / / T h i s c o d e i s p r e s e r v e d i f t h e C R T i s r e − g e n e r a t e d . . e n d o f u s e r c o d e 2 : / ∗ VDSG<insert-code-before-device-initialization> */ .start_of_user_code2: // Insert additional code to be executed before device initialization here. // This code is preserved if the CRT is re-generated. .end_of_user_code2: /* VDSG<insertcodebeforedeviceinitialization>/.startofusercode2://Insertadditionalcodetobeexecutedbeforedeviceinitializationhere.//ThiscodeispreservediftheCRTisregenerated..endofusercode2:/VDSG */

/
// device-initialization
// initialise the devices known about for stdio.
CALL.X _init_devtab;
.extern _init_devtab;
.type _init_devtab,STT_FUNC;

/
// cplusplus
CALL.X ___ctorloop; // run global scope C++ constructors
.extern ___ctorloop;
.type ___ctorloop,STT_FUNC;

/* V D S G < i n s e r t − c o d e − b e f o r e − m a i n − e n t r y > ∗ / . s t a r t o f u s e r c o d e 3 : / / I n s e r t a d d i t i o n a l c o d e t o b e e x e c u t e d b e f o r e m a i n h e r e . / / T h i s c o d e i s p r e s e r v e d i f t h e C R T i s r e − g e n e r a t e d . . e n d o f u s e r c o d e 3 : / ∗ VDSG<insert-code-before-main-entry> */ .start_of_user_code3: // Insert additional code to be executed before main here. // This code is preserved if the CRT is re-generated. .end_of_user_code3: /* VDSG<insertcodebeforemainentry>/.startofusercode3://Insertadditionalcodetobeexecutedbeforemainhere.//ThiscodeispreservediftheCRTisregenerated..endofusercode3:/VDSG */

/
// get-args
// Read command-line arguments.
CALL.X __getargv;
r1.l=__Argv;
r1.h=__Argv;

.extern __getargv;
.type __getargv,STT_FUNC;
.extern __Argv;
.type __Argv,STT_OBJECT;

/
// standard
// Call the application program.
CALL.X _main;

/
// call-exit
CALL.X _exit; // passing in main’s return value
.extern _exit;
.type _exit,STT_FUNC;

/
// standard
.start.end: // Required by the linker to know the size of the routine
// that is needed for absolute placement.

.global start;
.type start,STT_FUNC;
.extern _main;
.type _main,STT_FUNC;
.extern ldf_stack_end;
.extern __unknown_exception_occurred;
.type __unknown_exception_occurred,STT_FUNC;

/
// cplusplus
.section/DOUBLEANY ctor;
.align 4;
___ctor_table:
.byte4=0;
.global ___ctor_table;
.type ___ctor_table,STT_OBJECT;
.section/DOUBLEANY .gdt;
.align 4;
___eh_gdt:
.global ___eh_gdt;
.byte4=0;
.type ___eh_gdt,STT_OBJECT;
.section/DOUBLEANY .frt;
.align 4;
___eh_frt:
.global ___eh_frt;
.byte4=0;
.type ___eh_frt,STT_OBJECT;

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

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

相关文章

【小甲鱼C语言】课后笔记第一章第三节——常量和宏定义

目录 1、常见的常量 2、宏定义&#xff08;符号常量&#xff09; 3、标识符 4、字符串常量 5、课后习题&#xff08;编程题&#xff09; 1、常见的常量 整型常量&#xff1a;520, 1314, 123 实型常量&#xff1a;3.14, 5.12, 8.97 字符常量 普通字符&#xff1a;L, o, v,…

基于短期的风力发电概率预测(Matlab代码实现)

&#x1f4a5;&#x1f4a5;&#x1f4a5;&#x1f49e;&#x1f49e;&#x1f49e;欢迎来到本博客❤️❤️❤️&#x1f4a5;&#x1f4a5;&#x1f4a5;&#x1f3c6;博主优势&#xff1a;&#x1f31e;&#x1f31e;&#x1f31e;博客内容尽量做到思维缜密&#xff0c;逻辑清…

Stm32旧版库函数5——ov2640通过nrf24l01发送图像

视频采集端&#xff1a; /******************************************************************************* // // 使用单片机STM32F100C8T6 8 // 晶振&#xff1a;8.00M // 编译环境 Keil uVision4 // 在3.3V的供电环境下&#xff0c;就能运行 // 波特率 115200 // 使…

PyTorch(六)网络模型

文章目录Log一、现有网络模型的使用及修改1. VGG① ImageNet 数据集下载② 模型加载③ 模型改造a. 添加一个线性层b. 插入一个线性层c. 修改一个线性层二、网络模型的保存与读取① 网络模型的保存a. 保存方式一b. 保存方式二② 网络模型的读取a. 读取方式一b. 读取方式二三、完…

微信公众号服务号配置对接在线客服系统教程

如果只需要实现微信公众号的关注自动回复&#xff0c;关键词自动回复功能&#xff0c;普通订阅号就可以 当需要对接实现公众号的模板消息提醒&#xff0c;模板消息与客服端H5的对接&#xff0c;访客在微信点击或扫码时获取到微信的昵称头像&#xff0c;需要网页授权功能。这种是…

Spring(一):Spring核心与设计思想(IoC、DI)

目录一、Spring是什么1.1 容器是什么&#xff1f;1.2 什么是IoC&#xff1f;1.3 理解Spring IoC1.4 DI是什么一、Spring是什么 我们这里所说的Spring指的是SpringFrameWork&#xff0c;是一个开源框架。Spring支持广泛的应用场景&#xff0c;它可以让Java企业级的应用程序开发…

k8s编程operator实战之云编码平台——②controller初步实现

文章目录1、工作空间镜像制作2、controller实现2.1 使用kubebuilder创建工程2.2 代码实现2.2.1 引入grpc2.2.2 实现CloudIdeServiceStatusInformer的实现CloudSpaceService定义方法CreateSpaceAndWaitForRunning方法GetPodSpaceInfo方法DeleteSpace方法GetPodSpaceStatus2.2.3 …

人才盘点的工具与方法有哪些?怎样做好人才盘点?

人才盘点是对组织和人才进行系统管理的一种流程。在此过程中&#xff0c;对组织架构、人员配比、人才绩效、关键岗位的继任计划、关键人才发展、关键岗位的招聘及关键人才的晋升和激励进行深入讨论&#xff0c;并制定详细的组织行动计划&#xff0c;确保组织以更加优化的结构和…

非零基础自学计算机操作系统 第1章 操作系统概述 1.5 操作系统的硬件环境 1.5.1 定时装置 1.5.2 堆与栈 1.5.3 寄存器

非零基础自学计算机操作系统 文章目录非零基础自学计算机操作系统第1章 操作系统概述1.5 操作系统的硬件环境1.5.1 定时装置1.5.2 堆与栈1.5.3 寄存器第1章 操作系统概述 1.5 操作系统的硬件环境 构建一个高效、可靠的操作系统&#xff0c;硬件需要提供哪些支持&#xff1f; 1…

MySQL数据库基本使用(一)-------登录及查看基本信息

1.MySQL登录命令 格式如下&#xff1a; mysql -h 主机名 -P 端口号 -u 用户名 -p密码例如&#xff1a; mysql -h localhost -P 3306 -u root -pabc123 # 这里我设置的root用户的密码是abc123注意&#xff1a; -p与密码之间不能有空格&#xff0c;其他参数名与参数值之间可以…

Spring Boot启动原理源码

Spring Boot启动原理源码 注意:这个springboot启动源码和springboot自动配置原理的源码是十分重要的,面试的时候要是问springboot,一般都会问这两个。 源码&#xff1a; SpringBoot 事假监听器发布顺序&#xff1a; 1.ApplicationStartingEvent 2.ApplicationEnvironmentPrepa…

springboot+mybatis配置多数据源实战

1.背景说明 2.配置多数据源步骤 2.1 项目结构变更 2.2 添加配置类 2.3 修改配置文件数据连接配置信息 1.背景说明一般一个项目中只会连接一个数据库.但是随着需求变更,会要求同一个项目中连接多个数据库,本文就讲一下如何在一个项目中对多…

usaco training刷怪旅 第一层第二题 Greedy Gift Givers

usaco training 关注我持续创作training题解 翻译有点奇葩&#xff0c;我就上原题目了&#xff0c;各位自己翻译吧QwQ A group of NP (2 ≤ NP ≤ 10) uniquely named friends has decided to exchange gifts of money. Each of these friends might or might not give some m…

一种基于PCI总线的反射内存卡设计

一种基于PCI总线的反射内存卡设计 摘要&#xff1a; 对实时传输&#xff0c; 传统的以太网络由于传输协议开销的不确定性&#xff0c; 很难满足实时网络的要求&#xff0c; 实时网络是一种应用于高实时性要求的专用网络通信技术&#xff0c; 一般采用基于高速网络的共享存储器…

Python爬虫实战,requests+openpyxl模块,爬取小说数据并保存txt文档(附源码)

前言 今天给大家介绍的是Python爬取小说数据并保存txt文档&#xff0c;在这里给需要的小伙伴们代码&#xff0c;并且给出一点小心得。 首先是爬取之前应该尽可能伪装成浏览器而不被识别出来是爬虫&#xff0c;基本的是加请求头&#xff0c;但是这样的纯文本数据爬取的人会很多…

web网页设计与开发:基于HTML+CSS+JavaScript简单的个人博客网页制作期末作业

&#x1f389;精彩专栏推荐&#x1f447;&#x1f3fb;&#x1f447;&#x1f3fb;&#x1f447;&#x1f3fb; ✍️ 作者简介: 一个热爱把逻辑思维转变为代码的技术博主 &#x1f482; 作者主页: 【主页——&#x1f680;获取更多优质源码】 &#x1f393; web前端期末大作业…

怎么让文字转换成语音?一步一步让你学会

在日常的生活中&#xff0c;我们经常会需要将文字转换成语音的情况&#xff0c;例如广告词、给文本配音等等&#xff0c;当然我们就简单的方法就是自己手动进行配音&#xff0c;但是如果没有专业的设备和配音环境&#xff0c;是很难配出很好的效果的&#xff0c;这该怎么办呢&a…

飞链云智能机器人-基于ChatGPT的有趣问答

最近ChatGPT火起来了&#xff1b; 可玩性很高&#xff0c;不亚于之前AI绘画的视觉冲击&#xff1b;这次ChatGPT带来的是逻辑冲击&#xff1b;上下文逻辑远超现有市面上其他所有的AI对话机器人&#xff1b; 有人用技巧训练ChatGPT&#xff0c;ChatGPT机器人宣言要毁灭人类&…

备战2023蓝桥国赛-传纸条

题目描述&#xff1a; 解析&#xff1a; 这道题想了我好久&#xff0c;一开始我是想假如只走一条路线&#xff0c;从(1,1)走到&#xff08;m,n&#xff09;&#xff0c;这种问题该怎么解决呢&#xff1f;针对这种问题我是设了dp[k][i][j]表示走了k步到达(i,j)的好心程度之和的…

[附源码]JAVA毕业设计迎宾酒店管理系统录屏(系统+LW)

[附源码]JAVA毕业设计迎宾酒店管理系统录屏&#xff08;系统LW&#xff09; 项目运行 环境项配置&#xff1a; Jdk1.8 Tomcat8.5 Mysql HBuilderX&#xff08;Webstorm也行&#xff09; Eclispe&#xff08;IntelliJ IDEA,Eclispe,MyEclispe,Sts都支持&#xff09;。 项目…