文章目录
- 1、PWM 绝对值位置读取功能
- 1.1 DataSheet说明
- 1.2 硬件支持
- 1.3 Cubemax配置及使用
- 1.4 项目代码实现
- 1.5 效果验证
- 1.6 注意事项
- 2、SPI 绝对值位置读取功能
- 2.2 硬件支持
- 2.3 Cubemax配置及使用
- 2.4 项目代码实现
1、PWM 绝对值位置读取功能
1.1 DataSheet说明
1.2 硬件支持
1.3 Cubemax配置及使用
1.4 项目代码实现
PWM输入捕获定时器初始化:
void MX_TIM4_Init(void)
{/* USER CODE BEGIN TIM4_Init 0 *//* USER CODE END TIM4_Init 0 */TIM_ClockConfigTypeDef sClockSourceConfig = {0};TIM_SlaveConfigTypeDef sSlaveConfig = {0};TIM_IC_InitTypeDef sConfigIC = {0};TIM_MasterConfigTypeDef sMasterConfig = {0};/* USER CODE BEGIN TIM4_Init 1 *//* USER CODE END TIM4_Init 1 */htim4.Instance = TIM4;htim4.Init.Prescaler = 83;htim4.Init.CounterMode = TIM_COUNTERMODE_UP;htim4.Init.Period = 0xFFFF;htim4.Init.ClockDivision = TIM_CLOCKDIVISION_DIV1;htim4.Init.AutoReloadPreload = TIM_AUTORELOAD_PRELOAD_DISABLE;if (HAL_TIM_Base_Init(&htim4) != HAL_OK){Error_Handler();}sClockSourceConfig.ClockSource = TIM_CLOCKSOURCE_INTERNAL;if (HAL_TIM_ConfigClockSource(&htim4, &sClockSourceConfig) != HAL_OK){Error_Handler();}if (HAL_TIM_IC_Init(&htim4) != HAL_OK){Error_Handler();}sSlaveConfig.SlaveMode = TIM_SLAVEMODE_RESET;sSlaveConfig.InputTrigger = TIM_TS_TI2FP2;sSlaveConfig.TriggerPolarity = TIM_INPUTCHANNELPOLARITY_RISING;sSlaveConfig.TriggerPrescaler = TIM_ICPSC_DIV1;sSlaveConfig.TriggerFilter = 0xA;if (HAL_TIM_SlaveConfigSynchro(&htim4, &sSlaveConfig) != HAL_OK){Error_Handler();}sConfigIC.ICPolarity = TIM_INPUTCHANNELPOLARITY_FALLING;sConfigIC.ICSelection = TIM_ICSELECTION_INDIRECTTI;sConfigIC.ICPrescaler = TIM_ICPSC_DIV1;sConfigIC.ICFilter = 0xA;if (HAL_TIM_IC_ConfigChannel(&htim4, &sConfigIC, TIM_CHANNEL_1) != HAL_OK){Error_Handler();}sConfigIC.ICPolarity = TIM_INPUTCHANNELPOLARITY_RISING;sConfigIC.ICSelection = TIM_ICSELECTION_DIRECTTI;if (HAL_TIM_IC_ConfigChannel(&htim4, &sConfigIC, TIM_CHANNEL_2) != HAL_OK){Error_Handler();}sMasterConfig.MasterOutputTrigger = TIM_TRGO_RESET;sMasterConfig.MasterSlaveMode = TIM_MASTERSLAVEMODE_DISABLE;if (HAL_TIMEx_MasterConfigSynchronization(&htim4, &sMasterConfig) != HAL_OK){Error_Handler();}/* USER CODE BEGIN TIM4_Init 2 *//* USER CODE END TIM4_Init 2 */}
编码器初始化函数:
/*** @brief * @param void* @retval void*/
void Bsp_Encoder_Init(void)
{if(sensor_peripheral.AuxEncoder_Sensor.encType==ENCODER_TYPE_MT_PWM_Abs){MX_TIM4_Init();HAL_TIM_IC_Start_IT (&htim4, TIM_CHANNEL_1);HAL_TIM_IC_Start_IT (&htim4, TIM_CHANNEL_2); ENC_485_RX_EN; }MX_TIM3_Init(); //ENCHAL_TIM_Encoder_Start_IT(&htim3, TIM_CHANNEL_ALL);
}
输入捕获中断回调:
/*** @brief Input Capture callback in non-blocking mode* @param htim TIM IC handle* @retval None*/
#define TIM_ENCODER_PWM TIM4
void HAL_TIM_IC_CaptureCallback(TIM_HandleTypeDef *htim)
{if(htim->Instance == TIM_ENCODER_PWM) //{Encoder_MT_PWM_Readout();}
}
输入捕获中断处理函数:
void Encoder_MT_PWM_Readout(void)
{if (htim4.Channel == HAL_TIM_ACTIVE_CHANNEL_2){enc_mt_pwm_input.freqTemp[0]=HAL_TIM_ReadCapturedValue(&htim4, TIM_CHANNEL_2)+1; // 1.读取整周期时间enc_mt_pwm_input.dutyTemp[0]=HAL_TIM_ReadCapturedValue(&htim4, TIM_CHANNEL_1)+1; // 2.读取高电平时间__HAL_TIM_SetCounter(&htim4, 0); }
}
角度读取函数(包含数据处理):
uint16_t Bsp_get_PWM_angle(void)
{enc_mt_pwm_input.usPwmAngReadFlag = 1;enc_mt_pwm_input.freq=enc_mt_pwm_input.freqTemp[0];enc_mt_pwm_input.duty=enc_mt_pwm_input.dutyTemp[0];if(enc_mt_pwm_input.dir){if(enc_mt_pwm_input.duty>=enc_mt_pwm_input.freq)enc_mt_pwm_input.duty=enc_mt_pwm_input.freq;elseenc_mt_pwm_input.duty=enc_mt_pwm_input.freq-enc_mt_pwm_input.duty; //get negation}enc_mt_pwm_input.factor=enc_mt_pwm_input.freq/enc_mt_pwm_input.div; //Acquire resolutionenc_mt_pwm_input.res=enc_mt_pwm_input.freq-(enc_mt_pwm_input.offset_h+enc_mt_pwm_input.offset_l)*enc_mt_pwm_input.factor;if(enc_mt_pwm_input.duty>=enc_mt_pwm_input.factor * enc_mt_pwm_input.offset_h)enc_mt_pwm_input.angle_temp=enc_mt_pwm_input.duty - enc_mt_pwm_input.factor * enc_mt_pwm_input.offset_h; //get angleelseenc_mt_pwm_input.angle_temp=0;enc_mt_pwm_input.angle=enc_mt_pwm_input.angle_temp*(4095/(enc_mt_pwm_input.res*(84/(ENC_PWM_INPUT_PRE+1)))); /* get value from 0 to 4095 */return enc_mt_pwm_input.angle;
}
结构体定义及初始化:
#define SAMPLE_NUM 1 /* Number of samples */
typedef struct
{uint8_t sample_count; /* counts of samples */uint16_t freqTemp[SAMPLE_NUM]; /* Acquisition frequency */float freq; /* frequency */uint16_t dutyTemp[SAMPLE_NUM]; /* Capture high level */float duty; /* duty */uint8_t dir;uint8_t offset_h; //16 high uint8_t offset_l; //8 low uint16_t div; //4095+16+8=4119float factor; float res; /* Resolution */float angle_temp; uint16_t angle; uint8_t usPwmAngReadFlag;
}enc_mt_pwm_input_t;extern enc_mt_pwm_input_t enc_mt_pwm_input;/************************************************************************************/
enc_mt_pwm_input_t enc_mt_pwm_input={.sample_count=0,.freqTemp={0},.freq=0,.dutyTemp={0},.duty=0,.dir=1,.offset_h=16,.offset_l=8,.div=4119,.factor=0,.res=0,.angle=0,.usPwmAngReadFlag = 0
};
1.5 效果验证
角度(占空比)周期化变化,满足预期。
1.6 注意事项
2、SPI 绝对值位置读取功能
2.2 硬件支持
MT6825编码器电路
驱动板电路
2.3 Cubemax配置及使用
2.4 项目代码实现
SPI外设初始化:
/* SPI1 init function */
void MX_SPI1_Init(void)
{/* USER CODE BEGIN SPI1_Init 0 *//* USER CODE END SPI1_Init 0 *//* USER CODE BEGIN SPI1_Init 1 *//* USER CODE END SPI1_Init 1 */hspi1.Instance = SPI1;hspi1.Init.Mode = SPI_MODE_MASTER;hspi1.Init.Direction = SPI_DIRECTION_2LINES;hspi1.Init.DataSize = SPI_DATASIZE_16BIT;hspi1.Init.CLKPolarity = SPI_POLARITY_HIGH;hspi1.Init.CLKPhase = SPI_PHASE_2EDGE;hspi1.Init.NSS = SPI_NSS_SOFT;hspi1.Init.BaudRatePrescaler = SPI_BAUDRATEPRESCALER_64; //8 10.5Mbit/s 64 1.3125Mbits 16 5.25Mbit/shspi1.Init.FirstBit = SPI_FIRSTBIT_MSB;hspi1.Init.TIMode = SPI_TIMODE_DISABLE;hspi1.Init.CRCCalculation = SPI_CRCCALCULATION_DISABLE;hspi1.Init.CRCPolynomial = 10;if (HAL_SPI_Init(&hspi1) != HAL_OK){Error_Handler();}/* USER CODE BEGIN SPI1_Init 2 *//* USER CODE END SPI1_Init 2 */}
结构体及初始化:
typedef struct{uint16_t cmd[3];uint16_t rec_data[3];uint8_t no_mag_warning_flag;uint8_t over_speed_flag;uint8_t pc1_flag;uint8_t pc2_flag;uint8_t pc1_count;uint8_t pc2_count;uint8_t err;uint32_t sample_data;uint32_t angle_data;uint32_t pre_angle_data;
}mag_enc_t;extern mag_enc_t mag_enc;/**********************************************************/
mag_enc_t mag_enc = {.cmd = {0x8300, 0x8400, 0x8500},.rec_data = {0, 0, 0},.no_mag_warning_flag = 0,.over_speed_flag = 0,.pc1_flag = 0,.pc2_flag = 0,.pc1_count = 0,.pc2_count = 0,.err = 0,.sample_data = 0,.angle_data =0,.pre_angle_data =0
};
SPI读取绝对值位置:
uint32_t SPI1_MT6825_fast_ReadData(void)
{short timeOut=1000;SPI1_CS_LOW;
// HAL_SPI_Transmit(&hspi1 ,(unsigned char *)&mag_enc.cmd[0] ,1,200);
// HAL_SPI_Receive(&hspi1 ,(unsigned char *)&mag_enc.rec_data[0] ,3,200);HAL_SPI_TransmitReceive(&hspi1 ,(unsigned char *)&mag_enc.cmd[0] ,(unsigned char *)&mag_enc.rec_data[0] ,3,200 );while( hspi1.State == HAL_SPI_STATE_BUSY ){if (timeOut-- ==0) return 0;} // wait for transmission completeSPI1_CS_HIGH;mag_enc.angle_data=((mag_enc.rec_data[0]&0x00FF)<<10)+((mag_enc.rec_data[1]&0xFC00)>>6)+((mag_enc.rec_data[1]&0x00F0)>>4);return mag_enc.angle_data;
}