Страница 41 из 421
Добавлено: Ср май 06, 2009 20:43:01
dm211
С вашими подсказками вроде разобрался,завтра посмотрим-будет ли работать,с кавычками так-
С первым вопросом так-
Код: Выделить всё
char priem[50];
char x;
//собираем символы со входа UART
while(getchar()!='\n'){x++; priem[x]=getchar();}
//если слово на входе=RING,то делаем что-то
if(priem=="RING")PORTB.0=1;
Добавлено: Ср май 06, 2009 22:05:44
Yellow Tiger
В Си нет строковых типов и операций с ними, так что, без строковых функций все же не обойтись.
Добавлено: Чт май 07, 2009 15:33:37
dm211
Пока не разобрался с этими строковыми функциями, сделал так-
Код: Выделить всё
if(getchar()=='R' && getchar()=='I' && getchar()=='N' && getchar()=='G')
кстати работает нормально, выбирает из множества символов только "RING", и то когда они в такой последовательности и между этими буквами нет других символов. Может быть это и лучше, хоть и не очень красиво.
Добавлено: Чт май 07, 2009 16:09:09
ikarab
Я бы еще скобочек добавил.
Добавлено: Чт май 07, 2009 17:05:53
dm211
Куда добавить скобочек? В протеусе это работает, с терминальной программы на схему в протеусе отправляю через COM2-COM1.
Добавлено: Чт май 07, 2009 18:43:04
Yellow Tiger
dm211 писал(а):Пока не разобрался с этими строковыми функциями, ...
Да что там разбираться-то

глянь на функции сравнения строк, и всех делов-то.
dm211 писал(а):Код: Выделить всё
if(getchar()=='R' && getchar()=='I' && getchar()=='N' && getchar()=='G')
...работает нормально, ... Может быть это и лучше,
Нет, не лучше - при таком решении будет исключена возможность ветвления по пришедшей команде, что-то типа такого (это
псевдокод):
Код: Выделить всё
s = gets(...);
switch ( *s ) {
case "RING" : SayNobodysHome();
break;
case "NOCK" : NockBack();
break;
case "SCRATCH" : SayHiHunny();
break;
otherwise:
break'em_all_twice(); // fff..ck!
}
Добавлено: Сб май 09, 2009 19:22:04
1995kenny
Расскажите плиз про битовые поля - как использовать, как вводить инфу в них и выводить(выводить побитно).
В нете нашел только
такое. Другого нигде нету

Добавлено: Сб май 09, 2009 20:25:38
Yellow Tiger
В дополнение к сказанному на CIT-форуме, можно еще почитать хэлп к любимому в этой ветке компилятору. Раздел - "Bit Variables".
Добавлено: Сб май 09, 2009 22:41:10
ARV
1995kenny писал(а):Расскажите плиз про битовые поля - как использовать, как вводить инфу в них и выводить(выводить побитно).
В нете нашел только
такое. Другого нигде нету

