본문 바로가기
DSP, MCU/STM32 (ARM Cortex-M)

STM32 , 4비트 병렬 가산기( IC 7483 ) 소스코드로 구현 ( 호환보드 사용 )

by eteo 2022. 5. 20.

 

호환보드에 대한 설명은 아래 링크에 있습니다.

https://eteo.tistory.com/65

 

 

 

 

호환보드에서 버튼 4개(PG0-PG3)을 사용했고 가산기의 Sum을 표현하는데 LED 4개(PD4-PD7)를 사용하고 Carry-Out을 표현하는데 LED 1개(PD2)해서 총 LED 5개를 사용했다.

 

그리고 F-M점퍼선으로 따로 선을 빼서 버튼 4개(PE6-PE3)를 더 추가하였고 Carry-In 역할을 하는 input으로 PC8을 사용했다.

 

참고로 버튼은 호환보드의 버튼이 풀업으로 되어 있어서 따로 뺀 버튼 또한 마찬가지로 풀업으로 구성했다.

 

 

 

소스코드

  /* USER CODE BEGIN WHILE */
while (1)
  {
      ttl74138();
    /* USER CODE END WHILE */
    /* USER CODE BEGIN 3 */
  }

 

while문 내에서는 그냥 ttl74138 함수를 호출한다. 입력을 받아서 변수에 저장하는건 while문 내에서 하고 변수의 주소나 배열의 시작주소를 인수로 넘기는 방식도 생각해봤는데 굳이 싶어서 뺐다.

 

 

void ttl7483(){
	  unsigned char inputA[4]={0,};
	  unsigned char inputB[4]={0,};
	  unsigned char inputC0;
	  unsigned char outputDecimal;
	  unsigned char sum[4] = {0,};
	  unsigned char outputC4;
	  unsigned char num1, num2;

	  for(int i=0; i<4; i++){
		  inputA[i] = (!HAL_GPIO_ReadPin(GPIOG, 0x0008 >> i)) * (0x0001)<<i;
	  }

	  num1 = inputA[0]+inputA[1]+inputA[2]+inputA[3];

	  for(int i=0; i<4; i++){
		  inputB[i] = (!HAL_GPIO_ReadPin(GPIOE, 0x0040 >> i)) * (0x0001)<<i;
	  }

	  num2 = inputB[0]+inputB[1]+inputB[2]+inputB[3];

	  inputC0 = HAL_GPIO_ReadPin(GPIOC, GPIO_PIN_8);	// carry-in

	  outputDecimal = num1 + num2 + inputC0;


	  for(int i=0; i<4; i++){
		  sum[i] = outputDecimal%2;
		  outputDecimal /= 2;
	  }

	  outputC4=outputDecimal;	// carry-out


	  if(sum[0])
		  HAL_GPIO_WritePin(GPIOD, GPIO_PIN_7, 1);
	  else
		  HAL_GPIO_WritePin(GPIOD, GPIO_PIN_7, 0);

	  if(sum[1])
		  HAL_GPIO_WritePin(GPIOD, GPIO_PIN_6, 1);
	  else
		  HAL_GPIO_WritePin(GPIOD, GPIO_PIN_6, 0);

	  if(sum[2])
		  HAL_GPIO_WritePin(GPIOD, GPIO_PIN_5, 1);
	  else
		  HAL_GPIO_WritePin(GPIOD, GPIO_PIN_5, 0);

	  if(sum[3])
		  HAL_GPIO_WritePin(GPIOD, GPIO_PIN_4, 1);
	  else
		  HAL_GPIO_WritePin(GPIOD, GPIO_PIN_4, 0);

	  if(outputC4)
		  HAL_GPIO_WritePin(GPIOD, GPIO_PIN_2, 1);
	  else
		  HAL_GPIO_WritePin(GPIOD, GPIO_PIN_2, 0);
}

 

먼저 버튼 4개(PG0-PG3) 에서 0부터 15범위의 4비트 2진수 하나를 받고 또 다른 버튼 4개(PE6-PE3)에서 역시 4비트 2진수 하나를 받아야 하는데 해당 부분은 for문을 사용했다.

 

풀업 스위치니까 !연산자를 사용하고 3번핀(0x0008)부터 0번핀(0x0001)까지를 읽는데 2진수니까 읽은 값에서 1 << i 만큼 가중치를 곱해준다. 

	  for(int i=0; i<4; i++){
		  inputA[i] = (!HAL_GPIO_ReadPin(GPIOG, 0x0008 >> i)) * (0x0001)<<i;
	  }

 

 

num1과 num2을 더하고 0부터 1범위의 carry-in까지 더한 값은 outputDecimal에 저장한다.

 

 

10진수를 2진수로 바꿔 배열에 순서대로 저장하는 것은 아래처럼 짰다.

	  for(int i=0; i<4; i++){
		  sum[i] = outputDecimal%2;
		  outputDecimal /= 2;
	  }

 

 

 

그 다음은 가산 결과에 따라 해당 2진수 자리에 불이 들어오고 만약 결과값이 0xf를 넘어서 Carry-out이 발생한다면 LED D3번에 불이 들어온다.