基于STM32F4xx利用串口播放视频(OLED)

2023-10-14 09:59

本文主要是介绍基于STM32F4xx利用串口播放视频(OLED),希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

效果视频 : 基于STM32F11的1.3寸OLED屏_驱动芯片SH1106_哔哩哔哩_bilibili

该屏幕用硬件SPI进行驱动的。买屏幕时商家都会提供驱动源码,显示文字,数字等的应该都没问题。我这次主要讲如何显示视频,我的图片显示和文字数字显示是自己写的(也可以私信我获取,但是显示速度没源码快)。

stm32单片机内存不够大,一个视频可能就几M了,完全放不下。视频其实也就一帧一帧照片组合而成,我们会了一张图片的显示也就会了视频的播放了(循环发送图片信息再刷新屏幕显示)。

接下来 我会把视频播放的步骤说一遍 (工具可以到下面网盘链接下载)

第一步骤:视频的图片捕获

        随便下载一个比较长时间的gif 把它后缀改成.mp4用KMPlayer.exe打开

        打开后如下右键屏幕 高级捕获

 

先暂停视频,再点击上图开始按钮,然后点击播放视频。你会发现在你上面的文件夹下面出现一堆bmp图片。

 第二步骤:把bmp图片转换成单片机需要的格式

        打开这个工具Img2Lcd.exe  配置弄成下图

        

 再打开第一张bmp

批量转换

选择是       随后就生产很多.ebm文件

这一步就是生成每个图片的ebm格式的内容了,你可以直接用串口发送这个文件  此时屏幕显示的图片就发生变化了。当然前提是你已经把串口接收写好,我用了dma 接收一张图片信息(大概1000多个字节)到了再中断。

所以单片机DMA中断然后就可以显示一张图片了。

为了连续发送所有的ebm文件我用了python 把文件结合一起,上图end.ebm就是python生成的文件。  下面是python的代码 需要下载python编译器不然运行不起来。

import time
import serial
import osdef gain_datas_true():meragefiledir = "C:/KMPlayer/Capture/1/batch"  #文件路径docList = os.listdir(meragefiledir)  # 将文件下的 文件名存入到 list 中docList.sort()  # 对文件名进行排序print(docList)fname = open("C:/KMPlayer/Capture/1/batch/end.ebm", "wb")  # 打开end.ebm文件 没有自动创建for i in docList:x = open('C:/KMPlayer/Capture/1/batch/' + i, "rb")  # 打开列表中的文件,读取文件内容fname.write(x.read())  # 写入新建的fname文件中x.close()fname.close()def main():gain_datas_true()if __name__ == '__main__':main()

生成后就完成了,然后直接串口发送就好了,下面是单片机的串口与DMA代码。标准库函数开发

usart.c

