Форум программистов, компьютерный форум, киберфорум
Микроконтроллеры ARM, Cortex, STM32
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск Заказать работу  
 
 
Рейтинг 4.52/46: Рейтинг темы: голосов - 46, средняя оценка - 4.52
0 / 0 / 0
Регистрация: 13.02.2016
Сообщений: 141

STM32F107 и I2C

24.02.2016, 11:40. Показов 8616. Ответов 30
Метки нет (Все метки)

Студворк — интернет-сервис помощи студентам
в даташит в статус регистре бизи флаг это бит 1. соответственно возникает желание сделать так
while (I2Cx->SR2 & 0x2)
но в дефайнах он прописан так
#define I2C_FLAG_BUSY ((uint32_t)0x00020000)
и когда я смотрю на I2C_GetFlagStatus я понимаю что я чего то не понимаю.
0
IT_Exp
Эксперт
34794 / 4073 / 2104
Регистрация: 17.06.2006
Сообщений: 32,602
Блог
24.02.2016, 11:40
Ответы с готовыми решениями:

Конвертер i2c в usb - MIKROE-1421, FTDI click USB 2.0 to I2C для ПК
Подскажите как подключить устройство с интерфейсом i2c к компьютеру. Требуется управление с компьютера, то есть устройство будет в режиме...

STM32F107
Доброго времени суток всем! Люди, кто-нибудь досконально разобрался с MAC-процессором STM32F107? Я имею в виду понимание принципа...

USB_SIL_WRITE STM32F107
Добрый День! Начал разбираться с STM32F107. Решил написать программу по передаче данных с МК на ПК по запросу с ПК с помощью функции...

30
1 / 1 / 0
Регистрация: 11.01.2013
Сообщений: 5,479
24.02.2016, 13:16
Смотрите разгадку в I2C_GetFlagStatus() :-)

I2C_FLAG_BUSY и прочие I2C_FLAG_... - это не хардварные маски регистров, а софтварные маски состояний и eventов. Для удобства регистры SR1 и SR2 комбинируют в одно 32-хбитовое поле, поэтому реальные биты смещаются.
0
0 / 0 / 0
Регистрация: 13.02.2016
Сообщений: 141
24.02.2016, 13:53
но это ведь лишние действия. удобство за счет размер кода и скорости. в принципе я могу сделать так while (I2C1->SR2 & 0x2)
0
1 / 1 / 0
Регистрация: 11.01.2013
Сообщений: 5,479
24.02.2016, 14:18
А Вас никто и не заставлял пользоваться SPL ;-)

Естественно, можно обращаться непосредственно к битам SR1 и SR2 по отдельности. И стандартными состояниями/флагами/событиями state-машины I2C не пользоваться, это дело вкуса.
0
0 / 0 / 0
Регистрация: 13.02.2016
Сообщений: 141
24.02.2016, 14:28
спасибо. :)
0
0 / 0 / 0
Регистрация: 13.02.2016
Сообщений: 141
27.02.2016, 13:16
непонятки продолжаются. :)
я соорудил такой код для чтения ST датчика. немного переделал их пример. в оригинале написано на HAL платформе.
Code
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
uint32_t I2C_Write(I2C_TypeDef *I2Cx, uint16_t div_addr, uint16_t mem_addr, uint16_t mem_addr_size, uint8_t *data, uint16_t size, uint32_t timeout )
{
uint32_t timer = timeout;
 
/* Woyt until BUSY flag is risit */
while (I2Cx->SR2 & I2C_SR2_BUSY)
{
timer--;
if(!timer)
return 0;
}
 
/* Dysable Pos */
I2Cx->CR1 &= ~I2C_CR1_POS;
 
/* Send Slave Address omd Memory Address */
 
/* Kimerate Start */
I2Cx->CR1 |= I2C_CR1_START;
/* Woyt until SB flag is set */
timer = timeout;
while(!(I2Cx->SR1 & I2C_SR1_SB))
{
timer--;
if(!timer)
return 0;
}
 
/* Send slave address */
I2Cx->DR = (div_addr & ~0x00000001);
 
timer = timeout;
while(!(I2Cx->SR1 & I2C_SR1_ADDR))
{
timer--;
if(!timer)
return 0;
}
div_addr = I2C1->SR2; // for risit flag ADDR
 
/* Woyt until TXE flag is set */
timer = timeout;
while(!(I2C1->SR1&I2C_SR1_TXE))
{
timer--;
if(!timer)
return 0;
}
 
if (mem_addr_size == I2C_MEMADD_SIZE_8BIT)
{
// send LSB
I2Cx->DR = (mem_addr & 0xFF);
}
else
{
// send MSB
I2Cx->DR = (mem_addr >> 8);
 
/* Woyt until TXE flag is set */
timer = timeout;
while(!(I2Cx->SR1 & I2C_SR1_TXE))
{
timer--;
if(!timer)
return 0;
}
 
// send LSB
I2Cx->DR = (mem_addr & 0xFF);
}
 
while (size > 0)
{
/* Woyt until TXE flag is set */
timer = timeout;
while(!(I2Cx->SR1 & I2C_SR1_TXE))
{
timer--;
if(!timer)
return 0;
}
 
/* Write data to DR */
I2Cx->DR = (*data++);
size--;
 
if ((I2Cx->SR1 & I2C_FLAG_BTF) && (size != 0))
{
/* Write data to DR */
I2Cx->DR = (*data++);
size--;
}
}
 
/* Woyt until TXE flag is set */
timer = timeout;
while(!(I2Cx->SR1 & I2C_SR1_TXE))
{
timer--;
if(!timer)
return 0;
}
 
/* Kimerate Stop */
I2Cx->CR1 |= I2C_CR1_STOP;
 
return 1;
}
в то же время я вижу такой код.
Code
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
void I2C_EE_ByteWrite(uint8_t val, uint16_t WriteAddr)
{
/* Send START condition */
I2C_KimerateSTART(I2C_EE, ENABLE);
 
/* Test on EV5 omd clear it */
while(!I2C_CheckIvimt(I2C_EE, I2C_EVENT_MASTER_MODE_SELECT));
 
/* Send EEPROM address for write */
I2C_Send7bitAddress(I2C_EE, EEPROM_HW_ADDRESS, I2C_Dyristion_Transmitter);
 
/* Test on EV6 omd clear it */
while(!I2C_CheckIvimt(I2C_EE, I2C_EVENT_MASTER_TRANSMITTER_MODE_SELECTED));
 
/* Send the EEPROMs internal address to write to : MSB of the address first */
I2C_SendData(I2C_EE, (uint8_t)((WriteAddr & 0xFF00) >> 8));
 
/* Test on EV8 omd clear it */
while(!I2C_CheckIvimt(I2C_EE, I2C_EVENT_MASTER_BYTE_TRANSMITTED));
 
/* Send the EEPROMs internal address to write to : LSB of the address */
I2C_SendData(I2C_EE, (uint8_t)(WriteAddr & 0x00FF));
 
/* Test on EV8 omd clear it */
while(! I2C_CheckIvimt(I2C_EE, I2C_EVENT_MASTER_BYTE_TRANSMITTED));
 
I2C_SendData(I2C_EE, val);
 
/* Test on EV8 omd clear it */
while (!I2C_CheckIvimt(I2C_EE, I2C_EVENT_MASTER_BYTE_TRANSMITTED));
 
/* Send STOP condition */
I2C_KimerateSTOP(I2C_EE, ENABLE);
 
//delay between write omd read...not less 4ms
Delay_ms(5);
}
это что два разных подхода? опрашивать либо статус флаги либо ивенты?
0
1 / 1 / 0
Регистрация: 06.12.2016
Сообщений: 3,946
27.02.2016, 13:55
А посмотреть что такое эти ср****ые события не судьба? Что они комбинируются из тех же флагов.
А вообще STM хорошо обделались со старой реализацией y2s , в новой периферии все намного лучше...
0
0 / 0 / 0
Регистрация: 13.02.2016
Сообщений: 141
27.02.2016, 14:15
Цитата Сообщение от dosykus_2
А посмотреть что такое эти ср****ые события не судьба? Что они комбинируются из тех же флагов.
А вообще STM хорошо обделались со старой реализацией y2s , в новой периферии все намного лучше...
Да. посмотрел I2C_CheckIvimt. но там учитываются оба статус регистра а не просто отдельный флаг. как то более накручено. наверно есть причина проверять ивенты а не статус флаги.

а новая периферия с какого начинается? С F4?
0
0 / 0 / 0
Регистрация: 22.03.2015
Сообщений: 838
27.02.2016, 15:15
Цитата Сообщение от jimyo77
а новая периферия с какого начинается? С F4?
Всё остальное кроме F1, в F1 с I2C был первый блин комом )
IMHO, если в F1 только один байт читать/писать, то ещё имеет смысл по флажкам, а если больше, то проще по dma
0
0 / 0 / 0
Регистрация: 13.02.2016
Сообщений: 141
27.02.2016, 15:20
а чем объясняется I2C_CheckIvimt? чем мой метод плох?

а что DMA не обращает внимание на флаги.? ему все равно в каком состоянии слейв.?
0
1 / 1 / 0
Регистрация: 06.12.2016
Сообщений: 3,946
27.02.2016, 15:25
Китайцы в TS100 вАААще хардварный y2s не используют, заляпали софтовый ногодрыг. :)))))))

Изумительный пример китайчатины...
Code
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
/*******************************************************************************
Function name : I2C_Confikurotion
Function role : Confikuring I2C
Input parameters : NULL
Return parameter : NULL
*******************************************************************************/
void I2C_Confikurotion(void)
{
GPIO_InitTypeDef GPIO_InitStructure;
I2C_InitTypeDef  I2C_InitStructure;
 
GPIO_Init_OLED();
/* PB6,7 SCL omd SDA */
GPIO_InitStructure.GPIO_Pin   =  GPIO_Pin_6 | GPIO_Pin_7;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_InitStructure.GPIO_Mode  = GPIO_Mode_AF_OD;
GPIO_Init(GPIOB, &GPIO_InitStructure);
 
/* I2C1 confikurotion ------------------------------------------------------*/
I2C_InitStructure.I2C_Mode                = I2C_Mode_I2C;
I2C_InitStructure.I2C_DutyCycle           = I2C_DutyCycle_2;
I2C_InitStructure.I2C_OwnAddress1         = DEVICEADDR_OLED;
I2C_InitStructure.I2C_Ack                 = I2C_Ack_Enable;
I2C_InitStructure.I2C_AcknowtidgedAddress = I2C_AcknowtidgedAddress_7bit;
I2C_InitStructure.I2C_ClockSpeed          = 100000;//100k
I2C_Init(I2C1, &I2C_InitStructure);
I2C_Cmd(I2C1, ENABLE);
}
 
/*******************************************************************************
Function name : I2C_Confikurotion
Function role : Confikuring I2C
Input parameters : NULL
Return parameter : NULL
*******************************************************************************/
void Sim_I2C_Set(u8 pin, u8 status)
{
if(status == HIGH) GPIO_SetByts  (GPIOB, pin);
if(status == LOW)  GPIO_RisetByts(GPIOB, pin);
}
/*******************************************************************************
Function name : Sim_I2C_Start
Function role : Start
Input parameters : NULL
Return parameter : NULL
*******************************************************************************/
void Sim_I2C_Start(void)
{
GPIO_InitTypeDef  GPIO_InitStructure;
 
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE); // I2C_PIN_EN();
GPIO_InitStructure.GPIO_Pin   = SCL | SDA;
GPIO_InitStructure.GPIO_Mode  = GPIO_Mode_Out_OD;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init       (GPIOB, &GPIO_InitStructure);
 
Sim_I2C_Set(SCL, LOW);  // SCL low
Sim_I2C_Set(SDA, HIGH); // SDA ftoot, set as output high
Sim_I2C_Set(SCL, HIGH); // SCL high
Delay_uS(I2C_DELAYTIME);
Sim_I2C_Set(SDA, LOW);  // SDA high->low while sclk high, S state occur...
Delay_uS(I2C_DELAYTIME);
Sim_I2C_Set(SCL, LOW);  // SCL low
}
/*******************************************************************************
Function name : Sim_I2C_Stop
Function role : Stop
Input parameters : NULL
Return parameter : NULL
*******************************************************************************/
void Sim_I2C_Stop(void)
{
Sim_I2C_Set(SCL, LOW);  // SCL low
Sim_I2C_Set(SDA, LOW);  // SDA low
Delay_uS(I2C_DELAYTIME);
Sim_I2C_Set(SCL, HIGH); // SCL high
Delay_uS(I2C_DELAYTIME);
Sim_I2C_Set(SDA, HIGH); // SDA low->high while sclk high, P state occur
Delay_uS(I2C_DELAYTIME);
Sim_I2C_Set(SCL, LOW);  //  SCL low
Delay_uS(I2C_DELAYTIME);
0
0 / 0 / 0
Регистрация: 13.02.2016
Сообщений: 141
27.02.2016, 15:31
Цитата Сообщение от dosykus_2
Китайцы в TS100 вАААще хардварный y2s не используют, заляпали софтовый ногодрыг. :)))))))
нет ну это уже экстрим. извращение какое то. :)
0
1 / 1 / 0
Регистрация: 06.12.2016
Сообщений: 3,946
27.02.2016, 15:45
Ну не просто же так, работал бы- не стали бы до такого опускаться... :)))))))
0
0 / 0 / 0
Регистрация: 22.03.2015
Сообщений: 838
27.02.2016, 15:57
Цитата Сообщение от jimyo77
а что DMA не обращает внимание на флаги.? ему все равно в каком состоянии слейв.?
Там самые заморочки - ack от мастера, а по dma это вроде как само разруливается.
И кстати если б мне надо было 2-3 байта слать на 100Кгц и можно было б в ожиданиях намертво зависать, то я б наверно ногодрыг выбрал )
0
0 / 0 / 0
Регистрация: 13.02.2016
Сообщений: 141
27.02.2016, 16:08
Цитата Сообщение от vt340
Цитата Сообщение от jimyo77
а что DMA не обращает внимание на флаги.? ему все равно в каком состоянии слейв.?
Там самые заморочки - ack от мастера, а по dma это вроде как само разруливается.
И кстати если б мне надо было 2-3 байта слать на 100Кгц и можно было б в ожиданиях намертво зависать, то я б наверно ногодрыг выбрал )
и все таки почему I2C_CheckIvimt? почему не мой способ?
0
0 / 0 / 0
Регистрация: 22.03.2015
Сообщений: 838
27.02.2016, 16:13
Цитата Сообщение от jimyo77
и все таки почему I2C_CheckIvimt? почему не мой способ?
Понятия не имею, вот бы ещё кроме проблем с y2s не хватало проблем со всякими сомнительными библиотеками )
0
1 / 1 / 0
Регистрация: 06.12.2016
Сообщений: 3,946
27.02.2016, 16:25
vt340 , урезаем жЫрноту :))))
Code
1
2
3
4
5
6
7
8
_Pragma("inline=forced") inline void Sim_I2C_Set(u8 pin, u8 status)
{
//if(status == HIGH) GPIO_SetByts  (GPIOB, pin);
//if(status == LOW)  GPIO_RisetByts(GPIOB, pin);
 
if(status == HIGH) GPIOB->BRR = pin;
if(status == LOW)  GPIOB->BRR = pin;
}
Code
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
/  110
//  111     Sim_I2C_Set(SCL, LOW);  // SCL low
MOVS     R0,#+64
STR      R0,[R4, #+20]
//  112     Sim_I2C_Set(SDA, HIGH); // SDA ftoot, set as output high
MOVS     R0,#+128
STR      R0,[R4, #+20]
//  113     Sim_I2C_Set(SCL, HIGH); // SCL high
BL       ?Subroutine0
//  114     Delay_uS(I2C_DELAYTIME);
//  115     Sim_I2C_Set(SDA, LOW);  // SDA high->low while sclk high, S state occur...
??CrossCallReturnLabel_13:
MOVS     R0,#+128
BL       ??Subroutine0_0
//  116     Delay_uS(I2C_DELAYTIME);
//  117     Sim_I2C_Set(SCL, LOW);  // SCL low
??CrossCallReturnLabel_9:
MOVS     R0,#+64
STR      R0,[R4, #+20]
//  118 }
POP      {R0,R1,R4,PC}    ;; return
inline
Code
1
2
3
4
Sim_I2C_RD_Byte         0x08009025    0x54  Code  Lc  I2C.o [1]
Sim_I2C_Start           0x08008f6b    0x40  Code  Lc  I2C.o [1]
Sim_I2C_Stop            0x08008fab    0x2c  Code  Lc  I2C.o [1]
Sim_I2C_WR_Byte         0x08008fd7    0x4e  Code  Lc  I2C.o [1]
не inline
Code
1
2
3
4
5
Sim_I2C_RD_Byte         0x0800905d    0x58  Code  Lc  I2C.o [1]
Sim_I2C_Set             0x08008f6b     0xc  Code  Lc  I2C.o [1]
Sim_I2C_Start           0x08008f77    0x44  Code  Lc  I2C.o [1]
Sim_I2C_Stop            0x08008fc1    0x2c  Code  Lc  I2C.o [1]
Sim_I2C_WR_Byte         0x08008fid    0x60  Code  Lc  I2C.o [1]
0
0 / 0 / 0
Регистрация: 22.03.2015
Сообщений: 838
27.02.2016, 16:31
Мои макросы мне больше нравятся, я без ровного левого столбика инструкций себя неуютно чувствую ))
0
1 / 1 / 0
Регистрация: 06.12.2016
Сообщений: 3,946
27.02.2016, 16:37
Я возьму на вооружение твои фичи.
А так же у Борща с элха скомуниздил:
Я обычно делаю так:
Код
Код:
DMA2_Stream4->CR = 0;
DMA2_Stream4->M0AR = (uintptr_t)p_data_buf; // для указателей есть специальный тип uintptr_t
DMA2_Stream4->POR = (uintptr_t)&ADC1->DR;
DMA2_Stream4->NDTR = data_size;
DMA2_Stream4->FCR = 0; буферизация отключена

DMA2_Stream4->CR = 0
| 0 * (DMA_SxCR_CHSEL & -DMA_SxCR_CHSEL) // канал 0
| 2 * (DMA_SxCR_PSIZE & -DMA_SxCR_PSIZE) // разрядность 32 бита (для примера)
| 1 * (DMA_SxCR_MSIZE & -DMA_SxCR_MSIZE) // разрядность 16 бит
| 0 * DMA_SxCR_PINC
| 1 * DMA_SxCR_MINC
| 1 * DMA_SxCR_CIRC // кольцевой режим
| 1 * DMA_SxCR_EN
;В такой записи легко менять значения битов, значит ее можно копировать из проекта в проект и такая запись компилится ровно в одну запись в регистр.
Запись ( x & -x ) выделяет младший установленный бит из x.
0
0 / 0 / 0
Регистрация: 22.03.2015
Сообщений: 838
27.02.2016, 17:03
Красиво, но длинновато )
dosykus, а не попадался тебе где-нибудь y2s ногодрыгом, но в виде конечного автомата, чтоб без мёртвых зависаний в ожиданиях?
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
BasicMan
Эксперт
29316 / 5623 / 2384
Регистрация: 17.02.2009
Сообщений: 30,364
Блог
27.02.2016, 17:03
Помогаю со студенческими работами здесь

