<delect id="sj01t"></delect>
  1. <em id="sj01t"><label id="sj01t"></label></em>
  2. <div id="sj01t"></div>
    1. <em id="sj01t"></em>

            <div id="sj01t"></div>

            實驗一轉速測量與控制(一)

            時間:2024-10-19 01:56:18 其他畢業論文 我要投稿
            • 相關推薦

            實驗一轉速測量與控制(一)

            由速度傳感器可以將測得的電機轉速轉換成相應的電壓信號,該信號經整形
            放大后送到CPU。CPU將采集來的數據經過一定的算法處理后,送給D/A轉換芯片,該芯片將數字信號轉換為模擬信號輸出,模擬信號經信號放大后,由弱電變為強電,從而實現電機轉速的控制。另外CPU與外界的交互通過I/O接口來實現。

             硬件電路設計原理
             1)信號產生與放大整形
             
            ①速度傳感器
             轉速傳感器將電動機轉速轉化為電壓信號,作為輸入。
            本實驗中采用光電式轉速傳感器,其工作原理是:利用電動機帶動一個圓周上有均勻分布小孔的圓盤來控制發光二極管的光強,使光的強度呈周期性變化。光電二極管的回路電流也呈周期性變化,頻率f=N/60×360=6N Hz,其中N為轉速,單位為 R/min。
             ②信號整形放大
             信號整形放大部分用于將傳感器輸出的幅值較小的電壓信號進行放大整形,使其信號電壓與芯片驅動電壓相匹配,并除去部分干擾,使輸出波形為方波的形勢。
             本實驗中電動機、光電傳感器、信號放大整形電路都集成在一起,封裝于一個圓柱形容器內。輸出的信號經過經過反向器和緩沖器后輸送給82C50單片機T0管腳。
             2)數據采集與處理
             電路板上有一個由555集成定時器構成的單穩態觸發器,提供1秒鐘的定時,來控制74HC244緩沖器的通與斷,這樣單片機計數器一次所累積的數即為脈沖頻率,經換算后可得到電動機的轉速。
             ①單穩態觸發器
             
            555定時器是一種多用途的時基電路,只要在外部配上幾個適當的電阻、電容,就可以構成單穩態觸發器。
             輸出電壓高電平的時間取決于RC的充電時間。
            單穩態觸發器的輸出信號,控制緩沖器74244的通斷,測得的電壓信號通過緩沖器接到8052的T0端口。在這里緩沖器起到了增加驅動、消除干擾的作用。
             ②單片機
             
            本實驗所用CPU為8052,如上圖,當為高電平時,CPU執行片內程序存儲器命令。當為低電平時,CPU實行片外程序存儲器命令。
            在本實驗中單片機主要負責數據的數據采集、數據處理、與鍵盤顯示的交互控制、以及直流電機的控制。
             3)鍵盤與顯示部分
             ①I2C串行總線接口7290
            ZLG7290芯片功能強大,I2C 串行接口提供鍵盤中斷信號方便與處器接口并可驅動8 位共陰數碼管或64 只獨立LED 和64 個按鍵。因為ZLG7290采用I2C串行總線,而AT89C52內部沒有集成I2C總線接口,因此利用軟件模擬I2C總線接口功能。本實驗中采取的是24個管腳的封裝形式。
             如前所述, 7290的SDA、 SCL管腳與8052P10、P11口相連,中斷管腳與8052的INT0相連,Dig0—Dig8連接LED 顯示位驅動及鍵盤掃描線;Seg0—Seg8連接LED 顯示段驅動及鍵盤掃描線 OSC1、OSC2管腳接外部晶振,RES腳接上電復位電路。
             ②鍵盤及數碼管
            數碼管的左四位顯示數值為當前所處狀態,右四位顯示數值為對應狀態的數值。以數值表示的狀態含義如下:
            0101――當前電機轉速
            0102――設置電機轉速
             4ⅹ4鍵盤布鍵如下:
             
             測量當前電機轉速,則按一下“電機”鍵,數碼管右四位即表示當前電機轉速;若要改變轉速,則按一下設置鍵,這時,數碼管左四位顯示“0102”,即可進行設置轉速,設置好后再按“確定”鍵。再按一次“電機”鍵,即可看到電機當前轉速,再按一次又回到設置轉速;設置時如想修改,按“取消”,即可重新輸入設置值(設置值500-2500R/M,否則無效)。
              4)、控制電路
            ①D/A轉換芯片TLV5618
             12位雙通道串行接口;可編程設置轉換時間,高速模式下為2.5us,低速模式下為12us;89C52將保存的設置預期轉速值轉換成串行數據輸出到5618的SDI端,從SDI端輸入的數字信號經TLV5618轉換成模擬信號,由OUTB端輸出,經放大后作用于直流電機,達到閉環控制目的。
             
                ②信號放大器
             直流電機的驅動電流和電壓都比較大,而D/A輸出的信號電壓和電流比較小,電壓范圍為0-5V,不能直接驅動,中間要經過電壓、電流放大。原理圖如下:

             針對ZLG7290的I2C總線讀寫程序如下:
            /*頭文件說明*/
            #include <AT89x52.h>
            #include <Intrins.h>
            #include <math.h>
            /*定義8052的端口*/
            #define iscl P1_1
            #define isda P1_0
            #define sdi  P1_2
            #define sdo  P1_3
            #define sclk P1_4
            #define rd1  P3_5
            /*指針定義*/
            unsigned char xdata *p=0x8001;
            unsigned char xdata *adp=0x8004;
            unsigned char s=1,num=1,need=1,new=0,lp=1;    /*the number of project */
            unsigned char display[]= /* display array */
                          {0,0,0,0,1,1,3};
            unsigned int r1,r2=0,r3=0x0;   /*rotate speed r1測量所得溫度,r2設置所得溫度*/
            unsigned char f1=0;  /* times and congiguration flag ,設置完溫度完成標志 f1=1*/
            unsigned int  bri=0;  /* the value of configuration  設置值*/
            unsigned char m1=0;   /* 設置值的最大位數 */
            /*延時*/
            void delay_ms(unsigned int x)
            {
              unsigned int i,j;
              for (i=0;i<x;i++)
                {j=108;
                 while (j--);
                 };
             }
            /*延時*/
            /*I2C總線的操作*/
            void i2cwait(void)  reentrant 
              {
                    _nop_();
               }
            void i2cinit(void) /*i2c總線的初始化*/
            { isda=1;
              iscl=1;
              }
            void i2cstart(void) /*i2c總線啟動,在串行時鐘iscl為高電平時,串行數據isda出現一個下降沿*/
            {
                isda=1;
                iscl=1;
                i2cwait();
                isda=0;
                i2cwait();
                iscl=0;
             }
            void i2cstop(void) /*i2c總線停止,在串行時鐘iscl為高電平時,isda出現一個上升沿*/
            {
                isda=0;
                i2cwait();
                iscl=1;
                i2cwait();
                isda=1;
                //i2cwait(); /*加兩條語句,保證串行時鐘iscl為低電平,準備數據,即isda只能在iscl為低電平期間改變*/
                //iscl=0;
              }
            unsigned char  i2csentbyte(unsigned char b) /*發送一個字節*/
            {
              unsigned char i,ack=1;
              for (i=0;i<8;i++)
                {
                  if (b & 0x80)  /*i2c總線,先發送最高位(總共八位),通過&運算測試最高位*/
                  isda=1;
                  else
                  isda=0;
                  b<<=1;
                  i2cwait();
                  iscl=1; /*在串行時鐘iscl為高電平期間,串行數據isda線上的數據必須穩定,否則被認為是啟停控制信號*/
                  i2cwait();
                  iscl=0;
                  i2cwait();
                 };
              isda=1; /*代替接收方發送一個應答位,這種情況出現在CPU發送數據時*/
              i2cwait();
              iscl=1;
              i2cwait();
              ack=isda; 
              iscl=0;
              i2cwait();
              return ack ;
                }
            void sendacknowlege(unsigned char ack) /*在每個字節后必須跟一個應答位,由接收方發送*/
              {
               isda=ack;
               iscl=1;
               i2cwait();
               iscl=0;
               i2cwait();
               }
            unsigned char  i2creceivebyte(void) /*接收一個字節*/
             {unsigned char i,a=0;
              for (i=0;i<8;i++)
                {
                 iscl=1; /*在正常數據傳送狀態下,iscl的高電平都對應于isda的穩定數據狀態*/
                 i2cwait();
                 a<<=1;
                 if (isda==1)
                   a|=0x01;  /*通過按位或|和按位與&及循環運算,將數據讀出并賦給變量a*/
                   else
                   a=a&0xfe;
                 iscl=0;
                 i2cwait();
                 };
               return a;
               }
            void writecmd7290(unsigned char i,unsigned char k) /*ZLG7290寄存器映象控制*/
               {
                      EA=0; /*CPU屏蔽所有的中斷申請*/
                      delay_ms(1);
                      i2cinit();
                  i2cstart();
               i2csentbyte(0x70); /*ZLG7290的從地址為70H*/
               i2csentbyte(i);
               i2csentbyte(k);
                 i2cstop();
                      EA=1;  /*CPU開放所有的中斷申請*/
                 }
            void writedata7290(unsigned char i,unsigned char k)  /*ZLG7290命令解釋控制*/
               {
                      EA=0;  /*CPU屏蔽所有的中斷申請*/
                      delay_ms(1);
                      i2cinit();
                  i2cstart();
               i2csentbyte(0x70);  /*ZLG7290的從地址為70H*/
                      i2csentbyte(0x07);  /*命令緩沖區0地址*/
               i2csentbyte(i);  /*寫命令緩沖區0*/
               i2csentbyte(k);  /*地址自動增加,寫命令緩沖區1*/
                 i2cstop();
                      EA=1; /*CPU開放所有的中斷申請*/
                 }
            unsigned char read7290(unsigned char i)
                {unsigned char x=0;
                  EA=0;  /*CPU屏蔽所有的中斷申請*/
                  delay_ms(1);
                  i2cinit();
                  i2cstart();
               i2csentbyte(0x70);  /*ZLG7290的從地址為70H*/
               i2csentbyte(i);
               i2cstart();
               i2csentbyte(0x71);  /*71H ?*/
            x=i2creceivebyte();
               sendacknomlege(0x1);
               i2cstop();
               return x;
                     // EA=1;  /*中斷開放在后邊的中斷子程序執行完之后才開放*/
                 }
            /*I2C OPERATION 2*/
            /* 5618 operation */
            void write5618(unsigned int k)
            {unsigned int i,j;
              EA=0; j=k;  /*CPU屏蔽所有的中斷申請*/
              P1=P1&0x5f;  /*5618地址,使能芯片*/
               _nop_();
              for (i=0;i<16;i++)  /*發送2字節數據:高四位是編程位,低12位是需要轉換的數據*/
               {
                if (j&0x8000)
                  sdi=1;
                 else
                  sdi=0;
                j<<=1;
                sclk=0;
                _nop_();
                sclk=1;
                };
                _nop_();
                _nop_();
              P1=0xff; /*使能結束*/
              EA=1;  /*CPU開放所有的中斷申請*/
            }
            /* 5618 operation */
            /*initial COUNTER0*/ 
            void init_time0()  /*初始化計數器0*/
            { TMOD=0x85;  /*T0:不受外部引腳控制,外部事件計數方式,工作方式為方式1,16位計數器*/
             TH0=0;  /*加計數寄存器高八位為0*/
             TL0=0;  /*加計數寄存器低八位為0*/
             TCON=0x10;  /*中斷控制寄存器:計數器運行控制位TR0=1;外部中斷源觸發方式控制位IT0=0,電平觸發*/
              }
            /*initial COUNTER0*/
            main()
            { unsigned int temp,t3=0xc100;
              unsigned char i=0;
              IE=0x95;IP=0x01;  /*IE:EA=1中斷開放,ES=1允許串口中斷,EX1=1,EX0=1外部中斷1,0允許*/
                  /*IP:PX0=1 外部中斷0定義為高優先級中斷*/
              P1=0xff;P3=P3|0x30;  /*端口初始化:P1為高電平;P3_5=1讀AD7865信號無效,P3_4=1*/
            init_time0();
            /*initiate 5618*/    
             write5618(0x4000);  /*設置DAC B為輸出,選擇快速模式*/
             write5618(0xc000);  /*設置DAC A為輸出,選擇快速模式*/
             /*initiate 5618*/
             /* motor measure start */
              P1=P1&0x3f;            /* triger 555  電機測速使能*/
              _nop_();
              P1=0xff;
             /* motor messure start */
             /*7290*/
              writedata7290(0x65,0);  /*按位下載數據且譯碼指令:第五位顯示'0',不閃爍,小數點不點亮*/
              writedata7290(0x67,0);  /*按位下載數據且譯碼指令:第七位顯示'0',不閃爍,小數點不點亮*/
             /*7290*/
             while(1)
               {
                /*display*/
                 if (need==1)  /*初始need=1,被顯示的數據更新后need=1,做為顯示更新標志need=1*/
                 { writedata7290(0x64,display[4]);  /*按位下載數據且譯碼指令:初始第四位顯示'1',不閃爍,小數點不點亮*/
                   writedata7290(0x66,display[5]);  /*按位下載數據且譯碼指令:初始第六位顯示'1',不閃爍,小數點不點亮*/
                   writecmd7290(0x13,0x0);  /*初始向顯示緩存寄存器DpRam3寫0,即第三位不點亮*/
                   writecmd7290(0x12,0x0);  /*初始向顯示緩存寄存器DpRam2寫0,即第二位不點亮*/
                   writecmd7290(0x11,0x0);  /*初始向顯示緩存寄存器DpRam1寫0,即第一位不點亮*/
                   for (i=0;i<display[6];i++)/*初始第零、一、二顯示'0',不閃爍,小數點不點亮*/
                      writedata7290((0x60+i),display[i]);
                   need=0;
                   };
                 /*display*/
              /* read speed and temperature and electricity*/
                i=*p;  /*7865狀態地址(只讀):0x8001 */
                if(!(i&0x08))   /*電機一次測速完成時執行*/
                  {
                    r1=TH0;r1=(r1<<8)+TL0;  /*將計數器所計的數值賦給r1*/
                    r1=(int)(r1*3/10);  /*?*/
                    TH0=0;TL0=0;EA=0;  /*將計數器清零,為下次計數做準備;關閉中斷*/
                    P1=P1&0x3f;   /* triger 555 電機測速使能*/
                    P1=0xff;EA=1;  /*測速使能完成;開放中斷*/
                    if(!(new&0x80))  /*初始new=0*/
                      if(num==1)  /*初始num=1*/
                           new|=0x01;  /*new=1*/
                   };
                    if(f1)  /*初始f1=0;設置完溫度后 f1=1 */
                     {f1=0; r3=(3*r2/2); 
                      if(r3>0x0fff)  /*D/A變換器是12位的*/
                        r3=0x0fff;
                        };
                      if ((r2>r1)&&(r3<0x0ff9))
                           r3=r3+4;
                      if ((r2<r1)&&(r3>0x05))
                            r3=r3-4;
                        write5618(r3+0x4000);  /*轉速控制,設置DAC B為輸出,選擇快速模式*/
            /*update display array*/
               switch(s)  /*初始 s=1*/
                 {
             /*測速情況*/
                    case 1:display[5]=1;
                           if(num==1)  /*num=1  0101――當前電機轉速*/
                            if (new&0x01)  /*(初始new=0x03;)設定轉速后new=0x01*/
                              {new&=0xfe;i=0;  /*將new清零*/
                               display[4]=1;
                               display[0]=0;
                               need=1;  /*數碼顯示更新標志,下次循環時,將改變數碼管顯示的值*/
                               temp=r1;
                               while (temp!=0)  /*將個、十……為依次放入數組display[i]的前幾位*/
                                {display[i]=temp-(int)(temp/10)*10;
                                 temp=(int)(temp/10);i++;
                                  };
                               if(i==0) i=1;
                               display[6]=i;  /*數組的第六位代表所存數字的位數*/
                               };
                            if (num==2)  /*0102――動態顯示設置電機轉速的過程*/
                               {if (new&0x08)  /*設置速度時new=0x88*/
                                  {need=1;new=0x80;  /*顯示更新標志need置1*/
                  /*將new置0x80,防止設置間隙時,此段程序繼續執行,提高效率*/
                                   display[4]=2;
                                   display[0]=0x40;  /*?*/
                                   temp=bri;i=0;
                                   while (temp!=0)
                                     {display[i]=temp-((int)(temp/10))*10+0x40;
                                      temp=(int)(temp/10);i++;
                                       };
                                    if(i==0)
                                      i=1;
                                    display[6]=i;
                                    };
                                 if (new&0x01)  /*顯示設置結果:“確定”顯示新設置的值,“取消”顯示上次設置的值*/
                                  {need=1;new&=0xfe;  /*將new清零,顯示更新標志need置1*/
                                   display[4]=2;
                                   display[0]=0x0;
                                   temp=r2;i=0;
                                   while (temp!=0)
                                     {display[i]=temp-(int)(temp/10)*10;
                                      temp=(int)(temp/10);i++;
                                       };
                                    if(i==0)
                                       i=1;
                                    display[6]=i;
                                    };
                                  };
                            break;
                  };
            /*update display array*/
               };
              }
            void ext0() interrupt 0 using 3  /*外部中斷0中斷服務函數:鍵值處理*/
            {
              unsigned char b=0;
               delay_ms(40);
               {
               b=read7290(0x01);  /*讀鍵值寄存器的值*/
               switch(b)
                {/*鍵盤:電機鍵*/
                 case 33:new=0x01;//new=new&0x67;
                        if(s==1)
                         {if (num==1)
                            num=2;
                         else
                            num=1;}
                         else
                          {s=1;num=1;
                            };
                         break;
                 /*鍵盤:溫度鍵*/
                 case 34:new=0x02;//new=new&0x67;
                         if (s==2)
                           {if (num==1)
                              num=2;
                           else
                              num=1;}
                          else
                            {s=2;
                             num=1;
                              };
                         break;
                 /*鍵盤:電量鍵*/
                 case 35:new=0x04;//new=new&0x67;
                         if (s!=3)
                           {s=3;
                            num數: A=K2/K1=4.89
             轉速曲線:Vm+  = 0.0077R + 0.87
                         VoutB =0.0016R + 0.52
            1、轉速R與控制電壓VoutB關系曲線

            2、轉速R與電機控制電壓Vm關系曲線

            實驗心得
            通過這個實驗,使我對測速傳感器的工作原理有了一定的了解,并掌握了硬件電路的基本原理,以及軟件的設計方法。
             硬件電路中,用到了許多以前沒有接觸的芯片,如7865,7290,5618等等,對于它們的使用方法,必須從頭學起,閱讀英文的說明書,雖然頗費一番工夫,但在了解芯片的用法的同時,更提升了我閱讀英文參考資料的能力。
             從老師所提供的完整的電路圖中,抽取出各個部分的電路圖,就是建立在
            對實驗原理框圖的掌握和對芯片的了解的基礎上的。
             分析軟件電路時,用到了單片機的知識,由于程序均為用C51編程的,這就不得不在溫習、學習一下這方面的知識。C51特定的函數,以及一些控制字的寫入,中斷程序的設定,與外部器件的接口,都必須叫熟練的掌握,為此我在寫實驗報告時,又參閱、學習了一些單片機的書籍。通過學習使我對單片機的應用有了更深一步的了解。
             最后,將實驗測得的數據,用MATLAB語言畫出擬合的曲線,從曲線上可以明顯看的實驗數據的準確與否。
             感謝張老師的指導,老師在講解實驗原理時是那么的清晰、細致,指導實驗
            時是那么的耐心,這為我完成實驗報告、掌握知識,提供了極大的幫助。
             這次實驗使我受益匪淺

            【實驗一轉速測量與控制(一)】相關文章:

            高速公路施工測量控制與管理(一)03-08

            對一種新型平動電機在恒定轉速下的轉矩仿真11-22

            實驗五 洗衣機自動控制實驗11-22

            自校正模糊控制交流電機轉速調整器的研究與設計03-18

            溫濕度測量(一)03-07

            脈搏測量數字顯示(一)03-07

            實驗名稱:橢圓偏振法測量薄膜厚度和折射率(一)03-07

            電阻測量設計性實驗芻議03-16

            自動控制理論試題(一)03-07

            <delect id="sj01t"></delect>
            1. <em id="sj01t"><label id="sj01t"></label></em>
            2. <div id="sj01t"></div>
              1. <em id="sj01t"></em>

                      <div id="sj01t"></div>
                      黄色视频在线观看