打印

利用stm32的I2C读取WII Nunchuck手柄数据出现问题

[复制链接]
2725|0
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
liuchangsheng|  楼主 | 2013-4-12 09:34 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
     亲们好,最近买了一个WII的Nunchuck **腿手柄,由于好奇,想利用身边的stm32读取操作手柄时手柄向外发送的数据。具体操作办法如下:经查阅资料发现该手柄接口为I2C接口,为此就利用stm32自带的I2C2尝试读取数据,查阅资料发现该手柄外设的地址为0x52,写寄存器的地址为0xA4。我利用的是PC自带的超级终端,用以显示读取的数据,但是出现的问题是:能利用超级终端读取数据,但是读取的数据不随手柄操作的变化而变化,超级终端上总是显示相同的6 bytes的数据(x、y轴数据:165、165;x、y、z轴加速度数据:661、661、661;按键Z与C:1、0),调了很多天没有结果,郁闷啊~各位亲们看能不能帮助小女子,小女子在此谢过~

#include "stm32f10x.h"
#include "stm32_eval.h"
#include "stdio.h"

/** @addtogroup STM32F10x_StdPeriph_Examples
  * @{
  */

/** @addtogroup I2C_Interrupt
  * @{
  */

/* Private define ------------------------------------------------------------*/
#define I2C2_SLAVE_ADDRESS7     0x52
#define ClockSpeed              400000
#define Buffersize              6

/* Private macro -------------------------------------------------------------*/
/* Private variables ---------------------------------------------------------*/

/* Private functions ---------------------------------------------------------*/
void RCC_Configuration(void);
void GPIO_Configuration(void);
void nunchuck_init(void);
void nunchuck_read(unsigned int* );
int fputc(int ch, FILE *f);                                //自定义fputc函数,以便使用printf进行串口输出
char nunchuk_decode_byte (char );
void delay(unsigned int);
unsigned int rx_data[Buffersize] ;                         // Nunchuk data array
void print();
int cnt=0;

__IO uint8_t Tx1_Idx, Rx1_Idx, Tx2_Idx, Rx2_Idx, Direction;
uint8_t I2C1_Buffer_Tx[], I2C1_Buffer_Rx[];
uint8_t I2C2_Buffer_Tx[], I2C2_Buffer_Rx[];
       /**
        * @brief   Main program
        * @param  None
        * @retval None
        */
