Не считывается регистр UCSRC в ATmega16A

Обсуждаем контроллеры компании Atmel.
Ответить
Родился
Сообщения: 15
Зарегистрирован: Вт дек 12, 2023 14:29:05

Сообщение Andrew33 »

Добрый день!
Не получается считать значение UCSRC в Mega16a. Согласно даташиту и форумам это делается так:
cli();
vrem = UBRRH;
vrem = UCSRC;
sei();
UBRRH и UCSRC находятся по одному адресу. Читать надо последовательно. На втором чтении выдает значение UCSRC.
У меня же хоть один, хоть два раза читай - UBRRH вылезает. Может кто сталкивался с таким?
Просто переписал библиотеку по modbus и хочу проверить меняется ли количество стоп бит, а никак не посмотреть
Реклама
Мучитель микросхем
Сообщения: 466
Зарегистрирован: Чт май 07, 2026 00:30:38

Сообщение Zapolyarny »

Во-первых, состояние управления URSEL?
Во-вторых, это симулятор или реальный микроконтроллер?
В-третьих, vrem - это что?
Ну и вообще, Вы привели листинг Си. А микроконтроллер будет выполнять то, что ему даст компилятор. А компилятор имеет варианты компиляции. Поэтому, не мешало бы смотреть листинг ассемблера.
Реклама
Родился
Сообщения: 15
Зарегистрирован: Вт дек 12, 2023 14:29:05

Сообщение Andrew33 »

URSEL на чтение, насколько я понимаю, не влияет. Только на запись.
Реальный контроллер, vrem - просто переменная, которую потом по modbus на комп пересылаю и смотрю

vrem = UBRRH;
000001B4 IN R24,0x20 In from I/O location
000001B5 STS 0x0277,R24 Store direct to data space
265: vrem = UCSRC;
000001B7 IN R24,0x20 In from I/O location
000001B8 STS 0x0277,R24 Store direct to data space
266: sei();

да, действительно добавляется команда STS Может из за нее два раза одно и то же получается?
Мучитель микросхем
Сообщения: 466
Зарегистрирован: Чт май 07, 2026 00:30:38

Сообщение Zapolyarny »

Вполне может. Чтобы проверить это, сделайте ассемблерной вставкой:
cli();
asm volatile (
"in __tmp_reg__, 0x20 \n\t" // 1-е чтение (UBRRH)
"in __tmp_reg__, 0x20 \n\t" // 2-е чтение подряд (UCSRC)
"sts vrem, __tmp_reg__ \n\t"
);
sei();
(я не помню формат, попросил ии)
Ну или обманом компилятора (не очень хорошо, может в какой-то момент оптимизироваться, если компилятор решит, что операция с UCSRC больше не волатильная):

cli();
vrem = UCSRC;
vrem = UCSRC;
sei();
Andrew33 писал(а): Чт авг 27, 2026 11:33:32 vrem - просто переменная
Си - язык строгой типизации, в нём не бывает просто переменных. Вопрос был про то, как она объявлена.
Реклама
Эиком - электронные компоненты и радиодетали
OKF
Это не хвост, это антенна
Сообщения: 1445
Зарегистрирован: Вт июн 07, 2011 08:03:18

Сообщение OKF »

Andrew33 писал(а): Чт авг 27, 2026 11:33:32 да, действительно добавляется команда STS Может из за нее два раза одно и то же получается?
Дважды подряд чтение из одного и того же порта ВВ должно быть! STS тут никак влиять не может.
Реклама
Мучитель микросхем
Сообщения: 466
Зарегистрирован: Чт май 07, 2026 00:30:38

Сообщение Zapolyarny »

Почему не может?
я вот глянул спецификацию, там строго указано

Код: Выделить всё

in r16,UBRRH
in r16,UCSRC
ret
и сказано:
If the register location was read in previous system clock cycle, reading the register in the current clock cycle will return the UCSRC contents
Полагаете, STS никак на такты не повлияет?

Вообще, влияет или нет должен показать URSEL. Вроде бы. Не установка, а состояние его. Это если додумывать спецификацию, где:
It is read as zero when reading UBRRH
Значит, если он 1 - то прочтён UCSRC. Возможно.
Реклама
Родился
Сообщения: 15
Зарегистрирован: Вт дек 12, 2023 14:29:05

Сообщение Andrew33 »

Да, дело было в лишней команде (STS). Ассемблерная вставка помогла. И да, при прочтении UCSRC URSEl сам устанавливается в 1.
Спасибо за наводку
Ответить

Вернуться в «AVR»