正交编码器测速
更新时间:2024-03-28 11:33:01 阅读量: 综合文库 文档下载
/******************** (C) COPYRIGHT 2007 STMicroelectronics ******************** * File Name : stm32f10x_encoder.c * Author : IMS Systems Lab * Date First Issued : 21/11/07
* Description : This file contains the software implementation for the * encoder unit
********************************************************************************
* History:
* 21/11/07 v1.0
********************************************************************************
* THE PRESENT SOFTWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS * WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE TIME.
* AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY DIRECT,
* INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING FROM THE * CONTENT OF SUCH SOFTWARE AND/OR THE USE MADE BY CUSTOMERS OF THE CODING * INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS.
*******************************************************************************/
/* Includes ------------------------------------------------------------------*/ //#include
/* Private variables ---------------------------------------------------------*/
s16 hPrevious_angle, hSpeed_Buffer[SPEED_BUFFER_SIZE], hRot_Speed; //static s16 hPrevious_angle, hSpeed_Buffer[SPEED_BUFFER_SIZE]; static u8 bSpeed_Buffer_Index = 0;
static volatile u16 hEncoder_Timer_Overflow;
#define TRUE 1 #define FALSE 0
static unsigned char bIs_First_Measurement = TRUE;
/*******************************************************************************
* Function Name : ENC_Init
* Description : General Purpose Timer x set-up for encoder speed/position * sensors * Input : None
* Output : None * Return : None
*******************************************************************************/
void ENC_Init(void) {
TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure; TIM_ICInitTypeDef TIM_ICInitStructure;
/* Encoder unit connected to TIM3, 4X mode */ GPIO_InitTypeDef GPIO_InitStructure; NVIC_InitTypeDef NVIC_InitStructure;
/* TIM3 clock source enable */
RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM3, ENABLE); /* Enable GPIOA, clock */
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);
GPIO_StructInit(&GPIO_InitStructure); /* Configure PA.06,07 as encoder input */
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_6 | GPIO_Pin_7; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING; GPIO_Init(GPIOA, &GPIO_InitStructure);
/* Enable the TIM3 Update Interrupt */
NVIC_InitStructure.NVIC_IRQChannel = TIM3_IRQn;
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = TIMx_PRE_EMPTION_PRIORITY; NVIC_InitStructure.NVIC_IRQChannelSubPriority = TIMx_SUB_PRIORITY; NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; NVIC_Init(&NVIC_InitStructure);
/* Timer configuration in Encoder mode */ TIM_DeInit(ENCODER_TIMER);
TIM_TimeBaseStructInit(&TIM_TimeBaseStructure);
TIM_TimeBaseStructure.TIM_Prescaler = 0x0; // No prescaling //72M捕获? TIM_TimeBaseStructure.TIM_Period = (4*ENCODER_PPR)-1; TIM_TimeBaseStructure.TIM_ClockDivision = TIM_CKD_DIV1;
TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up; TIM_TimeBaseInit(ENCODER_TIMER, &TIM_TimeBaseStructure);
TIM_EncoderInterfaceConfig(ENCODER_TIMER, TIM_EncoderMode_TI12, TIM_ICPolarity_Rising, TIM_ICPolarity_Rising); TIM_ICStructInit(&TIM_ICInitStructure);
TIM_ICInitStructure.TIM_ICFilter = ICx_FILTER;
TIM_ICInit(ENCODER_TIMER, &TIM_ICInitStructure);
// Clear all pending interrupts
TIM_ClearFlag(ENCODER_TIMER, TIM_FLAG_Update); TIM_ITConfig(ENCODER_TIMER, TIM_IT_Update, ENABLE); //Reset counter
TIM2->CNT = COUNTER_RESET;
ENC_Clear_Speed_Buffer();
TIM_Cmd(ENCODER_TIMER, ENABLE); }
/*******************************************************************************
* Function Name : ENC_Get_Electrical_Angle
* Description : Returns the absolute electrical Rotor angle * Input : None * Output : None
* Return : Rotor electrical angle: 0 -> 0 degrees,
* S16_MAX-> 180 degrees,
* S16_MIN-> -180 degrees *******************************************************************************/
s16 ENC_Get_Electrical_Angle(void) {
s32 temp;
temp = (s32)(TIM_GetCounter(ENCODER_TIMER)) * (s32)(4294967295 / (4*ENCODER_PPR)); return((s16)(temp/65536)); // s16 result }
/*******************************************************************************
* Function Name : ENC_Clear_Speed_Buffer
* Description : Clear speed buffer used for average speed calculation * Input : None * Output : None * Return : None
*******************************************************************************/
void ENC_Clear_Speed_Buffer(void) {
u32 i;
for (i=0;i hSpeed_Buffer[i] = 0; } bIs_First_Measurement = TRUE; } /******************************************************************************* * Function Name : ENC_Calc_Rot_Speed * Description : Compute return latest speed measurement * Input : None * Output : s16 * Return : Return the speed in 0.1 Hz resolution. *******************************************************************************/ s16 ENC_Calc_Rot_Speed(void) { s32 wDelta_angle; u16 hEnc_Timer_Overflow_sample_one, hEnc_Timer_Overflow_sample_two; u16 hCurrent_angle_sample_one, hCurrent_angle_sample_two; signed long long temp; s16 haux; if (!bIs_First_Measurement) { // 1st reading of overflow counter hEnc_Timer_Overflow_sample_one = hEncoder_Timer_Overflow; // 1st reading of encoder timer counter hCurrent_angle_sample_one = ENCODER_TIMER->CNT; // 2nd reading of overflow counter hEnc_Timer_Overflow_sample_two = hEncoder_Timer_Overflow; // 2nd reading of encoder timer counter hCurrent_angle_sample_two = ENCODER_TIMER->CNT; // Reset hEncoder_Timer_Overflow and read the counter value for the next // measurement hEncoder_Timer_Overflow = 0; haux = ENCODER_TIMER->CNT; if (hEncoder_Timer_Overflow != 0) { haux = ENCODER_TIMER->CNT; hEncoder_Timer_Overflow = 0; } if (hEnc_Timer_Overflow_sample_one != hEnc_Timer_Overflow_sample_two) { //Compare sample 1 & 2 and check if an overflow has been generated right //after the reading of encoder timer. If yes, copy sample 2 result in //sample 1 for next process hCurrent_angle_sample_one = hCurrent_angle_sample_two; hEnc_Timer_Overflow_sample_one = hEnc_Timer_Overflow_sample_two; } if ( (ENCODER_TIMER->CR1 & TIM_CounterMode_Down) == TIM_CounterMode_Down) {// encoder timer down-counting wDelta_angle = (s32)(hCurrent_angle_sample_one - hPrevious_angle - (hEnc_Timer_Overflow_sample_one) * (4*ENCODER_PPR)); } else {//encoder timer up-counting wDelta_angle = (s32)(hCurrent_angle_sample_one - hPrevious_angle + (hEnc_Timer_Overflow_sample_one) * (4*ENCODER_PPR)); } // speed computation as delta angle * 1/(speed sempling time) temp = (signed long long)(wDelta_angle * SPEED_SAMPLING_FREQ); temp *= 10; // 0.1 Hz resolution temp /= (4*ENCODER_PPR); } //is first measurement, discard it else { bIs_First_Measurement = FALSE; temp = 0; hEncoder_Timer_Overflow = 0; haux = ENCODER_TIMER->CNT; // Check if Encoder_Timer_Overflow is still zero. In case an overflow IT // occured it resets overflow counter and wPWM_Counter_Angular_Velocity if (hEncoder_Timer_Overflow != 0) { haux = ENCODER_TIMER->CNT; hEncoder_Timer_Overflow = 0; } } hPrevious_angle = haux; return((s16) temp); } /******************************************************************************* * Function Name : ENC_Calc_Average_Speed * Description : Compute smoothed motor speed based on last SPEED_BUFFER_SIZE informations and store it variable * Input : None * Output : s16 * Return : Return rotor speed in 0.1 Hz resolution. This routine will return the average mechanical speed of the motor. *******************************************************************************/ void ENC_Calc_Average_Speed(void) { s32 wtemp,wtemp_1=0; u32 i; // wtemp = ENC_Calc_Rot_Speed(); // ///* Compute the average of the read speeds */ // hSpeed_Buffer[bSpeed_Buffer_Index] = (s16)wtemp; // bSpeed_Buffer_Index++; // // if (bSpeed_Buffer_Index == SPEED_BUFFER_SIZE) // { // bSpeed_Buffer_Index = 0; // } // wtemp=0; // for (i=0;i // wtemp += hSpeed_Buffer[i]; // } // wtemp /= SPEED_BUFFER_SIZE; for (i=0;i if (bSpeed_Buffer_Index == SPEED_BUFFER_SIZE) { bSpeed_Buffer_Index = 0; } wtemp = ENC_Calc_Rot_Speed(); hSpeed_Buffer[bSpeed_Buffer_Index] = (s16)wtemp; bSpeed_Buffer_Index++; wtemp_1 += wtemp; } wtemp_1 /= SPEED_BUFFER_SIZE; hRot_Speed = ((s16)(wtemp_1)); } /******************************************************************************* * Function Name : LCD_Display * Description : This function handles the display of timer counter, theta and electronical frequency: theta --- resolution: 1 degree; electronical frequency --- resolution: 0.1Hz. * Input : None * Output : None * Return : None *******************************************************************************/ //void LCD_Display(DisplayType DisplayStatus) //{ // u16 hValue; // s16 Theta; // s16 hSpeed; // char *pstr; // // switch (DisplayStatus) // { // case DISPLAY_TIMCNT: // hValue = TIM_GetCounter(ENCODER_TIMER); // LCD_ShowNum(0,0,(hValue),5); // printf(\// break; // // case DISPLAY_THETA: // Theta = ENC_Get_Electrical_Angle()*360/65535; //U16_MAX; // if (Theta < 0) // { // hValue = (u16)(-Theta); //// pstr = int2char(hValue); // *pstr = '-'; // } // else // { // hValue = (u16)Theta; //// pstr = int2char(hValue); // if (hValue != 0) *pstr = '+'; // } // LCD_ShowChar(0,8,*pstr); // LCD_ShowNum(0,9,hValue,5); // break; // // default: // hSpeed = hRot_Speed; // if (hSpeed < 0) // { // hValue = (u16)(-hSpeed); //// pstr = int2char(hValue); // *pstr = '-'; // } // else // { // hValue = (u16)hSpeed; //// pstr = int2char(hValue); // if (hValue != 0) *pstr = '+'; // } // LCD_ShowChar(0,8,*pstr); // LCD_ShowNum(1,0,*pstr,5); // break; // } //} /******************************************************************************* * Function Name : TIM2_IRQHandler * Description : This function handles TIMx Update interrupt request. Encoder unit connected to TIM2 * Input : None * Output : None * Return : None ******************************************************************************* / void TIM3_IRQHandler(void) { /* Clear the interrupt pending flag */ TIM_ClearFlag(ENCODER_TIMER, TIM_FLAG_Update); if (hEncoder_Timer_Overflow != 65535) { hEncoder_Timer_Overflow++; } } //寄存器版本 /******************* (C) COPYRIGHT 2007 STMicroelectronics *****END OF FILE****/ //#include \ //void Encoder_Init(void) //{ // /* TIM3 clock source enable */ // RCC->APB1ENR|=1<<1; //TIM3时钟使能 // /* Enable GPIOA, clock */ // RCC->APB2ENR|=1<<2; //使能PORTA时钟 // /* Configure PA.06,07 as encoder input */ // GPIOA->CRL&=0XF0FFFFFF;//PA6 // GPIOA->CRL|=0X04000000;//浮空输入 // GPIOA->CRL&=0X0FFFFFFF;//PA7 // GPIOA->CRL|=0X40000000;//浮空输入 // /* Enable the TIM3 Update Interrupt */ // //这两个东东要同时设置才可以使用中断 // TIM3->DIER|=1<<0; //允许更新中断 // TIM3->DIER|=1<<6; //允许触发中断 // MY_NVIC_Init(1,3,TIM3_IRQChannel,2); // /* Timer configuration in Encoder mode */ // TIM3->PSC = 0x0;//预分频器 // TIM3->ARR = ENCODER_TIM_PERIOD-1;//设定计数器自动重装值 // TIM3->CR1 &=~(3<<8);// 选择时钟分频:不分频 // TIM3->CR1 &=~(3<<5);// 选择计数模式:边沿对齐模式 // // TIM3->CCMR1 |= 1<<0; //CC1S='01' IC1FP1映射到TI1 // TIM3->CCMR1 |= 1<<8; //CC2S='01' IC2FP2映射到TI2 // TIM3->CCER &= ~(1<<1); //CC1P='0' IC1FP1不反相,IC1FP1=TI1 // TIM3->CCER &= ~(1<<5); //CC2P='0' IC2FP2不反相,IC2FP2=TI2 // TIM3->CCMR1 |= 3<<4; // IC1F='1000' 输入捕获1滤波器 // TIM3->SMCR |= 3<<0; //SMS='011' 所有的输入均在上升沿和下降沿有效 // TIM3->CNT = COUNTER_RESET; // TIM3->CR1 |= 0x01; //CEN=1,使能定时器 //} 1. #ifndef __ENCODER_H__ 2. #define __ENCODER_H__ 3. 4. #include \5. 6. //void Encoder_Init(void); 7. 8. //#endif 9. 10. /******************** (C) COPYRIGHT 2007 STMicroelectronics ************ ******** 11. * File Name : stm32f10x_encoder.h 12. * Author : IMS Systems Lab 13. * Date First Issued : 21/11/07 14. * Description : This file contains the software implementation fo r the 15. * encoder position and speed reading. 16. *********************************************************************** ********* 17. * History: 18. * 21/11/07 v1.0 19. *********************************************************************** ********* 20. * THE PRESENT SOFTWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUST OMERS 21. * WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE TIME. 22. * AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY DIREC T, 23. * INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING F ROM THE 24. * CONTENT OF SUCH SOFTWARE AND/OR THE USE MADE BY CUSTOMERS OF THE CODIN G 25. * INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS. 26. *********************************************************************** ********/ 27. 28. /* Define to prevent recursive inclusion -------------------------------------*/ 29. 30. 31. /* Private typedef -----------------------------------------------------------*/ 32. typedef enum {DISPLAY_TIMCNT = 0,DISPLAY_THETA,DISPLAY_W} DisplayType; 33. 34. /* Private typedef -----------------------------------------------------------*/ 35. /* Private define ------------------------------------------------------------*/ 36. #define ENCODER_TIMER TIM3 // Encoder unit connected to TIM3 37. #define ENCODER_PPR (u16)(200) // number of pulses per revol ution 38. #define SPEED_BUFFER_SIZE 2//8 39. 40. #define COUNTER_RESET (u16)0 41. #define ICx_FILTER (u8) 6 // 6<-> 670nsec 42. 43. #define TIMx_PRE_EMPTION_PRIORITY 1 44. #define TIMx_SUB_PRIORITY 0 45. 46. #define SPEED_SAMPLING_FREQ (u16)(2000/(SPEED_SAMPLING_TIME+1)) 47. 48. extern s16 hRot_Speed; 49. 50. 51. /* Private functions ---------------------------------------------------------*/ 52. s16 ENC_Calc_Rot_Speed(void); 53. 54. 55. /* Includes ------------------------------------------------------------------*/ 56. /* Private define ------------------------------------------------------------*/ 57. #define SPEED_SAMPLING_TIME 9 // (9+1)*500usec = 5msec 58. 59. /* Exported functions ------------------------------------------------------- */ 60. void ENC_Init(void); 61. s16 ENC_Get_Electrical_Angle(void); 62. void ENC_Clear_Speed_Buffer(void); 63. void ENC_Calc_Average_Speed(void); 64. //void LCD_Display(DisplayType DisplayStatus); 65. s16 ENC_Get_Speed(void); 66. void TIM3_IRQHandler(void);; 67. 68. #endif 69. /*__STM32F10x_ENCODER_H*/ 70. /******************* (C) COPYRIGHT 2007 STMicroelectronics *****END OF F ILE****/
正在阅读:
正交编码器测速03-28
建筑基坑工程安全管理规范DB 45T960-201408-18
汕尾市幼儿园名录2018版122家05-26
电机拖动电拖复习2012-511-15
bat批处理命令大全106-28
小学生关于交通安全的作文06-15
与四季为友作文500字07-09
08年述职报告(XXX)05-22
五语上19 天火之谜07-12
- 多层物业服务方案
- (审判实务)习惯法与少数民族地区民间纠纷解决问题(孙 潋)
- 人教版新课标六年级下册语文全册教案
- 词语打卡
- photoshop实习报告
- 钢结构设计原理综合测试2
- 2014年期末练习题
- 高中数学中的逆向思维解题方法探讨
- 名师原创 全国通用2014-2015学年高二寒假作业 政治(一)Word版
- 北航《建筑结构检测鉴定与加固》在线作业三
- XX县卫生监督所工程建设项目可行性研究报告
- 小学四年级观察作文经典评语
- 浅谈110KV变电站电气一次设计-程泉焱(1)
- 安全员考试题库
- 国家电网公司变电运维管理规定(试行)
- 义务教育课程标准稿征求意见提纲
- 教学秘书面试技巧
- 钢结构工程施工组织设计
- 水利工程概论论文
- 09届九年级数学第四次模拟试卷
- 正交
- 测速
- 编码器
- 宁化县特殊教育学校教研工作总结
- 林业副高业务自传
- 2016-2020年四川省智能交通行业发展竞争及投资策略分析目录
- 大学化学实验报告(全) - 图文
- 2018-2019高三高考数学二轮复习专题训练+17+Word版含答案
- 金属学与热处理第十一章 铸铁习题与思考题
- 会计电算化各章练习题
- 2017-2018学年高中语文一轮复习专题三标点符号基础知识整合
- 螺杆式氨压缩机常见故障分析与处理
- 车间带班副主任工作总结
- 铁路T梁预制作业指导书(全套)
- 委托融资+协议
- 江西逝江市2017 - 2018学年高二历史上学期第二次月考试题2017122
- 2.2 离子反应(必修1)
- 作业二
- 2011年GCT英语考试真题(B卷)及答案
- 生理复习题与答案
- 数控加工中心M代码
- 三学一练课堂模式在英语语法教学中的运用
- 2016年贵师大教育综合333考研真题回忆版