从不同端口移动位并将其存储在内存中

时间:2013-11-26 17:21:01

标签: c bit-manipulation

我有这个问题,我在应用程序中为不同模式选择了一个类似选择器的拨动开关。有3位来创建选择器,但它们来自不同的端口,例如,来自portB的位号3,来自portC的位号1和来自portC的位号3,我想移动这3位并将它们存储在一个寄存器,这样我可以创建选择器,我已经在汇编程序中完成了它,但我是C编程的新手,直到现在唯一类似的答案是从整个端口移动所有信息,但任何与一个位有关的东西。我应该用什么命令从不同的端口移动这些位?

2 个答案:

答案 0 :(得分:1)

在C中,要获得位级精度,您需要使用bitwise operators。例如,假设您有一个8位容器(也是C中最小的数据类型),但您只对1位感兴趣;提取该位的最佳方法是进行按位AND。在C中,按位AND执行如下:

char c = 0x0B;
char bit = 0;

// Let's get the value of the second bit, so we must shift
// our bits to the right by one, then perform a bitwise AND
// to invalidate all other bits except the first.
bit = (c >> 1) & 0x01;

在二进制文件中,它看起来像这样:

00001011

Shift right once:
00000101

AND:
00000101 & 000000001

Yields: 000000001

要在同一内存位置存储不同的位,可以使用按位运算符,它是C |中的垂直管道。这是一个例子:

char c = 0x00;
c = c | 0x01; /* c will now yield 0x01 */
c = c | 0xF0; /* c will now yield 0xF1 */

Final binary result: 11110001

使用&|,您可以执行许多库中包含的强大功能,以便在一个参数中传递多个选项。使用8位,您可以存储8个不同的标志(或选项),16位,16个选项。您可以将此理念用于不同的端口。如果每个端口只有4位数据,则​​可以使用16位容器,剩下4位,可以简单地忽略。你这样做:

short port_values = 0;

port_values = port_values | (port_a & 0x000F); // pretend port_a only has 4 bits of data and contains 0x0001
// port_values is now 0000 0000 0000 0001
// prepare to receive port_b by shifting the bits 4 to the left
port_values = port_values << 4;
// port_values is now 0000 0000 0001 0000
port_values = port_values | (port_b & 0x000F); // pretend port_b only has 4 bits of data and contains 0x000F
// port_values is now 0000 0000 0001 1111
// prepare to receive port_b by shifting the bits 4 to the left
port_values = port_values << 4;
// port_values is now 0000 0001 1111 0000
port_values = port_values | (port_c & 0x000F); // pretend port_c only has 4 bits of data and contains 0x0002
// port_values is now 0000 0001 1111 0010

答案 1 :(得分:0)

我决定执行以下代码,但是当我运行代码时,它不会进入switch-case,只需返回设置“COMBINACION”的最后一位可能是我的错误。感谢您的时间和考虑,我是新的C世界。

 void SECUENCIA_1();
 void SECUENCIA_2();
 void SECUENCIA_3();
 void SECUENCIA_4();
 void SECUENCIA_5();
 void SECUENCIA_6();
 void SECUENCIA_ERROR();
 void SALIDA_OK();
 int i;
 unsigned char COMBINACION;

 void main(void) {
 ADCON1 = 0x0F;
 PORTA  = 0x00;
 TRISA  = 0b00000;
 PORTC  = 0x00;
 TRISC  = 0b11100000;
 PORTD  = 0x00;
 TRISD  = 0b110000;
 PORTE  = 0x00;
 TRISE  = 0b000;
 PORTB  = 0x00;
 TRISB  = 0b11111111; 


COMBINACION = 0x00;
COMBINACION = COMBINACION | (PORTCbits.RC5);
COMBINACION = COMBINACION << 1;
COMBINACION = COMBINACION | (PORTCbits.RC4);
COMBINACION = COMBINACION << 1;
COMBINACION = COMBINACION | (PORTDbits.RD3);


switch (COMBINACION)
    {
    case 0x0: SECUENCIA_ERROR; break;
    case 0x1: SECUENCIA_1; break;
    case 0x2: SECUENCIA_2; break;
    case 0x3: SECUENCIA_3; break;
    case 0x4: SECUENCIA_4; break;
    case 0x5: SECUENCIA_5; break;
    case 0x6: SECUENCIA_6; break;
    default:SECUENCIA_ERROR;
    }

}