【国信长天蓝桥杯】CT117E-M4 嵌入式开发板 显示屏播放Bad Apple,采用OLED_ToolBox

摘要

最近在指导学生参见 蓝桥杯 嵌入式比赛,比赛完成后开发板就闲置了,于是准备拿过来做一个好玩的东东。

总体思路是这样的,计算机端通过上位机获取视频信息,并将视频信息转换成显示屏可现实的数据,然后通过串口将数据发送到M4开发板,开发板在串口中断中处理数据,最后将数据显示到屏幕上。

【国信长天蓝桥杯】CT117E-M4 嵌入式开发板 显示屏播放Bad Apple,采用OLED_ToolBox_第1张图片

上位机软件

上位机软件采用的是开源软件 OLED_ToolBox,软件下载地址:
https://shyboy.oss-cn-shenzhen.aliyuncs.com/readonly/OLED_ToolBox.exe

这个软件是开源的,如果有兴趣的话可以研究下源码,源码地址:
https://github.com/AnChangNice/oled_display_gui



软件配置如下:

【国信长天蓝桥杯】CT117E-M4 嵌入式开发板 显示屏播放Bad Apple,采用OLED_ToolBox_第2张图片
波特率建议采用100000,分辨率采用240*160,横向扫描,字节横向排列。

右边选择 Screen模式,在B站搜索 Bad Apple,打开视频,将捕获窗口拖到视频上,调节下窗口大小,刚好包含图像即可。

操作小提示:

  1. 点击 Scan Port 扫描到串口后,一定要在下拉框再次点选对应的串口号才行!
  2. 捕获窗口是一个红色的框框,点击框框上部可进行拖拽移动,移动到合适位置后,一定要再次点击鼠标才能将窗口固定。

单片机代码

单片机软件在 显示屏代码 【HAL_06_LCD】的基础上添加了串口接收功能,波特率1000000,并开启了接收中断,操作步骤如下:

① 添加 stm32g4xx_hal_uart.c , stm32g4xx_hal_uart_ex.c

双击Drivers/STM32G4xx_HAL_Driver,打开添加文件对话框,在向上一级 -> Drivers -> STM32G4xx_HAL_Driver -> Src中,找到stm32g4xx_hal_uart.c , stm32g4xx_hal_uart_ex.c 并添加。添加后如下图所示:
【国信长天蓝桥杯】CT117E-M4 嵌入式开发板 显示屏播放Bad Apple,采用OLED_ToolBox_第3张图片

② 修改 stm32g4xx_hal_conf.h 文件

在如下位置找到该文件,并打开:
【国信长天蓝桥杯】CT117E-M4 嵌入式开发板 显示屏播放Bad Apple,采用OLED_ToolBox_第4张图片
取消注释 #define HAL_UART_MODULE_ENABLED 这一行,取下注释后如下图所示:
【国信长天蓝桥杯】CT117E-M4 嵌入式开发板 显示屏播放Bad Apple,采用OLED_ToolBox_第5张图片

main.c 添加#include "stm32g4xx_hal_uart.h"

main.c 适当位置添加#include "stm32g4xx_hal_uart.h",添加后如下图所示:
【国信长天蓝桥杯】CT117E-M4 嵌入式开发板 显示屏播放Bad Apple,采用OLED_ToolBox_第6张图片

④ 复制如下 TIM 初始化的代码

注意:下列代码包含了UART1的初始化接收中断,同学们可参考自行使用!

UART_HandleTypeDef huart1;
uint8_t uart_rx_buf1[1024 * 6]; //串口接收数据缓冲区1
uint8_t uart_rx_buf2[1024 * 6]; //串口接收数据缓冲区2


