#c #embedded
#c #встроенный
Вопрос:
Мне нужно установить PORTC во временную переменную, которая изменяется с помощью набора операторов if, но битовая последовательность, назначенная PORTC в самом конце, равна нулю, поэтому я предполагаю, что ни одно из выражений в операторах if не было оценено как true, где я проверяю, является ли битовая последовательность меньше илиравно шестнадцатеричному.
#include <avr/io.h>
unsigned char GetBit(unsigned char x, unsigned char k) {
return ((x amp; (0x01 << k)) != 0);
}
unsigned char SetBit(unsigned char x, unsigned char k, unsigned char b) {
return (b ? x | (0x01 << k) : x amp; ~(0x01 << k));
}
int main(void)
{
/* Replace with your application code */
DDRA = 0x00; PORTA = 0x0F;
DDRC = 0xFF; PORTC = 0x00;
unsigned char tmpa = 0x00;
unsigned char tmpc = 0x00;
tmpa = tmpa | PORTA;
tmpc = tmpc | PORTC;
while (1)
{
if (tmpa <= 0x02) //less than or equal to 2
{
SetBit(tmpc, 5, 1);
SetBit(tmpc, 6, 1);
}
if (tmpa <= 0x04) //less than or equal to 4
{
SetBit(tmpc, 4, 1);
SetBit(tmpc, 6, 1);
}
if (tmpa <= 0x06) //less than or equal to 6
SetBit(tmpc, 3, 1);
if (tmpa <= 0x09) //less than or equal to 9
SetBit(tmpc,2,1);
if (tmpa <= 0x0C)
SetBit(tmpc,1,1); //less than or equal to 12
if (tmpa <= 0x0F)
SetBit(tmpc,0,1); //less than or equal to 15
PORTC = PORTC | tmpc; ////////PORTC ends up being all zeros
asm("break");
}
}
Комментарии:
1. Вы путаете представление значения с самим значением. Операторы работают со значениями. Не имеет значения, представлены ли они в виде восьмеричных, десятичных или шестнадцатеричных чисел.
2. скомпилируйте код на своем компьютере и используйте отладчик
3. Я предполагаю
PORTC
, что это какой-то аппаратный регистр. Вы уверены, что они доступны для чтения и записи? Вы должны проверить, что вы читаете перед своейif
последовательностью, и какое значение у вас есть,tmpc
прежде чем записывать его.4. Вы также можете убедиться, что ваша
setbit
функция возвращает правильные значения. На всякий случай я бы добавил скобки вокруг выражений слева и справа от:
5. Ваше тело не содержит вопроса, и ответ на заголовок явно «да» — ответ не решает вашу проблему. Вы задаете неправильный вопрос, вопрос X-Y; вы действительно должны спросить, почему ваши вызовы
setBit()
не изменяют аргумент. Шестнадцатеричное число — это просто представление в исходном коде для удобства чтения человеком, на машинном двоичном уровне это просто целое число, машина ничего не знает о шестнадцатеричном, десятичном или восьмеричном.
Ответ №1:
Проблема в том, что возвращаемое значение SetBit
отбрасывается. Попробуйте изменить вызовы этой функции следующим образом:
SetBit(tmpc,0,1); //less than or equal to 15
Для
tmpc = SetBit(tmpc,0,1); //less than or equal to 15
Комментарии:
1. супер базовая ошибка кодирования, и теперь она работает, спасибо, что указали на это
Ответ №2:
Вы определенно можете использовать логические операторы для шестнадцатеричных значений. Не имеет значения, является ли представление двоичным, шестнадцатеричным или десятичным. Для вашего компилятора это 8-битное значение.
Что касается вашего примера: tmpa равно 0x0F, поэтому выполняется только в том случае, если условие проверено. В этой строке tmpc равен 0x00 (после инициализации). При прохождении SetBit(tmpc,0,1))
условие будет равно true (b = 1), и функция вернет x | (0x01 << k
значение, которое в этом случае равно 0x01. tmpc равен 0x00 в конце (его начальное значение), потому что вы не присваиваете его возвращаемому значению вашей функции setBit! Попробуйте это :
if (tmpa <= 0x0F)
tmpc = SetBit(tmpc,0,1); //less than or equal to 15
Ответ №3:
Да, вы можете использовать логические операторы, но этот код излишне медленный и сложный. Вам не нужны ветви или сравнения, все, что вам нужно, это справочная таблица с 16 значениями.
const uint8_t VAL [0x10] =
{
[0x00] = 1u<<5 | 1u<<6,
[0x01] = 1u<<5 | 1u<<6,
[0x02] = 1u<<5 | 1u<<6,
[0x03] = 1u<<4 | 1u<<6,
[0x04] = 1u<<4 | 1u<<6,
// ... up to 0x0F
};
tmpc = VAL[tmpa amp; 0xF];