找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 3367|回复: 7
收起左侧

STM32直流电机位置PID调节程序 上位机显示波形,直流电机位置环

  [复制链接]
ID:474195 发表于 2021-8-15 12:31 | 显示全部楼层 |阅读模式
其中包含原理图,pcb,bom表 app 上位机stm32f103c8t6为主控,app控制显示波形,上位机显示波形,直流电机位置环。
位置PID调节使用说明
简介:
应用stm32f103c8t6最小系统与双相编码器电机实现电机位置pid调节。
主要功能:
  •       可使用app进行pid参数与目标值的设定
  •       可使 上位机显示pid调节过程的波形
  •       Oled显示目标值,pid值,当前值等数据
整体结构:
使用说明:
  • 首先连接电源线连接电脑USB


  •   连接完毕后可见oled显示如下:
第一行数据为目标值(初始为10000脉冲的位置);
第二行为目前数值(初始为10000脉冲的位置故初始电机不动作);

Altium Designer画的原理图和PCB图如下:(51hei附件中可下载工程文件)
51hei.png 51hei.png 51hei.png
51hei.png 51hei.png

STM32单片机源程序如下:
  1. #include "oled.h"
  2. #include "delay.h"
  3. #include "sys.h"
  4. #include "TIME.h"
  5. #include "usart.h"         
  6. #include "DataScope_DP.h"
  7. #include "usart2.h"
  8. #include "string.h"

  9. u8 modle=3;        //改变倍数选择  
  10. u16 Target=30000; //初始化目标值
  11. float Kp=120,Ki=0,Kd=360;//pid参数初始设定
  12. unsigned char i;          //计数变量
  13. unsigned char Send_Count; //串口需要发送的数据个数
  14. void gui(void);//oled界面函数
  15. void blup(void);//上位机传输函数
  16. void blue_recive(void);//蓝牙接收函数
  17. int main(void)
  18. {         

  19.         delay_init();                     //延时函数初始化         
  20.         NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2); //中断分组
  21.         TIME_init(); //定时器,定时中断初始化
  22.         PWM_init();//pwwm初始化
  23.         usart2_init(115200);//串口2初始化 只用到发送
  24.         uart_init(9600);//串口1初始化
  25.         LED_Init();  //相关io初始化
  26.         OLED_Init();                          //初始化OLED      
  27.         OLED_Refresh_Gram();                //更新显示到OLED  
  28.          
  29.         while(1)
  30.         {            
  31.   gui();
  32.         blup();
  33.         blue_recive();
  34.         delay_ms(70);         
  35.         printf("%d",((int)((TIM2->CNT)*0.02)));
  36.         //printf("PID调节测试程序ok");
  37.         }
  38. }
  39.   
  40. /************************************************
  41. 名称:蓝牙接收程序
  42. 介绍:接收来自app的串口数据
  43. 应用:串口1
  44. ************************************************/

  45. void blue_recive()
  46. {      

  47.     if(USART_RX_STA&0x8000)                                             //如果串口有数据发来
  48.     {                     
  49.                         
  50.                                 if(USART_RX_BUF[0]=='T') {Target=(USART_RX_BUF[1]-'0')*10000+(USART_RX_BUF[2]-'0')*1000+
  51.                                                         (USART_RX_BUF[3]-'0')*100+(USART_RX_BUF[4]-'0')*10+(USART_RX_BUF[5]-'0')*1;}                //解码app发来的 tardgt的位置
  52.                                                         if(USART_RX_BUF[0]=='s')  modle=1;//改变倍数*0.01
  53.                                                         if(USART_RX_BUF[0]=='S')  modle=2;//改变倍数*0.1
  54.                                                         if(USART_RX_BUF[0]=='M')  modle=3;//改变倍数*1
  55.                                                         if(USART_RX_BUF[0]=='L')  modle=4; //改变倍数*10
  56.                                                                                                                                        
  57.                                                         if(USART_RX_BUF[0]=='B')  Target+=2000;  //响应正步进2000
  58.                                                         if(USART_RX_BUF[0]=='b')  Target-=2000;  //响应负步进2000
  59.                                                         
  60.                                                 
  61.                   if(modle==1)//倍数*0.01
  62.                                                                  {
  63.                                                            if(USART_RX_BUF[0]=='P'&USART_RX_BUF[1]=='+') {Kp+=0.01;}//如果发来的数据以p为帧头则为p的变量以下同理
  64.                                                                   if(USART_RX_BUF[0]=='I'&USART_RX_BUF[1]=='+') {Ki+=0.01;}//此部分可以用str函数进行                                         
  65.                                                            if(USART_RX_BUF[0]=='D'&USART_RX_BUF[1]=='+') {Kd+=0.01;}               
  66.                  if(USART_RX_BUF[0]=='P'&USART_RX_BUF[1]=='-') {Kp-=0.01;}
  67.                                                            if(USART_RX_BUF[0]=='I'&USART_RX_BUF[1]=='-') {Ki-=0.01;}
  68.                                                            if(USART_RX_BUF[0]=='D'&USART_RX_BUF[1]=='-') {Kd-=0.01;}
  69.                                                                  }     
  70.                   if(modle==2)//倍数*0.1
  71.                                                                  {
  72.                                                            if(USART_RX_BUF[0]=='P'&USART_RX_BUF[1]=='+') {Kp+=0.1;}
  73.                                                                   if(USART_RX_BUF[0]=='I'&USART_RX_BUF[1]=='+') {Ki+=0.1;}                                                
  74.                                                            if(USART_RX_BUF[0]=='D'&USART_RX_BUF[1]=='+') {Kd+=0.1;}               
  75.                  if(USART_RX_BUF[0]=='P'&USART_RX_BUF[1]=='-') {Kp-=0.1;}
  76.                                                            if(USART_RX_BUF[0]=='I'&USART_RX_BUF[1]=='-') {Ki-=0.1;}
  77.                                                            if(USART_RX_BUF[0]=='D'&USART_RX_BUF[1]=='-') {Kd-=0.1;}
  78.                                                                  }   
  79.                   if(modle==3)//倍数*1
  80.                                                                  {
  81.                                                            if(USART_RX_BUF[0]=='P'&USART_RX_BUF[1]=='+') {Kp+=1;}
  82.                                                                   if(USART_RX_BUF[0]=='I'&USART_RX_BUF[1]=='+') {Ki+=1;}                                                
  83.                                                            if(USART_RX_BUF[0]=='D'&USART_RX_BUF[1]=='+') {Kd+=1;}               
  84.                  if(USART_RX_BUF[0]=='P'&USART_RX_BUF[1]=='-') {Kp-=1;}
  85.                                                            if(USART_RX_BUF[0]=='I'&USART_RX_BUF[1]=='-') {Ki-=1;}
  86.                                                            if(USART_RX_BUF[0]=='D'&USART_RX_BUF[1]=='-') {Kd-=1;}
  87.                                                                  }   
  88.                   if(modle==4)//倍数*10
  89.                                                                  {
  90.                                                            if(USART_RX_BUF[0]=='P'&USART_RX_BUF[1]=='+') {Kp+=10;}
  91.                                                                   if(USART_RX_BUF[0]=='I'&USART_RX_BUF[1]=='+') {Ki+=10;}                                                
  92.                                                            if(USART_RX_BUF[0]=='D'&USART_RX_BUF[1]=='+') {Kd+=10;}               
  93.                  if(USART_RX_BUF[0]=='P'&USART_RX_BUF[1]=='-') {Kp-=10;}
  94.                                                            if(USART_RX_BUF[0]=='I'&USART_RX_BUF[1]=='-') {Ki-=10;}
  95.                                                            if(USART_RX_BUF[0]=='D'&USART_RX_BUF[1]=='-') {Kd-=10;}
  96.                                                                  }                                                                                    
  97.                USART_RX_STA=0;                                       //清除中断 标志位
  98.     }
  99. }

  100. /************************************************
  101. 名称:上位机波形显示程序
  102. 介绍:向上位机发送波形信息
  103. 应用:串口2
  104. ************************************************/
  105. void blup(void)
  106. {

  107.         DataScope_Get_Channel_Data(TIM2->CNT, 1 );
  108.         DataScope_Get_Channel_Data(Target, 2 );
  109.         Send_Count = DataScope_Data_Generate(2);
  110.         for( i = 0 ; i < Send_Count; i++)
  111.         {
  112.         while((USART2->SR&0X40)==0);  
  113.         USART2->DR = DataScope_OutPut_Buffer[i];
  114.         }
  115. }


  116. /************************************************
  117. 名称:oled界面程序
  118. 介绍:编辑oled界面提示相关信息
  119. 应用:spi通讯
  120. ************************************************/
  121. void gui(void)
  122. {

  123.   OLED_ShowString(0,0,"Target:",12);  
  124.         OLED_ShowNum(48,0,Target,5,12);        
  125.                                 
  126.         OLED_ShowString(0,16,"CNT:",12);  
  127.         OLED_ShowNum(48,16,TIM2->CNT,5,12);        
  128.                
  129.         OLED_ShowString(0,32,"PWM:",12);  
  130.         OLED_ShowNum(42,32,PWMA,4,12);        
  131.         OLED_ShowString(66,32,"/7100",12);                  
  132.                
  133.         OLED_ShowString(0,46,"Kp:",12);       OLED_ShowNum(15,46,Kp,3,12);        
  134.   OLED_ShowString(50,46,"Ki:",12);      OLED_ShowNum(66,46,Ki*100,2,12);        
  135.   OLED_ShowString(90,46,"Kd:",12);                  OLED_ShowNum(108,46,Kd,3,12);        
  136.         if(modle==1)        OLED_ShowString(100,16,"s",12);  
  137.         if(modle==2)        OLED_ShowString(100,16,"S",12);  
  138.         if(modle==3)        OLED_ShowString(100,16,"M",12);  
  139.         if(modle==4)        OLED_ShowString(100,16,"L",12);  
  140.   OLED_Refresh_Gram();                //更新显示到OLED
  141. }
复制代码

上位机和app没有代码,只有单片机有代码
资料51hei下载地址:
PID演示调节资料.7z (12.17 MB, 下载次数: 148)

评分

参与人数 1黑币 +80 收起 理由
admin + 80 共享资料的黑币奖励!

查看全部评分

回复

使用道具 举报

ID:812760 发表于 2021-11-2 11:03 | 显示全部楼层
楼主想问一下,可以实现精准控制电机转动角度,或者距离吗
回复

使用道具 举报

ID:474195 发表于 2021-12-20 21:14 | 显示全部楼层
xyw@6 发表于 2021-11-2 11:03
楼主想问一下,可以实现精准控制电机转动角度,或者距离吗

可以的 精度取决于你的负载和pid参数
回复

使用道具 举报

ID:228452 发表于 2022-4-2 18:38 | 显示全部楼层
Hello
after trying MiniBalance.exe I am getting error

Data Scope cannot operate normally because it cannot create the necessary configuration information!
Please try to run DataScope as a sound agent

Does it work on WIN10 X64 ?

Thank you
回复

使用道具 举报

ID:806701 发表于 2022-4-23 21:13 | 显示全部楼层
请问可以借鉴下上位机和APP代码吗?
回复

使用道具 举报

ID:228452 发表于 2022-4-24 01:29 | 显示全部楼层
" Does it work on WIN10 X64 ?"

This program must be run under Win32
found with ultraedit...
回复

使用道具 举报

ID:474195 发表于 2022-4-28 22:04 | 显示全部楼层
xzp0630 发表于 2022-4-23 21:13
请问可以借鉴下上位机和APP代码吗?

上位机不是 我写的 你可以用qt做一个
回复

使用道具 举报

ID:149144 发表于 2022-11-18 15:02 | 显示全部楼层
好东西,下载完了评论点赞
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

手机版|小黑屋|51黑电子论坛 |51黑电子论坛6群 QQ 管理员QQ:125739409;技术交流QQ群281945664

Powered by 单片机教程网

快速回复 返回顶部 返回列表