I2C_InitTypeDef I2C_InitStructure;
int main(void)
{
  
        /* System clocks configuration ---------------------------------------------*/
  RCC_Configuration();
        /* GPIO configuration ------------------------------------------------------*/
  GPIO_Configuration();

        /* USART1 configuration ------------------------------------------------------*/
        /* USART1 configured as follow:
        - BaudRate = 9600 baud  
        - Word Length = 8 Bits
        - One Stop Bit
        - No parity
        - Hardware flow control enabled (RTS and CTS signals)
        - Receive and transmit enabled
        */
  USART_InitTypeDef USART_InitStructure;
  USART_Cmd(USART1, ENABLE);
  USART_InitStructure.USART_BaudRate = 9600;
  USART_InitStructure.USART_WordLength = USART_WordLength_8b;
  USART_InitStructure.USART_StopBits = USART_StopBits_1;
  USART_InitStructure.USART_Parity = USART_Parity_No ;
  USART_InitStructure.USART_HardwareFlowControl=USART_HardwareFlowControl_None;
  USART_InitStructure.USART_Mode = USART_Mode_Rx | USART_Mode_Tx;
  USART_Init(USART1, &USART_InitStructure);
  // Configures COM port
  STM_EVAL_COMInit(COM1, &USART_InitStructure);



  /* Enable I2C2----------------------------------------------------*/
  /* I2C2 configuration ------------------------------------------------------*/
   
  nunchuck_init();                                         //initialize nunchuck
  delay(100);
  printf("\x0c\0");                                       //超级终端清屏
  printf("\033[1;40;32m");                                //设置超级终端背景为黑色,字符为绿色
  printf("\r\n*******************************************************************************");
  printf("\r\n********************* Reading data from Nunchuck by stm32 *********************");
  printf("\r\n*******************************************************************************");
  printf("\r\n");
  
  printf ("x_axis");
  printf("\t");
  printf ("y_axis");
  printf("\t");
  printf ("accel_x_axis");
  printf ("\t");
  printf ("accel_y_axis");
  printf ("\t");
  printf ("accel_z_axis");
  printf ("\t");
  printf("btn_z");
  printf ("\t");
  printf("btn_c");
  printf ("\t");
  printf ("\r\n");

while(1)
  {
    rx_data[cnt]= nunchuk_decode_byte (I2C_ReceiveData(I2C2));
    nunchuck_read(rx_data);                                   //read data from nunchuck
    cnt++;
    if (cnt >= 5)
    {
      cnt = 0;
      print ();
    }
   
   I2C_GenerateSTART(I2C1, ENABLE);
   I2C_SendData(I2C2,0XA4);
   I2C_SendData(I2C2,0X00);
   I2C_GenerateSTOP(I2C2, ENABLE);
   
    delay(200);
   
  }
}
   void print()
  {
    unsigned int  btn_z=0, btn_c=0;
    int joy_x_axis = rx_data[0];
    int joy_y_axis = rx_data[1];
    int accel_x_axis = rx_data[2] * 2 * 2;
    int accel_y_axis = rx_data[3] * 2 * 2;
    int accel_z_axis = rx_data[4] * 2 * 2;
    if(( rx_data[5])>>0&1)
    {
      btn_z=1;
    }
    if(( rx_data[5])>>1&1)
    {
      btn_c=1;
    }
    if(( rx_data[5])>>2&1)
    {
      accel_x_axis += 2;
    }
     if(( rx_data[5])>>3&1)
    {
      accel_x_axis += 1;
    }
    if(( rx_data[5])>>4&1)
    {
      accel_y_axis += 2;
    }
    if(( rx_data[5])>>5&1)
    {
      accel_y_axis += 1;
    }
    if(( rx_data[5])>>6&1)
    {
      accel_z_axis += 2;
    }
     if(( rx_data[5])>>7&1)
    {
      accel_z_axis += 1;
    }
    printf ("%d",joy_x_axis);
    printf("\t");
    printf ("%d",joy_y_axis);
    printf("\t");
    printf ("%d",accel_x_axis);
    printf ("\t");
    printf ("%d",accel_y_axis);
    printf ("\t");
    printf ("%d",accel_z_axis);
    printf ("\t");
    printf("%d",btn_z);
    printf ("\t");
    printf("%d",btn_c);
    printf ("\t");
    printf ("\r\n");
   }


void delay(unsigned int i)                                          // 定义一个延时函数
{
  unsigned int m,n;
  for(m=i;m>0;m--)
   for(n=110;n>0;n--);
}

// Encode data to format that most wiimote drivers except
// only needed if you use one of the regular wiimote drivers
//         字节译码
char nunchuk_decode_byte (char x)  //  ok
{
  x = (x ^ 0x17) + 0x17;
  return x;
}
  

/**
  * @brief  Configures the different system clocks.
  * @param  None
  * @retval None
  */


//对 RCC进行初始化
void RCC_Configuration(void)         
{
     /* Setup the microcontroller system. Initialize the Embedded Flash Interface,  
     initialize the PLL and update the SystemFrequency variable. */
  SystemInit();

     /* Enable peripheral clocks --------------------------------------------------*/
     /* Enable I2C1 and I2C2 clock */
  RCC_APB1PeriphClockCmd(RCC_APB1Periph_I2C2 ,ENABLE);
     /* Enable GPIOB clock */
  RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE);
}


/**
  * @brief  Configures the different GPIO ports.
  * @param  None
  * @retval None
  */

// 对GPIO进行初始化
void GPIO_Configuration(void)         
{
  
  GPIO_InitTypeDef GPIO_InitStructure;
  GPIO_InitStructure.GPIO_Pin =  GPIO_Pin_10 | GPIO_Pin_11;
  GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_OD;
  GPIO_Init(GPIOB, &GPIO_InitStructure);
  
}

