본문 바로가기
# Semiconductor/[Semicon Academy]

[Harman 세미콘 아카데미] 37일차 - ARM & RTOS 활용(UART & ADC 활용)

by Graffitio 2023. 8. 17.
[Harman 세미콘 아카데미] 37일차 - ARM & RTOS 활용(UART & ADC 활용)
728x90
반응형
[UART]

 

UART : 비동기 직렬 통신

과거에는 속도가 1,200 bps(≒baudrate)정도였기에,

   k(10^3 ≒ 2^10), M(10^6 ≒ 2^20), G(10^9 ≒ 2^30), T(10^12 ≒ 2^40), P(10^15 ≒ 2^50)

   m(mili), u(micro), n(nano), p(pico)

와 같이 데이터 크기를 상세하게 구분하여 관리하였다.

 

UART 관련 내용 참조

https://rangvest.tistory.com/entry/Harman-%EC%84%B8%EB%AF%B8%EC%BD%98-%EC%95%84%EC%B9%B4%EB%8D%B0%EB%AF%B8-28%EC%9D%BC%EC%B0%A8-ATmege128UART-%ED%86%B5%EC%8B%A0-Realtime-clock

 

[Harman 세미콘 아카데미] 28일차 - ATmege128(UART 통신, Realtime clock)

[UART 통신] Serial 통신의 기초 1. 마이크로 프로세서의 정보 교환 방법(외부와 정보 교환) 1) 직렬 통신(Serial Communications) : 데이터 비트를 1개의 비트 단위로 외부에 송수신하는 방식으로, 구현하기

rangvest.tistory.com

 


 

[ADC]

 

총 19개의 채널이 있으며,

15개까지의 외부 input이 존재하고 나머지 4개는 이미 reserve되어 있기에 수정 불가

붉은색 라인은 채널로 사용 시, 이미 Reserve되어 있으므로 주의를 요한다는 의미

 

채널을 선택하면,

해당 채널의 Parameter를 볼 수 있고 여기서 주목해야할 것은 Resolution 항목이다.

3.3V(Vss, Vdd이면 대부분 5V) 기준이며,

IN1의 Resolution을 분석해보면 3.3 ÷ 4096(2^12)을 나타내는 것을 알 수 있다.

 


 

[UART & ADC 활용]

 

UART 실습

 

GPIO Setting에서 해당 핀의 정보를 볼 수 있다.

 

현재는 Nucleo mode로 USB를 통해 PC와 연결되어 통신할 수 있게 되어 있다.

UART1을 쓰려면 변환 젠더가 추가로 필요하니, UART2를 사용할 것

 

Word length : 한 번에 출력되는 데이터 크기

stop bit : word와 word간, data와 data 를 구분해주는 역할을 한다.

실무에서는 위 parameter spec을 115200 N 8 1 이렇게 부름

 

얘네는 USB롤 통해서 이미 연결되어 있으므로 따로 배선해줄 필요 없음.

 

__io_putchar 

 

UART module을 통해 문자를 전송하는 역할을 한다.(시리얼 포트로 1 byte씩 내보내도록 리디렉션)

UART 함수는 실제로 실체가 없기 때문에 console 함수를 통해 실체화시켜줘야 한다.

STM 보드에는 모니터와 같은 출력 콘솔과 연결할 수 있는 단자가 없기에, 시리얼 터미널로 리디렉션해줘야 한다.

이렇게 리디렉션 해줌으로써, printf 함수(string 출력 함수) 등을 사용할 수 있게 된다.

 

여기에 해당 함수 있으니, 가져와서 쓰면 된다.

    <extern>

       : 해당 변수나 함수가 현재 파일 내에 정의되지 않았음을 컴파일러에게 알리는 기능을 한다.

         다른 소스파일에서 정의된 변수나 함수를 현재 파일에서 사용하고자 할 때 사용한다.         

huart2로 typedef(handle)되어 있다.

        &huart : UART Port에 대한 handle(포인터)

        &ch :전송할 버퍼의 Data pointer

        1 :전송할 버퍼의 Data size

        500 : Timeout : 정상적으로 통신이 이루어지지 않았다는 것을 판단을 할 수 있는 시간

                 9600 ≒ 1k byte / sec = 1 byte / 1ms

 

.

 

<참고 사항 >

  ① 우리는 HAL_Transmit 함수(HAL 함수)를 사용할 것이므로, 

  ② HAL_Init; 이후에 문장이 작성되어야 한다.

  ③ Putty 는 개행문자가 없다면, while문 외부에서 사용 시 출력이 되지 않는다.

 

 

ADC 실습

 

Port에서 아날로그 값을 읽어오는 작업은 3 단계로 이루어 진다.

Start ▶ Read Stop

 

<가변저항값(Volume Value)에 따른 아날로그 입력 신호를 출력>

void SystemClock_Config(void);
static void MX_GPIO_Init(void);
static void MX_USART2_UART_Init(void);
static void MX_ADC1_Init(void);
/* USER CODE BEGIN PFP */

/* USER CODE END PFP */

