Страница 1 из 3
Как на С "приплюсовать" два символа?
Добавлено: Чт авг 09, 2012 19:33:48
DerMeister
Приветствую вас, уважаемые Коты!
Нужна ваша помощь чайнику в программировании.
Программить начал недавно, по сему на многое пока мозгов не хватает...
Работаю в CVAVR.
Задача такова:
Контроллер опрашивает пины. Если сработал, например, первый - шлет по UART символ Q. Если сработал второй - шлет символ W. А если сработали оба - надо слать строку QW (ну или WQ).
Вот как же мне "склеивать" эти символы в программе?
Дайте пожалуйста пример кода или ткните в место, где можно почитать об этом. А то сам найти ничего не могу...

Спасибо Вам огромное!
Re: Как на С "приплюсовать" два символа?
Добавлено: Чт авг 09, 2012 19:48:16
Kavka
Если просто символы, без "перевода строки", то и посылай их по отдельности. Они просто придут подряд. И всё.
Re: Как на С "приплюсовать" два символа?
Добавлено: Чт авг 09, 2012 19:52:53
da-nie
А если сработали оба - надо слать строку QW (ну или WQ).
Не ясна ваша проблема.

Всё, что вы пошлёте по UART'у, никак не разделяется на сообщения. Если вы сперва пошлёте Q, а потом W, то получатель их и получит в таком порядке. Даже если W придёт через час. Что же такое "Вот как же мне "склеивать" эти символы в программе?"?
Re: Как на С "приплюсовать" два символа?
Добавлено: Чт авг 09, 2012 19:54:29
DerMeister
Вот в том-то и проблема (для меня): символов всего может быть 20. И посылаться они могут, как я писал выше, в любой последовательности, в зависимости от сработавших датчиков. Гадость в том, что сперва должны опрашиваться все 20 датчиков, а уж потом зараз отсылаться строка символов. Т.е. сработавшие символы надо как бы склеиль в строку и отослать.
Вот как так сделать я не могу сообразить...
Re: Как на С "приплюсовать" два символа?
Добавлено: Чт авг 09, 2012 20:01:24
da-nie
Т.е. сработавшие символы надо как бы склеиль в строку и отослать.
Только зачем вам вклеивать? Их всё равно примет абонент ПОСЛЕДОВАТЕЛЬНО в порядке передачи.
Ну сделайте тогда так:
if (сработал_датчик1) послать символ 1
if (сработал_датчик2) послать символ 2
...
if (сработал_датчикN) послать символ N
послать символ '\r'
послать символ '\n'
Или через массив:
unsigned char sensor[100];
int sensor_index=0;
if (сработал датчик1)
{
sensor[sensor_index]='Q';
sensor_index++;
}
...
if (сработал датчикN)
{
sensor[sensor_index]='W';
sensor_index++;
}
//передаём строку
sensor[sensor_index]='\r';
sensor_index++;
sensor[sensor_index]='\n';
sensor_index++;
for(int n=0;n<sensor_index;n++)
{
//отправляете символ из sensor[n] по UART.
}
Вот и всё.
Только, конечно, проверку датчиков лучше в цикл засунуть.
Re: Как на С "приплюсовать" два символа?
Добавлено: Чт авг 09, 2012 20:18:05
DerMeister
Опять же они будут слаться последовательно. Хотя с массивом - это идея хорошая! Спасибо Вам!
Просто я боюсь что могу упустить срабатывание датчика пока буду слать. Датчики могут срабатывать "одновременно", точнее с разницей в несколько микросекунд. И пока я буду слать упущу срабатывание. Или я не прав?
А сколько тактов занимает отправка символа, очистка буфера, выставление флага и т. д. Через сколько вобщем можно будет проверять следующий датчик после отправки?
Re: Как на С "приплюсовать" два символа?
Добавлено: Чт авг 09, 2012 21:04:55
da-nie
Просто я боюсь что могу упустить срабатывание датчика пока буду слать.
Тогда используйте прерывания. Отправляйте символ по UART, а момент окончания передачи фиксируйте по прерыванию.
Re: Как на С "приплюсовать" два символа?
Добавлено: Чт авг 09, 2012 21:16:31
DerMeister
Тогда я еще больше времени потеряю: пока зашел в прерывание, пока вышел...
Я так понимаю С не умеет делать как я хочу...
Наверно надо тогда создать кучу (по количеству датчиков) переменных типа bit, записывать единовременно в них состояния датчиков на момент опроса,. а потом уж те переменные в которых 1 - датчик сработал, сопостовлять с символом и слать их по очереди, как и советовали.
Мне кажется это единственное решение...
Re: Как на С "приплюсовать" два символа?
Добавлено: Чт авг 09, 2012 21:30:45
Jack_A
Ну вот - достаточно было правильно сформулировать вопрос, как ответ пришел сам собой

