l want to know how i can represent keys like enter shift etc in c programming language. is there any binary values for those keys?
as i can represent esc key with a help of binary value 27.
for example:
int main()
{
int x;
char ch;
while(1)
{
ch=getch();
if(ch==27)
{
printf("esc key pressed");
break;
}
else
{
printf("%c key pressed\n",ch);
}
}
}
in my program if i press esc it will break. now if i want to break with any other keys like enter, shift, alt how to do it ?
Most of this would be platform dependent. However, some keys can be detected by using the keyboard scan codes and the following example program:
#include<stdio.h>
int main()
{
int ch;
int ascii[10];
int count=1;
ch=getchar();
ascii[0]=ch;
while (1) //Loop used for storing successive ASCII values
{
ascii[count]=getchar();
if (ascii[count]==10) break;
count++;
}
if (27==ascii[0] && 79==ascii[1] && 80==ascii[2]) printf("F1 is pressed");
if (27==ascii[0] && 79==ascii[1] && 81==ascii[2]) printf("F2 is pressed");
if (27==ascii[0] && 79==ascii[1] && 82==ascii[2]) printf("F3 is pressed");
if (27==ascii[0] && 91==ascii[1] && 72==ascii[2]) printf("HOME key is pressed");
return 0;
}
If you want a more useful example without having to hit ENTER after each keystroke, you could try disabling input buffering and enabling raw mode.
I want to know how i can represent keys like enter shift etc in c programming language...
As others have said, this is OS dependent.
This function:
short GetAsyncKeyState(int key);
( For Windows programming ) can be used in conjunction with the following #defines in WinUser.h to determine the current AND recent states of a key:
#define VK_CLEAR 0x0C
#define VK_RETURN 0x0D //AKA enter
#define VK_SHIFT 0x10
#define VK_CONTROL 0x11
#define VK_MENU 0x12
#define VK_PAUSE 0x13
#define VK_CAPITAL 0x14
#define VK_KANA 0x15
#define VK_HANGEUL 0x15 /* old name - should be here for compatibility */
#define VK_HANGUL 0x15
#define VK_JUNJA 0x17
#define VK_FINAL 0x18
#define VK_HANJA 0x19
#define VK_KANJI 0x19
#define VK_ESCAPE 0x1B
#define VK_CONVERT 0x1C
#define VK_NONCONVERT 0x1D
#define VK_ACCEPT 0x1E
#define VK_MODECHANGE 0x1F
#define VK_SPACE 0x20
#define VK_PRIOR 0x21
#define VK_NEXT 0x22
#define VK_END 0x23
#define VK_HOME 0x24
#define VK_LEFT 0x25
#define VK_UP 0x26
#define VK_RIGHT 0x27
#define VK_DOWN 0x28
#define VK_SELECT 0x29
#define VK_PRINT 0x2A
#define VK_EXECUTE 0x2B
#define VK_SNAPSHOT 0x2C
#define VK_INSERT 0x2D
#define VK_DELETE 0x2E
#define VK_HELP 0x2F
Related
Hi i am working on a school project where I'm supposed to output temperature values on an Oled display.
i have managed to do it with Arduino Code so i know that the sensor and display works, but the code has to be written in Atmel studio in pure embedded C for the project.
I'm not sure what I'm doing wrong and what I'm am doing right.
I'm struggling with C code and the I2C protocol.
i have done a lot of research on the subject but evertime i seem to only find arduino tutorials, or theory related posts.
I'm totally new to programming.
anyway this is the code i have come up with so far.
the txt i have written for the display is displayed. everthing works as it should except for the temperatur values:
#define F_CPU 16000000UL
#include <avr/io.h>
#include <stdio.h>
#include <stdlib.h>
#include <avr/interrupt.h>
#include <util/delay.h>
#include "OLED.h"
#include "ATmega_Init.h"
#include "i2c_master.h"
//From Arduino Adafruit_MLX90614 lib
// RAM
#define MLX90614_RAWIR1 0x04
#define MLX90614_RAWIR2 0x05 //Important for reading out
#define MLX90614_TA 0x06
#define MLX90614_TOBJ1 0x07
#define MLX90614_TOBJ2 0x08
// EEPROM
#define MLX90614_TOMAX 0x20
#define MLX90614_TOMIN 0x21
#define MLX90614_PWMCTRL 0x22
#define MLX90614_TARANGE 0x23
#define MLX90614_EMISS 0x24
#define MLX90614_CONFIG 0x25
#define MLX90614_ADDR 0x0E
#define MLX90614_ID1 0x3C
#define MLX90614_ID2 0x3D
#define MLX90614_ID3 0x3E
#define MLX90614_ID4 0x3F
#define SLAVE_ADDRESS 0x5A
int main(void)
{
//uint8_t test_recieve[2];
uint16_t test_recieve_high; //To receive the high byte
uint16_t test_recieve_low; //To receive the low byte
init_atmega_setup();
initDisplay();
i2c_init();
clsDisplay();
strFont5XY("Floor Unit",25,3);
_delay_ms(2000);
clsDisplay();
//uint8_t receive_command = 0x00; //Needs the receive command,
definitely not just 0x00
while(1){
i2c_start(SLAVE_ADDRESS);
i2c_write(MLX90614_TOBJ1);
i2c_start(SLAVE_ADDRESS);
test_recieve_high = i2c_read_ack();
i2c_start(MLX90614_TOBJ1);
test_recieve_high = ((uint8_t)i2c_read_ack())<<8;
test_recieve_high |= i2c_read_ack();
i2c_stop();
i2c_start(SLAVE_ADDRESS);
i2c_write(MLX90614_TOBJ1);*/
i2c_start(MLX90614_TOBJ1);
test_recieve_low = ((uint8_t)i2c_read_ack())<<8;
test_recieve_low |= i2c_read_ack();
i2c_stop();
intFont5XY(test_recieve_low,1,0);
intFont5XY(test_recieve_high,1,1);
_delay_ms(1000);
};
};
// Created by lenovo on 8/27/2017.
//
#ifndef UART_UART_CFG_H
#define UART_UART_CFG_H
#define UART_BaudRate 1200 //9600UL
#define CLK 16
#define UART_Parity NONE
#define UART_TX EN_TX
#define UART_RX EN_RX
#define UART_STARTBITS 1
#define UART_STOPBITS 1
#define UART_DATABITS EightBits
#endif //UART_UART_CFG_H
This is the error "called object is not a function or pointer"
and this my private file that have all word's addresses inside the config file. The first file:
//
// Created by lenovo on 8/27/2017.
//
#ifndef UART_UART_PRIV_H
#define UART_UART_PRIV_H
/* Main PINS */
#define UCSRA *((volatile u8 *)0x2B)
#define UCSRB *((volatile u8 *)0x2A)
#define UCSRC *((volatile u8 *)0x40)
#define UBRRL *((volatile u8 *)0x29)
#define UBRRH *((volatile u8 *)0x40)
#define UDR *((volatile u8 *)0x2C)
/* END Main PINS */
#define NONE 0x00
#define twoBit 0x08
#define oneBit 0x00
/* Bits */
#define fiveBits 0x00
#define SixBits 0x02
#define SevenBits 0x04
#define EightBits 0x06
/* End Bits */
#define DIS 0 // Disable
#define EN 1 // Enable
#define UART_9600 9600UL
#endif //UART_UART_PRIV_H
Private file that have some addresses for my Microcontroller ATmega16. Moreover, my config file is reference to private file; which have keys that defined in private. For example, in UART_Partit I wrote NONE and NONE address defined in private but it shows error
You need to include your file with declarations.
#ifndef UART_UART_CFG_H
#define UART_UART_CFG_H
#include "uart_priv.h"
#define UART_BaudRate 1200 //9600UL
#define CLK 16
#define UART_Parity NONE
#define UART_TX EN_TX
#define UART_RX EN_RX
#define UART_STARTBITS 1
#define UART_STOPBITS 1
#define UART_DATABITS EightBits
#endif //UART_UART_CFG_H
and there are no EN_TX or EN_RX defines for these constants in your second file.
I have 2 defines:
#define REG1 (BASE_ADDR + REG1_OFFSET) //address
#define REG1_MASK 0x3f
I want to generate a command through macro that would use both defines but with giving as a variable only REG1. for instance, writing down
WRITE_TO_REG(REG1)
will result in:
foo(REG1,0xa5a5a5a5,REG1_MASK)
For this I created these macros:
#define MASK_REG(REG) REG ## _MASK
#define FOO_REG(REG) foo(REG,0xa5a5a5a5,MASK_REG(REG))
but I get an error (I'm compiling in gcc): pasting ")" and "_MASK" does not give a valid preprocessing token.
I tried a few variations, including:
#define MASK_REG(REG) MASK2_REG(REG)
#define MASK2_REG(REG) IDENTITY(REG) ## _MASK
#define IDENTITY(REG) REG
or:
#define PASTE2(x,y) PASTE(x,y)
#define PASTE(x,y) x ## y
#define MASK_REG(REG) PASTE2(REG,_MASK)
None of them worked. any ideas?
Adding a complete code:
#include <stdio.h>
#define REG1_BASE_ADDR 0x100
#define REG1_OFFSET 0x5
#define REG1 (REG1_BASE_ADDR + REG1_OFFSET)
#define REG1_MASK 0x3f
#define PASTE2(x,y) PASTE(x,y)
#define PASTE(x,y) x ## y
#define MASK_REG(REG) REG ## _MASK
#define FOO_REG(REG) (REG + MASK_REG(REG))
int main() {
printf("addr: %x, mask: %x, addr+mask: %x",REG1,REG1_MASK,FOO_REG(REG1));
}
Ok, I actually think I got it.
The problem was that the macro REG1 was evaluated BEFORE pre-processsor made the paste to _MASK.
It seems I didn't need any more defines to perform the paste:
#include <stdio.h>
#define REG1_BASE_ADDR 0x100
#define REG1_OFFSET 0x5
#define REG1 (REG1_BASE_ADDR + REG1_OFFSET)
#define REG1_MASK 0x3f
#define FOO_REG(REG) (REG + REG##_MASK)
int main() {
printf("addr: %x, mask: %x, addr+mask: %x",REG1,REG1_MASK,FOO_REG(REG1));
}
I have following chunk of code:
// **** 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 ****
Now, I am pretty sure these if clauses (since this is embedded world) can be replaced with bit manipulation techniques, can someone show me how? I know this is pretty stupid question, but I've simply forgot these things ...
Here is header file with structure:
#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 is type uin8_t and I am using IAR Embedded Workbench with C and STM32F4Discovery board. Here is a code that inits part of 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;
and deviceLIS3DSH is declared as:
LIS3DSH_InitTypeDef deviceLIS3DSH;
The same code but with the if-statements replaced with pure bit manipulation:
// **** 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 ****
These are already bit manipulation.
if(LIS3DSH_InitStruct->CR4_Bdu)
This tests if the integer inside is 0 or not. The test is a logical operator, so it checks all the bits. Internally, it might be a tst assembly instruction.
ctrl|=(1<<LIS3DSH_CR4_BDU_POSITION);
Here is some actual bit manipulation. ctrl has 8 bits, and we want to make one of these a 1, even it is already is 1.
So we take 1 which is 00000001 and shift the bits left to get the 1 into the position we are concerned with. Which position is this? It is given by the macro LIS3DSH_CR4_BDU_POSITION which is defined to be a number from 0 to 7 in the header file.
So the right hand side becomes 1<<4 or 00010000 or 0x10 or 16.
The we or this number with ctrl via ctrl = ctrl | 0x10; Which has the effect of making sure the 5th bit of the ctrl integer is a 1. It is shorter to write ctrl |= (1<<4);
I've created a structure called panel which render in OpenGL,works fine,but I want to add this to panel:
int flags;
then I define this in header :
#define PANEL_TITLE 0x0001
#define PANEL_MOVEABLE 0x0002
#define PANEL_SHADOW 0x0003
to use the flags value like this:
panel.flags = PANEL_TITLE | PANEL_MOVEABLE;
instead of have a lot :(which looks not good)
bool panel_has_title;
bool panel_moveable;
bool panel_shadow;
then check bool value,instead I can just have single int to achieve same result.I have read a lot open source stuff,that use flags,like the code above.
however my problem is it doesn't work,when I check the flags with:
panel.flags = PANEL_TITLE | PANEL_MOVEABLE;
if(panel.flags & PANEL_TITLE) //this one works
{
}
if(panel.flags & PANEL_MOVEABLE) //this one doesn't work
{
//not gets called
}
edit:
ok,now I've change it to
#define PANEL_TITLE 0x0002
#define PANEL_MOVEABLE 0x0004
#define PANEL_SHADOW 0x0008
are they intersect with each other again?
the new problem is if I set
panel.flags = PANEL_TITLE;
then every functions inside of it gets called
if(panel.flags & PANEL_TITLE)
{
//called which is normal
}
if(panel.flags & PANEL_MOVEABLE)
{
//called ..
}
if(panel.flags & PANEL_SHADOW)
{
//called ..
}
is it normal?
The problem here is that the bitmasks intersect with each other.
e.g. (simplefied for 8 bit)
#define PANEL_TITLE 0x0001 // 0b00000001
#define PANEL_MOVEABLE 0x0002 // 0b00000010
#define PANEL_SHADOW 0x0003 // 0b00000011
What you want is this:
#define PANEL_TITLE 0x0001 // 0b00000001
#define PANEL_MOVEABLE 0x0002 // 0b00000010
#define PANEL_SHADOW 0x0004 // 0b00000100
edit to your edit:
you don't set them like that, you set them with:
panel.flags |= PANEL_TITLE;
And for the last problem, I can't see anything wrong at first sight, try to step over it with a debugger and output the variable, that will give you a much clearer view of the problem
#define PANEL_TITLE 0x0001
#define PANEL_MOVEABLE 0x0002
#define PANEL_SHADOW 0x0003
When you define flags, they should not intersect. With your definition
PANEL_SHADOW == PANEL_MOVEABLE | PANEL_TITLE
is true.Did you meant it? Rather use a different bit, like
#define PANEL_SHADOW 0x0004
Print the values of panel.flags & XXX. Should be different from 0. The error is probaly somewhere else (do you modify the panel.flags?)
No, it's not normal. It's supernatural (just kidding...)
$ cat >pan.c && gcc pan.c && ./a.exe
#define PANEL_TITLE 0x0002
#define PANEL_MOVEABLE 0x0004
#define PANEL_SHADOW 0x0008
struct {int flags;} panel;
int main(){
panel.flags = PANEL_TITLE | PANEL_MOVEABLE;
if (panel.flags & PANEL_TITLE) printf("Hep\n");
if (panel.flags & PANEL_MOVEABLE) printf("Hop\n");
if (panel.flags & PANEL_SHADOW) printf("Hip\n");
}
Outputs as expected. It's not hip.
Hep
Hop
As are all the three variations in the modified question.
No suggested answer explains the claims. And while it's not necessarily right to have PANEL_SHADOW 0x0003, it's necessarily not wrong. In those cases though, one just typically declares:
#define PANEL_SHADOW (PANEL_TITLE | PANEL_MOVEABLE)
... to indicate that this indeed is the purpose.
Is your "panel" somehow mapped to a volatile memory?
Does the function alter it?
Have you #defined 0x0002 to mean something completely different?