Advertisement
Guest User

Untitled

a guest
Jan 22nd, 2020
107
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 7.87 KB | None | 0 0
  1. #include "mcu_support_package/inc/stm32f10x.h"
  2. #include "signal.h"
  3. #include "stdbool.h"
  4. #define dt 0.005
  5. #define PI 3.1415926
  6.  
  7. int current_1 = 0;
  8. int current_2 = 0;
  9. int sample_time = 0;
  10. int PI_velocity_period=0;
  11. int PI_current_period=0;
  12. static int angular_velocity = 0;
  13. static int desired_current = 0;
  14. static int desired_velocity = 500; //желаемая скорость
  15. int prev_position = 0;
  16. int position = 0;
  17. int desired_voltage = 0;
  18. int final_position = 0;
  19.  
  20. void TIM1_UP_IRQHandler(void) {
  21. TIM_ClearFlag(TIM1, TIM_FLAG_Update);
  22. }
  23.  
  24. void TIM3_IRQHandler(void) {
  25. TIM_ClearFlag(TIM3, TIM_FLAG_Update);
  26. sample_time++;
  27. PI_velocity_period++;
  28. PI_current_period++;
  29. }
  30.  
  31. void init_all() {
  32. RCC_APB2PeriphClockCmd(RCC_APB2Periph_TIM1, ENABLE);
  33. RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2, ENABLE);
  34. RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM3, ENABLE);
  35. RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);
  36. RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOC, ENABLE);
  37. RCC_APB2PeriphClockCmd(RCC_APB2Periph_ADC1, ENABLE);
  38. RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO, ENABLE);
  39.  
  40. //настройка TIM1 и TIM3
  41. GPIO_InitTypeDef GPIOA_pwn;
  42. GPIOA_pwn.GPIO_Mode = GPIO_Mode_AF_PP;
  43. GPIOA_pwn.GPIO_Pin = GPIO_Pin_8|GPIO_Pin_9;
  44. GPIOA_pwn.GPIO_Speed = GPIO_Speed_50MHz;
  45. GPIO_Init(GPIOA, &GPIOA_pwn);
  46.  
  47. TIM_TimeBaseInitTypeDef TIM1_init;
  48. TIM_TimeBaseStructInit( & TIM1_init);
  49. TIM1_init.TIM_Prescaler = 71;
  50. TIM1_init.TIM_Period = 50; //20 000 раз в секунду
  51. TIM1_init.TIM_CounterMode = TIM_CounterMode_Up;
  52. TIM_TimeBaseInit(TIM1, &TIM1_init);
  53. TIM_CtrlPWMOutputs(TIM1,ENABLE);
  54.  
  55. TIM_TimeBaseInitTypeDef TIM3_init;
  56. TIM_TimeBaseStructInit( & TIM3_init);
  57. TIM3_init.TIM_Prescaler = 71;
  58. TIM3_init.TIM_Period = 10; //100 000 раз в секунду
  59. TIM3_init.TIM_CounterMode = TIM_CounterMode_Up;
  60. TIM_TimeBaseInit(TIM3, & TIM3_init);
  61.  
  62. TIM_OCInitTypeDef PA8_channel_pwn;
  63. TIM_OCStructInit( & PA8_channel_pwn);
  64. PA8_channel_pwn.TIM_OCMode = TIM_OCMode_PWM1;
  65. PA8_channel_pwn.TIM_OutputState = TIM_OutputState_Enable;
  66. TIM_OC1Init(TIM1, &PA8_channel_pwn);
  67.  
  68. TIM_OCInitTypeDef PA9_channel_pwn;
  69. TIM_OCStructInit( & PA9_channel_pwn);
  70. PA9_channel_pwn.TIM_OCMode = TIM_OCMode_PWM1;
  71. PA9_channel_pwn.TIM_OutputState = TIM_OutputState_Enable;
  72. TIM_OC2Init(TIM1, &PA9_channel_pwn);
  73.  
  74. //настройка АЦП
  75. GPIO_InitTypeDef PortA_adc;
  76. PortA_adc.GPIO_Mode = GPIO_Mode_AIN;
  77. PortA_adc.GPIO_Pin = GPIO_Pin_0|GPIO_Pin_1;
  78. GPIO_Init(GPIOA, &PortA_adc);
  79.  
  80. ADC_InitTypeDef ADC_init;
  81. ADC_init.ADC_Mode = ADC_Mode_Independent;
  82. ADC_init.ADC_ScanConvMode = ENABLE;
  83. ADC_init.ADC_ContinuousConvMode = ENABLE;
  84. ADC_init.ADC_ExternalTrigConv = ADC_ExternalTrigConv_None;
  85. ADC_init.ADC_DataAlign = ADC_DataAlign_Right;
  86. ADC_init.ADC_NbrOfChannel = 2;
  87. ADC_Init(ADC1,&ADC_init);
  88. ADC_InjectedSequencerLengthConfig(ADC1,2);
  89. ADC_InjectedChannelConfig(ADC1,ADC_Channel_0,1,ADC_SampleTime_55Cycles5);
  90. ADC_InjectedChannelConfig(ADC1,ADC_Channel_1,2,ADC_SampleTime_55Cycles5);
  91.  
  92. ADC_ExternalTrigInjectedConvConfig( ADC1, ADC_ExternalTrigInjecConv_None );
  93.  
  94. //калибровка АЦП
  95. ADC_ResetCalibration(ADC1);
  96. while(ADC_GetResetCalibrationStatus(ADC1)){;}
  97. ADC_StartCalibration(ADC1);
  98. while(ADC_GetCalibrationStatus(ADC1)){;}
  99.  
  100. //включение прерываний
  101. ADC_ITConfig(ADC1,ADC_IT_EOC,ENABLE);
  102. TIM_ITConfig(TIM1, TIM_IT_Update, ENABLE);
  103. TIM_ITConfig(TIM3, TIM_IT_Update, ENABLE);
  104. NVIC_EnableIRQ(ADC1_2_IRQn);
  105. NVIC_EnableIRQ(TIM1_UP_IRQn);
  106. NVIC_EnableIRQ(TIM3_IRQn);
  107.  
  108. TIM_Cmd(TIM1, ENABLE);
  109. TIM_Cmd(TIM3, ENABLE);
  110. ADC_Cmd(ADC1,ENABLE);
  111.  
  112. ADC_AutoInjectedConvCmd(ADC1,ENABLE);
  113. ADC_SoftwareStartConvCmd(ADC1, ENABLE);
  114. }
  115.  
  116.  
  117.  
  118. float PI_velocity(const float error, const float Kp, const float Ki){//ПИ регулятор, возвращающий желаемый ток
  119.  
  120. float ext_value = 0;
  121. static float integral = 0;
  122. integral += error * PI_velocity_period/100000;
  123. ext_value = Kp * error + Ki * integral;
  124.  
  125. //30% от максимального значения на выходе
  126. if (integral > 400) integral = 400;
  127. if (integral < -400) integral = -400;
  128. return ext_value;
  129. }
  130.  
  131. float PI_current(const float error, const float Kp, const float Ki ){ //ПИ регулятор, возвращающий желаемое напряжение
  132.  
  133. float ext_value = 0;
  134. static float integral = 0;
  135. integral += error * PI_current_period/100000;
  136. ext_value= Kp * error + Ki * integral;
  137.  
  138. //30% от максимального значения на выходе
  139. if (integral > 200) integral= 200;
  140. if (integral < -200) integral = -200;
  141. return ext_value;
  142. }
  143.  
  144. void ADC1_2_IRQHandler(void) {//прерывания от АЦП
  145. current_1 = ADC_GetInjectedConversionValue(ADC1,ADC_InjectedChannel_1) - 2048;
  146. current_2 = ADC_GetInjectedConversionValue(ADC1,ADC_InjectedChannel_2) - 2048;
  147. // if(current_1<0) current_1=0;
  148. // if(current_2<0) current_2=0;
  149. }
  150.  
  151. void setVoltage( int voltage ) {
  152.  
  153. if(voltage > 9000) desired_voltage = 9000;
  154. if(voltage < -9000) desired_voltage = -9000;
  155. float PWN_Value=(int) voltage * 50 / 9000;
  156. if (PWN_Value>=0) {
  157. TIM_SetCompare1(TIM1, PWN_Value);
  158. TIM_SetCompare2(TIM1, 0);
  159. }
  160. else {
  161. TIM_SetCompare1(TIM1,0);
  162. TIM_SetCompare2(TIM1, -PWN_Value);
  163. }
  164. }
  165.  
  166.  
  167. int main(void) {
  168.  
  169. init_all();
  170. TIM_SetCompare1(TIM1, 0);
  171. TIM_SetCompare2(TIM1, 0);
  172.  
  173. while (1) {
  174. position = TIM2->CNT ; //положение ротора
  175. int position_difference = (position - prev_position);
  176. if(position_difference > 512){
  177. final_position -= 1024;
  178. final_position += position_difference;
  179. }
  180. else {
  181. if (position_difference < -512){
  182. final_position += 1024;
  183. final_position += position_difference;
  184. }
  185. else final_position += position_difference;
  186. }
  187. if(sample_time >= dt * 100000){//срабатывает раз в 0.005 с
  188. angular_velocity = (int) 2 * PI * 100000 * final_position / (1024 * sample_time);//угловая скорость
  189. sample_time = 0;
  190. final_position = 0;
  191. }
  192. prev_position = position;
  193.  
  194. desired_current = PI_velocity(desired_velocity - angular_velocity, 1.2, 1);//регулировка скорости 1.2 4.95
  195. desired_current = (int) 2048.0 * desired_current / 3000.0;//нормировка по максимальному значению на выходе
  196. if (desired_voltage > 0){//вращение вперёд
  197. if(current_1 > current_2) desired_voltage = PI_current(desired_current - current_1, 5.2, 1.1); // 18.2 10.1
  198. else desired_voltage = PI_current(desired_current - current_2, 5.2, 1.1);//регулировка тока
  199. }
  200. else{//вращение назад
  201. if(current_1 > current_2)
  202. desired_voltage = PI_current(desired_current + current_1, 5.2, 1.1);
  203. else desired_voltage = PI_current(desired_current + current_2, 5.2, 1.1);
  204. }
  205.  
  206. setVoltage(desired_voltage);
  207. }
  208. }
  209.  
  210. // классический ассерт для STM32
  211. #ifdef USE_FULL_ASSERT
  212. void assert_failed(uint8_t * file, uint32_t line)
  213. {
  214. /* User can add his own implementation to report the file name and line number,
  215. ex: printf("Wrong parameters value: file %s on line %d\r\n", file, line) */
  216.  
  217. (void)file;
  218. (void)line;
  219.  
  220. while(1){};
  221. }
  222. #endif
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement