oldbrowze 0 19 ноября, 2021 Опубликовано 19 ноября, 2021 · Жалоба Приветствую, друзья! Передо мной стоит задача: подключить камень stm32f103c8t6 по SPI через MAX7219 к семисегментнику. Подключал по схеме: Скрытый текст Выясняется, что у меня ничего не работает. Понять почему я, увы, не могу.Функции инициализации SPI и отправки данных: Скрытый текст Чтобы понять проблему, я подключил логический анализатор ко всем трем выводам(MOSI, SCK, SS): Скрытый текст Исходя из даташита на MAX7219, она принимает данные после того, как будут отправлены 2 байта и поднята ножка SS. На фотографии с анализатора становится понятно, что SS дергается после того, как абсолютно все данные уйдут. В чем проблема, с чем это связано - я не могу понять. Пробовал добавить задержку в функции отправки, подумав, что, может быть, мой анализатор не фиксирует их. На что я получил ошибки в отправляемых данных: Скрытый текст Не понимаю, что я сделал не так... Буду очень рад, если Вы подскажете! Заранее большое спасибо! Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
x893 32 19 ноября, 2021 Опубликовано 19 ноября, 2021 · Жалоба Сделайте ногодрыгом по диаграмме от МАХ Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
andrew_su 1 19 ноября, 2021 Опубликовано 19 ноября, 2021 · Жалоба У Вас на схеме из МАХ-а выходят сигналы: DIG1(с двух контактов??), DIG3, DIG4. А на индикатор приходят сигналы: DIG1, DIG2(откуда он берётся) и два DIG3. Это так задумано? Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
oldbrowze 0 19 ноября, 2021 Опубликовано 19 ноября, 2021 · Жалоба 33 минуты назад, andrew_su сказал: Это так задумано? Спасибо за замечание! Перепутал немного, неправильно составил. Скрытый текст 47 минут назад, x893 сказал: Сделайте ногодрыгом по диаграмме от МАХ Согласно диаграмме, CS на нуле перед началом передачи и на единице - после. В этом-то и проблема: у меня через анализатор видно, что CS поднимается после !всей! передачи, а это - 16 байт ( 8 функций, каждая функция отправляет 2 байта). Я не понимаю, в чем ошибка в коде. Почему у меня перещелкивается CS только после всей передачи, ведь я в функции управляю им. По логике, CS должен до и после выполнения функции дергаться, но этого, к сожалению, не видно. Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
dimka76 42 19 ноября, 2021 Опубликовано 19 ноября, 2021 · Жалоба 23 minutes ago, oldbrowze said: Почему у меня перещелкивается CS только после всей передачи, ведь я в функции управляю им. По логике, CS должен до и после выполнения функции дергаться, но этого, к сожалению, не видно. 1. Код лучше выкладывать текстом, а не картинками. 2. Возможно флаг SPI_SR_BSY не успевает установиться до того как вы его начали проверять. Попробуйте либо вести задержку перед проверкой этого флага, либо проверять флаг SPI_SR_RXNE. Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
jcxz 172 19 ноября, 2021 Опубликовано 19 ноября, 2021 · Жалоба 1 час назад, oldbrowze сказал: По логике, CS должен до и после выполнения функции дергаться, но этого, к сожалению, не видно. Потому что нет никакой паузы между установкой CS=1 и последующей CS=0. Быстродействие GPIO гораздо ниже, чем у CPU и несколько тактов задержки на выполнение нескольких команд - крайне мало. К тому же - ёмкость линий на плате !=0, мгновенно напряжение на них не может изменяться. PS: Для манипуляций с отдельными ногами GPIO сделали специальный регистр BSRR. Использование ODR - чревато. PPS: То что у вас нарисовано в __delay() - это не задержка. Почитайте хоть немного раздел "Для начинающих" - 100500 раз уже об этом твердилось. Хоть немного включите голову и подумайте над вопросами: 1. Какая тактовая частота у моего CPU? 2. Какова длительность(тактов) лог."1" между GPIOB->ODR |= ... и GPIOB->ODR &= ~... ? 3. Какова частота сэмплирования моего лог.анализатора? Какие минимальные по длительности сигналы он может захватить? 4. На какой частоте работает GPIO в моём МК? Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
x893 32 19 ноября, 2021 Опубликовано 19 ноября, 2021 · Жалоба 30 minutes ago, jcxz said: Хоть немного включите голову и подумайте над вопросами: 0. Зачем это всё надо ?! Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
jcxz 172 19 ноября, 2021 Опубликовано 19 ноября, 2021 · Жалоба 1 минуту назад, x893 сказал: 0. Зачем это всё надо ?! Включать голову? А можно без неё писать код? Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
oldbrowze 0 19 ноября, 2021 Опубликовано 19 ноября, 2021 · Жалоба 1 час назад, jcxz сказал: Хоть немного включите голову и подумайте над вопросами Спасибо, подумал. Я действительно уже мало думал под конец, отчаялся. Хотя, если честно, я правда не додумался, что ошибка в этом.. У меня действительно все получилось. Скрытый текст Спасибо всем за ответы. Но, к сожалению, не понимаю, почему микросхемка отказывается зажигать светодиоды.. Команды отправляю согласно даташиту, передача(дрыг ноги CS) удовлетворяет даташиту.. LED_I::send_command(0x9, 0xFF); // режим декодирования LED_I::send_command(0xB, 0x3); // количество разрядов LED_I::send_command(0xA, 0x5); // яркость LED_I::send_command(0xC, 0x1); // включаем LED_I::send_command(0x1, 0x1); // единица Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Eddy_Em 1 19 ноября, 2021 Опубликовано 19 ноября, 2021 · Жалоба Было дело, баловался я с MAX7219, и как раз на STM32F103. Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Arlleex 129 19 ноября, 2021 Опубликовано 19 ноября, 2021 · Жалоба Моя рекомендация на данном этапе: сделайте read-back регистров, которые Вы записали. Когда считаете ровно то, что было записано, можно будет считать, что со связью все в порядке. Если же там белиберда - сами понимаете... Сейчас пока нет уверенности, что регистры получают ровно то, что Вы пишете. А пока нет уверенности в этом - дальше смысла смотреть просто нет. Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Sergey_Aleksandrovi4 0 19 ноября, 2021 Опубликовано 19 ноября, 2021 · Жалоба Попробуйте факт окончания передачи отслеживать по двум флагам: первично по TXE и лишь вторично по BSY. Уже не вспомню, но были какие-то "приколы" с BSY-флагом в F1xx семействе. void foo(bar) { GPIOB->ODR &= ~GPIO_ODR11; //..... while (!(SPI1->SR & SPI_SR_TXE)); while (SPI1->SR & SPI_SR_BSY); GPIOB->ODR |= GPIO_ODR11; } upd BSY устанавливается с задержкой. Т.е. факт начала передачи отслеживаете по TXE==0. Он становится '0' сразу же после записи слова данных в SPI_DR. После первого такта SCLK, когда слово из временного буфера выгрузилось в сдвиговый регистр, флаг TXE становится '1' и в дело вступает BSY, который к этому времени гарантированно установился в '1'. В общем в RefManual почитайте, сейчас нет времени в это окунаться. Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
oldbrowze 0 20 ноября, 2021 Опубликовано 20 ноября, 2021 (изменено) · Жалоба 19.11.2021 в 20:46, dimka76 сказал: 2. Возможно флаг SPI_SR_BSY не успевает установиться до того как вы его начали проверять. Попробуйте либо вести задержку перед проверкой этого флага, либо проверять флаг SPI_SR_RXNE. 19 часов назад, Sergey_Aleksandrovi4 сказал: upd BSY устанавливается с задержкой. Т.е. факт начала передачи отслеживаете по TXE==0. Он становится '0' сразу же после записи слова данных в SPI_DR. После первого такта SCLK, когда слово из временного буфера выгрузилось в сдвиговый регистр, флаг TXE становится '1' и в дело вступает BSY, который к этому времени гарантированно установился в '1'. В общем в RefManual почитайте, сейчас нет времени в это окунаться. Да, полагаю, мой анализатор просто не успевает углядеть. Поставил небольшую задержку, все успешно. Спасибо еще раз. 21 час назад, Arlleex сказал: Моя рекомендация на данном этапе: сделайте read-back регистров, которые Вы записали. Когда считаете ровно то, что было записано, можно будет считать, что со связью все в порядке. Если же там белиберда - сами понимаете... Сейчас пока нет уверенности, что регистры получают ровно то, что Вы пишете. А пока нет уверенности в этом - дальше смысла смотреть просто нет. Считать с другого устройства у меня, увы, нет возможности. Если это можно как-то провернуть без использования стороннего устройства - буду рад услышать. И, все-таки, подскажите, пожалуйста, что можно сделать с этим: Скрытый текст 23 часа назад, oldbrowze сказал: Спасибо, подумал. Я действительно уже мало думал под конец, отчаялся. Хотя, если честно, я правда не додумался, что ошибка в этом.. У меня действительно все получилось. Показать содержимое Спасибо всем за ответы. Но, к сожалению, не понимаю, почему микросхемка отказывается зажигать светодиоды.. Команды отправляю согласно даташиту, передача(дрыг ноги CS) удовлетворяет даташиту.. LED_I::send_command(0x9, 0xFF); // режим декодирования LED_I::send_command(0xB, 0x3); // количество разрядов LED_I::send_command(0xA, 0x5); // яркость LED_I::send_command(0xC, 0x1); // включаем LED_I::send_command(0x1, 0x1); // единица Уже сравниваю с даташитом по анализатору: диаграмма идентична, если так можно выразится. Но все равно не заводится микросхема. Скрытый текст void LED_I::send_command(const uint8_t &address, const uint8_t &command) { GPIOB->BRR |= GPIO_BRR_BR11; //while(SPI1->SR & SPI_SR_BSY); //GPIOB->BRR |= GPIO_BRR_BR11; SPI1->DR = (address << 8) | command; // отслыем первым байтом адрес регистра, втором - команду для регистра //__delay(_FUNCTION_DELAY); //GPIOB->BSRR |= GPIO_BSRR_BS11; while (!(SPI1->SR & SPI_SR_TXE)); //while (SPI1->SR & SPI_SR_RXNE); while(SPI1->SR & SPI_SR_BSY); GPIOB->BSRR |= GPIO_BSRR_BS11; __delay(1); } void LED_I::init() { RCC->APB2ENR |= RCC_APB2ENR_SPI1EN | RCC_APB2ENR_IOPBEN | RCC_APB2ENR_IOPAEN; // запускаем тактирование SPI, PB SPI1->CR1 |= (1 << SPI_CR1_DFF_Pos) // 16-битная передача | (1 << SPI_CR1_SSM_Pos) // программный SS | (1 << SPI_CR1_SSI_Pos) | (1 << SPI_CR1_BIDIMODE_Pos) | (1 << SPI_CR1_BIDIOE_Pos) | (0 << SPI_CR1_LSBFIRST_Pos) | (0b111 << SPI_CR1_BR_Pos) | (1 << SPI_CR1_MSTR_Pos) | (0 << SPI_CR1_CPHA_Pos) | (0 << SPI_CR1_CPOL_Pos); SPI1->CR1 |= (1 << SPI_CR1_SPE_Pos); //SCK GPIOA->CRL |= (0b10 << GPIO_CRL_CNF5_Pos) | (0b11 << GPIO_CRL_MODE5_Pos); //CS GPIOB->CRH |= (0b00 <<GPIO_CRH_CNF11_Pos) | (0b11 << GPIO_CRH_MODE11_Pos); GPIOB->BSRR |= GPIO_BSRR_BS11; //MOSI GPIOA->CRL |= (0b10 << GPIO_CRL_CNF7_Pos) | (0b11 << GPIO_CRL_MODE7_Pos); while(SPI1->SR & SPI_SR_MODF); } int main() { RCC_Init(); //инициализация тактирования LED_I::init(); LED_I::send_command(0x9, 0xFF); // режим декодирования LED_I::send_command(0xB, 0x3); // количество разрядов LED_I::send_command(0xA, 0x5); // яркость LED_I::send_command(0xC, 0x1); // включаем LED_I::send_command(0x1, 0x1); // единица while(true); return 0; } Хотя бы, в какую сторону смотреть..Где я мог допустить ошибку. Диаграммы с анализатора: Скрытый текст Изменено 20 ноября, 2021 пользователем oldbrowze Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Arlleex 129 20 ноября, 2021 Опубликовано 20 ноября, 2021 · Жалоба Что-то я не догоняю, как Вы отлаживаетесь? Что значит "считать с другого устройства"? Я говорю про обратное чтение того, что записали в микросхему с последующей сверкой. Вы же на реальной железке отлаживаетесь? Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
oldbrowze 0 20 ноября, 2021 Опубликовано 20 ноября, 2021 · Жалоба 3 минуты назад, Arlleex сказал: Вы же на реальной железке отлаживаетесь? Да. Вы меня извините, может я не развился еще до таких знаний, но как я сделаю сам read-back данных? Как я Вас понял: я делаю slave-устройство, читаю с него и сверяю с отправленными данными. Но как сделать с MAX7219 - не представляю. Наверное, глупо выгляжу)) Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться