机器人制作之STC单片机控制数字舵机

2025-12-17 06:33:56

1、//STC15F2K60S2定时/计数器中断 (晶振12MHz,12分频) 单位时间等于12分频/12MHz,即计数器每次加1使用的时间是1微秒。

#include <STC15F2K60S2.H>

#include <math.h> //pow(x,y) x的y次方函数需要

sbit KEY1 = P3^2;

sbit KEY2 = P3^3;

sbit led1 = P1^1;

sbit led2 = P1^2;

unsigned int counter = 0;   //例子中需要使用的变量

2、/*****

函数名:定时计数器中断初始化

调用:TimerCounterIntInit_12MHz(Tx, delay_us);

参数:bit T_C_Int(定时器中断0或定时器中断1), delay_us(多少微米)

返回值:无

结果:启动T/C1或T/C0并设置计数器初值

*****/

void TimerCounterIntInit_12MHz(bit Tx,unsigned int delay_us)

{

        //定时器0和定时器1都使用工作方式0:16位自动装载的定时/计数器

        TMOD = 0x00;

        //中断总开关(属IE:中断允许寄存器)  

        EA = 1;  

        if(Tx==0){

            ET0 = 1;  //允许定时器中断0中断(属IE:中断允许寄速哨艺存器)

            TH0 = (65536 - delay_us) >> 8;        //16位计数寄存器T0高8位

            TL0 = (65536 - delay_us) & 0x00FF;  //16位计数寄存器T0低8位

        } 

        else {

            ET1 = 1;  //允许定时器中断1中断(属IE:中断允许寄存器)

            TH1 = (65536 - delay_us) >> 8;        //16位计数寄存器T1高8位

 捕独           TL1 = (65536 - delay_us) & 0x00FF;  //16位计数寄存器T1低8位

        }       

}

3、/*****

函数名:定时/计数器0中断处理函数

调  用:[T/C0溢出后中断处获盲理]

参  数:无

返回值:无

结  果:重新写入16位计数寄存器初始值,处理用户程序

备  注:

定时/计数器1中断处理函数:

void TimerCounter_1 (void) interrupt 3  using 3{ //切换寄存器组到3

    //重新写入初值

    //用户函数内容

}

*****/

void TimerCounter_0 (void) interrupt 1  using 1{ //切换寄存器组到1

     counter++;

     if(counter ==2000){  

              //这个数值需要根据TimerCounterIntInit_12MHz(Tx,delay_us)函数的delay_us值进行调整counter=20000us/delay_us

             TR0 = 0;  //停止定时器,使舵机运行稳定

             counter = 0;     //重置

    }

}

4、/*****

函数名:模拟PWM

调用:SimulationPWM(unsigned char pin,unsigned int pwmOut,unsigned int theNumOfTimes);

参数:unsigned char pin(输出模拟PWM的引脚,如:11表示P1^1,3表示P0^3)

unsigned int pwmOut(多少微米)

unsigned int theNumOfTimes(舵机的一个脉冲是20ms,500-2500us的高电平控制舵机角度,循环次数需要大于等于

     1T单片机大概4个_nop()是1us,所以theNumOfTimes的数量起码要大于角度对应的时间)

返回值:无

结果:产生20ms的pwm

*****/

void SimulationPWM(unsigned char pin,unsigned int pwmOut,unsigned int theNumOfTimes)  //pwmOut取值(50~250)

{   

    unsigned int i=1; 

    int Pn = pin/10;

    int PnBit = pin%10;

    PnBit = pow(2,PnBit);

    TR0 = 1;

    for(i=0;i<theNumOfTimes;i++){

        if(counter>0 && counter<pwmOut){

            switch(Pn){

                case 0:P0 |= PnBit;

                break;

                case 1:P1 |= PnBit;

                break;

                case 2:P2 |= PnBit;

                break;

                case 3:P3 |= PnBit;

                break;

                case 4:P4 |= PnBit;

                break;

                case 5:P5 |= PnBit;

                break;

            }

   

        }else{

            switch(Pn){

                case 0:P0 &= ~PnBit;

                break;

                case 1:P1 &= ~PnBit;

                break;

                case 2:P2 &= ~PnBit;

                break;

                case 3:P3 &= ~PnBit;

                break;

                case 4:P4 &= ~PnBit;

                break;

                case 5:P5 &= ~PnBit;

                break;

            }

        }

    }

}

5、//主函数

void main(void)

{

    TimerCounterIntInit_12MHz(0,10); //0.01毫秒,这个时间需要根据不同舵机进行调整。 

   while(1){

      led1=0;

      led2=0;

      if(KEY1==0){

         SimulationPWM(12,90,10001);

         SimulationPWM(11,140,10001);

      }

      else if(KEY2==0){

         SimulationPWM(12,120,12001);

      SimulationPWM(11,180,10001);

      }

   }

}

声明:本网站引用、摘录或转载内容仅供网站访问者交流或参考,不代表本站立场,如存在版权或非法内容,请联系站长删除,联系邮箱:site.kefu@qq.com。
猜你喜欢