python+keil5实现用oled播放视频

文中需要用到的硬件模块

1.stm32最小系统板

2.下载仿真器带串口的(pwlink2)

3.oled咯

需要用到的软件

1.python(用来做视频处理和串口输出)

2.keil5

3.取模软件

下来就废话少说,直接演示一遍流程

1.打开python,安装opencv,pip install opencv,然后把下面代码输入就能得到视频的每一帧图片了

import cv2
import os

# 打开视频文件
video = cv2.VideoCapture('F:/kun/video/maxin_g.mp4')

# 检查视频是否成功打开
if not video.isOpened():
    print('无法打开视频文件')
    exit()

# 创建保存图片的目录
path = 'F:/kun/video/maxin_g/'
if not os.path.exists(path):
    os.makedirs(path)
    
#调整图片长宽比
new_height = 64
new_width_flag = 0
mask = np.zeros((64,128),np.uint8)
# 初始化帧计数器
frame_count = 1000

while True:
    # 逐帧读取视频
    ret, frame = video.read()
    # 如果视频读取结束,退出循环
    if not ret:
        break
    if new_width_flag == 0:
        height,width=frame.shape[:2]
        new_width = int(width * new_height / height)       
        new_width_flag+=1
    img = cv2.resize(frame,(new_width,new_height))
    img_gray = cv2.cvtColor(img,cv2.COLOR_BGR2GRAY) 
    mask[:64,mid_dst:mid_dst+new_width] = img_gray
    #frame = cv2.resize(mask,(128,64))   #画布大小只能是这个,不然就得改oled显示原理代码 要不就其他地方填黑色 必须得是1024个128*8才能写oled
    # 在帧上添加帧编号
    frame_count += 1
#     text = f'Frame: {frame_count}'
#     frame = cv2.putText(frame, text, (10, 30), cv2.FONT_HERSHEY_SIMPLEX, 1, (255, 255, 255), 2)

    # 将帧保存为图片
    filename = os.path.join(path, f'{frame_count}.jpg')
    cv2.imwrite(filename, mask)

    # 显示当前帧
    cv2.imshow('Frame', mask)

    # 按下 'q' 键退出循环
    if cv2.waitKey(60) & 0xFF == ord('q'):
        break

# 释放资源
video.release()
cv2.destroyAllWindows()

2.打开取模软件image2lcd,批量转换成c格式,如图

3.打开python,粘贴以下代码,改好路径就行,就能合并上面生成的.c文件成.h。

import os

path = 'F:\\kun\\video\\maxin_g\\batch'  # 源文件路径,需要酌情修改

# 获取当前文件夹中的文件名称列表
filenames = os.listdir(path)

# 打开当前目录下的xi.h文件,如果没有则创建
file = open('ma.h', 'w', encoding='utf8')  # 目标文件,合并成的文件

# 遍历文件名
for filename in filenames:
    filepath = path + '\\'
    filepath = filepath + filename
    # 遍历单个文件,读取行数,写入目标文件
    for line in open(filepath, encoding='utf8'):
        file.writelines(line)
    file.write('\n')
# 关闭文件
file.close()

4.打开keil5,配置好oled和串口

main.c

#include "stm32f10x.h"                  // Device header
#include "Delay.h"
#include "OLED.h"
#include "Serial.h"


int main(void)
{
	OLED_Init();//初始化OLED
	Serial_Init();//初始化串口
//	OLED_DisplayTurn(1);  //屏幕反转
//	OLED_ShowString(1, 1,"123456");
	while (1)
	{
		if (Serial_GetRxFlag() == 1)//如果串口收到数据
		{
			//OLED显示图像
			int i=0,j=0;
			OLED_SetCursor(0,0);//设置每帧图像开始打印的位置(光标)
				
			for(i=1023;i>=0;i--)//每帧图像中有用部分为128*64/8=1024字节  i=1023;i>=0;i--  i=0;i<=1023;i++
			{
				OLED_WriteData(Serial_RxPacket[i-6]);//将串口收到的数据传给OLED,请看OLED.c和Serial.c  i-6与图像头有关
				
				if((1024-i)%128==0)//换行1024-i
				{
					j++;
					OLED_SetCursor(j,0);//设定光标的位置到下一行
				}	
			}
			j=0;
		}
	}
}

oled.c

#include "OLED.h"
#include "OLED_Font.h"
#include "Delay.h"

#define	SPI1_SCK_PIN_SET()  	GPIO_SetBits	(GPIOA,GPIO_Pin_5)  //时钟
#define	SPI1_SCK_PIN_CLR()  	GPIO_ResetBits(GPIOA,GPIO_Pin_5)

#define	SPI1_MOSI_SET()  	GPIO_SetBits	(GPIOA,GPIO_Pin_7)  //数据
#define	SPI1_MOSI_CLR()  	GPIO_ResetBits(GPIOA,GPIO_Pin_7)



/*引脚初始化*/
void OLED_SPI_Init(void)
{
	GPIO_InitTypeDef  GPIO_InitStructure;
 	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA|RCC_APB2Periph_AFIO, ENABLE);	 //使能B端口时钟
	GPIO_PinRemapConfig(GPIO_Remap_SWJ_JTAGDisable, ENABLE);
	GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0|GPIO_Pin_1|GPIO_Pin_4 |GPIO_Pin_5|GPIO_Pin_7;	
 	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP; 		 //推挽输出
	GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;//速度50MHz
 	GPIO_Init(GPIOA, &GPIO_InitStructure);	  //
//	GPIO_SetBits(GPIOA,GPIO_Pin_0|GPIO_Pin_1|GPIO_Pin_4|GPIO_Pin_5 |GPIO_Pin_7);	
}
void SPI_WriteByte(u8 Data) //0x__的数据
{
	unsigned char i=0;
	for(i=8;i>0;i--)  //按二进制写入spi的发送缓冲区 例:ff
	{
	  if(Data&0x80)	
		{
			SPI1_MOSI_SET(); 
		}
		else
		{
			SPI1_MOSI_CLR(); 
	  }
    SPI1_SCK_PIN_CLR();     
    SPI1_SCK_PIN_SET();    
    Data<<=1;    
	}
}

void OLED_WR_Byte(uint8_t dat,uint8_t cmd)
{
	if(cmd)
	{
		OLED_DC(1);
	}
	else
	{
		OLED_DC(0);
	}
	OLED_CS(0);
	SPI_WriteByte(dat);
	OLED_CS(1);
	
}

/*******************************************************************
 * @name       :void OLED_Display_On(void)
 * @date       :2022-06-22
 * @function   :打开OLED显示
 * @parameters :无
 * @retvalue   :无
********************************************************************/ 	  
void OLED_Display_On(void)
{
	OLED_WR_Byte(0X8D,0);		//SET DCDC命令
	OLED_WR_Byte(0X14,0);		//DCDC ON
	OLED_WR_Byte(0XAF,0);		//DISPLAY ON
}
/*******************************************************************
 * @name       :void OLED_Reset(void)
 * @date       :2022-06-22
 * @function   :重置OLED屏幕显示
 * @parameters :dat:0-显示全黑
                    1-显示全白
 * @retvalue   :无
********************************************************************/ 
void OLED_Reset(void)
{
	OLED_RES(1);
	Delay_ms(100);
	OLED_RES(0);
	Delay_ms(100);
	OLED_RES(1);
}
/**
  * @brief  OLED写命令
  * @param  Command 要写入的命令
  * @retval 无
  */
void OLED_WriteCommand(uint8_t Command)
{
	OLED_WR_Byte(Command,0); 
}

/**
  * @brief  OLED写数据
  * @param  Data 要写入的数据
  * @retval 无
  */
void OLED_WriteData(uint16_t Data)
{
	OLED_WR_Byte(Data,1);
}


//屏幕旋转180度
void OLED_DisplayTurn(u8 i)
{
	if(i==0)
		{
			OLED_WriteCommand(0xC8);//正常显示
			OLED_WriteCommand(0xA1);
		}
	if(i==1)
		{
			OLED_WriteCommand(0xC0);//反转显示
			OLED_WriteCommand(0xA0);
		}
}

/**
  * @brief  OLED设置光标位置
  * @param  Y 以左上角为原点,向下方向的坐标,范围:0~7
  * @param  X 以左上角为原点,向右方向的坐标,范围:0~127
  * @retval 无
  */
