Перейти к содержанию
    

Регистры сравнения через указатель

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

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

megajohn, спасибо, заработало!

 

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

Так в этом нет ничего страшного, регистры сравнения 8 битные и адреса их тоже.

Так что все нормально.

Нужно будет только выбрать для 16 битного таймера OCR1AL или OCR1AH

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

вот такой код в иаре компилится и должен работать

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

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Какой-то у нас разный IAR. Тут ошибка. Адресное пространство неверно выбрано.
Да ладно! Весь ввод-вывод живет в том же адресном пространстве, что и ОЗУ. Если __io - это расширение для доступа командами IN/OUT, то не нужно через него пытаться лезть к OCR - потому что часть OCR просто не доступна через это адресное пространство.

 

Читайте внимательно текст ошибки: это внутренняя ошибка компилятора, то есть программисты что-то не предусмотрели внутри компилятора, надо сообщить им и ждать более новой версии.

 

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Если __io - это расширение для доступа IN/OUT, то не нужно через него пытаться лезть к OCR - потому что часть OCR просто не доступна через это адресное пространство.

С __io компилятор сам разбирается где IN, а где STS использовать. Смотрите листинг. Без него, по идее, всё должно как ОЗУ трактоваться, но компилятор попытался OUT воткнуть и обломался.

 

Читайте внимательно текст ошибки: это внутренняя ошибка компилятора, то есть программисты что-то не предусмотрели внутри компилятора, надо сообщить им и ждать более новой версии.
Версия последняя.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

С __io компилятор сам разбирается где IN, а где STS использовать. Смотрите листинг. Без него, по идее, всё должно как ОЗУ трактоваться, но компилятор попытался OUT воткнуть и обломался.

Безусловно это внутренняя ошибка IAR. Даже листинг смотреть не стоит достаточно посмотреть на сообщение:

Illegal instruction: 68 ( OUT 0x48, R16)

IAR пытается оформить команду ввода-вывода OUT, но почему-то адрес операнда модифицирует для выполнения команды работы с памятью: 0x28 -> 0x48, поэтому и испытывает крайний внутренний дискомфорт. Правильная команда вывода должна быть OUT 0x28, R16.

 

 

 

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Присоединяйтесь к обсуждению

Вы можете написать сейчас и зарегистрироваться позже. Если у вас есть аккаунт, авторизуйтесь, чтобы опубликовать от имени своего аккаунта.

Гость
Ответить в этой теме...

×   Вставлено с форматированием.   Вставить как обычный текст

  Разрешено использовать не более 75 эмодзи.

×   Ваша ссылка была автоматически встроена.   Отображать как обычную ссылку

×   Ваш предыдущий контент был восстановлен.   Очистить редактор

×   Вы не можете вставлять изображения напрямую. Загружайте или вставляйте изображения по ссылке.

×
×
  • Создать...