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

 找回密碼
 立即注冊

QQ登錄

只需一步,快速開始

搜索
查看: 5783|回復: 4
打印 上一主題 下一主題
收起左側(cè)

51單片機舵機控制程序

[復制鏈接]
跳轉(zhuǎn)到指定樓層
樓主
ID:301968 發(fā)表于 2018-6-21 14:16 | 只看該作者 回帖獎勵 |倒序瀏覽 |閱讀模式
/**********************
   舵機控制PWM/按鍵控制/LED顯示
    V1.0版
******************************************/   

#include "STC15W40XXX.H"
#include "intrins.h"
//定義主時鐘
#define FOSC 33177600UL
#define T1000Hz (FOSC / 12 / 1000)
#define CCP_S0 0x10 //P_SW1.4
#define CCP_S1 0x20 //P_SW1.5

//************** PWM8 變量和常量以及IO口定義 ***************
//********************  6通道8 bit 軟PWM ********************

sbit  P_PWM6 =  P3^4;           //  舵機1 PWM定義IO
sbit  P_PWM5 =  P3^5;      //  舵機2 PWM定義IO
sbit  P_PWM4 =  P3^6;          //  舵機3 PWM定義IO
sbit  P_PWM3 =  P2^0;
sbit  P_PWM2 =  P2^1;
sbit  P_PWM1 =  P2^2;
sbit  LED1 = P2^3;
sbit  LED2 = P2^4;
sbit  LED3  = P2^5;
sbit  LED4  = P2^6;
sbit  LED5  = P2^7;
sbit  LED6  = P1^0;
sbit  Key1=P5^5;          //單個舵機轉(zhuǎn)動
sbit  Key2=P5^4;          //全部舵機轉(zhuǎn)動
sbit  Key3=P1^7;          //復位按鍵
bit Reset=0;
uint P1_11us=0;
uint cnt;
uint value;
uchar K1_cont=0;
uchar K2_cont=0;
unsigned char  j;
unsigned char KeySta[3] = { 1, 1,  1 };  //全部按鍵的當前狀態(tài)
unsigned char backup[3] = { 1, 1,  1 };   //按鍵值備份,保存前一次的值
uint Ptem_angle[6]={90,90,90,90,90,90};     //6個舵機臨時存儲角度(在0-180內(nèi))
uint SetP_angle[6] ={90,90,90,90,90,90}; //6個設定舵機轉(zhuǎn)動角(0-180)(11us*(45-225)=0.5ms -2.5ms

//--------------------
void UartInit();        [url=]//9600bps@33.1776MHz[/url]
void Timer0Init();      //Timer0 set
void PCATimerInit();    //Timer0 set
void Key_scan();      //按鍵掃描函數(shù)
void Key_Function();     //按鍵功能函數(shù)
void LDE_Shew();         //LED顯示函數(shù)
void Motor_Run();         //LED顯示函數(shù)
   
void Delay500ms()  [url=]//@33.1776MHz[/url]
{
unsigned char i, j, k;
_nop_();
_nop_();
i = 64;
j = 9;
k = 179;
do
{
  do
  {
   while (--k);
  } while (--j);
} while (--i);
}

/**********************************************/
void main()
{

PCATimerInit();   //PCA定時器初始化
Timer0Init();    //定時器0初始化
UartInit();     //串口初始化
EA = 1;           //打開總中斷
Delay500ms();

while(1)
{
Key_Function();
LDE_Shew();
}
}
/********************** Timer0 11us中斷函數(shù) ************************/
//為什么要定義11us的中斷,因為20ms的周期信號控制舵機轉(zhuǎn)動,0.5-2.5中,只有2ms時間高電平控制0-180的角度。
//因此轉(zhuǎn)動1度時,需要11us的時間(一次中斷產(chǎn)生),180度需要1980us,約2MS,例如轉(zhuǎn)動90度是1.5MS高和18.5的低,
//一個周期20ms產(chǎn)生1800次的中斷,其中90+45=135次中斷為高,1800-135=1665次為低。循環(huán)得到結(jié)果
void timer0 (void) interrupt 1
{   

switch (K1_cont)

      {
    case 0:  P_PWM1=0;  break;
               
    case 1:  Motor_Run();  P_PWM2= P_PWM3= P_PWM4= P_PWM5= P_PWM6= 0;
        if(P1_11us<=Ptem_angle[K1_cont-1]) { P_PWM1 =  1; }  else  { P_PWM1 =  0; }  break;
      
    case 2:  Motor_Run(); P_PWM1=P_PWM3=P_PWM4=P_PWM5=P_PWM6= 0;
        if(P1_11us<=Ptem_angle[K1_cont-1]) { P_PWM2 =  1; }  else { P_PWM2 =  0; }  break;
   
    case 3:  Motor_Run(); P_PWM1 =P_PWM2=P_PWM4=P_PWM5=P_PWM6= 0;     
        if(P1_11us<=Ptem_angle[K1_cont-1]) { P_PWM3 =  1; } else { P_PWM3 =  0;  }  break;

    case 4:  Motor_Run(); P_PWM1 =P_PWM2=P_PWM3=P_PWM5=P_PWM6= 0;     
        if(P1_11us<=Ptem_angle[K1_cont-1]) { P_PWM4 =  1;  } else  { P_PWM4 =  0; }  break;
         
     case 5:  Motor_Run();  P_PWM1 =P_PWM2=P_PWM3=P_PWM4=P_PWM6=0;   
        if(P1_11us<=Ptem_angle[K1_cont-1]) { P_PWM5 =  1;  } else { P_PWM5 =  0;  }  break;
    case 6:  Motor_Run(); P_PWM1=P_PWM2=P_PWM3= P_PWM4= P_PWM5=0;   
        if(P1_11us<=Ptem_angle[K1_cont-1]) { P_PWM6 =  1;  } else { P_PWM6 =  0;  }  break;      
   
    default: break;
   
    }

  }
