2013-11-02 17 views
0

我有以下的代码块替换:如果位条款cheking有位操作用C

// **** CONTROL REGISTER 4 SETUP **** 
    ctrl|=(uint8_t)(LIS3DSH_InitStruct->CR4_Odr); 
    if(LIS3DSH_InitStruct->CR4_Bdu) 
     ctrl|=(1<<LIS3DSH_CR4_BDU_POSITION); 
    if(LIS3DSH_InitStruct->CR4_Zen) 
     ctrl|=(1<<LIS3DSH_CR4_Z_AXIS_POSITION); 
    if(LIS3DSH_InitStruct->CR4_Yen) 
     ctrl|=(1<<LIS3DSH_CR4_Y_AXIS_POSITION); 
    if(LIS3DSH_InitStruct->CR4_Xen) 
     ctrl|=(1<<LIS3DSH_CR4_X_AXIS_POSITION); 
    LIS3DSH_Write(&ctrl, 
        LIS3DSH_CTRL_REG4_ADDR, 
        sizeof(ctrl)); 
    delay(1000000); 
// **** END OF CONTROL REGISTER 4 SETUP **** 

现在,我敢肯定这些if引导的从句(因为这是嵌入式世界)可以用位操作来代替技术,有人可以告诉我如何?我知道这是非常愚蠢的问题,但我只是忘了这些事......

这里是头文件与结构:

#ifndef __STM32F4_DISCOVERY_LIS3DS_H 
#define __STM32F4_DISCOVERY_LIS3DS_H 

#include "stm32f4xx.h" 

#define LIS3DSH_CTRL_REG1_ADDR 0x21 
#define LIS3DSH_CTRL_REG2_ADDR 0x22 
#define LIS3DSH_CTRL_REG3_ADDR 0x23 
#define LIS3DSH_CTRL_REG4_ADDR 0x20 
#define LIS3DSH_CTRL_REG5_ADDR 0x24 
#define LIS3DSH_CTRL_REG6_ADDR 0x25 

#define LIS3DSH_INFO1_REG_ADDR 0x0d 
#define LIS3DSH_INFO2_REG_ADDR 0x0e 
#define LIS3DSH_WHOAMI_REG_ADDR 0x0f 

#define LIS3DSH_STATUS_REG_ADDR 0x27 

#define LIS3DSH_TEMPERATURE_REG_ADDR 0x0c 

#define LIS3DSH_OUT_X_L_REG_ADDR 0x28 
#define LIS3DSH_OUT_X_H_REG_ADDR 0x29 
#define LIS3DSH_OUT_Y_L_REG_ADDR 0x2a 
#define LIS3DSH_OUT_Y_H_REG_ADDR 0x2b 
#define LIS3DSH_OUT_Z_L_REG_ADDR 0x2c 
#define LIS3DSH_OUT_Z_H_REG_ADDR 0x2d 

#define LIS3DSH_FLAG_ZXYOR ((uint8_t)0x00) 
#define LIS3DSH_FLAG_ZOR  ((uint8_t)0x01) 
#define LIS3DSH_FLAG_YOR  ((uint8_t)0x02) 
#define LIS3DSH_FLAG_XOR  ((uint8_t)0x03) 
#define LIS3DSH_FLAG_ZXYDA ((uint8_t)0x04) 
#define LIS3DSH_FLAG_ZDA  ((uint8_t)0x05) 
#define LIS3DSH_FLAG_YDA  ((uint8_t)0x06) 
#define LIS3DSH_FLAG_XDA  ((uint8_t)0x07) 

#define DEVICE_ID ((uint8_t)0x3f) 

#define LIS3DSH_SM1_INT_TO_PIN_INT1 ((uint8_t)0x00) 
#define LIS3DSH_SM1_INT_TO_PIN_INT2 ((uint8_t)0x01) 

#define LIS3DSH_SM1_DISABLE ((uint8_t)0x00) 
#define LIS3DSH_SM1_ENABLE ((uint8_t)0x01) 

#define LIS3DSH_SM2_INT_TO_PIN_INT1 ((uint8_t)0x00) 
#define LIS3DSH_SM2_INT_TO_PIN_INT2 ((uint8_t)0x01) 

#define LIS3DSH_SM2_DISABLE ((uint8_t)0x00) 
#define LIS3DSH_SM2_ENABLE ((uint8_t)0x01) 

#define LIS3DSH_CR3_DREN_TO_INT1_DISABLE ((uint8_t)0x00) 
#define LIS3DSH_CR3_DREN_TO_INT1_ENABLE  ((uint8_t)0x01) 

#define LIS3DSH_CR3_IEA_ACTIVE_LOW ((uint8_t)0x00) 
#define LIS3DSH_CR3_IEA_ACTIVE_HIGH ((uint8_t)0x01) 

#define LIS3DSH_CR3_IEL_LATCHED ((uint8_t)0x00) 
#define LIS3DSH_CR3_IEL_PULSED ((uint8_t)0x01) 

#define LIS3DSH_CR3_INT2_DISABLED ((uint8_t)0x00) 
#define LIS3DSH_CR3_INT2_ENABLED ((uint8_t)0x01) 

#define LIS3DSH_CR3_INT1_DISABLED ((uint8_t)0x00) 
#define LIS3DSH_CR3_INT1_ENABLED ((uint8_t)0x01) 

#define LIS3DSH_CR3_VFILT_DISABLED ((uint8_t)0x00) 
#define LIS3DSH_CR3_VFILT_ENABLED ((uint8_t)0x01) 

#define LIS3DSH_CR3_NO_SOFT_RESET ((uint8_t)0x00) 
#define LIS3DSH_CR3_SOFT_RESET  ((uint8_t)0x01) 

#define LIS3DSH_CR4_ODR_POWER_DOWN ((uint8_t)0x00) 
#define LIS3DSH_CR4_ODR_3f125HZ  ((uint8_t)0x01) 
#define LIS3DSH_CR4_ODR_6f25HZ  ((uint8_t)0x02) 
#define LIS3DSH_CR4_ODR_12f5HZ  ((uint8_t)0x03) 
#define LIS3DSH_CR4_ODR_25HZ  ((uint8_t)0x04) 
#define LIS3DSH_CR4_ODR_50HZ  ((uint8_t)0x05) 
#define LIS3DSH_CR4_ODR_100HZ  ((uint8_t)0x06) 
#define LIS3DSH_CR4_ODR_400HZ  ((uint8_t)0x07) 
#define LIS3DSH_CR4_ODR_800HZ  ((uint8_t)0x08) 
#define LIS3DSH_CR4_ODR_1600HZ  ((uint8_t)0x09) 

#define LIS3DSH_CR4_BDU_DISABLED ((uint8_t)0x00) 
#define LIS3DSH_CR4_BDU_ENABLED  ((uint8_t)0x01) 
#define LIS3DSH_CR4_BDU_POSITION ((uint8_t)0x04) 

#define LIS3DSH_CR4_Z_AXIS_DISABLED ((uint8_t)0x00) 
#define LIS3DSH_CR4_Z_AXIS_ENABLED ((uint8_t)0x01) 
#define LIS3DSH_CR4_Z_AXIS_POSITION ((uint8_t)0x05) 

#define LIS3DSH_CR4_X_AXIS_DISABLED ((uint8_t)0x00) 
#define LIS3DSH_CR4_X_AXIS_ENABLED ((uint8_t)0x01) 
#define LIS3DSH_CR4_X_AXIS_POSITION ((uint8_t)0x07) 

#define LIS3DSH_CR4_Y_AXIS_DISABLED ((uint8_t)0x00) 
#define LIS3DSH_CR4_Y_AXIS_ENABLED ((uint8_t)0x01) 
#define LIS3DSH_CR4_Y_AXIS_POSITION ((uint8_t)0x06) 

#define LIS3DSH_CR5_BW_800HZ ((uint8_t)0x00) 
#define LIS3DSH_CR5_BW_400HZ ((uint8_t)0x01) 
#define LIS3DSH_CR5_BW_200HZ ((uint8_t)0x02) 
#define LIS3DSH_CR5_BW_50HZ  ((uint8_t)0x03) 

#define LIS3DSH_CR5_FSCALE_2G ((uint8_t)0x00) 
#define LIS3DSH_CR5_FSCALE_4G ((uint8_t)0x01) 
#define LIS3DSH_CR5_FSCALE_6G ((uint8_t)0x02) 
#define LIS3DSH_CR5_FSCALE_8G ((uint8_t)0x03) 
#define LIS3DSH_CR5_FSCALE_16G ((uint8_t)0x04) 

#define LIS3DSH_CR5_ST_DISABLE  ((uint8_t)0x00) 
#define LIS3DSH_CR5_ST_POSITIVE  ((uint8_t)0x01) 
#define LIS3DSH_CR5_ST_NEGATIVE  ((uint8_t)0x02) 
#define LIS3DSH_CR5_ST_NOT_ALLOWED ((uint8_t)0x03) 

#define LIS3DSH_CR5_MODE_4_WIRE_INTERFACE ((uint8_t)0x00) 
#define LIS3DSH_CR5_MODE_3_WIRE_INTERFACE ((uint8_t)0x01) 

#define LIS3DSH_CR6_FORCE_REBOOT_DISABLE ((uint8_t)0x00) 
#define LIS3DSH_CR6_FORCE_REBOOT_ENABLE  ((uint8_t)0x01) 

#define LIS3DSH_CR6_FIFO_DISABLED ((uint8_t)0x00) 
#define LIS3DSH_CR6_FIFO_ENABLED ((uint8_t)0x01) 

#define LIS3DSH_CR6_WTM_DISABLED ((uint8_t)0x00) 
#define LIS3DSH_CR6_WTM_ENABLED  ((uint8_t)0x01) 

#define LIS3DSH_CR6_ADDINC_DISABLED ((uint8_t)0x00) 
#define LIS3DSH_CR6_ADDINC_ENABLED ((uint8_t)0x01) 

#define LIS3DSH_CR6_FIFO_EMPTY_TO_INT1_DISABLED ((uint8_t)0x00) 
#define LIS3DSH_CR6_FIFO_EMPTY_TO_INT1_ENABLED ((uint8_t)0x01) 

#define LIS3DSH_CR6_FIFO_WTM_TO_INT1_DISABLED ((uint8_t)0x00) 
#define LIS3DSH_CR6_FIFO_WTM_TO_INT1_ENABLED ((uint8_t)0x01) 

#define LIS3DSH_CR6_FIFO_OVERRUN_TO_INT1_DISABLED ((uint8_t)0x00) 
#define LIS3DSH_CR6_FIFO_OVERRUN_TO_INT1_ENABLED ((uint8_t)0x01) 

#define LIS3DSH_CR6_BOOT_TO_INT2_DISABLED ((uint8_t)0x00) 
#define LIS3DSH_CR6_BOOT_TO_INT2_ENABLED ((uint8_t)0x01) 

#define LIS3DSH_SPI      SPI1 
#define LIS3DSH_SPI_CLK     RCC_APB2Periph_SPI1 

#define LIS3DSH_SPI_SCK_PIN    GPIO_Pin_5 
#define LIS3DSH_SPI_SCK_GPIO_PORT   GPIOA 
#define LIS3DSH_SPI_SCK_GPIO_CLK   RCC_AHB1Periph_GPIOA 
#define LIS3DSH_SPI_SCK_SOURCE   GPIO_PinSource5 
#define LIS3DSH_SPI_SCK_AF    GPIO_AF_SPI1 

#define LIS3DSH_SPI_MISO_PIN    GPIO_Pin_6 
#define LIS3DSH_SPI_MISO_GPIO_PORT  GPIOA 
#define LIS3DSH_SPI_MISO_GPIO_CLK   RCC_AHB1Periph_GPIOA 
#define LIS3DSH_SPI_MISO_SOURCE   GPIO_PinSource6 
#define LIS3DSH_SPI_MISO_AF    GPIO_AF_SPI1 

#define LIS3DSH_SPI_MOSI_PIN    GPIO_Pin_7 
#define LIS3DSH_SPI_MOSI_GPIO_PORT  GPIOA 
#define LIS3DSH_SPI_MOSI_GPIO_CLK   RCC_AHB1Periph_GPIOA 
#define LIS3DSH_SPI_MOSI_SOURCE   GPIO_PinSource7 
#define LIS3DSH_SPI_MOSI_AF    GPIO_AF_SPI1 

#define LIS3DSH_SPI_CS_PIN    GPIO_Pin_3 
#define LIS3DSH_SPI_CS_GPIO_PORT   GPIOE 
#define LIS3DSH_SPI_CS_GPIO_CLK   RCC_AHB1Periph_GPIOE 

#define LIS3DSH_SPI_INT1_PIN    GPIO_Pin_0 
#define LIS3DSH_SPI_INT1_GPIO_PORT  GPIOE 
#define LIS3DSH_SPI_INT1_GPIO_CLK   RCC_AHB1Periph_GPIOE 
#define LIS3DSH_SPI_INT1_EXTI_LINE  EXTI_Line0 
#define LIS3DSH_SPI_INT1_EXTI_PORT_SOURCE EXTI_PortSourceGPIOE 
#define LIS3DSH_SPI_INT1_EXTI_PIN_SOURCE EXTI_PinSource0 
#define LIS3DSH_SPI_INT1_EXTI_IRQn  EXTI0_IRQn 

