基于STM32 的16路舵机控制板 【PCA9685】 程序掉进循环出不来了

2019-07-14 19:45发布

#include "PWMIIC.h"
#include "delay.h"


void I2C_init(void)
{
        GPIO_InitTypeDef GPIO;
        I2C_InitTypeDef  HS_I2C;
        
        RCC_APB1PeriphClockCmd(RCC_APB1Periph_I2C1, ENABLE);
        RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB , ENABLE);
        GPIO.GPIO_Pin=GPIO_Pin_6|GPIO_Pin_7;//I2C1
        GPIO.GPIO_Speed=GPIO_Speed_50MHz;
        GPIO.GPIO_Mode = GPIO_Mode_AF_OD;
        GPIO_Init(GPIOB, &GPIO);
        
        HS_I2C.I2C_Mode=I2C_Mode_I2C;
        HS_I2C.I2C_DutyCycle=I2C_DutyCycle_2;
        HS_I2C.I2C_OwnAddress1=0x40;//STM32×÷Ö÷»ú
        HS_I2C.I2C_Ack=I2C_Ack_Enable;
        HS_I2C.I2C_AcknowledgedAddress=I2C_AcknowledgedAddress_7bit;
        HS_I2C.I2C_ClockSpeed=400000;
        I2C_Cmd(I2C1,ENABLE);
        I2C_Init(I2C1,&HS_I2C);
//    write8(PCA9685_MODE1, 0x0);
}

u8 read8(u8 addr)
{
        I2C_AcknowledgeConfig(I2C1,ENABLE);
        I2C_GenerateSTART(I2C1,ENABLE);
        while(!I2C_CheckEvent(I2C1,I2C_EVENT_MASTER_MODE_SELECT));
        I2C_Send7bitAddress(I2C1,0x41,I2C_Direction_Transmitter);
        delay_ms(10);
        while(!I2C_CheckEvent(I2C1,I2C_EVENT_MASTER_TRANSMITTER_MODE_SELECTED));
        I2C_SendData(I2C1,addr);
        while(!I2C_CheckEvent(I2C1,I2C_EVENT_MASTER_BYTE_TRANSMITTED));
        I2C_GenerateSTOP(I2C1,ENABLE);
        return I2C_ReceiveData(I2C1);
}
void write8(u8 addr, u8 d)
{
        I2C_AcknowledgeConfig(I2C1,ENABLE); //
        I2C_GenerateSTART(I2C1,ENABLE);
        while(!I2C_CheckEvent(I2C1,I2C_EVENT_MASTER_MODE_SELECT));
        I2C_Send7bitAddress(I2C1,0x40,I2C_Direction_Transmitter);
        delay_ms(10);
        while(!I2C_CheckEvent(I2C1,I2C_EVENT_MASTER_TRANSMITTER_MODE_SELECTED));
        I2C_SendData(I2C1,addr);
        I2C_SendData(I2C1,d);
        while(!I2C_CheckEvent(I2C1,I2C_EVENT_MASTER_BYTE_TRANSMITTED));
        I2C_GenerateSTOP(I2C1,ENABLE);
}
void setPWMFreq(u8 freq) //ÉèÖÃƵÂÊ
{
        u8 prescale;
        u8 prescaleval;
        u8 oldmode;
        u8 newmode;
  freq *= 0.9;  // Correct for overshoot in the frequency setting (see issue #11).
  prescaleval = (u8)25000000/4096;
  prescaleval /= freq;
  prescaleval -= 1;
//  if (ENABLE_DEBUG_OUTPUT) {
//      printf("Estimated pre-scale: ");
//      printf(prescaleval);
//  }
  prescale = (u8)floor(prescaleval +0.5);//ËÄÉáÎåÈë
  oldmode = read8(MODE1);
  newmode = (oldmode&0x7F) | 0x10; // sleep
  write8(MODE1, newmode); // go to sleep
  write8(PRE_SCALE, prescale); // set the prescaler
  write8(MODE1, oldmode);
  delay_ms(5);
  write8(MODE1, oldmode | 0xa1);  //  This sets the MODE1 register to turn on auto increment.
                                  // This is why the beginTransmission below was not working.
//  Serial.print("Mode now 0x"); Serial.println(read8(PCA9685_MODE1), HEX);
}


void setPWM(u8 num, u16 on, u16 off)
{
  //Serial.print("Setting PWM "); Serial.print(num); Serial.print(": "); Serial.print(on); Serial.print("->"); Serial.println(off);
        I2C_GenerateSTART(I2C1,ENABLE);
        while(!I2C_CheckEvent(I2C1,I2C_EVENT_MASTER_MODE_SELECT));
        I2C_Send7bitAddress(I2C1,0x80,I2C_Direction_Transmitter);
        while(!I2C_CheckEvent(I2C1,I2C_EVENT_MASTER_TRANSMITTER_MODE_SELECTED));
        I2C_SendData(I2C1,PWM0_ON_L+4*num);
        while(!I2C_CheckEvent(I2C1,I2C_EVENT_MASTER_BYTE_TRANSMITTED));/*此处掉进循环  无法自拔  等各                                                                                                                          位大神前来营救*/
        I2C_SendData(I2C1,on);
        I2C_SendData(I2C1,on>>8);
        I2C_SendData(I2C1,off);
        I2C_SendData(I2C1,off>>8);
        while(!I2C_CheckEvent(I2C1,I2C_EVENT_MASTER_BYTE_TRANSMITTED));
        I2C_GenerateSTOP(I2C1,ENABLE);
}
// Sets pin without having to deal with on/off tick placement and properly handles
// a zero value as completely off./* 0  ´ú±íÈ«²¿¹Ø±Õ */  Optional invert parameter supports inverting
// the pulse for sinking to ground.  Val should be a value from 0 to 4095 inclusive./*Val=0~4095*/
void setPin(u8 num, u16 val, u8 invert)
{
  if(val>4095)val=4095;
  if (invert) {
    if (val == 0) {
      // Special value for signal fully on.
      setPWM(num, 4096, 0);
    }
    else if (val == 4095) {
      // Special value for signal fully off.
      setPWM(num, 0, 4096);
    }
    else {
      setPWM(num, 0, 4095-val);
    }
  }
  else {
    if (val == 4095) {
      // Special value for signal fully on.
      setPWM(num, 4096, 0);
    }
    else if (val == 0) {
      // Special value for signal fully off.
      setPWM(num, 0, 4096);
    }
    else {
      setPWM(num, 0, val);
    }
  }
}


<a target="_blank" href="http://wpa.qq.com/msgrd?v=3&uin=&site=qq&menu=yes"><img border="0" src="http://wpa.qq.com/pa?p=2::52" alt="点击这里给我发消息" title="点击这里给我发消息"/></a>


0条回答

一周热门 更多>