// UART1 初始化
static void MX_UART1_Init(void)
{
     
	GPIO_InitTypeDef GPIO_InitStruct = {
     0};
	RCC_PeriphCLKInitTypeDef PeriphClkInit = {
     0};
	
	PeriphClkInit.PeriphClockSelection = RCC_PERIPHCLK_USART1;
	PeriphClkInit.Usart1ClockSelection = RCC_USART1CLKSOURCE_PCLK2;
	HAL_RCCEx_PeriphCLKConfig(&PeriphClkInit); //配置USART1外设的时钟
	
	__HAL_RCC_USART1_CLK_ENABLE(); //打开USART1的时钟
	__HAL_RCC_GPIOA_CLK_ENABLE();
	
	huart1.Instance = USART1;
	huart1.Init.BaudRate = 1000000; //设置波特率
	huart1.Init.WordLength = UART_WORDLENGTH_8B; //设置数据位
	huart1.Init.StopBits = UART_STOPBITS_1; //设置停止位
	huart1.Init.Parity = UART_PARITY_NONE;
	huart1.Init.Mode = UART_MODE_TX_RX;
	huart1.Init.HwFlowCtl = UART_HWCONTROL_NONE;
	huart1.Init.OverSampling = UART_OVERSAMPLING_16;
	huart1.Init.OneBitSampling = UART_ONE_BIT_SAMPLE_DISABLE;
	huart1.Init.ClockPrescaler = UART_PRESCALER_DIV1;
	huart1.AdvancedInit.AdvFeatureInit = UART_ADVFEATURE_NO_INIT;
	
	HAL_MultiProcessor_Init(&huart1, 0, UART_WAKEUPMETHOD_IDLELINE);
	HAL_UARTEx_SetTxFifoThreshold(&huart1, UART_TXFIFO_THRESHOLD_1_8);
	
	HAL_UARTEx_SetRxFifoThreshold(&huart1, UART_RXFIFO_THRESHOLD_1_8);
	HAL_UARTEx_DisableFifoMode(&huart1);
	
	GPIO_InitStruct.Pin = GPIO_PIN_9|GPIO_PIN_10;
	GPIO_InitStruct.Mode = GPIO_MODE_AF_OD; //复用开漏输出
	GPIO_InitStruct.Pull = GPIO_NOPULL;
	GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
	GPIO_InitStruct.Alternate = GPIO_AF7_USART1;//复用功能
	HAL_GPIO_Init(GPIOA, &GPIO_InitStruct); //初始化串口引脚PA9 PA10
	
	HAL_NVIC_SetPriority(USART1_IRQn, 0, 0); //设置串口中断优先级
	HAL_NVIC_EnableIRQ(USART1_IRQn); //打开串口中断
	
	HAL_UART_Receive_IT(&huart1, uart_rx_buf1, 4800); //设置串口中断缓冲区及中断阈值(当前为1)
}

//串口中断
void USART1_IRQHandler(void) //串口中断
{
     
	HAL_UART_IRQHandler(&huart1);
}
int buf = 1; //记录当前使用的是buf1 还是 buf2
int disp = 0; //告诉main该显示什么内容,0不显示,1显示buf1,2显示buf2

//串口中断回调函数
void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart) 
{
     
	if(buf == 1) //若果当前是使用的是buf1
	{
     
		buf = 2; //下次使用buf2
		disp = 1;//告诉main显示buf1的内容到屏幕
		HAL_UART_Receive_IT(&huart1, uart_rx_buf2, 4800);  //切换为buf2
	}
	else
	{
     
		buf = 1; //下次使用buf1
		disp = 2;//告诉main显示buf2的内容到屏幕
		HAL_UART_Receive_IT(&huart1, uart_rx_buf1, 4800);  //切换为buf2
	}
}

⑤ 主函数main()内容

int main(void)
{
     
	HAL_Init();
	
	SystemClock_Config();
	
	MX_GPIO_Init();
	
	MX_UART1_Init();
	
	LCD_Init();
	
	LCD_Clear(Black);
	LCD_SetBackColor(Black);
	LCD_SetTextColor(White);
	

  while (1)
  {
     
		if(disp == 1) 
		{
     
			disp = 0;
			LCD_UartPic(uart_rx_buf1);
		}
		else if(disp == 2)
		{
     
			disp = 0;
			LCD_UartPic(uart_rx_buf2);
		}
  }
}

LCD_UartPic()函数内容如下,次函数应放在lcd.c

void LCD_UartPic(uc8 *c)
{
     
	u32 index = 1, i = 0;
	
	u8 x = 40;
	u16 y = 0;
	
	for(; x < 200; x++)
	{
     
		LCD_SetCursor(x, 280);
		LCD_WriteRAM_Prepare(); /* Prepare to write GRAM */
		for(y = 0; y < 30; y++)
		{
     
			for(i = 0; i < 8; i ++)
			{
     
				if((c[index] & (1 << i)) == 0x00)
				{
     
					LCD_WriteRAM(BackColor);
				}
				else
				{
     
					LCD_WriteRAM(TextColor);
				}
			}
			index ++;
		}
	}
}

运行效果

虽然是彩屏,但是当成黑白屏使用了

【国信长天蓝桥杯】CT117E-M4 嵌入式开发板 显示屏播放Bad Apple,采用OLED_ToolBox_第7张图片

如果你喜欢此文章,欢迎点赞 关注 收藏 转发.

你可能感兴趣的:(蓝桥杯嵌入式大赛,单片机,stm32,BadApple,蓝桥杯,国信长天)