MaxiMuz 0 12 декабря, 2011 Опубликовано 12 декабря, 2011 · Жалоба Вообщем я понял, из за неприспосбленного и непродуманного компилятора WinAVR и кривизны оптимизатора код с заранее настроенным на адрес регистром: int16_t *p; p=&(a); Cnt1=pgm_read_byte(p++); - почемуто не работает , увеличение p происходит на 2 байта вместо одного! Единственный правильный вариант: volatile uint8_t Cnt1;//фоновый счетчик длительности переключения свдиода uint16_t p=0; uint8_t a[] PROGMEM={22,15,233,40,69,39,203,2,1}; ...... ...... Cnt1=pgm_read_byte(&(a[p++])); Хотя тоже корявый: Cnt1=pgm_read_byte(&(a[p++])); aa: 84 91 lpm r24, Z+ ac: 80 93 62 00 sts 0x0062, r24 b0: 31 96 adiw r30, 0x01; 1 Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Сергей Борщ 141 12 декабря, 2011 Опубликовано 12 декабря, 2011 · Жалоба почемуто не работает , увеличение p происходит на 2 байта вместо одного!А с чего бы ему увеличиваться на один, если вы его объявили как указатель на uint16_t. Он честно, как вы и просите, увеличивается на sizeof(uint16_t). Пассаж про зеркалокомпилятор опустим. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
MaxiMuz 0 12 декабря, 2011 Опубликовано 12 декабря, 2011 · Жалоба А с чего бы ему увеличиваться на один, если вы его объявили как указатель на uint16_t. Он честно, как вы и просите, увеличивается на sizeof(uint16_t). Пассаж про зеркалокомпилятор опустим. Да, действительно! Я все провожу паралели с Ассемблером и посчитал что тип_данных перед указателем есть размер ячейки памяти которая используется для указания адреса. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
GenaSPB 11 12 декабря, 2011 Опубликовано 12 декабря, 2011 (изменено) · Жалоба Кст ати, это тоже рабочий вариант и ни какой не шедевр! Если правильно задать массив , то работает, но байт информации в массиве пакуется в слово с 00h в ст.байте: Вы описали массив указателей на int8_t, инициализируя их целыми числами. Компилятор ругнулся по поводу инициализации десяток раз (или сколько у Вас там инициализаторов), а Вы и не заметили... Причём, в первых двух выкладываниях текста программы было всё нормально а в последнем (там где дизассемблерный листинг с кусочками исходного текста) эта ошибка уже внесена. Естественно, при перескоке через байт всё заработало. Изменено 12 декабря, 2011 пользователем Genadi Zawidowski Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
MaxiMuz 0 13 декабря, 2011 Опубликовано 13 декабря, 2011 (изменено) · Жалоба Вы описали массив указателей на int8_t, инициализируя их целыми числами. Компилятор ругнулся по поводу инициализации десяток раз (или сколько у Вас там инициализаторов), а Вы и не заметили... Теперь понял какую я ерунду написал. Почему то в строчке p=&a; volatile uint8_t Cnt1;//фоновый счетчик длительности переключения свдиода uint8_t *p; ...... uint8_t a[] PROGMEM={22,15,233,40,69,39,203,2,1}; p=&a; ...... компил. выдает предупреждение: warning: assignment from incompatible pointer type ? Изменено 13 декабря, 2011 пользователем MaxiMuz Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Сергей Борщ 141 13 декабря, 2011 Опубликовано 13 декабря, 2011 · Жалоба warning: assignment from incompatible pointer type[/code] ?p - указатель на uint8_t. Имя массива является указателем на его нулевой член. Оператор & возвращает указательна свой аргумент. Т.е. запись &a имеет тип "указатель на указатель на uint8_t". Вам же надо просто "указатель на uint8_t". Поэтому либо берите адрес нулевого элемента массива p = &a[0], либо берите адрес массива p = a. И еще - ваш массив находится во флеш, значит является константным по условию. Значит ваш указатель нужно делать указателем на константу: uint8_t const * p. И неважно, что компилятор сейчас позволяет объявить указатель на неконстантный объект - во первых, это уже исправлено в последних версиях, а во-вторых - это предохранит вас от ошибочной попытки изменить данные, на которые указывает p простым присваиванием, компилятор выдаст сообщение об ошибке. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
MaxiMuz 0 14 декабря, 2011 Опубликовано 14 декабря, 2011 · Жалоба Заменил p=&a; на p=&a[0]; действительно предупреждение пропало, спасибо Сергею! Но возник другой вопрос. Я немного поменял алгоритм основной программы на: p=&a[0]; ........................................ ........................................ int main (void) { uint8_t temp; init(); sei (); while (1) { if (RF.bOne==0) { RF.bOne=1; temp=pgm_read_byte(p++); if (temp!=0) {Cnt1=pgm_read_byte(p++);} } } } И получил код: p=&a[0]; 8a: 84 e1 ldi r24, 0x14 ; 20 8c: 90 e0 ldi r25, 0x00 ; 0 8e: 90 93 61 00 sts 0x0061, r25 92: 80 93 60 00 sts 0x0060, r24 ........................................ ........................................ uint8_t temp; init(); 98: e8 df rcall .-48 ; 0x6a <init> sei (); 9a: 78 94 sei 9c: 20 91 60 00 lds r18, 0x0060 a0: 30 91 61 00 lds r19, 0x0061 a4: c9 01 movw r24, r18 while (1) { if (RF.bOne==0) a6: 10 fd sbrc r17, 0 a8: fe cf rjmp .-4 ; 0xa6 <__stack+0x7> { RF.bOne=1; aa: 11 60 ori r17, 0x01 ; 1 } int main (void) { ac: ac 01 movw r20, r24 ae: 4f 5f subi r20, 0xFF ; 255 b0: 5f 4f sbci r21, 0xFF ; 255 { if (RF.bOne==0) { RF.bOne=1; temp=pgm_read_byte(p++); b2: fc 01 movw r30, r24 b4: 84 91 lpm r24, Z+ if (temp!=0) b6: 88 23 and r24, r24 b8: 11 f4 brne .+4 ; 0xbe <__stack+0x1f> ba: ca 01 movw r24, r20 bc: f4 cf rjmp .-24 ; 0xa6 <__stack+0x7> { Cnt1=pgm_read_byte(p++); be: 9a 01 movw r18, r20 c0: 2f 5f subi r18, 0xFF ; 255 c2: 3f 4f sbci r19, 0xFF ; 255 c4: fa 01 movw r30, r20 c6: 84 91 lpm r24, Z+ c8: 80 93 62 00 sts 0x0062, r24 cc: eb cf rjmp .-42 ; 0xa4 <__stack+0x5> Долго ломал голову зачем по несколько раз копировалась ссылка на массив! Создалось такое впечатление что, происходит дублирование пары регистров с адресом массива... Непомерно раздутый код , который можно заменить как минимум вдвое меньшим числом команд. Я понимаю что возможно ктото скажет, что если не нравиться, пользуйся асемблерными вставками. Программа работает правильно. Может я слишком требователен к компилятору, но может есть менее громоздкий способ обращению к массиву ? Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
AHTOXA 18 14 декабря, 2011 Опубликовано 14 декабря, 2011 · Жалоба :bb-offtopic: И кто будет после этого утверждать, что изучать ассемблер полезно? Вот изучил человек ассемблер, и что? Теперь он вместо написания программы, реализации своего алгоритма, создания своего устройства - занят анализом работы компилятора... :laughing: MaxiMuz, вы сначала просто программу напишите, а оптимизировать её можно потом. Если возникнет нужда (а она скорее всего и не возникнет). Кроме того, со временем вы набьёте руку в Си, и будете автоматом писать наиболее оптимальным способом. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
MaxiMuz 0 20 января, 2012 Опубликовано 20 января, 2012 · Жалоба Проблема решилась выносом p++ за "скобки" функции pgm_read_byte: while (1) { if (RF.bOne==0) { RF.bOne=1; temp=pgm_read_byte(p); p++; if (temp!=0) { Cnt1=pgm_read_byte(p); p++; } } } Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
ARV 1 21 января, 2012 Опубликовано 21 января, 2012 · Жалоба какая проблема решилась? по-моему, что в скобках, что за скобками - все одно и то же... Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
demiurg_spb 0 23 января, 2012 Опубликовано 23 января, 2012 · Жалоба по-моему, что в скобках, что за скобками - все одно и то же...Однозначно! Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
AHTOXA 18 23 января, 2012 Опубликовано 23 января, 2012 · Жалоба какая проблема решилась? по-моему, что в скобках, что за скобками - все одно и то же... Что-то там не так оптимизировалось: Долго ломал голову зачем по несколько раз копировалась ссылка на массив! Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
MaxiMuz 0 23 января, 2012 Опубликовано 23 января, 2012 · Жалоба какая проблема решилась? по-моему, что в скобках, что за скобками - все одно и то же... решилась проблема лишних сохранений и тусований ссылочного регистра Z. при использовании: pgm_read_byte(p); p++; вместо pgm_read_byte(p++); код сокращается на 18 байт! Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться