Вопрос: как обращаться напрямую к регистрам микроконтроллеров 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...
int main (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" и значение не меняется, какое бы оно в тот момент ни было.
Вы не можете начинать темы Вы не можете отвечать на сообщения Вы не можете редактировать свои сообщения Вы не можете удалять свои сообщения Вы не можете добавлять вложения