void OLED_SetCursor(uint8_t Y, uint8_t X)
{
	OLED_WriteCommand(0xB0 | Y);					//设置Y位置
	OLED_WriteCommand(0x10 | ((X & 0xF0) >> 4));	//设置X位置高4位
	OLED_WriteCommand(0x00 | (X & 0x0F));			//设置X位置低4位
}

/**
  * @brief  OLED清屏
  * @param  无
  * @retval 无
  */
void OLED_Clear(void)
{  
	uint8_t i, j;
	for (j = 0; j < 8; j++)
	{
		OLED_SetCursor(j, 0);
		for(i = 0; i < 128; i++)
		{
			OLED_WriteData(0x00);
		}
	}
}

/**
  * @brief  OLED显示一个字符
  * @param  Line 行位置,范围:1~4
  * @param  Column 列位置,范围:1~16
  * @param  Char 要显示的一个字符,范围:ASCII可见字符
  * @retval 无
  */
void OLED_ShowChar(uint8_t Line, uint8_t Column, char Char)
{      	
	uint8_t i;
	OLED_SetCursor((Line - 1) * 2, (Column - 1) * 8);		//设置光标位置在上半部分
	for (i = 0; i < 8; i++)
	{
		OLED_WriteData(OLED_F8x16[Char - ' '][i]);			//显示上半部分内容
	}
	OLED_SetCursor((Line - 1) * 2 + 1, (Column - 1) * 8);	//设置光标位置在下半部分
	for (i = 0; i < 8; i++)
	{
		OLED_WriteData(OLED_F8x16[Char - ' '][i + 8]);		//显示下半部分内容
	}
}

/**
  * @brief  OLED显示字符串
  * @param  Line 起始行位置,范围:1~4
  * @param  Column 起始列位置,范围:1~16
  * @param  String 要显示的字符串,范围:ASCII可见字符
  * @retval 无
  */
void OLED_ShowString(uint8_t Line, uint8_t Column, char *String)
{
	uint8_t i;
	for (i = 0; String[i] != '\0'; i++)
	{
		OLED_ShowChar(Line, Column + i, String[i]);
	}
}

/**
  * @brief  OLED次方函数
  * @retval 返回值等于X的Y次方
  */
uint32_t OLED_Pow(uint32_t X, uint32_t Y)
{
	uint32_t Result = 1;
	while (Y--)
	{
		Result *= X;
	}
	return Result;
}

/**
  * @brief  OLED显示数字(十进制,正数)
  * @param  Line 起始行位置,范围:1~4
  * @param  Column 起始列位置,范围:1~16
  * @param  Number 要显示的数字,范围:0~4294967295
  * @param  Length 要显示数字的长度,范围:1~10
  * @retval 无
  */
void OLED_ShowNum(uint8_t Line, uint8_t Column, uint32_t Number, uint8_t Length)
{
	uint8_t i;
	for (i = 0; i < Length; i++)							
	{
		OLED_ShowChar(Line, Column + i, Number / OLED_Pow(10, Length - i - 1) % 10 + '0');
	}
}

/**
  * @brief  OLED显示数字(十进制,带符号数)
  * @param  Line 起始行位置,范围:1~4
  * @param  Column 起始列位置,范围:1~16
  * @param  Number 要显示的数字,范围:-2147483648~2147483647
  * @param  Length 要显示数字的长度,范围:1~10
  * @retval 无
  */
void OLED_ShowSignedNum(uint8_t Line, uint8_t Column, int32_t Number, uint8_t Length)
{
	uint8_t i;
	uint32_t Number1;
	if (Number >= 0)
	{
		OLED_ShowChar(Line, Column, '+');
		Number1 = Number;
	}
	else
	{
		OLED_ShowChar(Line, Column, '-');
		Number1 = -Number;
	}
	for (i = 0; i < Length; i++)							
	{
		OLED_ShowChar(Line, Column + i + 1, Number1 / OLED_Pow(10, Length - i - 1) % 10 + '0');
	}
}

/**
  * @brief  OLED显示数字(十六进制,正数)
  * @param  Line 起始行位置,范围:1~4
  * @param  Column 起始列位置,范围:1~16
  * @param  Number 要显示的数字,范围:0~0xFFFFFFFF
  * @param  Length 要显示数字的长度,范围:1~8
  * @retval 无
  */