#include "usart.h"
#include <stdio.h>//------------------------------------------------修改以下宏定义可以配置相应的串口初始化----------------------------------------------------
#define USART_TX GPIO_Pin_9	//串口GPIO发送端口
#define USART_RX GPIO_Pin_10	//串口GPIO接收端口#define USART_GPIO_TypeDef GPIOA	//串口对应的GPIO位置#define USART_Pin_TX GPIO_PinSource9	//串口映射发送的GPIO
#define USART_Pin_RX GPIO_PinSource10 //串口映射读取的GPIO#define USART_RCC RCC_APB2Periph_USART1	// 注意串口1/6 是APB2总线  其它是APB1总线
#define USART_GPIO_RCC RCC_AHB1Periph_GPIOA //串口对应的GPIO总线#define USART_IRQ USART1_IRQn //串口 中断号
#define USART USART1	//串口号
//------------------------------------------------修改以上宏定义可以配置相应的串口初始化----------------------------------------------------
/*
函数功能:初始化串口1
函数参数:uint32_t USART_BaudRate 
函数返回值:无 
函数描述:无
*/
void Usart1_Init(uint32_t USART_BaudRate)
{GPIO_InitTypeDef GPIO_InitStruct;    //串口GPIO结构体定义USART_InitTypeDef USART_InitStruct; //串口结构体定义RCC_APB2PeriphClockCmd(USART_RCC,ENABLE);	//使能串口外设的线   注意串口1/6 是APB2总线  其它是APB1总线RCC_AHB1PeriphClockCmd(USART_GPIO_RCC,ENABLE);	//使能串口对应的GPIO线GPIO_PinAFConfig(USART_GPIO_TypeDef,USART_Pin_TX,GPIO_AF_USART1);	//串口发送复用映射GPIO_PinAFConfig(USART_GPIO_TypeDef,USART_Pin_RX,GPIO_AF_USART1);	//串口接收复用映射GPIO_InitStruct.GPIO_Mode = GPIO_Mode_AF;GPIO_InitStruct.GPIO_OType = GPIO_OType_PP;GPIO_InitStruct.GPIO_Pin = USART_TX | USART_RX;GPIO_InitStruct.GPIO_PuPd = GPIO_PuPd_NOPULL;GPIO_InitStruct.GPIO_Speed = GPIO_Speed_100MHz;GPIO_Init(USART_GPIO_TypeDef,&GPIO_InitStruct);	//串口 发送/接受端口初始化USART_InitStruct.USART_BaudRate = USART_BaudRate;USART_InitStruct.USART_HardwareFlowControl = USART_HardwareFlowControl_None;USART_InitStruct.USART_Mode = USART_Mode_Rx | USART_Mode_Tx;USART_InitStruct.USART_Parity = USART_Parity_No;USART_InitStruct.USART_StopBits = USART_StopBits_1;USART_InitStruct.USART_WordLength = USART_WordLength_8b;USART_Init(USART,&USART_InitStruct); //串口初始化USART_ReceiveData(USART);	//初始化时候读取一次避免 一开始就有中断USART_DMACmd(USART,USART_DMAReq_Rx,ENABLE); //读取中断配置USART_Cmd(USART,ENABLE);
}/*
函数功能:printf函数重定向
函数参数:无
函数返回值:无 
函数描述:无
*/
int fputc(int ch, FILE * f)
{USART->DR = (unsigned char)ch; //USART是上面宏定义的 哪个串口初始化就打印那个串口while((USART->SR & 0x80) == 0);	return ch;
}
//------------------------------------------------某个串口初始化和打印完成----------------------------------------------------

usart.h

#ifndef _USART_H_
#define _USART_H_#include "stm32f4xx.h"void Usart1_Init(uint32_t USART_BaudRate);#endif

dma.c

