Toby's Study Blog
article thumbnail
Published 2023. 8. 30. 14:17
[stm32] UART ์‹ค์Šต embedded

๐ŸŒ ์‹ค์Šต ๋ชฉํ‘œ

1. PC - MCU Uart Polling & Interrupt ๋‘๊ฐ€์ง€ ๋ฐฉ์‹ ๋ฌธ์ž์—ด ์†ก์ˆ˜์‹  ํ…Œ์ŠคํŠธ  
2. PC - MCU Uart ํ†ต์‹  ์—ฐ๊ฒฐ์„ ์œ„ํ•œ uart.c ํŒŒ์ผ ์ƒ์„ฑ

3. Command Line Interface (CLI)์˜ ๊ธฐ๋Šฅ ๊ตฌํ˜„์„ ์œ„ํ•œ cli.c ํŒŒ์ผ ์ƒ์„ฑ
4. ์ˆ˜ํ–‰ํ•  ๋™์ž‘ led.c, pwm.c ํŒŒ์ผ ์ƒ์„ฑ

 

๐ŸŒ Uart ์„ธํŒ…

์—ฌ๊ธฐ์„œ USART๋Š” ๊ฐ์ข… ํ†ต์‹  ํ”„๋กœํ† ์ฝœ(e.g. UART, SPI, I2C ๋“ฑ..)์„ ๊ตฌํ˜„ํ•˜๊ณ  ์„œ๋น„์Šคํ•˜๋Š” ํฌํŠธ์ด์ง€ USART ํ†ต์‹ ์ด ์•„๋‹ˆ๋‹ค.

 

1. UART ์„ธํŒ…

 1.1 Word Length 
 ํ•œ ๋ฒˆ์˜ ๋ฐ์ดํ„ฐ ์ „์†ก์—์„œ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๋Š” ๋น„ํŠธ ์ˆ˜๋ฅผ ์„ค์ •  8๋น„ํŠธ์ด๋ฉด 0๋ถ€ํ„ฐ 255๊นŒ์ง€์˜ ๊ฐ’์ด๋ฏ€๋กœ ๋Œ€๋ถ€๋ถ„์˜ ๊ฐ’์„ ํ‘œํ˜„ํ•  ์ˆ˜
 ์žˆ์œผ๋ฉฐ ๋” ๋‚ฎ๊ฑฐ๋‚˜ ๋” ๋†’์„ ๊ฒฝ์šฐ ํ˜ธํ™˜์„ฑ, ํšจ์œจ์„ฑ ๋“ฑ ๋ฌธ์ œ๊ฐ€ ๋ฐœ์ƒํ•  ์ˆ˜ ์žˆ์–ด 8๋น„ํŠธ๋ฅผ ์‚ฌ์šฉํ•œ๋‹ค.
 1.2 Parity
 ์ „์†กํ•  ๋ฐ์ดํ„ฐ bit ์ˆ˜๊ฐ€ ์ง์ˆ˜, ํ™€์ˆ˜ ์ธ์ง€๋ฅผ ๋งจ ๋ ๋น„ํŠธ๋ฅผ ํ†ตํ•ด ํ‘œ์‹œํ•˜์—ฌ ์ˆ˜์‹  ์‹œ ์ง์ˆ˜ ํ™€์ˆ˜ ๋งž๋Š”์ง€ ํ™•์ธ
 1.3 Data Direction
 ํ•ด๋‹น MCU๋กœ๋ถ€ํ„ฐ ๋ฐ์ดํ„ฐ๊ฐ€ ํ˜๋Ÿฌ๊ฐ€๋Š” ๋ฐฉํ–ฅ์„ ์„ค์ •ํ•˜๋ฉฐ ์†ก์‹ , ์ˆ˜์‹ , ์†ก/์ˆ˜์‹  ์ค‘ ํ•˜๋‚˜๋ฅผ ์„ ํƒํ•œ๋‹ค. 
 1.4 Over Sampling
 ์†ก/์ˆ˜์‹ ์˜ ์ •ํ™•๋„๋ฅผ ๋†’์ด๋Š” ๋ฐ ์‚ฌ์šฉ๋˜๋ฉฐ ๋ณดํ†ต 16๋ฐฐ๋ฅผ ์‚ฌ์šฉํ•œ๋‹ค.

