STM32 новичку в ARM что к чему
- Сообщения: 2316
- Зарегистрирован: Вс июн 26, 2011 20:03:21
Получается, что в плане общения с модулем разницы никакой нет между F1 и F4?
- Реклама
- Сообщения: 2567
- Зарегистрирован: Вт май 01, 2018 19:44:47
Да инициализация то в I2C не самое главное. Там как раз всё просто.
Основные заморочки при передаче все состояния правильно обработать.
Код: Выделить всё
//В хидер процессора
#define I2C_CCR_CCR(value) ((I2C_CCR_CCR_Msk & ((value) << I2C_CCR_CCR_Pos)))
#define I2C_CR2_FREQ(value) ((I2C_CR2_FREQ_Msk & ((value) << I2C_CR2_FREQ_Pos)))
//Инициализация
// Ножки SDA и SCL предварительно установить в OUTPUT2_ALT_OPEN_DRAIN
RCC->APB1ENR |= RCC_APB1ENR_I2C1EN;
I2C1->CR1 = I2C_CR1_SWRST;
I2C1->CR1 = 0;
I2C1->CCR = I2C_CCR_CCR(45); // F = PCLK1/CCR/2
I2C1->CR2 = I2C_CR2_FREQ(36); // Значение PCLK1 [МГц]
I2C1->TRISE = 9;
I2C1->CR1 = I2C_CR1_PE;
- Сообщения: 3604
- Зарегистрирован: Пн июл 28, 2008 22:12:01
isx, новые модули в F7 и F0 , вот там как раз с инициализацией все не просто. Зато работа с ним намного проще и эффективней.
[uquote="isx",url="/forum/viewtopic.php?p=3378397#p3378397"]Получается, что в плане общения с модулем разницы никакой нет между F1 и F4?[/uquote]
На F1 есть пакости в errata ...
[uquote="isx",url="/forum/viewtopic.php?p=3378397#p3378397"]Получается, что в плане общения с модулем разницы никакой нет между F1 и F4?[/uquote]
На F1 есть пакости в errata ...
- Сообщения: 2316
- Зарегистрирован: Вс июн 26, 2011 20:03:21
Всем спасибо) Полез в errata 
Добавлено after 1 hour 38 minutes 14 seconds:
Ещё вопрос возник. Сегодня буду пытаться прикрутить к f103 семисегментник на TM1637. Там фишка в том, что эта микра не поддерживает адресацию и сразу надо слать команду.
Это как-то отразится на работе или можно тупо после старта засылать байт с командой?
Добавлено after 1 hour 38 minutes 14 seconds:
Ещё вопрос возник. Сегодня буду пытаться прикрутить к f103 семисегментник на TM1637. Там фишка в том, что эта микра не поддерживает адресацию и сразу надо слать команду.
Это как-то отразится на работе или можно тупо после старта засылать байт с командой?
- Реклама
- Сообщения: 3604
- Зарегистрирован: Пн июл 28, 2008 22:12:01
[uquote="Myp3ik",url="/forum/viewtopic.php?p=3378551#p3378551"]Там не I2C....[/uquote]
Правильно будет - "Там не совсем i2c" ...
isx, все в твоих руках ...
Правильно будет - "Там не совсем i2c" ...
isx, все в твоих руках ...
- Сообщения: 3604
- Зарегистрирован: Пн июл 28, 2008 22:12:01
- Сообщения: 2316
- Зарегистрирован: Вс июн 26, 2011 20:03:21
Да настрой нормальный
Просто я не в курсе, может они в принципе железно несовместимы (как SPI и нормальный I2C). Вот и решил спросить у знающих, чтоб не ходить по уже истоптанным граблям.
- Сообщения: 3604
- Зарегистрирован: Пн июл 28, 2008 22:12:01
Физически то чем адрес от команды отличается?isx писал(а):Там фишка в том, что эта микра не поддерживает адресацию и сразу надо слать команду.
- Сообщения: 2316
- Зарегистрирован: Вс июн 26, 2011 20:03:21
Там же к 7-ми битам адреса привязывается бит Read/Write. Он не аппаратно ставится после передачи старт бита?
Может и не получится I2C использовать.
Но есть же еще SPI, может можно примонстрячить.
USART в синхронном режиме.
А может в асинхронном, но два UARTa одновременно (почти одновременно)?
Действительно. Программный ногодрыг на таком контроллере как-то не интересно, но можно и на ногодрыге.
Но есть же еще SPI, может можно примонстрячить.
USART в синхронном режиме.
А может в асинхронном, но два UARTa одновременно (почти одновременно)?
Действительно. Программный ногодрыг на таком контроллере как-то не интересно, но можно и на ногодрыге.
- Сообщения: 6452
- Зарегистрирован: Пт сен 13, 2013 13:11:31
- Сообщения: 2316
- Зарегистрирован: Вс июн 26, 2011 20:03:21
Ещё вопрос по I2C.
Нашел в даташите расчет битов CCR регистра CCR. Там такой пример:
Откуда появилось 5000 ns?
Нашел в даташите расчет битов CCR регистра CCR. Там такой пример:
Ну про FREQR = 08 понятно (расчет для частоты тактирования шины равной 8МГц). 125ns тоже понятно (длительность такта при 8МГц).For instance: in Sm mode, to generate a 100 kHz SCL frequency:
If FREQR = 08, TPCLK1 = 125 ns so CCR must be programmed with 0x28
(0x28 <=> 40d x 125 ns = 5000 ns.)
Откуда появилось 5000 ns?
[uquote="a5021",url="/forum/viewtopic.php?p=3379265#p3379265"]Немного полегче и попроще, чем HAL, но все одно -- на любителя.[/uquote]
если по объему сгенеренного кода смотреть - тогда намного. Местами раз в пять-шесть. Оттуда выкинут HAL-овский бред с callback-ами, всякая мелочь типа дрыгоножества сделана макросами или static inline-ами, нет необходимости все делать через жирные FOO_InitTypeDef, и вообще внутри оно весьма напоминает SPL.
если по объему сгенеренного кода смотреть - тогда намного. Местами раз в пять-шесть. Оттуда выкинут HAL-овский бред с callback-ами, всякая мелочь типа дрыгоножества сделана макросами или static inline-ами, нет необходимости все делать через жирные FOO_InitTypeDef, и вообще внутри оно весьма напоминает SPL.
- Сообщения: 2567
- Зарегистрирован: Вт май 01, 2018 19:44:47
[uquote="isx",url="/forum/viewtopic.php?p=3379314#p3379314"]Откуда появилось 5000 ns?[/uquote]
100 кГц скважность 2.
100 кГц скважность 2.
- Сообщения: 2316
- Зарегистрирован: Вс июн 26, 2011 20:03:21
Чет я вообще ниче не пойму. Сделал предварительные настройки для I2c в F103, чтоб поиграться через поллинг:
TM1637_DSC = 0x40. После старта код успешно доходит до строки Test_1 = 1; .
Только вот тактового сигнала нет. В логанализаторе такая хрень:

