Вопрос: как обращаться напрямую к регистрам микроконтроллеров 1-й серии Attiny (в моем случае Attiny212)? В даташите указаны привычные названия регистров и названия их битов. Но я не могу по этим названиям к ним обратиться. Вместо этого используются нелепые конструкции с битовыми масками и какими то Microchip-кими загонами. Среда разработки: IDE - VSCode and PlatformIO. Win-AVR-GCC Язык: C
Для конфигурации таймера TCA0 в режим прерывания по переполнению, в заголовочном файле iotn212.h, прописаны битовые маски совершенно упорантского вида аля STM-кие. То есть я должен написать: TCA0.SINGLE.INTCTRL= TCA_SINGLE_OVF_bm; Для сравнения такой же код для ATiny13 счетчика: TIMSK0=1<<TOIE0; То есть как написано в даташите так и пишем и это удобно. Всегда можно открыть даташит и вспомнить. В случае же с Attiny212 в даташите так же указаны такие же регистры, но без битовых масок я не могу обратиться к ним на прямую.
Вот например регистр конфигурации прерываний INTCTRL
Его маска выглядит так:
Логично, для конфигурации таймера по переполнению я должен написать: INTCTRL= 1<<OVF; Но в место этого: TCA0.SINGLE.INTCTRL= TCA_SINGLE_OVF_bm; Причем в бинарном варианте можно написать: TCA0.SINGLE.INTCTRL=0b00000001; Но по названию регистра INTCTRL=0b00000001; нельзя....
Возможно проблема в фреймворке Arduino под которым работает PlatformIO с этим контроллером, но пишу то я на C со стандартными функциями Win-AVR-GCC...
intmain(void){ PORTA.DIR=PIN1_bm|PIN2_bm|PIN3_bm;//пины сконфигурированы как "выход" PORTA.DIR&=~PIN7_bm|~PIN6_bm;//пины сконфигурированы как "вход"
PORTA.OUT&=~PIN1_bm|~PIN2_bm|~PIN3_bm;//подтяжка к GND PORTA.OUT=PIN0_bm|PIN6_bm|PIN7_bm;//подтяжка к VCC
TCA0.SINGLE.INTCTRL= TCA_SINGLE_OVF_bm;//прерывания по переполнению таймера TCA0 INTCTRL= 1<<OVF; // НЕ РАБОТАЕТ INTCTRL= 0b00000001; // НЕ РАБОТАЕТ TCA0.SINGLE.INTCTRL=0b00000001;// РАБОТАЕТ
sei();
while (1) {
if (~PORTA.IN & PIN7_bm) {PORTA.OUTSET=PIN2_bm;} else {PORTA.OUTCLR=PIN2_bm;}
} }
Последний раз редактировалось dds7sdd Ср дек 25, 2024 20:34:26, всего редактировалось 1 раз.
Для тех МК в ардуино IDE отдельная "платформа" (из категории "внесены")... Причем весьма навороченная (обычно там и отличия от стандартных в комплекте загружаются). Была б ардуино IDE - дал бы ссылку на установку... Как в VSCode and PlatformIO устанавливается - сего не ведаю...
Для конфигурации таймера TCA0 в режим прерывания по переполнению, в заголовочном файле iotn212.h, прописаны битовые маски совершенно упорантского вида аля STM-кие. То есть я должен написать: TCA0.SINGLE.INTCTRL= TCA_SINGLE_OVF_bm;
Все познается в сравнении... На Pico, например, определения могут быть такими, потому что отличии от STM32 они даже не сдвинуты )
Ну и нафига так делать и усложнять?? В AVR 0-siries было все понятно и просто. Да и здесь в даташите названия регистров в прежнем формате, только вот не могу понять как к ним обращаться без говномасок микрочиповских...
Обычно раньше в документации все выкладывалось. Но после "перехода в микрощип" соответственно и подход к документации изменился "в стиле микрощипа" - т.е. помимо даташита на конкретную микросхему есть еще несколько документов на всю группу и на прошивку... Честно - не лез пока в те "дебри" с новинками настолько глубоко - пока и "стандартных" вполне хватает. А с учетом "ссакций" еще неизвестно, чего дальше удобным и доступным будет...
Чем сложнее мк, тем больше регистров и полей, тем больше вероятность пересечения названий, потому ничего удивительного в добавлении названия регистра не вижу, так и должно быть. А SINGLE добавляется потому что у таймера есть режимы Normal и Split.
Чем сложнее мк, тем больше регистров и полей, тем больше вероятность пересечения названий, потому ничего удивительного в добавлении названия регистра не вижу, так и должно быть. А SINGLE добавляется потому что у таймера есть режимы Normal и Split.
Чем 8 бит МК Attiny212 сложнее 8 бит Attiny85?? Более того, у них и формат регистров в даташите одинаков!
Но нет же, Микрочипу нужно выипнуться и сделать совершенно противоположный подход с масками и усложнить максимально переход от классических AVR... Зачем?
Да те же IO чего стоят... В классическом AVR:
DDRA=1<<PB1; PORTA=1<<PB1; И всё! Порт настроен как выход с подтяжкой к VCC...
Что мы видим на аналогичном МК 8-бит новой генерации?? Вот: PORTA.DIR=PIN1_bm; PORTA.OUT=PIN1_bm; PORTA.PIN1CTRL = PORT_PULLUPEN_bm;
И там еще всякие: PORTA.SET PORTA.CLR и тд. и т.п.... Вопрос: нахиба? Если все решается так же просто побитово как и в аттини 85....
Чем сложнее мк, тем больше регистров и полей, тем больше вероятность пересечения названий, потому ничего удивительного в добавлении названия регистра не вижу, так и должно быть. А SINGLE добавляется потому что у таймера есть режимы Normal и Split.
Режимы таймера аля NORMAL, CTC и т. д. в AVR всегда выставлялись отдельными битами и это никак не связано с названиями регистров и что они как то могут пересекаться. Например режим CTC mode в Attiny85:
TCCR1 = 1<<CTC1;
Что мешало сделать в Attiny212 так же?? Религия? Тем более регистры и биты ведь такие же...
Добавлено after 3 minutes 51 second: Это мне напоминает версии Windows, где задачей разработчиков есть сделать так, что бы интерфейс взаимодействия с пользователем был максимально противоположен тому что был в предыдущей версии...
И там еще всякие: PORTA.SET PORTA.CLR и тд. и т.п.... Вопрос: нахиба? Если все решается так же просто побитово как и в аттини 85....
На tiny85 если хочешь просто помигать светодиодом в главном цикле, то нужно или на время записи в порт выключать прерывания или гарантировать отсутствие записи в другие биты этого порта из прерывания, а эти регистры SET/CLR/TOGGLE позволяют такое делать не выключая прерывания. Их аналоги есть в большинстве современных мк, на STM32 для этого используют регистр BSRR. Фактически PORTA.OUT только на стадии инициализации стоит использовать, во время работы писать при помощи него в порт стоит только если записать нужно все 8 бит.
Честно - не лез пока в те "дебри" с новинками настолько глубоко - пока и "стандартных" вполне хватает.
Я еще повелся на новый протокол прошивки без программатора по одному кабелю UPDI, аппаратные SPI, I2C, UART на борту, 16 битный таймер с возможностью разбивки на два 8-битных, RTC, IRDA да и много фич по работе с питанием... И стоит это всё те же 1$ как и Attiny13, но разница на лицо!
Adrift Никогда не встречал, чтоб прерывания не позволяли выполнять запись данных в порт вывода... Ежли только не изворачиваться с прерыванием и работой с одним и тем же битом порта (теоретически). Может имелся ввиду какой иной изврат?
регистры SET/CLR/TOGGLE позволяют такое делать не выключая прерывания. Их аналоги есть в большинстве современных мк, на STM32 для этого используют регистр BSRR.
Типа двойная буфферизация? Ну я еще не дочитал даташит... подгорело в самом начале...
Добавлено after 3 minutes 16 seconds: То что я прочитал про SET/CLR/TGL - это биты на запись только, а вот в сравнении с OUT - запись\чтение. Вроде это и вся разница
Есть всевозможные варианты. Написать свой драйвер? Но почему? Привыкайте к этому. На второй месяц все будет нормальным. Сужу само собой за STM32. Напр. о GPIOC->BRR = BSRR_VAL; было странно, запутанно, и отвратительно. Но к очень быстро привыкаешь. Теперь стало более предпочтительным. (частично использоваю переводчика)
Расширенное управление добавляется для дополнительных удобств. Но основ не меняет - так что возврат к старым проектам только добавляет возможных вариантов для решения задачи.
Никогда не встречал, чтоб прерывания не позволяли выполнять запись данных в порт вывода... Ежли только не изворачиваться с прерыванием и работой с одним и тем же битом порта (теоретически).
Допустим в PORTA у нас 0x35 и мы хотим в основном цикле записать новое значение в младшие 4 бита порта, например, 7. Не важно 1 бит или 4, придется сначала прочитать значение из PORTA, очистить 4 младших бита, наложить новое значение и записать обратно: 0x35 & 0xF0 | 0x07 = 0x37 Однако после чтения из порта, но до записи нового значения обратно, вызывается прерывание которое меняет 4 старших бита PORTA на 0xF: 0x35 & 0x0F | 0xF0 = 0xF5 Вернувшись из прерывания прерванная операция завершается записью в порт 0x37, а должно быть 0xF7.
Теперь то же самое с PORTA.TGL:
Код:
PORTA.TGL = PORTA.OUT ^ 0x07 & 0x0F;
Это работает поскольку при записи Toggle фактически выполняет функцию XOR, то есть получается следующее: PORTA.OUT ^ (PORTA.OUT ^ 0x07 & 0x0F) = PORTA.OUT ^ 0x02 = 0x37 При этом для старших 4 бит выполняется "value XOR 0" и значение не меняется, какое бы оно в тот момент ни было.
Сейчас этот форум просматривают: нет зарегистрированных пользователей и гости: 10
Вы не можете начинать темы Вы не можете отвечать на сообщения Вы не можете редактировать свои сообщения Вы не можете удалять свои сообщения Вы не можете добавлять вложения