Микроконтроллеры, АЦП, память и т.д Темы касающиеся микроконтроллеров разных производителей, памяти, АЦП/ЦАП, периферийных модулей... |
27.04.2009, 19:28
|
#31
|
Прописка
Регистрация: 21.04.2007
Сообщений: 171
Сказал спасибо: 0
Сказали Спасибо 4 раз(а) в 3 сообщении(ях)
|
суть состоит в том, что в правой и левой части равенства вы можете указывать операторы разных типов, но не факт , что компилятор может правильно привести типы правой части к типам левой части. В таких случаях применяют операцию приведения типов.
Например,
if (inp0_inp==0) {temp |= 1‹‹16;}//сразу читаем в нужный бит - в левой части равенства указан оператор
temp, объявленный как unsigned long (32 бита). В правой части указан оператор сдвига 1 влево 16 раз, всё бы хорошо, но процессор у вас 8-битный, аккумулятор у него тоже 8-битный и компилятор подключает 8-битную библиотеку, и все битовые сдвиги от 9 до 16 происходят некорректно.
Другой ваш пример:
tempinp = tempinp & 0xff00ffff | temp‹‹16;}////гасим биты и сдвигаем на нужное место - в Правой части равенства у вас присутствуют переменные temp, tempinp, объявленные как unsigned long (32 бита). В этом случае компилятор подключает 32-битную библиотеку и корректно делает сдвиг влево 16 раз.
Для того , чтобы правильно работал ваш 1 пример просто делаете явное приведение типа правой части к unsigned long (32 бита):
if (inp0_inp==0) {temp |=(unsigned long) (1‹‹16);}//сразу читаем в нужный бит
|
|
|
|
27.04.2009, 20:13
|
#32
|
Почётный гражданин KAZUS.RU
Регистрация: 06.02.2007
Сообщений: 1,340
Сказал спасибо: 3
Сказали Спасибо 106 раз(а) в 66 сообщении(ях)
|
А вот лично Вы пробовали это сделать,прежде чем постить ? Ну, просто интересно...
|
|
|
|
28.04.2009, 04:13
|
#33
|
Прописка
Регистрация: 21.04.2007
Сообщений: 171
Сказал спасибо: 0
Сказали Спасибо 4 раз(а) в 3 сообщении(ях)
|
Если вы заметили, то мои посты - это попытка разобраться в сути вопроса.
Сообщение от vly67
|
Попробуйте операцию приведения типов:
if (inp0_inp==0) {temp |= (unsigned long)(1‹‹16);}//сразу читаем в нужный бит
Возможно, что это решит вашу проблему.
Хотя это применяют обычно к переменным, но, кажется, это должно помочь.
|
Как оказалось, суть действительно состоит в этом. Я сразу, оговорился , что данное приведение типов может быть некорректно.
Но если немного напрячь мозги, то окажется что совсем не сложно, зная суть вопроса, решить эту проблему
if (inp0_inp==0) {temp |= (unsigned long)(1‹‹16);}//сразу читаем в нужный бит - это не работает
, но работает следующее
unsigned long One =1;
if (inp0_inp==0) {temp |= One‹‹16;}//сразу читаем в нужный бит - это проверено, работает в си-компиляторе, правда не в IAR, но и там должно работать
|
|
|
|
28.04.2009, 04:24
|
#34
|
Прописка
Регистрация: 21.04.2007
Сообщений: 171
Сказал спасибо: 0
Сказали Спасибо 4 раз(а) в 3 сообщении(ях)
|
в общем, все работает как и в моем первоначальном варианте,
правда есть небольшой нюансик - скобку надо перенести:
Попробуйте операцию приведения типов:
if (inp0_inp==0) {temp |= (unsigned long)(1‹‹16);}//сразу читаем в нужный бит - не работает, но работает это
if (inp0_inp==0) {temp |= (unsigned long)(1 )‹‹16;}//сразу читаем в нужный бит - разница от предыдущей записи только в перенесённой скобке от цифры 16 к единице.
|
|
|
|
28.04.2009, 13:19
|
#35
|
Почётный гражданин KAZUS.RU
Регистрация: 07.10.2007
Адрес: Луганск
Сообщений: 1,816
Сказал спасибо: 13
Сказали Спасибо 399 раз(а) в 214 сообщении(ях)
|
Сообщение от vly67
|
в общем, все работает как и в моем первоначальном варианте, правда есть небольшой нюансик - скобку надо перенести: Попробуйте операцию приведения типов:
|
Но мне не совсем понятно зачем (принципиально нужна) операция приведения типов, если ОБЕ переменные объявлены UNSIGNED LONG, и ещё, ведь операция преведения в вашей записи применяется не к переменной а к операции сдвига...
Ведь так придётся приводить во всех вычислениях с LONG ...
Из интереса я попробовал ваши варианты записей...
на эту компилято ругается (shift count is too large)
Код:
|
if (key16_inp==0) {temp |=(unsigned long)(1‹‹16);} |
на эту запись компилятор не ругается
Код:
|
if (key16_inp==0) {temp |=(unsigned long)(1)‹‹16;} |
и на эту то же,
Код:
|
unsigned long One =1;
if (inp16_inp==0) {temp |= One‹‹16;} |
но код почему то генерит не правильный...
вот код СИ
Код:
|
unsigned long temp=0;//tempinp глобальная
unsigned long One =1;
temp = tempkey & 0xff00ffff;//гасим считываемые биты
if (key16_inp==0) {temp |=(unsigned long)(1)‹‹16;}//сразу читаем в нужный бит
if (key17_inp==0) {temp |=(unsigned long)(1)‹‹17;}
if (key18_inp==0) {temp |=(unsigned long)(1)‹‹18;}
if (key19_inp==0) {temp |=(unsigned long)(1)‹‹19;}
if (key20_inp==0) {temp |=(unsigned long) One‹‹20;}
if (key21_inp==0) {temp |=(unsigned long) One‹‹21;}
if (key22_inp==0) {temp |=(unsigned long) One‹‹22;}
if (key23_inp==0) {temp |=(unsigned long) One‹‹23;}
tempkey = tempkey; |
вот генеримый код АСМ
Код:
|
read_32key2:
RCALL Subroutine3:
Subroutine3: IN R16,PINB
IN R16,PINB
IN R16,PINB
IN R16,PINB
RET |
А этот код СИ, который нашёл опытным путём (просто перебирал варианты записей), и не требует приведения
Код:
|
unsigned long temp=0;//tempinp глобальная
if (key16_inp==0) {temp |= 1‹‹0;}
if (key17_inp==0) {temp |= 1‹‹1;}
if (key18_inp==0) {temp |= 1‹‹2;}
if (key19_inp==0) {temp |= 1‹‹3;}
if (key20_inp==0) {temp |= 1‹‹4;}
if (key21_inp==0) {temp |= 1‹‹5;}
if (key22_inp==0) {temp |= 1‹‹6;}
if (key23_inp==0) {temp |= 1‹‹7;}
tempkey = tempkey & 0xff00ffff | temp‹‹16;*/ |
генерит АСМ как раз то что нужно...
Код:
|
read_32key3: LDI R16, 0
SBIS 0x16, 0x00 ;считывает 0 бит
LDI R16, 1 ;устанавливает
SBIS 0x16, 0x01 ;1
ORI R16, 0x02
SBIS 0x16, 0x02 ;2
ORI R16, 0x04
SBIS 0x16, 0x03 ;3
ORI R16, 0x08
SBIS 0x16, 0x04 ;4
ORI R16, 0x10
SBIS 0x16, 0x05 ;5
ORI R16, 0x20
SBIS 0x16, 0x06 ;6
ORI R16, 0x40
SBIS 0x16, 0x07 ;7
ORI R16, 0x80
LDI R30, tempkey
LD R20, Z
LDD R21, Z+1
LDD R22, Z+2
ST Z, R20
STD Z+1, R21
STD Z+2, R22
STD Z+3, R16
RET |
И я уже получил рабочий код....
Я думаю скорее всего у компилятора какие то особенности именно в том варианте на котором он спотыкается... Так что буду в дальнейшем пользоватся найденым мною удачным вариантом записи )))
Спасибо за участие... А то так можно разбираться до посинения а дело может в компиляторе
Хотя IAR AVR обычно хвалят.
|
|
|
|
28.04.2009, 14:11
|
#36
|
Прописка
Регистрация: 21.04.2007
Сообщений: 171
Сказал спасибо: 0
Сказали Спасибо 4 раз(а) в 3 сообщении(ях)
|
честно говоря это очень странно, что в обоих примерах код генерится неправильный. А как вы определяете правильность или неправильность? Может вы ошибаетесь?
Я проверял в Кейле: оба мои примера отлично и правильно работают или как вы выразились генерится правильный код.
|
|
|
|
28.04.2009, 18:01
|
#37
|
Почётный гражданин KAZUS.RU
Регистрация: 07.10.2007
Адрес: Луганск
Сообщений: 1,816
Сказал спасибо: 13
Сказали Спасибо 399 раз(а) в 214 сообщении(ях)
|
Сообщение от vly67
|
честно говоря это очень странно, что в обоих примерах код генерится неправильный. А как вы определяете правильность или неправильность? Может вы ошибаетесь?
Я проверял в Кейле: оба мои примера отлично и правильно работают или как вы выразились генерится правильный код.
|
Угу странно...
А проверяю - смотрю в окне отладчика и щёлкаю по шагам... в ассемблере и в исходнике СИ... я приводил дизасемблер того что генерится в разных случаях...
|
|
|
|
Ваши права в разделе
|
Вы не можете создавать новые темы
Вы не можете отвечать в темах
Вы не можете прикреплять вложения
Вы не можете редактировать свои сообщения
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, время: 00:45.
|
|