Микроконтроллеры, АЦП, память и т.д Темы касающиеся микроконтроллеров разных производителей, памяти, АЦП/ЦАП, периферийных модулей... |
19.04.2009, 02:31
|
|
Почётный гражданин KAZUS.RU
Регистрация: 07.10.2007
Адрес: Луганск
Сообщений: 1,816
Сказал спасибо: 13
Сказали Спасибо 399 раз(а) в 214 сообщении(ях)
|
Что бы не плодить темы, пишу сюда...
Осваиваю IARAVR 5.20.1 Возник вопрос.
(в IARAVR5.11B та же фигня)
В функцииях считывания из портов в переменную LONG.
Происходит такая бяка. При считывании младших 8 бит, всё нормально. А при считывании битов 8-15, происходит дополнительная установка в "1" и битов 16-31, которые ещё не считывали.
Делал разные варианты. Разноcил считываемые ножки по разным портам, считывал все из одного порта, считывал сначала во временную переменную в регистрах а потом сохранял в RAM... устанавливал разную оптимизацию, всегда ведёт себя одинаково...
После считывания 15-го бита при сохранении в RAM устанавливает в "1" с 16 по 31 биты.
Если считывать только 8 бит (в переменные типа char) или 16 бит (в переменные типа int) происходит нормально!! А с long творятся чудеса... дайте пинка в нужном направлении... уже мозги сломал.
В прикреплённом два проекта (считывание через регистры и без регистров сразу в переменную) и рисунок в DJVU со снимком экрана в отладчике, виден код Cи И АСМ.
Кто сможет пояснить, Заранее сенк.
Прикрепленный файл: 5435935.RAR
|
|
|
|
19.04.2009, 07:35
|
|
Почётный гражданин KAZUS.RU
Регистрация: 06.02.2007
Сообщений: 1,340
Сказал спасибо: 3
Сказали Спасибо 106 раз(а) в 66 сообщении(ях)
|
а если глобальную переменную long объявить с квалификатором static, то что тогда ?
|
|
|
|
23.04.2009, 23:35
|
|
Почётный гражданин KAZUS.RU
Регистрация: 07.10.2007
Адрес: Луганск
Сообщений: 1,816
Сказал спасибо: 13
Сказали Спасибо 399 раз(а) в 214 сообщении(ях)
|
Долбаюсь с Си дальше.. возник вопрос..
А кто может подсказать, нужно сдвинуть массив char [8] влево (или 8 переменных CHAR). Я написал так.
Код:
|
unsigned char bcd[8];
unsigned char bcd0,bcd1,bcd2,bcd3,bcd4,bcd5,bcd6,bcd7;
bcd[7] = bcd[7]‹‹1 | (bcd[6]››7 & 1);//сдвигаем байт на "1", "ИЛИ" 7-й бит
bcd[6] = bcd[6]‹‹1 | (bcd[5]››7 & 1);
bcd[5] = bcd[5]‹‹1 | (bcd[4]››7 & 1);
bcd[4] = bcd[4]‹‹1 | (bcd[3]››7 & 1);
bcd[3] = bcd[3]‹‹1 | (bcd[2]››7 & 1);
bcd[2] = bcd[2]‹‹1 | (bcd[1]››7 & 1);
bcd[1] = bcd[1]‹‹1 | (bcd[0]››7 & 1);
bcd[0] = bcd[0]‹‹1;
//или переменные:
bcd7 = bcd7‹‹1 | (bcd6››7 & 1);//сдвигаем байт на "1", "ИЛИ" 7-й бит
bcd6 = bcd6‹‹1 | (bcd5››7 & 1);
bcd5 = bcd5‹‹1 | (bcd4››7 & 1);
bcd4 = bcd4‹‹1 | (bcd3››7 & 1);
bcd3 = bcd3‹‹1 | (bcd2››7 & 1);
bcd2 = bcd2‹‹1 | (bcd1››7 & 1);
bcd1 = bcd1‹‹1 | (bcd0››7 & 1);
bcd0 = bcd0‹‹1; |
Но эта запись компилируется очень длинно. А есть ли возможность записать сдвиг масива или переменных char так, что бы откомпилировался сдвиг через флаг С, командами ROL (или ROR если вправо) что то типа этого
Код:
|
ror R16
ror R17
ror R18
ror R19
ror R20
ror R21
ror R22
ror R23 |
|
|
|
|
24.04.2009, 12:33
|
|
Почётный гражданин KAZUS.RU
Регистрация: 06.02.2007
Сообщений: 1,340
Сказал спасибо: 3
Сказали Спасибо 106 раз(а) в 66 сообщении(ях)
|
Что мешает проверить ?
Код:
|
union{
struct{
unsigned char l;
}st[8];
unsigned long long k;
}un;
void main(void) //
{
char i,q;
q=0;
for(i=0;i‹8;i++)
{
un.st[i].l=0x01;
}
if(un.st[0].l & 1)q=1;
un.k››=1;
if(q){un.st[7].l+=128;} |
А вот на кодевижин этот фокус уже не пройдет...
|
|
|
|
24.04.2009, 13:10
|
|
Прописка
Регистрация: 21.04.2007
Сообщений: 171
Сказал спасибо: 0
Сказали Спасибо 4 раз(а) в 3 сообщении(ях)
|
Сообщение от picavr
|
В функцииях считывания из портов в переменную LONG.
Происходит такая бяка. При считывании младших 8 бит, всё нормально. А при считывании битов 8-15, происходит дополнительная установка в "1" и битов 16-31, которые ещё не считывали.
После считывания 15-го бита при сохранении в RAM устанавливает в "1" с 16 по 31 биты.
Если считывать только 8 бит (в переменные типа char) или 16 бит (в переменные типа int) происходит нормально!! А с long творятся чудеса... дайте пинка в нужном направлении... уже мозги сломал.
Кто сможет пояснить, Заранее сенк.
|
Могу предположить, что сдвиг 32 битного числа происходит в 8-битном аккумулятору (используете то 8-битный процессор?) - отсюда такие проблемы. Всё , что выше 16 бит - сдвигается некорректно, хотя и объявили переменную как беззнаковый лонг. Возможно, что библиотека IAR правильно работает с int и char, но не с long.
Прикрепленный файл: 5435935.RAR
|
|
|
|
24.04.2009, 14:07
|
|
Почётный гражданин KAZUS.RU
Регистрация: 07.10.2007
Адрес: Луганск
Сообщений: 1,816
Сказал спасибо: 13
Сказали Спасибо 399 раз(а) в 214 сообщении(ях)
|
Сообщение от vly67
|
Могу предположить, что сдвиг 32 битного числа происходит в 8-битном аккумулятору (используете то 8-битный процессор?) - отсюда такие проблемы.
|
Если интерестно, то вот примеры что я накопал...
Так была проблемма. На все строчки сдвига компилятор ругался - далеко сдвигать...
Код:
|
unsigned long temp=0;//tempinp глобальная
temp = tempinp & 0xff00ffff;//гасим считываемые биты
if (inp0_inp==0) {temp |= 1‹‹16;}//сразу читаем в нужный бит
if (inp1_inp==0) {temp |= 1‹‹17;}
if (inp2_inp==0) {temp |= 1‹‹18;}
if (inp3_inp==0) {temp |= 1‹‹19;}
if (inp4_inp==0) {temp |= 1‹‹20;}
if (inp5_inp==0) {temp |= 1‹‹21;}
if (inp6_inp==0) {temp |= 1‹‹22;}
if (inp7_inp==0) {temp |= 1‹‹23;}
tempinp = tempinp;}
temp = tempinp & 0x00ffffff;
if (inp0_inp==0) {temp |= 1‹‹24;)
if (inp1_inp==0) {temp |= 1‹‹25;)
if (inp2_inp==0) {temp |= 1‹‹26;)
if (inp3_inp==0) {temp |= 1‹‹27;}
if (inp4_inp==0) {temp |= 1‹‹28;}
if (inp5_inp==0) {temp |= 1‹‹29;}
if (inp6_inp==0) {temp |= 1‹‹30;}
if (inp7_inp==0) {temp |= 1‹‹31;}
tempinp = tempinp;} |
А вот так заработало, и компилирует в компактный код.
Код:
|
unsigned long temp=0;//tempinp глобальная
if (inp0_inp==0) {temp |= 1‹‹0;}//читаем в 0-7 бит
if (inp1_inp==0) {temp |= 1‹‹1;}
if (inp2_inp==0) {temp |= 1‹‹2;}
if (inp3_inp==0) {temp |= 1‹‹3;}
if (inp4_inp==0) {temp |= 1‹‹4;}
if (inp5_inp==0) {temp |= 1‹‹5;}
if (inp6_inp==0) {temp |= 1‹‹6;}
if (inp7_inp==0) {temp |= 1‹‹7;}
tempinp = tempinp & 0xff00ffff | temp‹‹16;}////гасим биты и сдвигаем на нужное место
unsigned long temp=0;//tempinp глобальная
if (inp0_inp==0) {temp |= 1‹‹0;}
if (inp1_inp==0) {temp |= 1‹‹1;}
if (inp2_inp==0) {temp |= 1‹‹2;}
if (inp3_inp==0) {temp |= 1‹‹3;}
if (inp4_inp==0) {temp |= 1‹‹4;}
if (inp5_inp==0) {temp |= 1‹‹5;}
if (inp6_inp==0) {temp |= 1‹‹6;}
if (inp7_inp==0) {temp |= 1‹‹7;}
tempinp = tempinp & 0x00ffffff | temp‹‹24;} |
Хотя и там и там происходит сдвиг на 16 и более бит..
Скорее всего у каждого компилятора есть какие то особенности, их нужно просто отловить, понять и использовать... Потому и спрашиваю кто уже это проходил...
Прикрепленный файл: 5435935.RAR
|
|
|
|
24.04.2009, 14:53
|
|
Прописка
Регистрация: 21.04.2007
Сообщений: 171
Сказал спасибо: 0
Сказали Спасибо 4 раз(а) в 3 сообщении(ях)
|
возможно , что причина состоит в следующем - вы указали справа от знака "равно" переменную с типом лонг и IAR подключил 32-битную библиотеку - поэтому не было проблем.
В 1 примере - не было явно указано - поэтому он по умолчанию использовал 8-битную библиотеку - отсюда произошла ошибка.
Попробуйте операцию приведения типов:
if (inp0_inp==0) {temp |= (unsigned long)(1‹‹16);}//сразу читаем в нужный бит
Возможно, что это решит вашу проблему.
Хотя это применяют обычно к переменным, но, кажется, это должно помочь.
|
|
|
|
24.04.2009, 16:35
|
|
Почётный гражданин KAZUS.RU
Регистрация: 07.10.2007
Адрес: Луганск
Сообщений: 1,816
Сказал спасибо: 13
Сказали Спасибо 399 раз(а) в 214 сообщении(ях)
|
Сообщение от vly67
|
Попробуйте операцию приведения типов:
if (inp0_inp==0) {temp |= (unsigned long)(1‹‹16);}
Возможно, что это решит вашу проблему.
|
Но в обоих примерах ОБЕ ПЕРЕМЕННЫЕ (TEMPINP и TEMP) объявлены как UNSIGNED LONG, так что несоответствие типов по моему не должно проявлятся.
tempinp - глобальная
temp - объявляется внутри функции,
я уже решил задачку, мой рабочий пример номер два.
Но за подсказку спасибо..
Привет Юра, спасибо, попробую и твой пример.
Вот наиболее короткий и быстрый код, который я получил,
Код:
|
union {
struct { unsigned long
templ0:8, //CHAR удобно для загрузки-выгрузки 8 битных чисел
templ1:8,
templ2:8,
templ3:8;};
unsigned long templ; //LONG удобно для сдвига и подсчёта
};
union {
struct { unsigned long
tempm0:8,
tempm1:8,
tempm2:8,
tempm3:8;};
unsigned long tempm;
};
union {
struct { unsigned int
temph0:8,
temph1:8;};
unsigned int temph;
};
//сам сдвиг подсмотрел на micrichip.ru
temph ‹‹=1; if((signed long)(tempm)‹0){temph |= 1;}
tempm ‹‹=1; if((signed long)(templ)‹0){tempm |= 1;}
templ ‹‹=1;} |
Вот здесь бы наверное было бы целесообразно применить асм для сдвига? просто сдвинуть 10 байт.
Код:
|
rol r16//младший
rol r17
rol r18
rol r19
rol r20
rol r21
rol r22
rol r23
rol r24
rol r25//старший |
|
|
|
|
26.04.2009, 13:19
|
|
Прописка
Регистрация: 21.04.2007
Сообщений: 171
Сказал спасибо: 0
Сказали Спасибо 4 раз(а) в 3 сообщении(ях)
|
вы не поняли - имеется в виду ПРАВАЯ ЧАСТЬ равенства
Сравните:
неправильно
if (inp0_inp==0) {temp |= 1‹‹16;}//сразу читаем в нужный бит
правильно
tempinp = tempinp & 0xff00ffff | temp‹‹16;}////гасим биты и сдвигаем на нужное место
Посмотрите в ПРАВУЮ ЧАСТЬ равенства правильного и неправильного примера и поймёте о чём я говорил
|
|
|
|
27.04.2009, 16:26
|
|
Почётный гражданин KAZUS.RU
Регистрация: 07.10.2007
Адрес: Луганск
Сообщений: 1,816
Сказал спасибо: 13
Сказали Спасибо 399 раз(а) в 214 сообщении(ях)
|
Сообщение от vly67
|
вы не поняли - имеется в виду ПРАВАЯ ЧАСТЬ равенства
|
Но если честно, не понял в чём неправильность.
Поясню так как это понимаю я.
temp |= 1‹‹16;
или то же самое:
temp OR= 1‹‹16;
или то же самое:
temp = temp OR 1‹‹16;
или то же самое:
temp = temp OR 0x00000100;
т.е. я устанавливаю в "1" 16-тый бит переменной temp... поправьте где я ошибаюсь. Хочу понять где я не правильно понял способ записи таких операций.
(Но случае с первыми 15-тью битами, по моему это работает правильно)
И спасибо за разьяснения
|
|
|
|
Ваши права в разделе
|
Вы не можете создавать новые темы
Вы не можете отвечать в темах
Вы не можете прикреплять вложения
Вы не можете редактировать свои сообщения
HTML код Выкл.
|
|
|
Тема |
Автор |
Раздел |
Ответов |
Последнее сообщение |
IAR for AVR
|
kassiopay |
Микроконтроллеры, АЦП, память и т.д |
5 |
27.03.2009 17:20 |
Вопрос новичка. IAR C, AVR & interrupt
|
sns13 |
Микроконтроллеры, АЦП, память и т.д |
5 |
18.03.2008 18:08 |
IAR for AVR
|
vasilij-kursikov |
Микроконтроллеры, АЦП, память и т.д |
29 |
28.09.2006 18:14 |
Вопрос по дизайну IAR
|
Oleksandr_Nemchenko |
Proteus, KiCAD и другие ECAD |
1 |
04.08.2006 14:16 |
Вопрос по IAR
|
константин |
Микроконтроллеры, АЦП, память и т.д |
1 |
11.09.2005 23:07 |
Часовой пояс GMT +4, время: 10:36.
|
|