2. ๋ฐ์ดํ„ฐ ์‹œํŠธ์— ์ ํ˜€์žˆ๋Š” ๋Œ€๋กœ PD8  ํ•€ -> TX ํ•€์œผ๋กœ, PD9 ํ•€ -> RX ํ•€์œผ๋กœ ์„ธํŒ…ํ•˜์˜€์œผ๋ฉฐ
3. USART3 ์™€ System Core NVIC์—์„œ ์ธํ„ฐ๋ŸฝํŠธ ์†ก์ˆ˜์‹ ์„ ์œ„ํ•œ Global interrupt๋ฅผ Enable๋กœ ์„ธํŒ…ํ•˜์˜€์Œ

USART3 ์†ก์ˆ˜์‹  ํฌํŠธ ์ง€์ •

๐ŸŒ ์‹ค์Šต ๊ฒฐ๊ณผ

ใ…ˆhttps://github.com/Tobbyvv/stm32-project/tree/main/uart_cli

PC - MCU Uart Polling & Interrupt ๋ฐฉ์‹์œผ๋กœ ๋ฌธ์ž์—ด ์†ก์ˆ˜์‹  ํ…Œ์ŠคํŠธ

 1.1 Polling ๋ฐฉ์‹ 

uint8_t text = 'Hello';
while(1)
{   //1. MCU์—์„œ ์ˆ˜์‹ (Receive) ์„ฑ๊ณต ์‹œ ๋ฐœ์ƒํ•˜๋Š” HAL_OK ์‹ ํ˜ธ๋ฅผ while ๋ฌธ์„ ํ†ตํ•ด ๋ฌดํ•œํžˆ ์ฒดํฌ
   if(HAL_UART_Receive(&huart3, &text, 1, 10) == HAL_OK){
    //2. ์ˆ˜์‹  ์„ฑ๊ณต ์‹œ ๋ฐ›์€ ๋ฉ”์„ธ์ง€๋ฅผ PC๋กœ ์†ก์‹ (Transmit) 
     HAL_UART_Transmit(&huart3, &text, 1, 10);
    }}

 1.2 Interrupt ๋ฐฉ์‹

uint8_t rx_buffer; 

//์ธํ„ฐ๋ŸฝํŠธ ๋ฐœ์ƒ ์‹œ ํ•˜๋˜ ์ž‘์—…์„ ๋ฉˆ์ถ”๊ณ  ํ•ด๋‹น ๋ฉ”์†Œ๋“œ๊ฐ€ ์‹คํ–‰๋จ
void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart)
{   
   if(huart->Instance==USART3){
        //IT : ๋น„ ๋ธ”๋กœํ‚น(์ˆ˜์‹  ๋Œ€๊ธฐ ์ค‘ ๋™์‹œ์— ํ•ด์•ผํ•  ๋‹ค๋ฅธ ์ž‘์—… ์ˆ˜ํ–‰)
      HAL_UART_Receive_IT(&huart3, &rx3_data, 1);  
        //์ธํ„ฐ๋ŸฝํŠธ(it) ์ˆ˜์‹  ํ•จ์ˆ˜, 1byte๊ฐ€ ๋“ค์–ด์˜ฌ ๋•Œ๋งˆ๋‹ค ํ™•์ธํ•จ
      HAL_UART_Transmit(&huart3, &rx3_data, 1, 10); 
        //๋“ค์–ด์˜จ ๋ฐ์ดํ„ฐ๋ฅผ 1byte ์”ฉ ๋ณด๋‚ธ๋‹ค.
   }}

Polling ๋ฐฉ์‹, ์ธํ„ฐ๋ŸฝํŠธ ๋ฐฉ์‹ ๋ชจ๋‘ Hello๋ฅผ ๋ณด๋‚ด๋ฉด Hello๊ฐ€ ์ถœ๋ ฅ๋จ

PC - MCU Uart ํ†ต์‹ ์„ ์œ„ํ•œ uart.c ํŒŒ์ผ ์ƒ์„ฑ

#include <stdio.h>
#include <stdlib.h>
#include <stdarg.h>
#include <stdbool.h>

#include "main.h"
#include "uart.h"
#include "cli.h"

