[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 관련 내용 참조
[ADC]
총 19개의 채널이 있으며,
15개까지의 외부 input이 존재하고 나머지 4개는 이미 reserve되어 있기에 수정 불가
붉은색 라인은 채널로 사용 시, 이미 Reserve되어 있으므로 주의를 요한다는 의미
채널을 선택하면,
해당 채널의 Parameter를 볼 수 있고 여기서 주목해야할 것은 Resolution 항목이다.
3.3V(Vss, Vdd이면 대부분 5V) 기준이며,
IN1의 Resolution을 분석해보면 3.3 ÷ 4096(2^12)을 나타내는 것을 알 수 있다.
[UART & ADC 활용]
UART 실습
현재는 Nucleo mode로 USB를 통해 PC와 연결되어 통신할 수 있게 되어 있다.
UART1을 쓰려면 변환 젠더가 추가로 필요하니, UART2를 사용할 것
Word length : 한 번에 출력되는 데이터 크기
stop bit : word와 word간, data와 data 를 구분해주는 역할을 한다.
실무에서는 위 parameter spec을 115200 N 8 1 이렇게 부름
__io_putchar
: UART module을 통해 문자를 전송하는 역할을 한다.(시리얼 포트로 1 byte씩 내보내도록 리디렉션)
UART 함수는 실제로 실체가 없기 때문에 console 함수를 통해 실체화시켜줘야 한다.
STM 보드에는 모니터와 같은 출력 콘솔과 연결할 수 있는 단자가 없기에, 시리얼 터미널로 리디렉션해줘야 한다.
이렇게 리디렉션 해줌으로써, printf 함수(string 출력 함수) 등을 사용할 수 있게 된다.
<extern>
: 해당 변수나 함수가 현재 파일 내에 정의되지 않았음을 컴파일러에게 알리는 기능을 한다.
다른 소스파일에서 정의된 변수나 함수를 현재 파일에서 사용하고자 할 때 사용한다.
&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축의 클릭 상태를 디지털 값으로 읽어 터미널 화면에 출력하여라.
우리가 사용할 채널이 두 가지 이므로, Number of Conversion = 2
각 Rank에 Channel 6, 7 설정
Sampling은 많이 할수록 정확한 값이 도출되므로 최대한 480cycle로 설정
/* 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을 출력하기 위해 반전해주었음.
'# Semiconductor > [Semicon Academy]' 카테고리의 다른 글
[Harman 세미콘 아카데미] 39일차 - ATmega128(Ultrasonic, ADC) (0) | 2023.08.21 |
---|---|
[Harman 세미콘 아카데미] 38일차 - ARM & RTOS 활용(ADC, Interrupt, Timer) (0) | 2023.08.18 |
[Harman 세미콘 아카데미] 36일차 - ARM & RTOS 활용(STM32 Review, LED 실습) (0) | 2023.08.16 |
[Harman 세미콘 아카데미] 35일차 - PSpice(CMOS Inverter, Gate, LATCH, Timer 555) (0) | 2023.08.04 |
[Harman 세미콘 아카데미] 34일차 - PSpice(OPAMP의 개념 및 활용) (0) | 2023.08.03 |