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

 
 
 
Reply to this topicStart new topic
> Опрос датчика освещенности по I2C
Dima92
сообщение Jul 11 2017, 08:36
Сообщение #1


Участник
*

Группа: Участник
Сообщений: 64
Регистрация: 25-04-15
Из: Санкт-Петербург
Пользователь №: 86 385



Здравствуйте. Пытаюсь общаться с датчиком 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, правильно посчитал?

До этого делал передачу по Айтуси на самой отладке между двумя интерфейсами, функции были другие, но работали.
Go to the top of the page
 
+Quote Post
k155la3
сообщение Jul 11 2017, 09:10
Сообщение #2


Профессионал
*****

Группа: Свой
Сообщений: 1 123
Регистрация: 8-03-09
Из: Днепр
Пользователь №: 45 848




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

I2C_SR1_ADDR - по контексту это должен быть флаговый бит.
Упоминание здесь об адресе (слейва ?) не очень понятно.
Если требуется сравнение, то & не пойдет.
Go to the top of the page
 
+Quote Post
Dima92
сообщение Jul 11 2017, 10:24
Сообщение #3


Участник
*

Группа: Участник
Сообщений: 64
Регистрация: 25-04-15
Из: Санкт-Петербург
Пользователь №: 86 385



Цитата(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), что адрес получен и совпал.
Go to the top of the page
 
+Quote Post
k155la3
сообщение Jul 11 2017, 12:29
Сообщение #4


Профессионал
*****

Группа: Свой
Сообщений: 1 123
Регистрация: 8-03-09
Из: Днепр
Пользователь №: 45 848



Цитата(Dima92 @ Jul 11 2017, 13:24) *
Да, флаг.
. . .
Как я понимаю, флаг, который выставляется после подтверждения (ACK), что адрес получен и совпал.

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

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


Go to the top of the page
 
+Quote Post

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

 


RSS Текстовая версия Сейчас: 23rd June 2025 - 21:31
Рейтинг@Mail.ru


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