extern UART_HandleTypeDef huart3;  // UART ํ†ต์‹  ํ•ธ๋“ค๋Ÿฌ ์„ ์–ธ

#define D_BUF_MAX 100  // ๋ฐ์ดํ„ฐ๋ฅผ ์ €์žฅํ•  ๋ฒ„ํผ์˜ ์ตœ๋Œ€ ํฌ๊ธฐ ์ •์˜

// ๋ฐ์ดํ„ฐ๋ฅผ ์ €์žฅํ•  ๊ตฌ์กฐ์ฒด ์ •์˜
typedef struct {
  uint8_t buf[D_BUF_MAX+1];  // ๋ฐ์ดํ„ฐ ๋ฒ„ํผ ๋ณ€์ˆ˜
  uint8_t idx;               // ๋ฒ„ํผ ์ธ๋ฑ์Šค ๋ณ€์ˆ˜
  uint8_t flag;              // ์ˆ˜์‹  ์™„๋ฃŒ ํ”Œ๋ž˜๊ทธ
} BUF_T;

BUF_T gBufObj[2];  // ๋‘ ๊ฐœ์˜ ๋ฒ„ํผ ๊ตฌ์กฐ์ฒด ๋ฐฐ์—ด๋กœ ์„ ์–ธ
static UART_CBF uart_cbf;  // UART ์ˆ˜์‹  ์ฝœ๋ฐฑ ํ•จ์ˆ˜ ํฌ์ธํ„ฐ ์„ ์–ธ
uint8_t rxd;  // ์ˆ˜์‹ ํ•œ ๋ฐ”์ดํŠธ ๋ฐ์ดํ„ฐ๋ฅผ ์ €์žฅํ•  ๋ณ€์ˆ˜

void uart_init(void)
{
  gBufObj[0].idx = 0;
  gBufObj[0].flag = false;
  // UART ์ˆ˜์‹  ์ธํ„ฐ๋ŸฝํŠธ ํ™œ์„ฑํ™” ๋ฐ ์ฒซ ๋ฒˆ์งธ ๋ฐ”์ดํŠธ(๋ฐ์•„ํ„ฐ) ์ˆ˜์‹  ๋Œ€๊ธฐ
  HAL_UART_Receive_IT(&huart3, (uint8_t *)&rxd, 1);
  printf("UART Initialized...\r\n");
  fflush(stdout);  // printf ํ›„ ์ถœ๋ ฅ ๋ฒ„ํผ ๋น„์›€
}
// UART ์ˆ˜์‹  ์ฝœ๋ฐฑ ํ•จ์ˆ˜ ๋“ฑ๋ก
void uart_regcbf(UART_CBF cbf)
{
  uart_cbf = cbf;  // ์ „๋‹ฌ๋œ ์ฝœ๋ฐฑ ํ•จ์ˆ˜๋ฅผ uart_cbf์— ๋“ฑ๋ก
}
// UART ์ˆ˜์‹ ๋œ ๋ฐ์ดํ„ฐ ์ฒ˜๋ฆฌ ํ•จ์ˆ˜
void uart_proc(void)
{
  BUF_T *p = (BUF_T *)&gBufObj[0];
  if (p->flag == true) {
    printf("%s:%s", __func__, p->buf);  // ๋””๋ฒ„๊น…์šฉ ์ˆ˜์‹ ๋œ ๋ฐ์ดํ„ฐ ์ถœ๋ ฅ
    if (uart_cbf != NULL) uart_cbf(p->buf); // UART ๋ฐ์ดํ„ฐ ํŒŒ์‹ฑ ํ•จ์ˆ˜ ํ˜ธ์ถœ (๋“ฑ๋ก๋œ ์ฝœ๋ฐฑ ํ•จ์ˆ˜)
    p->idx = 0;  // ๋‹ค์Œ ๋ฐ์ดํ„ฐ ์ˆ˜์‹ ์„ ์œ„ํ•œ ๋ฒ„ํผ ์ธ๋ฑ์Šค ์ดˆ๊ธฐํ™”
    p->flag = false;  // ์ˆ˜์‹  ์™„๋ฃŒ ํ”Œ๋ž˜๊ทธ ์ดˆ๊ธฐํ™”
  }}
