Страница 1 из 1
Не считывается регистр UCSRC в ATmega16A
Добавлено: Чт авг 27, 2026 11:03:14
Andrew33
Добрый день!
Не получается считать значение UCSRC в Mega16a. Согласно даташиту и форумам это делается так:
cli();
vrem = UBRRH;
vrem = UCSRC;
sei();
UBRRH и UCSRC находятся по одному адресу. Читать надо последовательно. На втором чтении выдает значение UCSRC.
У меня же хоть один, хоть два раза читай - UBRRH вылезает. Может кто сталкивался с таким?
Просто переписал библиотеку по modbus и хочу проверить меняется ли количество стоп бит, а никак не посмотреть
Re: Не считывается регистр UCSRC в ATmega16A
Добавлено: Чт авг 27, 2026 11:16:45
Zapolyarny
Во-первых, состояние управления URSEL?
Во-вторых, это симулятор или реальный микроконтроллер?
В-третьих, vrem - это что?
Ну и вообще, Вы привели листинг Си. А микроконтроллер будет выполнять то, что ему даст компилятор. А компилятор имеет варианты компиляции. Поэтому, не мешало бы смотреть листинг ассемблера.
Re: Не считывается регистр UCSRC в ATmega16A
Добавлено: Чт авг 27, 2026 11:33:32
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 Может из за нее два раза одно и то же получается?
Re: Не считывается регистр UCSRC в ATmega16A
Добавлено: Чт авг 27, 2026 13:25:41
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 - просто переменная
Си - язык строгой типизации, в нём не бывает просто переменных. Вопрос был про то, как она объявлена.
Re: Не считывается регистр UCSRC в ATmega16A
Добавлено: Чт авг 27, 2026 15:20:24
OKF
Andrew33 писал(а): Чт авг 27, 2026 11:33:32
да, действительно добавляется команда STS Может из за нее два раза одно и то же получается?
Дважды подряд чтение из одного и того же порта ВВ должно быть! STS тут никак влиять не может.
Re: Не считывается регистр UCSRC в ATmega16A
Добавлено: Чт авг 27, 2026 16:25:01
Zapolyarny
Почему не может?
я вот глянул спецификацию, там строго указано
и сказано:
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. Возможно.
Re: Не считывается регистр UCSRC в ATmega16A
Добавлено: Пт авг 28, 2026 14:50:11
Andrew33
Да, дело было в лишней команде (STS). Ассемблерная вставка помогла. И да, при прочтении UCSRC URSEl сам устанавливается в 1.
Спасибо за наводку