Помощь - Поиск - Пользователи - Календарь
Полная версия этой страницы: Опрос датчика освещенности по I2C
Форум разработчиков электроники ELECTRONIX.ru > Сайт и форум > В помощь начинающему > ARM, 32bit
Dima92
Здравствуйте. Пытаюсь общаться с датчиком OPT3001 от TI. Он установлен на одной из тексасовских отладок.
Контроллер - STM32F100 на отладке Discovery. Для начала попробовал спрашивать ID производителя, пишут, что датчик должен отвечать "TI".
Код инициализации:
Код
//I2C1 is the master
void I2C1Init (void){
    RCC->APB2ENR |= RCC_APB2ENR_IOPBEN;
    RCC->APB2ENR |= RCC_APB2ENR_AFIOEN;
    RCC->APB1ENR |= RCC_APB1ENR_I2C1EN;
    //SCL line
    GPIOB->CRL   &= ~GPIO_CRL_MODE6;
    GPIOB->CRL   |= GPIO_CRL_MODE6_1;
    GPIOB->CRL   |= GPIO_CRL_CNF6;
    //SDA line
    GPIOB->CRL   &= ~GPIO_CRL_MODE7;
    GPIOB->CRL   |= GPIO_CRL_MODE7_1;
    GPIOB->CRL   |= GPIO_CRL_CNF7;
    //Periph init
        I2C1->CR2    |= 0x18;//24 MHz  - APB2 frequency
        I2C1->CCR    |= I2C_CCR_FS;
    I2C1->CCR    &= ~I2C_CCR_DUTY;
        I2C1->CCR    |= 0x24;//1500 ns high, 3000 ns low state
        I2C1->TRISE  |= 0x08;//300 ns rise time
    //I2C1->CR1    |= I2C_CR1_ACK;
        //I2C1->CR1    |= I2C_CR1_PE;
}

Функция опроса:
Код
uint16_t I2C1Send (void){
uint8_t OPTWriteAddress = 0x88;
uint8_t OPTReadAddress = 0x89;
uint8_t IDRegister          = 0x7E;
uint8_t OPTIDMSB          = 0;
uint8_t OPTIDLSB           = 0;
uint16_t result                = 0;
    
I2C1->CR1 |= I2C_CR1_PE;
I2C1->CR1 |= I2C_CR1_ACK;
I2C1->CR1 |= I2C_CR1_START;
while (!(I2C1->SR1 & I2C_SR1_SB)){}
I2C1->DR = OPTWriteAddress;
while(!(I2C1->SR1 & I2C_SR1_ADDR)){}
(void)I2C1->SR1;
(void)I2C1->SR2;
I2C1->DR = IDRegister;
I2C1->CR1 |= I2C_CR1_START;
while (!(I2C1->SR1 & I2C_SR1_SB)){}
I2C1->DR = OPTReadAddress;
while(!(I2C1->SR1 & I2C_SR1_ADDR)){}
(void)I2C1->SR1;
(void)I2C1->SR2;
while(!(I2C_SR1_RXNE)){}
OPTIDMSB = I2C1->DR;
while(!(I2C_SR1_RXNE)){}
OPTIDLSB = I2C1->DR;
I2C1->CR1 &= ~I2C_CR1_ACK;
I2C1->CR1 |= I2C_CR1_STOP;
result = (OPTIDMSB<<8) | OPTIDLSB;
return result;
}


Проблема:
Сейчас функция зависает на строке "while(!(I2C1->SR1 & I2C_SR1_ADDR)){}", т.е. подтверждения адреса от датчика не приходит.

Вопросы:
1) Правильно ли организована функция опроса?
2) Можно ли при отладке проходить функцию пошагово - в паспорте на OPT пишут, что у него есть 25 мс таймаут по шине при SCLK в низком, не мешает ли это шагать по строкам?
3) В документации на отладку с датчиком написано, что его нога ADDR подключена к земле, т.е. адрес 1000100.
Т.е. если я хочу туда что-то записать, то получаю адрес 10001000 = 0х88, правильно посчитал?

До этого делал передачу по Айтуси на самой отладке между двумя интерфейсами, функции были другие, но работали.
k155la3

while( ! ( I2C1->SR1 & I2C_SR1_ADDR) ){}

I2C_SR1_ADDR - по контексту это должен быть флаговый бит.
Упоминание здесь об адресе (слейва ?) не очень понятно.
Если требуется сравнение, то & не пойдет.
Dima92
Цитата(k155la3 @ Jul 11 2017, 12:10) *
while( ! ( I2C1->SR1 & I2C_SR1_ADDR) ){}
I2C_SR1_ADDR - по контексту это должен быть флаговый бит.
Упоминание здесь об адресе (слейва ?) не очень понятно.
Если требуется сравнение, то & не пойдет.

Да, флаг.
"Address sent (Master)
0: No end of address transmission
1: End of address transmission
– For 7-bit addressing, the bit is set after the ACK of the byte.
Note: ADDR is not set after a NACK reception."
Как я понимаю, флаг, который выставляется после подтверждения (ACK), что адрес получен и совпал.
k155la3
Цитата(Dima92 @ Jul 11 2017, 13:24) *
Да, флаг.
. . .
Как я понимаю, флаг, который выставляется после подтверждения (ACK), что адрес получен и совпал.

В таком случае - проще всего было бы посмотреть лог. анализатором, что происходит на шине.

Как вариант - сформировать адрес слейва "ногодрыгом" и приверить наличие ACK.
Проверьте аппаратную часть шины - осцилографом посмотреть форму импульсов (с этого желательно начать).
Частота тактирования допустимая ?
ps - некоторые слейвы на I2C могут впадать в анабиоз (можно завесить некорректной командой) - лечится холодным рестартом.
Для отладки - почаще перевключайте слейв.


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