// UART ์ˆ˜์‹  ์™„๋ฃŒ ์ฝœ๋ฐฑ ํ•จ์ˆ˜
void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart)
{
  if (huart == &huart3) {
    BUF_T *p = (BUF_T *)&gBufObj[0];
    if (p->flag == false) {
      p->buf[p->idx] = rxd;  // ์ˆ˜์‹ ํ•œ ๋ฐ์ดํ„ฐ๋ฅผ ๋ฒ„ํผ์— ์ €์žฅ
      if (p->idx < D_BUF_MAX) {
        p->idx++;  // ๋ฒ„ํผ ์ธ๋ฑ์Šค ์ฆ๊ฐ€
      }
      if (rxd == '\r' || rxd == '\n') {
        p->buf[p->idx] = '\0';  // ์ˆ˜์‹  ๋ฐ์ดํ„ฐ์˜ ๋์— NULL ๋ฌธ์ž ์ถ”๊ฐ€
        p->flag = true;  // ์ˆ˜์‹  ์™„๋ฃŒ ํ”Œ๋ž˜๊ทธ ์„ค์ •
      }}
    uart_proc();  // ์ˆ˜์‹ ๋œ ๋ฐ์ดํ„ฐ ์ฒ˜๋ฆฌ ํ•จ์ˆ˜ ํ˜ธ์ถœ
    HAL_UART_Receive_IT(&huart3, (uint8_t *)&rxd, 1);  // ๋‹ค์Œ ์ˆ˜์‹  ๋Œ€๊ธฐ
  }}
// UART ํ‘œ์ค€ ์ž…์ถœ๋ ฅ ํ•จ์ˆ˜
int __io_putchar(int ch)
{
  HAL_UART_Transmit(&huart3, (uint8_t *)&ch, 1, 0xffff);  // ๋ฌธ์ž ์ „์†ก
  return ch;
}

Command Line Interface (CLI)์˜ ๊ธฐ๋Šฅ ๊ตฌํ˜„์„ ์œ„ํ•œ cli.c ํŒŒ์ผ ์ƒ์„ฑ

#include <stdio.h>
#include <stdlib.h>
#include <stdarg.h>
#include <stdbool.h>
#include <string.h>

#include "main.h"
#include "uart.h"
#include "led.h"
#include "pwm.h"
#include "cli.h"

#define D_DELIMITER	" ,\r\n" //๊ณต๋ฐฑ, ์‰ผํ‘œ, ๊ตฌ๋ถ„์ž ์ •์˜

// ๋ช…๋ น์–ด ์ฒ˜๋ฆฌ ํ•จ์ˆ˜์˜ ์‹œ๊ทธ๋‹ˆ์ฒ˜ ์ •์˜
typedef int (*CMD_FUNC_T)(int argc, char **argv);

// ๋ช…๋ น์–ด์™€ ํ•ด๋‹น ๋ช…๋ น์–ด๋ฅผ ์ฒ˜๋ฆฌํ•  ํ•จ์ˆ˜ ์ •๋ณด๋ฅผ ์ €์žฅํ•˜๋Š” ๊ตฌ์กฐ์ฒด ์ •์˜
typedef struct {
  char *cmd;        // ๋ช…๋ น์–ด ๋ฌธ์ž์—ด
  uint8_t no;       // ๋ช…๋ น์–ด ๋ฒˆํ˜ธ (๊ณ ์œ  ์‹๋ณ„์ž)
  CMD_FUNC_T cbf;   // ๋ช…๋ น์–ด๋ฅผ ์ฒ˜๋ฆฌํ•  ํ•จ์ˆ˜ ํฌ์ธํ„ฐ
  char *remark;     // ๋ช…๋ น์–ด์— ๋Œ€ํ•œ ์„ค๋ช… ๋ฌธ์ž์—ด
} CMD_LIST_T;

// ๊ฐ ๋ช…๋ น์–ด์— ๋Œ€ํ•œ ์ฒ˜๋ฆฌ ํ•จ์ˆ˜ ์„ ์–ธ
static int cli_help(int argc, char *argv[]);
static int cli_echo(int argc, char *argv[]);
static int cli_led(int argc, char *argv[]);
static int cli_pwm(int argc, char *argv[]);

