亲们好,最近买了一个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)
{
}
}
|
|