кто бы мне рассказал, зачем практически эти битовые поля нужны, кроме как компактная (условно) форма хранения булевых переменных? не вижу абсолютно никаких преимуществ перед манипуляцией с битами напрямую...
Добавлено: Вс май 10, 2009 01:17:48
Yellow Tiger
ARV писал(а):кто бы мне рассказал, зачем практически эти битовые поля нужны, кроме как компактная (условно) форма хранения булевых переменных? не вижу абсолютно никаких преимуществ перед манипуляцией с битами напрямую...
Ну, что Вы,
ARV, не так уж они и бесполезны, эти битовые поля...
Если бы битовые поля могли иметь только один размер - в 1 бит, то действительно, разницы с манипуляцией битами напрямую не было бы никакой, или точнее -
она была бы невелика, но поля с длиной больше 1 бита уже можно использовать более широко.
Пусть, к примеру, есть некий девайс, которым управляют, записывая в его регистр команд два байта (к примеру: LSB,MSB) и считывая его состояние из регистра статуса. Пусть два упомянутых байта содержат некие координаты, скажем - номера "головки", "цилиндра" и "сектора". Как мог бы выглядеть код, сканирующий всё "пространство" в этом девайсе, если использовать битовые поля? Ну, например так:
Код: Выделить всё
// Device STATUS register: error flag, ready flag, FUNC selection, strobe bit
static
union {
struct {
unsigned int err: 1;
unsigned int rdy: 1;
unsigned int fse: 5;
unsigned int strb:1;
} bit;
unsigned char byte;
} status;
// Device COMMAND register: Coordinates (H/C/S)
static
union {
struct {
unsigned int head:2;
unsigned int sec: 4;
unsigned int cyl: 10;
} bit;
struct {
unsigned char lwr;
unsigned char upr;
} byt;
} DvcCmd;
void inline StrobeDvcReg(){
status.bit.strb = 1; DvcStsReg = status.byte;
status.bit.strb = 0; DvcStsReg = status.byte;
}
void ScanDvcSpace()
{
// Init device
status.bit.fse = _SCAN_DVC_;
DvcStsReg = status.byte;
// Init space
DvcCmd.byt.lwr = 0;
DvcCmd.byt.upr = 0;
// scan all controller space
do {
do {
do {
while ( status.byte = DvcStsReg, !status.bit.rdy ) ; // wait while device got READY
DvcCmdReg = DvcCmd.byt.lwr; // send lower CMD byte
StrobeDvcReg(); // latch cmd byte
DvcCmdReg = DvcCmd.byt.upr; // send upper CMD byte
StrobeDvcReg(); // latch cmd byte
} while ( DvcCmd.bit.sec++ < MAX_SEC );
} while ( DvcCmd.bit.cyl++ < MAX_CYL );
} while ( DvcCmd.bit.head++ < MAX_HEAD );
}
Согласитесь, что запись алгоритма с использованием битовых полей - короче и логичнее, чем манипуляции с тремя отдельными байтовыми переменными, отслеживание переполнения, потом маскирование до нужной длины в битах и, наконец, сбор каждого байта сдвигами и побитным ИЛИ (поле "цилиндр", заметьте, придется еще делить на части, так как два его бита лежат в младшем байте команды, а остальные - в старшем!).
Как говаривал старина Вирт: "
алгоритмы + структуры данных = программы", не так ли?
P.S. Пример, разумеется, выдуман на ходу, и все совпадения имён, фамилий и длин битовых полей - случайны!

Добавлено: Вс май 10, 2009 09:39:07
ARV
для неоднобитовых данных какой-то смысл есть, спасибо за напоминание. почему-то всегда в первую очередь вспоминаются самые простые варианты

Добавлено: Вс май 10, 2009 12:47:50
Yellow Tiger
Я, как законченный perfectionist, считаю, что определенный смысл в использовании битовых полей есть и для однобитовых, но, в общем, не стану спорить с тем, что это уже, в значительной степени, дело вкуса, привычек и прочих граничных условий.
Надеюсь, автору
вопроса стало понятнее, как пользоваться битовыми полями.

Добавлено: Пн май 11, 2009 18:04:59
clawham
Здравствуйте и меня поставила в тупик немнога эта махина!
Вопрос следующий -
1wire.h - библиотека работы с сетью 1wire далласа
если 1wire write функция отрабатывает на ура то вот read - ну совсем не понимаю!!!
хочу работать с 1 wire ключами таймерами и т.д. а не получается читать - функция всегда возвращяет 255....может на момент необходимости чтения надо зациклиться и как только прочитается чтото отличное от 255 - выдать это как результат?
чего-то я явно недопонимаю

мастер шлёт команду чтения - слейвы - отвечают а не получается так почемуто
второе - у меги 16 есть аппаратный СПИ теперь хочу то же самое портануть на тиньку 2313 - вроде ресурсов хватает но что это такое за УСИ - тип универсальный последовательный интерфейс окей я эт понял а вот как в него слать чтото? в меге была команда spi() которая байт выгоняла в порт используя либу spi.h а в тиньке как быть?
Третий вопрос самый крутой!
Есть у техас инструменталс такая вот чудная память -
http://focus.ti.com/docs/prod/folders/p ... 015ly.html
она скоростная незабывается после выключения питания имеет парралельный примитивный интерфейс и объёма в 512 килобайт на всё хватить должно НО....мега не умеет аппаратно адресоваться ко внешней памяти -> вопрос - как написать такую либку которая бы заставила кодвижн авр хранить переменную в этой памяти?
описать процедуры записи и чтения из памяти этой - не проблема. а вот например мне надо подкинуть 100 термометров дс18б20 - мне нужно гдето хранить массив ихних номерков!!! я же не могу опросить номера первой пятерки скинуть массив в раму потом следующей пятерки и так далее - это неправильно
может можно как-то перегрузить функции отвечающие за память, её выделение и разметку?
Добавлено: Пн май 11, 2009 19:15:56
Aheir
Вообще, АВР умеет "адресоваться" ко внешней памяти. Если этого не умеет конкретно Ваша модель МК конкретно к этой памятит - другой вопрос.
я же не могу опросить номера первой пятерки скинуть массив в раму потом следующей пятерки и так далее - это неправильно
вполне нормально, если очищать не забывать
Добавлено: Пн май 11, 2009 19:57:15
clawham
я говорил про функцию w1_search(0xf0,rom_codes);
она то хочет массив который она же и заполнит
Добавлено: Вт май 12, 2009 10:40:52
clawham
Такаже если взять Мегу 128 она всёравно задействовать сможет только 1/8 часть моей микрухи памяти