// ๋ช…๋ น์–ด์™€ ํ•จ์ˆ˜ ์ •๋ณด๋ฅผ ์ €์žฅํ•˜๋Š” ๋ฐฐ์—ด ์„ ์–ธ ๋ฐ ์ดˆ๊ธฐํ™”
const CMD_LIST_T gCmdListObj[] = {
  { "help",  1, cli_help,  "help" },
  { "echo",  2, cli_echo,  "echo [echo data]" },
  { "led",   3, cli_led,   "led [2/3] [on/off]" },
  { "pwm",   4, cli_pwm,   "pwm [0] [0~100]" },
  { NULL,    0, NULL,      NULL }
};

// help ๋ช…๋ น์–ด ์ฒ˜๋ฆฌ ํ•จ์ˆ˜
static int cli_help(int argc, char *argv[])
{
  // ๋“ฑ๋ก๋œ ๋ชจ๋“  ๋ช…๋ น์–ด์— ๋Œ€ํ•œ ์„ค๋ช… ๋ฌธ์ž์—ด ์ถœ๋ ฅ
  for (int i = 0; gCmdListObj[i].cmd != NULL; i++) {
    printf("%s\r\n", gCmdListObj[i].remark);
  }
  return 0;
}
// echo ๋ช…๋ น์–ด ์ฒ˜๋ฆฌ ํ•จ์ˆ˜
static int cli_echo(int argc, char *argv[])
{
  if (argc < 2) printf("Need more arguments\r\n");
  printf("%s\r\n", argv[1]); // ์ž…๋ ฅ๋œ ๋ฐ์ดํ„ฐ ๊ทธ๋Œ€๋กœ ์ถœ๋ ฅ
  return 0;
}

// led ๋ช…๋ น์–ด ์ฒ˜๋ฆฌ ํ•จ์ˆ˜
static int cli_led(int argc, char *argv[])
{
  if (argc < 3) printf("Need more arguments\r\n");
  long no = strtol(argv[1], NULL, 10);  // ๋ฌธ์ž -> ์ˆซ์ž ๋ณ€ํ™˜
  int onoff = strcasecmp(argv[2], "off"); // off์ด๋ฉด 0์„ ๋ฐ˜ํ™˜
  if (onoff != 0) onoff = 1;              // 0์ด ์•„๋‹ˆ๋ฉด 1๋กœ ๋ณ€ํ™˜						
  led_onoff((uint8_t)no, (uint8_t)onoff);   // LED ์ œ์–ด ํ•จ์ˆ˜ ํ˜ธ์ถœ
  return 0;
}