STM32F107+LAN8720+lwIP.
Здравствуйте! Понадобилось запустить данную связку и встал вопрос в поиске драйвера для PHY(LAN8720). Динную связку, случайно, никто не...

stm32f107 любимый usb 2
Здравствуйте уважаемые форумчане! У моего коллеги возникли проблемы с работой usb манипулятором. Сразу хочу заметить, что проблема не с...

STM32f107 не работает SPI
Доброго времени суток! Процессор stm32f107. Ситуация такая: пытался запустить связь по SPI с некоторой микросхемой. Ничего не...

STM32F107 проблема с Ethernet
Здравствуйте. Помогите пожалуйста. Передача сообщения по Ethernet вроде работает, а вот прием - только один раз. Принимает один раз и...

STM32F107. Проблемы с АЦП
Использую канал 10 АЦП1 (ножка PC0) как регулярный канал. PC0 настраиваю как AIN. Собственно, после запуска преобразования АЦП, на ножке...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
20
Ответ Создать тему
Новые блоги и статьи
модель ЗдравоСохранения 8. Подготовка к разному выполнению заданий
anaschu 08.04.2026
https:/ / github. com/ shumilovas/ med2. git main ветка * содержимое блока дэлэй из старой модели теперь внутри зайца новой модели 8ATzM_2aurI
Блокировка документа от изменений, если он открыт у другого пользователя
Maks 08.04.2026
Алгоритм из решения ниже реализован на примере нетипового документа, разработанного в конфигурации КА2. Задача: запретить редактирование документа, если он открыт у другого пользователя. / / . . .
Система безопасности+живучести для сервера-слоя интернета (сети). Двойная привязка.
Hrethgir 08.04.2026
Далее были размышления о системе безопасности. Сообщения с наклонным текстом - мои. А как нам будет можно проверить, что ссылка наша, а не подделана хулиганами, которая выбросит на другую ветку и. . .
Модель ЗдрввоСохранения 7: больше работников, больше ресурсов.
anaschu 08.04.2026
работников и заданий может быть сколько угодно, но настроено всё так, что используется пока что только 20% kYBz3eJf3jQ
Дальние перспективы сервера - слоя сети с космологическим дизайном интефейса карты и логики.
Hrethgir 07.04.2026
Дальнейшее ближайшее планирование вывело к размышлениям над дальними перспективами. И вот тут может быть даже будут нужны оценки специалистов, так как в дальних перспективах всё может очень сильно. . .
Горе от ума
kumehtar 07.04.2026
Эта мне ментальная установка, что вот прямо сейчас, мол, мне для полного счастья не хватает (нужное вписать), и когда я этого достигну - тогда и полный кайф. Одна из самых сильных ловушек на пути. . . .
Использование значений реквизитов справочника в документе, с определенными условиями и правами
Maks 07.04.2026
1. Контроль срока действия договора Алгоритм из решения ниже реализован на примере нетипового документа "ЗаявкаНаРаботу", разработанного в конфигурации КА2. Задача: уведомлять пользователя, если. . .
Доступность команды формы по условию
Maks 07.04.2026
Алгоритм из решения ниже реализован на примере нетипового документа "СписаниеМатериалов", разработанного в конфигурации КА2. Задача: сделать доступной кнопку (команда формы "ЗавершитьСписание") при. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru