Форум программистов, компьютерный форум, киберфорум
Микроконтроллеры ARM, Cortex, STM32
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск  
 
 
-26 / 4 / 0
Регистрация: 26.09.2024
Сообщений: 128

Передача данных по i2c через DMA STM32F401CUE6

08.10.2025, 13:46. Показов 4105. Ответов 95
Метки нет (Все метки)

Студворк — интернет-сервис помощи студентам
Добрый день. При попытки передать данные на устройство по i2c через DMA нифига не выходит, DMA не в какую не хочет работать.

Адрес устройства определяется как надо, условие Старт и отправка адреса тоже происходит нормально но DMA не стартует и нет прерывания от DMA.
В отладке видно что бит DMA1_Stream6->CR |= DMA_SxCR_EN; устанавливается.
C
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
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
I2C_HandleTypeDef hi2c1;
 
void SystemClock_Config(void);
static void MX_GPIO_Init(void);
static void MX_I2C1_Init(void);
void DMA_Init(void);
uint8_t st7567a_IsDeviceReady(I2C_HandleTypeDef i2c);
void DMA_Transmit(I2C_HandleTypeDef *hi2c, uint8_t *pBuffer, uint8_t size);
void I2C_write(I2C_HandleTypeDef *hi2c, uint8_t Addr, uint8_t *pBuffer, uint16_t size);
//==============================================================================================================================
 
uint8_t addr_i2c;
uint8_t Buffer[10] = {0x1,0x2,0x3,0x4,0x5,0x6,0x7,0x8,0x9,0xFF};
//==============================================================================================================================
 
void DMA_Init(void)
{
  __enable_irq ();
  RCC->AHB1ENR|=RCC_AHB1ENR_DMA1EN;
  DMA1_Stream6->CR = 0 ;
  DMA1_Stream6->CR |= DMA_CHANNEL_6;
  DMA1_Stream6->CR |= DMA_SxCR_MINC;
  DMA1_Stream6->CR |= DMA_SxCR_DIR_0;
  DMA1_Stream6->CR |= DMA_SxCR_TCIE | DMA_SxCR_HTIE | DMA_SxCR_TEIE | DMA_SxCR_DMEIE;
  HAL_NVIC_SetPriority(DMA1_Stream6_IRQn, 0, 0);
  HAL_NVIC_EnableIRQ(DMA1_Stream6_IRQn);
}
//==============================================================================================================================
 
uint8_t st7567a_IsDeviceReady(I2C_HandleTypeDef i2c)
{
    for(uint8_t i = 0; i < 255; i++)
    {
        HAL_Delay(10);
        if(HAL_I2C_IsDeviceReady(&i2c, i, 3, 100) == HAL_OK)
        {
            return i;
        }
    }
    return 0;
}
//==============================================================================================================================
 
void DMA1_Stream6_IRQHandler(void)
{
    HAL_GPIO_TogglePin(GPIOC, GPIO_PIN_13);
    if(DMA1->HISR & DMA_HISR_TCIF6)
    {
        DMA1->HIFCR &= ~ DMA_HIFCR_CTCIF6;
        DMA1_Stream6->CR&=~DMA_SxCR_EN;
        uint8_t temp __attribute__((unused)) = hi2c1.Instance->SR1 | hi2c1.Instance->SR2;
        hi2c1.Instance->CR1 |= I2C_CR1_STOP;
        while( !( hi2c1.Instance->CR1 & I2C_CR1_STOP )) ;
    }
    else if(DMA1->HISR & DMA_HISR_HTIF6)
        {
        DMA1->HIFCR &= ~ DMA_HIFCR_CHTIF6;
        }
    else if(DMA1->HISR & DMA_HISR_TEIF6)
            {
        DMA1->HIFCR &= ~ DMA_HIFCR_CTEIF6;
            }
    else if(DMA1->HISR & DMA_HISR_DMEIF6)
            {
        DMA1->HIFCR &= ~ DMA_HIFCR_CDMEIF6;
            }
}
 
//==============================================================================================================================
uint8_t tmp = 1;
void DMA_Transmit(I2C_HandleTypeDef *hi2c, uint8_t *pBuffer, uint8_t size)
{
    DMA1_Stream6->M0AR = (uint32_t)pBuffer;
    DMA1_Stream6->PAR=(uint32_t)&hi2c->Instance->DR;
    DMA1_Stream6->NDTR = size;
    hi2c->Instance->CR2 |= I2C_CR2_DMAEN;
    DMA1_Stream6->CR |= DMA_SxCR_EN;
    tmp = 2;
}
//==============================================================================================================================
 