//对 nunchuck 进行初始化
void nunchuck_init(void)   
{
     I2C_InitStructure.I2C_Mode = I2C_Mode_I2C;
     I2C_InitStructure.I2C_DutyCycle = I2C_DutyCycle_2;
     I2C_InitStructure.I2C_OwnAddress1 = I2C2_SLAVE_ADDRESS7;
     I2C_InitStructure.I2C_Ack = I2C_Ack_Enable;
     I2C_InitStructure.I2C_AcknowledgedAddress = I2C_AcknowledgedAddress_7bit;
     I2C_InitStructure.I2C_ClockSpeed = ClockSpeed;
     I2C_Init(I2C2, &I2C_InitStructure);
     I2C_Cmd(I2C2, ENABLE);
     
  
   
     I2C_GenerateSTART(I2C2, ENABLE);            //I2C_GenerateSTART(I2C1, ENABLE);
     I2C_SendData(I2C2,0XA4);                    //I2C_SendData(I2C1,0XA4);
     I2C_SendData(I2C2,0XF0);                     //I2C_SendData(I2C1,0X40);
     I2C_SendData(I2C2,0X55);                     //I2C_SendData(I2C1,0X00);
     I2C_GenerateSTOP(I2C2, ENABLE);              //I2C_GenerateSTOP(I2C1, ENABLE);
   
     I2C_GenerateSTART(I2C2, ENABLE);
     I2C_SendData(I2C2,0XA4);
     I2C_SendData(I2C2,0XFB);
     I2C_SendData(I2C2,0X00);
     I2C_GenerateSTOP(I2C2, ENABLE);
   
}

// 从 初始化后的 nunchuck 中读取数据
void nunchuck_read(unsigned int *array )  
{
  
    I2C_GenerateSTART(I2C2, ENABLE);            // I2C start
    I2C_SendData(I2C2,0XA4);                    //发送Nunchuck的write address
    I2C_SendData(I2C2,0X00);                    //activate Nunchuck
    I2C_GenerateSTOP(I2C2, ENABLE);             // I2C stop
   
    I2C_GenerateSTART(I2C2, ENABLE);            //I2C start
    I2C_SendData(I2C2,0XA5);                    //begin reading data from Nunchuck
    array[0]=I2C_ReceiveData(I2C2);   
    I2C_AcknowledgeConfig(I2C2,ENABLE);         // 收到数据后,向Nunchuck发送应答信号
    array[1]=I2C_ReceiveData(I2C2);
    I2C_AcknowledgeConfig(I2C2,ENABLE);
    array[2]=I2C_ReceiveData(I2C2);
    I2C_AcknowledgeConfig(I2C2,ENABLE);
    array[3]=I2C_ReceiveData(I2C2);
    I2C_AcknowledgeConfig(I2C2,ENABLE);
    array[4]=I2C_ReceiveData(I2C2);
    I2C_AcknowledgeConfig(I2C2,ENABLE);      
    array[5]=I2C_ReceiveData(I2C2);
    I2C_AcknowledgeConfig(I2C2,DISABLE);      
    I2C_GenerateSTOP(I2C2, ENABLE);   
     
}

// 使用printf函数串口发送数据
   int fputc(int ch, FILE *f)
   {
     USART_SendData(USART1, (unsigned char) ch);       // USART1 可以换成 USART2 等
     while (!(USART1->SR & USART_FLAG_TXE));
    return (ch);
  }


/**
  * @brief  Configures NVIC and Vector Table base location.
  * @param  None
  * @retval None
  */



#ifdef  USE_FULL_ASSERT
/**
  * @brief  Reports the name of the source file and the source line number
  *   where the assert_param error has occurred.
  * @param  file: pointer to the source file name
  * @param  line: assert_param error line source number
  * @retval None
  */
void assert_failed(uint8_t* file, uint32_t line)
{
  /* User can add his own implementation to report the file name and line number,
     ex: printf("Wrong parameters value: file %s on line %d\r\n", file, line) */

  /* Infinite loop */
  while (1)
  {
  }
}

发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

1

主题

1

帖子

1

粉丝