在OLED屏上通过串口来显示视频的代码(python+C)
python:
import numpy as np
import cv2
import serial
import time# 将128*64的二值化图像转换为OLED数组格式
def img2array(frame):array = np.zeros((8, 129), dtype='uint8')for j in range(64):for i in range(128):if frame[j][i] > 0:array[j // 8][i] = (array[j // 8][i]) | (0x01 << (j % 8))if (i==127):array[j//8][i] = 255return array# 打开串口
serial_port = serial.Serial('COM3', 9600)# 设置预览窗口
cv2.namedWindow('img', cv2.WINDOW_NORMAL)
cv2.resizeWindow('img', 128 * 4, 64 * 4)# 打开视频
cap = cv2.VideoCapture('C:\\Users\\lin2590\\Desktop\\OLED播放视频\\OLED播放视频\\OLED播放视频\\Python代码\\打篮球.mp4')# 记住开始时间
start_time = time.time()while cap.isOpened():# 获取当前时间对应的帧数run_time = time.time() - start_timefps = cap.get(cv2.CAP_PROP_FPS)frame_number = int(run_time * fps)# 获取当前帧cap.set(cv2.CAP_PROP_POS_FRAMES, frame_number)flag, img = cap.read()if not flag:break# 帧图像处理img = cv2.resize(img, (128, 64)) # 修改尺寸img = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY) # 灰度化img = cv2.threshold(img, 170, 255, cv2.THRESH_BINARY)[1] # 二值化# 预览图像cv2.imshow('img', img)# 转换为数组并使用串口发送img_array = img2array(img)serial_port.write(img_array)# 等待按键,按q键退出key = cv2.waitKey(1)if key & 0xFF == ord('q'):break
# 释放资源
cap.release()
cv2.destroyAllWindows()
serial_port.close()
C:
#include "intrins.h"
#include "reg52.h"
sbit sda = P3^2;
sbit scl = P3^3;
sbit led = P3^1;
sfr AUXR = 0x8E;
void UartInit(void)
{
//9600bps@11.0592MHz
AUXR = 0x01;
SCON = 0x50;
TMOD &= 0x0F;
TMOD |= 0x20;
TH1 = 0xFD;
TL1 = 0xFD;//9600
TR1 = 1;
EA = 1;
ES = 1;
RI = 0;
TI = 0;
}
void IIC_Start()
{
sda = 1;
scl = 1;
_nop_();
sda = 0;
_nop_();
}
void IIC_Stop()
{
sda = 0;
scl = 1;
_nop_();
sda = 1;
_nop_();
}
char IIC_ACK()
{
char flag;
sda = 1;
_nop_();
scl = 1;
_nop_();
flag = sda;
_nop_();
scl = 0;
_nop_();
return flag;
}
void IIC_Send_Byte(char dataSend)
{
int i;
for(i = 0;i<8;i++)
{
scl = 0;//scl,sda
sda = dataSend & 0x80;
_nop_();
scl = 1;
_nop_();
scl = 0;
_nop_();
dataSend = dataSend << 1;
}
}
void Oled_Write_Cmd(char dataCmd)
{
// 1. start()
IIC_Start();
//
// 2. ?????? b0111 1000 0x78
IIC_Send_Byte(0x78);
// 3. ACK
IIC_ACK();
// 4. cotrol byte: (0)(0)000000 ???? (0)(1)000000????
IIC_Send_Byte(0x00);
// 5. ACK
IIC_ACK();
//6. ????/??
IIC_Send_Byte(dataCmd);
//7. ACK
IIC_ACK();
//8. STOP
IIC_Stop();
}
void Oled_Write_Data(char dataData)
{
// 1. start()
IIC_Start();
//
// 2. ?????? b0111 1000 0x78
IIC_Send_Byte(0x78);
// 3. ACK
IIC_ACK();
// 4. cotrol byte: (0)(0)000000 ???? (0)(1)000000????
IIC_Send_Byte(0x40);
// 5. ACK
IIC_ACK();
///6. ????/??
IIC_Send_Byte(dataData);
//7. ACK
IIC_ACK();
//8. STOP
IIC_Stop();
}
void Oled_Init(void)
{
Oled_Write_Cmd(0xAE);//--display off
Oled_Write_Cmd(0x00);//---set low column address
Oled_Write_Cmd(0x10);//---set high column address
Oled_Write_Cmd(0x40);//--set start line address
Oled_Write_Cmd(0xB0);//--set page address
Oled_Write_Cmd(0x81); // contract control
Oled_Write_Cmd(0xFF);//--128
Oled_Write_Cmd(0xA1);//set segment remap
Oled_Write_Cmd(0xA6);//--normal / reverse
Oled_Write_Cmd(0xA8);//--set multiplex ratio(1 to 64)
Oled_Write_Cmd(0x3F);//--1/32 duty
Oled_Write_Cmd(0xC8);//Com scan direction
Oled_Write_Cmd(0xD3);//-set display offset
Oled_Write_Cmd(0x00);//
Oled_Write_Cmd(0xD5);//set osc division
Oled_Write_Cmd(0x80);//
Oled_Write_Cmd(0xD8);//set area color mode off
Oled_Write_Cmd(0x05);//
Oled_Write_Cmd(0xD9);//Set Pre-Charge Period
Oled_Write_Cmd(0xF1);//
Oled_Write_Cmd(0xDA);//set com pin configuartion
Oled_Write_Cmd(0x12);//
Oled_Write_Cmd(0xDB);//set Vcomh
Oled_Write_Cmd(0x30);//
Oled_Write_Cmd(0x8D);//set charge pump enable
Oled_Write_Cmd(0x14);//
Oled_Write_Cmd(0xAF);//--turn on oled panel
}
void Oled_Clear()
{
unsigned char i,j; //-128 --- 127
for(i=0;i<8;i++)
{
Oled_Write_Cmd(0xB0 + i);
//page0--page7
//??page?0?
Oled_Write_Cmd(0x00);
Oled_Write_Cmd(0x10);
for(j = 0;j<128;j++)
{
Oled_Write_Data(0);
}
}
}
void main()
{
unsigned char buffer;
int i = 0;
led = 1;
UartInit();
Oled_Init();
Oled_Clear();
Oled_Write_Cmd(0x20);
Oled_Write_Cmd(0x02);
while (1)
{
while(!RI);
buffer = SBUF;
led = !led;
RI = 0;
if (i%128 == 0)
{
Oled_Write_Cmd(0xB0 + i/128);
Oled_Write_Cmd(0x00);
Oled_Write_Cmd(0x10);
}
i++;
Oled_Write_Data(buffer);
if (i == 1024)
{
i = 0;
}
}
}