Например TDA7294

Форум РадиоКот • Просмотр темы - stm32f1 cmsis настройка I2C
Форум РадиоКот
Здесь можно немножко помяукать :)





Текущее время: Ср апр 24, 2024 10:13:08

Часовой пояс: UTC + 3 часа


ПРЯМО СЕЙЧАС:



Начать новую тему Ответить на тему  [ Сообщений: 37 ]    , 2
Автор Сообщение
Не в сети
 Заголовок сообщения: Re: stm32f1 cmsis настройка I2C
СообщениеДобавлено: Вс авг 16, 2020 18:57:23 
Друг Кота
Аватар пользователя

Карма: 1
Рейтинг сообщений: 157
Зарегистрирован: Пн окт 11, 2010 19:00:08
Сообщений: 3328
Рейтинг сообщения: 0
А что вас интересует? Полностью готовое решение, написанное за вас кем-то другим?


Вернуться наверх
 
Не в сети
 Заголовок сообщения: Re: stm32f1 cmsis настройка I2C
СообщениеДобавлено: Пт окт 23, 2020 15:28:54 
Мучитель микросхем

Карма: -8
Рейтинг сообщений: -23
Зарегистрирован: Вс дек 29, 2019 08:05:21
Сообщений: 440
Рейтинг сообщения: 0
У F103 есть только одна существенная проблема с I2C.
Цитата:
I2C analog filter may provide wrong value, locking BUSY flag and preventing master mode entry
Description
The I2C analog filters embedded in the I2C I/Os may be tied to low level, whereas SCL and
SDA lines are kept at high level. This can occur after an MCU power-on reset, or during
ESD stress. Consequently, the I2C BUSY flag is set, and the I2C cannot enter master mode
(START condition cannot be sent). The I2C BUSY flag cannot be cleared by the SWRST
control bit, nor by a peripheral or a system reset. BUSY bit is cleared under reset, but it is
set high again as soon as the reset is released, because the analog filter output is still at low
level. This issue occurs randomly.
Note: Under the same conditions, the I2C analog filters may also provide a high level, whereas
SCL and SDA lines are kept to low level. This should not create issues as the filters output
will be correct after next SCL and SDA transition.
Возникает при сильных помехах на I2C (кто-то туда полез тыкать отверткой или пинцетом и куда попало коротить). Решается программно.
Цитата:
Workaround
The SCL and SDA analog filter output is updated after a transition occurs on the SCL and
SDA line respectively. The SCL and SDA transition can be forced by software configuring
the I2C I/Os in output mode. Then, once the analog filters are unlocked and output the SCL
and SDA lines level, the BUSY flag can be reset with a software reset, and the I2C can enter
master mode. Therefore, the following sequence must be applied:
1. Disable the I2C peripheral by clearing the PE bit in I2Cx_CR1 register.
2. Configure the SCL and SDA I/Os as General Purpose Output Open-Drain, High level
(Write 1 to GPIOx_ODR).
3. Check SCL and SDA High level in GPIOx_IDR.
4. Configure the SDA I/O as General Purpose Output Open-Drain, Low level (Write 0 to
GPIOx_ODR).
5. Check SDA Low level in GPIOx_IDR.
6. Configure the SCL I/O as General Purpose Output Open-Drain, Low level (Write 0 to
GPIOx_ODR).
7. Check SCL Low level in GPIOx_IDR.
8. Configure the SCL I/O as General Purpose Output Open-Drain, High level (Write 1 to
GPIOx_ODR).
9. Check SCL High level in GPIOx_IDR.
10. Configure the SDA I/O as General Purpose Output Open-Drain , High level (Write 1 to
GPIOx_ODR).
11. Check SDA High level in GPIOx_IDR.
12. Configure the SCL and SDA I/Os as Alternate function Open-Drain.
13. Set SWRST bit in I2Cx_CR1 register.
14. Clear SWRST bit in I2Cx_CR1 register.
15. Enable the I2C peripheral by setting the PE bit in I2Cx_CR1 register.
Я не считаю что из-за этого стоит отказываться от МК.


Добавлено after 1 minute 8 seconds:
Каким образом это реализовывать?.В инециализации?


Вернуться наверх
 
Не в сети
 Заголовок сообщения: Re: stm32f1 cmsis настройка I2C
СообщениеДобавлено: Пт окт 23, 2020 17:02:25 
Мучитель микросхем

Карма: 4
Рейтинг сообщений: 80
Зарегистрирован: Вс ноя 01, 2015 09:15:16
Сообщений: 445
Откуда: 69.Ржев
Рейтинг сообщения: 0
перепишите эту процедуру в понятных Вам терминах и Вы поймете что к параметрам инита это никакого отношения не имеет.
протокол проверки линий перед тем как вновь поднять интерфейс.


Вернуться наверх
 
PCBWay - всего $5 за 10 печатных плат, первый заказ для новых клиентов БЕСПЛАТЕН

Сборка печатных плат от $30 + БЕСПЛАТНАЯ доставка по всему миру + трафарет

Онлайн просмотровщик Gerber-файлов от PCBWay + Услуги 3D печати
Не в сети
 Заголовок сообщения: Re: stm32f1 cmsis настройка I2C
СообщениеДобавлено: Пт окт 23, 2020 22:00:28 
Мучитель микросхем