// pwm ๋ช…๋ น์–ด ์ฒ˜๋ฆฌ ํ•จ์ˆ˜
static int cli_pwm(int argc, char *argv[])
{
  if (argc < 3) printf("Need more arguments\r\n");
  // ๋ฌธ์ž -> ์ˆซ์ž ๋ณ€ํ™˜
  long no = strtol(argv[1], NULL, 10); 
  long duty = strtol(argv[2], NULL, 10);
  // duty ์ฃผ๊ธฐ ๊ฐ’์ด ์œ ํšจ ๋ฒ”์œ„๋ฅผ ๋ฒ—์–ด๋‚œ ๊ฒฝ์šฐ ์กฐ์ •
  if (duty > 100) duty = 100;
  if (duty < 0) duty = 0;
  pwm_dimming((uint8_t)no, (uint8_t)duty);  // PWM ์ œ์–ด ํ•จ์ˆ˜ ํ˜ธ์ถœ
  return 0;
}
// ๋ช…๋ น์–ด ๋ฌธ์ž์—ด ๋ถ„์„, ํ•ด๋‹น ๋ช…๋ น์–ด์˜ ์ฒ˜๋ฆฌ ํ•จ์ˆ˜ ํ˜ธ์ถœ์„ ์œ„ํ•œ ํ•จ์ˆ˜
bool cli_parser(uint8_t *buf)
{
#if 1
  int argc = 0;	// ๋ช…๋ น์–ด์˜ ๊ฐฏ์ˆ˜
  char *argv[10]; // ๋ช…๋ น์–ด๋ฅผ ์ €์žฅํ•  ๋ฐฐ์—ด
  char *ptr; // ๋ฌธ์ž์—ด ๋ถ„๋ฆฌ๋ฅผ ์œ„ํ•œ ํฌ์ธํ„ฐ ๋ณ€์ˆ˜

  // ์ž…๋ ฅ๋œ ๋ฌธ์ž์—ด์„ ๊ณต๋ฐฑ ๋ฐ ๊ตฌ๋ถ„์ž๋กœ ๋ถ„๋ฆฌํ•˜์—ฌ argv ๋ฐฐ์—ด์— ์ €์žฅ
  ptr = strtok((char *)buf, D_DELIMITER);
  if (ptr == NULL) return false;

  while(ptr != NULL) {
    argv[argc] = ptr;
    argc++;
    ptr = strtok(NULL, D_DELIMITER);
  }

  // ์ž…๋ ฅ๋œ ๋ช…๋ น์–ด์™€ ๋“ฑ๋ก๋œ ๋ช…๋ น์–ด๋ฅผ ๋น„๊ตํ•˜์—ฌ ํ•ด๋‹น ๋ช…๋ น์–ด์˜ ์ฒ˜๋ฆฌ ํ•จ์ˆ˜ ํ˜ธ์ถœ
  for (int i=0; gCmdListObj[i].cmd != NULL; i++) {
    if (strcasecmp(gCmdListObj[i].cmd, argv[0]) == 0) {
      printf("Calling %s function with argc=%d\n", gCmdListObj[i].cmd, argc);
      gCmdListObj[i].cbf(argc, argv);  // ํ•ด๋‹น ๋ช…๋ น์–ด์˜ ์ฒ˜๋ฆฌ ํ•จ์ˆ˜ ํ˜ธ์ถœ
      return true;
    }}
  printf("Unsupported command..\r\n"); 

#else
  char *ptr = strtok(buf, " ");    //์ฒซ๋ฒˆ์งธ strtok ์‚ฌ์šฉ.
  while (ptr != NULL)              //ptr์ด NULL์ผ๋•Œ๊นŒ์ง€ (strtok ํ•จ์ˆ˜๊ฐ€ NULL์„ ๋ฐ˜ํ™˜ํ• ๋•Œ๊นŒ์ง€)
  {
      printf("%s\n", ptr);         //์ž๋ฅธ ๋ฌธ์ž ์ถœ๋ ฅ
      ptr = strtok(NULL, " ");     //์ž๋ฅธ ๋ฌธ์ž ๋‹ค์Œ๋ถ€ํ„ฐ ๊ตฌ๋ถ„์ž ๋˜ ์ฐพ๊ธฐ
  }
  uart_regcbf(cli_parser);  // UART ์ˆ˜์‹  ์ฝœ๋ฐฑ ํ•จ์ˆ˜ ๋“ฑ๋ก
#endif
  return true;
}
// CLI ์ดˆ๊ธฐํ™” ํ•จ์ˆ˜ (UART ์ˆ˜์‹  ์ฝœ๋ฐฑ ํ•จ์ˆ˜ ๋“ฑ๋ก)
void cli_init(void)
{
  uart_regcbf(cli_parser);
}

์ˆ˜ํ–‰ํ•  ๋™์ž‘ led.c, pwm.c ํŒŒ์ผ ์ƒ์„ฑ

 4.1 led.c

#include <stdint.h>
#include <stdbool.h>
#include <stdio.h>

#include "main.h"
#include "led.h"

void led_init(void)
{
  printf("LED initialized...\r\n"); // LED ์ดˆ๊ธฐํ™” ๋ฉ”์‹œ์ง€ ์ถœ๋ ฅ
}
//led on/off ํ•จ์ˆ˜
bool led_onoff(uint8_t no, uint8_t onoff)
{
  GPIO_PinState sts = onoff ? GPIO_PIN_SET : GPIO_PIN_RESET; 
  switch (no) { // ์ „๋‹ฌ๋œ ๊ฐ’์— ๋”ฐ๋ผ LED ์ƒํƒœ ์„ค์ •
    case 2 :
      HAL_GPIO_WritePin(LD2_GPIO_Port, LD2_Pin, sts);
      break;
    case 3 :
      HAL_GPIO_WritePin(LD3_GPIO_Port, LD3_Pin, sts); 
      break;
    default :
      return false;
  }
  return true; // ์ฒ˜๋ฆฌ ๊ฒฐ๊ณผ ๋ฐ˜ํ™˜ (์„ฑ๊ณต: true, ์‹คํŒจ: false)
}

  4.2 pwm.c

