新聞中心

EEPW首頁(yè) > 嵌入式系統(tǒng) > 設(shè)計(jì)應(yīng)用 > 增量式PID的stm32實(shí)現(xiàn),整定過(guò)程

增量式PID的stm32實(shí)現(xiàn),整定過(guò)程

作者: 時(shí)間:2016-11-28 來(lái)源:網(wǎng)絡(luò) 收藏
首先說(shuō)說(shuō)增量式PID的公式,這個(gè)關(guān)系到MCU算法公式的書(shū)寫(xiě),實(shí)際上兩個(gè)公式的寫(xiě)法是同一個(gè)公式變換來(lái)得,不同的是系數(shù)的差異。
資料上比較多的是:

還有一種是:

感覺(jué)第二種的Kp Ki Kd比較清楚,更好理解,下面介紹的就以第二種來(lái)吧。(比例、積分、微分三個(gè)環(huán)節(jié)的作用這里就詳細(xì)展開(kāi),百度會(huì)有很多)

硬件部分:
控制系統(tǒng)的控制對(duì)象是4個(gè)空心杯直流電機(jī),電機(jī)帶光電編碼器,可以反饋轉(zhuǎn)速大小的波形。電機(jī)驅(qū)動(dòng)模塊是普通的L298N模塊。
芯片型號(hào),STM32F103ZET6

軟件部分:
PWM輸出:TIM3,可以直接輸出4路不通占空比的PWM波
PWM捕獲:STM32除了TIM6 TIM7其余的都有捕獲功能,使用TIM1 TIM2 TIM4 TIM5四個(gè)定時(shí)器捕獲四個(gè)反饋信號(hào)
PID的采樣和處理:使用了基本定時(shí)器TIM6,溢出時(shí)間就是我的采樣周期,理論上T越小效果會(huì)越好,這里我取20ms,依據(jù)控制對(duì)象吧,如果控制水溫什么的采樣周期會(huì)是幾秒幾分鐘什么的。

