Вопросы по С/С++ (СИ)

Если ваш вопрос не влез ни в одну из вышеперечисленных тем, вам сюда.
Ответить
Вымогатель припоя
Аватара пользователя
Сообщения: 535
Зарегистрирован: Вт авг 28, 2012 22:21:33

Сообщение menzoda »

Kavka писал(а):он и не должен быть равен нулю.
Не понял. Кто не должен? Что не должен? Если про PINB0, то он объявлен именно как #define PINB0 0

А не понравилось вот это:
Мikа писал(а):Берем число 0b00000000 (8 знаков, т.к. в PORTB 8 ног) и нулевой бит числа устанавливаем в 1.
Потому что мы не берем ноль, а берем единицу, и не устанавливаем нулевой бит, а сдвигаем на число, скрывающееся за PINB0. Ведь человек хочет разобраться, что там происходит, вот я и говорю как есть.
Реклама
Мудрый кот
Аватара пользователя
Сообщения: 1810
Зарегистрирован: Чт июн 10, 2010 08:55:35
Откуда: Сибирские Афины

Сообщение Kavka »

Аааа... Вон про что вы.
Ну не понял с ходу. :) Главное разобрались! :tea:
Когда уже ничего не помогает - прочтите, наконец, инструкцию.
Лучший оптимизатор находится у вас между ушей. (Майкл Абраш, программист Quake и QuakeII)
Избыток информации ведёт к оскудению души - Леонтьев А. (сказано в 1965 г.)
Реклама
Открыл глаза
Аватара пользователя
Сообщения: 42
Зарегистрирован: Пн июл 04, 2011 13:42:43
Откуда: Тула

Сообщение Dan Swano »

Уважаемые коты! Подскажите, может уже было где-то, как представить число на Си в виде десятичной дроби для вывода на индикатор без использования функции printf, чтобы не занимать лишнюю память? :dont_know: Есть значение, выдаваемое АЦП (0-1023), хочу преобразовать его к напряжению 0-5 В с точностью 2 знака после запятой. МК Atmega32, AVR Studio 4, AVR-GCC из WinAVR
Контактная информация:
Сверлит текстолит когтями
Аватара пользователя
Сообщения: 1163
Зарегистрирован: Ср янв 05, 2011 16:25:15

Сообщение ChipKiller »

Dan Swano писал(а):как представить число на Си в виде десятичной дроби для вывода на индикатор без использования функции printf
.. можно так
Реклама
Эиком - электронные компоненты и радиодетали
Опытный кот
Аватара пользователя
Сообщения: 882
Зарегистрирован: Ср фев 22, 2012 01:25:21

Сообщение shads »

Dan Swano писал(а):как представить число на Си в виде десятичной дроби для вывода на индикатор без использования функции printf
.. и так
Реклама
Друг Кота
Аватара пользователя
Сообщения: 6330
Зарегистрирован: Вт апр 24, 2007 07:45:40
Откуда: Minsk

Сообщение Jack_A »

Нужно учитывать еще величину опорного напряжения, потому что АЦП выдает результат в квантах относительно опоры, а не а абсолютных В/мВ .
Реклама
Открыл глаза
Аватара пользователя
Сообщения: 42
Зарегистрирован: Пн июл 04, 2011 13:42:43
Откуда: Тула

Сообщение Dan Swano »

Спасибо, это мне тоже пригодится. Но тут вывод на семисегментники, а я хочу вывести это число на LCD 16x2, для этого число, например, типа int хочу разложить в два байта unsigned char, по полбайта на цифру, например, а затем сделать lcd_putchar(), сдвинуть на 4 бита и снова вывести
Контактная информация:
Мудрый кот
Аватара пользователя
Сообщения: 1810
Зарегистрирован: Чт июн 10, 2010 08:55:35
Откуда: Сибирские Афины

Сообщение Kavka »

Dan Swano писал(а):int хочу разложить в два байта unsigned char, по полбайта на цифру
Это вариант хранения. Можно и один байт на цифру. А вообще это называется BCD-представление числа.
Dan Swano писал(а):Но тут вывод на семисегментники, а я хочу вывести это число на LCD 16x2
Главное получить из числа цифры, а куда их потом выводить, на семисегментники, LCD, отправлять через UART - отдельное дело, и к переводу числа в BCD никакого отношение не имеет.
Когда уже ничего не помогает - прочтите, наконец, инструкцию.
Лучший оптимизатор находится у вас между ушей. (Майкл Абраш, программист Quake и QuakeII)
Избыток информации ведёт к оскудению души - Леонтьев А. (сказано в 1965 г.)
Модератор
Аватара пользователя
Сообщения: 4614
Зарегистрирован: Чт мар 18, 2010 23:09:57
Откуда: Планета Земля

Сообщение Аlex »

без использования функции printf
int хочу разложить в два байта unsigned char, по полбайта на цифру
А причём тут printf ? Деление с остатком не пойдёт ?
Контактная информация:
Встал на лапы
Аватара пользователя
Сообщения: 111
Зарегистрирован: Вт окт 05, 2010 08:11:41
Откуда: г. Петрозаводск

Сообщение ciph »

Не подскажите, как решить вопрос..
Вводная: attiny13, частота 9,6 МГц, шим

int main(void)
{
DDRB=000001;

// быстрый шим, дрыгает ножку OC0A
TCCR0A=(1<<COM0A1)
|(1<<COM0A0)
|(1<<WGM01)
|(1<<WGM00);

// делитель на 64
TCCR0B=(0<<WGM02)
|(0<<CS02)
|(1<<CS01)
|(1<<CS00);

OCR0A=100;

for (;;)
{
}
return 0;
}

Получается частота шим 9600000/(256*64)=585Гц, а на ножне почему-то 73Гц. Почему?
Друг Кота
Сообщения: 3956
Зарегистрирован: Ср окт 14, 2009 10:37:49
Откуда: Украина

Сообщение Soir »

ciph писал(а):Получается частота шим 9600000/(256*64)=585Гц, а на ножне почему-то 73Гц. Почему?
А FUSE CKDIV8?
Говорящий с текстолитом
Аватара пользователя
Сообщения: 1518
Зарегистрирован: Пт дек 28, 2012 21:56:46
Откуда: St. Petersburg

Сообщение blackx »

ciph,
Atmel Corporation писал(а):The device is shipped with CKSEL = “10”, SUT = “10”, and CKDIV8 programmed. The default
clock source setting is therefore the Internal RC Oscillator running at 9.6 MHz with longest startup
time and an initial system clock prescaling of 8.
Изображение only pure true norwegian blackx Изображение
Встал на лапы
Аватара пользователя
Сообщения: 111
Зарегистрирован: Вт окт 05, 2010 08:11:41
Откуда: г. Петрозаводск

Сообщение ciph »

Soir писал(а):
ciph писал(а):Получается частота шим 9600000/(256*64)=585Гц, а на ножне почему-то 73Гц. Почему?
А FUSE CKDIV8?
:shock: ужос, откуда он взялся?! Спасибо огромное! :beer:
Опытный кот
Аватара пользователя
Сообщения: 882
Зарегистрирован: Ср фев 22, 2012 01:25:21

Сообщение shads »

Раз уж тема про tiny13 пошла.....
Звиняюсь шо не по Си теме, но помоему вумные мужи сюда в первую очередь заглядывают....

Дано: tiny13A, внешнее прерывание по изменению уровня на PCINT0..
Как железно узнать от какого изменения произошло прерывание?
Я пока самой программой прерывания анализирую уровень... НО проблема в том, что иногда изменение уровня не чистое, и программа может считать уровень не соответствующий тому который вызвал прерывание, соответственно не устойчиво работает алгоритм.....
Мудрый кот
Аватара пользователя
Сообщения: 1810
Зарегистрирован: Чт июн 10, 2010 08:55:35
Откуда: Сибирские Афины

Сообщение Kavka »

Вроде никак. Только считывать pinb сразу при входе в прерывание.
3 такта от изменения сигнала до установки флага на прерывание. Плюс 4-6(7) тактов на вход в прерывание. Плюс 2 такта rjmp. (Возврат по reti ещё 4 такта.)
И это без учёта сохранения/восстановления sreg и других регистров.
Чтобы изменение сигнала было поймано импульс должен быть больше 1 периода тактового сигнала. Но в таком случае в прерывании не поймать правильное значение.
Чтобы надёжно поймать правильное значение надо чтобы импульс был минимум 12 тактов (если первой же командой после rjmp считывать pinb).
Но это импульс. А если надо оба фронта нормально обрабатывать, то надо чтобы полное время обработки прерывания в худшем случае было менее половины периода отслеживаемого сигнала.

Сам сейчас переписываю прогу с Си на асм. Так как реакция моего алгоритма на Pin Change на Си при 9.6МГц получается хуже 100КГц
Когда уже ничего не помогает - прочтите, наконец, инструкцию.
Лучший оптимизатор находится у вас между ушей. (Майкл Абраш, программист Quake и QuakeII)
Избыток информации ведёт к оскудению души - Леонтьев А. (сказано в 1965 г.)
Сверлит текстолит когтями
Аватара пользователя
Сообщения: 1163
Зарегистрирован: Ср янв 05, 2011 16:25:15

Сообщение ChipKiller »

shads писал(а):Как железно узнать от какого изменения произошло прерывание?
... если нужно железно, то "железно" и сделать (RESETы триггеров соединяем ) :)
Изображение
правда "лишняя" мелкосхема будет покрупнее тиньки
Вложения
ext_irq.JPG
(9.58 КБ) 807 скачиваний
Мудрый кот
Аватара пользователя
Сообщения: 1810
Зарегистрирован: Чт июн 10, 2010 08:55:35
Откуда: Сибирские Афины

Сообщение Kavka »

ChipKiller, в тиньке pin change, т.е. по изменению сигнала, т.е. по любому из фронтов срабатывает.
По вашему методу это два тригера + один 2или на одну линию получается, что-ли. :)
Когда уже ничего не помогает - прочтите, наконец, инструкцию.
Лучший оптимизатор находится у вас между ушей. (Майкл Абраш, программист Quake и QuakeII)
Избыток информации ведёт к оскудению души - Леонтьев А. (сказано в 1965 г.)
Опытный кот
Аватара пользователя
Сообщения: 882
Зарегистрирован: Ср фев 22, 2012 01:25:21

Сообщение shads »

Kavka писал(а):Вроде никак.
Тоже излистал мануал по внешним прерываниям, ничего не нашел....

У себя решил проблему так: (Речь идет о декодировании MANCHESTER сигнала)
Изначально было: после сработки внешнего прерывания (А) запрещаем внешние прерывания на время (B) и сразу определяем уровень на выводе PIN, потом таймером отсчитываем промежуток времени (B), опять разрешаем внешние прерывания (C) и ждем нового внешнего прерывания. После его поступления, анализируем время (D) если оно в допустимых рамках, продолжаем по кругу прием битов данных.

Изображение

Но как я уже сказал, иногда чтение сразу после прерывания, давало не верное значение, т.к. анализируемый сигнал это выпрямленная ВЧ несущая, и иногда фронты не очень крутые, пролазит 125КГц, поэтому иногда перебоило.....

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

Результат 100% меня устроил.
Kavka писал(а):Сам сейчас переписываю прогу с Си на асм. Так как реакция моего алгоритма на Pin Change на Си при 9.6МГц получается хуже 100КГц
Кстати бешенный вариант, писать основную прогу на Си, а скоростное прерывание на асме.... Я просто в облаках от результата..... Сама программа читабельна (Си), а прерывание как капля в море по размеру (асм).

вот что получилось.....
Вложения
RFID_diagram.png
(24.66 КБ) 758 скачиваний
Родился
Сообщения: 5
Зарегистрирован: Пт сен 23, 2011 11:00:09

Сообщение char »

Всем привет.

Вопрос 1.
В AVRStudio 4.0 структура, объявленная подобным образом, никаких вопросов у компилятора не вызвала :

Код: Выделить всё

#pragma pack(1)
typedef struct{
	unsigned char  Query[4];   
	unsigned char  Command;    
	unsigned char  Param;     
}REQUEST;
Если я правильно понимаю, то директива pragma здесь сообщает компилятору, что поля структуры должны быть выравнены
на 1 байт, верно?

В то же время в AVRStudio 6.1 такое объявление структуры не годится, компилятор выдает предупреждение о том, что
директива pragma проигнорирована. Я изменил код вот так :

Код: Выделить всё

//#pragma pack(1)
typedef struct{
	unsigned char  Query[4];   
	unsigned char  Command;    
	unsigned char  Param;      
}__attribute__((packed)) REQUEST;

Правильно ли я сделал?



Вопрос 2.

Есть указатель на вышеописанную структуру :
REQUEST *req;

Правильно ли я понимаю, что в этой строке :

Код: Выделить всё

*((uchar *)req + s) = Function_2( *((uchar *)req + s) , (*((uchar *)req )) + s);
1) *((uchar *)req + s) - означает, что значению по адресу req+s присваивается то, что вернет Function_2?

2)(*((uchar *)req )) + s - означает, что значение по адресу req суммируется с s?
Сверлит текстолит когтями
Аватара пользователя
Сообщения: 1163
Зарегистрирован: Ср янв 05, 2011 16:25:15

Сообщение ChipKiller »

Kavka писал(а):По вашему методу это два тригера...
... просто немного не понял в чем проблема у shads_а - думал он ловит "иголки", которые постоянно дергают прерывание... триггер ловит первый только первый "0", а клок на reset переводит его в начальное состояние.
char писал(а):Правильно ли я понимаю, что в этой строке
... правильно, но "вольное" обращение с указателями может натворить дел ... используя req + s можно легко перескочить за рамки структуры ( например s=6) - для обращения к полям лучше использовать req.x или req->x, где x одно из полей
Ответить

Вернуться в «Разные вопросы по МК»