//PCA定時器中斷
void PCA_isr() interrupt 7 using 1
{
    CCF0 = 0;                       //清中斷標志
    CCAP0L = value;
    CCAP0H = value >> 8;            //更新比較值
    value += T1000Hz;
    if (cnt-- == 0)
    {
        cnt = 2000;                  //記數(shù)1000次
        SBUF=0XFF;
    }
  Key_scan();
}
//*************************************************************************
//UART  串口中斷
void Uart() interrupt 4 using 1
{
  if (RI)
   {
     RI = 0;   
    }
if (TI)
  {
   TI = 0; //
  }
}

void Key_scan()//按鍵掃描函數(shù)
{
uchar j;                                   
static uchar keybuf[3] = { 0xFF, 0xFF, 0xFF };   //按鍵掃描緩沖區(qū)
  //將3 個按鍵值移入緩沖區(qū)
keybuf[0] = (keybuf[0] << 1) | Key3;
keybuf[1] = (keybuf[1] << 1) | Key2;
keybuf[2] = (keybuf[2] << 1) | Key1;
//消抖后更新按鍵狀態(tài)
for (j=0; j<3; j++) //       3 個按鍵,所以循環(huán) 3 次
{
  if ((keybuf[j] & 0xFF) == 0x00)   //連續(xù) 3次掃描值為 0,即 24ms 內(nèi)都是按下狀態(tài)時,可認為按鍵已穩(wěn)定的按下
  {
   KeySta[j] = 0;
  }
  else
  if ((keybuf[j] & 0xFF) == 0xFF)
   {        //連續(xù) 4次掃描值為 1,即16ms 內(nèi)都是彈起狀態(tài)時,可認為按鍵已穩(wěn)定的彈起
    KeySta[j] = 1;
   }
  
}
}
void Key_Function()
{   
  static bit i=0;
for (j=0; j<3; j++)  //依次檢測按鍵
  {
   if (backup[j] != KeySta[j]) //檢測按鍵動作
   {
    if (backup[j] != 0) //按鍵按下時執(zhí)行動作
    {
   
     switch (j)
          {
            case 0:  K2_cont=0; K1_cont++; if(K1_cont>=7)  K1_cont=0;      
        
        break;
        
        case 1:
            if(!i)
            {
             SetP_angle[K1_cont-1]-=10;
             if(SetP_angle[K1_cont-1]<=45)
             {
              i=!i;
             }
            }
            else
            {
              SetP_angle[K1_cont-1]+=10;
              if(SetP_angle[K1_cont-1]>=170)
              {
               i=!i;
              }
            }
            
            
            
      
        break;
        
        case 2:
        
        break;
            
        default: break;
       }
    }
     backup[j] = KeySta[j]; //更新前一次的備份值
   }
  }
}
//
//////LEDf顯示函數(shù)
void LDE_Shew()
{
switch (K1_cont)
          {
            case 0:  LED1=LED2=LED3=LED4=LED5=LED6=1;  break;   
               
        case 1:  LED1=LED2=LED3=LED4=LED5=LED6=1; LED1=0;   break;
                                          
        case 2:  LED1=LED2=LED3=LED4=LED5=LED6=1; LED2=0;   break;
                              
        case 3:  LED1=LED2=LED3=LED4=LED5=LED6=1; LED3=0;  break;
      
        case 4:  LED1=LED2=LED3=LED4=LED5=LED6=1; LED4=0;   break;
                       
        case 5:  LED1=LED2=LED3=LED4=LED5=LED6=1; LED5=0;   break;
                     
        case 6:  LED1=LED2=LED3=LED4=LED5=LED6=1; LED6=0;   break;
                                 
        default: break;
       }
   
}
void Motor_Run()
{
  
  P1_11us++;           //一次中斷,自加一次
  if (P1_11us>1800)    //20ms執(zhí)行以下程序
  {
    P1_11us=0;        //清0
    if(Ptem_angle[K1_cont-1]>=(SetP_angle[K1_cont-1]+40))      
    {
     Ptem_angle[K1_cont-1]--;              //自加一次角度,電機緩慢運行,在設定的角度內(nèi)反復轉(zhuǎn)動,如0-90度
      
    }
    else
    {
     Ptem_angle[K1_cont-1]++;
   
    }
  }
}
//******************串口初始化
void UartInit(void)  [url=]//9600bps@33.1776MHz[/url]
{
SCON = 0x50;  //8位數(shù)據(jù),可變波特率
AUXR |= 0x01;  //串口1選擇定時器2為波特率發(fā)生器
AUXR &= 0xFB;  //定時器2時鐘為Fosc/12,即12T
T2L = 0xB8;   //設定定時初值
T2H = 0xFF;   //設定定時初值
AUXR |= 0x10;  //啟動定時器2
ES=1;      //允許串口中斷
}
//定時器T0用作脈沖發(fā)生器,定時11us
void Timer0Init(void)  //11微秒@33.1776MHz
{
AUXR |= 0x80;  //定時器時鐘1T模式
TMOD &= 0xF0;  //設置定時器模式
TL0 = 0x8F;   //設置定時初值
TH0 = 0xFE;   //設置定時初值
TF0 = 0;    //清除TF0標志
TR0 = 1;    //定時器0開始計時
ET0=1; //中斷允許     
}
//PCA定時器設置 定時1MS
void PCATimerInit()
{
ACC = P_SW1;

ACC &= ~(CCP_S0 | CCP_S1);          //CCP_S0=0 CCP_S1=0
P_SW1 = ACC;                 //(P1.2/ECI, P1.1/CCP0, P1.0/CCP1, P3.7/CCP2)
CCON = 0;               //初始化PCA控制寄存器
                      //PCA定時器停止 清除CF標志 清除模塊中斷標志
CL = 0;               //復位PCA寄存器
CH  = 0;
CMOD = 0x00;        //設置PCA時鐘源
                       //禁止PCA計數(shù)器中斷
value = T1000Hz;
CCAP0L = value;
CCAP0H = value >> 8;    //初始化PCA模塊0
value += T1000Hz;
CCAPM0 = 0x49;        //PCA模塊0為16位定時器模式
CR = 1;               //PCA定時器開始工作
cnt = 0;
}

評分

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

查看全部評分

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

使用道具 舉報

沙發(fā)
ID:1 發(fā)表于 2018-6-21 17:32 | 只看該作者
原理圖與頭文件能分享一下嗎?
回復

使用道具 舉報

板凳
ID:346558 發(fā)表于 2018-6-22 23:50 | 只看該作者
大哥,能幫我調(diào)試一下我最近做的一個項目嗎,跟您的控制三個舵機類似,必有重謝!!
回復

使用道具 舉報

地板
ID:301968 發(fā)表于 2018-7-28 10:53 | 只看該作者
Somiy 發(fā)表于 2018-6-22 23:50
大哥,能幫我調(diào)試一下我最近做的一個項目嗎,跟您的控制三個舵機類似,必有重謝!!

可以
回復

使用道具 舉報

5#
ID:436733 發(fā)表于 2018-12-8 17:51 | 只看該作者
是藍牙控制的嗎
回復

使用道具 舉報

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

本版積分規(guī)則

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

Powered by 單片機教程網(wǎng)

快速回復 返回頂部 返回列表
主站蜘蛛池模板: 精品成人免费一区二区在线播放 | 成人在线视频免费播放 | 国产在线精品一区二区三区 | 欧美精品欧美精品系列 | 日韩精品久久久久久 | 午夜一级大片 | 日韩成人在线播放 | 精品免费国产视频 | 亚洲精选一区二区 | 成年视频在线观看福利资源 | 欧美日韩视频在线 | 天堂一区二区三区 | 人人干在线视频 | 午夜影院操 | 国产精品一区在线观看 | 干干干日日日 | 九九九国产 | 殴美黄色录像 | 婷婷久久网| 亚洲国产精品自拍 | 欧美一级欧美一级在线播放 | 国产精品久久久久aaaa | 午夜丁香视频在线观看 | 色免费视频 | 最新一级毛片 | 日韩视频一区二区 | 日日日色 | 日本成人久久 | 国产成人免费视频网站视频社区 | 国产一区二区三区四区三区四 | 亚洲午夜一区二区 | 91免费在线看 | 日韩欧美国产精品 | 高清黄色毛片 | 国产日韩欧美精品一区二区 | 一区二区日韩 | 国产一区二区三区免费观看视频 | 欧美性网站 | 欧美成人综合 | 久久机热 | 91 中文字幕 |