Что я делаю не так?
Спойлер
Код: Выделить всё
RCC->CFGR &= ~RCC_CFGR_SW; //Очистка битов выбора источника тактового сигнала
RCC->CR &= ~RCC_CR_PLLON; //Отключаем генератор PLL
RCC->CR &= ~RCC_CR_HSEON;
while((RCC->CR & RCC_CR_HSERDY)!=0) {}
RCC->CR |= RCC_CR_HSION; //Включить генератор HSI
while((RCC->CR & RCC_CR_HSIRDY)==0) {}
RCC->CFGR |= RCC_CFGR_SW_HSI; //Выбрать источником тактового сигнала HSI
/*Тактируем периферию*/
RCC->APB1ENR |= RCC_APB1ENR_I2C1EN;
RCC->APB2ENR |= RCC_APB2ENR_IOPBEN;
/*----------------------------------------------------------------*/
/*Настраиваем Порт B*/
GPIOB->CRL = 0xDD444444;
/*-------------------------------I2C-----------------------------------*/
I2C1->CR1 = I2C_CR1_SWRST;
I2C1->CR1 = 0;
I2C1->CR2 = 0;
I2C1->OAR1 = 0;
I2C1->OAR2 = 0;
I2C1->SR1 = 0;
I2C1->SR2 = 0;
I2C1->CCR = 0;
I2C1->TRISE = 2;
I2C1->CR1 |=
//I2C_CR1_PE | /*!< Peripheral Enable */
//I2C_CR1_SMBUS | /*!< SMBus Mode */
//I2C_CR1_SMBTYPE | /*!< SMBus Type */
//I2C_CR1_ENARP | /*!< ARP Enable */
//I2C_CR1_ENPEC | /*!< PEC Enable */
//I2C_CR1_ENGC | /*!< General Call Enable */
//I2C_CR1_NOSTRETCH | /*!< Clock Stretching Disable (Slave mode) */
//I2C_CR1_START | /*!< Start Generation */
//I2C_CR1_STOP | /*!< Stop Generation */
//I2C_CR1_ACK | /*!< Acknowledge Enable */
//I2C_CR1_POS | /*!< Acknowledge/PEC Position (for data reception) */
//I2C_CR1_PEC | /*!< Packet Error Checking */
//I2C_CR1_ALERT | /*!< SMBus Alert */
//I2C_CR1_SWRST | /*!< Software Reset */
0;
I2C1->CR2 |=
//I2C_CR2_FREQ | /*!< FREQ[5:0] bits (Peripheral Clock Frequency) ((uint16_t)0x003F)*/
//I2C_CR2_FREQ_0 | /*!< Bit 0 */
//I2C_CR2_FREQ_1 | /*!< Bit 1 */
I2C_CR2_FREQ_2 | /*!< Bit 2 */
//I2C_CR2_FREQ_3 | /*!< Bit 3 */
//I2C_CR2_FREQ_4 | /*!< Bit 4 */
//I2C_CR2_FREQ_5 | /*!< Bit 5 */
//I2C_CR2_ITERREN | /*!< Error Interrupt Enable */
//I2C_CR2_ITEVTEN | /*!< Event Interrupt Enable */
//I2C_CR2_ITBUFEN | /*!< Buffer Interrupt Enable */
//I2C_CR2_DMAEN | /*!< DMA Requests Enable */
//I2C_CR2_LAST | /*!< DMA Last Transfer */
0;
I2C1->OAR1 |=
//I2C_OAR1_ADD1_7 | /*!< Interface Address ((uint16_t)0x00FE)*/
//I2C_OAR1_ADD8_9 | /*!< Interface Address ((uint16_t)0x0300)*/
//I2C_OAR1_ADD0 | /*!< Bit 0 */
//I2C_OAR1_ADD1 | /*!< Bit 1 */
//I2C_OAR1_ADD2 | /*!< Bit 2 */
//I2C_OAR1_ADD3 | /*!< Bit 3 */
//I2C_OAR1_ADD4 | /*!< Bit 4 */
//I2C_OAR1_ADD5 | /*!< Bit 5 */
//I2C_OAR1_ADD6 | /*!< Bit 6 */
//I2C_OAR1_ADD7 | /*!< Bit 7 */
//I2C_OAR1_ADD8 | /*!< Bit 8 */
//I2C_OAR1_ADD9 | /*!< Bit 9 */
//I2C_OAR1_ADDMODE | /*!< Addressing Mode (Slave mode) */
0;
I2C1->OAR2 |=
//I2C_OAR2_ENDUAL | /*!< Dual addressing mode enable */
//I2C_OAR2_ADD2 | /*!< Interface address ((uint8_t)0xFE)*/
0;
//I2C1->DR = I2C_DR_DR; /*!< 8-bit Data Register ((uint8_t)0xFF)*/
I2C1->CCR |= 20 |
//I2C_CCR_CCR | /*!< Clock Control Register in Fast/Standard mode (Master mode) ((uint16_t)0x0FFF)*/
//I2C_CCR_DUTY | /*!< Fast Mode Duty Cycle */
//I2C_CCR_FS | /*!< I2C Master Mode Speed Selection */
0;
/*For instance: in Sm mode, to generate a 100 kHz SCL frequency:
If FREQR = 08, TPCLK1 = 125 ns so CCR must be programmed with 0x28 (40)
(0x28 <=> 40d x 125 ns = 5000 ns.)*/
I2C1->TRISE = 9;
//I2C_TRISE_TRISE; /*!< Maximum Rise Time in Fast/Standard mode (Master mode) ((uint8_t)0x3F)*/
I2C1->CR1 |= I2C_CR1_PE;
/*------------------------------_END--------------------------------*/
__enable_irq ();
while(1)
{
I2C1->CR1 |= I2C_CR1_START;
while (!(I2C1->SR1 & I2C_SR1_SB)){;}
Test_1 = I2C1->SR1;
I2C1->DR = TM1637_DSC;
Test_1 = 1;
while(1){}
}
}
Только вот тактового сигнала нет. В логанализаторе такая хрень:
Что я делаю не так?
- Сообщения: 2567
- Зарегистрирован: Вт май 01, 2018 19:44:47
1. I2C не терпит суеты. Я же привёл код для инициализации.
2. Вы же от HSI работаете, он при включении установлен, зачем его дрюкать? Это к делу не относится, выкинуть.
3. При передаче:
- ждём пока I2C_SR2_BUSY
- ставим I2C_CR1_START
- ждём пока не упадёт I2C_SR1_SB
- пишем в DR адрес
- ждем пока не вскочит I2C_SR1_ADDR (одновременно смотрим на вскочил ли I2C_SR1_AF, тогда I2C_CR1_STOP и выход)
- читаем SR2
- ждем пока не вскочит I2C_SR1_TXE (одновременно смотрим на вскочил ли I2C_SR1_AF, тогда I2C_CR1_STOP и выход)
- пишем в DR данные
- ждем пока не вскочит I2C_SR1_TXE (одновременно смотрим на вскочил ли I2C_SR1_AF, тогда I2C_CR1_STOP и выход)
- даём I2C_CR1_STOP
2. Вы же от HSI работаете, он при включении установлен, зачем его дрюкать? Это к делу не относится, выкинуть.
3. При передаче:
- ждём пока I2C_SR2_BUSY
- ставим I2C_CR1_START
- ждём пока не упадёт I2C_SR1_SB
- пишем в DR адрес
- ждем пока не вскочит I2C_SR1_ADDR (одновременно смотрим на вскочил ли I2C_SR1_AF, тогда I2C_CR1_STOP и выход)
- читаем SR2
- ждем пока не вскочит I2C_SR1_TXE (одновременно смотрим на вскочил ли I2C_SR1_AF, тогда I2C_CR1_STOP и выход)
- пишем в DR данные
- ждем пока не вскочит I2C_SR1_TXE (одновременно смотрим на вскочил ли I2C_SR1_AF, тогда I2C_CR1_STOP и выход)
- даём I2C_CR1_STOP



