본문 바로가기
개발 노트 (C언어)

[C언어] 비트 연산 및 비트 시프트

by jjongday 2024. 4. 13.
반응형

아래 Swith-case문에 사용된 내용 중 한 case만 Sample 예제로 가져왔다.

 

변수 초기값을 Setting 한다. 

uint8 set_0 = cOFF, set_1 = cOFF, set_2 = cOFF, set_3 = cOFF;
uint16 PWM_Digital_Duty = 0;

 

 

아래 코드를 해석해보자.

case HIGH_SPEED13_OUTPUT_CLOSE_SW:
	PWM_Digital_Duty = ( (uint32)pwmDuty << 10 )/100u;
	if(PWM_Digital_Duty > PWM_MAX_DUTY)
	{
		PWM_Digital_Duty = PWM_MAX_DUTY;
	}
	else
	{
		;
	}

	pCR7->PWMx_DC_9 = (PWM_Digital_Duty & 0x200)>>9;
	pCR7->PWMx_DC_8 = (PWM_Digital_Duty & 0x100)>>8;
	pCR7->PWMx_DC_7 = (PWM_Digital_Duty & 0x80)>>7;
	pCR7->PWMx_DC_6 = (PWM_Digital_Duty & 0x40)>>6;
	pCR7->PWMx_DC_5 = (PWM_Digital_Duty & 0x20)>>5;
	pCR7->PWMx_DC_4 = (PWM_Digital_Duty & 0x10)>>4;
	pCR7->PWMx_DC_3 = (PWM_Digital_Duty & 0x8)>>3;
	pCR7->PWMx_DC_2 = (PWM_Digital_Duty & 0x4)>>2;
	pCR7->PWMx_DC_1 = (PWM_Digital_Duty & 0x2)>>1;
	pCR7->PWMx_DC_0 = (PWM_Digital_Duty & 0x1)>>0;

	pCR14->HS13_3 = set_3;
	pCR14->HS13_2 = set_2;
	pCR14->HS13_1 = set_1;
	pCR14->HS13_0 = set_0;

 

 

위 코드는 하드웨어에서 PWM (Pulse Width Modulation) 신호의 듀티 사이클을 설정하고 관련 하드웨어 레지스터에 이를 적용하는 과정을 보여준다. PWM은 전자 장치에서 전력 출력을 제어하는 일반적인 방법이다. 

 

1. PWM 듀티 사이클 계산

PWM_Digital_Duty = ((uint32)pwmDuty << 10) / 100u; 
pwmDuty 값을 32비트 부호 없는 정수로 캐스팅하고, 10비트 왼쪽으로 시프트한다.

이는 pwmDuty 값을 1024배하는 것과 같다. 그 후, 100으로 나누어 퍼센트 단위의 듀티 사이클을 계산한다.

if (PWM_Digital_Duty > PWM_MAX_DUTY);
계산된 PWM_Digital_Duty 값이 허용된 최대 듀티 사이클 값 PWM_MAX_DUTY를 초과하는 경우, 

PWM_Digital_Duty를 PWM_MAX_DUTY로 제한한다. 

이는 하드웨어를 보호하고 오동작을 방지하기 위함이다.

 

2. PWM 듀티 사이클 비트 설정

pCR7 포인터를 사용하여 하드웨어 레지스터에 비트 단위로 듀티 사이클 값을 설정한다.

이 코드는 듀티 사이클 값을 비트 마스크 연산과 비트 시프트 연산을 통해 분리하여 각각의 비트 필드

(PWMx_DC_9부터 PWMx_DC_0)에 할당하고 있다.


예를 들어, pCR7->PWMx_DC_9 = (PWM_Digital_Duty & 0x200) >> 9;는 

듀티 사이클 값에서 9번째 비트를 추출하여 PWMx_DC_9에 설정한다.

 

하드웨어의 PWM 출력 관련 설정에서 사용되는 레지스터에 특정 비트 값을 설정하는 과정을 설명한다.

이 코드는 특히 PWM 듀티 사이클을 제어하는 데 중요한 역할을 하는 비트를 설정한다.

자세한 설명은 다음과 같다.

 

비트 마스크(&)

& 0x200: 이 연산은 비트 마스킹을 사용하여 PWM_Digital_Duty 값에서 10번째 비트(2^9, 512를 나타내는 비트)만을 추출한다. 0x200은 16진수로 512를 의미하며, 이는 이진수 1000000000과 동일하다. PWM_Digital_Duty 값과 이 마스크를 AND 연산을 수행하면, PWM_Digital_Duty의 10번째 비트만 남고 나머지 비트는 0이 된다.


비트 시프트(>>)

>> 9: 위 비트 마스킹 결과로 얻은 값에서 추출된 비트(10번째 비트)를 오른쪽으로 9비트 시프트한다. 이 연산은 10번째 비트를 최하위 비트(0번 비트) 위치로 이동시킨다. 결과적으로 이 비트는 값이 0이거나 1인 단일 비트 값으로 변환된다.

할당(=)

pCR7->PWMx_DC_9 =: 비트 시프트 결과로 얻은 단일 비트 값을 pCR7의 PWMx_DC_9 멤버에 할당한다. PWMx_DC_9는 PWM 듀티 사이클을 제어하는 데 사용되는 하드웨어 레지스터의 한 부분을 나타내며, 해당 비트 위치는 PWM 신호의 전체 듀티 사이클 설정에서 중요한 역할을 한다.


첨언(응용)

이 구문을 통해 PWM 듀티 사이클의 10번째 비트가 PWMx_DC_9 레지스터 비트로 설정된다. 이러한 방식으로, PWM 신호의 듀티 사이클을 제어하여, 예를 들면 모터의 회전 속도를 조절하거나 LED의 밝기를 세밀하게 조정하는 등의 작업에서 사용된다. 특히, 이런 설정은 하드웨어가 요구하는 정확한 시간과 주기에 맞추어서 PWM 신호를 생성할 때 필수적이다.

 

3. 추가 레지스터 설정

pCR14->HS13_3 = set_3; 등과 같은 라인들은 pCR14 레지스터의 특정 비트를 설정한다.

set_3, set_2, set_1, set_0 등의 값들은 이 case에 따라 각 비트의 값을 나타낸다.

 

따라서 위 코드는 주로 하드웨어의 특정 기능을 활성화하거나 구성하기 위해 사용된다.

PWM 설정은 주로 모터 속도 제어, LED 밝기 조절 등에 널리 사용되며,

pCR14와 같은 추가 레지스터 설정은 해당 하드웨어 모듈의 다른 기능을 설정하거나 특정 상태를 활성화하기 위해 사용된다.

반응형

'개발 노트 (C언어)' 카테고리의 다른 글

Stack Overflow 왜 발생하는가? #스택 #큐  (0) 2024.05.15
[C언어] 포인터  (0) 2024.04.24