technik-1017 0 8 июля, 2018 Опубликовано 8 июля, 2018 · Жалоба если я не ошибаюсь, то каналы ШИМ в mega48 имеют разную разрядность, одни построены на 8-битном таймере, другие на 16-битном, вы же определяере все OCR как 8-битные Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
s_gary 0 8 июля, 2018 Опубликовано 8 июля, 2018 · Жалоба megajohn, спасибо, заработало! если я не ошибаюсь, то каналы ШИМ в mega48 имеют разную разрядность, одни построены на 8-битном таймере, другие на 16-битном, вы же определяере все OCR как 8-битные Так в этом нет ничего страшного, регистры сравнения 8 битные и адреса их тоже. Так что все нормально. Нужно будет только выбрать для 16 битного таймера OCR1AL или OCR1AH Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
VladislavS 29 9 июля, 2018 Опубликовано 9 июля, 2018 · Жалоба вот такой код в иаре компилится и должен работать 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 Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Сергей Борщ 119 9 июля, 2018 Опубликовано 9 июля, 2018 · Жалоба Какой-то у нас разный IAR. Тут ошибка. Адресное пространство неверно выбрано.Да ладно! Весь ввод-вывод живет в том же адресном пространстве, что и ОЗУ. Если __io - это расширение для доступа командами IN/OUT, то не нужно через него пытаться лезть к OCR - потому что часть OCR просто не доступна через это адресное пространство. Читайте внимательно текст ошибки: это внутренняя ошибка компилятора, то есть программисты что-то не предусмотрели внутри компилятора, надо сообщить им и ждать более новой версии. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
VladislavS 29 9 июля, 2018 Опубликовано 9 июля, 2018 · Жалоба Если __io - это расширение для доступа IN/OUT, то не нужно через него пытаться лезть к OCR - потому что часть OCR просто не доступна через это адресное пространство. С __io компилятор сам разбирается где IN, а где STS использовать. Смотрите листинг. Без него, по идее, всё должно как ОЗУ трактоваться, но компилятор попытался OUT воткнуть и обломался. Читайте внимательно текст ошибки: это внутренняя ошибка компилятора, то есть программисты что-то не предусмотрели внутри компилятора, надо сообщить им и ждать более новой версии.Версия последняя. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
aiwa 0 9 июля, 2018 Опубликовано 9 июля, 2018 · Жалоба С __io компилятор сам разбирается где IN, а где STS использовать. Смотрите листинг. Без него, по идее, всё должно как ОЗУ трактоваться, но компилятор попытался OUT воткнуть и обломался. Безусловно это внутренняя ошибка IAR. Даже листинг смотреть не стоит достаточно посмотреть на сообщение: Illegal instruction: 68 ( OUT 0x48, R16) IAR пытается оформить команду ввода-вывода OUT, но почему-то адрес операнда модифицирует для выполнения команды работы с памятью: 0x28 -> 0x48, поэтому и испытывает крайний внутренний дискомфорт. Правильная команда вывода должна быть OUT 0x28, R16. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться