基于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

相关文章

用js控制视频播放进度基本示例代码

《用js控制视频播放进度基本示例代码》写前端的时候,很多的时候是需要支持要网页视频播放的功能,下面这篇文章主要给大家介绍了关于用js控制视频播放进度的相关资料,文中通过代码介绍的非常详细,需要的朋友可... 目录前言html部分:JavaScript部分:注意:总结前言在javascript中控制视频播放

Python基于wxPython和FFmpeg开发一个视频标签工具

《Python基于wxPython和FFmpeg开发一个视频标签工具》在当今数字媒体时代,视频内容的管理和标记变得越来越重要,无论是研究人员需要对实验视频进行时间点标记,还是个人用户希望对家庭视频进行... 目录引言1. 应用概述2. 技术栈分析2.1 核心库和模块2.2 wxpython作为GUI选择的优

Python+PyQt5实现多屏幕协同播放功能

《Python+PyQt5实现多屏幕协同播放功能》在现代会议展示、数字广告、展览展示等场景中,多屏幕协同播放已成为刚需,下面我们就来看看如何利用Python和PyQt5开发一套功能强大的跨屏播控系统吧... 目录一、项目概述:突破传统播放限制二、核心技术解析2.1 多屏管理机制2.2 播放引擎设计2.3 专

使用Python实现文本转语音(TTS)并播放音频

《使用Python实现文本转语音(TTS)并播放音频》在开发涉及语音交互或需要语音提示的应用时,文本转语音(TTS)技术是一个非常实用的工具,下面我们来看看如何使用gTTS和playsound库将文本... 目录什么是 gTTS 和 playsound安装依赖库实现步骤 1. 导入库2. 定义文本和语言 3

如何使用C#串口通讯实现数据的发送和接收

《如何使用C#串口通讯实现数据的发送和接收》本文详细介绍了如何使用C#实现基于串口通讯的数据发送和接收,通过SerialPort类,我们可以轻松实现串口通讯,并结合事件机制实现数据的传递和处理,感兴趣... 目录1. 概述2. 关键技术点2.1 SerialPort类2.2 异步接收数据2.3 数据解析2.

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