Перейти к содержанию
    

remixx

Участник
  • Постов

    37
  • Зарегистрирован

  • Посещение

Весь контент remixx


  1. А при этом на выходе в анализаторе получится просто упорядоченный набор цифр, или же именно набор параметров + их значения? То есть я не совсем понимаю существует ли вообще возможность передачи именно структуры, или же указывая в Ethertype (тип Ethernet пакета) конкретное интересующее значение она формируется автоматически, а дальше, как вы и сказали, с учетом длины нужно поэлементно передать численные значения, а они сами автоматически присвоются параметрам по порядку?
  2. Здравствуйте. На просторах интернета нашел старый пример реализации передачи Ethernet пакета с использованием DMA. В нем производится запись и передача значений 0x01 и 0x02. Код программы: #include "stm32f40x.h" #include "stm32_eth.h" #include <stdio.h> #include "delay.h" //PHY_ADDRESS #define PHY_ADDRESS 0x01F /* PHY_ADDRESS TE-STM32F407 Board */ #define RMII_MODE /*MII mode or RMII mode*/ #define MY_MAC_ADD_0 0x33 #define MY_MAC_ADD_1 0x35 #define MY_MAC_ADD_2 0x43 #define MY_MAC_ADD_3 0x38 #define MY_MAC_ADD_4 0xF3 #define MY_MAC_ADD_5 0xA3 #define ETH_RXBUFNB 8 #define ETH_TXBUFNB 2 ETH_InitTypeDef ETH_InitStructure; ETH_DMADESCTypeDef DMARxDscrTab[ETH_RXBUFNB], DMATxDscrTab[ETH_TXBUFNB]; u8 Rx_Buff[ETH_RXBUFNB][ETH_MAX_PACKET_SIZE], Tx_Buff[ETH_TXBUFNB][ETH_MAX_PACKET_SIZE]; int main(void) { SysTick_Config(SystemCoreClock/1000); RCC_Configuration(); NVIC_Configuration(); GPIO_PinRemapConfig(GPIO_Remap_ETH, DISABLE); GPIO_ETH_MediaInterfaceConfig(GPIO_ETH_MediaInterface_MII); RCC->CFGR |= RCC_CFGR_MCO_HSE; GPIO_Configuration(); ETH_DeInit(); ETH_SoftwareReset(); while(ETH_GetSoftwareResetStatus()==SET); ETH_StructInit(&ETH_InitStructure); /*------------------------ MAC -----------------------------------*/ ETH_InitStructure.ETH_AutoNegotiation = ETH_AutoNegotiation_Enable ; ETH_InitStructure.ETH_Speed = ETH_Speed_100M; ETH_InitStructure.ETH_LoopbackMode = ETH_LoopbackMode_Disable; ETH_InitStructure.ETH_Mode = ETH_Mode_FullDuplex; ETH_InitStructure.ETH_RetryTransmission = ETH_RetryTransmission_Disable; ETH_InitStructure.ETH_AutomaticPadCRCStrip = ETH_AutomaticPadCRCStrip_Disable; ETH_InitStructure.ETH_ReceiveAll = ETH_ReceiveAll_Enable; ETH_InitStructure.ETH_BroadcastFramesReception = ETH_BroadcastFramesReception_Disable; ETH_InitStructure.ETH_PromiscuousMode = ETH_PromiscuousMode_Disable; ETH_InitStructure.ETH_MulticastFramesFilter = ETH_MulticastFramesFilter_Perfect; ETH_InitStructure.ETH_UnicastFramesFilter = ETH_UnicastFramesFilter_Perfect; /* Configure ETHERNET */ Value = ETH_Init(&ETH_InitStructure, PHY_ADDRESS); /* Initialize Tx Descriptors list: Chain Mode */ ETH_DMATxDescChainInit(DMATxDscrTab, &Tx_Buff[0][0], ETH_TXBUFNB); /* Initialize Rx Descriptors list: Chain Mode */ ETH_DMARxDescChainInit(DMARxDscrTab, &Rx_Buff[0][0], ETH_RXBUFNB); //Разрешаем прием DMARxDscrTab -> Status = ETH_DMARxDesc_OWN; /* Enable MAC and DMA transmission and reception */ ETH_Start(); while(1) { TransmitPacket(); } } Функция TransmitPacket: void TransmitPacket(void) { if ((DMATxDscrTab->Status & ETH_DMARxDesc_OWN)==0) { //Сначала отключаем передачу ETH_DMATransmissionCmd(DISABLE); Tx_Buff[0][20] = 0x01; Tx_Buff[0][21] = 0x02; //отдаем дескриптор в руки DMA Ethernet DMATxDscrTab -> Status = ETH_DMARxDesc_OWN | ETH_DMATxDesc_TCH | ETH_DMATxDesc_TTSE | ETH_DMATxDesc_LS | ETH_DMATxDesc_FS; //разрешаем отправку ETH_DMATransmissionCmd(ENABLE); } Возможно ли по такой же схеме передать структуру? То есть чтобы в анализаторе пакетов было нечто подобное: Кусок этой структуры сформировал, но как засунуть её в пакет не понимаю. struct APDU { 2 int8_t savPDU_tag; 3 int8_t savPDU_length; // razmer APDU 4 int8_t noASDU_tag; 5 int8_t noASDU_length; // razmer noASDU 6 int8_t noASDU; 7 int8_t SequenceofASDU_tag; 8 int8_t SequenceofASDU_length; // razmer vseh ASDU 9 struct ASDU_LE ASDU1; 10 };
  3. В общем копался копался и вот к чему пришел:Скачал готовые примеры udp и http сервера с сайта stm, правда конкретно для дискавери их нету, поэтому пришлось переконфигурировать их. За основу брал вот эту тему т.к. разбирается как раз мой случай.После прошивки контроллера подключил плату напрямую к контроллеру и если раньше разъем Rj45 просто горел зеленым, то после прямого подключения загорается оранжевый светодиод, а зеленый начинает хаотично мигать.Пробую пинговать - результата нет, пробую через браузер зайти на http сервер - аналогично.Залил в контроллер программу udp клиента, который должен посылать echo сообщения на статический ip адрес. Настраиваю его на ПК и указываю его в программе. Запускаю wireshark и вот что он выдает:2001 2086.482021000 192.168.0.10 192.168.0.255 NBNS 92 Name query NB MSCDC1.ZGHR.RU<00>2002 2344.964991000 192.168.0.10 192.168.0.255 NBNS 92 Name query NB MSCTMG<00>2003 2347.958454000 AsustekC_a8:15:63 Broadcast ARP 42 Who has 192.168.0.1? Tell 192.168.0.10И дальше по сути эти пакеты повторяются в хаотичной последовательности. Если фильтровать по ip платы, то от неё никаких пакетов не поступает, ping через командную строку тоже не работает.В связи с чем появился вопрос - т.к. компьютер рабочий, то вероятно в нем есть какие-то сетевые настройки предназначенные для защиты, т.к. MSCDC1.ZGHR.RU это название организации, помимо этого вне зависимости подключен ли ПК к интернету или напрямую к плате, он постоянно посылает вот эти Name query NB на последний ip в сети (т.е. первые три цифры могут меняться в зависимости от задаваемых настроек ххх.ххх.ххх но последняя всегда остается 255 на которую и идут все эти запросы).Т.е. может быть такое что именно из-за этой защиты плата не может быть увидена и пропингована ПК?
  4. воркбенч тоже не видит их upd: тут недопонимание - я использую stm32systemworkbench)
  5. скачал, но на работе нельзя ставить кейл (использую систем воркбенч), дома попробую запуститься)
  6. сейчас буду разбираться может быть проблема даже не в самом коде, потому что после прошивки и подключения интернет кабеля на разъеме rj45 начинает гореть зеленый светодиод, это по идеи означает что соединение по локальной сети установлено. Может что-то мешает конкретно добавить новое устройство в сеть?
  7. по конкретней бы( похоже что это файл настроек, которые в кубе находятся в LWIP->Key options, там не менял ничего в соответствии с теми уроками по которым собственно и делал этот проект
  8. Тогда все функции есть
  9. Я так понимаю настройку тактовой частоты выполняет функция SystemClock_Config, после неё вызывается MX_LWIP_Init вместе с функциями инициализации портов и таймера, а уже после идет цикл.
  10. STM32F407VG + LAN8720 ETH BOARD (Waveshare)

    Пытаюсь запустить эзернет на 407, используя готовый модуль от waveshare. В кубе добавляю ETH по RMII, в настройках ввожу МАК и выставляю PHY Address в 1 (нашел в даташите для этого модуля) и больше ничего не трогаю. Подключаю к этому LWIP, в нем отключаю DHCP и руками задаю маску и шлюз роутера + вписываю свободный ip. Включаю UDP и больше ничего не трогаю. Собираю проект, в переменные добавляю структуру gnetif, а в бесконечном цикле функции для постоянной работы стека (ethernetif_input и sys_check_timeouts). После прошивки в контроллер плата по указанному ip не пингуется, а роутер не находит новое устройство с указанным маком. Перепроверил все подключения на правильность, прослушал контакты - все в порядке. Уже отчаялся, так и не могу понять в чем заключается проблема...
  11. Попала в руки плата дискавери, к которой необходимо подключить ЖКИ 1602. Запитал его от 5В на плате, а вот с контрастом все оказалось сложнее, т.к. нету подстроечника. Поэтому решил регулировать контраст с помощью ШИМ.Выставил следующие настройки таймера: Код: htim2.Instance = TIM2; htim2.Init.Prescaler = 839; htim2.Init.CounterMode = TIM_COUNTERMODE_UP; htim2.Init.Period = 999; htim2.Init.ClockDivision = TIM_CLOCKDIVISION_DIV1; sMasterConfig.MasterOutputTrigger = TIM_TRGO_RESET; sMasterConfig.MasterSlaveMode = TIM_MASTERSLAVEMODE_DISABLE; sConfigOC.OCMode = TIM_OCMODE_PWM1; sConfigOC.Pulse = 0; sConfigOC.OCPolarity = TIM_OCPOLARITY_HIGH; sConfigOC.OCFastMode = TIM_OCFAST_DISABLE; Ну и в качестве теста попробовал изменить длительность импульса от максимума до минимума: Код: for (i=0; i<=999; i++) { TIM2->CCR1=i; } for (i=999; i>0; i--) { TIM2->CCR1=i; } По итогу получил, что когда импульс находится в минимуме, то на экране появляются еле заметные квадраты в обеих строках, а по мере его увеличения они вообще пропадают. Находил примеры лишь демонстрации работы такой схемы, без конкретной реализации.Можно ли все таки использовать ШИМ с дискавери для регулировки контраста ЖКИ? И каким образом подобрать оптимальное значение?
  12. Пытаюсь запрограммировать 107rct6 через st-link utility. На одном компьютере подключение выполняется в нормальном режиме и заливка программы проходит успешно, на другом же коннект к таргету происходит только через ресет и при попытке залить программу выдается вот такая ошибка: 10:09:06 : Connection to device is lost: check power supply and debug connection. 10:09:06 : If the target is in low power mode, please enable "Debug in Low Power mode" option from Target->settings menu. В чем может быть проблема? Настройки в st-link utility:
  13. Стоит. Залез в сам шаблон, убрал перед строчками знак "=" и вроде все ожило. Единственный вопрос, а можно как-нибудь менять размер и положение надписей непосредственно на схеме? Просто наименования изделий разные, где-то больше где-то меньше, а поля у меня корректируются только в шаблоне.
  14. Вроде бы все делаю по инструкции Design->Document Options->Parameters и там меняю информацию, но чтобы я не писал у меня в самом документе в каждом поле остается #NAME? Я подумал что это из-за шрифтов, но даже вводя цифры и английские буквы все остается также.
  15. Применяя форматки наших ГОСТов почему-то не меняются параметры (фамилии, названия и т.д.), поэтому хотел экспортировать в dwg/dxf чтобы открыть в компасе где заполнение всей информации гораздо проще и удобней.
  16. При экспортировании схемы (schdoc) в dwg/dxf с помощью File->Export->DWG/DXF, появляется вот такая ошибка: Класс не зарегистрирован at 1C5F5361. AdvSch.dll, Base Address: 1B840000. Exception Occurred In Export Версия альтиума 15.0 В чем может быть проблема?
  17. В рбщем поговорил с преподавателем, решили т.к. времени мало организовать всю работу на таймерах/счетчиках. Дальше уже буду сам разбираться :laughing: Но вот на деле уже 2 дня так и не могу пропинговать плату) В настройках LWIP пробую забивать как статический ip так и выставлять DHCP. Реакции 0. Варианта 2: либо я что-то неправильно подключил (схему приложил) либо подозрение упало на PHYADR, в дш написано что по дефолту он 1, собственно 1 в настройках LWIP я и выставляю, но у меня вывод PHYAD0 вообще не подключен, а 1-4 включены т.к. это RXD. Получается у меня PHY адрес 30 или все таки дефолтный 1?
  18. на крайняк сделаю с "тупыми" задержками :biggrin: посмотрю еще сегодня ISR.
  19. В указанном примере как раз таки MAC и ip адреса вбиваются вручную, все хидеры lwip проставляет автоматически, все что остается это засунуть данные в payload. По советам jcxz решил, что надо добавлять в проект и RTOS. Из той информации, которую изучил на данный момент, имею следующее представление: 1. Создаю 2 задачи. В первой провожу инициализацию АЦП и в бесконечном цикле отправляю запрос на единичное преобразование, записывая результат в соответствующий элемент структуры и ставя её в очередь. Примерный код: // Добавляю глобальную переменную для очереди // osMailQId strout_Queue // Указываю размер очереди // #define MAIL_SIZE (uint32_t) 1 // Насколько я понимаю, чтобы гарантированно передать по ethernet значение преобразования, в очереди должен быть всего 1 элемент, соответственно если она заполнена, то первая задача находится в блокированном состоянии // Задаю структуру с данными // typedef data_t { int32_t temperature; uint8_t time; uint8_t date; } data; // Создаю задачу RTOS // osThreadDef(ADC, StartTaskADC, osPriorityNormal, 0, 128); ADCHandle = osThreadCreate(osThread(ADC), NULL); // Создаю очередь // osMailQDef(stroutqueue, MAIL_SIZE, data; strout_Queue = osMailCreate(osMailQ(stroutqueue), NULL); // Создаю функцию первой задачи // void StartTaskADC(void const * argument) { /* USER CODE BEGIN StartTaskADC */ struct_out *qstruct; // добавляю переменную типа передаваемой в очереди структуры ADC_Init; // выполняю инициализацию АЦП (отправляю набор команд по SPI, использую функцию HAL_SPI_Transmit, можно ли взять её или для таких применений нужно с DMA каким-нибудь?) /* Infinite loop */ for(;;) { qstruct = osMailAlloc(strout_Queue, osWaitForever); // выделяю память под очередь qstruct->temperature = ADC_ReadValue; // записываю в элемент структуры temperature полученное значение из АЦП (посылаю команду единичного преобразования через HAL_SPI_Transmit, аналогичный вопрос) qstruct->time = 1 // записываю в элемент структуры time рандомное значение (пока не важно) qstruct->date = 2 // записываю в элемент структуры date рандомное значение (пока не важно) osMailPut(strout_Queue, qstruct); // отправляю структуру в очередь osDelay(1); } /* USER CODE END StartTaskADC */ } 2. Создаю вторую задачу, которая будет инициализировать UDP, получать измеренное значение температуры из очереди и отправлять его. // Создаю глобальные переменные структур, требующихся для передачи по ethernet // extern struct netif gnetif; static struct udp_pcb *udp_Pcb1_p; // Создаю задачу RTOS // osThreadDef(ETH, StartTaskETH, osPriorityNormal, 0, 128); ETHHandle = osThreadCreate(osThread(ETH), NULL); // Создаю функцию второй задачи // void StartTaskETH(void const * argument) { /* USER CODE BEGIN StartTaskETH */ osEvent event; // добавляю переменную типа структуры состояния очереди struct_out *qstruct; // добавляю переменную типа передаваемой в очереди структуры UDP_Init; // выполняю инициализацию UDP (в ней создается новое подключение UDP (udp_new), вручную записывается mac и ip адрес компа, биндится соединение (udp_bind) и проверяется на наличие ошибок) /* Infinite loop */ for(;;) { static const char packet[]; // создаю переменную для данных, которые буду класть в payload event = osMailGet(strout_Queue, osWaitForever); // забираю данные из очереди if (event.status == osEventMail) // проверяю состояние очереди qstruct = event.value.p; // присваиваю переменной типа структуры очереди указатель на элемент очереди packet[] = qstruct->temperature, qstruct->time, qstruct->date; // записываю полученные данные в переменную для payload SendPacket; // вызываю функцию отправки udp (здесь указывается ip адрес клиента, создается буффер для передачи по eth, в который заносим вышеуказанный packet[], заносим все это в payload и отправляем (udp_sendto) ethernetif_input(&gnetif); // вписываю стандартный код для обеспечения постоянной работы стека sys_check_timeouts; // продолжение... (говорят, что эти 2 строки можно заменить MX_LWIP_Process() тогда и extern struct netif gnetif не нужно, но пока попробую запуститься так) osDelay(1); } /* USER CODE END StartTaskETH */ } Где-то что-то упустил или вообще все кардинально неправильно?))
  20. Мне действительно интересно этим заниматься, в будущем планирую работать в сфере, где требуется представление о программировании хотя бы на таком уровне. Опыта без практики не получить. Задача сама по себе не связана с реальным применением, просто некий теоретический вариант, для реализации которого требуется работа с основной перефирией МК, что и является главной целью в данной работе. Пары не прогуливал :biggrin: , большинство курсов в основном были связаны с элементной базой, принципом работы ИМС, их проектированием и т.п. На единственном курсе, связанным с программированием, мы по-этапно выводили символ нажатой кнопки на ЖКИ в течение 3-х лаб, писалось все на ассемблере. Поэтому "уровень" соответствующий. Вообще специальность называется микроэлектроника, поэтому прямой связи с программированием и уж тем более работой с сетями нету. Собственно вот с таким "багажом" я и подошел к работе над вышеупомянутой задачей), поэтому возникает куча вопросов на каждом шагу. Ну ладно, это небольшое лирическое отступление :biggrin: По теме: под пакетом преподаватель имел ввиду фрейм (IEEE 802.3), структуру представил ниже. То есть насколько я понял, преамбула, header mac, длина и LLC формируются автоматически при отправке, с указанными значениями при инициализации, а в блок данных (data unit), необходимо завести требуемые значения измерений. Думаю это удобно сделать через struct, пример: struct Data { int32_t temperature; uint8_t time; uint8_t date; } Перед каждой отправкой приравниваю переменные к полученным значениям измерений и отправляю их. После чего некая задержка, ну из первого что пришло в голову 1 сек / 1000 = 1 мс, соответственно её и беру. И снова измерение, формирование фрейма, отправка. И так 1000 раз. По вашим советам стал искать информацию, как осуществить передачу, используя lwip. Наткнулся вот на такой пример. С помощью куба он инициализирует ethernet и подключает lwip. В коде добавляет функции для udp и отправляет тестовый фрейм. Вроде бы это то что нужно) Кстати для анализа полученных пакетов использую wireshark.
  21. Функционал устроства верный . Это мой дипломный проект, по сути представляет из себя некий измерительный блок, который оцифровывает показания датчика температуры и передает их по ethernet. Вообще задача сформулирована следующим образом: необходимо передать 1000 ethernet пакетов с определенной структурой в секунду. В каждом пакете должны содержаться: значение измеренной температуры, время, дата и еще несколько параметров. Сам блок подключается к компьютеру, к нему никаких обращений не требуется, т.е. она просто гонит данные и все. Читаю про TCP/IP стек, но теория без практики воспринимается сложно. Пытаюсь найти примеры с реализацией lwip. Пробовал пинговать плату при обычной инициализации ethernet (без lwip), результата нет.
  22. STM32F107RCT6 + KSZ8721 (ethernet)

    Пытаюсь запустить эзернет на МК. В качестве внешнего PHY использую KSZ8721. Задача следующая: сформировать пакет определенной структуры (т.е. условно 20-28 байт параметр1, 29-36 байт параметр2, 37-50 параметр3 и т.д.), записать в эти параметры значения с АЦП и передать определенное количество пакетов в секунду. Подключение MII, режим full duplex. Собственно в связи с вышеизложенным следующие вопросы: 1. Каким образом можно сформировать произвольную структуру пакета? 2. Будет ли достаточно для данных целей обычной инициализации эзернета в кубе и передачи пакетов функцией HAL_ETH_TransmitFrame()? Код функции представлен ниже. /** * @brief Sends an Ethernet frame. * @param heth: pointer to a ETH_HandleTypeDef structure that contains * the configuration information for ETHERNET module * @param FrameLength: Amount of data to be sent * @retval HAL status */ HAL_StatusTypeDef HAL_ETH_TransmitFrame(ETH_HandleTypeDef *heth, uint32_t FrameLength) { uint32_t bufcount = 0U, size = 0U, i = 0U; /* Process Locked */ __HAL_LOCK(heth); /* Set the ETH peripheral state to BUSY */ heth->State = HAL_ETH_STATE_BUSY; if (FrameLength == 0U) { /* Set ETH HAL state to READY */ heth->State = HAL_ETH_STATE_READY; /* Process Unlocked */ __HAL_UNLOCK(heth); return HAL_ERROR; } /* Check if the descriptor is owned by the ETHERNET DMA (when set) or CPU (when reset) */ if(((heth->TxDesc)->Status & ETH_DMATXDESC_OWN) != (uint32_t)RESET) { /* OWN bit set */ heth->State = HAL_ETH_STATE_BUSY_TX; /* Process Unlocked */ __HAL_UNLOCK(heth); return HAL_ERROR; } /* Get the number of needed Tx buffers for the current frame */ if (FrameLength > ETH_TX_BUF_SIZE) { bufcount = FrameLength/ETH_TX_BUF_SIZE; if (FrameLength % ETH_TX_BUF_SIZE) { bufcount++; } } else { bufcount = 1U; } if (bufcount == 1U) { /* Set LAST and FIRST segment */ heth->TxDesc->Status |=ETH_DMATXDESC_FS|ETH_DMATXDESC_LS; /* Set frame size */ heth->TxDesc->ControlBufferSize = (FrameLength & ETH_DMATXDESC_TBS1); /* Set Own bit of the Tx descriptor Status: gives the buffer back to ETHERNET DMA */ heth->TxDesc->Status |= ETH_DMATXDESC_OWN; /* Point to next descriptor */ heth->TxDesc= (ETH_DMADescTypeDef *)(heth->TxDesc->Buffer2NextDescAddr); } else { for (i=0U; i< bufcount; i++) { /* Clear FIRST and LAST segment bits */ heth->TxDesc->Status &= ~(ETH_DMATXDESC_FS | ETH_DMATXDESC_LS); if (i == 0U) { /* Setting the first segment bit */ heth->TxDesc->Status |= ETH_DMATXDESC_FS; } /* Program size */ heth->TxDesc->ControlBufferSize = (ETH_TX_BUF_SIZE & ETH_DMATXDESC_TBS1); if (i == (bufcount-1U)) { /* Setting the last segment bit */ heth->TxDesc->Status |= ETH_DMATXDESC_LS; size = FrameLength - (bufcount-1U)*ETH_TX_BUF_SIZE; heth->TxDesc->ControlBufferSize = (size & ETH_DMATXDESC_TBS1); } /* Set Own bit of the Tx descriptor Status: gives the buffer back to ETHERNET DMA */ heth->TxDesc->Status |= ETH_DMATXDESC_OWN; /* point to next descriptor */ heth->TxDesc = (ETH_DMADescTypeDef *)(heth->TxDesc->Buffer2NextDescAddr); } } /* When Tx Buffer unavailable flag is set: clear it and resume transmission */ if (((heth->Instance)->DMASR & ETH_DMASR_TBUS) != (uint32_t)RESET) { /* Clear TBUS ETHERNET DMA flag */ (heth->Instance)->DMASR = ETH_DMASR_TBUS; /* Resume DMA transmission*/ (heth->Instance)->DMATPDR = 0U; } /* Set ETH HAL State to Ready */ heth->State = HAL_ETH_STATE_READY; /* Process Unlocked */ __HAL_UNLOCK(heth); /* Return function status */ return HAL_OK; }
  23. STM32F107RCT6 + ADS1256

    Есть отдельный кварц на АЦП. Все заработало! Похоже проблема была именно в режиме SPI (0, 2Edge). Всем спасибо.
  24. STM32F107RCT6 + ADS1256

    1. Насколько я понимаю рабочая частота АЦП определяется кварцем? В таком случае она равна 8 МГц. Частоту SPI беру с очень большим запасом (1.125 МГц, картинка ниже). 2. А такое наблюдается даже если дергаешь CS программно? 3. Попробую. 4. По задержкам ниже представил код с исправлениями. 5. Проверил, по питанию все уровне в норме. 1. Настройку SPI выполняю только в кубе, ниже рисунок с параметрами из 1 поста. Нужно ли кроме этого что-то настраивать еще? 2. После доработок получился вот такой код с учетом задержек: int main(void) { /* USER CODE BEGIN 1 */ /* USER CODE END 1 */ /* MCU Configuration----------------------------------------------------------*/ /* Reset of all peripherals, Initializes the Flash interface and the Systick. */ HAL_Init(); /* USER CODE BEGIN Init */ /* USER CODE END Init */ /* Configure the system clock */ SystemClock_Config(); /* USER CODE BEGIN SysInit */ /* USER CODE END SysInit */ /* Initialize all configured peripherals */ MX_GPIO_Init(); MX_SPI3_Init(); /* USER CODE BEGIN 2 */ DWT_Delay_Init(); CS_ON(); // Enable CS DWT_Delay_us(10); // Задержка t3. По ДШ её может и не быть (0 нс), но небольшую все-таки сделал - 10 мкс. Пробовал и больше (1 мс). spiTxBuf[0]=0xFE; // Set RESET command address HAL_SPI_Transmit(&hspi3, spiTxBuf, 1, 50); // Transmit buffer via SPI CS_OFF(); // Disable CS CS_ON(); // Enable CS DWT_Delay_us(10); // Задержка t3. spiTxBuf[0]=0x0F; // Set SDATAC command address HAL_SPI_Transmit(&hspi3, spiTxBuf, 1, 50); // Transmit buffer via SPI CS_OFF(); // Disable CS CS_ON(); // Enable CS DWT_Delay_us(10); // Задержка t3. spiTxBuf[0]=0x50; // Set WREG command address + address of STATUS register HAL_SPI_Transmit(&hspi3, spiTxBuf, 1, 50); // Transmit buffer via SPI spiTxBuf[0]=3; // Set number of registers to be written HAL_SPI_Transmit(&hspi3, spiTxBuf, 1, 50); // Transmit buffer via SPI spiTxBuf[0]=0x02; // STATUS - MSB; Disable auto-calibration; Disable buffer; DRDY spiTxBuf[1]=0x01; // MUX - AIN0 as POSITIVE, AIN1 as NEGATIVE spiTxBuf[2]=0x00; // ADCON - Clock out disable; Sensor detect disable; PGA = 1 spiTxBuf[3]=0xF0; // DRATE - 30000 SPS HAL_SPI_Transmit(&hspi3, spiTxBuf, 4, 50); // Transmit buffer via SPI CS_OFF(); // Disable CS /* USER CODE END 2 */ /* Infinite loop */ /* USER CODE BEGIN WHILE */ while (1) { /* USER CODE END WHILE */ /* USER CODE BEGIN 3 */ CS_ON(); // Enable CS DWT_Delay_us(10); // Задержка t3. spiTxBuf[0]=0xFC; // Set SYNC command address HAL_SPI_Transmit(&hspi3, spiTxBuf, 1, 50); // Transmit buffer via SPI CS_OFF(); // Disable CS CS_ON(); // Enable CS DWT_Delay_us(10); // Задержка t3. spiTxBuf[0]=0x00; // Set WAKEUP command address HAL_SPI_Transmit(&hspi3, spiTxBuf, 1, 50); CS_OFF(); // Disable CS while(HAL_GPIO_ReadPin(DRDY_GPIO_Port, DRDY_Pin)==GPIO_PIN_SET) {} // Read level of DRDY pin, if it's set to HIGH - wait CS_ON(); // Enable CS DWT_Delay_us(10); // Задержка t3. spiTxBuf[0]=0x01; // Set RDATA command address HAL_SPI_Transmit(&hspi3, spiTxBuf, 1, 50); // Transmit buffer via SPI DWT_Delay_us(10); // Задержка t6. По Дш = 50/fCLK. У меня fCLK = 8 МГц, откуда t6 = 6,25 мкс. Беру с запасом - 10 мкс. HAL_SPI_Receive(&hspi3, spiRxBuf, 3, 50); // Receive result of conversion via SPI CS_OFF(); // Disable CS result = spiRxBuf[0]; result = result << 8; result |= spiRxBuf[1]; result = result << 8; result |= spiRxBuf[2]; LCD_PrintInt(result); } /* USER CODE END 3 */ } Единственное чего не делаю, это задержек после отправки и получения SPI. Как мне казалось внутри этих функций есть проверка флагов окончания передачи, попробую добавить задержки после них.
  25. STM32F107RCT6 + ADS1256

    Вернулся к работе, но после всех корректировок так ничего и не изменилось) Может быть я неправильно настраиваю CPOL и CPHA? Приложил картинку передачи сигналов из ДШ. По-моему в настройках SPI нужно устанавливать CPOL - 0, CPHA - 1Edge. Еще кстати заметил, что в настройках выводов SCK и MOSI заданы как AF, а MISO как Input. А разве MISO не должен тоже задаваться как AF?
×
×
  • Создать...