微波EDA网,见证研发工程师的成长!
首页 > 研发问答 > 嵌入式设计讨论 > MCU和单片机设计讨论 > 使用AVR控制PCA9685输出PWM型号,硬件调试没问题的话却一直无法输出信号,求大佬帮忙看看

使用AVR控制PCA9685输出PWM型号,硬件调试没问题的话却一直无法输出信号,求大佬帮忙看看

时间:10-02 整理:3721RD 点击:
附上自己写的程序:
#include "avr/io.h"
#include "avr/interrupt.h"
#include "avr/signal.h"
#include "avr/delay.h"
#define Start() ( TWCR = (1<<TWINT) | (1<<TWSTA) | (1<<TWEN) )        //产生START信号
#define Stop()  ( TWCR = (1<<TWINT) | (1<<TWSTO) | (1<<TWEN) )        //产生STOP信号  
#define PCA9685_adrr 0x80
#define PCA9685_MODE1 0x0
#define PCA9685_PRESCALE 0xfe
//#define on 0
#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
#define uint unsigned int
#define uchar unsigned char
void TWI_write( unsigned char twi_d )
{
        TWDR = ( twi_d );
        TWCR = ( 1<<TWINT ) | ( 1<<TWEN );
}
void TWI_init( void )
{
        TWCR=0X00; //关闭TWI总线
        TWBR=0x12; //设置传输比特率  
        TWSR=0x03; //设置TWI总线的速度,频率不能大于400K,否则5767不工作
        TWCR=0x04; //使能TWI总线
}
unsigned char TWI_read( void )
{
        unsigned char temp;
        TWCR |= 0x04;
        while(!(TWCR&(1<<TWINT)));
        temp = TWDR;
        return temp;
}
void PCA_Write(uchar address,uchar date)
{
        Start();
        while(!(TWCR&(1<<TWINT)));
        TWI_write( PCA9685_adrr );
        while(!(TWCR&(1<<TWINT)));
        TWI_write( address );
        while(!(TWCR&(1<<TWINT)));
        TWI_write( date );
        while(!(TWCR&(1<<TWINT)));
        Stop();
}
uchar PCA_Read(uchar address)
{
        uchar date;
        Start();
        while(!(TWCR&(1<<TWINT)));
        TWI_write( PCA9685_adrr );
        while(!(TWCR&(1<<TWINT)));
        TWI_write( address );
        while(!(TWCR&(1<<TWINT)));
        TWI_write(PCA9685_adrr|0x01);        //地址的第八位控制数据流方向,就是写或读
    date = TWI_read();
        Stop();
        return date;
}
void reset(void)
{
    PCA_Write(PCA9685_MODE1,0x0);
}

void begin(void)
{
    reset();
}

void setPWMFreq(float freq)
{
    unsigned int 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 = PCA_Read(PCA9685_MODE1);
    newmode = (oldmode&0x7F) | 0x10; // sleep
    PCA_Write(PCA9685_MODE1, newmode); // go to sleep
    PCA_Write(PCA9685_PRESCALE, prescale); // set the prescaler
        oldmode &= 0xef;         //清除sleep位
    PCA_Write(PCA9685_MODE1, oldmode);
    //delayms(2);
        //Delay_1ms();
        _delay_ms(2);
    PCA_Write(PCA9685_MODE1, oldmode | 0xA1);
}
/****************************************************************************
                                PCA9685修改角度函数
num:舵机PWM输出引脚0~15,on:PWM上升计数值0~4096,off:PWM下降计数值0~4096
一个PWM周期分成4096份,由0开始+1计数,计到on时跳变为高电平,继续计数到off时
跳变为低电平,直到计满4096重新开始。所以当on不等于0时可作延时,当on等于0时,
off/4096的值就是PWM的占空比。
****************************************************************************/
//offzhuomian
void SetPWM(unsigned int num, unsigned int on, unsigned int off)
{
        PCA_Write(LED0_ON_L+4*num,on);
        PCA_Write(LED0_ON_H+4*num,on>>8);
        PCA_Write(LED0_OFF_L+4*num,off);
        PCA_Write(LED0_OFF_H+4*num,off>>8);
}

void main()
{
        DDRC = 0x80;    //scl输出,sda输入
        //PORTC
        TWBR = 0x12;    //设置输出比特率
        TWSR = 0x03;           //设置TWI总线速度
        TWCR = 0x04;         //使能TWI
        begin();
        setPWMFreq(60);     //Freq50HZ
        
        SetPWM(0,0,2048);
}

顶一个!

Copyright © 2017-2020 微波EDA网 版权所有

网站地图

Top