Encode.c 5.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210
  1. /*
  2. * @Author: mikey.zhaopeng
  3. * @Date: 2018-12-20 19:51:02
  4. * @Last Modified by: mikey.zhaopeng
  5. * @Last Modified time: 2018-12-20 19:51:02
  6. */
  7. #include "global.h"
  8. #include "Encode.h"
  9. #define ENCODEPERIOD 65536
  10. typedef struct
  11. {
  12. unsigned short encode1_use;
  13. unsigned short encode2_use;
  14. float BMGearRatio_ch1;
  15. float BMGearRatio_ch2;
  16. long cRealPosi_ch1;
  17. long cRealPosi_ch2;
  18. } cEncodeAxis_t;
  19. static cEncodeAxis_t cEncodeAxis;
  20. void EncoderInit(void)
  21. {
  22. if (cEncodeAxis.encode1_use)//编码器1
  23. {
  24. RCC->APB2ENR |= 0x10 ;
  25. GPIO_Set(GPIOA, PIN15, GPIO_MODE_IN_FLOATING, GPIO_SPEED_50M, GPIO_PUPD_NONE);
  26. GPIO_Set(GPIOB, PIN13, GPIO_MODE_IN_FLOATING, GPIO_SPEED_50M, GPIO_PUPD_NONE); //
  27. AFIO->MAPR |=3<<8;//用TIME2 完全映射
  28. RCC->APB1ENR |=1<<0;//开启TIME3定时器时钟
  29. Sys_NVIC_Init(1, 1, TIM2_IRQn, 1);
  30. TIM2->CR1 = 0;
  31. TIM2->CR1 |= (0 << 8) | (0 << 7) | (0 << 5) | (0 << 4) | (0 << 3) | (1 << 2) | (0 << 1); // 禁止自动重载
  32. TIM2->CR2 = 0;
  33. TIM2->PSC = 0; //72
  34. TIM2->ARR = ENCODEPERIOD - 1;
  35. TIM2->CCER = 0;
  36. TIM2->CCMR1 = 0;
  37. TIM2->SMCR = 0;
  38. TIM2->DIER = 0;
  39. TIM2->DIER |= 1; // 允许更新中断
  40. TIM2->CNT = 0;
  41. TIM2->SMCR |=(3 << 0); // 编码器模弿1
  42. TIM2->CCMR1 |= (3 << 12) | (0 << 10) | (1 << 8);
  43. TIM2->CCMR1 |= (3 << 4) | (0 << 2) | (1 << 0); //CH1 CH2 输入配置 ,一分频,滤波设罿
  44. TIM2->CCER |= (0 << 5) | (0 << 1); //CH1 CH2 输入捕获 上升沿有敿
  45. TIM2->CCER |= (1 << 4) | (1 << 0); // 弿启输入捕莿
  46. TIM2->CR1 |= 1 << 0;
  47. TIM2->SR = 0;
  48. }
  49. if (cEncodeAxis.encode2_use)//编码器2
  50. {
  51. RCC->APB2ENR |= 0x10 ;
  52. GPIO_Set(GPIOC, PIN6, GPIO_MODE_IN_FLOATING, GPIO_SPEED_50M, GPIO_PUPD_NONE);
  53. GPIO_Set(GPIOC, PIN7, GPIO_MODE_IN_FLOATING, GPIO_SPEED_50M, GPIO_PUPD_NONE); //
  54. AFIO->MAPR |=3<<10;//用TIME3 完全映射
  55. RCC->APB1ENR |=1<<1;//开启TIME3定时器时钟
  56. Sys_NVIC_Init(1, 1, TIM3_IRQn, 1);
  57. TIM3->CR1 = 0;
  58. TIM3->CR1 |= (0 << 8) | (0 << 7) | (0 << 5) | (0 << 4) | (0 << 3) | (1 << 2) | (0 << 1); // 禁止自动重载
  59. TIM3->CR2 = 0;
  60. TIM3->PSC = 0; //72
  61. TIM3->ARR = ENCODEPERIOD - 1;
  62. TIM3->CCER = 0;
  63. TIM3->CCMR1 = 0;
  64. TIM3->SMCR = 0;
  65. TIM3->DIER = 0;
  66. TIM3->DIER |= 1; // 允许更新中断
  67. TIM3->CNT = 0;
  68. TIM3->SMCR |=(3 << 0); // 编码器模弿1
  69. TIM3->CCMR1 |= (3 << 12) | (0 << 10) | (1 << 8);
  70. TIM3->CCMR1 |= (3 << 4) | (0 << 2) | (1 << 0); //CH1 CH2 输入配置 ,一分频,滤波设罿
  71. TIM3->CCER |= (0 << 5) | (0 << 1); //CH1 CH2 输入捕获 上升沿有敿
  72. TIM3->CCER |= (1 << 4) | (1 << 0); // 弿启输入捕莿
  73. TIM3->CR1 |= 1 << 0;
  74. TIM3->SR = 0;
  75. }
  76. }
  77. //定时器检测高速输入接口信号
  78. void TIM2_IRQHandler(void)
  79. {
  80. if (TIM2->SR & TIM_SR_UIF)
  81. {
  82. if ((TIM2->CR1 & TIM_CR1_DIR))
  83. {
  84. cEncodeAxis.cRealPosi_ch1--;
  85. }
  86. else if ((TIM2->CR1 & TIM_CR1_DIR)==0)
  87. {
  88. cEncodeAxis.cRealPosi_ch1++;
  89. }
  90. TIM2->SR &= ~TIM_SR_UIF;
  91. }
  92. }
  93. //定时器检测高速输入接口信号
  94. void TIM3_IRQHandler(void)
  95. {
  96. if (TIM3->SR & TIM_SR_UIF)
  97. {
  98. if ((TIM3->CR1 & TIM_CR1_DIR))
  99. {
  100. cEncodeAxis.cRealPosi_ch2--;
  101. }
  102. else if ((TIM3->CR1 & TIM_CR1_DIR)==0)
  103. {
  104. cEncodeAxis.cRealPosi_ch2++;
  105. }
  106. TIM3->SR &= ~TIM_SR_UIF;
  107. }
  108. }
  109. long GetEncodeNum(int ch)
  110. {
  111. long encode_num;
  112. switch(ch)
  113. {
  114. case ENCODE_X20X21:
  115. encode_num = (int)TIM2->CNT;
  116. encode_num += ENCODEPERIOD * cEncodeAxis.cRealPosi_ch1;
  117. return encode_num;
  118. break;
  119. case ENCODE_X22X23:
  120. encode_num = (int)TIM3->CNT;
  121. encode_num += ENCODEPERIOD * cEncodeAxis.cRealPosi_ch1;
  122. return encode_num;
  123. break;
  124. }
  125. return 0;
  126. }
  127. long GetEncodePos(int ch)
  128. {
  129. float pulse_buff;
  130. switch(ch)
  131. {
  132. case ENCODE_X20X21:
  133. if(cEncodeAxis.BMGearRatio_ch1==0)cEncodeAxis.BMGearRatio_ch1=1;
  134. pulse_buff=(float)GetEncodeNum(ENCODE_X20X21);
  135. return (long)(pulse_buff/cEncodeAxis.BMGearRatio_ch1);
  136. break;
  137. case ENCODE_X22X23:
  138. if(cEncodeAxis.BMGearRatio_ch2==0)cEncodeAxis.BMGearRatio_ch2=1;
  139. pulse_buff=(float)GetEncodeNum(ENCODE_X22X23);
  140. return (long)(pulse_buff/cEncodeAxis.BMGearRatio_ch2);
  141. break;
  142. }
  143. return (0);
  144. }
  145. void SetEncodePos(int ch,long pos)
  146. {
  147. switch(ch)
  148. {
  149. case ENCODE_X20X21:
  150. cEncodeAxis.cRealPosi_ch1=(long)((pos*cEncodeAxis.BMGearRatio_ch1)/ENCODEPERIOD);
  151. TIM2->CNT=(int)(pos*cEncodeAxis.BMGearRatio_ch1)%ENCODEPERIOD;
  152. break;
  153. case ENCODE_X22X23:
  154. cEncodeAxis.cRealPosi_ch2=(long)((pos*cEncodeAxis.BMGearRatio_ch2)/ENCODEPERIOD);
  155. TIM3->CNT=(int)(pos*cEncodeAxis.BMGearRatio_ch2)%ENCODEPERIOD;
  156. break;
  157. }
  158. }
  159. //设置编码器的比例
  160. void SetEncodeGearRatio(int ch,float gearRatio)
  161. {
  162. switch(ch)
  163. {
  164. case ENCODE_X20X21:
  165. if(gearRatio==0)gearRatio=1;
  166. cEncodeAxis.BMGearRatio_ch1=gearRatio;
  167. break;
  168. case ENCODE_X22X23:
  169. if(gearRatio==0)gearRatio=1;
  170. cEncodeAxis.BMGearRatio_ch2=gearRatio;
  171. break;
  172. }
  173. }
  174. //编码器应用设置
  175. void SetEncode_enable(int ch)
  176. {
  177. switch(ch)
  178. {
  179. case ENCODE_X20X21:
  180. cEncodeAxis.encode1_use=1;
  181. break;
  182. case ENCODE_X22X23:
  183. cEncodeAxis.encode2_use=1;
  184. break;
  185. }
  186. }