#c #bit-shift #atmega
#c #смещение бита #atmega
Вопрос:
Я использую Atmega 16 на плате программатора STK500. я пытаюсь включить светодиоды на DDRA, начиная с Led0 с 0b00000001 до Led7 с 0b1000000. Кажется, что я выталкиваю установленный бит из регистра с помощью >> сдвига. Не следует ли просто переместить 1 вправо? У меня есть этот фрагмент
# define F_CPU 8000000UL
#include <util/delay.h>
#include <avr/io.h>
int main(void)
{
DDRA=0xFF;
char leds=0x01;
while(1)
{
if (leds==0x01)
{
for (int i=0;i<8;i )
{
PORTA=~leds;
leds=leds<<1;
_delay_ms(300);
}
}
else
for (int x=0;x<8;x )
{
leds=leds>>1;
PORTA=~leds;
_delay_ms(300);
}
}
}
похоже, что эта часть
for (int x=0;x<8;x )
{
leds=leds>>1;
PORTA=~leds;
_delay_ms(300);
}
выталкивает бит из регистра, но этого не должно быть. я совершаю ошибку?
Комментарии:
1. Какой дисплей вы получаете и какой дисплей вы ожидаете?
2. Прежде чем пытаться заставить это работать на микроконтроллере, попробуйте это на своем компьютере, просто распечатывая биты
leds
на каждой итерации. Вы быстро увидите, насколько ваши ожидаемые результаты отличаются от того, что на самом деле делает математика.3. @Sneftel Нет. Просто проверьте фактическое значение регистра с помощью встроенного отладчика…
4. подсказка: каково значение светодиодов после первого раза с помощью инструкции while. Как это будет обработано во второй раз в цикле while? И, насколько я вижу, else выполняется во второй раз.
5. Здесь у вас есть некоторые ошибки, которые не обязательно связаны с проблемой. Ошибка 1) Вы никогда не должны использовать
char
для 8-битной арифметики, поскольку она имеет определяемую реализацией подписанность. Используйтеuint8_t
вместо этого. Ошибка 2) Ваш MCU содержит 16-битные целые числа, и все типы малых целых чисел будут неявно переведены в signedint
. В случае, еслиleds
для индикатора MSB установлено значение 0x80, вы вызываете неопределенное поведение путем сдвигаleds
в 8 раз влево. Вы вызываете поведение, определяемое реализацией, путем сдвигаleds
8 раз вправо. Всегда приводитеleds
кuint16_t
перед сдвигом.
Ответ №1:
Вы смещаете 1 в первом цикле. И вы не видите, потому что вы обновляете отображение перед сдвигом.
В конце итерации с i = 0 значения leds будут равны 0x02. Итак, следуя этой логике, вы получаете:
i, leds (end of the loop)
0, 0x02
1, 0x04
2, 0x08
3, 0x10
4, 0x20
5, 0x40
6, 0x80
7, 0x00
Комментарии:
1. Да, я надеялся, что OP сможет решить это самостоятельно.
2. да, моей проблемой было обновление дисплея перед переключением. я предположил, что светодиоды будут указывать, какой бит установлен.
3. @barny, извините, я не видел вашего комментария.