2013-11-02 58 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