и это ещё надо д-триггер впаивать и так далее не говоря уже о том что мне пока не поддаётся СМД монтаж такого корпуса а платки-макетки в нашем городе с такой разводкой нету

мне кстати нужно много таких платок - уже штук под 6 для усилителей в TQFP 64 корпусах
всёравно даже те же 512 кб - маловато оперативки(которая не стирается при выключении но внешне - обычная срамка 19 линий адреса, 8-данных...
похоже что и вправду нужно будет адрес в 2 приёма формировать 2-мя триггерами и по той же шине данные гонять в обход триггеров но... это ж всё программная реализация...а в реальности я не смогу создать массив размером больше чем останется от оперативки встроенной моей меги .... а это мало
Хотя может я просто ошибся с выбором компилятора или такого вообще не существует чтоб он умел мапиться переменными во внешнее устройство
С другой стороны проблема АТМЕГИ в том что они всего-то 0xFFFF максимальный адрес кушают....
Да я так подумал что ладно уж с ними....с 512-ю....сам писану туда но в меге 16 и 32 нету внешней памяти...программно снова таки сделать не проблема но....для компилятора это всеголишь внешнее устройство и а никакая не память для переменных
Разве сложно подменять простой MOV на MOV relf-то в временный регистр, потом пару команд на ввод-вывод и потом восстановление временного регистра и то же самое на чтение....
Чисто теоретически возможно но.....кто знает как это заставить делать?
Да и в принципе я согласен сам управлять памятью-то...мне там надо массив флоатов - вот и буду сохранять побайтно а потом восстанавливать но...как же быть с 1wire ?
нужно порядка 200 устройств обрабатывать и меге скоростухи хватает....в отличие от памяти чтоб их каждый адрес запомнить....прийдётся наверное таки делать свою либу поиска 1Wire устройств

ужас какой-то
Добавлено: Вт май 12, 2009 17:36:20
1995kenny
Yellow Tiger
Да, стало намного понятнее
А нет других способов вытащить 1 бит из числа(например типа long)?
А то с этоими полями так всё мудрено...
т.е. если есть 0b000100
100100 и нужно придать переменной
tmp значение выделенного бита, что делать?
Добавлено: Вт май 12, 2009 20:03:03
Yellow Tiger
1995kenny писал(а):А нет других способов вытащить 1 бит из числа(например типа long)? А то с этоими полями так всё мудрено...

Нет там ничего мудреного - это всего лишь двоичные числа с разрядностью неравной/некратной байту, упакованные в байты.
А чтобы выделить один (несколько) бит нужно получить результат, в котором
все остальные биты заведомо равны нулю - смотри побитовые логические операции. В некоторых случаях, после выделения нужных бит весь результат еще сдвигают так, чтобы младший нужный бит оказался в самом младшем разряде.
Добавлено: Ср май 13, 2009 11:32:51
clawham
Я делал как-то процедурку получения температуры и разбивал побитно так
Код: Выделить всё
ds_temp = ds_temp + (float)((temp&1)*0.0625+((temp>>1)&1)*0.125+((temp>>2)&1)*0.25+((temp>>3)&1)*0.5+((temp>>4)&1)+((temp>>5)&1)*2+((temp>>6)&1)*4+((temp>>7)&1)*8);
каждый отдельный бит умножал на его вес и прибавлял к общему результату

просто и со вкусом - всего 2 операции
Добавлено: Ср май 13, 2009 14:07:09
Yellow Tiger
Не две, а двадцать две.

А почему не так:
Код: Выделить всё
Temperature = (*((int *) &__ds18b20_scratch_pad.temp_lsb) & bit_mask[resolution])*0.0625;
???
Ведь проще же.
