本帖最后由 spi-sd 于 2025-5-12 19:26 编辑
新人自学stm32h750,在网上找了一些教程学习硬解jpg图片,然后发现硬解jpg以后的数据和我预期的不一样,所以想请教一下下面这种解码错误的图一般是哪里出现的问题
下面图片的数据是我dump解码以后的yuv图片的数据,是还没有转换成rgb的数据,上面那张是正常的照片,下面是解码出错的照片(看起来都是在解码为8x8小块的时候就出错了)
解码的流程是首先各种初始化以后,设置好jpg寄存器,然后读取jpg图片到内存,设置好MDMA_Channel7直接将图片的内存地址传递过去开启MDMA中断,然后就不管了,接着等jpg的文件头解析完毕,然后就开始监视JPEG->SR的OFNEF寄存器如果有数据就接收,但是最后接收的数据好像对不怎么对,数据量也少了一半,请问是我哪里的逻辑没对吗?
[C] 纯文本查看 复制代码 if (JPEG->SR & JPEG_SR_OFNEF) {
uint32_t r3 = JPEG->DOR; // 读取32位数据(2个像素)
*argb_dest++ = (r3 >> 16) & 0xFFFF; // 高16位像素
*argb_dest++ = r3 & 0xFFFF; // 低16位像素
output_pixel_count += 2; // 每次读取2个像素
}
[C] 纯文本查看 复制代码 void JPEG_Init_0(void) {
RCC->AHB3ENR |= 1 << 5;
JPEG->CR = 0; /* 先清零 */
JPEG->CR |= 1 << 0; /* 使能硬件JPEG 启用JPEG编解码器核心*/
JPEG->CONFR0 &= ~(1 << 0); /* 停止JPEG编解码进程 */
JPEG->CR |= 1 << 13; /* 清空输入fifo */
JPEG->CR |= 1 << 14; /* 清空输出fifo */
JPEG->CFR = 3 << 5; /* 清空标志 */
JPEG->CONFR1 |= 1 << 8; /* 使能header处理 */
NVIC_SetPriority(JPEG_IRQn, 1); // 设置JPEG中断优先级 (抢占优先级: 1, 子优先级: 0)
// 使能JPEG中断
NVIC_EnableIRQ(JPEG_IRQn);
/////////////////////////////////////////////////
JPEG->CONFR1 |= 1 << 3; /* 硬件JPEG解码模式 */
// JPEG->CR &= ~(0X3F << 1); /* 关闭所有中断 */
JPEG->CR |= 1 << 6; /* 使能Jpeg Header解码完成中断 */
JPEG->CR |= 1 << 5; /* 使能解码完成中断 */
JPEG->CONFR0 |= 1 << 0; /* 使能JPEG编解码进程 启动解码*/
////////////////////////////////////////////////////////
MDMA_Channel7->CCR = 0; /* MDMA通道7禁止 */
MDMA_Channel7->CIFCR = 0X1F; /* 中断标志清零 */
JPEG->CONFR1 |= 1 << 3; /* 硬件JPEG解码模式 */
JPEG->CONFR0 &= ~(1 << 0); /* 停止JPEG编解码进程 */
JPEG->CR &= ~(0X3F << 1); /* 关闭所有中断 */
JPEG->CR |= 1 << 13; /* 清空输入fifo */
JPEG->CR |= 1 << 14; /* 清空输出fifo */
JPEG->CR |= 1 << 6; /* 使能Jpeg Header解码完成中断 */
JPEG->CR |= 1 << 5; /* 使能解码完成中断 */
JPEG->CFR = 3 << 5; /* 清空标志 */
JPEG->CONFR0 |= 1 << 0; /* 使能JPEG编解码进程 */
}
[C] 纯文本查看 复制代码 void jpeg_in_dma_init(uint32_t meminaddr, uint32_t meminsize)
{
uint32_t regval = 0;
uint32_t addrmask = 0;
RCC->AHB3ENR |= 1 << 0; /* 使能MDMA时钟 */
MDMA_Channel7->CCR = 0; /* 输入MDMA清零 */
while (MDMA_Channel7->CCR & 0X01); /* 等待MDMA_Channel7关闭完成 */
MDMA_Channel7->CIFCR = 0X1F; /* 中断标志清零 */
MDMA_Channel7->CCR |= 1 << 2; /* CTCIE=1,使能通道传输完成中断 */
MDMA_Channel7->CCR |= 2 << 6; /* PL[1:0]=2,高优先级 */
MDMA_Channel7->CBNDTR = meminsize; /* 传输长度为meminsize */
MDMA_Channel7->CDAR = (uint32_t)&JPEG->DIR; /* 目标地址为:JPEG->DIR */
MDMA_Channel7->CSAR = meminaddr; /* meminaddr作为源地址 */
regval = 0 << 28; /* TRGM[1:0]=0,每个MDMA请求触发一次buffer传输 */
regval |= 1 << 25; /* PKE=1,打包使能 */
regval |= (32 - 1) << 18; /* TLEN[6:0]=31,buffer传输长度为32字节 */
regval |= 4 << 15; /* DBURST[2:0]=4,目标突发传输长度为16 */
regval |= 4 << 12; /* SBURST[2:0]=4,源突发传输长度为16 */
regval |= 0 << 8; /* SINCOS[1:0]=0,源地址变化单位为8位(字节) */
regval |= 2 << 6; /* DSIZE[1:0]=2,目标位宽为32位 */
regval |= 0 << 4; /* SSIZE[1:0]=0,源位宽为8位 */
regval |= 0 << 2; /* DINC[1:0]=0,目标地址固定 */
regval |= 2 << 0; /* SINC[1:0]=2,源地址自增 */
MDMA_Channel7->CTCR = regval; /* 设置CTCR寄存器 */
MDMA_Channel7->CTBR = 17 << 0; /* MDMA的硬件触发通道17触发inmdma,通道17=JPEG input FIFO threshold
* 详见<STM32H7xx参考手册>577页,table 95
*/
addrmask = meminaddr & 0XFF000000; /* 获取掩码 */
if (addrmask == 0X20000000 || addrmask == 0)MDMA_Channel7->CTBR |= 1 << 16; /* 使用AHBS总线访问DTCM/ITCM */
// 配置NVIC
// 设置MDMA中断优先级 (抢占优先级: 2, 子优先级: 0)
NVIC_SetPriority(MDMA_IRQn, 2);
// 使能MDMA中断
NVIC_EnableIRQ(MDMA_IRQn);
}
|