IF_P 1 1 мая, 2020 Опубликовано 1 мая, 2020 · Жалоба Есть подпрограмма, в которой нужно сбросить бит в р-ре. Что не нравится IAR при сбросе бита в ADMUX? ("err_clr_bit.png") Здесь же добавил сброс 0-го бита в другом р-ре. Там все нормально. И попутно еще вопрос по локальной переменной ("local.png") В команде asm ("LDS R14, i") компилятор выдает ошибку, если i локальная переменная. При глобальной переменной все нормально. Ошибка также возникает если вместо i использовать элемент union, который описан в хидерном файле: union { uint Word; struct { char c1; char c2; } Symv; } Int_Char; Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
VladislavS 29 1 мая, 2020 Опубликовано 1 мая, 2020 · Жалоба Пища для размышлений. // ADMUX &= ~(1<<MUX0); CBI 0x07, 0x00 // ADMUX &= -(1<<MUX0); IN R16, 0x07 OUT 0x07, R16 Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
IF_P 1 1 мая, 2020 Опубликовано 1 мая, 2020 · Жалоба Попробовал сбросить бит MUX1. Все нормально. ("Err_clr_bit_n.png") Но есть еще небольшая проблема связаная с отладкой программы. ("proteus.png") В Proteus не могу пройти по шагам после адреса 0xFF. Сам код выполняется , но остановиться на нем я не могу. Не зная в ком проблема: IAR или Proteus. И это все в той же п/п. Вот привожу ее полностью void Result_ADC (void) { uchar i; static uint sum_adc; static uchar ch_adc; uchar low_adc, high_adc; uint adc_value; low_adc = ADCL; high_adc = ADCH; adc_value = high_adc * 256 + low_adc; sum_adc += adc_value; if (--count_cycle_adc == 0) { count_cycle_adc = N_CYCLE_ADC; Int_Char.Word = sum_adc; // asm ("LDS R14, Int_Char.Symv.c1"); i = Int_Char.Symv.c1; // asm ("LDS R14, i"); i = Int_Char.Symv.c2; // asm ("LDS R15, i"); for (i = 0; i < 3; i++) { asm ("LSR R14"); asm ("ROR R15"); } switch (ch_adc) { case 0: asm ("STS adc_ch_0_low, R15"); asm ("STS adc_ch_0_high, R14"); ch_adc = 1; ADMUX |= (1 << MUX0); break; case 1: asm ("STS adc_ch_1_low, R15"); asm ("STS adc_ch_1_high, R14"); ch_adc = 0; // asm ("CBI 0x07, 0x0"); ADMUX &= -(1 << MUX0); ADMUX &= -(1 << MUX1); break; } sum_adc = 0; } ADCSRA |= (1 << ADIF); ADCSRA |= (1 << ADSC); } В хидерном файле есть такая инфрмация: void Result_ADC (void); #define N_CYCLE_ADC 8 union { uint Word; struct { char c1; char c2; } Symv; } Int_Char; uchar count_cycle_adc; uchar adc_ch_0_low, adc_ch_0_high, adc_ch_1_low, adc_ch_1_high; Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
VladislavS 29 1 мая, 2020 Опубликовано 1 мая, 2020 · Жалоба Между -(1<<MUX0) и ~(1<<MUX0) разницу вообще не наблюдаете? Первое это 0xFF, а второе 0xFE, между нами девочками. И объясните уже, нахрена тут asm? Вы только мешаете компилятру работать своими вставками. Поверьте, он умнее вас. Точно так же как какие-то левые union... IAR достаточно умный, чтобы вот так уметь. // uint16_t adc_value = ADC; IN R16, 0x04 //ADCL IN R17, 0x05 //ADCH // adc_value += ADC; IN R18, 0x04 IN R19, 0x05 ADD R18, R16 ADC R17, R19 // DDRC = adc_value; OUT 0x14, R18 // DDRB = adc_value>>8; OUT 0x17, R17 Просто не мешайте ему. Совет на будущее. Не надо придумывать непонятные типы данных. В стандарте языка есть stdint.h - пользуйтесь. Стандартный uint16_t на любой платформе останется 16-битным беззнаковым целым и любой компилятор/программист однозначно поймёт что это, в отличии от uint. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
IF_P 1 1 мая, 2020 Опубликовано 1 мая, 2020 (изменено) · Жалоба 6 hours ago, VladislavS said: Между -(1<<MUX0) и ~(1<<MUX0) разницу вообще не наблюдаете? Первое это 0xFF, а второе 0xFE, между нами девочками. Я прекрасно понимаю разницу между выражениями. Но подвело зрение. Пора, наверное, уже брать очки, а все не хочется. Большое спасибо за выявление моей ошибки. Я бы так и не увидел ее, если бы Вы явно не указали на нее. Но в уме не укладывается, каким образом вместо тильды попал минус - они на разных концах клавиатуры. 6 hours ago, VladislavS said: И объясните уже, нахрена тут asm? ... IAR достаточно умный, чтобы вот так уметь. Согласен. Сам так делал. Но тут как-то сразу не сообразил. Просто я использую union в другом месте, где нужен доступ у переменной либо как int либо как char. Вот автоматом и сюда вставил. 6 hours ago, VladislavS said: В стандарте языка есть stdint.h - пользуйтесь. Стандартный uint16_t ... Я часто встречал такое описание, но оно как-то мне было не по душе. К тому же я пишу на C и всегда пользовался библиотекой CLIB. А этот файл есть в DLIB. Ну что ж, попробую использовать DLIB. А как на счет отладки в Proteus'е? Есть ли какие идеи? Сама п/программа работает и у меня нет необходимости влезать сейчас туда. Но хотелось бы выяснить на будущее. Где искать - в IAR'е или в Proteus'е? Изменено 1 мая, 2020 пользователем IF_P Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Baser 5 1 мая, 2020 Опубликовано 1 мая, 2020 · Жалоба 7 минут назад, IF_P сказал: 6 часов назад, VladislavS сказал: В стандарте языка есть stdint.h - пользуйтесь. Стандартный uint16_t ... Я часто встречал такое описание, но оно как-то мне было не по душе. К тому же я пишу на C и всегда пользовался библиотекой CLIB. А этот файл есть в DLIB. Ну что ж, попробую использовать DLIB. Вы можете и дальше использовать CLIB, если не нужны дополнительные функции. Просто в ручную подключайте stdint.h - это всего лишь файл описаний. Точно так же, как и для использования bool в ANSI C просто подключаете stdbool.h #include <stdbool.h> #include <limits.h> #include <float.h> #include <stdlib.h> #include <string.h> #include <math.h> и т.д. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
IF_P 1 1 мая, 2020 Опубликовано 1 мая, 2020 (изменено) · Жалоба Я скопировал "stdint.h" в CLIB и подключил его в проект. Без подключения DLIB не получается. С подключением работает. Вот что я еще заметил. Невозможность пройти по шагам в отладке возникает при включенной оптимизации "High-Size" ("no_adc_value.png"). При отключеной оптимизации все нормально. ("yes_adc_value.png") Изменено 1 мая, 2020 пользователем IF_P Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
VladislavS 29 2 мая, 2020 Опубликовано 2 мая, 2020 · Жалоба for (i = 0; i < 3; i++) { asm ("LSR R14"); asm ("ROR R15"); } Когда вы вычистите подобную дичь, то и отладка не понадобится. Я же говорил, компилятор всё сам умеет. Напишите алгоритм на чистом С и он будет работать всегда, а не как звёзды лягут. // uint16_t x = ADC; IN R16, 0x04 IN R17, 0x05 // x >>= 3; LSR R17 ROR R16 LSR R17 ROR R16 LSR R17 ROR R16 // DDRC = x; OUT 0x14, R16 // DDRD = x>>8; OUT 0x11, R17 Давайте лучше ваш алгоритм приведём в порядок вместо разгадывания шарад с протеусом. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
VladislavS 29 2 мая, 2020 Опубликовано 2 мая, 2020 · Жалоба #define N_CYCLE_ADC 8 uint16_t adc_ch_0, adc_ch_1; void Result_ADC() { static uint16_t sum_adc = 0; static uint8_t counter = N_CYCLE_ADC; sum_adc += ADC; if (--counter == 0) { if(ADMUX & 0x01) { adc_ch_1 = sum_adc/N_CYCLE_ADC; ADMUX &= ~(1<<MUX0); } else { adc_ch_0 = sum_adc/N_CYCLE_ADC; ADMUX |= (1<<MUX0); } counter = N_CYCLE_ADC; sum_adc = 0; } ADCSRA |= (1 << ADSC); } Так задумывалось? Что-то мне подсказывает, что это будет оптимальней ваших изысканий. // void Result_ADC() ??Result_ADC: // { // static uint16_t sum_adc = 0; // static uint8_t counter = N_CYCLE_ADC; // sum_adc += ADC; LDS R18, (adc_ch_0 + 4) LDS R19, (adc_ch_0 + 5) IN R16, 0x04 IN R17, 0x05 ADD R18, R16 ADC R19, R17 // if (--counter == 0) LDS R16, (adc_ch_0 + 6) DEC R16 BRNE ??Result_ADC_1 // { // sum_adc/N_CYCLE_ADC; LSR R19 ROR R18 LSR R19 ROR R18 LSR R19 ROR R18 // if(ADMUX & 0x01) SBIS 0x07, 0x00 RJMP ??Result_ADC_2 // { // adc_ch_1 = sum_adc/N_CYCLE_ADC; STS (adc_ch_0 + 2), R18 STS (adc_ch_0 + 3), R19 // ADMUX &= ~(1<<MUX0); CBI 0x07, 0x00 RJMP ??Result_ADC_3 // } // else // { / adc_ch_0 = sum_adc/N_CYCLE_ADC; ??Result_ADC_2: STS adc_ch_0, R18 STS (adc_ch_0 + 1), R19 // ADMUX |= (1<<MUX0); SBI 0x07, 0x00 // } // counter = N_CYCLE_ADC; ??Result_ADC_3: LDI R16, 8 // sum_adc = 0; LDI R18, 0 LDI R19, 0 ??Result_ADC_1: STS (adc_ch_0 + 6), R16 STS (adc_ch_0 + 4), R18 STS (adc_ch_0 + 5), R19 // } // ADCSRA |= (1 << ADSC); SBI 0x06, 0x06 // } RET Насчёт пошаговой отладки. При включенной оптимизации компилятор очень сильно видоизменяет код. Поэтому не всегда получается сопоставить строкам Си-кода соответствующие ассемблерные директивы. Вот отладчик и не может шагать по коду. Надо просто переходить в окно дизасма и там шагать. Переключите компилятор на С++ раз и навсегда. Получите одни бонусы, даже если не будете использовать классы, шаблоны и т.д. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
IF_P 1 2 мая, 2020 Опубликовано 2 мая, 2020 · Жалоба 4 hours ago, VladislavS said: Переключите компилятор на С++ раз и навсегда. Получите одни бонусы, даже если не будете использовать классы, шаблоны и т.д. Попробую. 4 hours ago, VladislavS said: Насчёт пошаговой отладки. При включенной оптимизации компилятор очень сильно видоизменяет код. Что касается отладки, то вот сейчас начал разбираться с листингом после оптимизации. 152 void Result_ADC (void) \ ??Result_ADC: 153 { 154 static uint sum_adc; 155 static uchar ch_adc; 156 uchar low_adc, high_adc; 157 uint adc_value; 158 159 low_adc = ADCL; \ 00000000 B104 IN R16, 0x04 160 high_adc = ADCH; 161 adc_value = high_adc * 256 + low_adc; 162 sum_adc += adc_value; \ 00000002 B135 IN R19, 0x05 \ 00000004 2F20 MOV R18, R16 \ 00000006 9100.... LDS R16, (message_buf + 22) \ 0000000A 9110.... LDS R17, (message_buf + 23) \ 0000000E 0F02 ADD R16, R18 \ 00000010 1F13 ADC R17, R19 \ 00000012 9300.... STS (message_buf + 22), R16 \ 00000016 9310.... STS (message_buf + 23), R17 Для локальных переменных low_adc и high_adc не выделяется память, а используются р-ры. Операцию adc_value = high_adc * 256 + low_adc; компилятор вообще выбросил за ненадобностью, т.к. эта информация уже хранится в р-рах R16 и R19. Переменная adc_value действительно не нужна, но я добавил ее только для отладки в Proteus'е. Мне так удобно видеть изменение АЦП в десятиричном виде. В реале я бы ее потом выбросил. Вот поэтому отладчик и не "видит" эти строки. А что касается Вашего кода, то мой компилятор выдает немного другой код. Хотя он и не сильно отличается. \ In segment CODE, align 2, keep-with-next 150 void Result_ADC() \ ??Result_ADC: 151 { 152 static uint16_t sum_adc = 0; 153 static uint8_t counter = N_CYCLE_ADC; 154 155 sum_adc += ADC; \ 00000000 9120.... LDS R18, (adc_ch_0 + 4) \ 00000004 9130.... LDS R19, (adc_ch_0 + 5) \ 00000008 B104 IN R16, 0x04 \ 0000000A B115 IN R17, 0x05 \ 0000000C 0F20 ADD R18, R16 \ 0000000E 1F31 ADC R19, R17 156 157 if (--counter == 0) \ 00000010 9100.... LDS R16, (adc_ch_0 + 6) \ 00000014 950A DEC R16 \ 00000016 F4B1 BRNE ??Result_ADC_1 158 { 159 if(ADMUX & 0x01) \ 00000018 9536 LSR R19 \ 0000001A 9527 ROR R18 \ 0000001C 9536 LSR R19 \ 0000001E 9527 ROR R18 \ 00000020 9536 LSR R19 \ 00000022 9527 ROR R18 \ 00000024 9B38 SBIS 0x07, 0x00 \ 00000026 C006 RJMP ??Result_ADC_2 160 { 161 adc_ch_1 = sum_adc/N_CYCLE_ADC; \ 00000028 9320.... STS (adc_ch_0 + 2), R18 \ 0000002C 9330.... STS (adc_ch_0 + 3), R19 162 ADMUX &= ~(1<<MUX0); \ 00000030 9838 CBI 0x07, 0x00 \ 00000032 C005 RJMP ??Result_ADC_3 163 } 164 else 165 { 166 adc_ch_0 = sum_adc/N_CYCLE_ADC; \ ??Result_ADC_2: \ 00000034 9320.... STS adc_ch_0, R18 \ 00000038 9330.... STS (adc_ch_0 + 1), R19 167 ADMUX |= (1<<MUX0); \ 0000003C 9A38 SBI 0x07, 0x00 168 } 169 counter = N_CYCLE_ADC; \ ??Result_ADC_3: \ 0000003E E008 LDI R16, 8 170 sum_adc = 0; \ 00000040 E020 LDI R18, 0 \ 00000042 E030 LDI R19, 0 171 } \ ??Result_ADC_1: \ 00000044 .... RJMP ?Subroutine0 \ 00000046 REQUIRE _A_ADC \ 00000046 REQUIRE _A_ADMUX \ 00000046 REQUIRE _A_ADCSRA 172 173 ADCSRA |= (1 << ADSC); 174 } В итоге большое спасибо за помощь, особенно за тильду. А то я "смотрю в книгу, вижу фигу". Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
VladislavS 29 2 мая, 2020 Опубликовано 2 мая, 2020 · Жалоба 46 минут назад, IF_P сказал: А что касается Вашего кода, то мой компилятор выдает немного другой код. Вот!!! Именно поэтому ваши ассемблерные костыли это огромное зло. Код вне функции влияет на то как компилятор будет распределять ресурсы и внутри функции. А вы там уже жёстко регистров понаписали. Забудьте про asm, он нужен только в экстренных случаях. И не так как вы его используете. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
NStorm 0 2 мая, 2020 Опубликовано 2 мая, 2020 · Жалоба По поводу отладки в протеусе - он очень тяжко и плохо воспринимает debug инфу от разных компиляторов, кроме WinAVR от 2010 года. Он даже с более новыми версиями avr-gcc некорректно работает при отладке, точно также пропускает строки кода. А вы хотите с IAR заставить его работать. Он ведь официально IAR для AVR не поддерживает. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
IF_P 1 2 мая, 2020 Опубликовано 2 мая, 2020 · Жалоба 1 hour ago, NStorm said: По поводу отладки в протеусе - он очень тяжко и плохо воспринимает debug инфу от разных компиляторов Я бы так не сказал. Я не "заставляю" его работать, а просто работаю с ним и IAR'ом. Отладку в Proteus'е я делаю уже более 10 лет. В нем я отлаживаю до 95% кода. Остальное отлаживаю в железе. И то потому, что либо нет моделей, либо сложно моделировать и в железе проще. Конечно, попадались глюки самого Proteus'а. Но потом их исправляли. Что-то было с пропуском строк раз или два, но сейчас не помню. Да я и не разбирался тогда с ними. Возможно, это было связано с самой программой, а не с Proteus'ом, как в выше приведенном случае. Просто Proteus сопоставляет листинг программы и ubrof. А в моем случае в ubrof'е, в результате оптимизации, не было того кода, что в листинге. Вот он и пропустил эти строки. Я выше уже написал это. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
NStorm 0 2 мая, 2020 Опубликовано 2 мая, 2020 · Жалоба Протеус и знать ничего не знает о ubrof афаик. Это проприетарный формат IAR'а. Он берет обычную coff/dwarf дебаг информацию из elf файла. Вы просто отключили оптимизацию и стало работать. Хотя должно работать и с оптимизацией. Я вам говорю реально простой пример - берем ASR-GCC 9.3 и комплируем им проект с опцией -Os -g - хрень полная получается в отладке протеуса полная. Тот же самый исходник с теми же самыми опциями, просто собранный AVR-GCC 4.х из WinAVR-2010.... прекрасно пошагово дебажится в протеусе без пропусков и проблем. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
IF_P 1 3 мая, 2020 Опубликовано 3 мая, 2020 (изменено) · Жалоба 14 hours ago, NStorm said: Протеус и знать ничего не знает о ubrof афаик. Это проприетарный формат IAR'а. Да неужели? А может все таки для начала стоит почитать документация по Proteus'у? Например, вот такую: ("Proteus Manual.pdf"). И вот что написано в этом документе: ("Ubrof.png") Обратите внимание на слова "where possible "- т.е. где возможно. А если такой возможности нет, то, следовательно, строки пропускаются. Приведу еще раз пример из моей программы: 152 void Result_ADC (void) \ ??Result_ADC: 153 { 154 static uint sum_adc; 155 static uchar ch_adc; 156 uchar low_adc, high_adc; 157 uint adc_value; 158 159 low_adc = ADCL; \ 00000000 B104 IN R16, 0x04 160 high_adc = ADCH; 161 adc_value = high_adc * 256 + low_adc; 162 sum_adc += adc_value; \ 00000002 B135 IN R19, 0x05 \ 00000004 2F20 MOV R18, R16 \ 00000006 9100.... LDS R16, (message_buf + 22) \ 0000000A 9110.... LDS R17, (message_buf + 23) \ 0000000E 0F02 ADD R16, R18 \ 00000010 1F13 ADC R17, R19 \ 00000012 9300.... STS (message_buf + 22), R16 \ 00000016 9310.... STS (message_buf + 23), R17 Строки 159-161 Proteus пропускает. А что бы Вы делали на его месте? Локальные переменные low_adc и high_adc (с.159-160) не существуют - они заменены р-рами. А строку 161 компилятор вообще выбросил за ненадобностью. А что касается WinAVR или других систем, то я с ними не работал и поэтому ничего сказать не могу. P.S. Или вот еще. Proteus Manual.pdf Изменено 3 мая, 2020 пользователем IF_P Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться