Потому что:
a) while (!(SPI1->SR & SPI_SR_RXNE)); - ожидает завершения передачи слова.
b) читать принятое надо ПОСЛЕ появления флага готовности, а не ДО.
в) читать надо командой data = *(uint8_t volatile *)&SPI1->DR; а не как у вас.
г) писать нужно также через (uint8_t volatile *) указатель, а не как у вас.
zenon,
1- SPI у F1 и F0 разный, в первом нет FIF0 очереди, источники для подглядывания надо выбирать соответствующие;
2- флаги TXE, RXNE можно сказать здесь относятся к очереди, а не процессу передачи - что приводит к тому, что Вы шурудите линеей DC прям во время передачи уходящего байта.
в оригинале :
while (!(SPI1->SR & SPI_SR_RXNE)); - дождаться ухода/прихода (здесь это одно и то же) байта
data = *(uint8_t *)&SPI1->DR; - прочитать DR чтоб снялся флаг RXNE (чтение SR потом DR - снимает флаг)
VladislavS,
спасибо. про доступ при записи на глаза не попалось, а про чтение нашел в RM - требует соответствия доступа.
м-да, тяжко когда уровень инглиш не в "свободном чтении".
Нда... мне читать-то не надо, только быстро передавать, и это... volatile в этом моменте тут не при чём. a797945 шурудить не буду, сначала правильно делал.
;_)
Что-то мне подсказывает, что на самом деле я не переключаюсь на 8 бит.
в пакетах, где частая смена линии DC (инит дисплея), ожидание завершения передачи байта, перед сменой сост. линии DC - неизбежность.
в пакетах, где DC менять не надо - в рукопашную не передают , используют DMA.
[uquote="a797945",url="/forum/viewtopic.php?p=4456874#p4456874"]в пакетах, где частая смена линии DC (инит дисплея), ожидание завершения передачи байта, перед сменой сост. линии DC - неизбежность.[/uquote]"неизбежность" это только для тех, кто контроллер не умеет подходящий выбрать. Если выбрать такой, который сможет аппаратно управлять этой линией и создать соответствующую схему, то и ждать ничего не потребуется - можно сразу выплюнуть всю посылку с командой и данными совместно и через DMA. Но без использования головы тут не обойтись, это точно.
Ха, jcxz бесячий же ты типчик, а родился ты наверное сразу со всеми интерфейсами, периферией и готовой прошивкой?
До DMA ещё не добрался, что до выбора мк - разбираюсь с чем есть, спешить некуда, ошибок ну сами знаете у кого нет.
ps. Нашёл старую тему по дисплею, пойду полистаю.
[uquote="Sergi",url="/forum/viewtopic.php?p=4457173#p4457173"]В F0 можно проверять флаг BUSY. Означает что передача не окончена. Ждать пока BSY=0 и потом можно дергать DC.[/uquote]
...Ждать когда BSY=0...
на быстром коде может потребоваться небольшая задержка после записи в DR до проверки BSY, он не сразу вскакивает.
непонятно было, когда Вы вопрос задали не приводя контекст, вот и ответ был - не надо читать - не читайте.
а код привели, стало понятно - вывод байта обрамляется сиг.DC, а как узнать когда можно уже дергать DC? -вот и ждут RXNE, а уже чтобы сбросить флаг - читают DR, можно в никуда.
когда не надо рулить DC - по TXE (движению очереди) грузят DR, но обычно не в ручную - DMA для этого есть.
Так я сам не сразу понял про DC, а первый раз вышеупомянутую ссылку на хабре прочёл по диагонали, не знаю как у кого, у меня окончательное понимание в железке происходит.
Добрый вечер! Передаю по USART2 байт с терминала и тут же его возвращаю. Не могу понять, почему возвращается число больше.... Передаю 7 - возвращается 37, передаю 8 - возвращается 38. СпойлерRCC -> APB1ENR |= RCC_APB1ENR_USART2EN; // Включение тактирования USART2
GPIOA -> MODER |= GPIO_MODER_MODE2_1; // Альтернативная функция для РА2 (USART2- TX)
GPIOA -> AFR[0] |= GPIO_AFRL_AFSEL2_0 | GPIO_AFRL_AFSEL2_1 | GPIO_AFRL_AFSEL2_2; // Альтернативная функция для РА2 - AF7
GPIOA -> MODER |= GPIO_MODER_MODE3_1; // Альтернативная функция для РА3 (USART2- RX)
GPIOA -> AFR[0] |= GPIO_AFRL_AFSEL3_0 | GPIO_AFRL_AFSEL3_1 | GPIO_AFRL_AFSEL3_2; // Альтернативная функция для РА3 - AF7
[uquote="ARV",url="/forum/viewtopic.php?p=4461381#p4461381"]Я так подозреваю, принимаете число, передаёте символ...[/uquote]
Я проверял внутри условия case - он уже принимает 0x37, а не 7
[uquote="Димаn",url="/forum/viewtopic.php?p=4461385#p4461385"]0x37, а не 7 [/uquote]
Вам же объяснили. 0х37 это ASCII код СИМВОЛА СЕМЬ. Вы передаете не число, а код символа.
Можете передать так любую букву или знак.
Символы чисел отличаются от самих чисел на величину 0х30.
[uquote="КРАМ",url="/forum/viewtopic.php?p=4461408#p4461408"][uquote="Димаn",url="/forum/viewtopic.php?p=4461385#p4461385"]0x37, а не 7 [/uquote]
Вам же объяснили.[/uquote]
Сообразил. Спасибо. Странно, вроде в терминале hex ставлю
[uquote="КРАМ",url="/forum/viewtopic.php?p=4461414#p4461414"]Я терминалом не пользуюсь, но полагаю, что из него всегда передаются ASCII коды ТЕКСТА, включая цифры, а не числа.[/uquote]
Да, проверил. Именно так. Поставил точку напротив ascii и так и отображается как передаю. Получается, ничего преобразовывать не надо (вычитать 30)?
Допустим, надо через усарт передать на spi число 0хС0.
Всем добра! имеется stm32f030т6 пытаюсь снять ацп с двух каналов. один работает хорошо. он снимает все работает но иногда их меняет местами как поборот?
inet:
RCC->APB2ENR |= RCC_APB2ENR_ADCEN;
RCC->APB2ENR |= RCC_APB2ENR_ADCEN;
ADC1->CR |= ADC_CR_ADSTART; /* start the ADC conversion */
while ((ADC1->ISR & ADC_ISR_EOC) == 0) /* wait end of conversion */
{
/* For robust implementation, add here time-out management */
}
if ((ADC1->ISR & ADC_ISR_EOC) != 0) /* checks EOC has triggered the IT */
{
ADC_array[CurrentChannel] = ADC1->DR; /* reads data and clears EOC flag */
CurrentChannel++; /* increments the index on ADC_array */
}
if ((ADC1->ISR & ADC_ISR_EOSEQ) != 0) /* checks EOSEQ has triggered the IT */
{
ADC1->ISR |= ADC_ISR_EOSEQ; /* clears the pending bit */
CurrentChannel = 0; /* reinitialize the CurrentChannel */
out_adc = ADC_array[0];in_adc = ADC_array[1];
}