Микроконтроллеры, АЦП, память и т.д Темы касающиеся микроконтроллеров разных производителей, памяти, АЦП/ЦАП, периферийных модулей... |
15.02.2011, 00:17
|
|
Почётный гражданин KAZUS.RU
Регистрация: 29.10.2006
Сообщений: 1,446
Сказал спасибо: 99
Сказали Спасибо 317 раз(а) в 233 сообщении(ях)
|
Re: Отправка числа 0 (ноль) по уарту
есть функция getchar(), которая возвращает результат - тип char. функция ждёт, пока придёт символ по UART.
...
c = getchar();
if(c==0) { ... }
всего делов-то...
P.S.
unsigned char getchar(void)
{
char status,data;
while( (((status=UCSR0A) & (1‹‹RXC) )==0));
data=UDR0;
if((status & ( (1‹‹FE) | (1‹‹UPE) | (1‹‹DOR)))) ERROR = 1;
return data;
}
Переменная ERROR выставляется в 1 при ошибках приёма (ошибке чётности, ошибке стопового бита и т.д.)
Последний раз редактировалось Godzilla82; 15.02.2011 в 00:35.
|
|
|
|
15.02.2011, 07:43
|
|
Почётный гражданин KAZUS.RU
Регистрация: 15.07.2009
Адрес: San Jose, USA
Сообщений: 927
Сказал спасибо: 11
Сказали Спасибо 228 раз(а) в 166 сообщении(ях)
|
Re: Отправка числа 0 (ноль) по уарту
Сообщение от Someone
|
Третье - в getchar команды cli и sei нафиг не нужны, потому что ни на что не влияют, ведь даже если произойдет прерывание приема очередного байта перед декрементом счетчика принятых байт в буфере, то этот счетчик всего лишь увеличиться на еденицу, а очередной байт пойдет в буфер.
|
Ну, это вот как раз не верно. Представьте себе такой сценарий для случая, если манипуляции с разрешением прерывания нет:
1. В основном потоке выполняется getchar, как раз собирается декрементировать rx_counter0 и читает его значение в регистр.
2. В этот момент происходит прерывание, выполняется usart0_rx_isr, которая инкрементирует rx_counter0. ISR заканчивается и возобновляется основной поток, который понятия не имеет что значение rx_counter0 изменилось.
3. Основной поток декрементирует старую копию rx_counter0 которая у него уже в регистре и записывает результат в память rx_counter0.
Таким образом, милейший, вы только что потеряли один символ.
Последний раз редактировалось urmlr; 15.02.2011 в 07:46.
|
|
|
|
15.02.2011, 14:22
|
|
Гражданин KAZUS.RU
Регистрация: 16.06.2005
Сообщений: 944
Сказал спасибо: 25
Сказали Спасибо 174 раз(а) в 123 сообщении(ях)
|
Re: Отправка числа 0 (ноль) по уарту
Сообщение от Cybermaker
|
Может ли return data =return '' ? Если может - то использование этой функции, при том что она не блокирующая, мне кажется весьма корявым.
|
Приведенная функция гетчар возвращает '' в случае, если буфер приема пуст.
Сообщение от urmlr
|
Ну, это вот как раз не верно. Представьте себе такой сценарий для случая, если манипуляции с разрешением прерывания нет:
1. В основном потоке выполняется getchar, как раз собирается декрементировать rx_counter0 и читает его значение в регистр.
2. В этот момент происходит прерывание, выполняется usart0_rx_isr, которая инкрементирует rx_counter0. ISR заканчивается и возобновляется основной поток, который понятия не имеет что значение rx_counter0 изменилось.
3. Основной поток декрементирует старую копию rx_counter0 которая у него уже в регистре и записывает результат в память rx_counter0.
Таким образом, милейший, вы только что потеряли один символ.
|
Справедливо. Так все и произойдет, и при таком коде я не прав. Но если написать вместо if (rx_counter0›0) такую строчку if (rx_wr_index0 != rx_rd_index0) то надобность в переменной rx_counter0 отпадает, что не только делает не нужными cli/sei но и заметно сокращает код.
|
|
|
|
15.02.2011, 20:51
|
|
Прописка
Регистрация: 02.01.2011
Сообщений: 159
Сказал спасибо: 8
Сказали Спасибо 32 раз(а) в 28 сообщении(ях)
|
Re: Отправка числа 0 (ноль) по уарту
Я думаю, что может return data = return ''
Не знаю, что там компилятор выдаст на '', но думаю, что просто символ с кодом 0.
Если буфер пуст, то надо возвращать не '', а код › 255, ест-но getchar возвращать
будет не char, а int.
|
|
|
Сказали "Спасибо" akimych
|
|
|
15.02.2011, 20:59
|
|
Почётный гражданин KAZUS.RU
Регистрация: 15.07.2009
Адрес: San Jose, USA
Сообщений: 927
Сказал спасибо: 11
Сказали Спасибо 228 раз(а) в 166 сообщении(ях)
|
Re: Отправка числа 0 (ноль) по уарту
Сообщение от Someone
|
Справедливо. Так все и произойдет, и при таком коде я не прав. Но если написать вместо if (rx_counter0›0) такую строчку if (rx_wr_index0 != rx_rd_index0) то надобность в переменной rx_counter0 отпадает, что не только делает не нужными cli/sei но и заметно сокращает код.
|
Так конечно лучше на первый взгляд. Только в этом случае, так как rx_buffer0 должен управляться как кольцевой буфер, соответственно, условие переполнения будет посложнее чем приведено в обсуждаемом фрагменте кода, поскольку rx_counter0 используемый для этой цели изначально, уже не существует. Плюс, более сложное вычисление условия переполнения будет вычисляться в ISR, так что "сокращение кода" очень сомнительно.
Вообще говоря, тип возврата getchar обычно определяется как int с большей разрядностью чем char. Тогда в случае если буфер пуст можно вернуть что-то осмысленное, не являющееся значением из диапазона значений char. То же самое и про ошибку. А что такое ('')? Ноль? Так ноль - это вполне допустимое значение символа, а вовсе не индикация пустого буфера, нет?
|
|
|
|
15.02.2011, 21:01
|
|
Почётный гражданин KAZUS.RU
Регистрация: 15.07.2009
Адрес: San Jose, USA
Сообщений: 927
Сказал спасибо: 11
Сказали Спасибо 228 раз(а) в 166 сообщении(ях)
|
Re: Отправка числа 0 (ноль) по уарту
Сообщение от akimych
|
getchar возвращать будет не char, а int.
|
О! Пока писал своё...
|
|
|
|
16.02.2011, 11:08
|
|
Гражданин KAZUS.RU
Регистрация: 16.06.2005
Сообщений: 944
Сказал спасибо: 25
Сказали Спасибо 174 раз(а) в 123 сообщении(ях)
|
Re: Отправка числа 0 (ноль) по уарту
Сообщение от urmlr
|
Так конечно лучше на первый взгляд. Только в этом случае, так как rx_buffer0 должен управляться как кольцевой буфер, соответственно, условие переполнения будет посложнее чем приведено в обсуждаемом фрагменте кода, поскольку rx_counter0 используемый для этой цели изначально, уже не существует. Плюс, более сложное вычисление условия переполнения будет вычисляться в ISR, так что "сокращение кода" очень сомнительно.
|
А вот тут неверно. В условии переполнения rx_counter0 вовсе не используется, для этой цели там:
if (++rx_rd_index0 == RX_BUFFER_SIZE0) { rx_rd_index0=0; }
А rx_counter0 используется только для хранения числа байт доступных для чтения (приняли байт в прерывании, положили в буфер, увеличили rx_counter0, а в гетчаре если rx_counter0 не 0, то читаем байт из буфера и возвращаем его), и уменьшается при чтении из буфера. Причем из-за такого алгоритма приходится вводить еще одну переменную, uart_data, ведь вызвав гетчар, и получив от нее 0, мы не сможем сказать, прочитали мы 0 из буфера или это признак того что в буфере нифига нет. Однако, если uart_data будет равна 1, то можно сказать, что чтение из буфера было, и полученный 0 пришел по уарт.
|
|
|
|
16.02.2011, 12:28
|
|
Почётный гражданин KAZUS.RU
Регистрация: 15.07.2009
Адрес: San Jose, USA
Сообщений: 927
Сказал спасибо: 11
Сказали Спасибо 228 раз(а) в 166 сообщении(ях)
|
Re: Отправка числа 0 (ноль) по уарту
Сообщение от Someone
|
А вот тут неверно. В условии переполнения rx_counter0 вовсе не используется, для этой цели там:
if (++rx_rd_index0 == RX_BUFFER_SIZE0) { rx_rd_index0=0; }
|
Да неужто? А я-то всю жизнь думал что это организация кольцевого буфера, вот дурак-то какой, правда?
А вот это:
Код:
|
if (++rx_counter0 == RX_BUFFER_SIZE0)
{
rx_counter0=0;
rx_buffer_overflow0=1;
}; |
- ну так просто фигня какая-то и ваще не при делах...
А может подумать сначала и код понять, а потом писать?
|
|
|
|
16.02.2011, 12:36
|
|
Почётный гражданин KAZUS.RU
Регистрация: 15.07.2009
Адрес: San Jose, USA
Сообщений: 927
Сказал спасибо: 11
Сказали Спасибо 228 раз(а) в 166 сообщении(ях)
|
Re: Отправка числа 0 (ноль) по уарту
Сообщение от Someone
|
А вот тут неверно.
|
От души советую, напишите-ка для себя формулу условия переполнения при условии неиспользования счётчика символов в кольцевом буфере. Только по настоящему, не шаляй-валяй и не от балды. Тогда и увидите.
|
|
|
|
16.02.2011, 13:01
|
|
Прописка
Регистрация: 04.08.2006
Сообщений: 181
Сказал спасибо: 1
Сказали Спасибо 31 раз(а) в 31 сообщении(ях)
|
Re: Отправка числа 0 (ноль) по уарту
Может кому-то лучше делать int вместо char, но мне больше нравится или сделать флаг, что в буфер что-то попало или проверять if (rx_counter0›0) - значит что-то есть и смотреть что там
|
|
|
|
Ваши права в разделе
|
Вы не можете создавать новые темы
Вы не можете отвечать в темах
Вы не можете прикреплять вложения
Вы не можете редактировать свои сообщения
HTML код Выкл.
|
|
|
Часовой пояс GMT +4, время: 14:20.
|
|