picavr (20.04.2009 00:27, просмотров: 7239) MBedder
Доброго времени суток, начал изучать Си, (асм уже лет 10) Возник вопрос по IARAVR 5.20.1.
Мультиплексированная обработка 32 клавиш.
В функцииях считывания из портов в переменную LONG, возникает непонятка.
При считывании младших 8 бит (с 0 по 7), всё нормально. При считываниии с 8 по 15 биты, перед сохранением переменной в RAM устанавливаются в "1" биты с 16 по 31. Компилятор генерит лишние команды типа "IOR 0ff" для двух старших байт переменной LONG, для битов которые которые не считывали.
И не генерит код в функциях для считывания оставшихся 2 байт (с16 по 31 биты). Компилятор как бы считает, что биты уже считаны..
При одинаковом коде Си 4-х функций, в 2 функциях компилируется совершенно разное...
Делал разные варианты. Разноcил считываемые ножки по разным портам, считывал все из одного порта, считывал сначала во временную переменную в регистрах а потом сохранял в RAM... устанавливал разную оптимизацию, всегда ведёт себя одинаково...
Уже обьявлял и static и volatile (на всякий случай).
Если функции для 8 бит (переменные типа char) или 16 бит (в переменные типа int) происходит нормально!! с long творятся чудеса...
Дайте плиз пинка в нужном направлении... уже мозги сломал.
unsigned long tempkey; //переменная для считывания
void read_32key0 (void){ //считывание клавиш 0-7
tempkey & 0xffffff00; //гасим считываемые биты 0-7
if (!PINA_Bit0) {tempkey |= 1<<0;}
if (!PINA_Bit1) {tempkey |= 1<<1;}
if (!PINA_Bit2) {tempkey |= 1<<2;}
if (!PINA_Bit3) {tempkey |= 1<<3;}
if (!PINA_Bit4) {tempkey |= 1<<4;}
if (!PINA_Bit5) {tempkey |= 1<<5;}
if (!PINA_Bit6) {tempkey |= 1<<6;}
if (!PINA_Bit7) {tempkey |= 1<<7;}
}
void read_32key1 (void){ //считывание клавиш 8-15
tempkey & 0xffff00ff; //гасим считываемые биты 8-15
if (!PINB_Bit0) {tempkey |= 1<<8;}
if (!PINB_Bit1) {tempkey |= 1<<9;}
if (!PINB_Bit2) {tempkey |= 1<<10;}
if (!PINB_Bit3) {tempkey |= 1<<11;}
if (!PINB_Bit4) {tempkey |= 1<<12;}
if (!PINB_Bit5) {tempkey |= 1<<13;}
if (!PINB_Bit6) {tempkey |= 1<<14;}
if (!PINB_Bit7) {tempkey |= 1<<15;}
}
void read_32key2 (void){ //считывание клавиш 16-23
tempkey & 0xff00ffff; //гасим считываемые биты 16-23
if (!PINC_Bit0) {tempkey |= 1<<16;}
if (!PINC_Bit1) {tempkey |= 1<<17;}
if (!PINC_Bit2) {tempkey |= 1<<18;}
if (!PINC_Bit3) {tempkey |= 1<<19;}
if (!PINC_Bit4) {tempkey |= 1<<20;}
if (!PINC_Bit5) {tempkey |= 1<<21;}
if (!PINC_Bit6) {tempkey |= 1<<22;}
if (!PINC_Bit7) {tempkey |= 1<<23;}
}
void read_32key3 (void){ //считывание клавиш 24-31
tempkey & 0x00ffffff; //гасим считываемые биты 24-31
if (!PIND_Bit0) {tempkey |= 1<<24;}
if (!PIND_Bit1) {tempkey |= 1<<25;}
if (!PIND_Bit2) {tempkey |= 1<<26;}
if (!PIND_Bit3) {tempkey |= 1<<27;}
if (!PIND_Bit4) {tempkey |= 1<<28;}
if (!PIND_Bit5) {tempkey |= 1<<29;}
if (!PIND_Bit6) {tempkey |= 1<<30;}
if (!PIND_Bit7) {tempkey |= 1<<31;}
}
main(void){
while (1){
read_32key0(); //вызов функции считывания 0-7
read_32key1(); //вызов функции считывания 8-15
read_32key2(); //вызов функции считывания 16-23
read_32key3(); //вызов функции считывания 24-31
}
}