/* Private user code ---------------------------------------------------------*/
/* USER CODE BEGIN 0 */
int __io_putchar(int ch) // 1 byte output function to CONSOLE(monitor)
{
//	char a = ch;
	HAL_UART_Transmit(&huart2, &ch, 1, 100);
}
/* USER CODE END 0 */

/**
  * @brief  The application entry point.
  * @retval int
  */
int main(void)
{
  /* USER CODE BEGIN 1 */

  /* USER CODE END 1 */

  /* MCU Configuration--------------------------------------------------------*/

  /* Reset of all peripherals, Initializes the Flash interface and the Systick. */
  HAL_Init();

  /* USER CODE BEGIN Init */
  int aVal = 0;
  /* USER CODE END Init */

  /* Configure the system clock */
  SystemClock_Config();

  /* USER CODE BEGIN SysInit */

  /* USER CODE END SysInit */

  /* Initialize all configured peripherals */
  MX_GPIO_Init();
  MX_USART2_UART_Init();
  MX_ADC1_Init();
  /* USER CODE BEGIN 2 */

  /* USER CODE END 2 */

  /* Infinite loop */
  /* USER CODE BEGIN WHILE */
  while (1)
  {
    /* USER CODE END WHILE */

    /* USER CODE BEGIN 3 */

	  HAL_ADC_Start(&hadc1); // Start
	  aVal = HAL_ADC_GetValue(&hadc1); // Read
	  HAL_ADC_Stop(&hadc1); // Stop
	  printf("ADC ch : %d, Value : %d\r\n", 0, aVal);
	  HAL_Delay(200);
  }
  /* USER CODE END 3 */
}

 


 

[Mission]

 

조이스틱의 X, Y 축을 ADC1의 아날로그 채널에 연결하여 스틱의 움직임에 따라 X, Y 값을 표기하고

동시에 Z축의 클릭 상태를 디지털 값으로 읽어 터미널 화면에 출력하여라.

 

 

X, Y : Analog / Z : Digital
HAL_ADC_PollForConversion(); : ADC 변환이 완료될 때까지 대기하도록 하는 함수

우리가 사용할 채널이 두 가지 이므로, Number of Conversion = 2

각 Rank에 Channel 6, 7 설정

Sampling은 많이 할수록 정확한 값이 도출되므로 최대한 480cycle로 설정

Z 입력은 디지털 신호 입력이며, 모듈에 별도 저항이 없으므로 내부 풀업 저항을 활성화시켜줘야 한다.

 

/* Private function prototypes -----------------------------------------------*/
void SystemClock_Config(void);
static void MX_GPIO_Init(void);
static void MX_USART2_UART_Init(void);
static void MX_ADC1_Init(void);
/* USER CODE BEGIN PFP */

/* USER CODE END PFP */

/* Private user code ---------------------------------------------------------*/
/* USER CODE BEGIN 0 */
int __io_putchar(int ch) // 1 byte output function to CONSOLE(monitor)
{
//	char a = ch;
	HAL_UART_Transmit(&huart2, &ch, 1, 100);
}
/* USER CODE END 0 */

/**
  * @brief  The application entry point.
  * @retval int
  */
int main(void)
{
  /* USER CODE BEGIN 1 */

  /* USER CODE END 1 */

  /* MCU Configuration--------------------------------------------------------*/

  /* Reset of all peripherals, Initializes the Flash interface and the Systick. */
  HAL_Init();

  /* USER CODE BEGIN Init */
  int xVal = 0;
  int yVal = 0;
  int zVal = 0;
  /* USER CODE END Init */

  /* Configure the system clock */
  SystemClock_Config();

  /* USER CODE BEGIN SysInit */

  /* USER CODE END SysInit */

  /* Initialize all configured peripherals */
  MX_GPIO_Init();
  MX_USART2_UART_Init();
  MX_ADC1_Init();
  /* USER CODE BEGIN 2 */

  /* USER CODE END 2 */

  /* Infinite loop */
  /* USER CODE BEGIN WHILE */
  while (1)
  {
    /* USER CODE END WHILE */

    /* USER CODE BEGIN 3 */
	  HAL_ADC_Start(&hadc1); // Start
	  HAL_ADC_PollForConversion(&hadc1, 100);
	  xVal = HAL_ADC_GetValue(&hadc1)*90/4095; // xVal Read
	  HAL_ADC_PollForConversion(&hadc1, 100);
	  yVal = HAL_ADC_GetValue(&hadc1)*90/4095; // yVal Read
	  HAL_ADC_Stop(&hadc1); // Stop
	  zVal = !(HAL_GPIO_ReadPin(Z_Value_GPIO_Port, Z_Value_Pin));
	  printf("X : %d, Y = %d, Z = %d \r\n", xVal, yVal, zVal);
	  HAL_Delay(300);
  }
  /* USER CODE END 3 */
}

 

xVal, yVal 는 0~4095까지의 범위를 가지므로, 좀 더 심플하게 표현하기 위해 해당 변수에 *90/4095 적용

zVal 은 풀업 저항을 사용하여 값을 표현하였고, 눌렀을 때 1을 출력하기 위해 반전해주었음.

 

 

 

728x90
반응형