#include "dma.h"/*
函数功能:DMA2初始化
函数参数:无
函数返回值:无
函数描述:DMA2 通道4 不用缓冲FIFO
*/
void Dma2Init(uint32_t DMA_Memory0BaseAddr,uint32_t DMA_PeripheralBaseAddr,uint32_t DMA_BufferSize)
{NVIC_InitTypeDef NVIC_InitStruct;	//总中断结构体定义DMA_InitTypeDef DMA_InitStruct;RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_DMA2,ENABLE);DMA_InitStruct.DMA_BufferSize = DMA_BufferSize;DMA_InitStruct.DMA_Channel = DMA_Channel_4;DMA_InitStruct.DMA_DIR = DMA_DIR_PeripheralToMemory;DMA_InitStruct.DMA_FIFOMode = DMA_FIFOMode_Disable;DMA_InitStruct.DMA_FIFOThreshold = DMA_FIFOThreshold_1QuarterFull;DMA_InitStruct.DMA_Memory0BaseAddr = DMA_Memory0BaseAddr;DMA_InitStruct.DMA_MemoryBurst = DMA_MemoryBurst_Single;DMA_InitStruct.DMA_MemoryDataSize = DMA_MemoryDataSize_Byte;DMA_InitStruct.DMA_MemoryInc = DMA_MemoryInc_Enable;DMA_InitStruct.DMA_Mode = DMA_Mode_Circular;DMA_InitStruct.DMA_PeripheralBaseAddr = DMA_PeripheralBaseAddr;DMA_InitStruct.DMA_PeripheralBurst = DMA_PeripheralBurst_Single;DMA_InitStruct.DMA_PeripheralDataSize = DMA_PeripheralDataSize_Byte;DMA_InitStruct.DMA_PeripheralInc = DMA_PeripheralInc_Disable;DMA_InitStruct.DMA_Priority = DMA_Priority_VeryHigh;DMA_Init(DMA2_Stream2,&DMA_InitStruct);DMA_ITConfig(DMA2_Stream2,DMA_IT_TC,ENABLE);NVIC_InitStruct.NVIC_IRQChannel = DMA2_Stream2_IRQn;NVIC_InitStruct.NVIC_IRQChannelCmd = ENABLE;NVIC_InitStruct.NVIC_IRQChannelPreemptionPriority = 1;NVIC_InitStruct.NVIC_IRQChannelSubPriority = 1;NVIC_Init(&NVIC_InitStruct);	//DMA总中断初始化DMA_Cmd(DMA2_Stream2,ENABLE);
}

dma.h

#ifndef _DMA_H_
#define _DMA_H_#include "stm32f4xx.h"void Dma2Init(uint32_t DMA_Memory0BaseAddr,uint32_t DMA_PeripheralBaseAddr,uint32_t DMA_BufferSize);#endif

主函数中你需要 以下函数

unsigned char UsartData[1056];

NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);                                     //中断优先级配置

Usart1_Init(115200);                                                                                      //串口初始化
Dma2Init((uint32_t)&UsartData[0],(uint32_t)&(USART1->DR),1056);   //串口使用DMA   

while循环里面如下

if(UsartFlagAchieve)                  //串口数据接收完成                                
    {
        Dis_Piture_Serial(UsartData);   //屏幕显示一张图片的
        UsartFlagAchieve = 0;                //接收完标志位置0 
    }         

现在是利用电脑端存数据 后续开发可以利用片外存储器。

最后最后确保一点 ,就是ebm文件通过串口发送过去必须要显示到完整的图片,不然ebm里面的数据格式不对,你连起来的数据格式也是不可以的。

由于每个人用到OLED屏幕不一样 我用的是1.3寸OLED屏_驱动芯片SH1106 

如果你用的是也是这种显示照片可以私信我哟。

链接:https://pan.baidu.com/s/1WH4T9Tgl1tpDGHDmD5QDBw 
提取码:0225 
--来自百度网盘超级会员V2的分享

这篇关于基于STM32F4xx利用串口播放视频(OLED)的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/209768

相关文章

Java如何获取视频文件的视频时长

《Java如何获取视频文件的视频时长》文章介绍了如何使用Java获取视频文件的视频时长,包括导入maven依赖和代码案例,同时,也讨论了在运行过程中遇到的SLF4J加载问题,并给出了解决方案... 目录Java获取视频文件的视频时长1、导入maven依赖2、代码案例3、SLF4J: Failed to lo

Python实现多路视频多窗口播放功能

《Python实现多路视频多窗口播放功能》这篇文章主要为大家详细介绍了Python实现多路视频多窗口播放功能的相关知识,文中的示例代码讲解详细,有需要的小伙伴可以跟随小编一起学习一下... 目录一、python实现多路视频播放功能二、代码实现三、打包代码实现总结一、python实现多路视频播放功能服务端开

Python实现视频转换为音频的方法详解

《Python实现视频转换为音频的方法详解》这篇文章主要为大家详细Python如何将视频转换为音频并将音频文件保存到特定文件夹下,文中的示例代码讲解详细,感兴趣的小伙伴可以跟随小编一起学习一下... 目录1. python需求的任务2. Python代码的实现3. 代码修改的位置4. 运行结果5. 注意事项