Хотя решения по существу и нет

По любому, частота опроса датчиков не может быть выше, чем частота посылок по UART , поэтому если датчик может "мигнуть" на пару микросекунд, то сигнал может быть пропущен.
Re: Как на С "приплюсовать" два символа?
Добавлено: Чт авг 09, 2012 21:35:05
da-nie
Тогда я еще больше времени потеряю: пока зашел в прерывание, пока вышел...
Вы, если не секрет, что делаете, если у вас микроконтроллер на мегагерцовой и выше частоте не может потратить десяток тактов (т.е. микросекунды!) на прерывания?
Наверно надо тогда создать кучу (по количеству датчиков) переменных типа bit, записывать единовременно в них состояния датчиков на момент опроса,. а потом уж те переменные в которых 1 - датчик сработал, сопоставлять с символом и слать их по очереди, как и советовали.
Опять непонятно, зачем вам это? Вы всё равно на время пересылки за датчиками следить не будете. У вас между опросом датчиков будет задержка в несколько миллисекунд (зависит от скорости COM-порта).
Ну вот - достаточно было правильно сформулировать вопрос, как ответ пришел сам собой
Э, нет. Что хотят сделать до конца всё равно не понятно. Пока что хотят не пропустить ни одного датчика и в то же время делать большие задержки между опросом на передачу всего массива сработавших датчиков. Я предлагал в прерывании UART определять момент завершения передачи и передавать следующий символ, если передача требуется.
По любому, частота опроса датчиков не может быть выше, чем частота посылок по UART , поэтому если датчик может "мигнуть" на пару микросекунд, то сигнал может быть пропущен.
Можно считать, что если за время передачи символа датчик сменил своё состояние на обратное, а потом снова вернулся в начальное на момент начала передачи, то он и не менялся.

Re: Как на С "приплюсовать" два символа?
Добавлено: Чт авг 09, 2012 21:45:02
Goodefine
da-nie писал(а):
По любому, частота опроса датчиков не может быть выше, чем частота посылок по UART , поэтому если датчик может "мигнуть" на пару микросекунд, то сигнал может быть пропущен.
Можно считать, что если за время передачи символа датчик сменил своё состояние на обратное, а потом снова вернулся в начальное на момент начала передачи, то он и не менялся.

Пять баллов!