void I2C_write(I2C_HandleTypeDef *hi2c, uint8_t Addr, uint8_t *pBuffer, uint16_t size)
{
    while(hi2c->Instance->SR2&I2C_SR2_BUSY){;}
    hi2c->Instance->CR1 |= I2C_CR1_START | I2C_CR1_ACK;
    while( !( hi2c->Instance->SR1 & I2C_SR1_SB )){;}
    hi2c->Instance->DR = Addr;
    while( !( hi2c->Instance->SR1 & I2C_SR1_ADDR )){;}
    DMA_Transmit(hi2c, pBuffer, size);
}
 
int main(void)
{
SystemClock_Config();
MX_GPIO_Init();
MX_I2C1_Init();
DMA_Init();
addr_i2c = st7567a_IsDeviceReady(hi2c1);
I2C_write(&hi2c1, addr_i2c, Buffer, 10);
while (1)
{
}
}
void SystemClock_Config(void)
{
  RCC_OscInitTypeDef RCC_OscInitStruct = {0};
  RCC_ClkInitTypeDef RCC_ClkInitStruct = {0};
  __HAL_RCC_PWR_CLK_ENABLE();
  __HAL_PWR_VOLTAGESCALING_CONFIG(PWR_REGULATOR_VOLTAGE_SCALE2);
  RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSE;
  RCC_OscInitStruct.HSEState = RCC_HSE_ON;
  RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON;
  RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_HSE;
  RCC_OscInitStruct.PLL.PLLM = 15;
  RCC_OscInitStruct.PLL.PLLN = 72;
  RCC_OscInitStruct.PLL.PLLP = RCC_PLLP_DIV2;
  RCC_OscInitStruct.PLL.PLLQ = 4;
  if (HAL_RCC_OscConfig(&RCC_OscInitStruct) != HAL_OK)
  {
    Error_Handler();
  }
 
  /** Initializes the CPU, AHB and APB buses clocks
  */
  RCC_ClkInitStruct.ClockType = RCC_CLOCKTYPE_HCLK|RCC_CLOCKTYPE_SYSCLK
                              |RCC_CLOCKTYPE_PCLK1|RCC_CLOCKTYPE_PCLK2;
  RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_PLLCLK;
  RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV1;
  RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV2;
  RCC_ClkInitStruct.APB2CLKDivider = RCC_HCLK_DIV1;
 
  if (HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_1) != HAL_OK)
  {
    Error_Handler();
  }
}
 
static void MX_I2C1_Init(void)
{
 
  hi2c1.Instance = I2C1;
  hi2c1.Init.ClockSpeed = 100000;
  hi2c1.Init.DutyCycle = I2C_DUTYCYCLE_2;
  hi2c1.Init.OwnAddress1 = 0;
  hi2c1.Init.AddressingMode = I2C_ADDRESSINGMODE_7BIT;
  hi2c1.Init.DualAddressMode = I2C_DUALADDRESS_DISABLE;
  hi2c1.Init.OwnAddress2 = 0;
  hi2c1.Init.GeneralCallMode = I2C_GENERALCALL_DISABLE;
  hi2c1.Init.NoStretchMode = I2C_NOSTRETCH_DISABLE;
  if (HAL_I2C_Init(&hi2c1) != HAL_OK)
  {
    Error_Handler();
  }
}
 
static void MX_GPIO_Init(void)
{
  GPIO_InitTypeDef GPIO_InitStruct = {0};
 
  /* GPIO Ports Clock Enable */
  __HAL_RCC_GPIOC_CLK_ENABLE();
  __HAL_RCC_GPIOH_CLK_ENABLE();
  __HAL_RCC_GPIOA_CLK_ENABLE();
  __HAL_RCC_GPIOB_CLK_ENABLE();
 
  /*Configure GPIO pin Output Level */
  HAL_GPIO_WritePin(GPIOC, GPIO_PIN_13, GPIO_PIN_SET);
 
  /*Configure GPIO pin Output Level */
  HAL_GPIO_WritePin(GPIOC, GPIO_PIN_14|GPIO_PIN_15, GPIO_PIN_RESET);
 
  /*Configure GPIO pin Output Level */
  HAL_GPIO_WritePin(GPIOA, GPIO_PIN_0|GPIO_PIN_1|GPIO_PIN_2|GPIO_PIN_3
                          |GPIO_PIN_4|GPIO_PIN_5|GPIO_PIN_6|GPIO_PIN_7
                          |GPIO_PIN_8|GPIO_PIN_9|GPIO_PIN_10|GPIO_PIN_11
                          |GPIO_PIN_12|GPIO_PIN_15, GPIO_PIN_RESET);
 
  /*Configure GPIO pin Output Level */
  HAL_GPIO_WritePin(GPIOB, GPIO_PIN_0|GPIO_PIN_1|GPIO_PIN_2|GPIO_PIN_10
                          |GPIO_PIN_12|GPIO_PIN_13|GPIO_PIN_14|GPIO_PIN_15
                          |GPIO_PIN_3|GPIO_PIN_4|GPIO_PIN_8|GPIO_PIN_9, GPIO_PIN_RESET);
 
  /*Configure GPIO pins : PC13 PC14 PC15 */
  GPIO_InitStruct.Pin = GPIO_PIN_13|GPIO_PIN_14|GPIO_PIN_15;
  GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
  GPIO_InitStruct.Pull = GPIO_NOPULL;
  GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
  HAL_GPIO_Init(GPIOC, &GPIO_InitStruct);
 
  /*Configure GPIO pins : PA0 PA1 PA2 PA3
                           PA4 PA5 PA6 PA7
                           PA8 PA9 PA10 PA11
                           PA12 PA15 */
  GPIO_InitStruct.Pin = GPIO_PIN_0|GPIO_PIN_1|GPIO_PIN_2|GPIO_PIN_3
                          |GPIO_PIN_4|GPIO_PIN_5|GPIO_PIN_6|GPIO_PIN_7
                          |GPIO_PIN_8|GPIO_PIN_9|GPIO_PIN_10|GPIO_PIN_11
                          |GPIO_PIN_12|GPIO_PIN_15;
  GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
  GPIO_InitStruct.Pull = GPIO_NOPULL;
  GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
  HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);
 
  /*Configure GPIO pins : PB0 PB1 PB2 PB10
                           PB12 PB13 PB14 PB15
                           PB3 PB4 PB8 PB9 */
  GPIO_InitStruct.Pin = GPIO_PIN_0|GPIO_PIN_1|GPIO_PIN_2|GPIO_PIN_10
                          |GPIO_PIN_12|GPIO_PIN_13|GPIO_PIN_14|GPIO_PIN_15
                          |GPIO_PIN_3|GPIO_PIN_4|GPIO_PIN_8|GPIO_PIN_9;
  GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
  GPIO_InitStruct.Pull = GPIO_NOPULL;
  GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
  HAL_GPIO_Init(GPIOB, &GPIO_InitStruct);
 
  /*Configure GPIO pin : PB5 */
  GPIO_InitStruct.Pin = GPIO_PIN_5;
  GPIO_InitStruct.Mode = GPIO_MODE_IT_RISING;
  GPIO_InitStruct.Pull = GPIO_NOPULL;
  HAL_GPIO_Init(GPIOB, &GPIO_InitStruct);
 
}
void Error_Handler(void)
{
  __disable_irq();
  while (1)
  {
  }
}
Добавлено через 55 минут
Нашёл ошибку DMA1_Stream6->CR |= DMA_CHANNEL_6; исправил на DMA1_Stream6->CR |= DMA_CHANNEL_1; как в таблице всё равно не хочет заводиться.
0
Programming
Эксперт
39485 / 9562 / 3019
Регистрация: 12.04.2006
Сообщений: 41,671
Блог
08.10.2025, 13:46
Ответы с готовыми решениями:

ADC->DMA->SDIO (или NAND через FSMC) без остановки в обработчике прерываний DMA на STM32F407VG, реально или нет?
Добрый день. Столкнулся с необходимостью писать большой объём данных АЦП с высокой скоростью....

USART2(RX+IDLE+DMA)+USART3(TX DMA)
Принимаю по юсарт2, побайтно, на скрости 115200. Пытаюсь передавать по юсарт3 через DMA, скорость...

