新聞中心

        EEPW首頁 > 嵌入式系統 > 設計應用 > 增量式PID的stm32實現,整定過程

        增量式PID的stm32實現,整定過程

        作者: 時間:2016-11-28 來源:網絡 收藏
        首先說說增量式PID的公式,這個關系到MCU算法公式的書寫,實際上兩個公式的寫法是同一個公式變換來得,不同的是系數的差異。
        資料上比較多的是:

        還有一種是:

        感覺第二種的Kp Ki Kd比較清楚,更好理解,下面介紹的就以第二種來吧。(比例、積分、微分三個環節的作用這里就詳細展開,百度會有很多)

        硬件部分:
        控制系統的控制對象是4個空心杯直流電機,電機帶光電編碼器,可以反饋轉速大小的波形。電機驅動模塊是普通的L298N模塊。
        芯片型號,STM32F103ZET6

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

        上面的PWM輸出和捕獲關于定時器的設置都有例程,我這里是這樣的:
        TIM3輸出四路PWM,在引腳 C 的 GPIO_Pin_6 | GPIO_Pin_7 | GPIO_Pin_8 | GPIO_Pin_9輸出
        四路捕獲分別是TIM4TIM1TIM2TIM5,對應引腳是:PB7 PE11 PB3 PA1
        高級定時器tim1的初始化略不同,它的中斷”名稱“和通用定時器不同,見代碼:
        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外設和AFIO復用功能模塊時鐘使能
        8. GPIO_PinRemapConfig(GPIO_FullRemap_TIM3, ENABLE); //Timer3全映射 GPIOC-> 6,7,8,9//用于TIM3的CH2輸出的PWM通過該LED顯示
        9. //設置該引腳為復用輸出功能,輸出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;//復用推挽輸出
        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);//默認電機使能端狀態:不使能
        15. TIM_TimeBaseStructure.TIM_Period = arr; //設置在下一個更新事件裝入活動的自動重裝載寄存器周期的值
        16. TIM_TimeBaseStructure.TIM_Prescaler =psc; //設置用來作為TIMx時鐘頻率除數的預分頻值這里是72分頻,那么時鐘頻率就是1M
        17. TIM_TimeBaseStructure.TIM_ClockDivision = 0; //設置時鐘分割:TDTS = Tck_tim
        18. TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;//TIM向上計數模式
        19. TIM_TimeBaseInit(TIM3, &TIM_TimeBaseStructure); //根據TIM_TimeBaseInitStruct中指定的參數初始化TIMx的時間基數單位
        20. TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM1; //選擇定時器模式:TIM脈沖寬度調制模式1
        21. TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable; //比較輸出使能
        22. TIM_OCInitStructure.TIM_Pulse = 0; //設置待裝入捕獲比較寄存器的脈沖值
        23. TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_High; //輸出極性:TIM輸出比較極性高
        24. TIM_OC1Init(TIM3, &TIM_OCInitStructure);//根據TIM_OCInitStruct中指定的參數初始化外設TIMx
        25. TIM_OC1PreloadConfig(TIM3, TIM_OCPreload_Enable);//使能TIMx在CCR1上的預裝載寄存器
        26. TIM_OC2Init(TIM3, &TIM_OCInitStructure);//根據TIM_OCInitStruct中指定的參數初始化外設TIMx
        27. TIM_OC2PreloadConfig(TIM3, TIM_OCPreload_Enable);//使能TIMx在CCR2上的預裝載寄存器
        28. TIM_OC3Init(TIM3, &TIM_OCInitStructure);//根據TIM_OCInitStruct中指定的參數初始化外設TIMx
        29. TIM_OC3PreloadConfig(TIM3, TIM_OCPreload_Enable);//使能TIMx在CCR3上的預裝載寄存器
        30. TIM_OC4Init(TIM3, &TIM_OCInitStructure);//根據TIM_OCInitStruct中指定的參數初始化外設TIMx
        31. TIM_OC4PreloadConfig(TIM3, TIM_OCPreload_Enable);//使能TIMx在CCR4上的預裝載寄存器
        32. TIM_ARRPreloadConfig(TIM3, ENABLE); //使能TIMx在ARR上的預裝載寄存器
        33. TIM_Cmd(TIM3, ENABLE);//使能TIMx外設
        34. }
        35. void TIM4_PWMINPUT_INIT(u16 arr,u16 psc)
        36. {
        37. TIM_TimeBaseInitTypeDefTIM_TimeBaseStructure;//TIM的初始化結構體
        38. NVIC_InitTypeDef NVIC_InitStructure;//中斷配置
        39. TIM_ICInitTypeDefTIM4_ICInitStructure;//TIM4PWM配置結構體
        40. GPIO_InitTypeDef GPIO_InitStructure;//IO口配置結構體
        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; //設置在下一個更新事件裝入活動的自動重裝載寄存器周期的值
        48. TIM_TimeBaseStructure.TIM_Prescaler =psc; //設置用來作為TIMx時鐘頻率除數的預分頻值
        49. TIM_TimeBaseStructure.TIM_ClockDivision = 0; //設置時鐘分割:TDTS = Tck_tim
        50. TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;//TIM向上計數模式
        51. TIM_TimeBaseInit(TIM4, &TIM_TimeBaseStructure); //根據TIM_TimeBaseInitStruct中指定的參數初始化TIMx的時間基數單位
        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:過濾
        62. TIM_PWMIConfig(TIM4, &TIM4_ICInitStructure);//PWM輸入配置
        63. TIM_SelectInputTrigger(TIM4, TIM_TS_TI2FP2);//選擇有效輸入端
        64. TIM_SelectSlaveMode(TIM4, TIM_SlaveMode_Reset);//配置為主從復位模式
        65. TIM_SelectMasterSlaveMode(TIM4, TIM_MasterSlaveMode_Enable);//啟動定時器的被動觸發
        66. TIM_ITConfig(TIM4, TIM_IT_CC2|TIM_IT_Update, ENABLE);//中斷配置
        67. TIM_ClearITPendingBit(TIM4, TIM_IT_CC2|TIM_IT_Update); //清除中斷標志位
        68. TIM_Cmd(TIM4, ENABLE);
        69. }
        70. void TIM4_IRQHandler(void)
        71. {
        72. if (TIM_GetITStatus(TIM4, TIM_IT_CC2) != RESET)//捕獲1發生捕獲事件
        73. {
        74. duty_TIM4=TIM_GetCapture1(TIM4); //采集占空比
        75. if(TIM_GetCapture2(TIM4)>600)period_TIM4=TIM_GetCapture2(TIM4);//簡單的處理
        76. CollectFlag_TIM4 = 0;
        77. }
        78. TIM_ClearITPendingBit(TIM4, TIM_IT_CC2|TIM_IT_Update); //清除中斷標志位
        79. }
        80. void TIM1_PWMINPUT_INIT(u16 arr,u16 psc)
        81. {
        82. TIM_TimeBaseInitTypeDefTIM_TimeBaseStructure;//TIM的初始化結構體
        83. NVIC_InitTypeDef NVIC_InitStructure;//中斷配置
        84. TIM_ICInitTypeDefTIM1_ICInitStructure;//PWM配置結構體
        85. GPIO_InitTypeDef GPIO_InitStructure;//IO口配置結構體
        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; //設置在下一個更新事件裝入活動的自動重裝載寄存器周期的值
        94. TIM_TimeBaseStructure.TIM_Prescaler =psc; //設置用來作為TIMx時鐘頻率除數的預分頻值
        95. TIM_TimeBaseStructure.TIM_ClockDivision = 0; //設置時鐘分割:TDTS = Tck_tim
        96. TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;//TIM向上計數模式
        97. TIM_TimeBaseInit(TIM1, &TIM_TimeBaseStructure); //根據TIM_TimeBaseInitStruct中指定的參數初始化TIMx的時間基數單位
        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:過濾
        108. TIM_PWMIConfig(TIM1, &TIM1_ICInitStructure);//PWM輸入配置
        109. TIM_SelectInputTrigger(TIM1, TIM_TS_TI2FP2);//選擇有效輸入端
        110. TIM_SelectSlaveMode(TIM1, TIM_SlaveMode_Reset);//配置為主從復位模式
        111. TIM_SelectMasterSlaveMode(TIM1, TIM_MasterSlaveMode_Enable);//啟動定時器的被動觸發
        112. // TIM_ITConfig(TIM1, TIM_IT_CC2|TIM_IT_Update, ENABLE);//中斷配置
        113. TIM_ITConfig(TIM1, TIM_IT_CC2, ENABLE); //通道2 捕獲中斷打開
        114. //TIM_ClearITPendingBit(TIM1, TIM_IT_CC2|TIM_IT_Update); //清除中斷標志位
        115. TIM_Cmd(TIM1, ENABLE);
        116. }
        117. void TIM1_CC_IRQHandler(void)
        118. {
        119. {
        120. if (TIM_GetITStatus(TIM1, TIM_IT_CC2) != RESET)//捕獲1發生捕獲事件
        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); //清除中斷標志位
        128. }
        129. void TIM2_PWMINPUT_INIT(u16 arr,u16 psc)
        130. {
        131. TIM_TimeBaseInitTypeDefTIM_TimeBaseStructure;//TIM的初始化結構體
        132. NVIC_InitTypeDef NVIC_InitStructure;//中斷配置
        133. TIM_ICInitTypeDefTIM2_ICInitStructure;//TIM2PWM配置結構體
        134. GPIO_InitTypeDef GPIO_InitStructure;//IO口配置結構體
        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外設和AFIO復用功能模塊時鐘
        138. GPIO_PinRemapConfig(GPIO_Remap_SWJ_JTAGDisable,ENABLE);//關閉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; //設置在下一個更新事件裝入活動的自動重裝載寄存器周期的值
        145. TIM_TimeBaseStructure.TIM_Prescaler =psc; //設置用來作為TIMx時鐘頻率除數的預分頻值
        146. TIM_TimeBaseStructure.TIM_ClockDivision = 0; //設置時鐘分割:TDTS = Tck_tim
        147. TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;//TIM向上計數模式
        148. TIM_TimeBaseInit(TIM2, &TIM_TimeBaseStructure); //根據TIM_TimeBaseInitStruct中指定的參數初始化TIMx的時間基數單位
        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:過濾
        159. TIM_PWMIConfig(TIM2, &TIM2_ICInitStructure);//PWM輸入配置
        160. TIM_SelectInputTrigger(TIM2, TIM_TS_TI2FP2);//選擇有效輸入端
        161. TIM_SelectSlaveMode(TIM2, TIM_SlaveMode_Reset);//配置為主從復位模式
        162. TIM_SelectMasterSlaveMode(TIM2, TIM_MasterSlaveMode_Enable);//啟動定時器的被動觸發
        163. TIM_ITConfig(TIM2, TIM_IT_CC2|TIM_IT_Update, ENABLE);//中斷配置
        164. TIM_ClearITPendingBit(TIM2, TIM_IT_CC2|TIM_IT_Update); //清除中斷標志位
        165. TIM_Cmd(TIM2, ENABLE);
        166. }
        167. void TIM2_IRQHandler(void)
        168. {
        169. {
        170. if (TIM_GetITStatus(TIM2, TIM_IT_CC2) != RESET)//捕獲1發生捕獲事件
        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); //清除中斷標志位
        178. }

        179. 上一頁 1 2 下一頁

        評論


        技術專區

        關閉
        主站蜘蛛池模板: 永寿县| 监利县| 太白县| 闽侯县| 永济市| 乌兰察布市| 都昌县| 镇康县| 磴口县| 海阳市| 岳阳县| 岢岚县| 永和县| 阿坝| 平乡县| 芜湖县| 凯里市| 白河县| 河北区| 青海省| 梁河县| 长葛市| 福清市| 天气| 大化| 贺州市| 如东县| 普格县| 阿鲁科尔沁旗| 勃利县| 太保市| 庆元县| 易门县| 葫芦岛市| 稻城县| 伊宁县| 霸州市| 宁都县| 利津县| 永州市| 名山县|