Re: Как на С "приплюсовать" два символа?
Добавлено: Чт авг 09, 2012 21:45:58
Goldsmith
DerMeister писал(а):Просто я боюсь что могу упустить срабатывание датчика пока буду слать. Датчики могут срабатывать "одновременно", точнее с разницей в несколько микросекунд. И пока я буду слать упущу срабатывание. Или я не прав?
Абсолютно правы, и боитесь совершенно правильно.
Чтобы не терять данные, нужно несколько усложнить программу добавлением кольцевого буфера FIFO. Программа обработки прерывания от датчика заносит соответствующую литеру в конец буфера. Программа обработки прерывания по готовности UART выводит литеру из начала буфера.
Конечно, и в такой схеме буфер может переполниться, если размер его невелик, данные поступают слишком быстро, а уходят слишком медленно. Нужно правильно все рассчитать, чтобы и потерь данных не было, и драгоценную память на буфер не тратить попусту.
Подробнее посмотрите в Bruce Powel Douglass, "Real-Time Design Patterns: Robust Scalable Architecture for Real-Time Systems". Почти готовые к употреблению фрагменты кода найдете в Jean J. Labrosse, "Embedded Systems Building Blocks. Complete and Ready-to-Use Modules in C".
DerMeister писал(а):Я так понимаю С не умеет делать как я хочу...
C вообще
никак не умеет. Умеет написанная на нем программа. А уж что именно она сумеет, зависит лишь от Вашего умения и старания.
Re: Как на С "приплюсовать" два символа?
Добавлено: Чт авг 09, 2012 22:09:08
DerMeister
Ну да, наверно я не совсем точно сформулировал, вернее не до конца. Прошу прощения
Опять непонятно, зачем вам это? Вы всё равно на время пересылки за датчиками следить не будете.
Датчики срабатывают как бы пакетно что ли. То есть в один момент времени может сработать сразу несколько, с разницей в несколько МИКРОсекунд, а после того как это произошло не один не может сработать раньше чем через 10 МИЛИсекунд. Вот поэтому мне и нужно успеть просканировать все дачтики сразу и только потом - в этот перерыв в 10 милисекунд - отсылать состояния этих датчиков.
Поэтому слать первый же сработавший сразу нельзя - можно пропустить следующий сработавший.
А если сперва записать состояние каждого в свою переменную (это всего по одному такту на датчик: a=PINB.0, b=PINB.1....), то потом, в эти десять милисекунд, мне конечно за глаза хватит чтоб отправить сработавшие.
Вот как-то так.
Уж не знаю понятно ли объяснил или нет...
Чтобы не терять данные, нужно несколько усложнить программу добавлением кольцевого буфера FIFO
Да, я читал про это, так и нужно делать чтоб было "красиво". Но честно говоря, до конца пока не разобрался. Я ведь еще только учусь...
Да и в данном случае можно обойтись и без него, благодаря 10и милисекундной задержке.
И спасибо Вам, что подсказали куда заглянуть по поводу буфера!
Re: Как на С "приплюсовать" два символа?
Добавлено: Чт авг 09, 2012 22:34:44
Аlex
Поэтому слать первый же сработавший сразу нельзя - можно пропустить следующий сработавший.
Интересно, а как Вы собираетесь узнавать сработает ли скоро следующий датчик или нет, и как скоро он сработает ? Это же неизвестно. Когда же его слать, если не сразу ? И когда наступит это "не сразу" ?
Делайте тогда посылку буфера через определённый промежуток времени, а буфер заполняйте по мере срабатывания датчиков.
Кстати, а датчиков сколько ? Может хватит внешних прерываний ?
Re: Как на С "приплюсовать" два символа?
Добавлено: Чт авг 09, 2012 22:45:22
DerMeister
Интересно, а как Вы собираетесь узнавать сработает ли скоро следующий датчик или нет
А зачем мне знать? Я в цикле проверки датчиков записываю состояние каждого в свою переменную. После скана всех (кстати 20и, но это пока) датчиков смотрю в эти переменные и те из них, где стоит 1 - датчик сработал значит - уже отсылаю по UART. Дальше опять сканируюю и т. д. А слать я буду только если сработает хоть один датчик, и у меня появится 10 милисекунд на отсылку.
Мне кажется это оптимальный вариант. Поправьте если я неправ.
Re: Как на С "приплюсовать" два символа?
Добавлено: Чт авг 09, 2012 23:21:14
Аlex
Т.е. датчики по любому срабатывают одновременно, только с небольшой задержкой ? Или могут срабатывать какой угодно когда угодно ?
Re: Как на С "приплюсовать" два символа?
Добавлено: Чт авг 09, 2012 23:27:42
DerMeister
чуть выше постом я описал алгоритм:
Датчики срабатывают как бы пакетно что ли. То есть в один момент времени может сработать сразу несколько, с разницей в несколько МИКРОсекунд, а после того как это произошло не один не может сработать раньше чем через 10 МИЛИсекунд. Вот поэтому мне и нужно успеть просканировать все дачтики сразу и только потом - в этот перерыв в 10 милисекунд - отсылать состояния этих датчиков.
Re: Как на С "приплюсовать" два символа?
Добавлено: Чт авг 09, 2012 23:31:06
zero648
DerMeister, какой МК вы хотите использовать для этой цели, какая частота кварца? И куда все это будет посылаться?
Re: Как на С "приплюсовать" два символа?
Добавлено: Чт авг 09, 2012 23:35:41
Аlex
Ну тогда вообще всё просто. Делайте внешнюю схему "ИЛИ" и заводите на одно внешнее прерывание, а в прерывании уже проверяйте все входы, обновляя буфер. Если нужно перед опросом немного задержаться, то делаем небольшую задержечку (можете на таймере, если обработчик держать - критично), а затем уже проверку.
Кстати, а срабатывают они на сколько, по времени ?
Re: Как на С "приплюсовать" два символа?
Добавлено: Чт авг 09, 2012 23:55:26
DerMeister
Это какую же микруху ИЛИ надо на 20 и более датчиков? И потом, хотелось бы с минимумом внешней обвязки т. к. во-первых: зачем вешать дополнительно детали если с этим один МК может справиться, во-вторых: корпус для устройства уже сделан и размеры его весьма критичны к сожалению. Запихнуть туда еще что-то будет проблематично...
Время срабатывания по идее от 1,5 до 2 микросекунд.