x265-1.8 编码器主函数分析

本文介绍x265编码器的工作流程,包括解析命令行参数、初始化编码器、设置编码头信息、执行视频编码及关闭编码器等关键步骤。

main ()函数——解析函数参数并进行编码准备工作:x265.cpp
(1)GetConsoleTitle(orgConsoleTitle, CONSOLE_TITLE_SIZE):获取控制台窗口
(2)cliopt.parse()函数:解析参数,直接调用可打印输入视频的详细信息
(3)api->encoder_open()函数:打开编码器配置
(4)api->encoder_headers()函数:设置NAL相关信息
(5)api->encoder_encode()函数:进入编码函数
(6)api->encoder_close()函数:结束编码并进行总结
参考:https://yq.aliyun.com/articles/31058

#include "stm32f10x.h" #include "stm32f10x_rcc.h" #include "stm32f10x_gpio.h" #include "stm32f10x_tim.h" #include "math.h" #define MPI 3.1415926535f // 系统时钟配置 (72MHz) void SystemClock_Config(void) { RCC_DeInit(); RCC_HSEConfig(RCC_HSE_ON); while(RCC_GetFlagStatus(RCC_FLAG_HSERDY) == RESET); RCC_PLLConfig(RCC_PLLSource_HSE_Div1, RCC_PLLMul_9); RCC_PLLCmd(ENABLE); while(RCC_GetFlagStatus(RCC_FLAG_PLLRDY) == RESET); RCC_SYSCLKConfig(RCC_SYSCLKSource_PLLCLK); while(RCC_GetSYSCLKSource() != 0x08); RCC_HCLKConfig(RCC_SYSCLK_Div1); RCC_PCLK1Config(RCC_HCLK_Div2); RCC_PCLK2Config(RCC_HCLK_Div1); SystemCoreClockUpdate(); } // 细分设置 (根据D36A拨码开关实际位置) #define MICROSTEPPING 16 // 可选: 1,2,4,8,16,32 // 步进电机参数 #define STEP_ANGLE 1.8f // 基本步距角(度) #define STEPS_PER_REV 200 // 每转步数 (360/1.8) // 计算实际步距角和每转步数 #define ACTUAL_STEP_ANGLE (STEP_ANGLE / MICROSTEPPING) #define ACTUAL_STEPS_PER_REV (STEPS_PER_REV * MICROSTEPPING) // 机械参数 (根据实际云台结构设置) #define SCREW_LEAD 5.0f // 丝杠导程(mm/转) #define STEPS_PER_MM (ACTUAL_STEPS_PER_REV / SCREW_LEAD) // 引脚定义 #define X_STEP_PIN GPIO_Pin_6 #define X_STEP_PORT GPIOA #define X_DIR_PIN GPIO_Pin_7 #define X_DIR_PORT GPIOA #define X_EN_PIN GPIO_Pin_0 #define X_EN_PORT GPIOB #define Y_STEP_PIN GPIO_Pin_6 #define Y_STEP_PORT GPIOB #define Y_DIR_PIN GPIO_Pin_7 #define Y_DIR_PORT GPIOB #define Y_EN_PIN GPIO_Pin_1 #define Y_EN_PORT GPIOB // 运动控制结构体 typedef struct { volatile int32_t target_steps; // 目标步数 volatile int32_t current_steps; // 当前步数 volatile uint16_t frequency; // 脉冲频率(Hz) volatile uint8_t moving; // 运动标志 TIM_TypeDef* TIMx; // 定时器指针 } StepperAxis; StepperAxis x_axis, y_axis; // 延时函数 void Delay_ms(uint32_t ms) { for(uint32_t i = 0; i < ms * 7200; i++); } // GPIO初始化 void GPIO_Config(void) { GPIO_InitTypeDef GPIO_InitStructure; // 使能GPIO时钟 RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA | RCC_APB2Periph_GPIOB | RCC_APB2Periph_AFIO, ENABLE); // 配置X轴步进引脚为复用推挽输出 GPIO_InitStructure.GPIO_Pin = X_STEP_PIN; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP; GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; GPIO_Init(X_STEP_PORT, &GPIO_InitStructure); // 配置X轴方向和控制引脚为推挽输出 GPIO_InitStructure.GPIO_Pin = X_DIR_PIN; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP; GPIO_Init(X_DIR_PORT, &GPIO_InitStructure); GPIO_InitStructure.GPIO_Pin = X_EN_PIN; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP; GPIO_Init(X_EN_PORT, &GPIO_InitStructure); // 配置Y轴步进引脚为复用推挽输出 GPIO_InitStructure.GPIO_Pin = Y_STEP_PIN; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP; GPIO_Init(Y_STEP_PORT, &GPIO_InitStructure); // 配置Y轴方向和控制引脚为推挽输出 GPIO_InitStructure.GPIO_Pin = Y_DIR_PIN; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP; GPIO_Init(Y_DIR_PORT, &GPIO_InitStructure); GPIO_InitStructure.GPIO_Pin = Y_EN_PIN; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP; GPIO_Init(Y_EN_PORT, &GPIO_InitStructure); // 使能电机 (高电平使能) GPIO_SetBits(X_EN_PORT, X_EN_PIN); GPIO_SetBits(Y_EN_PORT, Y_EN_PIN); } // 定时器配置 void TIM_Config(void) { TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure; TIM_OCInitTypeDef TIM_OCInitStructure; NVIC_InitTypeDef NVIC_InitStructure; // 使能定时器时钟 RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM3 | RCC_APB1Periph_TIM4, ENABLE); // 通用定时器配置 TIM_TimeBaseStructInit(&TIM_TimeBaseStructure); TIM_TimeBaseStructure.TIM_Period = 1000 - 1; TIM_TimeBaseStructure.TIM_Prescaler = 72 - 1; // 1MHz计数频率 TIM_TimeBaseStructure.TIM_ClockDivision = 0; TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up; // 配置X轴定时器 (TIM3) TIM_TimeBaseInit(TIM3, &TIM_TimeBaseStructure); TIM_OCStructInit(&TIM_OCInitStructure); TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM1; TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable; TIM_OCInitStructure.TIM_Pulse = 500; // 50%占空比 TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_High; TIM_OC1Init(TIM3, &TIM_OCInitStructure); TIM_OC1PreloadConfig(TIM3, TIM_OCPreload_Enable); // 配置Y轴定时器 (TIM4) TIM_TimeBaseInit(TIM4, &TIM_TimeBaseStructure); TIM_OC1Init(TIM4, &TIM_OCInitStructure); TIM_OC1PreloadConfig(TIM4, TIM_OCPreload_Enable); // 配置中断 NVIC_InitStructure.NVIC_IRQChannel = TIM3_IRQn; NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0; NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1; NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; NVIC_Init(&NVIC_InitStructure); NVIC_InitStructure.NVIC_IRQChannel = TIM4_IRQn; NVIC_InitStructure.NVIC_IRQChannelSubPriority = 2; NVIC_Init(&NVIC_InitStructure); TIM_ITConfig(TIM3, TIM_IT_Update, ENABLE); TIM_ITConfig(TIM4, TIM_IT_Update, ENABLE); TIM_Cmd(TIM3, DISABLE); TIM_Cmd(TIM4, DISABLE); } // 步进电机控制函数 void Stepper_Move(StepperAxis* axis, int32_t steps, uint16_t freq) { if(steps == 0) return; // 无移动 // 设置方向 if(axis == &x_axis) { GPIO_WriteBit(X_DIR_PORT, X_DIR_PIN, (steps > 0) ? Bit_SET : Bit_RESET); } else { GPIO_WriteBit(Y_DIR_PORT, Y_DIR_PIN, (steps > 0) ? Bit_SET : Bit_RESET); } // 设置运动参数 axis->target_steps = abs(steps); axis->current_steps = 0; axis->frequency = freq; axis->moving = 1; // 计算ARR (ARR = 1e6 / freq - 1) uint32_t arr_val = (1000000 / freq) - 1; if(arr_val < 10) arr_val = 10; // 防止过小 // 使用库函数设置定时器参数 TIM_SetAutoreload(axis->TIMx, arr_val); TIM_SetCounter(axis->TIMx, 0); // 重置计数器 // 启动定时器 TIM_Cmd(axis->TIMx, ENABLE); } // 停止电机 void Stepper_Stop(StepperAxis* axis) { TIM_Cmd(axis->TIMx, DISABLE); axis->moving = 0; axis->target_steps = 0; axis->current_steps = 0; } // 检查是否运动完成 uint8_t Motion_Complete(void) { return (x_axis.moving == 0) && (y_axis.moving == 0); } // 定时器中断处理 void TIM3_IRQHandler(void) { if(TIM_GetITStatus(TIM3, TIM_IT_Update) != RESET) { TIM_ClearITPendingBit(TIM3, TIM_IT_Update); if(x_axis.current_steps < x_axis.target_steps) { x_axis.current_steps++; } else { Stepper_Stop(&x_axis); } } } void TIM4_IRQHandler(void) { if(TIM_GetITStatus(TIM4, TIM_IT_Update) != RESET) { TIM_ClearITPendingBit(TIM4, TIM_IT_Update); if(y_axis.current_steps < y_axis.target_steps) { y_axis.current_steps++; } else { Stepper_Stop(&y_axis); } } } // 画圆函数 void Draw_Circle(float radius_mm, uint16_t speed) { const uint16_t segments = 200; // 圆的分段数 float angle_step = 2.0f * MPI / segments; float last_x = radius_mm, last_y = 0; for(int i = 1; i <= segments; i++) { float angle = i * angle_step; float x = radius_mm * cosf(angle); float y = radius_mm * sinf(angle); // 计算增量 (mm) float dx = x - last_x; float dy = y - last_y; // 转换为步数 (考虑细分) int32_t x_steps = (int32_t)(dx * STEPS_PER_MM); int32_t y_steps = (int32_t)(dy * STEPS_PER_MM); // 启动双轴运动 Stepper_Move(&x_axis, x_steps, speed); Stepper_Move(&y_axis, y_steps, speed); // 等待运动完成 while(!Motion_Complete()); last_x = x; last_y = y; } } // 移动到指定位置 void Move_To_Position(float x_mm, float y_mm, uint16_t speed) { // 转换为步数 int32_t x_steps = (int32_t)(x_mm * STEPS_PER_MM); int32_t y_steps = (int32_t)(y_mm * STEPS_PER_MM); // 启动运动 Stepper_Move(&x_axis, x_steps, speed); Stepper_Move(&y_axis, y_steps, speed); // 等待完成 while(!Motion_Complete()); } //// 主函数 //int main(void) { // // 系统初始化 // SystemClock_Config(); // GPIO_Config(); // TIM_Config(); // // // 初始化轴结构体 // x_axis.TIMx = TIM3; // y_axis.TIMx = TIM4; // x_axis.moving = 0; // y_axis.moving = 0; // // // 设置初始位置 // float current_x = 0, current_y = 0; // // while(1) { // // 示例动作序列 // Move_To_Position(30.0f, 30.0f, 1500); // 移动到(30,30) // Delay_ms(1000); // // Draw_Circle(20.0f, 2000); // 画半径20mm的圆 // Delay_ms(1000); // // Move_To_Position(0.0f, 0.0f, 1500); // 返回原点 // Delay_ms(2000); // } //} #ifdef USE_FULL_ASSERT void assert_failed(uint8_t* file, uint32_t line) { while(1); } #endif 使用库函数,不能直接操作寄存器
最新发布
07-31
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值