#define LIS3DSH_SPI_INT2_PIN    GPIO_Pin_1 
#define LIS3DSH_SPI_INT2_GPIO_PORT  GPIOE 
#define LIS3DSH_SPI_INT2_GPIO_CLK   RCC_AHB1Periph_GPIOE 
#define LIS3DSH_SPI_INT2_EXTI_LINE  EXTI_Line1 
#define LIS3DSH_SPI_INT2_EXTI_PORT_SOURCE EXTI_PortSourceGPIOE 
#define LIS3DSH_SPI_INT2_EXTI_PIN_SOURCE EXTI_PinSource1 
#define LIS3DSH_SPI_INT2_EXTI_IRQn  EXTI1_IRQn 

#define LIS3DSH_CS_LOW() GPIO_ResetBits(LIS3DSH_SPI_CS_GPIO_PORT, LIS3DSH_SPI_CS_PIN) 
#define LIS3DSH_CS_HIGH() GPIO_SetBits(LIS3DSH_SPI_CS_GPIO_PORT, LIS3DSH_SPI_CS_PIN) 

#define LIS3DSH_FLAG_TIMEOUT ((uint32_t)0x1000) 

typedef struct 
{ 
    // **** Control Register 1 **** 
    uint8_t SM1_Hysteresis; 
    uint8_t SM1_Pin; 
    uint8_t SM1_Enable; 
    // **** END OF Control Register 1 **** 

    // **** Control Register 2 **** 
    uint8_t SM2_Hysteresis; 
    uint8_t SM2_Pin; 
    uint8_t SM2_Enable; 
    // **** END OF Control Register 2 **** 

    // **** Control Register 3 **** 
    uint8_t CR3_Dren; 
    uint8_t CR3_Iea; 
    uint8_t CR3_Iel; 
    uint8_t CR3_Int2En; 
    uint8_t CR3_Int1En; 
    uint8_t CR3_Vfilt; 
    uint8_t CR3_Strt; 
    // **** END OF Control Register 3 

    // **** Control Register 4 **** 
    uint8_t CR4_Odr; 
    uint8_t CR4_Bdu; 
    uint8_t CR4_Zen; 
    uint8_t CR4_Yen; 
    uint8_t CR4_Xen; 
    // **** END OF Control Register 4 

    // **** Control Register 5 **** 
    uint8_t CR5_Bw; 
    uint8_t CR5_Fscale; 
    uint8_t CR5_St; 
    uint8_t CR5_Sim; 
    // **** END OF Control Register 5 

    // **** Control Register 6 **** 
    uint8_t CR6_Boot; 
    uint8_t CR6_FifoEn; 
    uint8_t CR6_WtmEn; 
    uint8_t CR6_AddInc; 
    uint8_t CR6_P1Empty; 
    uint8_t CR6_P1Wtm; 
    uint8_t CR6_P1OverRun; 
    uint8_t CR6_P2Boot; 
    // **** END OF Control Register 6 
} LIS3DSH_InitTypeDef; 

typedef struct 
{ 
    uint16_t x; 
    uint16_t y; 
    uint16_t z; 
} accel_vector; 

extern LIS3DSH_InitTypeDef deviceLIS3DSH; 
extern GPIO_InitTypeDef portLIS3DSH; 
extern SPI_InitTypeDef busLIS3DSH; 
extern accel_vector accelData; 

void LIS3DSH_Init(LIS3DSH_InitTypeDef* LIS3DSH_InitStruct); 
uint32_t LIS3DSH_TIMEOUT_UserCallback(void); 
void LIS3DSH_AccelInit(void); 
void LIS3DSH_Read(uint8_t* pBuffer, 
        uint8_t ReadAddr, 
        uint16_t NumByteToRead); 
void LIS3DSH_Write(uint8_t* pBuffer, 
        uint8_t WriteAddr, 
        uint16_t NumByteToWrite); 
void LIS3DSH_FailureHandler(void); 
accel_vector LIS3DSH_ReadData(void); 
void LIS3DSH_SoftReset(void); 

#endif 

CTRL是类型uin8_t,我使用的IAR Embedded Workbench使用C和STM32F4Discovery板。下面是inits LIS3DSH_IniStruct的部分代码:

deviceLIS3DSH.CR4_Odr=LIS3DSH_CR4_ODR_1600HZ; 
deviceLIS3DSH.CR4_Bdu=LIS3DSH_CR4_BDU_ENABLED; 
deviceLIS3DSH.CR4_Zen=LIS3DSH_CR4_Z_AXIS_ENABLED; 
deviceLIS3DSH.CR4_Yen=LIS3DSH_CR4_Y_AXIS_ENABLED; 
deviceLIS3DSH.CR4_Xen=LIS3DSH_CR4_X_AXIS_ENABLED; 

和deviceLIS3DSH声明为:

LIS3DSH_InitTypeDef deviceLIS3DSH; 
+0

你能告诉'ctrl'声明和T他是什么类型的'LIS3DSH_InitStruct'? – ouah

+0

我正在关注这个加速度计(LIS3DSH)数据表,然后编码头文件。我已经添加了标题和ctrl变量描述。 – KernelPanic

+0

从上面我可以看到,像'LIS3DSH_InitStruct-> CR4_Bdu'这样的变量被测试为零或非零。如果你想不做测试,你需要知道他们有什么价值。为什么不打印这些值来查看内部是什么? – Zane

回答

3

相同的代码,但与if语句纯位操作代替:

// **** CONTROL REGISTER 4 SETUP **** 
    ctrl |= (LIS3DSH_InitStruct->CR4_Odr); 
    ctrl |= (LIS3DSH_InitStruct->CR4_Bdu << LIS3DSH_CR4_BDU_POSITION); 
    ctrl |= (LIS3DSH_InitStruct->CR4_Zen << LIS3DSH_CR4_Z_AXIS_POSITION); 
    ctrl |= (LIS3DSH_InitStruct->CR4_Yen << LIS3DSH_CR4_Y_AXIS_POSITION); 
    ctrl |= (LIS3DSH_InitStruct->CR4_Xen << LIS3DSH_CR4_X_AXIS_POSITION); 
    LIS3DSH_Write(&ctrl, 
        LIS3DSH_CTRL_REG4_ADDR, 
        sizeof(ctrl)); 
    delay(1000000); 
// **** END OF CONTROL REGISTER 4 SETUP **** 
+1

好的,但这是一个问题:假设我想配置X,Y,Z轴启用的加速度计,并且输出数据速率(ODR)设置为100 Hz。如果我在以前的帖子中设置:deviceLIS3DSH.CR4_Odr = LIS3DSH_CR4_ODR_1600HZ; deviceLIS3DSH.CR4_Bdu = LIS3DSH_CR4_BDU_ENABLED; deviceLIS3DSH.CR4_Zen = LIS3DSH_CR4_Z_AXIS_ENABLED; deviceLIS3DSH.CR4_Yen = LIS3DSH_CR4_Y_AXIS_ENABLED; deviceLIS3DSH。CR4_Xen = LIS3DSH_CR4_X_AXIS_ENABLED; 那么ctrl的值应该是0x67(来自应用笔记),但是这个代码给了我ctrl的值,这些设置是0xe6,这是错误的。为什么? – KernelPanic

+0

代码给出的值应该为0xf9,假设它最初被设置为0x00。 –

+0

我已经解决了问题,ODR值必须转换为msb,然后通过标准位maninuplation技术设置所有其他位!非常感谢你! – KernelPanic

2

这些已经位操作。

if(LIS3DSH_InitStruct->CR4_Bdu) 

这测试如果里面的整数是0或不是。该测试是一个逻辑运算符,因此它会检查所有位。在内部,它可能是一个tst汇编指令。

ctrl|=(1<<LIS3DSH_CR4_BDU_POSITION); 

这是一些实际的位操作。 ctrl有8位,我们要使其中一个1,即使它已经是1.

因此,我们取1是00000001,并将位左移1以使我们关注的位置。这是哪个位置?它由宏LIS3DSH_CR4_BDU_POSITION给出,它被定义为头文件中从0到7的数字。

所以右侧变得1<<4或00010000或0x10的或16

的我们or通过ctrl = ctrl | 0x10;这个数字与ctrl其中有确保的效果CTRL整数的第5位是1。短写ctrl |= (1<<4);

+0

非常感谢您的澄清,但是如何在高4位设置多位值? – KernelPanic

+0

需要将ODR值设置为MSB位置,然后才能正常工作! – KernelPanic