#include <stdio.h>
#include <string.h>
#include <stdbool.h>
#include <stdint.h>

#include "main.h"

extern TIM_HandleTypeDef htim3; // ํƒ€์ด๋จธ ํ•ธ๋“ค๋Ÿฌ ๋ณ€์ˆ˜ ์„ ์–ธ

void pwm_init(void)
{
  printf("Timer3 PWM start\r\n"); 
  HAL_TIM_PWM_Start(&htim3, TIM_CHANNEL_3); // TIM3 ์ฑ„๋„3 PWM ์‹œ์ž‘
}
// PWM ์‹ ํ˜ธ๋กœ ๋ฐ๊ธฐ ์กฐ์ ˆํ•˜๋Š” ํ•จ์ˆ˜
bool pwm_dimming(uint8_t no, uint8_t duty)
{
  bool res = true; // ๋ฐ˜ํ™˜์šฉ ๊ฒฐ๊ณผ ๋ณ€์ˆ˜ ์„ ์–ธ
  uint16_t ccr = (uint16_t)duty * 10; // duty ์ฃผ๊ธฐ๋ฅผ ํƒ€์ด๋จธ์˜ Compare/Capture ๋ ˆ์ง€์Šคํ„ฐ ๊ฐ’์œผ๋กœ ๋ณ€ํ™˜
  switch (no) {
    case 0 :
      __HAL_TIM_SET_COMPARE(&htim3, TIM_CHANNEL_3, ccr); 
    // TIM3์˜ ์ฑ„๋„ 3์˜ Compare/Capture ๋ ˆ์ง€์Šคํ„ฐ์— ccr ๊ฐ’์„ ์„ค์ •ํ•˜์—ฌ ๋ฐ๊ธฐ ์กฐ์ ˆ
      break;
    default :
      res = false;
  }
  return res; // ์ฒ˜๋ฆฌ ๊ฒฐ๊ณผ ๋ฐ˜ํ™˜ (์„ฑ๊ณต: true, ์‹คํŒจ: false)
}

๐ŸŒ ๊ฒฐ๊ณผ ์‚ฌ์ง„

1, help ๋ช…๋ น์–ด

help ๋ช…๋ น์–ด ์ „๋‹ฌ ๊ฒฐ๊ณผ

2. echo ๋ช…๋ น์–ด

echo ๋ช…๋ น์–ด ์ „๋‹ฌ ๊ฒฐ๊ณผ

3. led on/off ๋ช…๋ น์–ด

led 2 on ๋ช…๋ น์–ด ์ „๋‹ฌ ๊ฒฐ๊ณผ

4. pwm duty ๋ณ€๊ฒฝ ๋ช…๋ น์–ด

pwm 0 2 ๋ช…๋ น์–ด ์ „๋‹ฌ ๊ฒฐ๊ณผ(LD1์˜ ์„ธ๊ธฐ๊ฐ€ ์•ฝํ•ด์ง)

 

'embedded' ์นดํ…Œ๊ณ ๋ฆฌ์˜ ๋‹ค๋ฅธ ๊ธ€

[stm32] ADC & DMA ์‹ค์Šต  (0) 2023.09.06
[stm32] ADC & DMA ์ด๋ก  ์ •๋ฆฌ  (0) 2023.09.06
[stm32] UART ์ด๋ก  ์ •๋ฆฌ  (0) 2023.08.16
[stm32] Timer ์‹ค์Šต  (0) 2023.08.16
[stm32] Timer ์ด๋ก  ์ •๋ฆฌ  (0) 2023.08.16
profile

Toby's Study Blog

@Toby12

ํฌ์ŠคํŒ…์ด ์ข‹์•˜๋‹ค๋ฉด "์ข‹์•„์š”โค๏ธ" ๋˜๋Š” "๊ตฌ๋…๐Ÿ‘๐Ÿป" ํ•ด์ฃผ์„ธ์š”!

๊ฒ€์ƒ‰ ํƒœ๊ทธ