Помощь - Поиск - Пользователи - Календарь
Полная версия этой страницы: STM32 I2C + Keil Странности с адресом
Форум разработчиков электроники ELECTRONIX.ru > Сайт и форум > В помощь начинающему > ARM, 32bit
RiseOfDeath
Доброго времени суток. Я столкнулся со странным поведением моей программы.

Делаю инициализацию I2C:

Код
...
        I2C_InitStruct.I2C_Mode =I2C_Mode_I2C;
    I2C_InitStruct.I2C_OwnAddress1=0x2a; <<<<
    I2C_InitStruct.I2C_Ack=I2C_Ack_Enable;
    I2C_InitStruct.I2C_DutyCycle=I2C_DutyCycle_2;
    I2C_InitStruct.I2C_ClockSpeed = 100000;
    I2C_InitStruct.I2C_AcknowledgedAddress=I2C_AcknowledgedAddress_7bit; <<<< //0x4000
    I2C_Init(I2C1, &I2C_InitStruct);
....


Делаю трассировку внутри функции I2C_Init, дохожу до строки

Код
I2Cx->OAR1 = (I2C_InitStruct->I2C_AcknowledgedAddress | I2C_InitStruct->I2C_OwnAddress1);


И тут начинается неладное - смотри в отладчик и вижу:
Нажмите для просмотра прикрепленного файла

(поясню.. add7 = (0x2a>>1), причем пробовал другие значения ставить, они именно смещаются на 1 бит в право).

Устройство действительно отзывается по адресу 15 (2a>>1)
Что я не так делаю?
Палыч
Цитата(RiseOfDeath @ Oct 4 2013, 15:20) *
Что я не так делаю?

Что Вас смущает?
Регистр OAR1 имеет поле ADD7, которое начинается не с младшего (нулевого) бита, а с первого. Keil расписал Вам регистр OAR1 по полям. Соответственно, при занесении в OAR1 значения 0x2А, в поле ADD7 будет отображаться 0x15 (т.е 2A >> 1).
RiseOfDeath
Цитата(Палыч @ Oct 4 2013, 17:22) *
Что Вас смущает?
Регистр OAR1 имеет поле ADD7, которое начинается не с младшего (нулевого) бита, а с первого. Keil расписал Вам регистр OAR1 по полям. Соответственно, при занесении в OAR1 значения 0x2А, в поле ADD7 будет отображаться 0x15 (т.е 2A >> 1).

Меня смущает, что стандартная стандартная СТМовская библиотека, по моему мнению, делает не очевидные вещи.
igorle
Я тоже ничего странного и неочевидного не заметил. Почему пишется 2A в регистр, а поле читается 15 - вам объяснили. К STM библиотеке это не имеет никакого отношения. Так что уточните, пожалуйста, вопрос.

А пока, для тренировки, разберите этот пример
Код
int main(void)
{
    union {
        int word;
        struct {
            int add0:1;
            int add7:6;
        } fields;
    } demo;

    demo.word = 0x2a;

    printf("add7 %#x\n", demo.fields.add7);
    return 0;
}

И угадайте - какой результат будет напечатан.
Проверить можно здесь
RiseOfDeath
Цитата(igorle @ Oct 7 2013, 10:52) *
Я тоже ничего странного и неочевидного не заметил. Почему пишется 2A в регистр, а поле читается 15 - вам объяснили. К STM библиотеке это не имеет никакого отношения. Так что уточните, пожалуйста, вопрос.


Как это не имеет отношения к STM библиотеке?

Мне одному кажется, что в результате выполнения строчки
I2C_InitStruct.I2C_OwnAddress1=0x2a;

OwnAddres должен быть 0x2a, а не 0x15 или вообще какой-нибудь 0xff. Иначе какой смысл в ней, я и сам мог бы записать в регистр значение.

Более того

Код
typedef struct
{
  uint32_t I2C_ClockSpeed;          /*!< Specifies the clock frequency.
                                         This parameter must be set to a value lower than 400kHz */

  uint16_t I2C_Mode;                /*!< Specifies the I2C mode.
                                         This parameter can be a value of @ref I2C_mode */

  uint16_t I2C_DutyCycle;           /*!< Specifies the I2C fast mode duty cycle.
                                         This parameter can be a value of @ref I2C_duty_cycle_in_fast_mode */

  uint16_t I2C_OwnAddress1;         /*!< Specifies the first device own address.
                                         This parameter can be a 7-bit or 10-bit address. */

  uint16_t I2C_Ack;                 /*!< Enables or disables the acknowledgement.
                                         This parameter can be a value of @ref I2C_acknowledgement */

  uint16_t I2C_AcknowledgedAddress; /*!< Specifies if 7-bit or 10-bit address is acknowledged.
                                         This parameter can be a value of @ref I2C_acknowledged_address */
}I2C_InitTypeDef;


/*!< Specifies the first device own address. This parameter can be a 7-bit or 10-bit address. */ Отсюда очевидно, что значение будет смещено? Насколько я знаю английский язык, тут сказано, что я именно адрес устройства задаю, ни слова про смещение и т.п.
igorle
Почитайте еще раз про битовые поля и посмотрите RM0008, параграф 26.6.3, I2C Own address register 1 (I2C_OAR1)
В моей версии РМ это страница 748.

ViKo
Согласен с топикстартером. Еще одно подтверждение, что без мануала библиотечными функциями пользоваться невозможно. Тогда зачем они? Ведь все можно сразу послать в нужные регистры.
igorle
ViKo спасибо. Объяснили - что именно смущает TC. До меня долго не доходило. Меня это не смущает. Невозможно разрабатывать и отлаживать устройство I2C, не зная как работает адресация. Библиотека должна быть минималистична. Но это мои личные предпочтения.

(А Кейл тут вообще ни причем)
ViKo
Цитата(igorle @ Oct 7 2013, 13:39) *
Библиотека должна быть минималистична.

О, хорошо бы! Но, увы... Отдельные части более-менее логично написаны, но некоторые очень избыточны. Я начинал с библиотечной инициализации портов, удивился объему полученного кода. Выбросил, по мануалу запрограммировал, возрадовался. Больше в библиотеку не ходил. Хотя, признаю, что USB запрограммировать будет сложновато.
Зато теперь смотрю на периферийные устройства не как обезьяна на новые ворота. rolleyes.gif
igorle
Получили противоречие. ТС желает, чтобы адрес всегда был адресом, а для семибитного случая код сам пододвигал его на бит влево. И вы его поддержали. А теперь сетуете, что библиотека содержит избыточной код. И отказались вы от библиотеки именно из-за ее избыточности...

Я понимаю, когда речь идет о действительно сложных вещах, типа USB. Но UART, SPI и I2C - ведь можно понять за разумное время, верно?
RiseOfDeath
Господа не ссорьтесь, а то я чувствую себя троллем.

В конце-концов с данным вопросом я разобрался.
Для просмотра полной версии этой страницы, пожалуйста, пройдите по ссылке.
Invision Power Board © 2001-2025 Invision Power Services, Inc.