Python视频处理库VidGear使用小结

《Python视频处理库VidGear使用小结》VidGear是一个高性能的Python视频处理库,本文主要介绍了Python视频处理库VidGear使用小结,文中通过示例代码介绍的非常详细,对大家的... 目录一、VidGear的安装二、VidGear的主要功能三、VidGear的使用示例四、VidGea

流媒体平台/视频监控/安防视频汇聚EasyCVR播放暂停后视频画面黑屏是什么原因?

视频智能分析/视频监控/安防监控综合管理系统EasyCVR视频汇聚融合平台,是TSINGSEE青犀视频垂直深耕音视频流媒体技术、AI智能技术领域的杰出成果。该平台以其强大的视频处理、汇聚与融合能力,在构建全栈视频监控系统中展现出了独特的优势。视频监控管理系统EasyCVR平台内置了强大的视频解码、转码、压缩等技术,能够处理多种视频流格式,并以多种格式(RTMP、RTSP、HTTP-FLV、WebS

综合安防管理平台LntonAIServer视频监控汇聚抖动检测算法优势

LntonAIServer视频质量诊断功能中的抖动检测是一个专门针对视频稳定性进行分析的功能。抖动通常是指视频帧之间的不必要运动,这种运动可能是由于摄像机的移动、传输中的错误或编解码问题导致的。抖动检测对于确保视频内容的平滑性和观看体验至关重要。 优势 1. 提高图像质量 - 清晰度提升:减少抖动,提高图像的清晰度和细节表现力,使得监控画面更加真实可信。 - 细节增强:在低光条件下,抖

Android平台播放RTSP流的几种方案探究(VLC VS ExoPlayer VS SmartPlayer)

技术背景 好多开发者需要遴选Android平台RTSP直播播放器的时候,不知道如何选的好,本文针对常用的方案,做个大概的说明: 1. 使用VLC for Android VLC Media Player(VLC多媒体播放器),最初命名为VideoLAN客户端,是VideoLAN品牌产品,是VideoLAN计划的多媒体播放器。它支持众多音频与视频解码器及文件格式,并支持DVD影音光盘,VCD影

《x86汇编语言:从实模式到保护模式》视频来了

《x86汇编语言:从实模式到保护模式》视频来了 很多朋友留言,说我的专栏《x86汇编语言:从实模式到保护模式》写得很详细,还有的朋友希望我能写得更细,最好是覆盖全书的所有章节。 毕竟我不是作者,只有作者的解读才是最权威的。 当初我学习这本书的时候,只能靠自己摸索,网上搜不到什么好资源。 如果你正在学这本书或者汇编语言,那你有福气了。 本书作者李忠老师,以此书为蓝本,录制了全套视频。 试

SAM2POINT:以zero-shot且快速的方式将任何 3D 视频分割为视频

摘要 我们介绍 SAM2POINT,这是一种采用 Segment Anything Model 2 (SAM 2) 进行零样本和快速 3D 分割的初步探索。 SAM2POINT 将任何 3D 数据解释为一系列多向视频,并利用 SAM 2 进行 3D 空间分割,无需进一步训练或 2D-3D 投影。 我们的框架支持各种提示类型,包括 3D 点、框和掩模,并且可以泛化到不同的场景,例如 3D 对象、室

树莓派5_opencv笔记27:Opencv录制视频(无声音)

今日继续学习树莓派5 8G:(Raspberry Pi,简称RPi或RasPi)  本人所用树莓派5 装载的系统与版本如下:  版本可用命令 (lsb_release -a) 查询: Opencv 与 python 版本如下: 今天就水一篇文章,用树莓派摄像头,Opencv录制一段视频保存在指定目录... 文章提供测试代码讲解,整体代码贴出、测试效果图 目录 阶段一:录制一段