Карма: -8
Рейтинг сообщений: -23
Зарегистрирован: Вс дек 29, 2019 08:05:21
Сообщений: 440
Рейтинг сообщения: 0
У F103 есть только одна существенная проблема с I2C.
Цитата:
I2C analog filter may provide wrong value, locking BUSY flag and preventing master mode entry
Description
The I2C analog filters embedded in the I2C I/Os may be tied to low level, whereas SCL and
SDA lines are kept at high level. This can occur after an MCU power-on reset, or during
ESD stress. Consequently, the I2C BUSY flag is set, and the I2C cannot enter master mode
(START condition cannot be sent). The I2C BUSY flag cannot be cleared by the SWRST
control bit, nor by a peripheral or a system reset. BUSY bit is cleared under reset, but it is
set high again as soon as the reset is released, because the analog filter output is still at low
level. This issue occurs randomly.
Note: Under the same conditions, the I2C analog filters may also provide a high level, whereas
SCL and SDA lines are kept to low level. This should not create issues as the filters output
will be correct after next SCL and SDA transition.
Возникает при сильных помехах на I2C (кто-то туда полез тыкать отверткой или пинцетом и куда попало коротить). Решается программно.
Цитата:
Workaround
The SCL and SDA analog filter output is updated after a transition occurs on the SCL and
SDA line respectively. The SCL and SDA transition can be forced by software configuring
the I2C I/Os in output mode. Then, once the analog filters are unlocked and output the SCL
and SDA lines level, the BUSY flag can be reset with a software reset, and the I2C can enter
master mode. Therefore, the following sequence must be applied:
1. Disable the I2C peripheral by clearing the PE bit in I2Cx_CR1 register.
2. Configure the SCL and SDA I/Os as General Purpose Output Open-Drain, High level
(Write 1 to GPIOx_ODR).
3. Check SCL and SDA High level in GPIOx_IDR.
4. Configure the SDA I/O as General Purpose Output Open-Drain, Low level (Write 0 to
GPIOx_ODR).
5. Check SDA Low level in GPIOx_IDR.
6. Configure the SCL I/O as General Purpose Output Open-Drain, Low level (Write 0 to
GPIOx_ODR).
7. Check SCL Low level in GPIOx_IDR.
8. Configure the SCL I/O as General Purpose Output Open-Drain, High level (Write 1 to
GPIOx_ODR).
9. Check SCL High level in GPIOx_IDR.
10. Configure the SDA I/O as General Purpose Output Open-Drain , High level (Write 1 to
GPIOx_ODR).
11. Check SDA High level in GPIOx_IDR.
12. Configure the SCL and SDA I/Os as Alternate function Open-Drain.
13. Set SWRST bit in I2Cx_CR1 register.
14. Clear SWRST bit in I2Cx_CR1 register.
15. Enable the I2C peripheral by setting the PE bit in I2Cx_CR1 register.
Я не считаю что из-за этого стоит отказываться от МК.


Добавлено after 1 minute 6 seconds:
Каким образом это можно реализовать.До настроек битов шины или как?

Добавлено after 17 minutes 4 seconds:
перепишите эту процедуру в понятных Вам терминах и Вы поймете что к параметрам инита это никакого отношения не имеет.
протокол проверки линий перед тем как вновь поднять интерфейс.

Вы имеете ввиду.Перед СтартоМ?


Вернуться наверх
 
Выбираем схему BMS для заряда литий-железофосфатных (LiFePO4) аккумуляторов

Обязательным условием долгой и стабильной работы Li-FePO4-аккумуляторов, в том числе и производства EVE Energy, является применение специализированных BMS-микросхем. Литий-железофосфатные АКБ отличаются такими характеристиками, как высокая многократность циклов заряда-разряда, безопасность, возможность быстрой зарядки, устойчивость к буферному режиму работы и приемлемая стоимость. Но для этих АКБ очень важен контроль процесса заряда и разряда для избегания воздействия внешнего зарядного напряжения после достижения 100% заряда. Инженеры КОМПЭЛ подготовили список таких решений от разных производителей.

Подробнее>>
Не в сети
 Заголовок сообщения: Re: stm32f1 cmsis настройка I2C
СообщениеДобавлено: Вс окт 25, 2020 11:56:51 
Мучитель микросхем

Карма: -8
Рейтинг сообщений: -23
Зарегистрирован: Вс дек 29, 2019 08:05:21
Сообщений: 440
Рейтинг сообщения: 0
И ещё один вопрос Check SCL and SDA High level in GPIOx_IDR.
4. Configure the SDA I/O as General Purpose Output Open-Drain, Low level (Write 0 to
GPIOx_ODR).
5. Check SDA Low level in GPIOx_IDR.
6. Configure the SCL I/O as General Purpose Output Open-Drain, Low level (Write 0 to
GPIOx_ODR).
7. Check SCL Low level in GPIOx_IDR.
Это что это SDA SCL выходы на входы настроить?


Вернуться наверх
 
Новый аккумулятор EVE серии PLM для GSM-трекеров, работающих в жёстких условиях (до -40°С)

Компания EVE выпустила новый аккумулятор серии PLM, сочетающий в себе высокую безопасность, длительный срок службы, широкий температурный диапазон и высокую токоотдачу даже при отрицательной температуре. Эти аккумуляторы поддерживают заряд при температуре от -40/-20°С (сниженным значением тока), безопасны (не воспламеняются и не взрываются) при механическом повреждении (протыкание и сдавливание), устойчивы к вибрации. Они могут применяться как для автотранспорта (трекеры, маячки, сигнализация), так и для промышленных устройств мониторинга, IoT-устройств.

Подробнее>>
Не в сети
 Заголовок сообщения: Re: stm32f1 cmsis настройка I2C
СообщениеДобавлено: Вс окт 25, 2020 12:13:31 
Сверлит текстолит когтями
Аватар пользователя

Карма: 25
Рейтинг сообщений: 168
Зарегистрирован: Ср янв 29, 2014 08:41:31
Сообщений: 1231
Откуда: Баку
Рейтинг сообщения: 0
Там же написано "Output open-drain". Какой ещё вход?

_________________
Каждый имеет право на свое личное ошибочное мнение.

У меня было тяжелое детство - я до 14 лет смотрел черно-белый телевизор.


Вернуться наверх
 
Не в сети
 Заголовок сообщения: Re: stm32f1 cmsis настройка I2C
СообщениеДобавлено: Вс окт 25, 2020 13:16:43 
Мучитель микросхем

Карма: -8
Рейтинг сообщений: -23
Зарегистрирован: Вс дек 29, 2019 08:05:21
Сообщений: 440
Рейтинг сообщения: 0
l in GPIOx_IDR регистр входа? Или я не так понимаю?


Вернуться наверх
 
Не в сети
 Заголовок сообщения: Re: stm32f1 cmsis настройка I2C