STM32F4Discovery - ADC DMA и FSMC DMA
Привет всем. Вынужден опять обратиться за Вашей помощью :) Ситуация такая. 1. Дисплей...

95
62 / 187 / 31
Регистрация: 14.02.2013
Сообщений: 1,715
12.10.2025, 16:03
Студворк — интернет-сервис помощи студентам
Цитата Сообщение от jcxz Посмотреть сообщение
Как такое можно написать, глядя в документацию - не представляю.
В доках даётся лишь порядок работы узлов МК и не пишут как лучше обрабатывать события всё остальное лишь зависит от разума программиста который мало того что должен знать перефирию так ещё и очень хорошо разбираться в электроники.
Цитата Сообщение от jcxz Посмотреть сообщение
Т.е. - если в процессе передачи возникнет ошибка, то ваш код просто повиснет
естественно поэтому далее я подключу целый таймер который будет работать в системе отслеживания работы i2c.
0
 Аватар для COKPOWEHEU
4144 / 2722 / 433
Регистрация: 09.09.2017
Сообщений: 12,056
12.10.2025, 16:31
Цитата Сообщение от VladimirU Посмотреть сообщение
COKPOWEHEU, выходит всё же придётся задействовать таймер
Есть же systick
0
62 / 187 / 31
Регистрация: 14.02.2013
Сообщений: 1,715
12.10.2025, 18:09
Цитата Сообщение от COKPOWEHEU Посмотреть сообщение
Есть же systick
Да есть и в в кубе он активно используется, видимо разработчики максимально хотели облекчеть свои функции не задействовав перефирию. Да вот только вышло это облекчение не очень, вышел наплыв лишнего кода. Не зря придумали ПРЕРЫВАНИЕ.

Добавлено через 1 минуту
Цитата Сообщение от COKPOWEHEU Посмотреть сообщение
Есть же systick
Тогда всё же возникает корректный вопрос, прерывание от таймера с его счётом или systick?

Добавлено через 4 минуты
Да конечно systick является самой независимой процедурой счёта на которую можно операться.

Добавлено через 1 минуту
Прошу прощения за мой Русский язык.
0
333 / 127 / 8
Регистрация: 19.07.2024
Сообщений: 675
12.10.2025, 18:44
Цитата Сообщение от VladimirU Посмотреть сообщение
Тогда всё же возникает корректный вопрос, прерывание от таймера с его счётом или systick?
Для работы STM32F4xx с I2C таймер не нужен. От слова "совсем".
0
 Аватар для COKPOWEHEU
4144 / 2722 / 433
Регистрация: 09.09.2017
Сообщений: 12,056
12.10.2025, 20:03
Цитата Сообщение от VladimirU Посмотреть сообщение
Да вот только вышло это облекчение не очень, вышел наплыв лишнего кода. Не зря придумали ПРЕРЫВАНИЕ.
Прерывание нужно, когда нужна быстрая реакция на какое-то событие. А при отслеживании не зависло ли ведомое I2C устройство точность не нужна вообще. Достаточно проверять не насчитал ли systick примерно столько-то тактов.
Цитата Сообщение от VladimirU Посмотреть сообщение
Да конечно systick является самой независимой процедурой счёта на которую можно операться.
К сожалению, не всегда. Некоторые RTOS его сбрасывают во время своего прерывания. Правда, если влезть в код, это можно поправить.
0
333 / 127 / 8
Регистрация: 19.07.2024
Сообщений: 675
12.10.2025, 20:24
Цитата Сообщение от COKPOWEHEU Посмотреть сообщение
А при отслеживании не зависло ли ведомое I2C устройство точность не нужна вообще. Достаточно проверять не насчитал ли systick примерно столько-то тактов.
Зачем? И что такое "зависло ли ведомое I2C устройство" и как при этом поможет таймер МК?
Если что: В теме идёт речь о случае когда микроконтроллер является мастером по I2C. Если вам это о чём-то говорит.
Таймер не нужен для работы I2C в режиме мастера. Никакой - ни по прерываниям ни поллингом.
0
Windows must die
610 / 883 / 104
Регистрация: 23.11.2021
Сообщений: 5,166
Записей в блоге: 19
12.10.2025, 20:58
Таймер нужен - проверить таймаут. И SysTick в этом отлично помогает: запоминаешь время перехода в новое состояние, да во время поллинга проверяешь. Если слишком натикало, значит, таймаут - какая-то фигня случилась (скажем, датчик слишком "задумался": выдает busy, но при этом ничего не происходит - надо сбросить). Но отдельный для этого таймер заводить, ясное дело, не нужно.
Кстати, мне такие дикие датчики попадались, которые запросто завешивали SCL или SDA и всю шину клали нафиг. И на стандартную посылку шестерки на нулевой адрес не реагировали по этой самой причине - шину-то использовать невозможно! Помогало только отключение/включение питания. Вот для подобных "засранцев" я и ставлю иной раз дополнительный p-канальный мосфет, чтобы им питание при необходимости отключить можно было.
Ну, а при работе DMA вообще просто: в прерывании по окончании передачи или приема выставляем флаг - вуаля, наш КА понимает, что все прошло успешно, и можно в следующее состояние переходить.
Плохо только, что для того, чтобы пнуть DMA, все равно сначала руками нужно послать адрес. А если передаешь/принимаешь больше 255 байт, то еще и эдакий КА внутрь прерывания DMA нужно засунуть, чтобы выставлять CONT или STOP и подпихивать очередной кусок буфера.
// я, кстати, очень надеялся, что DMA инкрементирует адрес, поэтому новый кусок считать не нужно будет. Ан нет, похоже, рабочий указатель на текущую порцию данных у него где-то внутри спрятан.
0
 Аватар для COKPOWEHEU
4144 / 2722 / 433
Регистрация: 09.09.2017
Сообщений: 12,056
12.10.2025, 22:58
Цитата Сообщение от Eddy_Em Посмотреть сообщение
Плохо только, что для того, чтобы пнуть DMA, все равно сначала руками нужно послать адрес.
Да, это неприятно. Но, возможно, это следствие максимально простого DMA и I2C. Ни тот, ни другой не делают ничего сверх минимально необходимого. В результате, по-хорошему, конечный автомат должен учитывать и состояние I2C, и DMA, и таймера. В общем-то, мне это было делать лень, поэтому на DMA я плюнул. И если использовать I2C по его прямому предназначению - читать и писать отдельные регистры - то DMA особо и не поможет.
Если же пытаться, скажем, передавать через него картинки, то да, DMA прикрутить стоит.
Цитата Сообщение от Eddy_Em Посмотреть сообщение
я, кстати, очень надеялся, что DMA инкрементирует адрес, поэтому новый кусок считать не нужно будет.
Вот эту фразу не понял. Инкремент адреса на слейве это ведь задача самого слейва. Некоторые умеют, некоторые нет.
0
Windows must die
610 / 883 / 104
Регистрация: 23.11.2021
Сообщений: 5,166
Записей в блоге: 19
13.10.2025, 01:05
Цитата Сообщение от COKPOWEHEU Посмотреть сообщение
Вот эту фразу не понял
Я имею в виду указатель на текущие данные, которые будут отправляться через DMA. То бишь, что DMA "самостоятельно" инкрементирует CMAR. А вот нет. И приходится вот такую дичь в прерывании писать (в данном случае - Rx only, т.к. я читаю данные с ИК-болометра 32×24 пикселя, 16-битными регистрами):
C
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
static void I2C_isr(int rx){
    uint32_t isr = DMA1->ISR;
    DMA_Channel_TypeDef *ch = (rx) ? DMA1_Channel7 : DMA1_Channel6;
    ch->CCR &= ~DMA_CCR_EN; // clear enable for further settings
    if(isr & (DMA_ISR_TEIF6 | DMA_ISR_TEIF7)){
        goterr = 1; goto ret;
    }
    if(dma_remain){ // receive/send next portion
        uint16_t len = (dma_remain > 255) ? 255 : dma_remain;
        ch->CNDTR = len;
        if(rx){
            if(!i2c_startr(dmaaddr, dma_remain, 0)){
                goterr = 1; goto ret;
            }
            ch->CMAR += 255;
        }
        dma_remain -= len;
        ch->CCR |= DMA_CCR_EN;
        DMA1->IFCR = DMA_IFCR_CTCIF6 | DMA_IFCR_CTCIF7;
        return;
    }else if(rx) i2c_got_DMA = 1; // last transfer was Rx and all data read
ret:
    ch->CCR = 0;
    I2Cbusy = 0;
    DMA1->IFCR = 0x0ff00000; // clear all flags for channel6/7
}
По-хорошему, нельзя в прерываниях такой длинный код писать. А приходится.
Аналогично с USB: уж замутили, так замутили. До такой степени запутанно, что не придумали, как при помощи DMA осуществить на USB прием/передачу. И приходится все это в прерываниях дергать…

