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

 找回密碼
 立即注冊

QQ登錄

只需一步,快速開始

搜索
查看: 4401|回復: 4
收起左側

單片機機械臂PWM波聯合控制多路舵機按規律動作程序仿真 以及壓力傳感器的應用和顯示

  [復制鏈接]
ID:756334 發表于 2020-12-3 21:45 | 顯示全部樓層 |閱讀模式
簡單的機械臂控制系統設計:
   沒有機械臂的具體結構圖,電機處僅代表機械臂關節處的運動情況。
   通過控制電機的運動來控制機械臂的具體動作。
   將貨物從一個固定位置搬運到另一個固定位置,重復此操作。其中用一個壓力傳感器作為機械臂的啟動開關,當壓力傳感器檢測到有貨物存在于貨架上時機械臂開始執行動作,將貨物夾起搬運到另一個位置。當貨物被搬運到另一個位置的時候數碼顯示屏幕記錄下搬運的個數,當搬運完畢后如果傳感器再次檢測到貨架上有貨物,機械臂即再一次執行剛才的動作,將貨物搬運到另一個位置,同時顯示屏顯示的數字加一,記錄下搬運的貨物數量。

機械臂主要結構,各連接處用電機代替

機械臂主要結構,各連接處用電機代替


機械臂末端示意圖
51hei.png

五個舵機:Kpower公司的舵機,分別為:兩個RC20P、一個RD13T、一個RC30P、一個RC05P3。
51hei.png

舵機的選擇的標準:
(1)轉速:轉速由舵機在無負載的情況下轉過60度所需要的時間。
(2)扭矩:可以理解為在舵盤上距舵機軸中心水平距離1厘米處,舵機能夠帶動的物品的重量。舵機扭矩的單位是千克厘米。
2.6軟件設計
    (1)定義芯片引腳
    (2)定義延時函數
(3)定義中斷函數
(4)定義舵機驅動函數
(5)定義模數轉換器轉換函數
(6)定義PWM波函數
(7)定義初始化函數
(8)通過合理的邏輯整理將要實現的功能通過邏輯運算關聯起來,組合成主函數,并多次調試與修改。


仿真原理圖如下(proteus仿真工程文件可到本帖附件中下載)

電路圖

電路圖


單片機源程序如下:
//線性區間標度變換公式:    y=(115-15)/(243-13)*X+15kpa   
#include<reg52.h>
#include <intrins.h>
#include <stdio.h>
#define uchar unsigned char
#define uint unsigned int

//ADC0832的引腳
sbit ADCS =P2^2;    //ADC0832 chip seclect
sbit ADDI =P2^4;    //ADC0832 k in
sbit ADDO =P2^4;    //ADC0832 k out
sbit ADCLK =P2^3;   //ADC0832 clock signal

sbit PWM0 = P3^0;
sbit PWM1 = P3^1;
sbit PWM2 = P3^2;
sbit PWM3 = P3^3;
sbit PWM4 = P3^4;

sbit PWM5 = P1^5;
sbit PWM6 = P1^6;
sbit PWM7 = P1^7;

sbit ADD = P3^4;
sbit B3 = P3^5;

uint t_up0 = 1500;                //舵機PWM高電平時間 1000~2000表示1ms到2ms
uint t_up1 = 1500;
uint t_up2 = 1500;
uint t_up3 = 1500;
uint t_up4 = 1500;

uint t0_h;
uint t0_l;
unsigned int D1,D2,D3,D4;
uint Flag=0;



uchar t0_flag = 0;
uint num_max = 65535;        //
uint t_change = 63036;  //換路周期2.5ms

uchar error0 = 45;
uchar error1 = 45;
uchar error2 = 52;
uchar error3 = 52;
uchar error4 = 57;
uchar error5 = 57;
uchar error6 = 63;
uchar error7 = 63;
uchar error8 = 70;
uchar error9 = 70;


unsigned char dispbitcode[8]={0xf7,0xfb,0xfd,0xfe,0xef,0xdf,0xbf,0x7f};  //位掃描
unsigned char dispcode[11]={0xC0,0xF9,0xA4,0xB0,0x99,0x92,0x82,0xF8,0x80,0x90,0xff};  //共陽數碼管字段碼
unsigned char dispbuf[4]; //顯示數碼管的數組
unsigned int temp;
unsigned char getdata; //獲取ADC轉換回來的值