СообщениеДобавлено: Вс окт 25, 2020 16:42:50 
Мучитель микросхем

Карма: 4
Рейтинг сообщений: 80
Зарегистрирован: Вс ноя 01, 2015 09:15:16
Сообщений: 445
Откуда: 69.Ржев
Рейтинг сообщения: 0
уже сколько раз у Вас спросили - Вы rm на камень вообще открывали?

раздел General-purpose and alternate-function I/Os (GPIOs and AFIOs)
(есть картинки)
SDA, SCL - линии системы i2c
в кубе или в даташите на конкретный камень можно увидеть на какие ножки мс приходятся.


Вернуться наверх
 
Не в сети
 Заголовок сообщения: Re: stm32f1 cmsis настройка I2C
СообщениеДобавлено: Вс окт 25, 2020 18:41:14 
Мучитель микросхем

Карма: -8
Рейтинг сообщений: -23
Зарегистрирован: Вс дек 29, 2019 08:05:21
Сообщений: 440
Рейтинг сообщения: 0
Открывал конечно.GPIOx_IDR но вот это мне не совсем понятно.


Вернуться наверх
 
Не в сети
 Заголовок сообщения: Re: stm32f1 cmsis настройка I2C
СообщениеДобавлено: Вс окт 25, 2020 19:49:08 
Поставщик валерьянки для Кота
Аватар пользователя

Карма: 18
Рейтинг сообщений: 403
Зарегистрирован: Вт май 01, 2018 19:44:47
Сообщений: 2479
Рейтинг сообщения: 0
И что конкретно непонятно? Буквы незнакомые?


Вернуться наверх
 
Не в сети
 Заголовок сообщения: Re: stm32f1 cmsis настройка I2C
СообщениеДобавлено: Вс окт 25, 2020 20:22:50 
Мучитель микросхем

Карма: -8
Рейтинг сообщений: -23
Зарегистрирован: Вс дек 29, 2019 08:05:21
Сообщений: 440
Рейтинг сообщения: 0
Это регистр входа .А у нас альтернативные выходы.


Вернуться наверх
 
Не в сети
 Заголовок сообщения: Re: stm32f1 cmsis настройка I2C
СообщениеДобавлено: Вс окт 25, 2020 21:51:53 
Поставщик валерьянки для Кота
Аватар пользователя

Карма: 18
Рейтинг сообщений: 403
Зарегистрирован: Вт май 01, 2018 19:44:47
Сообщений: 2479
Рейтинг сообщения: 0
Вы где-то видите отключение IDR от входа в AF?
Изображение
Вложение:
image_2020-10-25_214958.png [81.66 KiB]
Скачиваний: 1003


Вернуться наверх
 
Не в сети
 Заголовок сообщения: Re: stm32f1 cmsis настройка I2C
СообщениеДобавлено: Вс окт 25, 2020 21:56:48 
Мучитель микросхем

Карма: 4
Рейтинг сообщений: 80
Зарегистрирован: Вс ноя 01, 2015 09:15:16
Сообщений: 445
Откуда: 69.Ржев
Рейтинг сообщения: 0
ну отключите АФ на эти ноги,
для работы i2c все равно включите, согласно п.12 этой процедуры.
я так понимаю у Вас не складывается дружба с i2c, и Вы почему-то решили что эта процедура Вам должна помочь, а то что она для решения конкретной (и скорее всего не Вашей) ситуации Вас не интересует.


Вернуться наверх
 
Не в сети
 Заголовок сообщения: Re: stm32f1 cmsis настройка I2C
СообщениеДобавлено: Сб ноя 21, 2020 07:02:18 
Мучитель микросхем

Карма: -8
Рейтинг сообщений: -23
Зарегистрирован: Вс дек 29, 2019 08:05:21
Сообщений: 440
Рейтинг сообщения: 0
всё равно не работает.
Код:

RCC->APB2ENR|=RCC_APB2ENR_IOPBEN ;
GPIOB->CRL|= GPIO_CRL_CNF7_1 | GPIO_CRL_CNF6_1 | GPIO_CRL_CNF7_0 | GPIO_CRL_CNF6_0 |
GPIO_CRL_MODE7_1 | GPIO_CRL_MODE6_1 | GPIO_CRL_MODE7_0 | GPIO_CRL_MODE6_0;
RCC->APB2ENR |= RCC_APB2ENR_AFIOEN;
RCC->APB1ENR|= RCC_APB1ENR_I2C1EN;
I2C1->CR1&=~I2C_CR1_SMBUS ;
I2C1->CCR &=~I2C_CCR_FS;


CLEAR_BIT(I2C1->CR1, I2C_CR1_NOSTRETCH);




I2C1->CR2 |=_VAL2FLD(I2C_CR2_FREQ,36);

I2C1->CCR=180;
I2C1->TRISE= 37;
I2C1->OAR1 = I2C_OWNADDRESS1_7BIT;//(36MHz/100KHz/2)
//(1mcs/(1/36MHz)+1)

I2C1->CR1|= I2C_CR1_ACK;
I2C1->CR1|=I2C_CR1_PE;
I2C1->CR1&=~I2C_CR1_PE;
GPIOB->CRL &= ~(GPIO_CRL_CNF6 | GPIO_CRL_CNF7);
GPIOB->CRL |= GPIO_CRL_CNF6_0 | GPIO_CRL_CNF7_0;//2

GPIOB->ODR |= GPIO_ODR_ODR6 | GPIO_ODR_ODR7;
while(!(GPIOB->IDR &(GPIO_IDR_IDR6 | GPIO_IDR_IDR7)));//3

GPIOB->ODR &= ~(GPIO_ODR_ODR7);//4
while(GPIOB->IDR & GPIO_IDR_IDR7 );//5

GPIOB->ODR &= ~(GPIO_ODR_ODR6);//6
while(GPIOB->IDR & GPIO_IDR_IDR6);//7

GPIOB->ODR |= GPIO_ODR_ODR6;//8
while(!(GPIOB->IDR & GPIO_IDR_IDR6));//9

GPIOB->ODR |= GPIO_ODR_ODR7;//10
while(!(GPIOB->IDR & GPIO_IDR_IDR7));//11
//

// PB6 SCL pin
GPIOB->CRL|=GPIO_CRL_CNF6; // 12 alternate function open drain
GPIOB->CRL|=GPIO_CRL_MODE6; // max speed 50MHz

// PB7 SDA pin
GPIOB->CRL|=GPIO_CRL_CNF7; // alternate function open drain
GPIOB->CRL|=GPIO_CRL_MODE7; // max speed 50MHz



I2C1->CR1 |= I2C_CR1_SWRST;//13
I2C1->CR1 &= ~(I2C_CR1_SWRST);//1

SET_BIT(I2C1->CR1, I2C_CR1_PE);
}
Код:

void RCC_init(void)
{
FLASH->ACR |=FLASH_ACR_PRFTBE ;
FLASH->ACR|=FLASH_ACR_LATENCY_2;

RCC->CR |=RCC_CR_HSEON ;
while(!(RCC->CR&RCC_CR_HSERDY ))
{

}
RCC->CR |=RCC_CR_CSSON ;
RCC->CFGR|=RCC_CFGR_PLLSRC;
RCC->CFGR|=RCC_CFGR_PLLXTPRE_HSE;

RCC->CFGR=RCC_CFGR_PLLMULL9;
RCC->CFGR|=RCC_CFGR_HPRE_DIV1; //_VAL2FLD(RCC_CFGR_HPRE,1);
RCC->CFGR|=RCC_CFGR_PPRE1_DIV2 ;//_VAL2FLD(RCC_CFGR_PPRE1,2);
RCC->CFGR|=RCC_CFGR_PPRE2_DIV1; //_VAL2FLD(RCC_CFGR_PPRE2,1);
RCC->CFGR|= RCC_CFGR_ADCPRE_DIV2;
RCC->CR|=RCC_CR_PLLON;
while(!(RCC->CR&RCC_CR_PLLRDY))
{

}

RCC->CFGR|=RCC_CFGR_SW_PLL;
while(!(RCC->CFGR&RCC_CFGR_SWS_PLL ))
{

}
}
Код:
[list][/list]

void NMI_Handler(void)
{
if((RCC->CIR & RCC_CIR_CSSF) != 0) // HSE fail
{
RCC->CIR |= RCC_CIR_CSSC; // Clear CSSF flag

}
}
вот такая тактовая частота.Я знаю что проблема в настройки шины .Но что я ещё не учёл ? Не знаю .Да и stm32f4 без заморочек не запускается.Котики помогите .Что упускаю?Какую настройку?

Добавлено after 5 minutes 29 seconds:
Код:
[*]

#define I2C_REQUEST_WRITE 0x00
#define I2C_REQUEST_READ 0x01
#define I2C_OWNADDRESS1_7BIT 0x00004000U
#define I2C_MODE_I2C 0x00000000U
//----------
__IO uint32_t tmpreg1;
//----------
void I2C_SendByteByADDR(I2C_TypeDef * i2c, uint8_t c,uint8_t addr)
{

i2c->CR1&=~ I2C_CR1_POS;
i2c->CR1|= I2C_CR1_ACK;
i2c->CR1|= I2C_CR1_START;
while (!(i2c->SR1& I2C_SR1_SB)){};
(void) i2c->SR1;

i2c->DR =addr | I2C_REQUEST_WRITE;
while (!(i2c->SR1& I2C_SR1_ADDR)){};
(void) i2c->SR1;
(void) i2c->SR2;

i2c->DR=c;
while (!(i2c->SR1& I2C_SR1_TXE)){};

i2c->CR1|= I2C_CR1_STOP;
}
Функция отправки байта. Она работает .Проверенно в кубе ll библиотека.


Вернуться наверх
 
Не в сети
 Заголовок сообщения: Re: stm32f1 cmsis настройка I2C
СообщениеДобавлено: Сб ноя 21, 2020 23:26:37 
Мучитель микросхем

Карма: -8
Рейтинг сообщений: -23
Зарегистрирован: Вс дек 29, 2019 08:05:21
Сообщений: 440
Рейтинг сообщения: 0
АУ вы где.? За мышами побижали?


Вернуться наверх
 
Не в сети
 Заголовок сообщения: Re: stm32f1 cmsis настройка I2C
СообщениеДобавлено: Вс ноя 22, 2020 14:38:36 
Мучитель микросхем

Карма: -8
Рейтинг сообщений: -23
Зарегистрирован: Вс дек 29, 2019 08:05:21
Сообщений: 440
Рейтинг сообщения: 0
ну отключите АФ на эти ноги,
для работы i2c все равно включите, согласно п.12 этой процедуры.
я так понимаю у Вас не складывается дружба с i2c, и Вы почему-то решили что эта процедура Вам должна помочь, а то что она для решения конкретной (и скорее всего не Вашей) ситуации Вас не интересует.

На stm32f407 всё получилось.А на stm32f103 пока 0.Я три недели болел ковид.
Код:

Код:

int main(void)
{

RCC_init();
init_systimer1();

APB1_GPIO_init();
GPIO_inits();
// I2C_Init();
//LCD_ini();
I2C_Init();
// RCC->APB1ENR&=~ RCC_APB1ENR_I2C1EN;
RCC->APB2ENR &=~RCC_APB2ENR_AFIOEN;
I2C1->CR1&=~I2C_CR1_PE;
GPIOB->CRL &= ~(GPIO_CRL_CNF6 | GPIO_CRL_CNF7);
GPIOB->CRL |= GPIO_CRL_CNF6_0 | GPIO_CRL_CNF7_0;//2

GPIOB->ODR |= GPIO_ODR_ODR6 | GPIO_ODR_ODR7;
while(!(GPIOB->IDR &(GPIO_IDR_IDR6 | GPIO_IDR_IDR7)));//3

GPIOB->ODR &= ~(GPIO_ODR_ODR7);//4
while(GPIOB->IDR & GPIO_IDR_IDR7 );//5

GPIOB->ODR &= ~(GPIO_ODR_ODR6);//6
while(GPIOB->IDR & GPIO_IDR_IDR6);//7

GPIOB->ODR |= GPIO_ODR_ODR6;//8
while(!(GPIOB->IDR & GPIO_IDR_IDR6));//9

GPIOB->ODR |= GPIO_ODR_ODR7;//10
while(!(GPIOB->IDR & GPIO_IDR_IDR7));//11
//

// PB6 SCL pin
// RCC->APB2ENR |=RCC_APB2ENR_AFIOEN;
// RCC->APB1ENR=RCC_APB1ENR_I2C1EN;
RCC->APB2ENR |=RCC_APB2ENR_AFIOEN;
GPIOB->CRL|=GPIO_CRL_CNF6; // 12 alternate function open drain
GPIOB->CRL|=GPIO_CRL_MODE6; // max speed 50MHz

// PB7 SDA pin
GPIOB->CRL|=GPIO_CRL_CNF7; // alternate function open drain
GPIOB->CRL|=GPIO_CRL_MODE7; // max speed 50MHz



I2C1->CR1 |= I2C_CR1_SWRST;//13
I2C1->CR1 &= ~I2C_CR1_SWRST;//1
// RCC->APB1RSTR|=RCC_APB1RSTR_I2C1RST ;
// RCC->APB1RSTR&=~RCC_APB1RSTR_I2C1RST ;
SET_BIT(I2C1->CR1, I2C_CR1_PE);
timer_1();
timer_3();
//init_systimer1();

init_ADC1();

LCD_ini();
// LCD_Clear();

LCD_SetPos(5,1);
LCD_String("String 2");
ADC1->CR2|=ADC_CR2_JEXTSEL_1;
Код:

#include "i2c_user.h"
#include"main.h"
//----------
#define I2C_REQUEST_WRITE 0x00
#define I2C_REQUEST_READ 0x01
#define I2C_OWNADDRESS1_7BIT 0x00004000U
#define I2C_MODE_I2C 0x00000000U
//----------
__IO uint32_t tmpreg1;
//----------
void I2C_SendByteByADDR(I2C_TypeDef * i2c, uint8_t c,uint8_t addr)
{

i2c->CR1&=~I2C_CR1_POS;
i2c->CR1|= I2C_CR1_ACK;
i2c->CR1|= I2C_CR1_START;
while (!(i2c->SR1& I2C_SR1_SB)){};
(void) i2c->SR1;
i2c->DR|= addr | I2C_REQUEST_WRITE;
while (!(i2c->SR1& I2C_SR1_ADDR)){};
(void) i2c->SR1;
(void) i2c->SR2;
//I2C_Write_Byte(c);
i2c->DR|= c;
while (!(i2c->SR1&I2C_SR1_TXE)){};
i2c->CR1|= I2C_CR1_STOP;
}
//----------
void I2C_Init(void)
{
//I2C1 GPIO
RCC->APB2ENR|=RCC_APB2ENR_IOPBEN ;
GPIOB->CRL|= GPIO_CRL_CNF7_1 | GPIO_CRL_CNF6_1 | GPIO_CRL_CNF7_0 | GPIO_CRL_CNF6_0 |
GPIO_CRL_MODE7_1 | GPIO_CRL_MODE6_1 | GPIO_CRL_MODE7_0 | GPIO_CRL_MODE6_0;
RCC->APB2ENR |= RCC_APB2ENR_AFIOEN;
RCC->APB1ENR|= RCC_APB1ENR_I2C1EN;
I2C1->CR1&=~I2C_CR1_SMBUS ;
I2C1->CCR &=~I2C_CCR_FS;


CLEAR_BIT(I2C1->CR1, I2C_CR1_NOSTRETCH);




I2C1->CR2 |=_VAL2FLD(I2C_CR2_FREQ,36);

I2C1->CCR|=180;
I2C1->TRISE|= 37;
I2C1->OAR1 |= I2C_OWNADDRESS1_7BIT;//(36MHz/100KHz/2)
//(1mcs/(1/36MHz)+1)

I2C1->CR1|= I2C_CR1_ACK;
I2C1->CR1|=I2C_CR1_PE;
}
Не работает.Что не хватает?


Вернуться наверх
 
Не в сети
 Заголовок сообщения: Re: stm32f1 cmsis настройка I2C
СообщениеДобавлено: Вс ноя 22, 2020 17:36:10 
Опытный кот
Аватар пользователя

Карма: 16
Рейтинг сообщений: 170
Зарегистрирован: Вс дек 02, 2012 16:58:33
Сообщений: 827
Откуда: Уже не город Белых гор
Рейтинг сообщения: 0
Я тоже немного приболел, и не могу проверить ваш код.
Вот рабочий код из рабочего проекта:
Спойлер
Код:
/*******************************************************************************
// Wait until I2C flag cleared
// input:
//   I2C_Flag - I2C flag (one of I2C_F_XXX values)
// return:
//   SUCCESS if flag cleared or ERROR in case of timeout
*******************************************************************************/
ErrorStatus wait_flag_reset (volatile u16 *reg, u16 Flag)
{
  u32 timer;
 
  timer_reset (&timer);
   while (timer_active (&timer, 3)) // Wait until flag cleared
  {
      if (!(*reg & Flag)) return SUCCESS;
   }
   return ERROR;
}

ErrorStatus i2c_init (void)
{
  const u32 i2c_APB_freq = 36;  // частота шины APB 32МГц
  const u32 i2c_freq = 400; // частота i2c= 400 кГц
  // CCR = 45, это кол-во тактов APB1 на полупериод SCL (36МГц/(400КГц * 2))
//  u32 i2c_ccr = 180;  // 36MHz / (2 * 100kHz) = 180
  const u32 i2c_ccr = (i2c_APB_freq * 1000) / (2 * i2c_freq);  // i2c_APB_freq / (2 * 400kHz) = 45
  // TRISE = 9, это кол-во тактов APB1, через которое проверяется состояние SCL
  // при переходе в откл. состояние (из 0 в 1),
  // это время должно быть чуть больше 1 мкс (1мкс/(1/i2c_APB_freq)+1) = i2c_APB_freq + 1
  const u32 t_rise = i2c_APB_freq + 1;
 
//---------- из Errata------------------------------------//
//1.Disable the I2C peripheral by clearing the PE bit in I2Cx_CR1 register.
   I2C1->CR1 &= ~I2C_CR1_PE;
//2. Configure the SCL and SDA I/Os as General Purpose Output Open-Drain, High level (Write 1 to GPIOx_ODR).
  GPIOB->CRL = GPIO_CRL_MODE0_INPUT     | GPIO_CRL_CNF0_IN_FL
            | GPIO_CRL_MODE1_INPUT      | GPIO_CRL_CNF1_IN_FL
            | GPIO_CRL_MODE2_INPUT      | GPIO_CRL_CNF2_IN_FL
            | GPIO_CRL_MODE3_INPUT      | GPIO_CRL_CNF3_IN_FL
            | GPIO_CRL_MODE4_INPUT      | GPIO_CRL_CNF4_IN_FL
            | GPIO_CRL_MODE5_INPUT      | GPIO_CRL_CNF5_IN_FL
            | GPIO_CRL_MODE6_OUTPUT10M  | GPIO_CRL_CNF6_OUT_GP_PP
            | GPIO_CRL_MODE7_OUTPUT10M  | GPIO_CRL_CNF7_OUT_GP_PP;
  GPIOB->BSRR = GPIO_BSRR_BS6 | GPIO_BSRR_BS7;
//3. Check SCL and SDA High level in GPIOx_IDR.
  wait_flag_set ((u16 *)GPIOB->IDR, GPIO_IDR_IDR6 | GPIO_IDR_IDR7);
//  while (!(GPIOB->IDR &(GPIO_IDR_IDR6 | GPIO_IDR_IDR7)));
//4. Configure the SDA I/O as General Purpose Output Open-Drain, Low level (Write 0 to GPIOx_ODR).
  GPIOB->CRL = GPIO_CRL_MODE0_INPUT     | GPIO_CRL_CNF0_IN_FL
            | GPIO_CRL_MODE1_INPUT      | GPIO_CRL_CNF1_IN_FL
            | GPIO_CRL_MODE2_INPUT      | GPIO_CRL_CNF2_IN_FL
            | GPIO_CRL_MODE3_INPUT      | GPIO_CRL_CNF3_IN_FL
            | GPIO_CRL_MODE4_INPUT      | GPIO_CRL_CNF4_IN_FL
            | GPIO_CRL_MODE5_INPUT      | GPIO_CRL_CNF5_IN_FL
            | GPIO_CRL_MODE6_OUTPUT10M  | GPIO_CRL_CNF6_OUT_GP_PP
            | GPIO_CRL_MODE7_OUTPUT10M  | GPIO_CRL_CNF7_OUT_GP_OD;
  GPIOB->BRR = GPIO_BRR_BR7;
//5. Check SDA Low level in GPIOx_IDR.
  wait_flag_reset ((u16 *)GPIOB->IDR, GPIO_IDR_IDR7);
//  while (GPIOB->IDR & GPIO_IDR_IDR7);
//6. Configure the SCL I/O as General Purpose Output Open-Drain, Low level (Write 0 to GPIOx_ODR).
  GPIOB->CRL = GPIO_CRL_MODE0_INPUT     | GPIO_CRL_CNF0_IN_FL
            | GPIO_CRL_MODE1_INPUT      | GPIO_CRL_CNF1_IN_FL
            | GPIO_CRL_MODE2_INPUT      | GPIO_CRL_CNF2_IN_FL
            | GPIO_CRL_MODE3_INPUT      | GPIO_CRL_CNF3_IN_FL
            | GPIO_CRL_MODE4_INPUT      | GPIO_CRL_CNF4_IN_FL
            | GPIO_CRL_MODE5_INPUT      | GPIO_CRL_CNF5_IN_FL
            | GPIO_CRL_MODE6_OUTPUT10M  | GPIO_CRL_CNF6_OUT_GP_OD
            | GPIO_CRL_MODE7_OUTPUT10M  | GPIO_CRL_CNF7_OUT_GP_OD;
  GPIOB->BRR = GPIO_BRR_BR6;
//7. Check SCL Low level in GPIOx_IDR.
  wait_flag_reset ((u16 *)GPIOB->IDR, GPIO_IDR_IDR6);
//  while (GPIOB->IDR & GPIO_IDR_IDR6);
//8. Configure the SCL I/O as General Purpose Output Open-Drain, High level (Write 1 to GPIOx_ODR).
  GPIOB->BSRR = GPIO_BSRR_BS6;
//9. Check SCL High level in GPIOx_IDR.
  wait_flag_set ((u16 *)GPIOB->IDR, GPIO_IDR_IDR6);
//  while (!(GPIOB->IDR & GPIO_IDR_IDR6));
//10. Configure the SDA I/O as General Purpose Output Open-Drain , High level (Write 1 to GPIOx_ODR).
  GPIOB->BSRR = GPIO_BSRR_BS7;
//11. Check SDA High level in GPIOx_IDR.
  wait_flag_set ((u16 *)GPIOB->IDR, GPIO_IDR_IDR7);
//  while (!(GPIOB->IDR & GPIO_IDR_IDR7));
//12. Configure the SCL and SDA I/Os as Alternate function Open-Drain.
  GPIOB->CRL = GPIO_CRL_MODE0_INPUT     | GPIO_CRL_CNF0_IN_FL
            | GPIO_CRL_MODE1_INPUT      | GPIO_CRL_CNF1_IN_FL
            | GPIO_CRL_MODE2_INPUT      | GPIO_CRL_CNF2_IN_FL
            | GPIO_CRL_MODE3_INPUT      | GPIO_CRL_CNF3_IN_FL
            | GPIO_CRL_MODE4_INPUT      | GPIO_CRL_CNF4_IN_FL
            | GPIO_CRL_MODE5_INPUT      | GPIO_CRL_CNF5_IN_FL
            | GPIO_CRL_MODE6_OUTPUT10M  | GPIO_CRL_CNF6_OUT_AF_OD
            | GPIO_CRL_MODE7_OUTPUT10M  | GPIO_CRL_CNF7_OUT_AF_OD;
//13. Set SWRST bit in I2Cx_CR1 register.
  I2C1->CR1 = I2C_CR1_SWRST;
//14. Clear SWRST bit in I2Cx_CR1 register.
  I2C1->CR1 = 0;
//15. Enable the I2C peripheral by setting the PE bit in I2Cx_CR1 register.
//----------//
  I2C1->CR2 = (I2C_CR2_FREQ & (i2c_APB_freq / 2)) // Peripheral Clock Frequency in MHz */
        | I2C_CR2_ITERREN   * 0   // Error Interrupt Enable
        | I2C_CR2_ITEVTEN   * 0   // Event Interrupt Enable
        | I2C_CR2_ITBUFEN   * 0   // Buffer Interrupt Enable
        | I2C_CR2_DMAEN     * 0   // DMA Requests Enable
        | I2C_CR2_LAST      * 0;  // DMA Last Transfer
 
  I2C1->TRISE = t_rise;
 
  I2C1->CCR = (I2C_CCR_CCR & i2c_ccr)
        | I2C_CCR_FS_F;   // Fm mode 400 kHz
  // Set I2C own address: 0x00, 7-bit
   I2C1->OAR1 = (1 << 14); // Bit 14 should be kept as 1
 
  I2C1->CR1 = I2C_CR1_PE    * 1   // Peripheral Enable
        | I2C_CR1_SMBUS     * 0   // SMBus Mode
        | I2C_CR1_SMBTYPE   * 0   // SMBus Type
        | I2C_CR1_ENARP     * 0   // ARP Enable
        | I2C_CR1_ENPEC     * 0   // PEC Enable
        | I2C_CR1_ENGC      * 0   // General Call Enable
        | I2C_CR1_NOSTRETCH * 0   // Clock Stretching Disable (Slave mode)
        | I2C_CR1_START     * 0   // Start Generation
        | I2C_CR1_STOP      * 0   // Stop Generation
        | I2C_CR1_ACK       * 1   // Acknowledge Enable
        | I2C_CR1_POS       * 0   // Acknowledge/PEC Position (for data reception)
        | I2C_CR1_PEC       * 0   // Packet Error Checking
        | I2C_CR1_ALERT     * 0   // SMBus Alert
        | I2C_CR1_SWRST     * 0;  // Software Reset

   // Wait until I2C bus is free
  ErrorStatus stat;
  stat = wait_flag_reset (&I2C1->SR2, I2C_SR2_BUSY);
  return stat;
}

Запись и чтение 8 и 16 бит данных:
Спойлер
Код:
ErrorStatus i2c_write (u8 addr, u8 *cmd, u16 len, u8 cont)
{
  I2C1->CR1 |= I2C_CR1_START;//стартуем
  if (wait_flag_set (&I2C1->SR1, I2C_SR1_SB) == ERROR) return ERROR;  // Wait for EV5

  I2C1->DR = addr & ~0x01; //передаем адрес устройства, бит 0 = 0 (запись)
  if (wait_flag_set (&I2C1->SR1, I2C_SR1_ADDR) == ERROR) return ERROR;  // Wait for EV6
  if (I2C1->SR1 & I2C_SR1_AF) return ERROR;  // if NACK
  (void) I2C1->SR1;  // clear ADDR
  (void) I2C1->SR2;  // clear ADDR

   I2C1->DR = *cmd++;  // Send first byte (EV8)
   while (--len)       // Send rest of data (if present)
  {
      if (wait_flag_set (&I2C1->SR1, I2C_SR1_TXE) == ERROR) return ERROR; // Wait for BTF flag set
      I2C1->DR = *cmd++;// Transmit byte via I2C
   }
   if (wait_flag_set (&I2C1->SR1, I2C_SR1_TXE | I2C_SR1_BTF) == ERROR) return ERROR; // Wait for BTF flag set

  if (!cont)
  {
    I2C1->CR1 |= I2C_CR1_STOP;
    if (wait_flag_reset (&I2C1->SR1, I2C_SR1_STOPF) == ERROR) return ERROR;
  }
  return SUCCESS;
}


ErrorStatus i2c_read (u8 addr, u8 *data, u16 len)
{
   I2C1->CR1 |= I2C_CR1_START; //рестарт!!!
   if (wait_flag_set (&I2C1->SR1, I2C_SR1_SB) == ERROR) return ERROR;  // Wait for EV5

   //передаем адрес устройства, но теперь для чтения
   I2C1->DR = addr | 0x01;
   if (wait_flag_set (&I2C1->SR1, I2C_SR1_ADDR) == ERROR) return ERROR; // Wait for EV6
 
   // There are can be three cases:
   //   read 1 byte
   //   read 2 bytes
   //   read more than 2 bytes
   if (len == 1) // Receive 1 byte (AN2824 figure 2)
  {
      I2C1->CR1 &= ~I2C_CR1_ACK;  // Disable I2C acknowledgment   
      __disable_irq();            // EV6_1 must be atomic operation (AN2824)
      (void) I2C1->SR1;           // Clear ADDR bit
      (void) I2C1->SR2;
      I2C1->CR1 |= I2C_CR1_STOP;  // Generate a STOP condition
      __enable_irq();
      // Wait for RxNE flag (receive buffer not empty) EV7
      if (wait_flag_set (&I2C1->SR1, I2C_SR1_RXNE) == ERROR) return ERROR;
      *data = (u8)I2C1->DR;       // Read received byte
   }
  else if (len == 2) // Receive 2 bytes (AN2824 figure 2)
  {
      I2C1->CR1 |= I2C_CR1_POS;   // Set POS flag (NACK position next)
      __disable_irq();            // EV6_1 must be atomic operation (AN2824)
    (void) I2C1->SR1;
      (void) I2C1->SR2;           // Clear ADDR bit
      I2C1->CR1 &= ~I2C_CR1_ACK;  // Disable I2C acknowledgment
      __enable_irq();
      // Wait for BTF flag set (byte transfer finished) EV7_3
      if (wait_flag_set (&I2C1->SR1, I2C_SR1_BTF) == ERROR) return ERROR;
      __disable_irq();            // This should be atomic operation
      I2C1->CR1 |= I2C_CR1_STOP;  // Generate a STOP condition
      *data++ = (u8)I2C1->DR;     // Read first received byte
      __enable_irq();
      *data = (u8)I2C1->DR;       // Read second received byte
   I2C1->CR1 &= ~I2C_CR1_POS;   // Clear POS flag // NACK position current
   }
  else // Receive more than 2 bytes (AN2824 figure 1)
  {
    (void) I2C1->SR1;
      (void) I2C1->SR2;           // Clear ADDR bit
      while (len-- > 2)          // Read received bytes into buffer
    {
         // Wait for BTF (cannot guarantee 1 transfer completion time)
         if (wait_flag_set (&I2C1->SR1, I2C_SR1_BTF) == ERROR) return ERROR;
         *data++ = (u8)I2C1->DR;
      }
      // Wait for BTF flag set (byte transfer finished) EV7_2
      if (wait_flag_set (&I2C1->SR1, I2C_SR1_BTF) == ERROR) return ERROR;
      I2C1->CR1 &= ~I2C_CR1_ACK;  // Disable the I2C acknowledgment
      __disable_irq();
      I2C1->CR1 |= I2C_CR1_STOP;  // Generate a STOP condition
      *data++ = (u8)I2C1->DR;     // Read received byte N-1
      __enable_irq();
      // Wait for last byte received
     if (wait_flag_set (&I2C1->SR1, I2C_SR1_RXNE) == ERROR) return ERROR;
      *data = (u8)I2C1->DR;// Read last received byte
   }
   // Wait for a STOP flag
   if (wait_flag_reset (&I2C1->SR1, I2C_SR1_STOPF) == ERROR) return ERROR;
  I2C1->CR1 |= I2C_CR1_ACK;   // Enable Acknowledgment
 
   return SUCCESS;   
}


ErrorStatus i2c_read16 (u8 addr, u16 *data, u16 len)
{
  u16 first_byte;
  u16 second_byte;
 
   I2C1->CR1 |= I2C_CR1_START; //рестарт!!!
   if (wait_flag_set (&I2C1->SR1, I2C_SR1_SB) == ERROR) return ERROR; // Wait for EV5
   //передаем адрес устройства, но теперь для чтения
   I2C1->DR = addr | 0x01;
   if (wait_flag_set (&I2C1->SR1, I2C_SR1_ADDR) == ERROR) return ERROR; // Wait for EV6
 
  if (len == 1) // Receive only 2 bytes (AN2824 figure 2)
  {
    I2C1->CR1 |= I2C_CR1_POS;       // Set POS flag (NACK position next)
    __disable_irq();                // This should be atomic operation
    (void) I2C1->SR1;               
    (void) I2C1->SR2;               // reset ADDR
    I2C1->CR1 &= ~I2C_CR1_ACK;      // NACK, Disable the I2C acknowledgment
    __enable_irq();
    // Wait for BTF flag set (byte transfer finished) EV7_3
    if (wait_flag_set (&I2C1->SR1, I2C_SR1_BTF) == ERROR) return ERROR;
    __disable_irq();                // This should be atomic operation
    I2C1->CR1 |= I2C_CR1_STOP;      // Generate a STOP condition
    first_byte = I2C1->DR << 8;  // Read received byte N-1
    __enable_irq();
    second_byte = I2C1->DR;      // Read second received byte
    *data = (first_byte << 8) | second_byte;
    // Wait for a STOP flag
    if (wait_flag_reset (&I2C1->SR1, I2C_SR1_STOPF) == ERROR) return ERROR;
    I2C1->CR1 &= ~I2C_CR1_POS;  // Clear POS flag // NACK position current
  }
  else
  {
    (void) I2C1->SR1;                       
    (void) I2C1->SR2;                       // reset ADDR
    while (--len)
    {
      if (wait_flag_set (&I2C1->SR1, I2C_SR1_RXNE) == ERROR) return ERROR;
      first_byte = I2C1->DR;
      if (wait_flag_set (&I2C1->SR1, I2C_SR1_RXNE) == ERROR) return ERROR;
      second_byte = I2C1->DR;
      *data++ = (first_byte << 8) | second_byte;
    }
    // receive last two bytes
    if (wait_flag_set (&I2C1->SR1, I2C_SR1_RXNE) == ERROR) return ERROR;   
    I2C1->CR1 &= ~I2C_CR1_ACK;      // NACK, Disable the I2C acknowledgment
    __disable_irq();                // This should be atomic operation
    I2C1->CR1 |= I2C_CR1_STOP;      // Generate a STOP condition
    first_byte = I2C1->DR;          // Read received byte N-1
    __enable_irq();
   
    if (wait_flag_set (&I2C1->SR1, I2C_SR1_RXNE) == ERROR) return ERROR;
    second_byte = I2C1->DR;      // Read second received byte
    // Wait for a STOP flag
    if (wait_flag_reset (&I2C1->SR1, I2C_SR1_STOPF) == ERROR) return ERROR;
    *data = (first_byte << 8) | second_byte;
  }
  I2C1->CR1 |= I2C_CR1_ACK;   // Enable Acknowledgment
   return SUCCESS;   
}


Вернуться наверх
 
Показать сообщения за:  Сортировать по:  Вернуться наверх
Начать новую тему Ответить на тему  [ Сообщений: 37 ]    , 2

Часовой пояс: UTC + 3 часа


Кто сейчас на форуме

Сейчас этот форум просматривают: Google [Bot], mab72 и гости: 32


Вы не можете начинать темы
Вы не можете отвечать на сообщения
Вы не можете редактировать свои сообщения
Вы не можете удалять свои сообщения
Вы не можете добавлять вложения

Найти:
Перейти:  


Powered by phpBB © 2000, 2002, 2005, 2007 phpBB Group
Русская поддержка phpBB
Extended by Karma MOD © 2007—2012 m157y
Extended by Topic Tags MOD © 2012 m157y