|
Регистры сравнения через указатель, iar avr Compiler V6.12.1.50500 |
|
|
|
Jul 8 2018, 12:47
|

Местный
  
Группа: Свой
Сообщений: 494
Регистрация: 23-06-09
Из: Полтава, UA
Пользователь №: 50 579

|
Здравствуйте, почему не работает такой код, что я еще не дописал? Вверху глобальной переменной OCR инициализирован массив, которому присвоены адреса 6-ти регистров сравнения атмега48, а внизу процедура (цикл убрал) в которой по циклу необходимо присваивать значения в выбранный регистр. Если имя массива и есть указатель на массив, то почему нижняя строка идет как ошибка?
Эскизы прикрепленных изображений
|
|
|
|
2 страниц
1 2 >
|
 |
Ответов
(1 - 20)
|
Jul 8 2018, 14:45
|
Группа: Участник
Сообщений: 12
Регистрация: 3-09-17
Пользователь №: 99 108

|
OCR это не РЕГИСТРЫ сравнения, а ПОРТЫ, вы пытаетесь обратиться к портам по указателю? Или какая цель этого кода? Что вы хотите получить? Наверно необходимо преобразование типа OCR до типа определения портов, чтобы компилятор понял, что это не адресное пространство RAM почитайте здесь (2. Передача порта через указатель) http://easyelectronics.ru/rabota-s-portami...erov-na-si.html
Сообщение отредактировал technik-1017 - Jul 8 2018, 14:52
--------------------
|
|
|
|
|
Jul 8 2018, 16:49
|
Местный
  
Группа: Свой
Сообщений: 475
Регистрация: 14-04-05
Из: Москва
Пользователь №: 4 140

|
Цитата(Ga_ry @ Jul 8 2018, 18:35)  SFR_B_R(0xB4, OCR2B) Ну а дальше пройтись и посмотреть что это значит не судьба? Небольшая цитатка из документации, чтобы осознать глубину задачи. Звёздочкой тут не отделаться, это вам не ARM. Цитата Memory attributes A memory attribute corresponds to a certain logical or physical memory in the microcontroller. Available function memory attributes: __nearfunc, __farfunc Available data memory attributes: __tiny, __near, __far, __huge, __regvar, __eeprom, __tinyflash, __flash, __farflash, __hugeflash, __generic, __io, and __ext_io. Data objects, functions, and destinations of pointers or C++ references always have a memory attribute. If no attribute is explicitly specified in the declaration or by the pragma directive #pragma type_attribute, an appropriate default attribute is implicitly used by the compiler. You can specify one memory attribute for each level of pointer indirection.
|
|
|
|
|
Jul 8 2018, 17:27
|
Местный
  
Группа: Свой
Сообщений: 475
Регистрация: 14-04-05
Из: Москва
Пользователь №: 4 140

|
Нет, я сейчас не занимаюсь AVR. Просто по старой памяти  Хотя нет, могу. Код OCR0A = pwm_tab[idx1];
|
|
|
|
|
Jul 8 2018, 18:02
|
Местный
  
Группа: Свой
Сообщений: 475
Регистрация: 14-04-05
Из: Москва
Пользователь №: 4 140

|
Да блин, ну я же цитату с документации не зря привёл! Код const uint8_t reg = 0x27; *(__io uint8_t *)reg = 0x55; Код // 12 *(__io uint8_t *)reg = 0x55; LDI R16, 85 OUT 0x27, R16 Для массива сами раскрутите...
|
|
|
|
|
Jul 8 2018, 18:54
|

Местный
  
Группа: Свой
Сообщений: 494
Регистрация: 23-06-09
Из: Полтава, UA
Пользователь №: 50 579

|
Извиняюсь, цитату я как раз пропустил читаю с телефона. Нет, все равно не идет даже без массива: Код const unsigned char OCR = 0x27; void cycle_1(void) { *(__io unsigned char *) OCR = pwm_tab[idx1]; } Строки с ошибкой теперь не выделяются а просто в сообщениях компилятор пишет. Tool Internal Error: Internal Error: [CoreUtil/General]: Illegal state Это точно для iar avr?
|
|
|
|
|
Jul 8 2018, 18:59
|
Местный
  
Группа: Свой
Сообщений: 475
Регистрация: 14-04-05
Из: Москва
Пользователь №: 4 140

|
Цитата(Ga_ry @ Jul 8 2018, 21:54)  Это точно для iar avr? Точнее не бывает. И с массивом тоже работает. idx1 как определено?
|
|
|
|
|
Jul 8 2018, 19:32
|

Профессионал
    
Группа: Свой
Сообщений: 1 080
Регистрация: 16-11-04
Из: СПб
Пользователь №: 1 143

|
Цитата(Ga_ry @ Jul 8 2018, 16:47)  Здравствуйте, почему не работает такой код, что я еще не дописал? вот такой код в иаре компилится и должен работать unsigned char volatile* ocr_arr[] = { &OCR0A, &OCR0B }; *ocr_arr[0] = *ocr_arr[1] = 12;
--------------------
Марс - единственная планета, полностью населенная роботами (около 7 штук).
|
|
|
|
|
Jul 8 2018, 19:37
|
Группа: Участник
Сообщений: 12
Регистрация: 3-09-17
Пользователь №: 99 108

|
если я не ошибаюсь, то каналы ШИМ в mega48 имеют разную разрядность, одни построены на 8-битном таймере, другие на 16-битном, вы же определяере все OCR как 8-битные
--------------------
|
|
|
|
|
Jul 8 2018, 19:41
|

Местный
  
Группа: Свой
Сообщений: 494
Регистрация: 23-06-09
Из: Полтава, UA
Пользователь №: 50 579

|
megajohn, спасибо, заработало! Цитата(technik-1017 @ Jul 8 2018, 22:37)  если я не ошибаюсь, то каналы ШИМ в mega48 имеют разную разрядность, одни построены на 8-битном таймере, другие на 16-битном, вы же определяере все OCR как 8-битные Так в этом нет ничего страшного, регистры сравнения 8 битные и адреса их тоже. Так что все нормально. Нужно будет только выбрать для 16 битного таймера OCR1AL или OCR1AH
|
|
|
|
|
Jul 9 2018, 03:21
|
Местный
  
Группа: Свой
Сообщений: 475
Регистрация: 14-04-05
Из: Москва
Пользователь №: 4 140

|
Цитата(megajohn @ Jul 8 2018, 22:32)  вот такой код в иаре компилится и должен работать unsigned char volatile* ocr_arr[] = { &OCR0A, &OCR0B }; *ocr_arr[0] = *ocr_arr[1] = 12; Какой-то у нас разный IAR. Тут ошибка. Адресное пространство неверно выбрано. Цитата Internal Error: [TaInstr::TaInstr]: Illegal instruction: 68 ( OUT 0x48, R16) Тогда уж правильно вот так Код uint8_t volatile __io * const ocr_arr[] = {&OCR0A, &OCR0B }; *ocr_arr[0] = *ocr_arr[1] = 12; =======================================
// 16 *ocr_arr[0] = *ocr_arr[1] = 12; LDI R16, 12 OUT 0x28, R16 OUT 0x27, R16 Не уверен что это будет работать, вот смотрите. Держу пари, вы не этого хотели. Код uint8_t volatile __io * ocr_arr[] = {&OCR0A, &OCR0B, &OCR1AL, &OCR1BL, &OCR2A, &OCR2B }; for(uint8_t i=0; i<6; i++) *ocr_arr[i] = i; =============================================================
MOVW R19:R18, R27:R26 SBIW R29:R28, 6 // 15 uint8_t volatile __io * ocr_arr[] = {&OCR0A, &OCR0B, &OCR1AL, &OCR1BL, &OCR2A, &OCR2B }; MOVW R17:R16, R29:R28 LDI R30, LOW(`?<Constant {(uint8_t volatile __io *)(&OCR0A),`) LDI R31, (`?<Constant {(uint8_t volatile __io *)(&OCR0A),`) >> 8 LDI R20, 6 LDI R21, 0 RCALL ?ML_FLASH_SRAM_16EC_16_L07 // 16 for(uint8_t i=0; i<6; i++) *ocr_arr[i] = i; LDI R17, 0 MOVW R27:R26, R29:R28 LDI R16, 6 ??main_0: LD R30, X+ LDI R31, 0 ST Z, R17 INC R17 DEC R16 BRNE ??main_0 И вообще, зачем эти извращения? Если нужно записать шесть регистров, то проще и быстрее просто записать эти шесть регистров. Ну не десятки их в конце концов. Прочувствуйте разницу. Код OCR0A = 0; OCR0B = 1; OCR1AL = 2; OCR1BL = 3; OCR2A = 4; OCR2B = 5; =================================================
LDI R16, 0 OUT 0x27, R16 LDI R16, 1 OUT 0x28, R16 LDI R16, 2 STS _A_OCR1A, R16 LDI R16, 3 STS _A_OCR1B, R16 LDI R16, 4 STS _A_OCR2A, R16 LDI R16, 5 STS _A_OCR2B, R16 PS: Хотя, если поиграться с расположением массива, то можно немного выиграть. Но всё равно, не торт. И 100% уверенности что записи попадут куда надо нет. Код static uint8_t volatile __io * const ocr_arr[] = {&OCR0A, &OCR0B, &OCR1AL, &OCR1BL, &OCR2A, &OCR2B }; for(uint8_t i=0; i<6; i++) *ocr_arr[i] = i;
======================================== LDI R17, 0 LDI R26, LOW(??ocr_arr) LDI R27, (??ocr_arr) >> 8 LDI R16, 6 LDI R31, 0 ??main_0: LD R30, X+ ST Z, R17 INC R17 DEC R16 BRNE ??main_0
|
|
|
|
|
Jul 9 2018, 07:29
|

Гуру
     
Группа: Модераторы
Сообщений: 8 455
Регистрация: 15-05-06
Из: Рига, Латвия
Пользователь №: 17 095

|
QUOTE (VladislavS @ Jul 9 2018, 06:21)  Какой-то у нас разный IAR. Тут ошибка. Адресное пространство неверно выбрано. Да ладно! Весь ввод-вывод живет в том же адресном пространстве, что и ОЗУ. Если __io - это расширение для доступа командами IN/OUT, то не нужно через него пытаться лезть к OCR - потому что часть OCR просто не доступна через это адресное пространство. Читайте внимательно текст ошибки: это внутренняя ошибка компилятора, то есть программисты что-то не предусмотрели внутри компилятора, надо сообщить им и ждать более новой версии.
--------------------
На любой вопрос даю любой ответ"Write code that is guaranteed to work, not code that doesn’t seem to break" ( C++ FAQ)
|
|
|
|
|
Jul 9 2018, 08:20
|
Местный
  
Группа: Свой
Сообщений: 475
Регистрация: 14-04-05
Из: Москва
Пользователь №: 4 140

|
Цитата(Сергей Борщ @ Jul 9 2018, 10:29)  Если __io - это расширение для доступа IN/OUT, то не нужно через него пытаться лезть к OCR - потому что часть OCR просто не доступна через это адресное пространство. С __io компилятор сам разбирается где IN, а где STS использовать. Смотрите листинг. Без него, по идее, всё должно как ОЗУ трактоваться, но компилятор попытался OUT воткнуть и обломался. Цитата(Сергей Борщ @ Jul 9 2018, 10:29)  Читайте внимательно текст ошибки: это внутренняя ошибка компилятора, то есть программисты что-то не предусмотрели внутри компилятора, надо сообщить им и ждать более новой версии. Версия последняя.
|
|
|
|
|
Jul 9 2018, 14:08
|
Местный
  
Группа: Участник
Сообщений: 301
Регистрация: 13-12-15
Из: Харьков
Пользователь №: 89 682

|
Цитата(VladislavS @ Jul 9 2018, 11:20)  С __io компилятор сам разбирается где IN, а где STS использовать. Смотрите листинг. Без него, по идее, всё должно как ОЗУ трактоваться, но компилятор попытался OUT воткнуть и обломался. Безусловно это внутренняя ошибка IAR. Даже листинг смотреть не стоит достаточно посмотреть на сообщение: Illegal instruction: 68 ( OUT 0x48, R16) IAR пытается оформить команду ввода-вывода OUT, но почему-то адрес операнда модифицирует для выполнения команды работы с памятью: 0x28 -> 0x48, поэтому и испытывает крайний внутренний дискомфорт. Правильная команда вывода должна быть OUT 0x28, R16.
|
|
|
|
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0
|
|
|