реклама на сайте
подробности

 
 
> STM32F103 и компас HMC6352, проблема коммуникации
D1mcon
сообщение Oct 13 2010, 16:13
Сообщение #1





Группа: Новичок
Сообщений: 6
Регистрация: 2-08-10
Пользователь №: 58 729



Всем привет! Работаю с МК STM32F103 и компасом HMC6352 по I2C. Но ни как не могу прочитать данные о курсе, всегда компас возвращает значение 0х42. В чем причина, понять не могу. Если кто работал с этим компасом, прошу помочь в решении проблемы.
Код программы
Код
#include "stm32f10x.h"
#include "stm32f10x_i2c.h"


GPIO_InitTypeDef         GPIO_InitStructure;
USART_InitTypeDef         USART_InitStructure;
I2C_InitTypeDef            I2C_InitStructure;
FlagStatus Status = SET;    

#define I2C1_SLAVE_ADDRESS7   0x42
#define HMC6352GetData          0x41
#define BufferSize             4
#define ClockSpeed             100000
typedef enum { FAILED = 0, PASSED = !FAILED} TestStatus;

int angle = 0;
void Delay(unsigned long ms)// delay 1 ms per count @ Crystal 8.0 MHz and PLL9x or SYSCLK = 72 MHz
{
    volatile unsigned long i,j;
    for (i = 0; i < ms; i++ )
    for (j = 0; j < 5525; j++ );
}

int HMC6352GetHeading( void)
{
   unsigned char data_l = 0, data_m = 0;
  

       /* Send I2C1 START condition */
      I2C_GenerateSTART(I2C1, ENABLE);
    while(!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_MODE_SELECT));

    I2C_Send7bitAddress(I2C1, 0x42, I2C_Direction_Transmitter);
    while(!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_TRANSMITTER_MODE_SELECTED ));

   I2C_SendData(I2C1,0x41);
    while(!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_BYTE_TRANSMITTED ));

   Delay(60);

   I2C_GenerateSTART(I2C1, ENABLE);
   while(!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_MODE_SELECT));

   I2C_Send7bitAddress(I2C1, 0x43, I2C_Direction_Transmitter);
    while(!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_RECEIVER_MODE_SELECTED ));

   data_l = I2C_ReceiveData(I2C1);         // read LSB data byte
   data_m = I2C_ReceiveData(I2C1);         // read MSB data byte
   I2C_AcknowledgeConfig(I2C1, DISABLE);
                    
   I2C_GenerateSTOP(I2C1, ENABLE);      // send STOP condition
   return ( (data_m << 8) + data_l);   // return 16 bits data
}

void main()
{    

    SystemInit();
    RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA  | RCC_APB2Periph_AFIO, ENABLE);
    RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1, ENABLE);

    RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE);
      /* I2C1 Periph clock enable */
      RCC_APB1PeriphClockCmd(RCC_APB1Periph_I2C1, ENABLE);
    /* Configure I2C1 pins: SCL and SDA ----------------------------------------*/
      GPIO_InitStructure.GPIO_Pin =  GPIO_Pin_6 | GPIO_Pin_7;
      GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
      GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_OD;
      GPIO_Init(GPIOB, &GPIO_InitStructure);

    /* I2C1 configuration ------------------------------------------------------*/
      I2C_InitStructure.I2C_Mode = I2C_Mode_I2C;
      I2C_InitStructure.I2C_DutyCycle = I2C_DutyCycle_2;
      I2C_InitStructure.I2C_OwnAddress1 = I2C1_SLAVE_ADDRESS7;
      I2C_InitStructure.I2C_Ack = I2C_Ack_Enable;
      I2C_InitStructure.I2C_AcknowledgedAddress = I2C_AcknowledgedAddress_7bit;
      I2C_InitStructure.I2C_ClockSpeed = ClockSpeed;
      I2C_Init(I2C1, &I2C_InitStructure);

    /* Enable I2C1 */
      I2C_Cmd(I2C1, ENABLE);

    GPIO_InitStructure.GPIO_Pin =  GPIO_Pin_9 | GPIO_Pin_4 | GPIO_Pin_5 | GPIO_Pin_6;
      GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
      GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
      GPIO_Init(GPIOA, &GPIO_InitStructure);

    GPIO_InitStructure.GPIO_Pin =  GPIO_Pin_9;
      GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
      GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
      GPIO_Init(GPIOA, &GPIO_InitStructure);

    GPIO_InitStructure.GPIO_Pin =  GPIO_Pin_10;
      GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
      GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;
      GPIO_Init(GPIOA, &GPIO_InitStructure);


    
    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 configuration */
      USART_Init(USART1, &USART_InitStructure);
    
      /* Enable USART */
      USART_Cmd(USART1, ENABLE);
    angle = HMC6352GetHeading();
    
    while(1)
    {
        
            angle = HMC6352GetHeading();
        USART_SendData(USART1, (uint8_t) angle);
    

    }
Go to the top of the page
 
+Quote Post
 
Start new topic
Ответов
KKV2003
сообщение Oct 21 2010, 14:39
Сообщение #2


Участник
*

Группа: Участник
Сообщений: 30
Регистрация: 11-02-08
Пользователь №: 34 931



Хорошо вам... А в моем даташите такого не было. Так что помучился. laughing.gif
Go to the top of the page
 
+Quote Post
D1mcon
сообщение Feb 7 2011, 19:48
Сообщение #3





Группа: Новичок
Сообщений: 6
Регистрация: 2-08-10
Пользователь №: 58 729



Продолжаем разговор sm.gif . Компас после нескольких месяцев не заработал sad.gif Причина - не получаю ACK после передачи адреса.
Привожу немного измененный код
Код
#include "stm32f10x.h"
#include "stm32f10x_i2c.h"



I2C_InitTypeDef            I2C_InitStructure;
FlagStatus Status = SET;    

#define ReadAddress                0x43
#define WriteAddress            0x42
#define BufferSize              4
#define GetHeading                0x41
#define ClockSpeed              100000

int I2C_address = 0;
bool exit = FALSE;
I2C_TypeDef* HMC6352_I2C;

void HMC6352Init(I2C_TypeDef* HMC6352_I2Cx)
{    
    GPIO_InitTypeDef         GPIO_InitStructure;
    I2C_InitTypeDef            I2C_InitStructure;
    
    HMC6352_I2C = HMC6352_I2Cx;
       I2C_Cmd(HMC6352_I2C, DISABLE);
       I2C_DeInit(HMC6352_I2C);
                                    
                                                      
    /* Configure I2C1 pins: SCL and SDA ----------------------------------------*/    
    
    RCC_APB1PeriphClockCmd(RCC_APB1Periph_I2C1, ENABLE);
    RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB , ENABLE);

      GPIO_InitStructure.GPIO_Pin =  GPIO_Pin_6 | GPIO_Pin_7;
      GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
      GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_OD;
      GPIO_Init(GPIOB, &GPIO_InitStructure);
        
    /* I2C1 configuration ------------------------------------------------------*/
      I2C_InitStructure.I2C_Mode = I2C_Mode_I2C;
      I2C_InitStructure.I2C_DutyCycle = I2C_DutyCycle_2;
      I2C_InitStructure.I2C_OwnAddress1 = 0x00;
      I2C_InitStructure.I2C_Ack = I2C_Ack_Enable;
      I2C_InitStructure.I2C_AcknowledgedAddress = I2C_AcknowledgedAddress_7bit;
      I2C_InitStructure.I2C_ClockSpeed = ClockSpeed;
      
      I2C_Init(HMC6352_I2C, &I2C_InitStructure);
    I2C_Cmd(HMC6352_I2C, ENABLE);
      
        

}

int HMC6352GetHeading()
{
  
  __IO uint16_t RegValue = 0;
  
  I2C_AcknowledgeConfig(HMC6352_I2C, ENABLE);
  /*--------------------------------- Transmission Phase ------------------*/

  I2C_GenerateSTART(HMC6352_I2C, ENABLE);
  while (!I2C_CheckEvent(HMC6352_I2C, I2C_EVENT_MASTER_MODE_SELECT));  /*!< EV5 */

  I2C_Send7bitAddress(HMC6352_I2C, WriteAddress, I2C_Direction_Transmitter);
  while (!I2C_CheckEvent(HMC6352_I2C, I2C_EVENT_MASTER_TRANSMITTER_MODE_SELECTED)); /*!< EV6 */
  
  I2C_SendData(HMC6352_I2C, GetHeading);
  while (!I2C_CheckEvent(HMC6352_I2C, I2C_EVENT_MASTER_BYTE_TRANSMITTED)); /*!< EV8 */


  /*-------------------------------- Reception Phase --------------------------*/
  I2C_GenerateSTART(HMC6352_I2C, ENABLE);
  while (!I2C_CheckEvent(HMC6352_I2C, I2C_EVENT_MASTER_MODE_SELECT));  /*!< EV5 */

  I2C_Send7bitAddress(HMC6352_I2C, ReadAddress, I2C_Direction_Receiver);
  while (!I2C_CheckEvent(HMC6352_I2C, I2C_EVENT_MASTER_RECEIVER_MODE_SELECTED));  /*!< EV6 */
  while (!I2C_CheckEvent(HMC6352_I2C, I2C_EVENT_MASTER_BYTE_RECEIVED));  /*!< EV7 */

  RegValue = I2C_ReceiveData(HMC6352_I2C) << 8;
  I2C_AcknowledgeConfig(HMC6352_I2C, DISABLE);
  I2C_GenerateSTOP(HMC6352_I2C, ENABLE);

  while (I2C_GetFlagStatus(HMC6352_I2C, I2C_FLAG_RXNE) == RESET);
  RegValue |= I2C_ReceiveData(HMC6352_I2C);


  return (RegValue/10);
}


И сигналы SCL и SDA. По сигналам видно что нормально происходит старт I2c, посылка адреса, но на 9 клоке SDA = 1, компас не ответил :cry:
Частота настроена верно. Питание на компасе есть. Подтягивающие резисторы на SCL и SDA по 2КОм, при 10КОм, как в ДШ на компас, сильно заваливались фронты.
Подскажите, в чем может быть причина отсутствия ACK?

Эскизы прикрепленных изображений
Прикрепленное изображение
 
Go to the top of the page
 
+Quote Post
D1mcon
сообщение Feb 14 2011, 19:48
Сообщение #4





Группа: Новичок
Сообщений: 6
Регистрация: 2-08-10
Пользователь №: 58 729



Вобщем проблема решена - нашел на демоплате перебитую дорожку на клоки.
Go to the top of the page
 
+Quote Post



Reply to this topicStart new topic
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0

 


RSS Текстовая версия Сейчас: 22nd July 2025 - 01:37
Рейтинг@Mail.ru


Страница сгенерированна за 0.01432 секунд с 7
ELECTRONIX ©2004-2016