реклама на сайте
подробности

 
 
> UART STM32, передача сообщения
ierofant
сообщение Oct 27 2011, 22:12
Сообщение #1


Участник
*

Группа: Участник
Сообщений: 32
Регистрация: 3-02-11
Из: Украина, Киев
Пользователь №: 62 695



Всем привет.
Разбираюсь в UARTe на STM32F100.

UART запутился, передачу и прием реализовал на прерываниях по окончанию передачи и приему.
В связи с этим есть вопросы:

Необходимо: Сделать передачу сообщения по событию, например - установке флага при нажатии на кнопку. (в программе message_must_send=1)

Проблема: Если реализовать это в прерывании, то прерывание по окончанию передачи просто напросто не генерируется и не происходит передача.(даже в обработчик не заходит, смотрел в отладчике) Передача начинается только после того, как был отправлен хотя бы один байт вне обработчика прерывания.
Т.е. нажимаю кнопкку на отладочной - ничего не передается, пока через терминал не пошлю любое примитивное соообщение(возвращается эхо, где и происходит отправка сообщения).

Если же первый элемент строки передавать во время установки флага, а все остальные уже в обработчике - все отлично работает.(хоть что-то записать в регистр данных, чтоыб потмо сработало прерывание по окончанию передачи) Но решать таким образом проблему как-то совсем глупо. Я надеюсь, вы мне подскажете поинтереснее варианты её решения.

Код ниже прилагается:
Инициализация:
Код
//инициализация юарта
void init_uart()
    {
    RCC->APB2ENR|= RCC_APB2ENR_AFIOEN; // Тактирование альтернативных функций GPIO.
    RCC->APB2ENR|= RCC_APB2ENR_USART1EN; // Включение тактирования USART1.
    GPIOA->CRH |= GPIO_CRH_MODE9; // Вывод TX PA.9 - на выход.
    GPIOA->CRH &=~GPIO_CRH_CNF9; GPIOA->CRH |=GPIO_CRH_CNF9_1; // Альтернативный выход.
    USART1->CR1 |=(USART_CR1_RE | USART_CR1_TE); // Разрешить выводы RX, TX.
          // Скорость 9.6 kbps. USARTDIV=FSYS/(16*baud) = 24e6/(16*9600)=156.25
    USART1->BRR=(156<<4); // Целая часть коэффициента деления USART1.
    USART1->BRR|=4; // Дробная часть*16 = 0,25*16 = 4.
    USART1->CR1 |=USART_CR1_UE; // Включение USART1.
    USART1->CR1 |=USART_CR1_TCIE|USART_CR1_RXNEIE; // Разрешить прерывания TC, RXNE.
    NVIC_EnableIRQ(USART1_IRQn); // Разрешить прерывание USART1_IRQn в NVIC.
    NVIC_SetPriority(USART1_IRQn, 3); //задать приоритет прерыванию
    }


Обработчик:
Код
void USART1_IRQHandler (void) // Обработчик прерывания USART1.
     {
          if (USART1->SR & USART_SR_RXNE) USART1->DR=USART1->DR;  // Если прерывание по приёму, то возвращаем эхо
          if (USART1->SR & USART_SR_TC) // Если прерывание по завершению передачи.
          {
            if(message_must_send==1)
            {
               if (message[tmp])
                {
                USART1->DR=message[tmp];
                tmp++;
                }
               else
                {
                tmp=0;
                message_must_send=0;
                }
            }
            USART1->SR&=~(USART_SR_TC|USART_SR_RXNE); // Очистить флаги прерывания.
          }
     }



Теперь вопросы:
1. Есть ли какой-то способ программно сгенерировать прерывание по окончанию передачи? Т.е. установить в статус-регистре SR бит ТС? Перерыл всю документацию - такой инфы не нашел.
2. Каким образом лучше производить передачу сообщения - в обработчике прерывания или же в основном цикле?
3. Если описать передачу в основном цикле - есть ли смысл в прерывании по окончанию передачи? Ведь можно просто отслеживать с таким же успехом состояние битов в статус-регистре.

Возможно, получилось несколько сбито и сумбурно, но столько вопросов и предложений вертится в голове, что сразу все и не вспомнишь. Буду очень благодарен за обьяснения и советы.
Go to the top of the page
 
+Quote Post
 
Start new topic
Ответов
AHTOXA
сообщение Oct 28 2011, 04:32
Сообщение #2


фанат дивана
******

Группа: Свой
Сообщений: 3 387
Регистрация: 9-08-07
Из: Уфа
Пользователь №: 29 684



Вместо прерывания по окончанию передачи удобнее использовать прерывание по опустошению передатчика (TXE).
Тогда отправка символа выглядит так:

Код
void putch(char ch)
{
    TxChannel.push(ch);
    enable_tx_interrupt();
}

а обработчик прерывания - вот так:
Код
void USART1_IRQHandler (void)
{
    uint16_t status = USART1->SR;
    if (status & USART_SR_RXNE)
    {
        uint8_t ch = USART1->DR;
        if (RxChannel.get_free_size())
            RxChannel.push(ch);
    }

    if (status & USART_SR_TXE)
    {
        if (TxChannel.get_count())
        {
            char ch = 0;
            TxChannel.pop(ch);
            USART1->DR = ch;
        }
        else
        {
            disable_tx_interrupt();
        }
    }
}

Запрет/разрешение прерывания по опустошению передатчика:
Код
inline void disable_tx_interrupt() { USART1->CR1 &= ~USART_CR1_TXEIE; }
inline void enable_tx_interrupt() { USART1->CR1 |= USART_CR1_TXEIE; }


--------------------
Если бы я знал, что такое электричество...
Go to the top of the page
 
+Quote Post
ierofant
сообщение Oct 28 2011, 19:30
Сообщение #3


Участник
*

Группа: Участник
Сообщений: 32
Регистрация: 3-02-11
Из: Украина, Киев
Пользователь №: 62 695



Цитата(AHTOXA @ Oct 28 2011, 07:32) *
Вместо прерывания по окончанию передачи удобнее использовать прерывание по опустошению передатчика (TXE).
Тогда отправка символа выглядит так:

Код
void putch(char ch)
{
    TxChannel.push(ch);
    enable_tx_interrupt();
}

а обработчик прерывания - вот так:
Код
...

Запрет/разрешение прерывания по опустошению передатчика:
Код
inline void disable_tx_interrupt() { USART1->CR1 &= ~USART_CR1_TXEIE; }
inline void enable_tx_interrupt() { USART1->CR1 |= USART_CR1_TXEIE; }

Спасибо большое за совет. Действительно, с таким прерыванием отлично заработало, как предпологалось изначально.

Сначала прочитал про него, подумал что полный аналог прерывания по окончанию передачи. Продолжил ковырять со старым прерыванием. Пока экспериментировал проследил в дебаге как меняются все регистры состояния и контроля юарта, вот там то и заметил, что когда буфер передатчика пуст - флаг TXE всегда установлен, и как только разрешено прерывание - оно сразу генерируется, в виду пустого передатчика.
В отличии от флага окончания передачи, который до прерывания сброшен.

Цитата
Помоему нужно сформировать прерывание по нажатию кнопки (изменению сигнала на пине ) и там начать передачу первого байта передать, а остальные уже по вашей технологии через окончание передачи. Можно при помощи DMA (автоматом все нужные байты передадутся из памяти в UART). Можно послать первый байт там, где формируется message_must_send=1, если передатчик пуст, а если он занят, то сработает прерывание завершения передачи и дальше Ваш метод сработает.

У меня антидребезг еще программно реализован с помощью прерываний таймера.
А передавать первый байт с установкой флага - мне казалось каким-то извратом. В общем сейчас все заработало как хотелось, что не может не радовать.
DMA контроллер - вещь весьма полезная, надо будет с нею разобраться.


Цитата
Дружище, а подскажите какая у вас среда разработки и были-ли проблемы запустить STM32?
Сам я к ST взор обратил недавно. Разобрался уже с STM8, а вот с STM32 проблемы.

Среда разработки - IAR 6.21.
Проблемы, конечно же, были. Куда без этого?!))
Были проблемы и с работой IARа, т.к. в новая версия(6.21) не хотела работать с внешними хидерами core_cm3.h, и с включением прерываний(пытался их включить, не добавив в проект файл с заголовками прерываний- startup для моего контроллера).

Но, для начала, хочу вам обьяснить, каким вообще образом можно создавать проекты для данных контроллеров:
Спасоб 1 : читая даташит и управляя всеми необходимыми регистрами для запуска и управления периферией(в этом случае используются только те стандартные библиотеки, где описываются бит-маски, обработчики прерываний и т.п.).
Спасоб 2 : используя стандартные библиотеки для работы с периферией(STM32F10x_StdPeriph), где, в принципе, интуитивно понятно происходит работа с периферией. Хотя, даташит, скорее всего, читать все же прийдется. Многие ругаются на её глючность.

Я покаместь использую только первый спасоб.

Для начала советую помотреть видео с данного ресурса:
http://bsvi.ru/category/embedded/arm/
Там небольшое вступление по документации и настройка ИАРа плюс создание простейшего проекта. Видео на русском, лишним однозначно не будет.

Много информации(статьи с примерами) есть на ресурсах:
http://easyelectronics.ru/ и http://we.easyelectronics.ru/
Поиск по тегам : STM32

http://eugenemcu.ru/publ/13 - тоже хороший ресурс

В принципе, почти все эти статьи - это переводы даташитов + примеры. Тем не менее, мне приятнее читать на родном языке. Потом я все равно еще пересматриваю описание работы нужной периферии в ДШ.

Всем еще раз спасибо за помощь.

Сообщение отредактировал ierofant - Oct 28 2011, 19:31
Go to the top of the page
 
+Quote Post
Apollo
сообщение Oct 31 2011, 07:17
Сообщение #4


Участник
*

Группа: Участник
Сообщений: 31
Регистрация: 10-07-07
Из: Москва
Пользователь №: 29 044



Цитата(ierofant @ Oct 28 2011, 22:30) *
Среда разработки - IAR 6.21.
Проблемы, конечно же, были. Куда без этого?!))

Для начала советую помотреть видео с данного ресурса:
http://bsvi.ru/category/embedded/arm/
Там небольшое вступление по документации и настройка ИАРа плюс создание простейшего проекта. Видео на русском, лишним однозначно не будет.

Спасибо, буду разбираться. Видео очень ценное. О многом просто не догадывался.
Go to the top of the page
 
+Quote Post

Сообщений в этой теме
- ierofant   UART STM32   Oct 27 2011, 22:12
- - Tolyaha   Цитата(ierofant @ Oct 28 2011, 01:12) Нео...   Oct 28 2011, 06:22
- - Apollo   Дружище, а подскажите какая у вас среда разработки...   Oct 28 2011, 11:20
- - kan35   STM32F10x_StdPeriph использую уже пару лет, с 1 по...   Oct 29 2011, 09:07
- - Serj78   Есть при использовании TXE один нюанс, связанный с...   Oct 29 2011, 15:02
|- - demiurg_spb   Цитата(Serj78 @ Oct 29 2011, 19:02) Есть ...   Oct 31 2011, 08:11
|- - AHTOXA   Цитата(demiurg_spb @ Oct 31 2011, 14:11) ...   Oct 31 2011, 08:55
|- - demiurg_spb   Цитата(AHTOXA @ Oct 31 2011, 12:55) Можно...   Oct 31 2011, 10:34
|- - AHTOXA   Сдаётся мне, что и с tail-chaining-ом будет проигр...   Oct 31 2011, 11:08
|- - demiurg_spb   Цитата(AHTOXA @ Oct 31 2011, 15:08) Сдаёт...   Oct 31 2011, 11:12
|- - demiurg_spb   Вот уже несколько лет работаю с STM32 и его различ...   Apr 5 2013, 14:23
|- - AHTOXA   Что-то я не вижу управления направлением передачи....   Apr 5 2013, 19:09
||- - demiurg_spb   Цитата(AHTOXA @ Apr 5 2013, 23:09) Что-то...   Apr 6 2013, 07:14
|- - kolobok0   Цитата(demiurg_spb @ Apr 5 2013, 18:23) ....   Apr 5 2013, 19:20
- - Apollo   Повторил пример из видеоурока. Всё заработало. Поп...   Oct 31 2011, 09:27


Reply to this topicStart new topic
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0

 


RSS Текстовая версия Сейчас: 24th June 2025 - 10:29
Рейтинг@Mail.ru


Страница сгенерированна за 0.01437 секунд с 7
ELECTRONIX ©2004-2016