×
单片机 > 单片机程序设计 > 详情

STC89C52RC单片机+串口+红外控制16路舵机程序

发布时间:2020-12-31 发布时间:
|

只有控制16路舵机的程序,现在发上来提供参考

舵机可以通过串口控制,也可以用红外控制

单片机源程序如下:

#include "PCA9685_TJ.h"

#include

#include


/*使用说明:

        在main主程序

                PCA9685_init();

        在main主程序的while加入

                PCA9685_main();                        //注: 必需放在UART1_main();的前面

*/


#define PCA9685_adrr 0x80//  1+A5+A4+A3+A2+A1+A0+w/r 


#define PCA9685_SUBADR1 0x2

#define PCA9685_SUBADR2 0x3

#define PCA9685_SUBADR3 0x4


#define PCA9685_MODE1 0x0

#define PCA9685_PRESCALE 0xFE


#define LED0_ON_L 0x6

#define LED0_ON_H 0x7

#define LED0_OFF_L 0x8

#define LED0_OFF_H 0x9


#define ALLLED_ON_L 0xFA

#define ALLLED_ON_H 0xFB

#define ALLLED_OFF_L 0xFC

#define ALLLED_OFF_H 0xFD

  

uchar mm,nn;

uint SERV0;                //存储值


/*---------------------------------------------------------------

                 IIC初始化         

----------------------------------------------------------------*/

void init()

{

        sda=1;                //sda scl使用前被拉高

        delay100us(1);

        scl=1;

        delay100us(1);

}


/*---------------------------------------------------------------

                 IIC启动

----------------------------------------------------------------*/

void start()

{

        sda=1;

        delay100us(1);

        scl=1;       //scl高 sda拉低 IIC启动

        delay100us(1);

        sda=0;

        delay100us(1);

        scl=0;

        delay100us(1);

}

/*---------------------------------------------------------------

                 IIC停止

----------------------------------------------------------------*/

void stop()

{

    sda=0;

    delay100us(1);

    scl=1;

    delay100us(1);

    sda=1;                   

    delay100us(1);

}

/*---------------------------------------------------------------

                 IIC应答

----------------------------------------------------------------*/

void ACK()

{

        uchar i;

        scl=1;

        delay100us(1);

        while((sda=1)&&(i<255)) {         

                i++;                     

        }                   

        scl=0;                                  

        delay100us(1);

}

/*---------------------------------------------------------------

              写字节

----------------------------------------------------------------*/

void write_byte(uchar byte)

{

        uchar i,temp;

        temp=byte;

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

        {

                temp=temp<<1;  

                scl=0;                  

                delay100us(1);

                sda=CY;                 

                delay100us(1);

                scl=1;           

                delay100us(1);

        }

        scl=0;                  

        delay100us(1);

        sda=1;                 

        delay100us(1);

}

/*---------------------------------------------------------------

              读字节

----------------------------------------------------------------*/

uchar read_byte()

{

        uchar i,j,k;

        scl=0;

        delay100us(1);

        sda=1;

        delay100us(1);

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

        {

                delay100us(1);

                scl=1;

                delay100us(1);

                if(sda==1)

                {

                        j=1;

                }

                else j=0;

                k=(k<< 1)|j;  

                scl=0;            

        }

        delay100us(1);

        return k;

}

/*---------------------------------------------------------------

                PCA9685

----------------------------------------------------------------*/

/*---------------------------------------------------------------

               写数据到PCA9685

----------------------------------------------------------------*/

void PCA9685_write(uchar address,uchar date)

{

        start();

        write_byte(PCA9685_adrr);

        ACK();                          

        write_byte(address);

        ACK();

        write_byte(date);

        ACK();

        stop();

}

/*---------------------------------------------------------------

            从PCA9685读数据有返回值

----------------------------------------------------------------*/

uchar PCA9685_read(uchar address)

{

        uchar date;

        start();

        write_byte(PCA9685_adrr);

        ACK();

        write_byte(address);

        ACK();

        start();

        write_byte(PCA9685_adrr|0x01);

        ACK();

        date=read_byte();

        stop();

        return date;

}

/*---------------------------------------------------------------

                        PCA9685复位

----------------------------------------------------------------*/

void reset(void) 

{

        PCA9685_write(PCA9685_MODE1,0x0);

}



void begin(void) 

{

        reset();

}

/*---------------------------------------------------------------

                 PCA9685修改频率

----------------------------------------------------------------*/

void setPWMFreq(float freq) 

{

        uint prescale,oldmode,newmode;

        float prescaleval;

        freq *= 0.92;  // Correct for overshoot in the frequency setting 

        prescaleval = 25000000;

        prescaleval /= 4096;

        prescaleval /= freq;

        prescaleval -= 1;

        prescale = floor(prescaleval + 0.5);

        

        oldmode = PCA9685_read(PCA9685_MODE1);

        newmode = (oldmode&0x7F) | 0x10; // sleep

        PCA9685_write(PCA9685_MODE1, newmode); // go to sleep

        PCA9685_write(PCA9685_PRESCALE, prescale); // set the prescaler

        PCA9685_write(PCA9685_MODE1, oldmode);

        delay1ms(10);

        PCA9685_write(PCA9685_MODE1, oldmode | 0xa1); 

}


void setPWM(uint num, uint on, uint off) 

{

        PCA9685_write(LED0_ON_L+4*num,on);

        PCA9685_write(LED0_ON_H+4*num,on>>8);

        PCA9685_write(LED0_OFF_L+4*num,off);

        PCA9685_write(LED0_OFF_H+4*num,off>>8);

}


void PCA9685_init() {

        init();                                //初始化

        begin();                        //初始化

setPWMFreq(50);



『本文转载自网络,版权归原作者所有,如有侵权请联系删除』

热门文章 更多