計算機控制技術實驗說明

      網友投稿 703 2022-05-29

      編程實驗分別仿真和實驗臺操作兩種方式。

      實驗1 AD轉換--輸入

      AD轉換是所有嵌入式系統或機器人獲取外部信息的一種重要方式,將溫度、角度和位置等轉換為對應的數字量,供處理器處理。

      原理圖:

      程序:

      計算機控制技術實驗說明

      /*************** ex1 ******************/

      #include

      #define uint unsigned int

      #define uchar unsigned char

      uchar code LEDData[]=

      {

      0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f

      };

      sbit OE = P1^0;

      sbit EOC = P1^1;

      sbit ST = P1^2;

      sbit CLK = P1^3;

      void DelayMS(uint ms)

      {

      uchar i;

      while(ms--)

      {

      for(i=0;i<120;i++);

      }

      }

      void Display_Result(uchar d)

      {

      P2 = 0xf7;

      P0 = LEDData[d%10];

      DelayMS(5);

      P2 = 0xfb;

      P0 = LEDData[d%100/10];

      DelayMS(5);

      P2 = 0xfd;

      P0 = LEDData[d/100];

      DelayMS(5);

      }

      void main()

      {

      TMOD = 0x02;

      TH0 = 0x14;

      TL0 = 0x00;

      IE = 0x82;

      TR0 = 1;

      P1 = 0x3f;

      while(1)

      {

      ST = 0;

      ST = 1;

      ST = 0;

      while(EOC == 0);

      OE = 1;

      Display_Result(P3);

      OE = 0;

      }

      }

      void Timer0_INT() interrupt 1

      {

      CLK = !CLK;

      }

      實驗臺,測量電壓值并顯示:

      代碼:

      //模數實驗

      #include "reg52.h"

      #define uint unsigned int

      #define uchar unsigned char

      #define ulong unsigned long

      sbit LE1=P3^3;

      //定義數值顯示

      uchar code xianshi[11]={0xFC,0x60,0xDA,0xF2,0x66,0xB6,0xbE,0xE0,0xFE,0xF6,0x00};

      sbit ST=P3^0; //起始

      sbit OE=P3^1; //使能

      sbit EOC=P3^2; //轉換完成標志位

      sbit ADD_A=P3^5; //輸入端口選擇A

      sbit ADD_B=P3^6; //輸入端口選擇B

      sbit ADD_C=P3^7; //輸入端口選擇C

      uint getdata,average,n,volt,sum; //變量

      void delay1_ms(uint time) //延時

      {

      uint i,j;

      for(i=0;i

      for(j=0;j<123;j++);

      }

      void display_num1(uint dat,uchar num1) //顯示數值

      {

      // P2=0x00;

      // P0=0x00;

      P0=xianshi[dat];

      switch(num1)

      {

      case 1: P2=0x01;break;

      case 2: P2=0x02;break;

      case 3: P2=0x04;break;

      case 4: P2=0x08;break;

      case 5: P2=0x10;break;

      case 6: P2=0x20;break;

      case 7: P2=0x40;break;

      case 8: P2=0x80;break;

      default: break;

      }

      delay1_ms(1);

      //P0=0x00;

      }

      //數碼管4位顯示函數

      void display_num4(uint num)

      {

      uint wan;

      uint qian;

      uint bai;

      uint shi;

      uint ge;

      P2=0x00;

      wan=(num/10000)%10;

      if(wan==0) wan=10;

      display_num1(wan,5);

      qian=(num/1000)%10;

      if(wan==10&&qian==0) qian=10;

      display_num1(qian,4);

      bai=(num/100)%10;

      if(wan==10&&qian==10&&bai==0) bai=10;

      display_num1(bai,3);

      shi=(num/10)%10;

      if(wan==10&&qian==10&&bai==10&&shi==0) shi=10;

      display_num1(shi,2);

      ge=num%10;

      display_num1(ge,1);

      }

      void delay(uint N)

      {

      while(N--);

      }

      uint adconvert_date()

      {

      ST=0;

      ST=1;

      delay(2);

      ST=0;

      while(!EOC);

      OE=1;

      delay(2);

      getdata=P1;

      delay(2);

      OE=0;

      return getdata;

      }

      void main()

      {

      uint i;

      uint n;

      uint volt;

      ulong sum=0;

      uint average;

      P2=0x00;

      ADD_A=0;

      ADD_B=0;

      ADD_C=0;

      delay(1000);

      while(1)

      {

      ADD_A=0;

      ADD_B=0;

      ADD_C=0;

      ST=0;

      P2=0x00;

      for(n=0;n<10;n++)

      {

      volt=adconvert_date(); //測量可變電阻電壓

      sum += volt; //累加次數50

      }

      average=sum/10; //取平均值

      average=average*19.4; //換算成電壓值 19.4=OK

      sum=0; //和清零

      for(i=0;i<400;i++)

      display_num4(average); //顯示平均值

      }

      }

      DA轉換將控制器結果轉為模擬量控制外部設備。最常用的實驗是波形仿真。

      數字調壓:

      代碼:

      #include

      #define uint unsigned int

      #define uchar unsigned char

      sbit K1 = P3^0;

      sbit K2 = P3^1;

      sbit K3 = P3^2;

      sbit K4 = P3^3;

      sbit K5 = P3^4;

      sbit K6 = P3^5;

      sbit K7 = P3^6;

      sbit K8 = P3^7;

      void DelayMS(uint ms)

      {

      uchar i;

      while(ms--)

      {

      for(i=0;i<120;i++);

      }

      }

      void main()

      {

      P2 = 0x00;

      while(1)

      {

      if(K1 == 0) P2 = 0;

      if(K2 == 0) P2 = 35;

      if(K3 == 0) P2 = 70;

      if(K4 == 0) P2 = 105;

      if(K5 == 0) P2 = 140;

      if(K6 == 0) P2 = 175;

      if(K7 == 0) P2 = 210;

      if(K8 == 0) P2 = 255;

      DelayMS(2);

      }

      }

      代碼:

      #include

      #include

      #define uint unsigned int

      #define uchar unsigned char

      #define DAC0832 XBYTE[0xfffe]

      char code sin_data[256]={0x80,0x83,0x86,0x89,0x8c,0x8f,0x92,0x95,0x98,0x9c,0x9f,0xa2,0xa5,0xa8,

      0xab,0xae,0xb0,0xb3,0xb6,0xb9,0xbc,0xbf,0xc1,0xc4,0xc7,0xc9,0xcc,0xce,0xd1,0xd3,0xd5,

      0xd8,0xda,0xdc,0xde,0xe0,0xe2,0xe4,0xe6,0xe8,0xea,0xec,0xed,0xef,0xf0,0xf2,0xf3,0xf4,

      0xf6,0xf7,0xf8,0xf9,0xfa,0xfb,0xfc,0xfc,0xfd,0xfe,0xfe,0xff,0xff,0xff,0xff,0xff,0xff,

      0xff,0xff,0xff,0xff,0xff,0xfe,0xfe,0xfd,0xfc,0xfc,0xfb,0xfa,0xf9,0xf8,0xf7,0xf6,0xf5,

      0xf3,0xf2,0xf0,0xef,0xed,0xec,0xea,0xe8,0xe6,0xe4,0xe3,0xe1,0xde,0xdc,0xda,0xd8,0xd6,

      0xd3,0xd1,0xce,0xcc,0xc9,0xc7,0xc4,0xc1,0xbf,0xbc,0xb9,0xb6,0xb4,0xb1,0xae,0xab,0xa8,

      0xa5,0xa2,0x9f,0x9c,0x99,0x96,0x92,0x8f,0x8c,0x89,0x86,0x83,0x80,0x7d,0x79,0x76,0x73,

      0x70,0x6d,0x6a,0x67,0x64,0x61,0x5e,0x5b,0x58,0x55,0x52,0x4f,0x4c,0x49,0x46,0x43,0x41,

      0x3e,0x3b,0x39,0x36,0x33,0x31,0x2e,0x2c,0x2a,0x27,0x25,0x23,0x21,0x1f,0x1d,0x1b,0x19,

      0x17,0x15,0x14,0x12,0x10,0xf,0xd,0xc,0xb,0x9,0x8,0x7,0x6,0x5,0x4,0x3,0x3,0x2,0x1,0x1,

      0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x1,0x1,0x2,0x3,0x3,0x4,0x5,0x6,0x7,0x8,

      0x9,0xa,0xc,0xd,0xe,0x10,0x12,0x13,0x15,0x17,0x18,0x1a,0x1c,0x1e,0x20,0x23,0x25,0x27,

      0x29,0x2c,0x2e,0x30,0x33,0x35,0x38,0x3b,0x3d,0x40,0x43,0x46,0x48,0x4b,0x4e,0x51,0x54,

      0x57,0x5a,0x5d,0x60,0x63,0x66,0x69,0x6c,0x6f,0x73,0x76,0x79,0x7c};//正弦碼表,可通過SIN()函數獲得

      void DelayMS(uint ms)

      {

      uchar i;

      while(ms--)

      {

      for(i=0;i<120;i++);

      }

      }

      void delay_nus(unsigned int i)

      {

      unsigned int j;

      while(i--)

      {

      for(j=0;j<127;j++);

      }

      }

      /**********************************************/

      void delay(unsigned char i)

      {

      unsigned char t;

      for(t=0;t

      }

      /**********************************************

      輸出數據到端口(注意考慮延時)

      **********************************************/

      void conversion(unsigned char out_data)

      {

      DAC0832 =out_data; //輸出數據

      delay(1);

      //delay_nus(10); //延時等待轉換

      }

      /************************************************

      產生正弦波函數

      ************************************************/

      void sine(void)

      {

      unsigned char i;

      for(i=0;i<255;i++)

      {

      conversion(sin_data[i]);

      }

      }

      /***********************************************

      產生鋸齒波(下降型)

      ***********************************************/

      void saw(void)

      {

      unsigned char j;

      for(j=0;j<255;j++)

      conversion(j);

      }

      /***********************************************

      產生方波(脈沖)

      ***********************************************/

      void pulse(void)

      {

      conversion(0xff);

      delay_nus(1000);

      conversion(0x00);

      delay_nus(1000);

      }

      /***********************************************

      產生三角波

      ***********************************************/

      void triangle(void)

      {

      unsigned char k;

      for(k=0;k<255;k++)

      conversion(k);

      for(;k>0;k--)

      conversion(k);

      }

      void main()

      {

      while(1)

      {

      // pulse();

      // saw();

      // sine();

      triangle();

      }

      }

      代碼:

      #include"reg52.h"

      char code sin_data[256]={0x80,0x83,0x86,0x89,0x8c,0x8f,0x92,0x95,0x98,0x9c,0x9f,0xa2,0xa5,0xa8,

      0xab,0xae,0xb0,0xb3,0xb6,0xb9,0xbc,0xbf,0xc1,0xc4,0xc7,0xc9,0xcc,0xce,0xd1,0xd3,0xd5,

      0xd8,0xda,0xdc,0xde,0xe0,0xe2,0xe4,0xe6,0xe8,0xea,0xec,0xed,0xef,0xf0,0xf2,0xf3,0xf4,

      0xf6,0xf7,0xf8,0xf9,0xfa,0xfb,0xfc,0xfc,0xfd,0xfe,0xfe,0xff,0xff,0xff,0xff,0xff,0xff,

      0xff,0xff,0xff,0xff,0xff,0xfe,0xfe,0xfd,0xfc,0xfc,0xfb,0xfa,0xf9,0xf8,0xf7,0xf6,0xf5,

      0xf3,0xf2,0xf0,0xef,0xed,0xec,0xea,0xe8,0xe6,0xe4,0xe3,0xe1,0xde,0xdc,0xda,0xd8,0xd6,

      0xd3,0xd1,0xce,0xcc,0xc9,0xc7,0xc4,0xc1,0xbf,0xbc,0xb9,0xb6,0xb4,0xb1,0xae,0xab,0xa8,

      0xa5,0xa2,0x9f,0x9c,0x99,0x96,0x92,0x8f,0x8c,0x89,0x86,0x83,0x80,0x7d,0x79,0x76,0x73,

      0x70,0x6d,0x6a,0x67,0x64,0x61,0x5e,0x5b,0x58,0x55,0x52,0x4f,0x4c,0x49,0x46,0x43,0x41,

      0x3e,0x3b,0x39,0x36,0x33,0x31,0x2e,0x2c,0x2a,0x27,0x25,0x23,0x21,0x1f,0x1d,0x1b,0x19,

      0x17,0x15,0x14,0x12,0x10,0xf,0xd,0xc,0xb,0x9,0x8,0x7,0x6,0x5,0x4,0x3,0x3,0x2,0x1,0x1,

      0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x1,0x1,0x2,0x3,0x3,0x4,0x5,0x6,0x7,0x8,

      0x9,0xa,0xc,0xd,0xe,0x10,0x12,0x13,0x15,0x17,0x18,0x1a,0x1c,0x1e,0x20,0x23,0x25,0x27,

      0x29,0x2c,0x2e,0x30,0x33,0x35,0x38,0x3b,0x3d,0x40,0x43,0x46,0x48,0x4b,0x4e,0x51,0x54,

      0x57,0x5a,0x5d,0x60,0x63,0x66,0x69,0x6c,0x6f,0x73,0x76,0x79,0x7c};//正弦碼表,可通過SIN()函數獲得

      void delay_nus(unsigned int i)

      {

      unsigned int j;

      while(i--)

      {

      for(j=0;j<127;j++);

      }

      }

      /**********************************************/

      void delay(unsigned char i)

      {

      unsigned char t;

      for(t=0;t

      }

      /**********************************************

      輸出數據到端口(注意考慮延時)

      **********************************************/

      void conversion(unsigned char out_data)

      {

      P0=out_data; //輸出數據

      delay(5);

      //delay_nus(10); //延時等待轉換

      }

      /************************************************

      產生正弦波函數

      ************************************************/

      void sine(void)

      {

      unsigned char i;

      for(i=0;i<255;i++)

      {

      conversion(sin_data[i]);

      }

      }

      /***********************************************

      產生鋸齒波(下降型)

      ***********************************************/

      void saw(void)

      {

      unsigned char j;

      for(j=0;j<255;j++)

      conversion(j);

      }

      /***********************************************

      產生方波(脈沖)

      ***********************************************/

      void pulse(void)

      {

      conversion(0xff);

      delay_nus(1000);

      conversion(0x00);

      delay_nus(1000);

      }

      /***********************************************

      產生三角波

      ***********************************************/

      void triangle(void)

      {

      unsigned char k;

      for(k=0;k<255;k++)

      conversion(k);

      for(;k>0;k--)

      conversion(k);

      }

      void main()

      {

      while(1)

      {

      pulse();

      //saw();

      //sine();

      //triangle();

      }

      }

      實驗臺:

      代碼:

      #include"reg52.h"

      #include "math.h"

      #define uchar unsigned char

      #define uint unsigned int

      uchar code xianshi[12]={0xFC,0x60,0xDA,0xF2,0x66,0xB6,0xbE,0xE0,0xFE,0xF6,0x9c,0x00};

      sbit PWM=P1^7;

      sbit key1=P1^0;

      sbit key2=P1^1;

      sbit key3=P1^2;

      uint wide=100;//脈寬計數

      uint t1=0; //低電平脈寬

      uint t2=0; //一個周期

      uint time_low=0;

      uint time_high=100;

      bit high_flag=0;

      bit low_flag=0;

      bit state_flag=0;

      uint set_count=100;//設定轉速值

      uint run_count=0;//實際頻率的讀取

      uint stop_count=0; //電機轉速存儲變量

      uint time=0;

      int en=0,en_1=0,en_2=0; //定義 三個時刻的誤差存儲變量

      float a0=1.7,a1=0.30,a2 =0.002,un=0; //定義PID計算參公式的參數

      void delay1_ms(uint time);

      void delay(uint time);

      void display_num1(uint dat,uchar num1);

      void display_num4(uint num);

      void time01_initiat(void);

      void key_precess(void);

      void pid(void);

      void main()

      {

      time01_initiat(); //初始化定時器0和定時器1

      while(1)

      {

      key_precess(); //鍵盤掃描函數

      }

      }

      //1ms延時函數

      void delay1_ms(uint time)

      {

      uint i,j;

      for(i=0;i

      for(j=0;j<123;j++);

      }

      //指定的位上顯示 指定的一位數據

      void display_num1(uint dat,uchar num1)

      {

      P0=xianshi[dat]; //段顯

      switch(num1)

      {

      case 1: P2=0x01;break;

      case 2: P2=0x02;break;

      case 3: P2=0x04;break;

      case 4: P2=0x08;break;

      default: break;

      }

      delay1_ms(2);

      }

      //四位數據顯示函數

      void display_num4(uint num)

      {

      uint qian;

      uint bai;

      uint shi;

      uint ge;

      qian=num/1000;

      if(qian==0)// qian=11;

      display_num1(11,4);

      bai=num%1000;

      bai=bai/100;

      if(qian==10&&bai==0) bai=10;

      display_num1(bai,3);

      shi=num%100;

      shi=shi/10;

      if(qian==10&&bai==10&&shi==0) shi=10;

      display_num1(shi,2);

      ge=num%10;

      display_num1(ge,1);

      }

      //四位數據顯示函數

      void display_num4_1(uint num)

      {

      uint qian;

      uint bai;

      uint shi;

      uint ge;

      display_num1(10,4);

      bai=num%1000;

      bai=bai/100;

      if(qian==10&&bai==0) bai=10;

      display_num1(bai,3);

      shi=num%100;

      shi=shi/10;

      if(qian==10&&bai==10&&shi==0) shi=10;

      display_num1(shi,2);

      ge=num%10;

      display_num1(ge,1);

      }

      void delay(uint time)

      {

      uint i;

      for(i=0;i

      display_num4_1(stop_count);

      }

      void delay1(uint num)

      {

      uint i;

      for(i=0;i

      display_num4(set_count);

      }

      void time01_initiat()

      {

      TMOD=0X11; //計數器0和定時器1

      TL0=0X33;

      TH0=0XFE;//計數器0賦初值 0.5ms

      TH1=0X4C;

      TL1=0X00;//定時器1賦初值 50ms

      EA=1;

      PT0=1;

      ET0=1;

      ET1=1;

      TR0=0;

      TR1=0;

      IT0=1;

      EX0=0;

      }

      void key_precess()

      {

      if(key1==0&&key2==1&&key3==1) //判斷系統的運行模式,如果KEY1鍵 按下

      //且state_flag為1則系統處于運行模式,如果state__flag為0則為設置模式

      {

      while(key1==0);

      state_flag=~state_flag;

      if(state_flag==1)

      {

      EX0=1;

      TR1=1;

      TR0=1;

      en =0;

      en_1 =0;

      en_2 =0;

      un =0;

      wide=150;

      //wide = set_count;

      }

      }

      if(key1==1&&key2==0&&key3==1&&state_flag==0) //KEY2為按鍵加

      {

      //while(key2==0);

      delay1(20);

      set_count+=1;

      if(set_count>300) set_count=100;

      }

      if(key1==1&&key2==1&&key3==0&&state_flag==0) //KEY3為按鍵減

      {

      // while(key3==0);

      delay1(20);

      if(set_count>100) set_count-=1;

      if(set_count==100) set_count=300;

      }

      if(state_flag==0) //如果系統處于設置模式,則關閉定時器中斷和外部中斷,同時初始化部分變量

      {

      PWM = 0;

      EX0=0;

      TR0=0;

      TR1=0;

      run_count=0;

      stop_count=0;

      time=0;

      t1=0;

      t2=0;

      display_num4(set_count);

      }

      if(state_flag==1) //如果系統處于運行模式則顯示電機的實際轉速值

      {

      display_num4_1(stop_count);

      }

      }

      void pid(void) //PID 計算輸出量

      {

      en=set_count-stop_count;

      un=1.7*en-0.03*en_1+0.002*en_2;//計算輸出量

      if(un > 400)un = 400;

      if(un <-400)un = -400;

      en_2=en_1; //更新誤差

      en_1=en;

      wide = wide + un/4; //計算wide,用于調節PWM的占空比,計算周期為100ms

      if(wide>900)wide=900; //防止超限,確保計算餓wide值有效

      if(wide<10)wide=10;

      }

      //外部中斷0用于電機轉速測量

      void int0() interrupt 0

      {

      EX0=0;

      run_count++;

      EX0=1;

      }

      //定時器0用于產生PWM ,占空比通過PID計算獲得

      void time0() interrupt 1

      {

      TL0=0X9c;

      TH0=0XFF;//計數器0賦初值 100us

      TR0=0;

      if(low_flag==0)t1++;//低電平時間計時

      t2++;

      if(t2==1000) //用于確定PWM的周期 ,t2乘以定時器的中斷周期即為PWM的周期

      {

      PWM=1;

      t2=0;

      low_flag=0;

      }

      if(t1==wide)//wide的值即為低電平的時間

      {

      PWM=0;

      t1=0;

      low_flag=1;

      }

      TR0=1;

      }

      void time1() interrupt 3

      {

      TH1=0X3C;

      TL1=0XBD; //50ms定時

      TR1=0;

      time++;

      if(time==40) //定時2s到,讀取到的值run_count即為電機每秒的轉速值

      {

      stop_count=run_count/2;

      time=0;

      run_count=0;

      pid(); //調用PID算法

      }

      TR1=1;

      }

      版權聲明:本文內容由網絡用戶投稿,版權歸原作者所有,本站不擁有其著作權,亦不承擔相應法律責任。如果您發現本站中有涉嫌抄襲或描述失實的內容,請聯系我們jiasou666@gmail.com 處理,核實后本網站將在24小時內刪除侵權內容。

      上一篇:物聯網網關開發:基于MQTT消息總線的設計過程丨【拜托了,物聯網!】
      下一篇:凱利公式(莊家必勝篇)——致放假在家的高薪程序員們
      相關文章
      久久久久久亚洲精品中文字幕| 亚洲狠狠成人综合网| 亚洲偷自拍另类图片二区| 久久精品国产亚洲AV电影| 亚洲av无码一区二区三区乱子伦| 亚洲熟女一区二区三区| 亚洲精品高清一二区久久| 另类专区另类专区亚洲| 久久综合亚洲色hezyo| 亚洲AV无码一区二区三区久久精品| 亚洲国产欧美一区二区三区| 日本亚洲色大成网站www久久| 亚洲大成色www永久网址| 亚洲卡一卡二卡乱码新区| 亚洲精品123区在线观看| 亚洲久热无码av中文字幕| 亚洲人成自拍网站在线观看| 亚洲欧美日韩中文高清www777| 亚洲中文无码亚洲人成影院| 亚洲精品无码久久久久YW| 亚洲AV综合色区无码一二三区| 国产精品亚洲专区一区| 亚洲毛片av日韩av无码| 三上悠亚亚洲一区高清| 国产亚洲美女精品久久久久狼| 亚洲色偷偷综合亚洲AVYP| 国产亚洲成AV人片在线观黄桃 | 亚洲一区精品无码| 亚洲色自偷自拍另类小说| 亚洲精品乱码久久久久久久久久久久| 亚洲另类激情综合偷自拍图| 亚洲AV无码欧洲AV无码网站| 老司机亚洲精品影院| 亚洲国产精品成人精品软件 | 久久影院亚洲一区| 亚洲AV无码成人精品区天堂| 亚洲高清视频免费| 亚洲色欲啪啪久久WWW综合网| 亚洲爆乳无码专区www| 亚洲国产精品无码久久98| 亚洲成a人片在线观看老师|