久久久久久久999_99精品久久精品一区二区爱城_成人欧美一区二区三区在线播放_国产精品日本一区二区不卡视频_国产午夜视频_欧美精品在线观看免费

 找回密碼
 立即注冊

QQ登錄

只需一步,快速開始

搜索
查看: 10372|回復: 10
打印 上一主題 下一主題
收起左側

基于單片機和NRF24L01的無線PID電機轉速控制器設計

  [復制鏈接]
跳轉到指定樓層
樓主
基于NRF24L01的PID電機轉速控制器,采用51單片機控制,有發送端和接收端的完整圖紙和程序代碼
下面是已經制作成功的實物圖:


原理圖:


項目介紹
在過程控制中,按偏差的比例(P)、積分(I)和微分(D)進行控制的PID控制器(亦稱PID調節器)是應用最為廣泛的一種自動控制器。它具有原理簡單,易于實現,適用面廣,控制參數相互獨立,參數的選定比較簡單等優點;而且在理論上可以證明,對于過程控制的典型對象──“一階滯后+純滯后二階滯后+純滯后的控制對象,PID控制器是一種最優控制。PID調節規律是連續系統動態品質校正的一種有效方法,它的參數整定方式簡便,結構改變靈活(PI、PDPID)。
然而PID算法在工業發展中也占據不小的地位,例如,液位,壓力,溫度,流量的控制都能利用PID算法進行精準控制。本項目將PID的算法用在了直流電機的控制當中,用于精準控制電機轉速,簡化電機控制難度。為了使操作者能夠簡單,方便,實時,快捷的控制電機的轉速,我又在此基礎上加上了無線模塊,使得操作者能夠更加簡單的操作本產品,操作者只需簡單改變主控板的設定值,接收機即可將電機轉速控制在設定值以內,誤差范圍控制在正負20r/s(轉/秒)。
一、   功能設計要點
1.        控制核心:接收和發射核心控制部分均采用STC12C5A60S2單片機進行控制
2.        顯示部分:接收機顯示采用普通的12864液晶顯示,發射部分為了減小其體積采用OLED液晶,功耗低,體積小,顯示效果好
3.        電機驅動部分:采用的是L298N電機驅動模塊,價格低,抗干擾能力強,安全性高,可靠性強,大大提高了電機的效率。
4.        速度檢測部分:采用44E開關型霍爾傳感器,成本低,電路簡單,可與單片機IO口直接連接,操作方便。
5.        無線數據傳輸采用NRF24L01無線模塊,工作在 2.4~2.5GHz 世界通用 ISM 頻段,工作電流只有 10.5mA, 接收時工作電流只有 18mA, 多種低功率工作模式, 功耗低。
6.        核心控制算法PID:此電路采用的是PID算法里的增量式算法,
file:///Z:\TEMP\msohtmlclip1\01\clip_image002.jpg
pid.voltage=pid.Kp*pid.err+pid.Ki*pid.integral+pid.Kd*(pid.err-pid.err_last);
增量式算法不需做累加, 計算誤差和計算精度問題對控制量的計算影響較;


四、系統工作原理方框圖




單片機源程序如下(無線接收部分):
  1. #include <STC12C5A60S2.H>
  2. #include <intrins.h>
  3. #include"delay.h"
  4. #include"12864.h"
  5. #include "nrf24l01.h"
  6. #include"mian.h"
  7. #include "keyscan.h"
  8. #include"display.h"
  9. #include"display1.h"
  10. uchar code tab11[]="0123456789:";
  11. uchar RX_BUF[TX_PLOAD_WIDTH];
  12. uchar TX_BUF[TX_PLOAD_WIDTH];
  13. uchar flag;                   //讀取接收數據完成標志位
  14. uchar temp,fuck;
  15. uchar str[4];//存儲轉換的字符串
  16. int speed_change;
  17. sbit  pulse=P1^7 ;        //從此引腳輸出脈沖信號
  18. bit g_bPIDRunFlag = 0;
  19. uchar bdata sta;
  20. sbit  RX_DR         = sta^6; //接收數據中斷
  21. sbit  TX_DS         = sta^5; //數據發送完成中斷
  22. sbit  MAX_RT = sta^4; //達到最多次重發中斷
  23. //sbit led=P1^6;
  24. /**************************************************
  25. 函數:Check_ACK()

  26. 描述:
  27.     檢查接收設備有無接收到數據包,設定沒有收到應答信
  28.         號是否重發
  29. /**************************************************/
  30. uchar Check_ACK(bit clear)
  31. {   
  32.         while(IRQ);                                                          //等待應答
  33.         sta = SPI_RW(NOP);                    // 返回狀態寄存器
  34.         if(MAX_RT)                                                          //如果達到最大重發次數
  35.                 if(clear)                         // 是否清除TX FIFO,沒有清除在復位MAX_RT中斷標志后重發
  36.                 SPI_RW(FLUSH_TX);                          //清除TX FIFO
  37.         SPI_RW_Reg(WRITE_REG + STATUS, sta);  // 清除TX_DS或MAX_RT中斷標志
  38.         IRQ = 1;                                                          //中斷復位
  39.         if(TX_DS)                                                          //發送完成中斷
  40.                 return(0x00);
  41.         else
  42.                 return(0xff);
  43. }

  44. /****pid***/
  45. struct _pid{
  46.     double SetSpeed;           //定義設定值
  47.     double ActualSpeed;        //定義實際值
  48.     double err;                //定義偏差值
  49.     double err_last;            //定義上一個偏差值
  50.         double err_second;            //定義上一個偏差值
  51.     double Kp,Ki,Kd;            //定義比例、積分、微分系數
  52.     double voltage;          //定義電壓值(控制執行器的變量)
  53.     double integral;            //定義積分值
  54. }pid;


  55. void PID_init(){

  56.     pid.SetSpeed=0;                           //定義設定值
  57.     pid.ActualSpeed=0;                    //定義實際值
  58.     pid.err=0;                                            //定義偏差值
  59.     pid.err_last=0;                                  //定義上一個偏差值
  60.     pid.voltage=0;                                  //定義電壓值(控制執行器的變量)
  61.     pid.integral=0;                                          //定義積分值
  62.     pid.Kp=0.4956;                          //                  定義比例
  63.     pid.Ki=0.000197;                  //                   積分
  64.     pid.Kd=0.0004;                          //                    微分系數
  65.   //  printf("PID_init end \n");
  66. }

  67. float PID_realize(double speed)
  68. {
  69.     pid.SetSpeed=speed;         //實際值=每分鐘電機轉速
  70.     pid.err=pid.SetSpeed-pid.ActualSpeed;  //轉速偏差=設定值-實際值
  71.     pid.integral+=pid.err;
  72.     pid.voltage=pid.Kp*pid.err+pid.Ki*pid.integral+pid.Kd*(pid.err-pid.err_last);
  73. //        pid.voltage=pid.Kp*pid.err+(0.05/pid.Ki)*pid.integral+(pid.Kd/0.05)*(pid.err-pid.err_last);
  74.     pid.err_last=pid.err;
  75.     pid.ActualSpeed=pid.voltage*1;
  76.     return pid.ActualSpeed;
  77. }

  78. void init_timer(void)
  79. {        
  80.         
  81.         TMOD = 0x01;                //設置定時器模式
  82.         TL0 = 0x00;                //設置定時初值
  83.         TH0 = 0x28;                //設置定時初值

  84.     TR0=1;                 //啟動定時器1
  85.     ET0=1;                 //Timer1中斷禁止
  86.     IT0=1;                 //下降沿觸發方式
  87.     EX0=1;                 //外部INT0中斷允許
  88.     EA=1;                  //開全局中斷
  89. }


  90. void main()
  91. {        pulse=1;
  92.     lcd_init();
  93.         display();
  94.         delay_50_ms(50);
  95.         lcd_init();
  96.         PWM_init ();
  97.         init_timer() ;
  98.     PID_init();
  99.         NRF24L01_init();
  100.         RX_Mode();
  101. display_init();
  102. // DS1302_Init();
  103.         while(1)//循環
  104.         {         

  105.             
  106.                 sta = SPI_Read(STATUS);          // 讀狀態寄存器
  107.                 temp=sta;   
  108.                 temp=(temp>>1)&0x07;  
  109.             if(RX_DR)                                  // 判斷是否接受到數據
  110.                 {
  111.                         SPI_Read_Buf(RD_RX_PLOAD, RX_BUF, TX_PLOAD_WIDTH);  // 從RX FIFO讀出數據
  112.                         flag = 1;
  113.                 }
  114.                 SPI_RW_Reg(WRITE_REG + STATUS, sta);  // 清除RX_DS中斷標志
  115.                   if(flag)                           // 接受完成
  116.                 {
  117.                         flag = 0;                                                                                                                  
  118.                          sheding=RX_BUF[0]*10+RX_BUF[1];
  119. //                                xianshi(0x92,tab11[RX_BUF[0]/10],tab11[RX_BUF[0]%10]);
  120. //                                xianshi(0x94,tab11[RX_BUF[1]/10],tab11[RX_BUF[1]%10]);
  121. //                                xianshi(0x96,tab11[0],tab11[1]);  xianshi(0x97,tab11[2],tab11[3]);
  122.        }
  123.              if(g_bPIDRunFlag)        //PID調節
  124.                              {
  125.                                    g_bPIDRunFlag=0;
  126. //                                   pulse=0;
  127.                                    pid.ActualSpeed=zhuansu;          // pid.ActualSpeed-實際值  speed_c-每分鐘電機轉速
  128.                                    speed_change=PID_realize(sheding);//pid.ActualSpeed  rad_set
  129.                            //  printf("%f\n",speed);
  130.                         //          if(speed_change<0)
  131.                         //          speed_change=speed_change*(-1);
  132.                                   pwm_1=255-PID_realize(sheding);
  133.                              if(pwm_1>255)
  134.                                           {
  135.                                             pwm_1=254;
  136.                                                           PWM0_set(pwm_1); //設置PWM占空比
  137.                                           }
  138.                                           if(pwm_1<0)
  139.                                           {
  140.                                              pwm_1=0;                                                                                                                        
  141.                                                 PWM0_set(pwm_1);    //設置PWM占空比
  142.                                              }
  143.                                         PWM0_set(pwm_1);
  144. //                                         pulse=1;
  145.                              }
  146.                                  display2();
  147.                                  keyscan();
  148.     }   
  149. }         
  150. void INIT0(void) interrupt 0
  151. {
  152.          x1++;
  153.    
  154. }
  155. void timer1(void) interrupt 1
  156. {
  157.          static uchar a = 0;
  158.            TL0 = 0x00;                //設置定時初值
  159.            TH0 = 0x28;                //設置定時初值5MS
  160. //                   TL0 = 0x00;                //設置定時初值
  161. //        TH0 = 0x04;                //設置定時初值
  162. ……………………

  163. …………限于本文篇幅 余下代碼請從51黑下載附件…………
復制代碼

所有資料51hei提供下載:
第二屆單片機大賽作品.zip (6.87 MB, 下載次數: 154)




評分

參與人數 1黑幣 +100 收起 理由
admin + 100 共享資料的黑幣獎勵!

查看全部評分

分享到:  QQ好友和群QQ好友和群 QQ空間QQ空間 騰訊微博騰訊微博 騰訊朋友騰訊朋友
收藏收藏5 分享淘帖 頂 踩
回復

使用道具 舉報

沙發
ID:1 發表于 2017-6-19 22:13 | 只看該作者
好資料,51黑有你更精彩!!!
回復

使用道具 舉報

板凳
ID:163950 發表于 2017-6-21 09:17 | 只看該作者
樓主為什么打開后都是問題!
NRF24L01.C(71): error C202: 'CSN': undefined identifier
NRF24L01.C(77): error C202: 'CE': undefined identifier
NRF24L01.C(102): error C202: 'CE': undefined identifier
NRF24L01.C(156): error C202: 'CE': undefined identifier
NRF24L01.C(166): error C202: 'CE': undefined identifier
NRF24L01.C(172): error C202: 'CE': undefined identifier
NRF24L01.C(173): error C202: 'CSN': undefined identifier
NRF24L01.C(174): error C202: 'SCK': undefined identifier
NRF24L01.C(175): error C202: 'IRQ': undefined identifier
Target not created
回復

使用道具 舉報

地板
ID:249545 發表于 2017-11-24 17:12 | 只看該作者
好文,好文,真不錯!
回復

使用道具 舉報

5#
ID:312760 發表于 2018-4-20 22:44 | 只看該作者
好東西,正好學習pid調節
回復

使用道具 舉報

6#
ID:288865 發表于 2018-4-22 15:05 | 只看該作者
正在學習謝謝
回復

使用道具 舉報

7#
ID:330988 發表于 2018-5-16 14:02 | 只看該作者
很好  可以學習一下
回復

使用道具 舉報

8#
ID:715082 發表于 2020-4-5 13:43 | 只看該作者
c03131401 發表于 2017-6-21 09:17
樓主為什么打開后都是問題!
NRF24L01.C(71): error C202: 'CSN': undefined identifier
NRF24L01.C(77): ...

您好,可能引腳定義丟失了,我也有問題,請問您有在軟件里找到3144霍爾P32引腳的定義嗎?萬望回復,謝謝您
回復

使用道具 舉報

9#
ID:110278 發表于 2020-4-7 14:16 | 只看該作者
資料挺全的,感謝分享。
回復

使用道具 舉報

10#
ID:89217 發表于 2020-4-11 22:44 | 只看該作者
學習了。感謝分享
回復

使用道具 舉報

11#
ID:701252 發表于 2020-10-17 09:37 | 只看該作者

學習了!謝謝樓主分享,正想學習pid調節呢!
回復

使用道具 舉報

您需要登錄后才可以回帖 登錄 | 立即注冊

本版積分規則

手機版|小黑屋|51黑電子論壇 |51黑電子論壇6群 QQ 管理員QQ:125739409;技術交流QQ群281945664

Powered by 單片機教程網

快速回復 返回頂部 返回列表
主站蜘蛛池模板: 在线免费观看黄色av | 在线中文字幕日韩 | 狠狠干天天干 | 国产精品美女久久久 | 精品久久久久久久久久久久 | 一区二区中文 | 欧美日韩综合视频 | 欧美成人精品二区三区99精品 | 老司机深夜福利网站 | 91精品久久久久久久 | 久久精品国产一区二区三区 | 91在线看片 | 国产精品网址 | 亚洲精品一区二区三区丝袜 | 亚洲精久 | 久久久夜 | 国产一区二区三区四区三区四 | 久久影音先锋 | 成人免费看黄网站在线观看 | 久久综合色综合 | 日韩视频中文字幕 | 精品一区国产 | 日韩欧美精品一区 | 综合久久综合久久 | 国产精品一二三区 | 91亚洲精品久久久电影 | 狠狠综合网 | 一区二区国产精品 | 干干干操操操 | 黄色片在线免费看 | 日韩国产一区二区三区 | 亚洲一区二区三区在线观看免费 | 网站黄色在线免费观看 | 亚洲精品乱码久久久久久按摩 | 成人一区二区在线 | 中文字幕日韩欧美一区二区三区 | 成人免费日韩 | 久久国产区 | 美女激情av| 日韩精品中文字幕一区二区三区 | 欧洲一区二区三区 |