|
stm32 SPI, коннект между двумя чипами от st по spi |
|
|
|
Apr 21 2018, 07:13
|
Участник

Группа: Участник
Сообщений: 44
Регистрация: 26-05-17
Пользователь №: 97 309

|
Есть две борды борда 1(Б1) (stm32f407vgt) и борда 2(Б2) (stm32f303vet), между которыми необходимо обеспечить связь по SPI, вот настройка SPI для Б1 и Б2: Б1 (Slave): CODE /* SPI2 De Initialization */ SPI_I2S_DeInit(SPI2); /* SPI2 configuration */ SPI_InitTypeDef SPI2_InitStructure; SPI2_InitStructure.SPI_Mode = SPI_Mode_Slave; SPI2_InitStructure.SPI_Direction = SPI_Direction_2Lines_FullDuplex; SPI2_InitStructure.SPI_DataSize = SPI_DataSize_16b; SPI2_InitStructure.SPI_CPOL = SPI_CPOL_Low; SPI2_InitStructure.SPI_CPHA = SPI_CPHA_1Edge; SPI2_InitStructure.SPI_NSS = SPI_NSS_Soft; SPI2_InitStructure.SPI_FirstBit = SPI_FirstBit_MSB; SPI2_InitStructure.SPI_CRCPolynomial = 7; SPI2_InitStructure.SPI_BaudRatePrescaler = SPI_BaudRatePrescaler_4; SPI_Init(SPI2, &SPI2_InitStructure); /* FIFO threshold */ SPI_RxFIFOThresholdConfig(SPI2, SPI_RxFIFOThreshold_HF); /* Interrupt handler priority */ NVIC_InitTypeDef NVIC_SPI2_InitStructure; NVIC_SPI2_InitStructure.NVIC_IRQChannel = SPI2_IRQn; NVIC_SPI2_InitStructure.NVIC_IRQChannelPreemptionPriority = 0; NVIC_SPI2_InitStructure.NVIC_IRQChannelSubPriority = 0; NVIC_SPI2_InitStructure.NVIC_IRQChannelCmd = ENABLE; NVIC_Init(&NVIC_SPI2_InitStructure); /* RXNE interrupt enable */ NVIC_EnableIRQ(SPI2_IRQn); SPI_I2S_ITConfig(SPI2, SPI_I2S_IT_RXNE, ENABLE);
/* Enable DMA Tx requests */ SPI_I2S_DMACmd(SPI2, SPI_I2S_DMAReq_Tx, ENABLE);
/* Enable SPI2 */ SPI_Cmd(SPI2, ENABLE); Б2(Master): CODE /*SPI3 configuration structure*/ SPI_InitTypeDef SPI3_InitStructure; /*Default parameters*/ SPI_StructInit(&SPI3_InitStructure); /*Configure SPI3*/ SPI3_InitStructure.SPI_Direction = SPI_Direction_2Lines_FullDuplex; SPI3_InitStructure.SPI_Mode = SPI_Mode_Master; SPI3_InitStructure.SPI_DataSize = SPI_DataSize_16b; SPI3_InitStructure.SPI_CPOL = SPI_CPOL_Low; SPI3_InitStructure.SPI_CPHA = SPI_CPHA_1Edge; SPI3_InitStructure.SPI_NSS = SPI_NSS_Soft; SPI3_InitStructure.SPI_BaudRatePrescaler = SPI_BaudRatePrescaler_64; SPI3_InitStructure.SPI_FirstBit = SPI_FirstBit_MSB; SPI3_InitStructure.SPI_CRCPolynomial = 7; SPI_Init(SPI3, &SPI3_InitStructure); /*Enable SPI3*/ SPI_Cmd(SPI3, ENABLE); между ними необходимо передавать данные нижеописанным образом: 1. Б2, который мастер, шлёт 16-битный флаг SPI_FLAG (0x0001); 2. Срабатывает прерывание по RXNE в Б1, Б1 читает принятую посылку, сравнивает с нужным значением и включает DMA_Stream, который запускает передачу данных в Б2 Код void SPI2_IRQHandler() { SPI_FLAG = SPI_I2S_ReceiveData16(SPI2); if(SPI_FLAG == 0x0001) { DMA_Cmd(DMA1_Channel5, ENABLE); } } Частота на шине APB1, где находится SPI3 Мастера 32MГц, с baudrateprescaler = 64 частота обмена 500Кбит/c . Теперь о проблемах, SPI_FLAG слэйвом я принимаю, а вот данные отправить ни как не получается, только если напрямую в коде где-то написать SPI_I2S_SendData, т.е. из прерывания я не могу отправить данные даже таким способом. Может я неправильно понимаю работу SPI? Подскажите пожалуйста в чём может быть проблема. Лично я грешу на софтовый NSS, я так понимаю при отправке данных слэйвом мастеру, мастер не генерит SCK, может ли помочь решить проблему использование хардварного NSS? Спасибо
Сообщение отредактировал IgorKossak - Apr 21 2018, 18:52
Причина редактирования: [codebox] для длинного кода, [code] - для короткого!
|
|
|
|
|
Apr 21 2018, 09:19
|

Гуру
     
Группа: Модераторы
Сообщений: 8 455
Регистрация: 15-05-06
Из: Рига, Латвия
Пользователь №: 17 095

|
QUOTE (Connor @ Apr 21 2018, 09:13)  я так понимаю при отправке данных слэйвом мастеру, мастер не генерит SCK, может ли помочь решить проблему использование хардварного NSS? Нет, не поможет. Чтобы что-то принять, ведущий должен что-то послать. Ведомый эти данные может игнорировать, а вот генерируемые этой посылкой такты позволяют ведомому передать в это время свои данные. То есть ведущий должен послать команду-флаг и следом столько байтов мусора, сколько данных хочет принять.
--------------------
На любой вопрос даю любой ответ"Write code that is guaranteed to work, not code that doesn’t seem to break" ( C++ FAQ)
|
|
|
|
|
Apr 21 2018, 10:06
|
Участник

Группа: Участник
Сообщений: 44
Регистрация: 26-05-17
Пользователь №: 97 309

|
а как это можно реализовать с помощью DMA? По DMA отравплять и по DMA получать?
|
|
|
|
|
Apr 21 2018, 10:22
|

Гуру
     
Группа: Модераторы
Сообщений: 8 455
Регистрация: 15-05-06
Из: Рига, Латвия
Пользователь №: 17 095

|
QUOTE (Connor @ Apr 21 2018, 12:06)  а как это можно реализовать с помощью DMA? Как и любую другую пересылку с использованием ПДП. QUOTE (Connor @ Apr 21 2018, 12:06)  По DMA отравплять и по DMA получать? Почему бы и да?
--------------------
На любой вопрос даю любой ответ"Write code that is guaranteed to work, not code that doesn’t seem to break" ( C++ FAQ)
|
|
|
|
|
Apr 21 2018, 10:54
|
Участник

Группа: Участник
Сообщений: 44
Регистрация: 26-05-17
Пользователь №: 97 309

|
Цитата(Сергей Борщ @ Apr 21 2018, 04:22)  Как и любую другую пересылку с использованием ПДП. Почему бы и да? Спасибо)
Сообщение отредактировал Connor - Apr 21 2018, 10:55
|
|
|
|
|
Apr 21 2018, 12:14
|
Участник

Группа: Участник
Сообщений: 44
Регистрация: 26-05-17
Пользователь №: 97 309

|
А ещё такой вопрос, есть ли необходимость софтового управления NSS сигналом, то есть дёргать gpio перед отправкой посылки? Я так понимаю "софтовость" заключается в том, что мы можем дёргать просто не подключенную ногу, вместо хардварной NSS? Просто я до этого ничего с NSS не делал, в смысле для этой задачи его не трогал
Сообщение отредактировал Connor - Apr 21 2018, 12:24
|
|
|
|
|
Apr 23 2018, 05:38
|
Участник

Группа: Участник
Сообщений: 44
Регистрация: 26-05-17
Пользователь №: 97 309

|
Цитата(k155la3 @ Apr 21 2018, 08:02)  Я предлагаю Вам для старта упростить задачу. Проверьте работу мастера без слейва на корректность передачи "по кольцу" в заданном режиме (с DMA или без него). 1. соедините MISO-MOSI. 2. передайте "константно-инкриментный" массив. 3. проверьте соответствие принятогго переданному. Если этот "номер" в требуемом режиме настройки прошел, можно подключать "клиента-слейва". Как вариант - чтобы не отлаживать одновременно клиент-сервера на 2 платах - можете реализовать такое кольцо на двух SPI в рамках вашей Б1 (Slave). кольцевой обмен данными я реализовывал на мастере, всё было отлично, но вот со слэйвом были проблемы, вопрос, который до сих пор "меня мучает" это возможно ли из прерывания как-то отправить сообщение от слэйва мастеру
|
|
|
|
|
Apr 23 2018, 07:33
|

Гуру
     
Группа: Модераторы
Сообщений: 8 455
Регистрация: 15-05-06
Из: Рига, Латвия
Пользователь №: 17 095

|
QUOTE (Connor @ Apr 23 2018, 07:38)  вопрос, который до сих пор "меня мучает" это возможно ли из прерывания как-то отправить сообщение от слэйва мастеру Ведомый не может ничего отправить пока ведущий это что-то не захочет забрать. В прерывании вы можете положить данные в регистр отправки, зарядить ПДП на отправку, но сама отправка произойдет только тогда, когда ведущий будет посылать данные, и в это же время в обратную сторону будет происходить отгрузка данных ведомым. Если ведомый ничего не зарядил на отправку - ведущий будет постоянно получать последние данные, лежащие в регистре отправки ведомого.
--------------------
На любой вопрос даю любой ответ"Write code that is guaranteed to work, not code that doesn’t seem to break" ( C++ FAQ)
|
|
|
|
|
Apr 23 2018, 07:47
|
Участник

Группа: Участник
Сообщений: 44
Регистрация: 26-05-17
Пользователь №: 97 309

|
Цитата(Сергей Борщ @ Apr 23 2018, 01:33)  Ведомый не может ничего отправить пока ведущий это что-то не захочет забрать. В прерывании вы можете положить данные в регистр отправки, зарядить ПДП на отправку, но сама отправка произойдет только тогда, когда ведущий будет посылать данные, и в это же время в обратную сторону будет происходить отгрузка данных ведомым. Если ведомый ничего не зарядил на отправку - ведущий будет постоянно получать последние данные, лежащие в регистре отправки ведомого. Я это осознал, другой вопрос заключается в том, что на мастере необходимо организовывать задержку перед отправкой "мусора", например, чтобы принять данные от слэйва(в котором включается дма в прерывании)?
|
|
|
|
|
Apr 23 2018, 11:03
|
Профессионал
    
Группа: Свой
Сообщений: 1 719
Регистрация: 13-09-05
Из: Novosibirsk
Пользователь №: 8 528

|
Цитата(Connor @ Apr 23 2018, 12:38)  кольцевой обмен данными я реализовывал на мастере, всё было отлично, но вот со слэйвом были проблемы, вопрос, который до сих пор "меня мучает" это возможно ли из прерывания как-то отправить сообщение от слэйва мастеру Один бит передать можно. У слэйва старший (или младший) бит из DR выдается на MISO сразу (при соответствующих уровнях на NSS и SCK) и со стороны мастера его можно прочитать c ноги, мимо SPI.
--------------------
Russia est omnis divisa in partes octo.
|
|
|
|
|
Apr 23 2018, 13:46
|
Участник

Группа: Участник
Сообщений: 44
Регистрация: 26-05-17
Пользователь №: 97 309

|
Получилось у меня реализовать обмен по дма между мастером и слэйвом с помощью прерывания, только у меня это танцы с конём получились, после принятия флага на чтение, приходится отключать прерывания по RXNE для слейва, чтобы слейв не ловил его, когда мастер начнёт посылать "мусор": Код void SPI2_IRQHandler() { SPI_FLAG = SPI_I2S_ReceiveData16(SPI2);
/* Disable RXNE interrupt*/ SPI_I2S_ITConfig(SPI2, SPI_I2S_IT_RXNE, DISABLE);
if(SPI_FLAG == 0x0001) { DMA_Cmd(DMA1_Channel5, ENABLE); } } в общем итоге "мусор" для принятия данных от слейва мастером мне приходится посылать только через >= 1 cек, то есть между отправкой флага и отправкой "мусора" от мастера проходит секунда, что меня совсем не радует, в противном случае слейв не успевает выставить в регистр DR данные и мастер читает нули Извиняюсь, я обманул сам себя а в итоге и вас, задержка получилась около 300мс, что к слову тоже многовато конечно(
Сообщение отредактировал Connor - Apr 23 2018, 14:03
|
|
|
|
|
Apr 23 2018, 14:45
|

Частый гость
 
Группа: Участник
Сообщений: 101
Регистрация: 2-05-15
Из: Россия, Омск
Пользователь №: 86 474

|
Таки странно. У меня в проекте было настроено так: Мастер чинает данные по DMA с ведомого. SPI настроен на работу с DMA. Размер посылки фиксирован на 8 байт. Ведомый так же настраивает SPI на работу с DMA (F030), но в режиме Slave - Ведомый. Сразу же настраиваются все указатели и режим кольцевого буфера (те же 8 байт в DMAxx->CNTDR). После этого в принципе забываю про обращение к настройкам и или данным. Буфер заполняется новыми данными, если пин /CS поднят (1). Если передача активна (/CS = 0) - контроллер уходит в ожидание на несколько милисекунд (фактически, уходит в __WFI() до прерывания от DMA о окончании передачи). После этого - забрасывает новые данные, если таковые есть (банально копирует данные из актуального буфера в буфер передачи) и они будут отправлены в следующем цикле. Пауз нет. Прерывания по смене состояния пина - нет. Обращения к памяти - только от DMA контроллера. Код // STM32F040 - Slave int main(void) { RCC->APB2RSTR = 0x00075A40; // Reset almost all on APB2 RCC->APB2RSTR = 0; RCC->APB1RSTR = 0x10FE4932; // Reset all on APB1 RCC->APB1RSTR = 0; RCC->AHBENR = 0x00020001; // GPIOA Enable, DMA Enable GPIOA->PUPDR |= 0x00000100; // GPIOA[4] PullUp. RCC->APB2ENR = RCC_APB2ENR_SPI1EN; // SPI1 Enable GPIOA->MODER = 0x6555AA54; // GPIOA.MODER = [OAOO OOOO AAAA OOOI] GPIOA->AFR[0] = 0; // GPIOA[4-7].Alternate -> SPI1 SPI1->CR1 = 0; SPI1->CR2 = 0742; // 8 bit, DMA-TX enabled SPI1->CR1 = SPI_CR1_SPE; // Channel enabled, slave. SPI1->CR2 = 0742; // 8 bit, DMA-TX enabled DMA1_Channel3->CPAR = (uint32_t)&(SPI1->DR); DMA1_Channel3->CMAR = (uint32_t)&(ButtonsPressed[0]); DMA1_Channel3->CCR = (DMA_CCR_MINC | DMA_CCR_CIRC | DMA_CCR_DIR | DMA_CCR_TCIE); DMA1_Channel3->CNDTR = 8; DMA1_Channel3->CCR |= DMA_CCR_EN; NVIC_SetPriority(DMA1_Channel2_3_IRQn, 1); NVIC_EnableIRQ(DMA1_Channel2_3_IRQn); NVIC_SetPriority(SysTick_IRQn, 0x00); // Настраиваем SYSTick. Наивысший приоритет. NVIC_EnableIRQ(SysTick_IRQn); // Включаем прерывание SYSTick. NVIC_SetPriority(SPI1_IRQn, 0x01); // Приоритет SPI1 ниже чем SysTick NVIC_EnableIRQ(SPI1_IRQn); // Включаем. while(1) { __WFI(); }; };
void SPI1_IRQHandler(void) { if (SPI1->SR & SPI_SR_MODF) { SPI1->CR1 = SPI1->CR1; // Вы таки не поверите, но это очищает некоторые флаги ошибки }; while(SPI1->SR & 0x0600) { (void)(SPI1->DR); // Если есть данные - читаем их. Они нам не нужны :( }; }; void DMA1_Channel2_3_IRQHandler(void) { if (DMA1->ISR & DMA_ISR_TCIF3) { DMA1->IFCR = DMA_IFCR_CTEIF3; // Очищаем флаг DMA1_Channel3->CCR &= ~DMA_CCR_EN; // Отключаем канал DMA1_Channel3->CNDTR = 8; // Снова вводим 8 байт на отправку DMA1_Channel3->CCR |= DMA_CCR_EN; // Переводим канал в состояние готовности }; if (DMA1->ISR & DMA_ISR_GIF3) { DMA1->IFCR = DMA_IFCR_CGIF3; // Очищаем флаг }; }; upd: Кстати, я слегка ошибся. Мастер читает НЕ в режиме DMA. Он просто читает Код while (hdr < 2) { // Ищем заголовок сообщения (если был сбой синхронизации). Теоретически должен сразу ловить заголовок, а сбой может быть только при первой передаче (или неподлюченом ведомом). for (i=0;i<16;i++) { GPIOE->BSRR = GPIO_BSRR_BS_11; // Deselect Keyboadr on SPI4 GPIOE->BSRR = GPIO_BSRR_BR_11; // Select Keyboadr on SPI4 SPI4->CR1 &= ~SPI_CR1_SPE; // Disable SPI4 and deselect slave SPI4->CR1 |= SPI_CR1_SPE; // Enable SPI4 and select slave SPI4->DR = 0xFF; // dummy while (!(SPI4->SR & SPI_SR_RXNE)); // Delay until read/write operation v = SPI4->DR; if (v == 0xAA) { hdr = 1; break; }; }; SPI4->DR = 0xFF; // dummy while (!(SPI4->SR & SPI_SR_RXNE)); // Delay until read/write operation v = SPI4->DR; if (v == 0x55) { hdr++; } else { hdr = 0; }; }; // Считываем текущее состояние for (i=0;i<6;i++) { SPI4->DR = 0xFF; // dummy while (!(SPI4->SR & SPI_SR_RXNE)); // Delay until read/write operation v = SPI4->DR; DataBuff[i+2] = v; }; OffTop: Привык, что SPOILER сворачивает текст.
Сообщение отредактировал AlanDrakes - Apr 23 2018, 14:59
|
|
|
|
|
Apr 23 2018, 14:58
|
Частый гость
 
Группа: Участник
Сообщений: 182
Регистрация: 16-10-15
Пользователь №: 88 894

|
Неужели так важна нулевая задержка между сообщениями? По сути, если не гоняться за минимальной задержкой - она сама по себе уменьшится, как-бы глупо это не звучало. Просто не нужно вот так кровь из носу отдавать или принимать сообщения, всё гораздо проще. Два кольцевых буфера на каждой стороне. И по два указателя голова/хвост. На стороне мастера: буфер на передачу с разрешением записи в него, указатель головы для него с разрешением записи, указатель хвоста для буфера приёма - с разрешением записи, сам буфер приёма - только чтение, хвост буфера передачи - только чтение, голова буфера приёма - только чтение. На стороне слейва такая-же структура, с небольшими изменениями. А теперь запускаем мастер через таймер, с выхлопом на ногу ce, на максимально допустимой скорости, и просто пользуемся кольцевыми буферами - что может быть проще?
Ну да, кольцевые буферы будут постоянно перезаписываться и обновляться. Но при сохранении целостности алгоритма - изменения будут только в свободной области. То-есть сначала проверка возможности записи, потом обновление инфы (которая возможно улетит в неполном варианте), потом обновление указателя. Пока приёмная сторона не обновит указатель хвоста - вся эта область считается занятой.
Размеры кольцевых буферов нет смысла делать больше 512 байт, будет только медленнее. При таких условиях задержка получается меньше 1мс.
Ошибки могут возникнуть по вине дма на очень высокой скорости и общем напряге системы. Но такое ещё нужно додуматься нагородить - не каждому под силу.
|
|
|
|
|
Apr 24 2018, 05:59
|
Участник

Группа: Участник
Сообщений: 44
Регистрация: 26-05-17
Пользователь №: 97 309

|
Всем спасибо за ответы, очень помогли  К слову работаю я на довольно низкой частоте 500 кбод/c, но я так понимаю скорость обмена зависит от тактовой частоты мастера, а не слейва?
|
|
|
|
|
Apr 24 2018, 15:21
|
Профессионал
    
Группа: Свой
Сообщений: 1 123
Регистрация: 8-03-09
Из: Днепр
Пользователь №: 45 848

|
Цитата(Connor @ Apr 23 2018, 10:47)  Я это осознал, другой вопрос заключается в том, что на мастере необходимо организовывать задержку перед отправкой "мусора", например, чтобы принять данные от слэйва(в котором включается дма в прерывании)? Используйте стандартные методы. Если слейв должен возвратить "быстрые" данные (например выборка параметра из RAM) то для этого таймауты не нужны и все можно "прокрутить" в одном запрос-ответе. Если же нужна задержка на подготовку данных (например отработка ADC) то это делается "наразвес", несколькими командами 1. Старт АЦП в слейве. 2. опрос регистра статуса слейва готовности данных АЦП. 3. Чтение слейва - данных АЦП.
|
|
|
|
|
Apr 25 2018, 06:02
|
Участник

Группа: Участник
Сообщений: 44
Регистрация: 26-05-17
Пользователь №: 97 309

|
Цитата(AlanDrakes @ Apr 24 2018, 06:58)  Частота обмена ВСЕГДА зависит от частоты мастера. Ведомый кристалл только выставляет соответствующий уровень на пине MISO в момент(ы) смены тактового сигнала SCK. Необходимое условие - частота обмена не более четверти тактовой частоты ведомого чипа. Заметьте, тактовой частоты его периферии. Приведу пример: Мастер: 8МГц. Ведомый: 8МГц. SPI мастера тактируется от внутренней частоты с делителем /2. Результатирующая - 4МГц (внутренняя) и 2МГц (максимальная частота на пине SCK (здесь я имею в виду полную смену тактового сигнала 0-1-0)). SPI ведомого тактируется от внутренней шины с делителем /4. Результатирующая - 2МГц (вроди бы, совпадает с внешней), но максимальная внешняя - 1МГц (тот же полный импульс 0-1-0). Так что, мастер должен дёргать пином минимум в 2 раза медленнее.
500кБод - вполне достаточно 1МГц на шине. На шине ведомого. Ну и мастер должен с этой частотой данные читать. Спасибо, это действительно логично Цитата(k155la3 @ Apr 24 2018, 09:21)  Используйте стандартные методы. Если слейв должен возвратить "быстрые" данные (например выборка параметра из RAM) то для этого таймауты не нужны и все можно "прокрутить" в одном запрос-ответе. Если же нужна задержка на подготовку данных (например отработка ADC) то это делается "наразвес", несколькими командами 1. Старт АЦП в слейве. 2. опрос регистра статуса слейва готовности данных АЦП. 3. Чтение слейва - данных АЦП. В том и проблема, что именно в такой системе как реализовано у меня, АЦП конвертируют данные, DMA записывает их в буфер, который копируется ещё в один (на отправку мастеру), по приходу флага копирование данных в этот буфер прекращается и я отправляю этот буфер мастеру, но как я уже говорил, флаг у меня приходит, срабатывает прерывания, на слэйве запускается DMA по Rx запросу, но чтобы мастер начал читать адекватные данные, когда я начинаю слать слэйву "мусор", нужно выждать что-то около 500мс, что очень плохо, потому что обновлять данные я должен несколько раз в секунду, поэтому решением этой ситуации, как мне подсказали выше, это реализовать просто обмен по DMA без всяких флагов, что я уже сделал и что гораздо проще в итоге
Сообщение отредактировал Connor - Apr 25 2018, 06:15
|
|
|
|
|
Apr 26 2018, 14:40
|
Профессионал
    
Группа: Свой
Сообщений: 1 123
Регистрация: 8-03-09
Из: Днепр
Пользователь №: 45 848

|
Цитата(Connor @ Apr 25 2018, 09:02)  . . . .начинаю слать слэйву "мусор", нужно выждать что-то около 500мс, что очень плохо, . . . Если сделаете аппаратную синхронизацию по времени цикла 1с по всей системе (например от мастера), то проблемы с таймаутами и готовностью-неготовностью можете "разрулить" с использованием таймеров. (не будет необходимости ожидания или контроля отработки для асинхронных событий между мастером и слейвом). Например, мастер на такте 0 таймера дает команду слейву на старт АЦП. Время работі АЦП, скажем, 500 мс. Соответственно, мастер дает команду опроса слейву на 520-ом такте, а слейв заботится о том, чтобы эти данные и все подготовительные операции к 520-му такту у него были закончены.
|
|
|
|
|
Apr 26 2018, 18:18
|
Частый гость
 
Группа: Участник
Сообщений: 182
Регистрация: 16-10-15
Пользователь №: 88 894

|
Цитата(k155la3 @ Apr 26 2018, 20:40)  Если сделаете аппаратную синхронизацию по времени цикла 1с по всей системе (например от мастера), то проблемы с таймаутами и готовностью-неготовностью можете "разрулить" с использованием таймеров. Плавали, знаем... Всё это будет работать до очередной хотелки клиента. После чего придётся переписывать почти весь проект, причём на оба чипа, и почти с нуля. Мне лень убеждать, но посмотреть со стороны всегда приятно. И всё-же: разделяйте уровень железа и программной части, уровень интерфейса и протокола пакетной связи, а также разумно используйте абстракции данных на уровне приложения (алгоритма). При использовании подобного разделения - ваш проект можно масштабировать практически бесконечно (в разумных пределах), а так-же использовать части и даже целые куски в новых проектах - без подгонки напильником. Реальный пример существующего проекта. На ПП несколько чипов, в том числе и слабенький st для работы с сенсорным экраном (не я придумывал). Изначально алгоритм этого чипа был очень простым: получить координаты нажатия экрана, и в режиме слейва отдать главному чипу. Потом ему добавили работы в определении нажатия иконок - протокол связи стал намного сложнее и обрёл множество садового инструментария. Количество изменений в проекте между этими двумя точками - просто безумное. Переписывалось даже то, что имеет лишь косвенное влияние. А потом хозяин проекта узнал что существуют готовые железные контролёры сенсорных экранов, в которых эти функции реализованы изначально. Такого количества подстановок я не встречал даже у индусов. Количество изменений равнялось общему объёму проекта. Поле чего автор проекта решил пристрелить больное бешенством животное, и начать с нового листа. И с первых строчек прострелил себе ногу в трёх местах. Я к тому что уровень адруино не лечится, если уже заразились - то постарайтесь не распространять заразу.
|
|
|
|
|
Apr 27 2018, 08:20
|
Профессионал
    
Группа: Свой
Сообщений: 1 123
Регистрация: 8-03-09
Из: Днепр
Пользователь №: 45 848

|
Цитата(AVI-crak @ Apr 26 2018, 21:18)  Плавали, знаем... Все понятно, кроме одного, зачем процитирован мой пост. Если процитирован, то замечания по сути. ps Используя метод психоанализа я, кажется, понял в чем причина  В терминах и их применении.
|
|
|
|
|
Apr 27 2018, 10:37
|
Частый гость
 
Группа: Участник
Сообщений: 182
Регистрация: 16-10-15
Пользователь №: 88 894

|
Цитата(k155la3 @ Apr 27 2018, 14:20)  Если процитирован, то замечания по сути. Всё очень просто. Использование предсказания поведения внешней системы с использованием таймера - намного уменьшает гибкость общего алгоритма. То-есть если-бы внешней системой было железо, механика или нечто подобное - то реализация предсказаний оправдывается. Но в связке двух процессоров - это наличие недостатка в алгоритме.
|
|
|
|
2 чел. читают эту тему (гостей: 2, скрытых пользователей: 0)
Пользователей: 0
|
|
|