А вот с экранчиками я по I2C не работал, поэтому надобности отсылать большие объемы данных не возникало (вот и не на чем проверить, у меня и экранчиков-то с I2C нет: все или SPI, или на параллельной шине). SPI, кстати, и пошустрей: ведь нет нужды в подтягивающих резисторах, поэтому и скорость не ограничена парой Мбод. I2C у меня на коротких проводочках максимум на 2Мбод (точней - около 1.9) работал на STM32F303. Пытался еще шустрей (около 4Мбод), с подтяжками на 470 Ом, но все равно сигнал получается страшный. И связь сильно ненадежная. С настройкой скоростей мне помог осциллограф: даже в документации написано, что тайминги на фронты не очень-то стабильные от железки к железке, поэтому нужно экспериментировать. А благодаря gdb это можно сделать, не мучая МК частыми перепрошивками: тормознул, поменял настройки I2C, и дальше проверяй себе, какие будут профили и скорости.

У разных серий STM32 достаточно сильно различается подход к I2C. Самая жесть - у STM32F103. Надо бы поковыряться с G и H сериями: пощупать, как оно там.
0
 Аватар для COKPOWEHEU
4144 / 2722 / 433
Регистрация: 09.09.2017
Сообщений: 12,056
13.10.2025, 10:06
Цитата Сообщение от Eddy_Em Посмотреть сообщение
То бишь, что DMA "самостоятельно" инкрементирует CMAR. А вот нет.
Все равно не понимаю. Как будто у вас DMA менять адрес-то умеет, но ограничено 1 байтом. Есть тестовый код под f103?
Ну и хардкод каналов это в любом случае неудачная идея.
Цитата Сообщение от Eddy_Em Посмотреть сообщение
Аналогично с USB: уж замутили, так замутили.
Ну это в F1 и подобных они какой-то наркоманией занимались. Я сейчас смотрю ch32v3. Похоже, что там для передачи указывается именно полный буфер в обычном ОЗУ, без деления на размер точки. Правда, в примерах от производителя в прерывании все равно творится что-то странное.
Цитата Сообщение от Eddy_Em Посмотреть сообщение
поэтому и скорость не ограничена парой Мбод.
А ведь стандарт указывает еще более жесткое ограничение: 100 / 400 кГц.
Цитата Сообщение от Eddy_Em Посмотреть сообщение
с подтяжками на 470 Ом, но все равно сигнал получается страшный.
Осталось источники тока вместо резисторов поставить...
0
1505 / 522 / 75
Регистрация: 22.09.2023
Сообщений: 1,651
13.10.2025, 14:51
Цитата Сообщение от COKPOWEHEU Посмотреть сообщение
А ведь стандарт указывает еще более жесткое ограничение: 100 / 400 кГц.
Ваши данные несколько устарели:
0
333 / 127 / 8
Регистрация: 19.07.2024
Сообщений: 675
13.10.2025, 15:07
Цитата Сообщение от Dushevny Посмотреть сообщение
Ваши данные несколько устарели:
Ваши - тоже. Уже более чем на 10 лет!
Data on the I2C-bus can be transferred at rates of up to 100 kbit/s in standard mode, up
to 400 kbit/s in fast mode and up to 3.4 Mbit/s in high-speed mode.
Выдержка из User Manual на TC29x датированного 2014г.
0
1505 / 522 / 75
Регистрация: 22.09.2023
Сообщений: 1,651
13.10.2025, 15:20
Цитата Сообщение от jcxz Посмотреть сообщение
Уже более чем на 10 лет!
Мой документ датирован 2021 годом, так что осетра-то урежьте

Добавлено через 4 минуты
Почитал мельком, HS-режим требует поддержки со стороны железа, простым разгоном не получается:
In order to shorten signal rise time HS mode master devices have a combination of an open-drain pull-down and current-source pull-up circuit on the SCL output.
Добавлено через 4 минуты
Поискал на сайте Филипса - мой документ является последней опубликованной версией стандарта I2С. Режим Fast mode+ был добавлен в стандарт в середине 2007 г. А режим HS - какое-то нестандартное расширение
0
333 / 127 / 8
Регистрация: 19.07.2024
Сообщений: 675
13.10.2025, 15:25
Цитата Сообщение от Dushevny Посмотреть сообщение
Почитал мельком, HS-режим требует поддержки со стороны железа, простым разгоном не получается
И что? 1Mb/s также требует поддержки со стороны железа. Никакой разницы.
И причём тут какой-то "разгон"? Значение указано в официальном документе, значит поддерживается штатно, без "разгонов".

Цитата Сообщение от Dushevny Посмотреть сообщение
Мой документ датирован 2021 годом
Вот именно - к дате выхода вашего документа данные по макс. скорости I2C уже не менее 7 лет как устарели.

Добавлено через 1 минуту
Цитата Сообщение от Dushevny Посмотреть сообщение
Поискал на сайте Филипса
Филипс у нас - единственный производитель полупроводников на Земле???
0
1505 / 522 / 75
Регистрация: 22.09.2023
Сообщений: 1,651
13.10.2025, 15:28
Цитата Сообщение от jcxz Посмотреть сообщение
к дате выхода вашего документа данные по макс. скорости I2C уже не менее 7 лет как устарели
Филипс является автором и правообладателем I2C. Поэтому то, что Филипс называет спецификацией интерфейса является (сюрприз!) спецификацией интерфейса. А все, что кто-то еще навешал поверх этого - является нестандартным расширением. А речь шла о стандарте.
Цитата Сообщение от jcxz Посмотреть сообщение
И что? 1Mb/s также требует поддержки со стороны железа. Никакой разницы.
Разница есть. Эдди разгоняет режим FM+ сверх оговоренного спецификацией.
0
333 / 127 / 8
Регистрация: 19.07.2024
Сообщений: 675
13.10.2025, 15:35
Цитата Сообщение от Dushevny Посмотреть сообщение
А речь шла о стандарте.
Так и приведите ссылку на стандарт. То что вы привели - ссылка на I2C в одном конкретном МК. В других МК (даже от того же NXP) - данные будут уже другие.

Цитата Сообщение от Dushevny Посмотреть сообщение
Филипс является автором и правообладателем I2C.
И где тот Филипс? Его давно уже нет.

PS: Некий неандерталец является автором и правообладателем колеса. И как вы думаете он бы отнёсся к тем колёсам, на которых вы сейчас гоняете? Сказал бы что это неправильные колёса? И стукнул каменным топором по башке?
Ведь его колесо было каменным и не ездило столь быстро как нонешние.
0
1505 / 522 / 75
Регистрация: 22.09.2023
Сообщений: 1,651
13.10.2025, 19:15
Цитата Сообщение от jcxz Посмотреть сообщение
Так и приведите ссылку на стандарт.
Читайте по губам:

Это не описание МК, это спецификация (=стандарт) на шину. Погуглить "UM10204" потрудитесь сами.
Цитата Сообщение от jcxz Посмотреть сообщение
И где тот Филипс? Его давно уже нет.
Никуда он не делся. После слияния с Моторолой сменил название на NXP.

Цитата Сообщение от jcxz Посмотреть сообщение
PS:
Да я прекрасно знаю, что вы никогда не признаете свою неправоту. Засим откланиваюсь.
0
1505 / 522 / 75
Регистрация: 22.09.2023
Сообщений: 1,651
13.10.2025, 19:31
Цитата Сообщение от Dushevny Посмотреть сообщение
После слияния с Моторолой сменил название на NXP.
Знаю, что сейчас придеретесь: в 2006 подразделение полупроводников было отделено от Philips и названо NXP. Потом с ним слилась Моторола. Потом отпочковалась Nexperia, которую на днях голландцы отжали у китайцев. А сам оставшийся Philips жив до сих пор.
0
Эксперт JavaЭксперт по электроникеЭксперт .NET
 Аватар для wizard41
