Приветствую вас, уважаемые Коты! Нужна ваша помощь чайнику в программировании. Программить начал недавно, по сему на многое пока мозгов не хватает... Работаю в CVAVR. Задача такова: Контроллер опрашивает пины. Если сработал, например, первый - шлет по UART символ Q. Если сработал второй - шлет символ W. А если сработали оба - надо слать строку QW (ну или WQ). Вот как же мне "склеивать" эти символы в программе? Дайте пожалуйста пример кода или ткните в место, где можно почитать об этом. А то сам найти ничего не могу... Спасибо Вам огромное!
Если просто символы, без "перевода строки", то и посылай их по отдельности. Они просто придут подряд. И всё.
_________________ Когда уже ничего не помогает - прочтите, наконец, инструкцию. Лучший оптимизатор находится у вас между ушей. (Майкл Абраш, программист Quake и QuakeII) Избыток информации ведёт к оскудению души - Леонтьев А. (сказано в 1965 г.)
А если сработали оба - надо слать строку QW (ну или WQ).
Не ясна ваша проблема. Всё, что вы пошлёте по UART'у, никак не разделяется на сообщения. Если вы сперва пошлёте Q, а потом W, то получатель их и получит в таком порядке. Даже если W придёт через час. Что же такое "Вот как же мне "склеивать" эти символы в программе?"?
Вот в том-то и проблема (для меня): символов всего может быть 20. И посылаться они могут, как я писал выше, в любой последовательности, в зависимости от сработавших датчиков. Гадость в том, что сперва должны опрашиваться все 20 датчиков, а уж потом зараз отсылаться строка символов. Т.е. сработавшие символы надо как бы склеиль в строку и отослать. Вот как так сделать я не могу сообразить...
Т.е. сработавшие символы надо как бы склеиль в строку и отослать.
Только зачем вам вклеивать? Их всё равно примет абонент ПОСЛЕДОВАТЕЛЬНО в порядке передачи. Ну сделайте тогда так:
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. } Вот и всё.
Только, конечно, проверку датчиков лучше в цикл засунуть.
Опять же они будут слаться последовательно. Хотя с массивом - это идея хорошая! Спасибо Вам! Просто я боюсь что могу упустить срабатывание датчика пока буду слать. Датчики могут срабатывать "одновременно", точнее с разницей в несколько микросекунд. И пока я буду слать упущу срабатывание. Или я не прав? А сколько тактов занимает отправка символа, очистка буфера, выставление флага и т. д. Через сколько вобщем можно будет проверять следующий датчик после отправки?
Тогда я еще больше времени потеряю: пока зашел в прерывание, пока вышел... Я так понимаю С не умеет делать как я хочу... Наверно надо тогда создать кучу (по количеству датчиков) переменных типа bit, записывать единовременно в них состояния датчиков на момент опроса,. а потом уж те переменные в которых 1 - датчик сработал, сопостовлять с символом и слать их по очереди, как и советовали. Мне кажется это единственное решение...
Ну вот - достаточно было правильно сформулировать вопрос, как ответ пришел сам собой Хотя решения по существу и нет По любому, частота опроса датчиков не может быть выше, чем частота посылок по UART , поэтому если датчик может "мигнуть" на пару микросекунд, то сигнал может быть пропущен.
Тогда я еще больше времени потеряю: пока зашел в прерывание, пока вышел...
Вы, если не секрет, что делаете, если у вас микроконтроллер на мегагерцовой и выше частоте не может потратить десяток тактов (т.е. микросекунды!) на прерывания?
Цитата:
Наверно надо тогда создать кучу (по количеству датчиков) переменных типа bit, записывать единовременно в них состояния датчиков на момент опроса,. а потом уж те переменные в которых 1 - датчик сработал, сопоставлять с символом и слать их по очереди, как и советовали.
Опять непонятно, зачем вам это? Вы всё равно на время пересылки за датчиками следить не будете. У вас между опросом датчиков будет задержка в несколько миллисекунд (зависит от скорости COM-порта).
Цитата:
Ну вот - достаточно было правильно сформулировать вопрос, как ответ пришел сам собой
Э, нет. Что хотят сделать до конца всё равно не понятно. Пока что хотят не пропустить ни одного датчика и в то же время делать большие задержки между опросом на передачу всего массива сработавших датчиков. Я предлагал в прерывании UART определять момент завершения передачи и передавать следующий символ, если передача требуется.
Цитата:
По любому, частота опроса датчиков не может быть выше, чем частота посылок по UART , поэтому если датчик может "мигнуть" на пару микросекунд, то сигнал может быть пропущен.
Можно считать, что если за время передачи символа датчик сменил своё состояние на обратное, а потом снова вернулся в начальное на момент начала передачи, то он и не менялся.
По любому, частота опроса датчиков не может быть выше, чем частота посылок по UART , поэтому если датчик может "мигнуть" на пару микросекунд, то сигнал может быть пропущен.
Можно считать, что если за время передачи символа датчик сменил своё состояние на обратное, а потом снова вернулся в начальное на момент начала передачи, то он и не менялся.
Пять баллов!
_________________ Любой, заслуживающий внимания, опыт приобретается себе в убыток...
Просто я боюсь что могу упустить срабатывание датчика пока буду слать. Датчики могут срабатывать "одновременно", точнее с разницей в несколько микросекунд. И пока я буду слать упущу срабатывание. Или я не прав?
Абсолютно правы, и боитесь совершенно правильно.
Чтобы не терять данные, нужно несколько усложнить программу добавлением кольцевого буфера 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 вообще никак не умеет. Умеет написанная на нем программа. А уж что именно она сумеет, зависит лишь от Вашего умения и старания.
_________________ Любой дурак может писать код. Настоящий профессионал - это тот, кто способен постоянно создавать продукт высокого качества, укладываясь при этом в бюджет. J. Ganssle
Ну да, наверно я не совсем точно сформулировал, вернее не до конца. Прошу прощения
Цитата:
Опять непонятно, зачем вам это? Вы всё равно на время пересылки за датчиками следить не будете.
Датчики срабатывают как бы пакетно что ли. То есть в один момент времени может сработать сразу несколько, с разницей в несколько МИКРОсекунд, а после того как это произошло не один не может сработать раньше чем через 10 МИЛИсекунд. Вот поэтому мне и нужно успеть просканировать все дачтики сразу и только потом - в этот перерыв в 10 милисекунд - отсылать состояния этих датчиков. Поэтому слать первый же сработавший сразу нельзя - можно пропустить следующий сработавший. А если сперва записать состояние каждого в свою переменную (это всего по одному такту на датчик: a=PINB.0, b=PINB.1....), то потом, в эти десять милисекунд, мне конечно за глаза хватит чтоб отправить сработавшие. Вот как-то так. Уж не знаю понятно ли объяснил или нет...
Цитата:
Чтобы не терять данные, нужно несколько усложнить программу добавлением кольцевого буфера FIFO
Да, я читал про это, так и нужно делать чтоб было "красиво". Но честно говоря, до конца пока не разобрался. Я ведь еще только учусь... Да и в данном случае можно обойтись и без него, благодаря 10и милисекундной задержке. И спасибо Вам, что подсказали куда заглянуть по поводу буфера!
Заголовок сообщения: Re: Как на С "приплюсовать" два символа?
Добавлено: Чт авг 09, 2012 22:34:44
Модератор
Карма: 90
Рейтинг сообщений: 1435
Зарегистрирован: Чт мар 18, 2010 23:09:57 Сообщений: 4603 Откуда: Планета Земля
Рейтинг сообщения:0 Медали: 1
Цитата:
Поэтому слать первый же сработавший сразу нельзя - можно пропустить следующий сработавший.
Интересно, а как Вы собираетесь узнавать сработает ли скоро следующий датчик или нет, и как скоро он сработает ? Это же неизвестно. Когда же его слать, если не сразу ? И когда наступит это "не сразу" ? Делайте тогда посылку буфера через определённый промежуток времени, а буфер заполняйте по мере срабатывания датчиков. Кстати, а датчиков сколько ? Может хватит внешних прерываний ?
Интересно, а как Вы собираетесь узнавать сработает ли скоро следующий датчик или нет
А зачем мне знать? Я в цикле проверки датчиков записываю состояние каждого в свою переменную. После скана всех (кстати 20и, но это пока) датчиков смотрю в эти переменные и те из них, где стоит 1 - датчик сработал значит - уже отсылаю по UART. Дальше опять сканируюю и т. д. А слать я буду только если сработает хоть один датчик, и у меня появится 10 милисекунд на отсылку. Мне кажется это оптимальный вариант. Поправьте если я неправ.
чуть выше постом я описал алгоритм: Датчики срабатывают как бы пакетно что ли. То есть в один момент времени может сработать сразу несколько, с разницей в несколько МИКРОсекунд, а после того как это произошло не один не может сработать раньше чем через 10 МИЛИсекунд. Вот поэтому мне и нужно успеть просканировать все дачтики сразу и только потом - в этот перерыв в 10 милисекунд - отсылать состояния этих датчиков.
Заголовок сообщения: Re: Как на С "приплюсовать" два символа?
Добавлено: Чт авг 09, 2012 23:35:41
Модератор
Карма: 90
Рейтинг сообщений: 1435
Зарегистрирован: Чт мар 18, 2010 23:09:57 Сообщений: 4603 Откуда: Планета Земля
Рейтинг сообщения:0 Медали: 1
Ну тогда вообще всё просто. Делайте внешнюю схему "ИЛИ" и заводите на одно внешнее прерывание, а в прерывании уже проверяйте все входы, обновляя буфер. Если нужно перед опросом немного задержаться, то делаем небольшую задержечку (можете на таймере, если обработчик держать - критично), а затем уже проверку. Кстати, а срабатывают они на сколько, по времени ?
Это какую же микруху ИЛИ надо на 20 и более датчиков? И потом, хотелось бы с минимумом внешней обвязки т. к. во-первых: зачем вешать дополнительно детали если с этим один МК может справиться, во-вторых: корпус для устройства уже сделан и размеры его весьма критичны к сожалению. Запихнуть туда еще что-то будет проблематично... Время срабатывания по идее от 1,5 до 2 микросекунд.
Сейчас этот форум просматривают: нет зарегистрированных пользователей и гости: 30
Вы не можете начинать темы Вы не можете отвечать на сообщения Вы не можете редактировать свои сообщения Вы не можете удалять свои сообщения Вы не можете добавлять вложения