void delayms(uint ms)
{      
        unsigned char a,b,c;
        while(ms--)
        {               
    for(c=1;c>0;c--)
        for(b=142;b>0;b--)
            for(a=2;a>0;a--);
        }
}
void timer_init()
{
        EA = 1;
        ET0 = 1;
        PT0 = 1;
        TMOD = 0x11;
        TH0 = (65536 - t_up0)/256;
        TL0 = (65536 - t_up0)%256;
}

void timer0() interrupt 1
{      
        if(t0_flag == 0)
        {
                PWM0 = 1;
                TH0 = (num_max - t_up0 + error0+50*2)/256; //是為了抵消執行語句花的時間
                TL0 = (num_max - t_up0 + error0+125)%256;
                t0_flag = 1;
        }
        else if(t0_flag == 1)
        {
                PWM0 = 0;
                TH0 = (t_change + t_up0 +error1+50*2)/256;
                TL0 = (t_change + t_up0 +error1+125)%256;
                t0_flag = 2;
        }
        else if(t0_flag == 2)
        {
                PWM1 = 1;
                TH0 = (num_max - t_up1 + error2+50*2)/256; //是為了抵消執行語句花的時間
                TL0 = (num_max - t_up1 + error2+125)%256;      
                t0_flag = 3;
        }
        else if(t0_flag == 3)
        {
                PWM1 = 0;
                TH0 = (t_change + t_up1 +error3+50*2)/256;
                TL0 = (t_change + t_up1 +error3+125)%256;      
                t0_flag = 4;
        }
        else if(t0_flag == 4)
        {
                PWM2 = 1;
                TH0 = (num_max - t_up2 + error4+50*2)/256; //是為了抵消執行語句花的時間
                TL0 = (num_max - t_up2 + error4+129)%256;      
                t0_flag = 5;
        }
        else if(t0_flag == 5)
        {
                PWM2 = 0;
                TH0 = (t_change + t_up2 +error5+50*2)/256;
                TL0 = (t_change + t_up2 +error5+129)%256;
               
                t0_flag = 6;
        }
        else if(t0_flag == 6)
        {
                PWM3 = 1;
                TH0 = (num_max - t_up3 + error6+50*2)/256; //是為了抵消執行語句花的時間
                TL0 = (num_max - t_up3 + error6+129+1)%256;
               
                t0_flag = 7;
        }
        else if(t0_flag == 7)
        {
                PWM3 = 0;
                TH0 = (t_change + t_up3 +error7+50*2)/256;
                TL0 = (t_change + t_up3 +error7+129+1)%256;      
                t0_flag = 8;
        }
        else if(t0_flag == 8)
        {
                PWM4 = 1;
                  TH0 = (num_max - t_up4 + error8+50*2)/256; //是為了抵消執行語句花的時間
                  TL0 = (num_max - t_up4 + error8+129+1)%256;      
                t0_flag = 9;
        }
        else if(t0_flag == 9)
        {
                PWM4 = 0;
                TH0 = (t_change + t_up4 +error9+50*2+10000)/256;
                TL0 = (t_change + t_up4 +error9+129+1)%256;      
                t0_flag = 0;
        }
      
}

//延時函數
void delay_1ms(void)  //12mhz delay 1.01ms
{
   unsigned char x,y;   
   x=3;
   while(x--)
  {
       y=40;
       while(y--);
    }
}

//顯示函數
void display(void)                          //數碼管顯示函數
{
  char k;
  for(k=0;k<4;k++)
  {

  P1 = dispbitcode[k];
  P0 = dispcode[dispbuf[k]];        //顯示壓力傳感器讀取到的數值,一共四個數
//  if(k==1)                                                  //加上數碼管的dp小數點
//          P0&=0x7f;                                        //p0相與后賦予新的值
    delay_1ms();      

  }
}

/************
讀ADC0832函數
************/

//采集并返回
unsigned int Adc0832(unsigned char channel)     //AD轉換,返回結果
{
    unsigned char i=0;
    unsigned char j;
    unsigned int dat=0;
    unsigned char ndat=0;

    if(channel==0)channel=2;
    if(channel==1)channel=3;
    ADDI=1;
    _nop_();
    _nop_();
    ADCS=0;//拉低CS端
    _nop_();
    _nop_();
    ADCLK=1;//拉高CLK端
    _nop_();
    _nop_();
    ADCLK=0;//拉低CLK端,形成下降沿1
    _nop_();
    _nop_();
    ADCLK=1;//拉高CLK端
    ADDI=channel&0x1;
    _nop_();
    _nop_();
    ADCLK=0;//拉低CLK端,形成下降沿2
    _nop_();
    _nop_();
    ADCLK=1;//拉高CLK端
    ADDI=(channel>>1)&0x1;
    _nop_();
    _nop_();
    ADCLK=0;//拉低CLK端,形成下降沿3
    ADDI=1;//控制命令結束
    _nop_();
    _nop_();
    dat=0;
    for(i=0;i<8;i++)
    {
        dat|=ADDO;//收數據
        ADCLK=1;
        _nop_();
        _nop_();
        ADCLK=0;//形成一次時鐘脈沖
        _nop_();
        _nop_();
        dat<<=1;
        if(i==7)dat|=ADDO;
    }  
    for(i=0;i<8;i++)
    {
        j=0;
        j=j|ADDO;//收數據
        ADCLK=1;
        _nop_();
        _nop_();
        ADCLK=0;//形成一次時鐘脈沖
        _nop_();
        _nop_();
        j=j<<7;
        ndat=ndat|j;
        if(i<7)ndat>>=1;
    }
    ADCS=1;//拉低CS端
    ADCLK=0;//拉低CLK端
    ADDO=1;//拉高數據端,回到初始狀態
    dat<<=8;
    dat|=ndat;
    return(dat);            //return ad k
}



void count(void)   //計算得到D1,D2,D3,D4
{
        unsigned int OverCounter = 0;
        bit OverFlg = 0;
        unsigned int temp,ppress = 0;
        float  press;

        getdata=Adc0832(0);
        if(14<getdata<243)                                  //當壓力值介于15kpa到115kpa之間時,遵循線性變換
        {                           
                int vary=getdata;                                  //y=(115-15)/(243-13)*X+15kpa                              
                press=((10.0/23.0)*vary)+9.3;          //測試時補償值為9.3                                                                                                         
                temp=(int)(press*10);                  //放大10倍,便于后面的計算
               if(temp != ppress)
               {
                          ppress = temp;
                       OverFlg = 1;
                    }                                                                                          
                        D1=temp/1000;                                     //取壓力值百位
                        D2=(temp%1000)/100;                            //取壓力值十位
                        D3=((temp%1000)%100)/10;            //取壓力值個位
                        D4=((temp%1000)%100)%10;                //取壓力值十分位
                }            
}


void KEY(void)  //搬運東西電機轉動程序
{      
                if(Flag<100)                              
                {
                        if(t_up0 <= 1950&&Flag<=30)
                        {
                                t_up0 = t_up0 + 5;
                                delayms(50);
                                Flag++;
                        }
                        if(t_up0 <= 1930&&(Flag>30&&Flag<=50))
                        {
                                t_up1 = t_up1 + 5;
                                delayms(50);
                                Flag++;
                        }
                        if(t_up0 <= 1930&&(Flag>50&&Flag<=70))
                        {
                                t_up2 = t_up2 + 5;
                                delayms(50);
                                Flag++;
                        }
                        if(t_up0 <= 1930&&(Flag>70&&Flag<=80))
                        {
                                t_up3 = t_up3 + 5;
                                delayms(50);
                                Flag++;
                        }
                        if(t_up0 <= 1950&&(Flag>80&&Flag<=100))
                        {
                                t_up4 = t_up4 + 5;
                                delayms(50);
                                Flag++;
                        }                                                      
                }
}

void KEY0(void)
{
                        if(t_up0 <= 1950&&Flag>=80)
                        {
                                t_up4 = t_up4 - 5;
                                delayms(50);
                                Flag--;
                        }

                        if(t_up0 <= 1930&&(Flag>=70&&Flag<80))
                        {
                                t_up3 = t_up3 - 5;
                                delayms(50);
                                Flag--;
                        }
                        if(t_up0 <= 1930&&(Flag>=50&&Flag<70))
                        {
                                t_up2 = t_up2 - 5;
                                delayms(50);
                                Flag--;
                        }
                        if(t_up0 <= 1930&&(Flag>=30&&Flag<50))
                        {
                                t_up1 = t_up1 - 5;
                                delayms(50);
                                Flag--;
                        }

                        if(t_up0 <= 1950&&(Flag>=0&&Flag<30))
                        {
                                t_up0 = t_up0 - 5;
                                delayms(50);
                                Flag--;
                        }

}

void main(void)
{
        uint a=1,b=0,c=0,d=0;
        uint flag=0,F=1,num,i=1;
        timer_init();
        TR0 = 1;

        while(1)
        {
        count();
        while(D2^F)                                                   //壓力值出現變化
        {
                if(D2<2)
                {
                        while(D2^F)
                        {
                                count();
                                 if(D2>=2)
                                {
                                        flag=1;
                                        i=1;
                                        num++;
                                        if(num>0)
                                        a++;
                                        if(num==10)
                                        a=0;
                                        if(num>=10&&num<20)
                                        b=1;
                                        if(num>=1000)
                                        d++;

                                        while(Flag>0)
                                        {
                                        KEY0();
                                        }        
                                        F=D2;
                                }
                        }
                }                                                                                                                                                                                                                                                                 
                else
                F=D2;                                                                                         
        }

        dispbuf[0]=a;  //個位                                                         
        dispbuf[1]=b;  //十位
        dispbuf[2]=c;  //百位
        dispbuf[3]=d;  //千位

        if(D2>=2)
        {
                flag=1;
                i=1;
        }
        if(flag==1&&i==1)
        {
                KEY();
        }
        if(Flag==100)
        display();
        }                    
}
51hei.png
全部資料51hei下載地址:
《基于單片機機械臂控制系統設計》.zip (1.36 MB, 下載次數: 102)

評分

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

查看全部評分

回復

使用道具 舉報

ID:582255 發表于 2021-1-5 15:36 | 顯示全部樓層
請問一下樓主,機械臂的扭矩是多少?里面木有說啊
回復

使用道具 舉報

ID:582255 發表于 2021-1-24 14:38 | 顯示全部樓層
說的壓力傳感器在哪 哦
回復

使用道具 舉報

ID:77126 發表于 2021-6-28 15:21 | 顯示全部樓層
謝謝樓主分享,下來好好學習!
回復

使用道具 舉報

ID:479857 發表于 2021-7-1 15:26 | 顯示全部樓層
樓主數碼管無顯示是因為數值沒傳到主函數
回復

使用道具 舉報

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

本版積分規則

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

Powered by 單片機教程網

快速回復 返回頂部 返回列表
主站蜘蛛池模板: 国产一区二 | 亚洲一区二区视频 | 狠狠久| 91亚洲欧美| 在线视频一区二区三区 | 一级毛片视频免费观看 | 亚洲一区亚洲二区 | 国产精品国产a | 日韩精品一区二区三区视频播放 | 午夜三区| 久久久不卡网国产精品一区 | 综合欧美亚洲 | 浮生影院免费观看中文版 | 亚洲欧洲成人 | 成人精品一区二区三区中文字幕 | 性视频一区 | 羞羞视频在线观看网站 | 欧美区在线 | 精品视频一区二区三区在线观看 | 成人在线视频免费观看 | 激情欧美日韩一区二区 | 欧美成人综合 | 欧美高清性xxxxhdvideosex | 成人午夜免费在线视频 | 亚洲欧美视频一区 | 丝袜 亚洲 另类 欧美 综合 | 国产一区二区三区在线免费 | 日韩中文字幕 | 精品免费| 中文字幕一二三 | 九九视频网 | 色综合久久天天综合网 | 成人不卡| 不卡的av在线 | 尤物在线| 日韩视频在线免费观看 | 在线观看国产wwwa级羞羞视频 | 国产丝袜人妖cd露出 | 国产激情视频网站 | 精品一区二区三区四区 | 欧美老妇交乱视频 |