上面的PWM輸出和捕獲關(guān)于定時(shí)器的設(shè)置都有例程,我這里是這樣的:
TIM3輸出四路PWM,在引腳 C 的 GPIO_Pin_6 | GPIO_Pin_7 | GPIO_Pin_8 | GPIO_Pin_9輸出
四路捕獲分別是TIM4TIM1TIM2TIM5,對(duì)應(yīng)引腳是:PB7 PE11 PB3 PA1
高級(jí)定時(shí)器tim1的初始化略不同,它的中斷”名稱(chēng)“和通用定時(shí)器不同,見(jiàn)代碼:
  1. void TIM3_PWM_Init(u16 arr,u16 psc)
  2. {
  3. GPIO_InitTypeDef GPIO_InitStructure;
  4. TIM_TimeBaseInitTypeDefTIM_TimeBaseStructure;
  5. TIM_OCInitTypeDefTIM_OCInitStructure;
  6. RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM3, ENABLE);
  7. RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOC| RCC_APB2Periph_AFIO, ENABLE);//使能GPIO外設(shè)和AFIO復(fù)用功能模塊時(shí)鐘使能
  8. GPIO_PinRemapConfig(GPIO_FullRemap_TIM3, ENABLE); //Timer3全映射 GPIOC-> 6,7,8,9//用于TIM3的CH2輸出的PWM通過(guò)該LED顯示
  9. //設(shè)置該引腳為復(fù)用輸出功能,輸出TIM3 CH1 CH2 CH3 CH4 的PWM脈沖波形
  10. GPIO_InitStructure.GPIO_Pin =GPIO_Pin_6 | GPIO_Pin_7 | GPIO_Pin_8 | GPIO_Pin_9; //初始化GPIO
  11. GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;//復(fù)用推挽輸出
  12. GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
  13. GPIO_Init(GPIOC, &GPIO_InitStructure);
  14. GPIO_ResetBits(GPIOC,GPIO_Pin_6 | GPIO_Pin_7 | GPIO_Pin_8 | GPIO_Pin_9);//默認(rèn)電機(jī)使能端狀態(tài):不使能
  15. TIM_TimeBaseStructure.TIM_Period = arr; //設(shè)置在下一個(gè)更新事件裝入活動(dòng)的自動(dòng)重裝載寄存器周期的值
  16. TIM_TimeBaseStructure.TIM_Prescaler =psc; //設(shè)置用來(lái)作為T(mén)IMx時(shí)鐘頻率除數(shù)的預(yù)分頻值這里是72分頻,那么時(shí)鐘頻率就是1M
  17. TIM_TimeBaseStructure.TIM_ClockDivision = 0; //設(shè)置時(shí)鐘分割:TDTS = Tck_tim
  18. TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;//TIM向上計(jì)數(shù)模式
  19. TIM_TimeBaseInit(TIM3, &TIM_TimeBaseStructure); //根據(jù)TIM_TimeBaseInitStruct中指定的參數(shù)初始化TIMx的時(shí)間基數(shù)單位
  20. TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM1; //選擇定時(shí)器模式:TIM脈沖寬度調(diào)制模式1
  21. TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable; //比較輸出使能
  22. TIM_OCInitStructure.TIM_Pulse = 0; //設(shè)置待裝入捕獲比較寄存器的脈沖值
  23. TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_High; //輸出極性:TIM輸出比較極性高
  24. TIM_OC1Init(TIM3, &TIM_OCInitStructure);//根據(jù)TIM_OCInitStruct中指定的參數(shù)初始化外設(shè)TIMx
  25. TIM_OC1PreloadConfig(TIM3, TIM_OCPreload_Enable);//使能TIMx在CCR1上的預(yù)裝載寄存器
  26. TIM_OC2Init(TIM3, &TIM_OCInitStructure);//根據(jù)TIM_OCInitStruct中指定的參數(shù)初始化外設(shè)TIMx
  27. TIM_OC2PreloadConfig(TIM3, TIM_OCPreload_Enable);//使能TIMx在CCR2上的預(yù)裝載寄存器
  28. TIM_OC3Init(TIM3, &TIM_OCInitStructure);//根據(jù)TIM_OCInitStruct中指定的參數(shù)初始化外設(shè)TIMx
  29. TIM_OC3PreloadConfig(TIM3, TIM_OCPreload_Enable);//使能TIMx在CCR3上的預(yù)裝載寄存器
  30. TIM_OC4Init(TIM3, &TIM_OCInitStructure);//根據(jù)TIM_OCInitStruct中指定的參數(shù)初始化外設(shè)TIMx
  31. TIM_OC4PreloadConfig(TIM3, TIM_OCPreload_Enable);//使能TIMx在CCR4上的預(yù)裝載寄存器
  32. TIM_ARRPreloadConfig(TIM3, ENABLE); //使能TIMx在A(yíng)RR上的預(yù)裝載寄存器
  33. TIM_Cmd(TIM3, ENABLE);//使能TIMx外設(shè)
  34. }
  35. void TIM4_PWMINPUT_INIT(u16 arr,u16 psc)
  36. {
  37. TIM_TimeBaseInitTypeDefTIM_TimeBaseStructure;//TIM的初始化結(jié)構(gòu)體
  38. NVIC_InitTypeDef NVIC_InitStructure;//中斷配置
  39. TIM_ICInitTypeDefTIM4_ICInitStructure;//TIM4PWM配置結(jié)構(gòu)體
  40. GPIO_InitTypeDef GPIO_InitStructure;//IO口配置結(jié)構(gòu)體
  41. RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM4, ENABLE);//Open TIM4 clock
  42. RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE);//open gpioB clock
  43. GPIO_InitStructure.GPIO_Pin = GPIO_Pin_7;//GPIO 7
  44. GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU;//上拉輸入
  45. GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
  46. GPIO_Init(GPIOB, &GPIO_InitStructure);
  47. TIM_TimeBaseStructure.TIM_Period = arr; //設(shè)置在下一個(gè)更新事件裝入活動(dòng)的自動(dòng)重裝載寄存器周期的值
  48. TIM_TimeBaseStructure.TIM_Prescaler =psc; //設(shè)置用來(lái)作為T(mén)IMx時(shí)鐘頻率除數(shù)的預(yù)分頻值
  49. TIM_TimeBaseStructure.TIM_ClockDivision = 0; //設(shè)置時(shí)鐘分割:TDTS = Tck_tim
  50. TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;//TIM向上計(jì)數(shù)模式
  51. TIM_TimeBaseInit(TIM4, &TIM_TimeBaseStructure); //根據(jù)TIM_TimeBaseInitStruct中指定的參數(shù)初始化TIMx的時(shí)間基數(shù)單位
  52. NVIC_InitStructure.NVIC_IRQChannel = TIM4_IRQn;
  53. NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1;
  54. NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1;
  55. NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
  56. NVIC_Init(&NVIC_InitStructure);
  57. TIM4_ICInitStructure.TIM_Channel = TIM_Channel_2;
  58. TIM4_ICInitStructure.TIM_ICPolarity = TIM_ICPolarity_Rising;
  59. TIM4_ICInitStructure.TIM_ICSelection = TIM_ICSelection_DirectTI;
  60. TIM4_ICInitStructure.TIM_ICPrescaler = TIM_ICPSC_DIV1;
  61. TIM4_ICInitStructure.TIM_ICFilter = 0x3;//Filter:過(guò)濾
  62. TIM_PWMIConfig(TIM4, &TIM4_ICInitStructure);//PWM輸入配置
  63. TIM_SelectInputTrigger(TIM4, TIM_TS_TI2FP2);//選擇有效輸入端
  64. TIM_SelectSlaveMode(TIM4, TIM_SlaveMode_Reset);//配置為主從復(fù)位模式
  65. TIM_SelectMasterSlaveMode(TIM4, TIM_MasterSlaveMode_Enable);//啟動(dòng)定時(shí)器的被動(dòng)觸發(fā)
  66. TIM_ITConfig(TIM4, TIM_IT_CC2|TIM_IT_Update, ENABLE);//中斷配置
  67. TIM_ClearITPendingBit(TIM4, TIM_IT_CC2|TIM_IT_Update); //清除中斷標(biāo)志位
  68. TIM_Cmd(TIM4, ENABLE);
  69. }
  70. void TIM4_IRQHandler(void)
  71. {
  72. if (TIM_GetITStatus(TIM4, TIM_IT_CC2) != RESET)//捕獲1發(fā)生捕獲事件
  73. {
  74. duty_TIM4=TIM_GetCapture1(TIM4); //采集占空比
  75. if(TIM_GetCapture2(TIM4)>600)period_TIM4=TIM_GetCapture2(TIM4);//簡(jiǎn)單的處理
  76. CollectFlag_TIM4 = 0;
  77. }
  78. TIM_ClearITPendingBit(TIM4, TIM_IT_CC2|TIM_IT_Update); //清除中斷標(biāo)志位
  79. }
  80. void TIM1_PWMINPUT_INIT(u16 arr,u16 psc)
  81. {
  82. TIM_TimeBaseInitTypeDefTIM_TimeBaseStructure;//TIM的初始化結(jié)構(gòu)體
  83. NVIC_InitTypeDef NVIC_InitStructure;//中斷配置
  84. TIM_ICInitTypeDefTIM1_ICInitStructure;//PWM配置結(jié)構(gòu)體
  85. GPIO_InitTypeDef GPIO_InitStructure;//IO口配置結(jié)構(gòu)體
  86. RCC_APB2PeriphClockCmd(RCC_APB2Periph_TIM1, ENABLE);//Open TIM1 clock
  87. RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOE, ENABLE);//open gpioE clock
  88. GPIO_PinRemapConfig(GPIO_FullRemap_TIM1, ENABLE); //Timer1完全重映射TIM1_CH2->PE11
  89. GPIO_InitStructure.GPIO_Pin = GPIO_Pin_11;//GPIO 11
  90. GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU;//上拉輸入
  91. GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
  92. GPIO_Init(GPIOE, &GPIO_InitStructure);
  93. TIM_TimeBaseStructure.TIM_Period = arr; //設(shè)置在下一個(gè)更新事件裝入活動(dòng)的自動(dòng)重裝載寄存器周期的值
  94. TIM_TimeBaseStructure.TIM_Prescaler =psc; //設(shè)置用來(lái)作為T(mén)IMx時(shí)鐘頻率除數(shù)的預(yù)分頻值
  95. TIM_TimeBaseStructure.TIM_ClockDivision = 0; //設(shè)置時(shí)鐘分割:TDTS = Tck_tim
  96. TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;//TIM向上計(jì)數(shù)模式
  97. TIM_TimeBaseInit(TIM1, &TIM_TimeBaseStructure); //根據(jù)TIM_TimeBaseInitStruct中指定的參數(shù)初始化TIMx的時(shí)間基數(shù)單位
  98. NVIC_InitStructure.NVIC_IRQChannel =TIM1_CC_IRQn;//TIM1捕獲中斷
  99. NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1;
  100. NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1;
  101. NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
  102. NVIC_Init(&NVIC_InitStructure);
  103. TIM1_ICInitStructure.TIM_Channel = TIM_Channel_2;
  104. TIM1_ICInitStructure.TIM_ICPolarity = TIM_ICPolarity_Rising;
  105. TIM1_ICInitStructure.TIM_ICSelection = TIM_ICSelection_DirectTI;
  106. TIM1_ICInitStructure.TIM_ICPrescaler = TIM_ICPSC_DIV1;
  107. TIM1_ICInitStructure.TIM_ICFilter = 0x03;//Filter:過(guò)濾
  108. TIM_PWMIConfig(TIM1, &TIM1_ICInitStructure);//PWM輸入配置
  109. TIM_SelectInputTrigger(TIM1, TIM_TS_TI2FP2);//選擇有效輸入端
  110. TIM_SelectSlaveMode(TIM1, TIM_SlaveMode_Reset);//配置為主從復(fù)位模式
  111. TIM_SelectMasterSlaveMode(TIM1, TIM_MasterSlaveMode_Enable);//啟動(dòng)定時(shí)器的被動(dòng)觸發(fā)
  112. // TIM_ITConfig(TIM1, TIM_IT_CC2|TIM_IT_Update, ENABLE);//中斷配置
  113. TIM_ITConfig(TIM1, TIM_IT_CC2, ENABLE); //通道2 捕獲中斷打開(kāi)
  114. //TIM_ClearITPendingBit(TIM1, TIM_IT_CC2|TIM_IT_Update); //清除中斷標(biāo)志位
  115. TIM_Cmd(TIM1, ENABLE);
  116. }
  117. void TIM1_CC_IRQHandler(void)
  118. {
  119. {
  120. if (TIM_GetITStatus(TIM1, TIM_IT_CC2) != RESET)//捕獲1發(fā)生捕獲事件
  121. {
  122. duty_TIM1=TIM_GetCapture1(TIM1); //采集占空比
  123. if(TIM_GetCapture2(TIM1)>600)period_TIM1=TIM_GetCapture2(TIM1);
  124. CollectFlag_TIM1 = 0;
  125. }
  126. }
  127. TIM_ClearITPendingBit(TIM1, TIM_IT_CC2|TIM_IT_Update); //清除中斷標(biāo)志位
  128. }
  129. void TIM2_PWMINPUT_INIT(u16 arr,u16 psc)
  130. {
  131. TIM_TimeBaseInitTypeDefTIM_TimeBaseStructure;//TIM的初始化結(jié)構(gòu)體
  132. NVIC_InitTypeDef NVIC_InitStructure;//中斷配置
  133. TIM_ICInitTypeDefTIM2_ICInitStructure;//TIM2PWM配置結(jié)構(gòu)體
  134. GPIO_InitTypeDef GPIO_InitStructure;//IO口配置結(jié)構(gòu)體
  135. RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2, ENABLE);//Open TIM2 clock
  136. // RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE);//open gpioB clock
  137. RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB| RCC_APB2Periph_AFIO, ENABLE);//使能GPIO外設(shè)和AFIO復(fù)用功能模塊時(shí)鐘
  138. GPIO_PinRemapConfig(GPIO_Remap_SWJ_JTAGDisable,ENABLE);//關(guān)閉JTAG
  139. GPIO_PinRemapConfig(GPIO_FullRemap_TIM2, ENABLE); //Timer2完全重映射TIM2_CH2->PB3
  140. GPIO_InitStructure.GPIO_Pin = GPIO_Pin_3;//GPIO 3
  141. GPIO_InitStructure.GPIO_Mode =GPIO_Mode_IPU;//浮空輸入 上拉輸入
  142. GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
  143. GPIO_Init(GPIOB, &GPIO_InitStructure);
  144. TIM_TimeBaseStructure.TIM_Period = arr; //設(shè)置在下一個(gè)更新事件裝入活動(dòng)的自動(dòng)重裝載寄存器周期的值
  145. TIM_TimeBaseStructure.TIM_Prescaler =psc; //設(shè)置用來(lái)作為T(mén)IMx時(shí)鐘頻率除數(shù)的預(yù)分頻值
  146. TIM_TimeBaseStructure.TIM_ClockDivision = 0; //設(shè)置時(shí)鐘分割:TDTS = Tck_tim
  147. TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;//TIM向上計(jì)數(shù)模式
  148. TIM_TimeBaseInit(TIM2, &TIM_TimeBaseStructure); //根據(jù)TIM_TimeBaseInitStruct中指定的參數(shù)初始化TIMx的時(shí)間基數(shù)單位
  149. NVIC_InitStructure.NVIC_IRQChannel = TIM2_IRQn;
  150. NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1;
  151. NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1;
  152. NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
  153. NVIC_Init(&NVIC_InitStructure);
  154. TIM2_ICInitStructure.TIM_Channel = TIM_Channel_2;
  155. TIM2_ICInitStructure.TIM_ICPolarity = TIM_ICPolarity_Rising;
  156. TIM2_ICInitStructure.TIM_ICSelection = TIM_ICSelection_DirectTI;
  157. TIM2_ICInitStructure.TIM_ICPrescaler = TIM_ICPSC_DIV1;
  158. TIM2_ICInitStructure.TIM_ICFilter = 0x3;//Filter:過(guò)濾
  159. TIM_PWMIConfig(TIM2, &TIM2_ICInitStructure);//PWM輸入配置
  160. TIM_SelectInputTrigger(TIM2, TIM_TS_TI2FP2);//選擇有效輸入端
  161. TIM_SelectSlaveMode(TIM2, TIM_SlaveMode_Reset);//配置為主從復(fù)位模式
  162. TIM_SelectMasterSlaveMode(TIM2, TIM_MasterSlaveMode_Enable);//啟動(dòng)定時(shí)器的被動(dòng)觸發(fā)
  163. TIM_ITConfig(TIM2, TIM_IT_CC2|TIM_IT_Update, ENABLE);//中斷配置
  164. TIM_ClearITPendingBit(TIM2, TIM_IT_CC2|TIM_IT_Update); //清除中斷標(biāo)志位
  165. TIM_Cmd(TIM2, ENABLE);
  166. }
  167. void TIM2_IRQHandler(void)
  168. {
  169. {
  170. if (TIM_GetITStatus(TIM2, TIM_IT_CC2) != RESET)//捕獲1發(fā)生捕獲事件
  171. {
  172. duty_TIM2=TIM_GetCapture1(TIM2); //采集占空比
  173. if(TIM_GetCapture2(TIM2)>600)period_TIM2=TIM_GetCapture2(TIM2);
  174. CollectFlag_TIM2 = 0;
  175. }
  176. }
  177. TIM_ClearITPendingBit(TIM2, TIM_IT_CC2|TIM_IT_Update); //清除中斷標(biāo)志位
  178. }

  179. 上一頁(yè) 1 2 下一頁(yè)

評(píng)論


技術(shù)專(zhuān)區(qū)

關(guān)閉