void OLED_ShowHexNum(uint8_t Line, uint8_t Column, uint32_t Number, uint8_t Length)
{
	uint8_t i, SingleNumber;
	for (i = 0; i < Length; i++)							
	{
		SingleNumber = Number / OLED_Pow(16, Length - i - 1) % 16;
		if (SingleNumber < 10)
		{
			OLED_ShowChar(Line, Column + i, SingleNumber + '0');
		}
		else
		{
			OLED_ShowChar(Line, Column + i, SingleNumber - 10 + 'A');
		}
	}
}

/**
  * @brief  OLED显示数字(二进制,正数)
  * @param  Line 起始行位置,范围:1~4
  * @param  Column 起始列位置,范围:1~16
  * @param  Number 要显示的数字,范围:0~1111 1111 1111 1111
  * @param  Length 要显示数字的长度,范围:1~16
  * @retval 无
  */
void OLED_ShowBinNum(uint8_t Line, uint8_t Column, uint32_t Number, uint8_t Length)
{
	uint8_t i;
	for (i = 0; i < Length; i++)							
	{
		OLED_ShowChar(Line, Column + i, Number / OLED_Pow(2, Length - i - 1) % 2 + '0');
	}
}

/**
  * @brief  OLED初始化
  * @param  无
  * @retval 无
  */
void OLED_Init(void)
{
	uint32_t i, j;
	OLED_SPI_Init();			//端口初始化
	for (i = 0; i < 1000; i++)			//上电延时
	{
		for (j = 0; j < 1000; j++);
	}
	OLED_RES(1);

	OLED_WriteCommand(0xAE);	//关闭显示
	
	OLED_WriteCommand(0xD5);	//设置显示时钟分频比/振荡器频率
	OLED_WriteCommand(0x80);
	
	OLED_WriteCommand(0xA8);	//设置多路复用率
	OLED_WriteCommand(0x3F);
	
	OLED_WriteCommand(0xD3);	//设置显示偏移
	OLED_WriteCommand(0x00);
	
	OLED_WriteCommand(0x40);	//设置显示开始行
	
	OLED_WriteCommand(0xA0);	//设置左右方向,0xA1正常 0xA0左右反置
	
	OLED_WriteCommand(0xC0);	//设置上下方向,0xC8正常 0xC0上下反置

	OLED_WriteCommand(0xDA);	//设置COM引脚硬件配置
	OLED_WriteCommand(0x12);
	
	OLED_WriteCommand(0x81);	//设置对比度控制
	OLED_WriteCommand(0xCF);

	OLED_WriteCommand(0xD9);	//设置预充电周期
	OLED_WriteCommand(0xF1);

	OLED_WriteCommand(0xDB);	//设置VCOMH取消选择级别
	OLED_WriteCommand(0x30);

	OLED_WriteCommand(0xA4);	//设置整个显示打开/关闭

	OLED_WriteCommand(0xA6);	//设置正常A6/倒转显示A7

	OLED_WriteCommand(0x8D);	//设置充电泵
	OLED_WriteCommand(0x14);

	OLED_WriteCommand(0xAF);	//开启显示
		
	OLED_Clear();				//OLED清屏
}

串口.c

#include "stm32f10x.h"                  // Device header
#include <stdio.h>
#include <stdarg.h>

uint8_t Serial_TxPacket[4];				//FF 01 02 03 04 FE
char Serial_RxPacket[1030];
uint8_t Serial_RxFlag;

void Serial_Init(void)
{
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1, ENABLE);
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);
	
	GPIO_InitTypeDef GPIO_InitStructure;
	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
	GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9;
	GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
	GPIO_Init(GPIOA, &GPIO_InitStructure);
	
	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU;
	GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10;
	GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
	GPIO_Init(GPIOA, &GPIO_InitStructure);
	
	USART_InitTypeDef USART_InitStructure;
	USART_InitStructure.USART_BaudRate = 3000000;
	USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None;
	USART_InitStructure.USART_Mode = USART_Mode_Tx | USART_Mode_Rx;
	USART_InitStructure.USART_Parity = USART_Parity_No;
	USART_InitStructure.USART_StopBits = USART_StopBits_1;
	USART_InitStructure.USART_WordLength = USART_WordLength_8b;
	USART_Init(USART1, &USART_InitStructure);
	
	USART_ITConfig(USART1, USART_IT_RXNE, ENABLE);
	
	NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);
	
	NVIC_InitTypeDef NVIC_InitStructure;
	NVIC_InitStructure.NVIC_IRQChannel = USART1_IRQn;
	NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
	NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1;
	NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1;
	NVIC_Init(&NVIC_InitStructure);
	
	USART_Cmd(USART1, ENABLE);
}

void Serial_SendByte(uint8_t Byte)
{
	USART_SendData(USART1, Byte);
	while (USART_GetFlagStatus(USART1, USART_FLAG_TXE) == RESET);
}

void Serial_SendArray(uint8_t *Array, uint16_t Length)
{
	uint16_t i;
	for (i = 0; i < Length; i ++)
	{
		Serial_SendByte(Array[i]);
	}
}

void Serial_SendString(char *String)
{
	uint8_t i;
	for (i = 0; String[i] != '\0'; i ++)
	{
		Serial_SendByte(String[i]);
	}
}

uint32_t Serial_Pow(uint32_t X, uint32_t Y)
{
	uint32_t Result = 1;
	while (Y --)
	{
		Result *= X;
	}
	return Result;
}

void Serial_SendNumber(uint32_t Number, uint8_t Length)
{
	uint8_t i;
	for (i = 0; i < Length; i ++)
	{
		Serial_SendByte(Number / Serial_Pow(10, Length - i - 1) % 10 + '0');
	}
}

int fputc(int ch, FILE *f)
{
	Serial_SendByte(ch);
	return ch;
}

void Serial_Printf(char *format, ...)
{
	char String[100];
	va_list arg;
	va_start(arg, format);
	vsprintf(String, format, arg);
	va_end(arg);
	Serial_SendString(String);
}


void Serial_SendPacket(void)
{
	Serial_SendByte(0xFF);
	Serial_SendArray(Serial_TxPacket, 4);
	Serial_SendByte(0xFE);
}

uint8_t Serial_GetRxFlag(void)
{
	if (Serial_RxFlag == 1)
	{
		Serial_RxFlag = 0;
		return 1;
	}
	return 0;
}

void USART1_IRQHandler(void)
{
	static uint8_t RxState = 0;
	static uint16_t pRxPacket = 0;
	if (USART_GetITStatus(USART1, USART_IT_RXNE) == SET)
	{
		uint8_t RxData = USART_ReceiveData(USART1);
		
		if (RxState == 0)
		{
			if (RxData == 0xFF)//数据包头
			{
				RxState = 1;
				pRxPacket = 0;
			}
		}
		else if (RxState == 1)//数据
		{
			Serial_RxPacket[pRxPacket] = RxData;
			pRxPacket ++;
			if (pRxPacket >= 1030)//数据字节数
			{
				RxState = 2;
			}
		}
		else if (RxState == 2)
		{
			if (RxData == 0xFE)//数据包尾
			{
				RxState = 0;
				Serial_RxFlag = 1;
			}
		}
		
		USART_ClearITPendingBit(USART1, USART_IT_RXNE);
	}
}

太多了,.h文件自己补一点就行

5.用python通过串口给stm32发送合并好的.h文件,也是简单改一个文件名就可以啦

import time
import serial.tools.list_ports

if __name__ == '__main__':
    # 读取串口列表
    ports_list = list(serial.tools.list_ports.comports())
    if len(ports_list) <= 0:
        print("无串口设备")
    else:
        print("可用的串口设备如下: ")
        print("%-10s %-30s %-10s" % ("num", "name", "number"))
        for i in range(len(ports_list)):
            comport = list(ports_list[i])
            comport_number, comport_name = comport[0], comport[1]
            print("%-10s %-30s %-10s" % (i, comport_name, comport_number))

        # 打开串口
        port_num = ports_list[0][0]
        print("默认选择串口: %s" % port_num)
        # 串口号: port_num, 波特率: 3000000, 数据位: 8, 停止位: 1, 超时时间: 0.5秒
        ser = serial.Serial(port=port_num, baudrate=3000000, bytesize=serial.EIGHTBITS, stopbits=serial.STOPBITS_ONE,
                            timeout=0.5)
        if not ser.isOpen():
            print("打开串口失败")
        else:
            print("打开串口成功, 串口号: %s" % ser.name)

            # 串口发送数据
            f = open('xi.h', 'r', encoding='utf-8')  # 打开hex图片文本文档,图片文本文档由imageLCD生成,由join together.py合并

            j = 0
            t0 = time.time()  # 统计总播放耗时,开始的时间
            while j < 2932:  # 总共播放 2932 帧
                ta = time.time()  # 统计每帧播放时长,开始计时
                dd = ""  # 中间变量
                ff = ""  # 存储每一帧并发给串口
                i = 0

                # 找到每帧数据开始的地方
                while ff != "{":  # 读取hex图片文本文档,见到”{“才继续
                    ff = f.read(1)  # 读下一个字

                # 读取每帧数据,把每帧数据传给 dd
                while i < 1030:  # 每帧数据有 1030 个字节
                    while ff != "X":  # 将图片文本中的 x 作为每个字节数据开始的标志,读到 x 才继续
                        ff = f.read(1)
                    ff = ""  # 清空 ff
                    dd = dd + f.read(2) + " "  # dd 存储每个字节数据
                    i += 1
                print(dd)

                # 通过串口发给单片机
                #         将16进制数转换为 字节
                ser.write(bytes.fromhex("FF"))  # 发送数据包包头 FF
                ser.write(bytes.fromhex(dd))  # 发送数据
                ser.write(bytes.fromhex("FE"))  # 发送包尾

                j += 1
                while time.time() - ta < 1/30:  # 等待,直到帧播放时长为0.03333
                    ""

            t1 = time.time()  # 统计总播放耗时,结束的时间

            f.close()  # 关闭文件

            # 关闭串口
            ser.close()
            if ser.isOpen():
                print("串口未关闭")
            else:
                print("串口已关闭")
                print("耗时:")
                print(t1-t0)

下面是结果:

...

  • 2
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
Git是一个分布式版本控制系统,而Keil是一款嵌入式开发工具。结合使用Git和Keil可以实现对嵌入式项目的版本控制和团队协作。下面是Git和Keil的使用方法: 1. 安装Git和Keil - 首先,你需要安装Git。你可以从官方网站下载并安装Git:https://git-scm.com/downloads - 然后,你需要安装Keil。你可以从Keil官方网站下载并安装Keil:https://www.keil.com/download/ 2. 创建Git仓库 - 在Keil打开你的项目文件夹。 - 在命令行进入到项目文件夹的根目录。 - 使用以下命令初始化Git仓库: ```shell git init ``` 3. 添加和提交文件 - 使用以下命令将所有文件添加到Git仓库: ```shell git add . ``` - 使用以下命令提交文件到Git仓库: ```shell git commit -m "Initial commit" ``` 4. 创建分支和切换分支 - 使用以下命令创建一个新的分支: ```shell git branch <branch_name> ``` - 使用以下命令切换到一个已存在的分支: ```shell git checkout <branch_name> ``` 5. 合并分支 - 使用以下命令切换到主分支: ```shell git checkout master ``` - 使用以下命令将一个分支合并到主分支: ```shell git merge <branch_name> ``` 6. 解决冲突 - 如果在合并分支时发生冲突,你需要手动解决冲突。打开冲突文件,编辑并保存解决冲突后的文件。 - 使用以下命令将解决冲突后的文件标记为已解决: ```shell git add <conflict_file> ``` - 使用以下命令继续合并分支: ```shell git merge --continue ``` 7. 推送和拉取代码 - 使用以下命令将本地代码推送到远程仓库: ```shell git push origin <branch_name> ``` - 使用以下命令从远程仓库拉取最新的代码: ```shell git pull origin <branch_name> ``` 8. 忽略文件 - 在Keil项目文件夹创建一个名为`.gitignore`的文件。 - 在`.gitignore`文件添加需要忽略的文件或文件夹的规则,例如: ``` *.bak *.obj *.o ``` 9. 使用GitHub Desktop - 如果你觉得在命令行使用Git比较麻烦,你可以尝试使用GitHub Desktop。GitHub Desktop是一个图形化的Git客户端,可以简化Git的操作。 - 你可以从GitHub Desktop的官方网站下载并安装:https://desktop.github.com/

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值