3460 / 2781 / 575
Регистрация: 04.09.2018
Сообщений: 8,743
Записей в блоге: 3
13.10.2025, 19:40
Дополню: I2C (TWI) действительно был придуман Филлипсом, запатентован и все такое. Его использование предполагало плату, но все на это дружно забили и юзают кто как хотят. Причем, не редко со своими "доработками"..
Отсылаться к стандарту напрямую вряд ли стоит. Что конкретно и как реализовано в СТМ - вопрос..
0
Windows must die
610 / 883 / 104
Регистрация: 23.11.2021
Сообщений: 5,166
Записей в блоге: 19
13.10.2025, 19:47
Цитата Сообщение от wizard41 Посмотреть сообщение
"доработками"
Есть такое. Встречал датчики, которые "как бы на I2C", но адрес передавать не надо... Типа point2point соединение. А т.к. стандартный I2C такое не умеет, приходится эти датчики отправлять "в дальний ящик", откуда они перекочевывают со временем в гараж, а из гаража - уже на свалку ☺
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
inter-admin
Эксперт
29715 / 6470 / 2152
Регистрация: 06.03.2009
Сообщений: 28,500
Блог
13.10.2025, 19:47

stm32f407+ADC+DMA. Проблема с DMA
Доброго дня! Новичок в stm, первый проект, начальные наброски, не понимаю,почему не работает эта...

STM32F4 I2C DMA CMSIS
Парни может кто писал под f4 скиньте рабочий код если не жалко

stm32 SPI+DMA или I2C внешнее АЦП
Есть у меня задача контролировать 3фазы линейно .Внутренний ацп не подходит наверное.Какое ацп...

передача данных USART + DMA и непонятные иероглифы
Всем привет! Есть проблема с передачей данных с МК на ПК через USORT + DMA. Ранее все работало...

stm32f4 SPI приём и передача данных по DMA
Посмотрел я примеры по SPI .Как правильно осуществить передачу данных и приём ?Особенно путаница с...


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

Или воспользуйтесь поиском по форуму:
60
Ответ Создать тему
Новые блоги и статьи
Из невошедшего на форум (диалог с ИИ-гугла)
zorxor 29.07.2026
А вот, что интересно, сказал мне ИИ-гугла: Этот текст — эмоциональный пост пользователя под ником zorxor на интернет-форуме (вероятно, посвященном мистике, непознанному или альтернативной науке). . . .
Был праздник вчера, а я и не знал.
kumehtar 28.07.2026
27. 07. 2026г. Intel Core 2 Duo исполнилось 20 лет Новости компьютерного мира и их обсуждение (4) Салют, шампанское, овации! :drink:
Нейтральные знания, чистый код - бла-бла-бла-бла, на самом деле кликбейт и самореклама, плагиат, и вот почему
Hrethgir 27.07.2026
То-есть отклонение такой публикации говорит само за себя, и пусть только возьмут на вооружение после отклонения публикации - это будет чистейшим актом плагиата. Отклонял Хабр. Дословно, отклонённая. . .
тв 16 бой ии
anaschu 27.07.2026
Великий Перелом ИИ: Как уравнения ОДУ Radau дожали цензурные фильтры Алисы Фиксируем в мемофонде Теории Всего беспрецедентный факт в истории ИИ-зондирования. В затяжном многораундовом. . .
мв 15. непроверенное, возможно, глюк
anaschu 27.07.2026
НАУЧНО-АНАЛИТИЧЕСКИЙ ОТЧЕТ. РАЗДЕЛ 1. 1: «НАУКА» (РАСШИРЕННАЯ СТЕХИОМЕТРИЧЕСКАЯ И ГЕНЕТИЧЕСКАЯ ВЕРСИЯ)Тема: Теоретическое обоснование инвариантности 19-мерного тензорного ядра непрерывных ОДУ и. . .
Очистка реквизитов и табличных частей документа при копировании (вариант 2)
Maks 26.07.2026
Алгоритм из решения ниже разработан на примере нетипового документа "ЗаявкаНаРаботу", разработанного в КА2. Задача: Заменить алгоритм запрета копирования документов для сотрудников с ролью "Стажер",. . .
Доктрина интенционального знания - Доктрина для портала "Срез".
Hrethgir 25.07.2026
Может найдётся кто захочет оценить доктрину. . . Написания правил участия для меня роскошь, требующая лимита времени, поэтому все сообщения не прошедшие модерацию будут видны только участникам портала,. . .
сукцессия 44. Решил подать на припринт в межународные сервисы препринтов. Но нужно одобрение от ученых
anaschu 25.07.2026
Английский вариант. Пока кто то не одобрит мою личность, мне не получиться это опубликовать на препринте. Но заявку на публикацию статьи я сегодня подам.
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru