<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0">
  <channel>
    <title>Embeded-Korea</title>
    <link>https://coding-yoon.tistory.com/</link>
    <description>This blog is the project and development journal!</description>
    <language>ko</language>
    <pubDate>Wed, 1 Jul 2026 23:16:21 +0900</pubDate>
    <generator>TISTORY</generator>
    <ttl>100</ttl>
    <managingEditor>18진수</managingEditor>
    <image>
      <title>Embeded-Korea</title>
      <url>https://tistory1.daumcdn.net/tistory/3568312/attach/2c9d134a11e54aa6a4345a474c17fbd3</url>
      <link>https://coding-yoon.tistory.com</link>
    </image>
    <item>
      <title>5. 아두이노 우노 Atmega328P 타이머로 1초 만들기.</title>
      <link>https://coding-yoon.tistory.com/307</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;자. 저번 글에서 delay 함수를 통해 LED를 1초 간격으로 Blinking 하는 예제를 만들어보았다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;하지만 그 단점으로 delay 동안 다른 동작을 할 수 없으므로 사용할 때 조심해야 한다 했으며, 타이머라는 것을 통해 똑같이 Blinking 을 구현한다고 하였다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;타이머란 무엇인가?&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;말 그대로 타이머는 시간을 재는 것이다. 아래 그림을 봐보자. 도망가지 말도록하자. 딥하게 들어가는건 다음이지만 대충 Timer/Counter가 어떻게 해서 시간을 재는지 정도의 플로우만 이해했으면 해서 데이터 시트의 그림을 첨부했다.&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock widthContent&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;761&quot; data-origin-height=&quot;538&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bxHw4k/btsL19KE0iZ/C9qbFhQ3cJkJ6idi6Up7q0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bxHw4k/btsL19KE0iZ/C9qbFhQ3cJkJ6idi6Up7q0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bxHw4k/btsL19KE0iZ/C9qbFhQ3cJkJ6idi6Up7q0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbxHw4k%2FbtsL19KE0iZ%2FC9qbFhQ3cJkJ6idi6Up7q0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;761&quot; height=&quot;538&quot; data-origin-width=&quot;761&quot; data-origin-height=&quot;538&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;아두이노 우노 보드를 자세히 보면, 아래와 같이 외부 발진기가 존재한다. 당연히 Atmega328P 칩 내에도 내부 발진기가 존재하나 외부 발진기가 안정성과 정확도가 더 높으므로 보통 보드를 사면 외부 발진기가 거의 존재한다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;78&quot; data-origin-height=&quot;46&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/GXYnT/btsL1BAAsYU/DsKbZN7nUsNkknvYTTEQbk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/GXYnT/btsL1BAAsYU/DsKbZN7nUsNkknvYTTEQbk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/GXYnT/btsL1BAAsYU/DsKbZN7nUsNkknvYTTEQbk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FGXYnT%2FbtsL1BAAsYU%2FDsKbZN7nUsNkknvYTTEQbk%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;78&quot; height=&quot;46&quot; data-origin-width=&quot;78&quot; data-origin-height=&quot;46&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;외부 발진기에서 클럭을 생성하는데 Clock MultiPlexer의 역할은 간단하다. 다양한 외부 발진기들이 있는데 그 중 하나를 골라주는 것이다. 자, Multiplexer(분배기)에서 나온 클럭이 Prescaler(분주기)로 흘러들어간다. 프리스케일러는 무엇일까?&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;음... 어떻게 설명해야할까? 클럭 주파수를 쪼개어 더 긴 시간 간격을 잴 수 있게끔 하기 위한 장치라고 생각하면 이해를 할 수있을까? 아래 예시를 잠깐 들어보았는데, 이해하기 쉽지 않다. 그냥 클럭 주파수를 쪼갠다는 개념으로만 이해해줘도 크게 문제될건 없다. 구현하다보면서 자연스럽게 이해되기 때문이다.&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc; background-color: oklch(0.99 0.004 106.471); color: oklch(0.304 0.04 213.681); text-align: left;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;span&gt;16비트 타이머 예시:&lt;/span&gt;&lt;span&gt;&lt;br /&gt;&lt;/span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&amp;nbsp;=65,535 (16비트로 표현할 수 있는 가장 큰 값)&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;span&gt;16MHz 클럭 &amp;rarr; 4.096&amp;mu;s당 오버플로 &amp;rarr;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;span&gt;&lt;b&gt;0.27ms&lt;/b&gt;&lt;/span&gt;&lt;span&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;밖에 측정 불가&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span&gt;분주기 1024 적용 &amp;rarr; 16MHz/1024 = 15.625kHz &amp;rarr;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;span&gt;&lt;b&gt;4.194초&lt;/b&gt;&lt;/span&gt;&lt;span&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;측정 가능&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;프리스케일러에서 출력된 클럭이 Control Unit에 들어가 최종 사용되는 타이머, ADC 등 여러 사용되는 곳이기 때문에 이 클럭 개념은 굉장히 중요하다.&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;타이머로 1초 만들기&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;회로는 저번이랑 동일하고 코드를 먼저 보여주겠다.&lt;/p&gt;
&lt;pre id=&quot;code_1738209767384&quot; class=&quot;cpp&quot; data-ke-language=&quot;cpp&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;#define F_CPU 16000000UL  // CPU 클럭 속도
#include &amp;lt;avr/io.h&amp;gt;
#include &amp;lt;avr/interrupt.h&amp;gt;

#define LED_RED 2

void Timer1_Init() {
	TCCR1B |= (1 &amp;lt;&amp;lt; WGM12);				  /* CTC 모드 설정 (Clear Timer on Compare Match) */
	TCCR1B |= (1 &amp;lt;&amp;lt; CS12) | (1 &amp;lt;&amp;lt; CS10);  /* 프리스케일러 1024 설정 */
	OCR1A = 15624;						  /* 비교 값 설정 (16MHz / 1024 / 1Hz - 1) */
	TIMSK1 |= (1 &amp;lt;&amp;lt; OCIE1A);			  /* 비교 매치 인터럽트 활성화 */
}

void Task10ms_Init(){
	Timer1_Init();				/* 타이머 초기화 */
	
	DDRD |= (1 &amp;lt;&amp;lt; LED_RED);		/* PD2 핀을 출력으로 설정 */
	PORTD &amp;amp;= ~(1 &amp;lt;&amp;lt; LED_RED);   /* 초기 LED OFF */
	
}

void Task10ms_Main(){
	PORTD ^= (1 &amp;lt;&amp;lt; LED_RED);  /* PD2 핀 토글 (LED ON/OFF) */
}

ISR(TIMER1_COMPA_vect) {
	Task10ms_Main();
}

int main(void) {
	Task10ms_Init();			
	sei();					/* 전역 인터럽트 활성화 */

	while (1) {
		
	}

	return 0;
}&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;코드는 Timer1_Init() 함수를 이해하면 오늘 포스팅도 끝이다.&lt;/p&gt;
&lt;pre id=&quot;code_1738209895844&quot; class=&quot;cpp&quot; data-ke-language=&quot;cpp&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;void Timer1_Init() {
    TCCR1B |= (1 &amp;lt;&amp;lt; WGM12);    // CTC 모드 활성화
    TCCR1B |= (1 &amp;lt;&amp;lt; CS12) | (1 &amp;lt;&amp;lt; CS10);  // 분주기 1024
    OCR1A = 15624;             // 비교값 설정
    TIMSK1 |= (1 &amp;lt;&amp;lt; OCIE1A);   // 비교 매치 인터럽트 활성화
}&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;CTC 모드 : 타이머가 OCR1A 값 도달했을 때&amp;nbsp; 자동 리셋되는 모드&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;분주기 계산은 아래와 같다.&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;617&quot; data-origin-height=&quot;178&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/ypS99/btsL1HgQofd/EkD9GckPLK5ySgSMYJjNpk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/ypS99/btsL1HgQofd/EkD9GckPLK5ySgSMYJjNpk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/ypS99/btsL1HgQofd/EkD9GckPLK5ySgSMYJjNpk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FypS99%2FbtsL1HgQofd%2FEkD9GckPLK5ySgSMYJjNpk%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;617&quot; height=&quot;178&quot; data-origin-width=&quot;617&quot; data-origin-height=&quot;178&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;div data-ke-type=&quot;moreLess&quot; data-text-more=&quot;더보기&quot; data-text-less=&quot;닫기&quot;&gt;&lt;a class=&quot;btn-toggle-moreless&quot;&gt;더보기&lt;/a&gt;
&lt;div class=&quot;moreless-content&quot;&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;분주된 클럭은 15,625인데&amp;nbsp; OCR1A는 15,624일까?&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이유는 간단하다. 컴퓨터는 0부터 시작하기 때문이다.&amp;nbsp;&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;아래 데이터 시트에 관련 챕터들을 필요한 부분만 체크하여 넣어놨으니 한 번 읽어보길 바란다.&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock widthContent&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1075&quot; data-origin-height=&quot;1122&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bXV85R/btsL2fKASu7/sYeEylS816otDmMeZWztk0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bXV85R/btsL2fKASu7/sYeEylS816otDmMeZWztk0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bXV85R/btsL2fKASu7/sYeEylS816otDmMeZWztk0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbXV85R%2FbtsL2fKASu7%2FsYeEylS816otDmMeZWztk0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1075&quot; height=&quot;1122&quot; data-origin-width=&quot;1075&quot; data-origin-height=&quot;1122&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;figure class=&quot;imageblock widthContent&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1072&quot; data-origin-height=&quot;761&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/xynAB/btsL2cfYda5/6d8KbfqzBtBzFlaNd0nrCK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/xynAB/btsL2cfYda5/6d8KbfqzBtBzFlaNd0nrCK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/xynAB/btsL2cfYda5/6d8KbfqzBtBzFlaNd0nrCK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FxynAB%2FbtsL2cfYda5%2F6d8KbfqzBtBzFlaNd0nrCK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1072&quot; height=&quot;761&quot; data-origin-width=&quot;1072&quot; data-origin-height=&quot;761&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;figure class=&quot;imageblock widthContent&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;993&quot; data-origin-height=&quot;657&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/b6scL6/btsL1zv1y4i/7vd9fNt05nkWt3kg9q4AdK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/b6scL6/btsL1zv1y4i/7vd9fNt05nkWt3kg9q4AdK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/b6scL6/btsL1zv1y4i/7vd9fNt05nkWt3kg9q4AdK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fb6scL6%2FbtsL1zv1y4i%2F7vd9fNt05nkWt3kg9q4AdK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;993&quot; height=&quot;657&quot; data-origin-width=&quot;993&quot; data-origin-height=&quot;657&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;pre id=&quot;code_1738210465086&quot; class=&quot;cpp&quot; data-ke-language=&quot;cpp&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;ISR(TIMER1_COMPA_vect) {
	Task10ms_Main();
}&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;타이머가 1초를 지나면 인터럽트가 발생하여 ISR (인터럽트 서비스 루틴)을 발생시킨다. 이제 그 호출되는 함수에 LED 블링킹 로직을 추가하면 된다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;10ms, 100us 등 다양한 타이머를 계산하여 만들 수 있는데, 계산만 잘하면 충분히 구현할 수 있다. 하지만 데이터시트를 보게되면 다양한 모드들이 있는데 CTC 뿐만 아니라 FAST PWM 등 다양한 모드들이 있다. 결국 원리만 이해하여 데이터 시트만 잘 분석하면 누구든 설계를 할 수 있다. 원리는 시간을 잰다 그 이상 그 이하도 아니다.&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;참고&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;CTC 모드에 관해 올려두었으니 읽어보길 바란다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock widthContent&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;676&quot; data-origin-height=&quot;371&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/dnKajO/btsL3ZGFM6I/5VfGX7rofK5XshiFchTwz0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/dnKajO/btsL3ZGFM6I/5VfGX7rofK5XshiFchTwz0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/dnKajO/btsL3ZGFM6I/5VfGX7rofK5XshiFchTwz0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FdnKajO%2FbtsL3ZGFM6I%2F5VfGX7rofK5XshiFchTwz0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;676&quot; height=&quot;371&quot; data-origin-width=&quot;676&quot; data-origin-height=&quot;371&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;639&quot; data-origin-height=&quot;302&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/m5Hc7/btsL1D6DdOx/cqnKxfNOpDa5jB532GV64K/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/m5Hc7/btsL1D6DdOx/cqnKxfNOpDa5jB532GV64K/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/m5Hc7/btsL1D6DdOx/cqnKxfNOpDa5jB532GV64K/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fm5Hc7%2FbtsL1D6DdOx%2FcqnKxfNOpDa5jB532GV64K%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;639&quot; height=&quot;302&quot; data-origin-width=&quot;639&quot; data-origin-height=&quot;302&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;</description>
      <category> AVR</category>
      <author>18진수</author>
      <guid isPermaLink="true">https://coding-yoon.tistory.com/307</guid>
      <comments>https://coding-yoon.tistory.com/307#entry307comment</comments>
      <pubDate>Thu, 30 Jan 2025 13:19:07 +0900</pubDate>
    </item>
    <item>
      <title>4. 아두이노 우노 ATmega328P LED 출력하기 (DDR, PORT)</title>
      <link>https://coding-yoon.tistory.com/306</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;처음 코딩 공부를 시작할 때, CMD 창에 Hello World!를 가장 먼저 출력해본다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;과연 임베디드 세계에서는 어떨까?&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;임베디드 설계에서 Hello World는 굉장히 어려운 일이다.&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그렇다면 임베디드 공부를 처음 시작할 때, 해보는 것은 뭘까?&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;바로 LED 켜보기이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그래서 우리도 LED를 켜보려고 한다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;334&quot; data-origin-height=&quot;151&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/XuXfF/btsL17MBYaR/qN4mNGb7LOKzMtflNGObK0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/XuXfF/btsL17MBYaR/qN4mNGb7LOKzMtflNGObK0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/XuXfF/btsL17MBYaR/qN4mNGb7LOKzMtflNGObK0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FXuXfF%2FbtsL17MBYaR%2FqN4mNGb7LOKzMtflNGObK0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;334&quot; height=&quot;151&quot; data-origin-width=&quot;334&quot; data-origin-height=&quot;151&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;가장 싸고 흔한 발광 다이오드이다.&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;하나만 기억하자. 전기는 (+) &amp;rarr; (-) 로 흐르는 것만 기억하고 저항이 없으면 LED가 버틸 수 없으므로 저항은 적당한거 하나 ANODE 쪽에 달아주자.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;아래 그림처럼 회로를 구성하였다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;408&quot; data-origin-height=&quot;352&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/duxLRh/btsL2edC1rv/5yCkMfk8BgxqV69MJlrYc0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/duxLRh/btsL2edC1rv/5yCkMfk8BgxqV69MJlrYc0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/duxLRh/btsL2edC1rv/5yCkMfk8BgxqV69MJlrYc0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FduxLRh%2FbtsL2edC1rv%2F5yCkMfk8BgxqV69MJlrYc0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;408&quot; height=&quot;352&quot; data-origin-width=&quot;408&quot; data-origin-height=&quot;352&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;하나 main.c 코드를 복붙한 후, 빌드를 해보자. 빌드 Success가 뜨고 object, hex, elf 파일이 생겼을 것이다. 나중에 하나하나 설명할 것이니 일단은 넘어가자.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;279&quot; data-origin-height=&quot;163&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bn6TGA/btsL3iNeufI/KgI5ijxOmoT4ai78eLoG9k/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bn6TGA/btsL3iNeufI/KgI5ijxOmoT4ai78eLoG9k/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bn6TGA/btsL3iNeufI/KgI5ijxOmoT4ai78eLoG9k/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fbn6TGA%2FbtsL3iNeufI%2FKgI5ijxOmoT4ai78eLoG9k%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;279&quot; height=&quot;163&quot; data-origin-width=&quot;279&quot; data-origin-height=&quot;163&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;pre id=&quot;code_1738082958465&quot; class=&quot;cpp&quot; data-ke-language=&quot;cpp&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;#define F_CPU 16000000L // CPU 클럭 속도
#include &amp;lt;avr/io.h&amp;gt;
#include &amp;lt;util/delay.h&amp;gt;

int main(void) {
	DDRD = 0x04U;			// PD2를 출력으로 설정

	while (1) {
		PORTD = 0x04U;		// LED ON
		_delay_ms(1000);    // 1초 대기
		PORTD = 0x0U;		// LED OFF
		_delay_ms(1000);    // 1초 대기
	}

	return 0;
}&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;AVRISP mkII ISP 프로그래머를 연결해본다. Apply를 눌러보면, Interface Settings에 ISP Clock이 제일 먼저 보일 것이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;ISP는 SPI 라고 간단히 생각하고, 아래 문구를 보게 되면 device의 주파수의 1/4보다 낮은 값으로 설정하라고 한다. Atmega328P 칩은 내부 오실레이터 주파수가 8MHz 이므로 대략 2MHz보다 낮으면 된다. (하지만 아두이노 우노 보드의 경우, 외부 오실레이터 16MHz를 사용하나 Fuse bit를 설정하여 이를 조절할 수 있다. 근데 125kHz도 충분히 빠르니 내비두자.)&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock widthContent&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;933&quot; data-origin-height=&quot;741&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/EOryJ/btsL2fQ6syU/ErF3YeHgS0kZFojXN602F0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/EOryJ/btsL2fQ6syU/ErF3YeHgS0kZFojXN602F0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/EOryJ/btsL2fQ6syU/ErF3YeHgS0kZFojXN602F0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FEOryJ%2FbtsL2fQ6syU%2FErF3YeHgS0kZFojXN602F0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;933&quot; height=&quot;741&quot; data-origin-width=&quot;933&quot; data-origin-height=&quot;741&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Memories 로 가보면 Flash (32KB) 가 보일 것이다. 실제 플레쉬 영역에 우리가 빌드한 Hex 파일을 ISP 방식으로 집어 넣는 것이다. Program을 누르면 Flash 영역을 한번 싹 0xFF로 밀어버린 후, Hex를 집어넣으므로 기존 아두이노 부트로더를 날라갈 것이다. 더 이상 우리가 알던 아두이노 방식으로는 개발을 할 수 없다. ㅋㄷ (ISP로 부트로더 다시 집어넣으면 됨)&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock widthContent&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;933&quot; data-origin-height=&quot;741&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/dD7Dj9/btsL2abzVMk/kvh8FVjNXnJST4svmgV7sk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/dD7Dj9/btsL2abzVMk/kvh8FVjNXnJST4svmgV7sk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/dD7Dj9/btsL2abzVMk/kvh8FVjNXnJST4svmgV7sk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FdD7Dj9%2FbtsL2abzVMk%2Fkvh8FVjNXnJST4svmgV7sk%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;933&quot; height=&quot;741&quot; data-origin-width=&quot;933&quot; data-origin-height=&quot;741&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://youtube.com/shorts/vJ8pUajn1kU?si=OGNoKXAHvJf-BCJp&quot;&gt;https://youtube.com/shorts/vJ8pUajn1kU?si=OGNoKXAHvJf-BCJp&lt;/a&gt;&lt;/p&gt;
&lt;figure data-ke-type=&quot;video&quot; data-ke-style=&quot;alignCenter&quot; data-video-host=&quot;youtube&quot; data-video-url=&quot;https://www.youtube.com/shorts/vJ8pUajn1kU&quot; data-video-thumbnail=&quot;https://scrap.kakaocdn.net/dn/Jtdrl/hyX4oJlUZX/URxblA0FjSW1NzK7EdEFd1/img.jpg?width=720&amp;amp;height=1280&amp;amp;face=0_0_720_1280,https://scrap.kakaocdn.net/dn/kTVWO/hyX4r0nj8y/Q03XVtvaS9bJ9OlkUehS8K/img.jpg?width=720&amp;amp;height=1280&amp;amp;face=0_0_720_1280&quot; data-video-width=&quot;720&quot; data-video-height=&quot;1280&quot; data-video-origin-width=&quot;720&quot; data-video-origin-height=&quot;1280&quot; data-ke-mobilestyle=&quot;widthContent&quot; data-video-title=&quot;Atmega328P led blinking test.&quot; data-original-url=&quot;&quot;&gt;&lt;iframe src=&quot;https://www.youtube.com/embed/vJ8pUajn1kU&quot; width=&quot;720&quot; height=&quot;1280&quot; frameborder=&quot;&quot; allowfullscreen=&quot;true&quot;&gt;&lt;/iframe&gt;
&lt;figcaption style=&quot;display: none;&quot;&gt;&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;_delay_ms는 말 그대로 MCU를 강제로 지연시키는 것이고, 우리가 알아야 하는 키워드가 2가지가 있다.&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;DDR&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;DDR에 대해 알아보자. 이제는 Atmega328P의 데이터시트를 확인해야 한다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;765&quot; data-origin-height=&quot;139&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bvqAfj/btsL2eYX0ox/6eNGzSmgeOF6tq7qglpda0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bvqAfj/btsL2eYX0ox/6eNGzSmgeOF6tq7qglpda0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bvqAfj/btsL2eYX0ox/6eNGzSmgeOF6tq7qglpda0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbvqAfj%2FbtsL2eYX0ox%2F6eNGzSmgeOF6tq7qglpda0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;765&quot; height=&quot;139&quot; data-origin-width=&quot;765&quot; data-origin-height=&quot;139&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;h4 style=&quot;background-color: oklch(0.99 0.004 106.471); color: oklch(0.304 0.04 213.681); text-align: start;&quot; data-ke-size=&quot;size20&quot;&gt;DDR 설정&lt;/h4&gt;
&lt;ul style=&quot;list-style-type: disc; background-color: oklch(0.99 0.004 106.471); color: oklch(0.304 0.04 213.681); text-align: start;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;span&gt;1: 출력 설정&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span&gt;0: 입력 설정&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;pre id=&quot;code_1738084571072&quot; class=&quot;cpp&quot; data-ke-language=&quot;cpp&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;DDRB = 0xFF;  // PORTB의 모든 핀을 출력으로 설정
DDRC = 0x00;  // PORTC의 모든 핀을 입력으로 설정
DDRD |= (1 &amp;lt;&amp;lt; PD7);  // PORTD의 7번 핀만 출력으로 설정
DDRD &amp;amp;= ~(1 &amp;lt;&amp;lt; PD0);  // PORTD의 0번 핀만 입력으로 설정&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;위 처럼 사용된다고 생각하면 된다. 입출력 결정한다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;276&quot; data-origin-height=&quot;144&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/PNpvA/btsL2dyYyt2/uT9KYDCPRPMWcmMwKkC09k/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/PNpvA/btsL2dyYyt2/uT9KYDCPRPMWcmMwKkC09k/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/PNpvA/btsL2dyYyt2/uT9KYDCPRPMWcmMwKkC09k/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FPNpvA%2FbtsL2dyYyt2%2FuT9KYDCPRPMWcmMwKkC09k%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;276&quot; height=&quot;144&quot; data-origin-width=&quot;276&quot; data-origin-height=&quot;144&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;코드를 보면 나는 PD2를&amp;nbsp; 출력 모드로 사용하였다.&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;PORT&lt;/h2&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;800&quot; data-origin-height=&quot;144&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/sCRt9/btsL2SnBQbu/LBk3JUkbYrQOac1gTX00Yk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/sCRt9/btsL2SnBQbu/LBk3JUkbYrQOac1gTX00Yk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/sCRt9/btsL2SnBQbu/LBk3JUkbYrQOac1gTX00Yk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FsCRt9%2FbtsL2SnBQbu%2FLBk3JUkbYrQOac1gTX00Yk%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;800&quot; height=&quot;144&quot; data-origin-width=&quot;800&quot; data-origin-height=&quot;144&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;&lt;b&gt;출력모드일 때&lt;/b&gt;&lt;/span&gt;&lt;span&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;(DDRx = 1)&lt;/span&gt;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc; background-color: oklch(0.99 0.004 106.471); color: oklch(0.304 0.04 213.681); text-align: start;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;span&gt;PORT = 1: HIGH (5V) 출력&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span&gt;PORT = 0: LOW (0V) 출력&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;PD2번에 LED를 연결하여 제어하고 있으므로 당연히 PORTD2 비트만 제어하여 LED를 제어한다. 크게 어렵지 않다. 굳이 설명할 필요도 없달까?&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;하지만 굳이 LED Blinking을 먼저 테스트한 이유는 첫 빌드 목적도 있지만 delay_ms 때문이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;MCU 입장에서 delay는 정말 조심해야하는 동작이다.&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;MCU도 결국 컴퓨터이다. 초소형 컴퓨터.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;MCU는 클럭에 의해 움직이는데, 클럭을 사람의 심장 박동으로 비교한다. 몸을 움직이지 않을 때는 심장 박동수가 내려가고 달리기를 하면 심장 박동수가 급격하게 뛴다.&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Atmega328P라는 MCU 칩은 8MHz 라는 클럭(심장 박동)을 가지고 있다. 1초에 8,000,000 번을 뛰는 것이다. (사람은 기껏해야 1초에 60 ~ 120번 정도 뛸 것이다. ) 그만큼 소형 칩일지언정 컴퓨터는 엄청난 속도로 연산을 하고 있다. 이 엄청난 속도로 인해 0, 1을 엄청나게 빠른 속도로 처리하므로 우리는 동시에 움직이는 것처럼 보인다.&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;자. 과연 이렇게 빠른 속도로 연산하는 MCU를 강제로 delay_ms(1000)를 통해 1초를 쉬게 한다. 사람 입장에서는 짧은 시간이지만 컴퓨터 입장에선 엄청난 시간 소요이다. 불필요한 동작인 셈이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;delay를 했다고 해서 과연 MCU의 클럭 또한 1초 만큼 멈출까? 아니다. 1초 동안 아무것도 하지말고 쉬라는 동작을 컴퓨터에게 명령을 한 것이며, 1초라는 시간을 재기 위해 클럭은 계속해서 발생시킨다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;간단한 동작에는 상관없지만, 센서가 늘어나고 로직이 추가되면 잘못 사용된 delay는 굉장히 버그를 유발시킬 수 있으며 타이밍을 어긋나게 할 수 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;delay를 쓰지말라는 것이 아니다. 적재적소에 사용되면 상관없지만 이번 코드에는 적절치 못하다는 것을 이야기하고 싶은 것이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;다음 글은 Timer 라는 것을 통해 똑같은 기능이지만 새로운 방법을 소개해보려한다. delay와 한 번 비교해보길 바란다.&lt;/p&gt;</description>
      <category> AVR</category>
      <author>18진수</author>
      <guid isPermaLink="true">https://coding-yoon.tistory.com/306</guid>
      <comments>https://coding-yoon.tistory.com/306#entry306comment</comments>
      <pubDate>Wed, 29 Jan 2025 02:42:33 +0900</pubDate>
    </item>
    <item>
      <title>3. 아두이노 우노 관련 자료 소개</title>
      <link>https://coding-yoon.tistory.com/305</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;아두이노 우노를 사용하여 설계를 하려면 그 보드에 대해 자세히 공부할 필요가 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;아래에 소개를 해놓을테니 참고하길 바란다. 이는 나에게도 해당한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;아두이노 우노로 시작하면 좋은 점이 다양한 참고 자료와 확장 보드가 많다는 점이라고 하였다. 그 외에도 추천하는 이유는 더 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;1. UART To Serial (USB) 가 존재한다. UART To Serial 모듈을 굳이 사지 않더라도 컴퓨터에 연결하여 UART 통신 테스트를 해볼 수 있다. 처음 공부하는 사람들에게는 큰 장점이라고 생각한다.&amp;nbsp;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc; background-color: oklch(0.99 0.004 106.471); color: oklch(0.304 0.04 213.681); text-align: start;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;span&gt;&lt;span&gt;&lt;b&gt;U1 (CP2102)&lt;/b&gt;&lt;/span&gt;&lt;span&gt;:&lt;/span&gt;&lt;/span&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;span&gt;USB-시리얼 변환기 IC로, USB 신호를 TTL 레벨의 UART 신호로 변환한다.&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span&gt;아두이노 또는 다른 MCU와 PC 간의 UART 통신을 가능하게 한다.&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;span&gt;&lt;span&gt;&lt;b&gt;U2 (PIC16F688-I/ST)&lt;/b&gt;&lt;/span&gt;&lt;span&gt;:&lt;/span&gt;&lt;/span&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;span&gt;Microchip의 8비트 마이크로컨트롤러.&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span&gt;이 회로에서 주된 제어 작업을 수행하거나 아두이노와 UART 통신을 통해 데이터를 주고받는다.&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;604&quot; data-origin-height=&quot;475&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/kNzNq/btsL3kYx4Uu/97HTN9qV6q1GZtoDOgIVnk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/kNzNq/btsL3kYx4Uu/97HTN9qV6q1GZtoDOgIVnk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/kNzNq/btsL3kYx4Uu/97HTN9qV6q1GZtoDOgIVnk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FkNzNq%2FbtsL3kYx4Uu%2F97HTN9qV6q1GZtoDOgIVnk%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;604&quot; height=&quot;475&quot; data-origin-width=&quot;604&quot; data-origin-height=&quot;475&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;2. 5V, 3.3V&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;센서마다 동작하는 전압이 다르다. 어떤 센서는 5V, 어떤 센서는 3.3V. 근데 아두이노는 이미 5V, 3.3V 출력 전압을 사용할 수 있다. 편하다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;굳이 단점을 뽑자면 UART가 하나이지만, 굳이 단점인가 싶다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;어차피 SPI나 I2C는 하나여도 충분하다.&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;1. 아두이노 우노 핀맵&lt;/h2&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1435&quot; data-origin-height=&quot;1310&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cnANRf/btsL2n9shRO/As5tORK85fVGz59ZoVmFT0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cnANRf/btsL2n9shRO/As5tORK85fVGz59ZoVmFT0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cnANRf/btsL2n9shRO/As5tORK85fVGz59ZoVmFT0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FcnANRf%2FbtsL2n9shRO%2FAs5tORK85fVGz59ZoVmFT0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1435&quot; height=&quot;1310&quot; data-origin-width=&quot;1435&quot; data-origin-height=&quot;1310&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;figure class=&quot;imagegridblock&quot;&gt;
  &lt;div class=&quot;image-container&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cw7sMo/btsMkrQ5iuQ/CpuUEzGuOEeqnzHhKHMuj1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cw7sMo/btsMkrQ5iuQ/CpuUEzGuOEeqnzHhKHMuj1/img.png&quot; data-origin-width=&quot;966&quot; data-origin-height=&quot;814&quot; data-is-animation=&quot;false&quot; width=&quot;747&quot; height=&quot;629&quot; style=&quot;width: 43.6364%; margin-right: 10px;&quot; data-widthpercent=&quot;44.15&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cw7sMo/btsMkrQ5iuQ/CpuUEzGuOEeqnzHhKHMuj1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fcw7sMo%2FbtsMkrQ5iuQ%2FCpuUEzGuOEeqnzHhKHMuj1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;966&quot; height=&quot;814&quot;/&gt;&lt;/span&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/FVZsO/btsMjG9l6Ji/J7sdxuRTzaKfhuzxztaJH1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/FVZsO/btsMjG9l6Ji/J7sdxuRTzaKfhuzxztaJH1/img.png&quot; data-origin-width=&quot;608&quot; data-origin-height=&quot;405&quot; data-is-animation=&quot;false&quot; style=&quot;width: 55.2008%;&quot; data-widthpercent=&quot;55.85&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/FVZsO/btsMjG9l6Ji/J7sdxuRTzaKfhuzxztaJH1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FFVZsO%2FbtsMjG9l6Ji%2FJ7sdxuRTzaKfhuzxztaJH1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;608&quot; height=&quot;405&quot;/&gt;&lt;/span&gt;&lt;/div&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;2. 회로도&amp;nbsp;&lt;/h2&gt;
&lt;p&gt;&lt;figure class=&quot;fileblock&quot; data-ke-align=&quot;alignCenter&quot;&gt;&lt;a href=&quot;https://blog.kakaocdn.net/dn/bmLyRN/btsL1C7lVKH/k3kwaCHMvGuy5wSKaBj20k/schematic%20%281%29.pdf?attach=1&amp;amp;knm=tfile.pdf&quot; class=&quot;&quot;&gt;
    &lt;div class=&quot;image&quot;&gt;&lt;/div&gt;
    &lt;div class=&quot;desc&quot;&gt;&lt;div class=&quot;filename&quot;&gt;&lt;span class=&quot;name&quot;&gt;schematic (1).pdf&lt;/span&gt;&lt;/div&gt;
&lt;div class=&quot;size&quot;&gt;0.02MB&lt;/div&gt;
&lt;/div&gt;
  &lt;/a&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;3. Atmega328P 데이터시트&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://ww1.microchip.com/downloads/en/DeviceDoc/Atmel-7810-Automotive-Microcontrollers-ATmega328P_Datasheet.pdf&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://ww1.microchip.com/downloads/en/DeviceDoc/Atmel-7810-Automotive-Microcontrollers-ATmega328P_Datasheet.pdf&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;484&quot; data-origin-height=&quot;620&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/AW5ce/btsL1GWkN88/PJKRA0yQk31zKO0dFHJHkk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/AW5ce/btsL1GWkN88/PJKRA0yQk31zKO0dFHJHkk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/AW5ce/btsL1GWkN88/PJKRA0yQk31zKO0dFHJHkk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FAW5ce%2FbtsL1GWkN88%2FPJKRA0yQk31zKO0dFHJHkk%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;484&quot; height=&quot;620&quot; data-origin-width=&quot;484&quot; data-origin-height=&quot;620&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;데이터시트에 방대한 내용이 있지만 차근차근 하나씩 보면 될 듯하다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;우선, 가장 먼저 해볼 것은 스위치와 LED이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;데이터시트와 함께 하나씩 봐보면 충분히 이해할 수 있다고 생각한다.&lt;/p&gt;</description>
      <category> AVR</category>
      <author>18진수</author>
      <guid isPermaLink="true">https://coding-yoon.tistory.com/305</guid>
      <comments>https://coding-yoon.tistory.com/305#entry305comment</comments>
      <pubDate>Tue, 28 Jan 2025 17:51:08 +0900</pubDate>
    </item>
    <item>
      <title>2. 아두이노 소개 &amp;amp; Atmel Studio7 프로젝트 생성하기</title>
      <link>https://coding-yoon.tistory.com/304</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;앞서 말했듯이 아두이노로 공부하기 위해서 2가지 재료가 필요하다고 했다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;아두이노 2개, ISP 다운로더&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;아두이노 IDE는 알아서 하길 바란다. 나는 Atmel Studio를 통해 개발을 할려고 한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Atmel Studio를 설치해야겠지?&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://www.microchip.com/en-us/tools-resources/develop/microchip-studio#Downloads&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://www.microchip.com/en-us/tools-resources/develop/microchip-studio#Downloads&lt;/a&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;설치는 그냥 Next 갈기면 된다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock widthContent&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;813&quot; data-origin-height=&quot;511&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bbiEAo/btsL18j9yj2/GNwBJ1pYpAOaCFNZjBzkH0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bbiEAo/btsL18j9yj2/GNwBJ1pYpAOaCFNZjBzkH0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bbiEAo/btsL18j9yj2/GNwBJ1pYpAOaCFNZjBzkH0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbbiEAo%2FbtsL18j9yj2%2FGNwBJ1pYpAOaCFNZjBzkH0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;813&quot; height=&quot;511&quot; data-origin-width=&quot;813&quot; data-origin-height=&quot;511&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;파일 -&amp;gt; Project&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock widthContent&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1179&quot; data-origin-height=&quot;809&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bWh6qf/btsL1FiwTdD/pmo2kxusYbZGAk6mmH9hy0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bWh6qf/btsL1FiwTdD/pmo2kxusYbZGAk6mmH9hy0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bWh6qf/btsL1FiwTdD/pmo2kxusYbZGAk6mmH9hy0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbWh6qf%2FbtsL1FiwTdD%2Fpmo2kxusYbZGAk6mmH9hy0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1179&quot; height=&quot;809&quot; data-origin-width=&quot;1179&quot; data-origin-height=&quot;809&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;프로젝트명을 아무거나 해주십다. GCC C Executable Project 선택해줍니다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock widthContent&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;941&quot; data-origin-height=&quot;656&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bmprau/btsL2kR9BFB/bUqTzTscwJ5luOPkyxDYN0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bmprau/btsL2kR9BFB/bUqTzTscwJ5luOPkyxDYN0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bmprau/btsL2kR9BFB/bUqTzTscwJ5luOPkyxDYN0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fbmprau%2FbtsL2kR9BFB%2FbUqTzTscwJ5luOPkyxDYN0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;941&quot; height=&quot;656&quot; data-origin-width=&quot;941&quot; data-origin-height=&quot;656&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;아두이노 칩은 ATmega328P 이므로 선택해준다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;355&quot; data-origin-height=&quot;484&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bm0zWW/btsL2R2ZVy6/oY05bk4ZkpMXKWvkkOvafk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bm0zWW/btsL2R2ZVy6/oY05bk4ZkpMXKWvkkOvafk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bm0zWW/btsL2R2ZVy6/oY05bk4ZkpMXKWvkkOvafk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fbm0zWW%2FbtsL2R2ZVy6%2FoY05bk4ZkpMXKWvkkOvafk%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;355&quot; height=&quot;484&quot; data-origin-width=&quot;355&quot; data-origin-height=&quot;484&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;옆에 지원하는 툴을 보면 다양하게 보여준다. STK500이 있다. 우리가 싸게 주고산 ISP 방식이 STK500이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이렇게 생성이 끝이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그래도 빌드해보고 헥사 한 번 넣어봐야지.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock widthContent&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1040&quot; data-origin-height=&quot;341&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bkwaB2/btsL3g2B54H/c7QkKpbB6kIH3NzkbTqtW0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bkwaB2/btsL3g2B54H/c7QkKpbB6kIH3NzkbTqtW0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bkwaB2/btsL3g2B54H/c7QkKpbB6kIH3NzkbTqtW0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbkwaB2%2FbtsL3g2B54H%2Fc7QkKpbB6kIH3NzkbTqtW0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1040&quot; height=&quot;341&quot; data-origin-width=&quot;1040&quot; data-origin-height=&quot;341&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;빌드 한 번 깔끔하게 해보자.&amp;nbsp; 당연히 아무것도 없으니 Build는 성공이다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock widthContent&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1636&quot; data-origin-height=&quot;377&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/DN62e/btsL1swVHjZ/38RtC6siukYB3MwAZnK4SK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/DN62e/btsL1swVHjZ/38RtC6siukYB3MwAZnK4SK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/DN62e/btsL1swVHjZ/38RtC6siukYB3MwAZnK4SK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FDN62e%2FbtsL1swVHjZ%2F38RtC6siukYB3MwAZnK4SK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1636&quot; height=&quot;377&quot; data-origin-width=&quot;1636&quot; data-origin-height=&quot;377&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;우측, 솔루션 탐색기를 봐보면 우리가 빌드해서 생성한 헥사 파일 및 설정파일들이 있다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;582&quot; data-origin-height=&quot;475&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cXXyou/btsL3nAFot2/WBOZna8T8buvMMudHUHPGk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cXXyou/btsL3nAFot2/WBOZna8T8buvMMudHUHPGk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cXXyou/btsL3nAFot2/WBOZna8T8buvMMudHUHPGk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FcXXyou%2FbtsL3nAFot2%2FWBOZna8T8buvMMudHUHPGk%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;582&quot; height=&quot;475&quot; data-origin-width=&quot;582&quot; data-origin-height=&quot;475&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;.hex 파일을 ISP 다운로더를 통해 칩에 직접 넣는 것이므로 경로를 알아야 한다. 그 외의 파일들은 지금 당장 중요하지 않으므로 나중에 설명하도록 한다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;499&quot; data-origin-height=&quot;491&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/670XW/btsL3jSy4Wm/9q1blPqZWBPjd8HOBsrjJ0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/670XW/btsL3jSy4Wm/9q1blPqZWBPjd8HOBsrjJ0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/670XW/btsL3jSy4Wm/9q1blPqZWBPjd8HOBsrjJ0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2F670XW%2FbtsL3jSy4Wm%2F9q1blPqZWBPjd8HOBsrjJ0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;499&quot; height=&quot;491&quot; data-origin-width=&quot;499&quot; data-origin-height=&quot;491&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Tools 에서 Device Programming을 누른다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock widthContent&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;933&quot; data-origin-height=&quot;741&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/XyGG4/btsL107qeET/jEYMXhSRPPfRNZs5T4VeU0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/XyGG4/btsL107qeET/jEYMXhSRPPfRNZs5T4VeU0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/XyGG4/btsL107qeET/jEYMXhSRPPfRNZs5T4VeU0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FXyGG4%2FbtsL107qeET%2FjEYMXhSRPPfRNZs5T4VeU0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;933&quot; height=&quot;741&quot; data-origin-width=&quot;933&quot; data-origin-height=&quot;741&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Tool을 보면 우리의 ISP 다운로더를 찾을 수 있다. 선택하고 Apply를 누른다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;528&quot; data-origin-height=&quot;524&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/WPWe7/btsL1j0ILFN/uFiE9KOL2HHQE9Kq3rEGGK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/WPWe7/btsL1j0ILFN/uFiE9KOL2HHQE9Kq3rEGGK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/WPWe7/btsL1j0ILFN/uFiE9KOL2HHQE9Kq3rEGGK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FWPWe7%2FbtsL1j0ILFN%2FuFiE9KOL2HHQE9Kq3rEGGK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;528&quot; height=&quot;524&quot; data-origin-width=&quot;528&quot; data-origin-height=&quot;524&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;아직 아두이노 다운로드는 할게아니라서 제대로 연결만 되는지 확인해본다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;자. 연결됐다면 ATmega328P에 Hex file을 넣을 준비가 되었다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;다음 글에 아두이노에 간단하게 헥사 파일을 넣어보자.&lt;/p&gt;</description>
      <category> AVR</category>
      <author>18진수</author>
      <guid isPermaLink="true">https://coding-yoon.tistory.com/304</guid>
      <comments>https://coding-yoon.tistory.com/304#entry304comment</comments>
      <pubDate>Mon, 27 Jan 2025 13:14:25 +0900</pubDate>
    </item>
    <item>
      <title>1. 임베디드 SW 취업에 관심 있는 취준생을 위하여.</title>
      <link>https://coding-yoon.tistory.com/303</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;임베디드 SW 로 취직을 하고 싶은 사람들을 위해...&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;별로 추천해주고 싶지 않은 업종이지만, 그럼에도 관심있는 사람들을 위하여 기본적으로 어떻게 공부해야하는지 방향성 정도를 제시하는 정도의 교육을 위해 작성해보려 한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;추천해주고 싶지 않은 이유는 업무 강도 및 진입에 비해 연봉이 다른 개발직군에 비해 짠 편이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;네카라쿠배당토 (네이버, 카카오, 라인, 쿠팡, 배달의 민족, 당근, 토스&amp;nbsp; 등등...)&amp;nbsp; 라고 IT 취업 시장이 한창 인기 있을 때 많이 들어보았을 것이다. (지금은 많이 식었다...)&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;과연 저기에 임베디드 분야가 있는가? 없다...&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;내 대학원 시절 선배가 임베디드 업계는 사람이 없어서 대우가 좋다는데... 쓰읍 전자의 말은 맞지만, 후자의 말은 틀렸다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;(그래도 업계에 사람이 적으므로, 나이 많이 먹고도 설계직군으로 우려먹을 수 있다는 장점이 있긴 하다.)&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;솔직히 이 때는 다들 학생 시절인데 무엇을 알겠는가.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;임베디드 업계가 다른 업계에 비해 짠 이유는 나름의 생각을 정리해보았다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;1. 중국&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;중국 제품 및 부품들이 너무 싸기 때문에 국내 제품들이 가격 경쟁력을 잃어가고 있다. 이미 우리는 체감을 하고 있다.&amp;nbsp; 찍어 내기식으로 알리, 테무 같은 플랫폼을 통해 무지하게 싼 가격으로 팔고 있다는 것을 알 수 있다.&amp;nbsp; 그러므로 당연히 기업입장에서는 퀄리티 차이가 엄청 나지 않는다면 국내 부품사를 사용할 이유가 없는 것이다. 한국은 비싼 인건비, 재료비, 유통 등 중국과 경쟁을 할 수가 없다. 특히나 시진핑이 기업에게 전폭적인 지원을 통해 밀고 나가고 있으니... 말 다한 셈이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;2. 제조업&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;임베디드 설계는 제조업과 엮일 수 밖에 없다. 네카라쿠배당토를 생각해보자.&amp;nbsp; IT가 메인인 회사이다. 하지만 임베디드는 애초에 메인이 될 수 없다. 메인은 제조업이다. 제조업 특성 상, IT를 등한시하는 경향이 굉장히 크다. 회사 측면에서 금형, 제조, 메카가 메인이다. 금형이 잘못나오면 몇 억 손실이 나므로 다들 포커스가 그쪽으로 쏠린다. 하지만 이는 장기적으로 시간이 지났을 때, 나아질 수 있는 충분한 여지가 있다. 점점 제품들은 스마트해지므로 소프트 설계자들의 입지가 올라가고 있다. 지금 당장 우리회사만 보더라도 소프트웨어 설계자들의 대우가 나아지고 있다. 하지만 그 반대로 다른 직무 인원들의 반발도 같이 올라간다. 이 부분은 시간이 해결해줄 것이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그렇다면, 임베디드 설계는 정말 별로인가?&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;괜찮은 직무도 꽤 많다.&amp;nbsp;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;가전, 자동차 분야 쪽이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;당장에서도 나는 전장부품(자동차 부품) 설계팀에 속해 있고 현재 설계해야할 제품이 넘치고 넘친다. 일 없어서 걱정할 필요가 없다. 그리고 다른 분야에 비해 설계자가 한참 부족하므로 나이먹고도 설계를 계속 해먹을 수 있다. 이건 정말 큰 장점인 듯하다.&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;임베디드는 진입 장벽이 굉장히 높다. 알아야 할 것들도 많고. 하지만 한 번 알아두면 내가 봤을 땐, 기존의 컴퓨터 체계(0, 1)가 바뀌지 않는다면 평생 써먹을 수 있는 지식들이다. 그리고 AI 가 다른 분야보다 대체하기 어렵다고 생각한다. 당연히 데이터시트를 대신 분석해주는 등 도우미 역할로는 좋지만, 오실로스코프나 멀티미터 등은 AI가 해줄 수 없기 때문이다.&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;고로 알아서 판단하길 바란다. 다른 설계자들의 자문도 구해보라. 난 잘 모르겠다. 만약 내가 말한 단점을 보고 이 분야에 관심이 사라졌다면 바로 나가길 바란다. 아래부터는 임베디드 SW를 공부하고 싶은데 뭘 해야할지 모르는 사람들을 위한 것이다. 나도 임베디드 공부를 하려고 했을 때 뭘 해야할지 몰랐다. 근데 다들 하는 말이 뭐든 만들라고 한다. 그게 쉬운게 아닌데 말들은 잘한다.&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style2&quot; /&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;임베디드 공부를 할려면 뭐든 만들어야지.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그런데 어떻게 만들 수 있을까?&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;진입하기 가장 좋은 보드가 있다. 바로 아두이노 이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;아두이노로 일단 오픈소스 라이브러리가 많고 커뮤니티가 활성화되어 있기 때문에 그냥 해보면 된다. 그냥 아두이노 키트사가지고 해보길 바란다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock widthContent&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;603&quot; data-origin-height=&quot;394&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/L3LT3/btsL1AnuK2J/yhbSpLj8qJqXrKxuVyVWck/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/L3LT3/btsL1AnuK2J/yhbSpLj8qJqXrKxuVyVWck/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/L3LT3/btsL1AnuK2J/yhbSpLj8qJqXrKxuVyVWck/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FL3LT3%2FbtsL1AnuK2J%2FyhbSpLj8qJqXrKxuVyVWck%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;603&quot; height=&quot;394&quot; data-origin-width=&quot;603&quot; data-origin-height=&quot;394&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;자. 그렇다면 임베디드 공부가 시작했는가? 난 아니라고 생각한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;레지스터 하나 설정해보지 않고, 칩 문서도 안 본 자는 임베디드 공부해봤다고 하면 안된다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;새로 보드를 사야하는가? 아니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;아두이노는 Atmega328P라는 칩의 플래시 영역에 부트로더를 얹어 간단하게 만들 수 있도록 설계된 교육용 보드이다. 고로 핀꼽기도 편하고 확장 보드도 많다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;내가 공부하는 방향은 부트로더를 날려버리고 실제 레지스터로 제어해보는 것이다. (GPIO, PWM 등등)&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;자세히 재료부터 말해보겠다. 정품이고 뭐고 필요 없다. 그냥 스펙 동일한 싼 우노 보드를 2개 사라.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock widthContent&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1418&quot; data-origin-height=&quot;706&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bLC5Ha/btsL05VLg0c/7Ma36OM2GUiE8eAoPThvkk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bLC5Ha/btsL05VLg0c/7Ma36OM2GUiE8eAoPThvkk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bLC5Ha/btsL05VLg0c/7Ma36OM2GUiE8eAoPThvkk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbLC5Ha%2FbtsL05VLg0c%2F7Ma36OM2GUiE8eAoPThvkk%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1418&quot; height=&quot;706&quot; data-origin-width=&quot;1418&quot; data-origin-height=&quot;706&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;다운로드용 ISP 이다. 부트로더를 날린 아두이노는 더 이상 기존 방식으로는 다운로드할 수 없고 아래 ISP 다운로더를 통해 헥사를 다운로드해야 한다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock widthContent&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1658&quot; data-origin-height=&quot;668&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bcuSrr/btsL1fqXKNV/IBOyAOv8EuHTIwwmAiPwu1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bcuSrr/btsL1fqXKNV/IBOyAOv8EuHTIwwmAiPwu1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bcuSrr/btsL1fqXKNV/IBOyAOv8EuHTIwwmAiPwu1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbcuSrr%2FbtsL1fqXKNV%2FIBOyAOv8EuHTIwwmAiPwu1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1658&quot; height=&quot;668&quot; data-origin-width=&quot;1658&quot; data-origin-height=&quot;668&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;아두이노는 일반 오픈소스를 통해 한 번 만들어 본다. 온도 센서를 예시로, 구글에 아두이노 온도 센서라고만 쳐도 무수히 많은 라이브러리와 블로그가 있다. 그대로 따라해보라.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;만약, 만들었다면 이제 부트로더를 날린 아두이노 보드를 그대로 따라해보자. 레지스터 하나하나 건드려서. 라이브러리가 이미 있지 않은가. 그걸 그대로&amp;nbsp; AVR 식으로 변경한다고 생각해보자. 당연히 어렵다. 하지만 우리에겐 칩 데이터시트도 있고, ChatGPT도 있다. 제어할 수 있는 센서나 통신이 하나씩 늘어난다면, 어느 순간 자신감이 쌓여있을 것이다. 어셈블리어, 회로도, 쓰레드, RTOS 등 더 딥한 세계를 찾게 될 것이다.&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;누군가를 알려줄만큼 설계를 잘하는 설계자는 아니다. 다만 적어도 프로젝트를 받았을 때 제품을 끝까지 수행할 수 있는 설계자라고 단언코 말할 수 있다. 이를 가능하게 했던건 질문과 공부였던 것 같다. 질문의 종류는 두 개 이다. 선배들한테 하는 질문, 나에게 하는 질문. 나에게 하는 질문은 무엇인가? 설계를 찍어내다 보면 내 스스로가 뭘 하고 있는지 모를 때가 많다. 특히, 자동화 툴이 많아짐에 따라 내가 뭘 모르는지 모를 때가 많다. 그 때 질문하는 것이다. 스스로에게 질문했을 때, 무언가 막히고 안개가 낀 것 같다면 그 부분을 공부를 하는 것이다. 그렇게 하다보면 일인분 하는 사람이 될 수 있지 않을까?&lt;/p&gt;</description>
      <category> AVR</category>
      <author>18진수</author>
      <guid isPermaLink="true">https://coding-yoon.tistory.com/303</guid>
      <comments>https://coding-yoon.tistory.com/303#entry303comment</comments>
      <pubDate>Sun, 26 Jan 2025 19:24:12 +0900</pubDate>
    </item>
    <item>
      <title>18. STM32 I2C 통신 - AM1008W-K-P 동작 구현</title>
      <link>https://coding-yoon.tistory.com/302</link>
      <description>&lt;p&gt;&lt;figure class=&quot;imageblock widthContent&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;600&quot; data-origin-height=&quot;600&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/rmqcW/btsLDcHYyOl/q9sWjIk6WkSZPMPfS33ahK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/rmqcW/btsLDcHYyOl/q9sWjIk6WkSZPMPfS33ahK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/rmqcW/btsLDcHYyOl/q9sWjIk6WkSZPMPfS33ahK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FrmqcW%2FbtsLDcHYyOl%2Fq9sWjIk6WkSZPMPfS33ahK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;600&quot; height=&quot;600&quot; data-origin-width=&quot;600&quot; data-origin-height=&quot;600&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이 전 글에서 AM1008W-K-P 데이터시트와 I2C HAL 함수들을 소개했다. 이번 글은 위 정보들을 이용하여 아두이노와 똑같이 재현하도록 하겠다. 우선 프로젝트를 생성한다. 프로젝트 생성에 대한 내용은 생략하겠다.&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;1. I2C 설정&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;I2C&amp;nbsp;동작을&amp;nbsp;구현하기&amp;nbsp;위해&amp;nbsp;레지스터를&amp;nbsp;설정해주어야&amp;nbsp;하는데,&amp;nbsp;CUBE&amp;nbsp;IDE에서는&amp;nbsp;간단하게&amp;nbsp;GUI를&amp;nbsp;통해&amp;nbsp;생성할&amp;nbsp;수&amp;nbsp;있다. &lt;br /&gt;&lt;br /&gt;I2C1와 USART1을 각각 활성화시킨다. (생략, 이 전글들 참고 바람)&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock widthContent&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;966&quot; data-origin-height=&quot;772&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/BFgHh/btsLDGBQW2W/CSOYleRxxBKiy5RomBmqbK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/BFgHh/btsLDGBQW2W/CSOYleRxxBKiy5RomBmqbK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/BFgHh/btsLDGBQW2W/CSOYleRxxBKiy5RomBmqbK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FBFgHh%2FbtsLDGBQW2W%2FCSOYleRxxBKiy5RomBmqbK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;966&quot; height=&quot;772&quot; data-origin-width=&quot;966&quot; data-origin-height=&quot;772&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;USART1는 기본 115200을 사용할 것이므로 별도의 설정을 할 필요는 없지만 I2C1은 속도를 설정해주어야 한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;AM1008W-K-P&amp;nbsp;센서는&amp;nbsp;30kbps&amp;nbsp;이하에서&amp;nbsp;동작하는&amp;nbsp;것이&amp;nbsp;스펙이다. &lt;br /&gt;&lt;br /&gt;I2C1은&amp;nbsp;default&amp;nbsp;설정으로&amp;nbsp;standard&amp;nbsp;모드로&amp;nbsp;100kbps이다.&amp;nbsp; &lt;br /&gt;&lt;br /&gt;100kbps는&amp;nbsp;오버&amp;nbsp;스피드이므로&amp;nbsp;통신&amp;nbsp;속도를&amp;nbsp;스펙대로&amp;nbsp;낮출&amp;nbsp;필요가&amp;nbsp;있다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;433&quot; data-origin-height=&quot;258&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bw9awf/btsLEdlDWiH/jAmDbPuyv5zQhjlFcrv1F0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bw9awf/btsLEdlDWiH/jAmDbPuyv5zQhjlFcrv1F0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bw9awf/btsLEdlDWiH/jAmDbPuyv5zQhjlFcrv1F0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fbw9awf%2FbtsLEdlDWiH%2FjAmDbPuyv5zQhjlFcrv1F0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;433&quot; height=&quot;258&quot; data-origin-width=&quot;433&quot; data-origin-height=&quot;258&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;I2C&amp;nbsp;Speed를&amp;nbsp;30,000Hz로&amp;nbsp;변경한다. &lt;br /&gt;&lt;br /&gt;STM32F103은&amp;nbsp;마스터로&amp;nbsp;동작하기&amp;nbsp;때문에&amp;nbsp;Slave&amp;nbsp;Features는&amp;nbsp;건드릴&amp;nbsp;필요가&amp;nbsp;없다. &lt;br /&gt;&lt;br /&gt;GPIO&amp;nbsp;설정으로&amp;nbsp;들어가&amp;nbsp;I2C&amp;nbsp;Maximum&amp;nbsp;output&amp;nbsp;스피드가&amp;nbsp;기본&amp;nbsp;High로&amp;nbsp;되어&amp;nbsp;있는데&amp;nbsp;Medium이나&amp;nbsp;Low&amp;nbsp;로&amp;nbsp;떨춰주어야&amp;nbsp;한다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock widthContent&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;908&quot; data-origin-height=&quot;541&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/UVZ8V/btsLDc2hbS0/9oUfZJfKarvWvb0bMB3NY0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/UVZ8V/btsLDc2hbS0/9oUfZJfKarvWvb0bMB3NY0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/UVZ8V/btsLDc2hbS0/9oUfZJfKarvWvb0bMB3NY0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FUVZ8V%2FbtsLDc2hbS0%2F9oUfZJfKarvWvb0bMB3NY0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;908&quot; height=&quot;541&quot; data-origin-width=&quot;908&quot; data-origin-height=&quot;541&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;해당&amp;nbsp;핀맵을&amp;nbsp;통해&amp;nbsp;내장&amp;nbsp;GPIO&amp;nbsp;Pull-up이&amp;nbsp;없기에&amp;nbsp;외장&amp;nbsp;Pull-up&amp;nbsp;저항을&amp;nbsp;써야하는&amp;nbsp;것을&amp;nbsp;알&amp;nbsp;수&amp;nbsp;있다. &lt;br /&gt;&lt;br /&gt;이렇게&amp;nbsp;되면&amp;nbsp;설정은&amp;nbsp;완료되었고&amp;nbsp;코드를&amp;nbsp;생성한다. &lt;br /&gt;&lt;br /&gt;여기서&amp;nbsp;UART를&amp;nbsp;활성화한&amp;nbsp;이유는&amp;nbsp;UART&amp;nbsp;to&amp;nbsp;Serial&amp;nbsp;을&amp;nbsp;통해&amp;nbsp;컴퓨터에서&amp;nbsp;값을&amp;nbsp;확인하기&amp;nbsp;위해서이다.&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;2. AM1008W-P-K 라이브러리&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;우리는 아두이노 글에서 AM1008W-K-P를 테스트하였다.&lt;br /&gt;&lt;br /&gt;운이&amp;nbsp;좋게도&amp;nbsp;github에&amp;nbsp;코드(아두이노&amp;nbsp;+&amp;nbsp;C++)들이&amp;nbsp;올라와&amp;nbsp;있었고&amp;nbsp;우리는&amp;nbsp;이를&amp;nbsp;STM32&amp;nbsp;+&amp;nbsp;C언어로&amp;nbsp;변경해주면&amp;nbsp;된다. &lt;br /&gt;&lt;br /&gt;여기서&amp;nbsp;팁&amp;nbsp;하나.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://github.com/neosarchizo/am1008w_k_i2c/tree/main/src&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://github.com/neosarchizo/am1008w_k_i2c/tree/main/src&lt;/a&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1736056631993&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-ke-align=&quot;alignCenter&quot; data-og-type=&quot;object&quot; data-og-title=&quot;am1008w_k_i2c/src at main &amp;middot; neosarchizo/am1008w_k_i2c&quot; data-og-description=&quot;CUBIC AM1008W-K I2C library. Contribute to neosarchizo/am1008w_k_i2c development by creating an account on GitHub.&quot; data-og-host=&quot;github.com&quot; data-og-source-url=&quot;https://github.com/neosarchizo/am1008w_k_i2c/tree/main/src&quot; data-og-url=&quot;https://github.com/neosarchizo/am1008w_k_i2c/tree/main/src&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/Redel/hyXWCfAYAQ/sTs0kmNiHYho4L1RX41xIk/img.png?width=1200&amp;amp;height=600&amp;amp;face=0_0_1200_600,https://scrap.kakaocdn.net/dn/iwZyE/hyXWqlU8PI/F0SUmPQpT16BX1sKtNFcNK/img.png?width=1200&amp;amp;height=600&amp;amp;face=0_0_1200_600&quot;&gt;&lt;a href=&quot;https://github.com/neosarchizo/am1008w_k_i2c/tree/main/src&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://github.com/neosarchizo/am1008w_k_i2c/tree/main/src&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/Redel/hyXWCfAYAQ/sTs0kmNiHYho4L1RX41xIk/img.png?width=1200&amp;amp;height=600&amp;amp;face=0_0_1200_600,https://scrap.kakaocdn.net/dn/iwZyE/hyXWqlU8PI/F0SUmPQpT16BX1sKtNFcNK/img.png?width=1200&amp;amp;height=600&amp;amp;face=0_0_1200_600');&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot; data-ke-size=&quot;size16&quot;&gt;am1008w_k_i2c/src at main &amp;middot; neosarchizo/am1008w_k_i2c&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;CUBIC AM1008W-K I2C library. Contribute to neosarchizo/am1008w_k_i2c development by creating an account on GitHub.&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;github.com&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock widthContent&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;966&quot; data-origin-height=&quot;112&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/FqU1W/btsLC5B2dO1/kC8hLIqIGwmjYDvtyohOa0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/FqU1W/btsLC5B2dO1/kC8hLIqIGwmjYDvtyohOa0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/FqU1W/btsLC5B2dO1/kC8hLIqIGwmjYDvtyohOa0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FFqU1W%2FbtsLC5B2dO1%2FkC8hLIqIGwmjYDvtyohOa0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;966&quot; height=&quot;112&quot; data-origin-width=&quot;966&quot; data-origin-height=&quot;112&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이제&amp;nbsp;개발자들도&amp;nbsp;조금&amp;nbsp;개발하는&amp;nbsp;스타일을&amp;nbsp;조금&amp;nbsp;스마트하게&amp;nbsp;가져갈&amp;nbsp;필요가&amp;nbsp;있다. &lt;br /&gt;&lt;br /&gt;그것은&amp;nbsp;바로&amp;nbsp;chatgpt&amp;nbsp;이용하는&amp;nbsp;방법이다. &lt;br /&gt;&lt;br /&gt;우리는&amp;nbsp;C++로&amp;nbsp;설계된&amp;nbsp;라이브러리를&amp;nbsp;C언어로&amp;nbsp;변경해야&amp;nbsp;하는데&amp;nbsp;GPT에게&amp;nbsp;던지면&amp;nbsp;간단히&amp;nbsp;변경할&amp;nbsp;수&amp;nbsp;있다.&amp;nbsp;(나는&amp;nbsp;GPT4를&amp;nbsp;사용하는데&amp;nbsp;3.5는&amp;nbsp;성능이&amp;nbsp;어느정도&amp;nbsp;인지는&amp;nbsp;잘모르겠다.)&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;966&quot; data-origin-height=&quot;707&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/diFYJe/btsLDdUt20O/8YneKJhPBy5I7EkGvUcyzK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/diFYJe/btsLDdUt20O/8YneKJhPBy5I7EkGvUcyzK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/diFYJe/btsLDdUt20O/8YneKJhPBy5I7EkGvUcyzK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FdiFYJe%2FbtsLDdUt20O%2F8YneKJhPBy5I7EkGvUcyzK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;966&quot; height=&quot;707&quot; data-origin-width=&quot;966&quot; data-origin-height=&quot;707&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;방법은&amp;nbsp;간단하다.&amp;nbsp;코드를&amp;nbsp;그대로&amp;nbsp;던져서&amp;nbsp;변경해달라고&amp;nbsp;하면&amp;nbsp;된다.&amp;nbsp;사소한&amp;nbsp;내용들은&amp;nbsp;debug하면&amp;nbsp;된다. &lt;br /&gt;&lt;br /&gt;gpt가&amp;nbsp;c언어로&amp;nbsp;변경한&amp;nbsp;소스코드들이다.&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;3. am1008w_k_i2c.h&lt;/h3&gt;
&lt;pre id=&quot;code_1736056781764&quot; class=&quot;cpp&quot; data-ke-language=&quot;cpp&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;/*
 * am1008w_k_i2c.h
 *
 *  Created on: Jul 17, 2024
 *      Author: Yoon
 */

#ifndef SRC_AM1008W_K_I2C_H_
#define SRC_AM1008W_K_I2C_H_

#include &amp;lt;stdint.h&amp;gt;
#include &quot;main.h&quot;

#define AM1008W_K_I2C_ADDRESS 0x28

#define AM1008W_K_I2C_FRAME_STX 0x16
#define AM1008W_K_I2C_LEN_READ_DATA_COMMAND 25

#define AM1008W_K_I2C_PSO_CLOSE 0x00
#define AM1008W_K_I2C_PSO_TIMING_MEASURING_MODE 0x05
#define AM1008W_K_I2C_PSO_DYNAMIC_MEASURING_MODE 0x06
#define AM1008W_K_I2C_PSO_CONTINOUS_MEASURING_MODE 0x0C
#define AM1008W_K_I2C_PSO_SINGLE_MEASURING_MODE 0x0D

#define AM1008W_K_I2C_CTRL_CLOSE_MEASUREMENT 0x01
#define AM1008W_K_I2C_CTRL_OPEN_MEASUREMENT 0x02
#define AM1008W_K_I2C_CTRL_CO2_CALIBRATION 0x03
#define AM1008W_K_I2C_CTRL_SET_UP_TIMING_MEASUREMENT 0x05
#define AM1008W_K_I2C_CTRL_SET_UP_DYNAMIC_MEASUREMENT 0x06
#define AM1008W_K_I2C_CTRL_SET_UP_PM_CALIBRATION_COEFFICIENT 0x07
#define AM1008W_K_I2C_CTRL_SET_UP_CONTINUOUSLY_MEASUREMENT 0x0C
#define AM1008W_K_I2C_CTRL_SET_UP_SINGLE_MEASUREMENT 0x0D

typedef union
{
    uint8_t value;
    struct
    {
        uint8_t fan_at_high_revolving_speed:1;
        uint8_t fan_at_low_revolving_speed:1;
        uint8_t working_temperature_is_high:1;
        uint8_t working_temperature_is_low:1;
    } bits;
} am1008w_k_i2c_status;

#ifdef __cplusplus
extern &quot;C&quot; {
#endif

void am1008w_k_i2c_begin(I2C_HandleTypeDef *hi2c);
uint8_t am1008w_k_i2c_pm_sensor_mode_close();
uint8_t am1008w_k_i2c_pm_sensor_mode_open();
uint8_t am1008w_k_i2c_pm_sensor_mode_single_measurement(uint16_t range);
uint8_t am1008w_k_i2c_pm_sensor_mode_continuously_measurement();
uint8_t am1008w_k_i2c_pm_sensor_mode_timing_measurement(uint16_t range);
uint8_t am1008w_k_i2c_pm_sensor_mode_dynamic_measurement();
uint8_t am1008w_k_i2c_set_pm_coefficient(uint8_t range);
uint8_t am1008w_k_i2c_calibrate_co2(uint16_t range);
uint8_t am1008w_k_i2c_read_data_command();
uint8_t am1008w_k_i2c_get_pm_operation_mode();
uint16_t am1008w_k_i2c_get_co2();
uint16_t am1008w_k_i2c_get_voc();
int am1008w_k_i2c_get_humidity();
int am1008w_k_i2c_get_temperature();
uint16_t am1008w_k_i2c_get_pm1p0();
uint16_t am1008w_k_i2c_get_pm2p5();
uint16_t am1008w_k_i2c_get_pm10();
uint16_t am1008w_k_i2c_get_voc_now_r_ref_r();
uint16_t am1008w_k_i2c_get_voc_ref_r();
uint16_t am1008w_k_i2c_get_voc_now_r();
am1008w_k_i2c_status am1008w_k_i2c_get_pm_sensor_status_alarm();

#ifdef __cplusplus
}
#endif

#endif /* SRC_AM1008W_K_I2C_H_ */&lt;/code&gt;&lt;/pre&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;4. am1008w_k_i2c.c&lt;/h3&gt;
&lt;pre id=&quot;code_1736056830172&quot; class=&quot;cpp&quot; data-ke-language=&quot;cpp&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;/*
 * am1008w_k_i2c.c
 *
 *  Created on: Jul 17, 2024
 *      Author: Yoon
 */
#include &quot;am1008w_k_i2c.h&quot;

static I2C_HandleTypeDef *mhi2c;
static uint8_t _buffer[32];
static uint8_t _pm_operation_mode;
static uint16_t _co2;
static uint16_t _voc;
static int _humidity;
static int _temperature;
static uint16_t _pm1p0;
static uint16_t _pm2p5;
static uint16_t _pm10;
static uint16_t _voc_now_r_ref_r;
static uint16_t _voc_ref_r;
static uint16_t _voc_now_r;
static am1008w_k_i2c_status _pm_sensor_status_alarm;

void am1008w_k_i2c_begin(I2C_HandleTypeDef *hi2c) {
    mhi2c = hi2c;
}

uint8_t am1008w_k_i2c_send_command_data(uint8_t ctrl, uint16_t data) {
    uint8_t tx_data[7] = {0};
    tx_data[0] = AM1008W_K_I2C_FRAME_STX;
    tx_data[1] = 7; // FRAME LENGTH
    tx_data[2] = ctrl; // Control Command of the PM Sensor
    tx_data[3] = (data &amp;gt;&amp;gt; 8) &amp;amp; 0xff; // high byte of data
    tx_data[4] = data &amp;amp; 0xff; // low byte of data
    tx_data[5] = 0;

    uint8_t cs = tx_data[0];
    for (uint8_t i = 1; i &amp;lt; 6; i++) {
        cs ^= tx_data[i];
    }
    tx_data[6] = cs;

    HAL_I2C_Master_Transmit(mhi2c, AM1008W_K_I2C_ADDRESS &amp;lt;&amp;lt; 1, tx_data, 7, HAL_MAX_DELAY);

    return 0;
}

uint8_t am1008w_k_i2c_pm_sensor_mode_close() {
    return am1008w_k_i2c_send_command_data(AM1008W_K_I2C_CTRL_CLOSE_MEASUREMENT, 0);
}

uint8_t am1008w_k_i2c_pm_sensor_mode_open() {
    return am1008w_k_i2c_send_command_data(AM1008W_K_I2C_CTRL_OPEN_MEASUREMENT, 0);
}

uint8_t am1008w_k_i2c_pm_sensor_mode_single_measurement(uint16_t range) {
    return am1008w_k_i2c_send_command_data(AM1008W_K_I2C_CTRL_SET_UP_SINGLE_MEASUREMENT, range);
}

uint8_t am1008w_k_i2c_pm_sensor_mode_continuously_measurement() {
    return am1008w_k_i2c_send_command_data(AM1008W_K_I2C_CTRL_SET_UP_CONTINUOUSLY_MEASUREMENT, 0);
}

uint8_t am1008w_k_i2c_pm_sensor_mode_timing_measurement(uint16_t range) {
    return am1008w_k_i2c_send_command_data(AM1008W_K_I2C_CTRL_SET_UP_TIMING_MEASUREMENT, range);
}

uint8_t am1008w_k_i2c_pm_sensor_mode_dynamic_measurement() {
    return am1008w_k_i2c_send_command_data(AM1008W_K_I2C_CTRL_SET_UP_DYNAMIC_MEASUREMENT, 0);
}

uint8_t am1008w_k_i2c_set_pm_coefficient(uint8_t range) {
    return am1008w_k_i2c_send_command_data(AM1008W_K_I2C_CTRL_SET_UP_PM_CALIBRATION_COEFFICIENT, range);
}

uint8_t am1008w_k_i2c_calibrate_co2(uint16_t range) {
    return am1008w_k_i2c_send_command_data(AM1008W_K_I2C_CTRL_CO2_CALIBRATION, range);
}

uint8_t am1008w_k_i2c_read_data_command() {

    HAL_I2C_Master_Receive(mhi2c, (AM1008W_K_I2C_ADDRESS &amp;lt;&amp;lt; 1) | 1, _buffer, 25, HAL_MAX_DELAY);

    uint8_t idx = 0;

    if (_buffer[0] != AM1008W_K_I2C_FRAME_STX) {
        return 2; // Frame header different
    }

    if (_buffer[1] != AM1008W_K_I2C_LEN_READ_DATA_COMMAND) {
        return 3; // Frame length different
    }

    uint8_t check_code = _buffer[0];
    for (uint8_t i = 1; i &amp;lt; AM1008W_K_I2C_LEN_READ_DATA_COMMAND - 1; i++) {
        check_code ^= _buffer[i];
    }

    if (_buffer[AM1008W_K_I2C_LEN_READ_DATA_COMMAND - 1] != check_code) {
        return 4; // Checksum wrong
    }

    _pm_operation_mode = _buffer[2];
    _co2 = (_buffer[3] &amp;lt;&amp;lt; 8) + _buffer[4];
    _voc = (_buffer[5] &amp;lt;&amp;lt; 8) + _buffer[6];
    _humidity = ((_buffer[7] &amp;lt;&amp;lt; 8) + _buffer[8]);
    _temperature = ((_buffer[9] &amp;lt;&amp;lt; 8) + _buffer[10] - 500);
    _pm1p0 = (_buffer[11] &amp;lt;&amp;lt; 8) + _buffer[12];
    _pm2p5 = (_buffer[13] &amp;lt;&amp;lt; 8) + _buffer[14];
    _pm10 = (_buffer[15] &amp;lt;&amp;lt; 8) + _buffer[16];
    _voc_now_r_ref_r = (_buffer[17] &amp;lt;&amp;lt; 8) + _buffer[18];
    _voc_ref_r = (_buffer[19] &amp;lt;&amp;lt; 8) + _buffer[20];
    _voc_now_r = (_buffer[21] &amp;lt;&amp;lt; 8) + _buffer[22];
    _pm_sensor_status_alarm.value = _buffer[23];

    return 0;
}

uint8_t am1008w_k_i2c_get_pm_operation_mode() {
    return _pm_operation_mode;
}

uint16_t am1008w_k_i2c_get_co2() {
    return _co2;
}

uint16_t am1008w_k_i2c_get_voc() {
    return _voc;
}

int am1008w_k_i2c_get_humidity() {
    return _humidity;
}

int am1008w_k_i2c_get_temperature() {
    return _temperature;
}

uint16_t am1008w_k_i2c_get_pm1p0() {
    return _pm1p0;
}

uint16_t am1008w_k_i2c_get_pm2p5() {
    return _pm2p5;
}

uint16_t am1008w_k_i2c_get_pm10() {
    return _pm10;
}

uint16_t am1008w_k_i2c_get_voc_now_r_ref_r() {
    return _voc_now_r_ref_r;
}

uint16_t am1008w_k_i2c_get_voc_ref_r() {
    return _voc_ref_r;
}

uint16_t am1008w_k_i2c_get_voc_now_r() {
    return _voc_now_r;
}

am1008w_k_i2c_status am1008w_k_i2c_get_pm_sensor_status_alarm() {
    return _pm_sensor_status_alarm;
}&lt;/code&gt;&lt;/pre&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;5. main.c&lt;/h3&gt;
&lt;pre id=&quot;code_1736056863699&quot; class=&quot;cpp&quot; data-ke-language=&quot;cpp&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;#include &quot;main.h&quot;
#include am1008w_k_i2c.h

/* Private variables ---------------------------------------------------------*/
I2C_HandleTypeDef hi2c1;

UART_HandleTypeDef huart1;

/* USER CODE BEGIN PV */

/* USER CODE END PV */

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

/* USER CODE END PFP */

/* Private user code ---------------------------------------------------------*/
/* USER CODE BEGIN 0 */

...

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 */

  /* 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_I2C1_Init();
  MX_USART1_UART_Init();
  /* USER CODE BEGIN 2 */
  am1008w_k_i2c_begin(&amp;amp;hi2c1);

  /* USER CODE END 2 */

  /* Infinite loop */
  /* USER CODE BEGIN WHILE */
  char buffer[100];

  while (1)
  {

	  am1008w_k_i2c_read_data_command();

	  int humidity = am1008w_k_i2c_get_humidity();
	  int temperature = am1008w_k_i2c_get_temperature();

	  uint16_t voc = am1008w_k_i2c_get_voc();
	  uint16_t co2 = am1008w_k_i2c_get_co2();
	  uint16_t pm1p0 = am1008w_k_i2c_get_pm1p0();
	  uint16_t pm2p5 = am1008w_k_i2c_get_pm2p5();
	  uint16_t pm10  = am1008w_k_i2c_get_pm10();

	  sprintf(buffer, &quot;Humidity: %d.%02d %%, Temperature: %d.%02d C\r\n&quot;,
			  humidity / 10, humidity % 10, temperature / 10, temperature % 10);

	  HAL_UART_Transmit(&amp;amp;huart1, (uint8_t*)buffer, strlen(buffer), 1000);

	  sprintf(buffer, &quot;CO2: %d ppm, VOC: %d ppb, PM1.0: %d, PM2.5: %d, PM10: %d\r\n&quot;,
	                  co2, voc, pm1p0, pm2p5, pm10);

	  HAL_UART_Transmit(&amp;amp;huart1, (uint8_t*)buffer, strlen(buffer), 1000);
	  HAL_Delay(1000);


    /* USER CODE END WHILE */

    /* USER CODE BEGIN 3 */

  }
  /* USER CODE END 3 */
}&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;아예&amp;nbsp;GPT가&amp;nbsp;생성해준&amp;nbsp;코드를&amp;nbsp;그대로&amp;nbsp;갖다쓴건&amp;nbsp;아니고,&amp;nbsp;내가&amp;nbsp;어느&amp;nbsp;정도&amp;nbsp;디버깅을&amp;nbsp;한&amp;nbsp;코드들이다.&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;6. 회로 구성&lt;/h3&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock widthContent&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;966&quot; data-origin-height=&quot;434&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bUm5EC/btsLDJL53Cd/19n1F4rnYej5NAMzWDkx4K/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bUm5EC/btsLDJL53Cd/19n1F4rnYej5NAMzWDkx4K/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bUm5EC/btsLDJL53Cd/19n1F4rnYej5NAMzWDkx4K/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbUm5EC%2FbtsLDJL53Cd%2F19n1F4rnYej5NAMzWDkx4K%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;966&quot; height=&quot;434&quot; data-origin-width=&quot;966&quot; data-origin-height=&quot;434&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이&amp;nbsp;회로와&amp;nbsp;똑같이&amp;nbsp;구성을&amp;nbsp;해주었다.&amp;nbsp;다만&amp;nbsp;10K옴을&amp;nbsp;4.7K옴으로&amp;nbsp;대체하였다.&amp;nbsp;(외부&amp;nbsp;풀업&amp;nbsp;저항을&amp;nbsp;사용해야&amp;nbsp;함.)&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;7. 동작 확인&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;정상적으로&amp;nbsp;동작하는&amp;nbsp;것을&amp;nbsp;확인하였으며&amp;nbsp;모니터를&amp;nbsp;통해&amp;nbsp;데이터가&amp;nbsp;제대로&amp;nbsp;출력되는&amp;nbsp;것을&amp;nbsp;확인한다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock widthContent&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;938&quot; data-origin-height=&quot;791&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bjBtDQ/btsLErKWi35/Uq5oE5Z9APHb26wWdt37R0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bjBtDQ/btsLErKWi35/Uq5oE5Z9APHb26wWdt37R0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bjBtDQ/btsLErKWi35/Uq5oE5Z9APHb26wWdt37R0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbjBtDQ%2FbtsLErKWi35%2FUq5oE5Z9APHb26wWdt37R0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;938&quot; height=&quot;791&quot; data-origin-width=&quot;938&quot; data-origin-height=&quot;791&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://youtube.com/shorts/TRYy-_zhIGg?si=BBddmJtvnHsqUXOM&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://youtube.com/shorts/TRYy-_zhIGg?si=BBddmJtvnHsqUXOM&lt;/a&gt;&lt;/p&gt;
&lt;figure data-ke-type=&quot;video&quot; data-ke-style=&quot;alignCenter&quot; data-video-host=&quot;youtube&quot; data-video-url=&quot;https://www.youtube.com/shorts/TRYy-_zhIGg&quot; data-video-thumbnail=&quot;https://scrap.kakaocdn.net/dn/bkyhRg/hyXWw0KTeJ/TnrlMsv0SkKkPRWR0GsTX1/img.jpg?width=720&amp;amp;height=720&amp;amp;face=0_0_720_720,https://scrap.kakaocdn.net/dn/bEwHUA/hyXWAIQ35k/UbAlGrcvKKRZLldn6sdWEk/img.jpg?width=720&amp;amp;height=720&amp;amp;face=0_0_720_720&quot; data-video-width=&quot;720&quot; data-video-height=&quot;720&quot; data-video-origin-width=&quot;720&quot; data-video-origin-height=&quot;720&quot; data-ke-mobilestyle=&quot;widthContent&quot; data-video-title=&quot;STM32 AM1008W-P-K 테스트 영상&quot; data-original-url=&quot;&quot;&gt;&lt;iframe src=&quot;https://www.youtube.com/embed/TRYy-_zhIGg&quot; width=&quot;720&quot; height=&quot;720&quot; frameborder=&quot;&quot; allowfullscreen=&quot;true&quot;&gt;&lt;/iframe&gt;
&lt;figcaption style=&quot;display: none;&quot;&gt;&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;다음&amp;nbsp;글로는&amp;nbsp;FTDI&amp;nbsp;를&amp;nbsp;블루투스로&amp;nbsp;대체하고,&amp;nbsp;현재&amp;nbsp;String으로&amp;nbsp;데이터를&amp;nbsp;표출하는데&amp;nbsp;패킷을&amp;nbsp;절약할&amp;nbsp;수&amp;nbsp;있게끔&amp;nbsp;코드를&amp;nbsp;변경할&amp;nbsp;예정이다. &lt;br /&gt;&lt;br /&gt;또한&amp;nbsp;블루투스는&amp;nbsp;무선&amp;nbsp;통신이니&amp;nbsp;그&amp;nbsp;패킷에&amp;nbsp;가능하다면&amp;nbsp;Checksum&amp;nbsp;로직을&amp;nbsp;추가하여&amp;nbsp;데이터의&amp;nbsp;신뢰성을&amp;nbsp;높여볼&amp;nbsp;것이다. &lt;br /&gt;&lt;br /&gt;내가&amp;nbsp;생성한&amp;nbsp;라이브러리는&amp;nbsp;첨부파일로&amp;nbsp;추가해놓으니&amp;nbsp;참고하면&amp;nbsp;좋을&amp;nbsp;것&amp;nbsp;같다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;fileblock&quot; data-ke-align=&quot;alignCenter&quot;&gt;&lt;a href=&quot;https://blog.kakaocdn.net/dn/dHdG0I/btsLE0zltom/4bYjkogvDzxnpCYCRoO4UK/am1008w_k_i2c.zip?attach=1&amp;amp;knm=tfile.zip&quot; class=&quot;&quot;&gt;
    &lt;div class=&quot;image&quot;&gt;&lt;/div&gt;
    &lt;div class=&quot;desc&quot;&gt;&lt;div class=&quot;filename&quot;&gt;&lt;span class=&quot;name&quot;&gt;am1008w_k_i2c.zip&lt;/span&gt;&lt;/div&gt;
&lt;div class=&quot;size&quot;&gt;0.00MB&lt;/div&gt;
&lt;/div&gt;
  &lt;/a&gt;&lt;/figure&gt;
&lt;/p&gt;</description>
      <category>  STM32</category>
      <category>am1008w-k-p</category>
      <category>STM32</category>
      <category>구현</category>
      <category>라이브러리</category>
      <category>코드</category>
      <author>18진수</author>
      <guid isPermaLink="true">https://coding-yoon.tistory.com/302</guid>
      <comments>https://coding-yoon.tistory.com/302#entry302comment</comments>
      <pubDate>Sun, 5 Jan 2025 15:14:03 +0900</pubDate>
    </item>
    <item>
      <title>[STM32] 17. I2C 통신 함수 종류</title>
      <link>https://coding-yoon.tistory.com/301</link>
      <description>&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;600&quot; data-origin-height=&quot;600&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bymeLM/btsK78dBX22/wh5RXuxAyWL4SXjhydsGWK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bymeLM/btsK78dBX22/wh5RXuxAyWL4SXjhydsGWK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bymeLM/btsK78dBX22/wh5RXuxAyWL4SXjhydsGWK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbymeLM%2FbtsK78dBX22%2Fwh5RXuxAyWL4SXjhydsGWK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;600&quot; height=&quot;600&quot; data-origin-width=&quot;600&quot; data-origin-height=&quot;600&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;  1. 주요 I2C HAL 함수&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;STM32Cube&amp;nbsp;HAL&amp;nbsp;기능을&amp;nbsp;기반으로&amp;nbsp;차단&amp;nbsp;모드,&amp;nbsp;인터럽트&amp;nbsp;모드&amp;nbsp;또는&amp;nbsp;DMA&amp;nbsp;모드의&amp;nbsp;3가지&amp;nbsp;모드로&amp;nbsp;I2C&amp;nbsp;데이터&amp;nbsp;전송을&amp;nbsp;수행할&amp;nbsp;수&amp;nbsp;있다.&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;⚙️&amp;nbsp;1. Blocking Mode&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;통신은&amp;nbsp;폴링&amp;nbsp;모드로&amp;nbsp;수행되며,&amp;nbsp;모든&amp;nbsp;데이터&amp;nbsp;처리&amp;nbsp;상태는&amp;nbsp;전송&amp;nbsp;완료&amp;nbsp;후&amp;nbsp;동일한&amp;nbsp;기능으로&amp;nbsp;반환된다.&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;HAL_I2C_Master_Transmit()&lt;/li&gt;
&lt;li&gt;HAL_I2C_Master_Receive()&lt;/li&gt;
&lt;li&gt;HAL_I2C_Slave_Transmit()&lt;/li&gt;
&lt;li&gt;HAL_I2C_Slave_Receive()&lt;/li&gt;
&lt;li&gt;HAL_I2C_Mem_Write()&lt;/li&gt;
&lt;li&gt;HAL_I2C_Mem_Read()&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size23&quot;&gt;⚙️ 2. Non-Blocking Mode&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;통신은&amp;nbsp;Interrupts&amp;nbsp;또는&amp;nbsp;DMA를&amp;nbsp;사용하여&amp;nbsp;수행되며,&amp;nbsp;이러한&amp;nbsp;함수는&amp;nbsp;전송&amp;nbsp;시작&amp;nbsp;상태를&amp;nbsp;반환한다. &lt;br /&gt;&lt;br /&gt;인터럽트&amp;nbsp;모드를&amp;nbsp;사용할&amp;nbsp;때는&amp;nbsp;전용&amp;nbsp;I2C&amp;nbsp;IRQ를&amp;nbsp;통해,&amp;nbsp;DMA&amp;nbsp;모드를&amp;nbsp;사용할&amp;nbsp;때는&amp;nbsp;DMA&amp;nbsp;IRQ를&amp;nbsp;통해&amp;nbsp;데이터&amp;nbsp;처리가&amp;nbsp;종료됨을&amp;nbsp;알&amp;nbsp;수&amp;nbsp;있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Interrupt&amp;nbsp;Mode&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;HAL_I2C_Master_Transmit_IT()&lt;/li&gt;
&lt;li&gt;HAL_I2C_Master_Receive_IT()&lt;/li&gt;
&lt;li&gt;HAL_I2C_Slave_Transmit_IT()&lt;/li&gt;
&lt;li&gt;HAL_I2C_Slave_Receive_IT()&lt;/li&gt;
&lt;li&gt;HAL_I2C_Mem_Write_IT()&lt;/li&gt;
&lt;li&gt;HAL_I2C_Mem_Read_IT()&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;DMA&amp;nbsp;Mode&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;HAL_I2C_Master_Transmit_DMA()&lt;/li&gt;
&lt;li&gt;HAL_I2C_Master_Receive_DMA()&lt;/li&gt;
&lt;li&gt;HAL_I2C_Slave_Transmit_DMA()&lt;/li&gt;
&lt;li&gt;HAL_I2C_Slave_Receive_DMA()&lt;/li&gt;
&lt;li&gt;HAL_I2C_Mem_Write_DMA()&lt;/li&gt;
&lt;li&gt;HAL_I2C_Mem_Read_DMA()&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;  2. I2C 설정&lt;/h2&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;⚙️ 1. STM32CubeMX 프로젝트 열기&lt;/h3&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock widthContent&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;966&quot; data-origin-height=&quot;436&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/7VA9D/btsK50O908X/fFmkmRkd5EOyFUM1Yf2zrk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/7VA9D/btsK50O908X/fFmkmRkd5EOyFUM1Yf2zrk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/7VA9D/btsK50O908X/fFmkmRkd5EOyFUM1Yf2zrk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2F7VA9D%2FbtsK50O908X%2FfFmkmRkd5EOyFUM1Yf2zrk%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;966&quot; height=&quot;436&quot; data-origin-width=&quot;966&quot; data-origin-height=&quot;436&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;⚙️ 2. I2C 설정&lt;/h3&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock widthContent&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;966&quot; data-origin-height=&quot;436&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/pmHnO/btsK6a5on6B/nlq3XBJUi09flp51En8eMk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/pmHnO/btsK6a5on6B/nlq3XBJUi09flp51En8eMk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/pmHnO/btsK6a5on6B/nlq3XBJUi09flp51En8eMk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FpmHnO%2FbtsK6a5on6B%2Fnlq3XBJUi09flp51En8eMk%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;966&quot; height=&quot;436&quot; data-origin-width=&quot;966&quot; data-origin-height=&quot;436&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;⚙️ 3. I2C 파라미터 설정&lt;/h3&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock widthContent&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;663&quot; data-origin-height=&quot;539&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bjntf8/btsK51N5af3/hQFHNi3BhAb2TfcqzAE8TK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bjntf8/btsK51N5af3/hQFHNi3BhAb2TfcqzAE8TK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bjntf8/btsK51N5af3/hQFHNi3BhAb2TfcqzAE8TK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fbjntf8%2FbtsK51N5af3%2FhQFHNi3BhAb2TfcqzAE8TK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;663&quot; height=&quot;539&quot; data-origin-width=&quot;663&quot; data-origin-height=&quot;539&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;  3. 코드&lt;/h2&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;  1. HAL_StatusTypeDef&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;HAL_I2C&amp;nbsp;함수들의&amp;nbsp;반환&amp;nbsp;자료형인&amp;nbsp;StatusTypeDef의&amp;nbsp;정의는&amp;nbsp;다음과&amp;nbsp;같다.&lt;/p&gt;
&lt;pre id=&quot;code_1733328361641&quot; class=&quot;cpp&quot; data-ke-language=&quot;cpp&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;typedef enum{
  HAL_I2C_STATE_RESET             = 0x00U,   /*!&amp;lt; Peripheral is not yet Initialized         */
  HAL_I2C_STATE_READY             = 0x20U,   /*!&amp;lt; Peripheral Initialized and ready for use  */
  HAL_I2C_STATE_BUSY              = 0x24U,   /*!&amp;lt; An internal process is ongoing            */
  HAL_I2C_STATE_BUSY_TX           = 0x21U,   /*!&amp;lt; Data Transmission process is ongoing      */
  HAL_I2C_STATE_BUSY_RX           = 0x22U,   /*!&amp;lt; Data Reception process is ongoing         */
  HAL_I2C_STATE_LISTEN            = 0x28U,   /*!&amp;lt; Address Listen Mode is ongoing            */
  HAL_I2C_STATE_BUSY_TX_LISTEN    = 0x29U,   /*!&amp;lt; Address Listen Mode and Data Transmission
                                                 process is ongoing                         */
  HAL_I2C_STATE_BUSY_RX_LISTEN    = 0x2AU,   /*!&amp;lt; Address Listen Mode and Data Reception
                                                 process is ongoing                         */
  HAL_I2C_STATE_ABORT             = 0x60U,   /*!&amp;lt; Abort user request ongoing                */
  HAL_I2C_STATE_TIMEOUT           = 0xA0U,   /*!&amp;lt; Timeout state                             */
  HAL_I2C_STATE_ERROR             = 0xE0U    /*!&amp;lt; Error                                     */

}HAL_I2C_StateTypeDef;&lt;/code&gt;&lt;/pre&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;  2. HAL_I2C_Master_Transmit&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;특정&amp;nbsp;I2C&amp;nbsp;Slave에&amp;nbsp;바이트&amp;nbsp;데이터를&amp;nbsp;보내는&amp;nbsp;함수이다.&lt;/p&gt;
&lt;pre id=&quot;code_1733328466887&quot; class=&quot;cpp&quot; data-ke-language=&quot;cpp&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;HAL_StatusTypeDef HAL_I2C_Master_Transmit(I2C_HandleTypeDef *hi2c, uint16_t DevAddress, uint8_t *pData, uint16_t Size, uint32_t Timeout)&lt;/code&gt;&lt;/pre&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li style=&quot;list-style-type: inherit;&quot;&gt;&lt;span&gt;hi2c: I2C 핸들의 주소&lt;/span&gt;&lt;/li&gt;
&lt;li style=&quot;list-style-type: inherit;&quot;&gt;&lt;span&gt;DevAddress: I2C Slave의 8bit 주소&lt;/span&gt;&lt;/li&gt;
&lt;li style=&quot;list-style-type: inherit;&quot;&gt;&lt;span&gt;pData: 버퍼 배열의 주소&lt;/span&gt;&lt;/li&gt;
&lt;li style=&quot;list-style-type: inherit;&quot;&gt;&lt;span&gt;Size: 전송할 데이터의 바이트 수&lt;/span&gt;&lt;/li&gt;
&lt;li style=&quot;list-style-type: inherit;&quot;&gt;&lt;span&gt;Timeout: 최대 지연 시간 [ms]&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;span&gt;  3. HAL_I2C_Mem_Write&lt;/span&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;I2C를 통하여 Repeated Start 명령을 주기 위해서는 다음과 같은 함수들을 이용한다.&lt;br /&gt;단순히 HAL_I2C_Master_Write와 HAL_I2C_Master_Read를 연달아 호출하는 것으로는 정상 작동 하지 않는다.&lt;br /&gt;하지만&amp;nbsp;다음과&amp;nbsp;같은&amp;nbsp;함수를&amp;nbsp;통하여&amp;nbsp;쉽게&amp;nbsp;사용할&amp;nbsp;수&amp;nbsp;있다.&lt;/span&gt;&lt;/p&gt;
&lt;pre id=&quot;code_1733328536318&quot; class=&quot;cpp&quot; data-ke-language=&quot;cpp&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;HAL_StatusTypeDef HAL_I2C_Mem_Write(I2C_HandleTypeDef *hi2c, uint16_t DevAddress, uint16_t MemAddress, uint16_t MemAddSize, uint8_t *pData, uint16_t Size, uint32_t Timeout)&lt;/code&gt;&lt;/pre&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;hi2c : I2C 핸들의 주소&lt;/li&gt;
&lt;li&gt;DevAddress : I2C Slave의 주소MemAddress : I2C Slave에서 쓰기 할 레지스터의 주소&lt;/li&gt;
&lt;li&gt;MemAddSize : 주소의 바이트 수(1byte-&amp;gt;1, 2byte-&amp;gt;2)&lt;/li&gt;
&lt;li&gt;pData : 버퍼 배열의 주소&lt;/li&gt;
&lt;li&gt;Size : 레지스터에 쓰기 할 바이트 수&lt;/li&gt;
&lt;li&gt;Timeout : 최대 지연 시간 [ms]&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;  4. HAL_I2C_GetState&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;현재&amp;nbsp;I2C&amp;nbsp;Peripheral의&amp;nbsp;상태를&amp;nbsp;반환한다.&lt;/p&gt;
&lt;pre id=&quot;code_1733328618854&quot; class=&quot;cpp&quot; data-ke-language=&quot;cpp&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;HAL_I2C_StateTypeDef HAL_I2C_GetState(I2C_HandleTypeDef *hi2c)
#define SLAVE_ADDR 0x27 &amp;lt;&amp;lt; 1
HAL_StatusTypeDef error;
uint8_t buffer[128] = {0x3F, 0xDD, 0x54};
error = HAL_I2C_Master_Transmit(&amp;amp;hi2c1, SLAVE_ADDR, buffer, 3, HAL_MAX_DELAY);
if (error != HAL_OK) while();

// I2C의 전송이 완료될 때까지 대기
while(HAL_I2C_GetState(&amp;amp;hi2c1) != HAL_I2C_STATE_READY);&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;HAL_I2C_GetError &lt;br /&gt;&lt;br /&gt;정수&amp;nbsp;형태의&amp;nbsp;에러&amp;nbsp;코드를&amp;nbsp;반환하는&amp;nbsp;코드이다.&lt;/p&gt;
&lt;pre id=&quot;code_1733328635494&quot; class=&quot;cpp&quot; data-ke-language=&quot;cpp&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;uint32_t HAL_I2C_GetError(I2C_HandleTypeDef *hi2c)&lt;/code&gt;&lt;/pre&gt;
&lt;pre id=&quot;code_1733328642093&quot; class=&quot;cpp&quot; data-ke-language=&quot;cpp&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;#define HAL_I2C_ERROR_NONE       0x00000000U    /*!&amp;lt; No error           */
#define HAL_I2C_ERROR_BERR       0x00000001U    /*!&amp;lt; BERR error         */
#define HAL_I2C_ERROR_ARLO       0x00000002U    /*!&amp;lt; ARLO error         */
#define HAL_I2C_ERROR_AF         0x00000004U    /*!&amp;lt; AF error           */
#define HAL_I2C_ERROR_OVR        0x00000008U    /*!&amp;lt; OVR error          */
#define HAL_I2C_ERROR_DMA        0x00000010U    /*!&amp;lt; DMA transfer error */
#define HAL_I2C_ERROR_TIMEOUT    0x00000020U    /*!&amp;lt; Timeout Error      */&lt;/code&gt;&lt;/pre&gt;</description>
      <category>  STM32</category>
      <category>i2c</category>
      <category>STM32</category>
      <category>종류</category>
      <category>통신</category>
      <category>함수</category>
      <author>18진수</author>
      <guid isPermaLink="true">https://coding-yoon.tistory.com/301</guid>
      <comments>https://coding-yoon.tistory.com/301#entry301comment</comments>
      <pubDate>Thu, 5 Dec 2024 01:14:45 +0900</pubDate>
    </item>
    <item>
      <title>[STM32] 16. I2C 센서 소개 (미세먼지/이산화탄소 복합 공기질 센서 CUBIC - AM1008W-K-P)</title>
      <link>https://coding-yoon.tistory.com/300</link>
      <description>&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;600&quot; data-origin-height=&quot;600&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cTPPQZ/btsK6b4g4mQ/VpZpoLUeff8UGsl4zOb5Kk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cTPPQZ/btsK6b4g4mQ/VpZpoLUeff8UGsl4zOb5Kk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cTPPQZ/btsK6b4g4mQ/VpZpoLUeff8UGsl4zOb5Kk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FcTPPQZ%2FbtsK6b4g4mQ%2FVpZpoLUeff8UGsl4zOb5Kk%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;600&quot; height=&quot;600&quot; data-origin-width=&quot;600&quot; data-origin-height=&quot;600&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;STM32&amp;nbsp;I2C&amp;nbsp;통신을&amp;nbsp;이용해&amp;nbsp;테스트를&amp;nbsp;해볼&amp;nbsp;센서는&amp;nbsp;복합&amp;nbsp;공기질&amp;nbsp;센서&amp;nbsp;AM1008W-K-P&amp;nbsp;모델이다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock widthContent&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;966&quot; data-origin-height=&quot;519&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/dz5WYZ/btsK7PrO0Mn/iCF8C6I6LOuNVh9HSCWmM1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/dz5WYZ/btsK7PrO0Mn/iCF8C6I6LOuNVh9HSCWmM1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/dz5WYZ/btsK7PrO0Mn/iCF8C6I6LOuNVh9HSCWmM1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fdz5WYZ%2FbtsK7PrO0Mn%2FiCF8C6I6LOuNVh9HSCWmM1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;966&quot; height=&quot;519&quot; data-origin-width=&quot;966&quot; data-origin-height=&quot;519&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;해당&amp;nbsp;센서는&amp;nbsp;주위&amp;nbsp;미세먼지와&amp;nbsp;이산화탄소&amp;nbsp;농도를&amp;nbsp;알려주는&amp;nbsp;복합&amp;nbsp;공기질&amp;nbsp;센서이며,&amp;nbsp;미세먼지&amp;nbsp;(PM),&amp;nbsp;VOC,&amp;nbsp;이산화탄소,&amp;nbsp;온습도&amp;nbsp;측정이&amp;nbsp;가능하다.&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;&lt;span style=&quot;color: #006dd7;&quot;&gt;➡️ 1. Features&lt;/span&gt;&lt;/b&gt;&lt;/h3&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;미세먼지(GRIMM 방식), 이산화탄소, VOC, 온습도&lt;/li&gt;
&lt;li&gt;공급 전압 : 5V&lt;/li&gt;
&lt;li&gt;노이즈 방지를 위한 금속 차폐&lt;/li&gt;
&lt;li&gt;통신 방식 : I2C, UART&lt;/li&gt;
&lt;li&gt;크기 : 80(W) x 50(H) x 13.6(D) [mm]&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;&lt;span style=&quot;color: #006dd7;&quot;&gt;➡️ 2. Application Ideas &lt;/span&gt;&lt;/b&gt;&lt;/h3&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;Air Purifier&lt;/li&gt;
&lt;li&gt;Air Quality Monitor&lt;/li&gt;
&lt;li&gt;Air Conditioner&lt;/li&gt;
&lt;li&gt;Ventilation System&lt;/li&gt;
&lt;li&gt;Consumer electronic products&lt;/li&gt;
&lt;li&gt;Environmental monitoring&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;&lt;span style=&quot;color: #006dd7;&quot;&gt;➡️ 3.&lt;span&gt; Specification&lt;/span&gt;&lt;/span&gt;&lt;/b&gt;&lt;/h3&gt;
&lt;table style=&quot;background-color: #ffffff; color: #000000; text-align: left; border-collapse: collapse; width: 100%;&quot; border=&quot;1&quot; data-ke-align=&quot;alignLeft&quot;&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td style=&quot;background-color: #ffffff;&quot; colspan=&quot;1&quot; rowspan=&quot;1&quot;&gt;
&lt;div&gt;&lt;span&gt;&lt;span style=&quot;background-color: #ffffff; color: #666666;&quot;&gt;&lt;b&gt;Operating principle&lt;/b&gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;
&lt;/td&gt;
&lt;td style=&quot;background-color: #ffffff;&quot; colspan=&quot;1&quot; rowspan=&quot;1&quot;&gt;
&lt;div&gt;&lt;span&gt;&lt;span style=&quot;background-color: #ffffff; color: #666666;&quot;&gt;CO2: NDIR technology&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;&lt;span&gt;&lt;span style=&quot;background-color: #ffffff; color: #666666;&quot;&gt;PM: laser scattering technology&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;&lt;span&gt;&lt;span style=&quot;background-color: #ffffff; color: #666666;&quot;&gt;VOC: semiconductor&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;background-color: #ffffff;&quot; colspan=&quot;1&quot; rowspan=&quot;1&quot;&gt;
&lt;div&gt;&lt;span&gt;&lt;span style=&quot;background-color: #ffffff; color: #666666;&quot;&gt;&lt;b&gt;Measurement range&lt;/b&gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;
&lt;/td&gt;
&lt;td style=&quot;background-color: #ffffff;&quot; colspan=&quot;1&quot; rowspan=&quot;1&quot;&gt;
&lt;div&gt;&lt;span&gt;&lt;span style=&quot;background-color: #ffffff; color: #666666;&quot;&gt;PM: 0 ~ 1,000ug/m&amp;sup3;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;&lt;span&gt;&lt;span style=&quot;background-color: #ffffff; color: #666666;&quot;&gt;CO2: 0 ~ 5,000ppm&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;&lt;span&gt;&lt;span style=&quot;background-color: #ffffff; color: #666666;&quot;&gt;VOC: 0 ~ 3 level&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;&lt;span&gt;&lt;span style=&quot;background-color: #ffffff; color: #666666;&quot;&gt;Temperature: -40&amp;deg;C~85&amp;deg;C&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;&lt;span&gt;&lt;span style=&quot;background-color: #ffffff; color: #666666;&quot;&gt;RH: 5 ~ 95%RH&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;background-color: #ffffff;&quot; colspan=&quot;1&quot; rowspan=&quot;1&quot;&gt;
&lt;div&gt;&lt;span&gt;&lt;span style=&quot;background-color: #ffffff; color: #666666;&quot;&gt;&lt;b&gt;Maximum consistency error for PM1.0/PM2.5 &lt;/b&gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;
&lt;/td&gt;
&lt;td style=&quot;background-color: #ffffff;&quot; colspan=&quot;1&quot; rowspan=&quot;1&quot;&gt;
&lt;div&gt;&lt;span&gt;&lt;span style=&quot;background-color: #ffffff; color: #666666;&quot;&gt;&amp;le;100ug/m&amp;sup3;, &amp;plusmn;10ug/m&amp;sup3;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;&lt;span&gt;&lt;span style=&quot;background-color: #ffffff; color: #666666;&quot;&gt;&amp;gt;100ug/m&amp;sup3;, &amp;plusmn;10% ofreading&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;&lt;span&gt;&lt;span style=&quot;background-color: #ffffff; color: #666666;&quot;&gt;Condition: 25 &amp;plusmn;2&amp;deg;C, 50&amp;plusmn;10%RH, &lt;/span&gt;&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;&lt;span&gt;&lt;span style=&quot;background-color: #ffffff; color: #666666;&quot;&gt;Reference instrument: GRIMM 11-A&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;&lt;span&gt;&lt;span style=&quot;background-color: #ffffff; color: #666666;&quot;&gt;Dust Source: Cigarette + Arizona A1&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;background-color: #ffffff;&quot; colspan=&quot;1&quot; rowspan=&quot;1&quot;&gt;
&lt;div&gt;&lt;span&gt;&lt;span style=&quot;background-color: #ffffff; color: #666666;&quot;&gt;&lt;b&gt;Maximum consistency error for PM10&lt;/b&gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;
&lt;/td&gt;
&lt;td style=&quot;background-color: #ffffff;&quot; colspan=&quot;1&quot; rowspan=&quot;1&quot;&gt;
&lt;div&gt;&lt;span&gt;&lt;span style=&quot;background-color: #ffffff; color: #666666;&quot;&gt;0 ~ 100ug/m&amp;sup3;, &amp;plusmn;25ug/m&amp;sup3;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;&lt;span&gt;&lt;span style=&quot;background-color: #ffffff; color: #666666;&quot;&gt;101 ~ 1,000ug/m&amp;sup3;, &amp;plusmn;25% reading&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;&lt;span&gt;&lt;span style=&quot;background-color: #ffffff; color: #666666;&quot;&gt;Condition: 25 &amp;plusmn;2&amp;deg;C,50&amp;plusmn;10%RH, &lt;/span&gt;&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;&lt;span&gt;&lt;span style=&quot;background-color: #ffffff; color: #666666;&quot;&gt;Reference instrument: GRIMM 11-A&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;&lt;span&gt;&lt;span style=&quot;background-color: #ffffff; color: #666666;&quot;&gt;Dust Source: Cigarette + Arizona A1&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;background-color: #ffffff;&quot; colspan=&quot;1&quot; rowspan=&quot;1&quot;&gt;
&lt;div&gt;&lt;span&gt;&lt;span style=&quot;background-color: #ffffff; color: #666666;&quot;&gt;&lt;b&gt;CO2 measurement accuracy&lt;/b&gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;
&lt;/td&gt;
&lt;td style=&quot;background-color: #ffffff;&quot; colspan=&quot;1&quot; rowspan=&quot;1&quot;&gt;
&lt;div&gt;&lt;span&gt;&lt;span style=&quot;background-color: #ffffff; color: #666666;&quot;&gt;&amp;plusmn; (50ppm+5% of reading) @25 &amp;plusmn;2&amp;deg;C, 50 &amp;plusmn;10%RH&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;&lt;span&gt;&lt;span style=&quot;background-color: #ffffff; color: #666666;&quot;&gt;&amp;plusmn; (50ppm+3%of reading) @25 &amp;plusmn;2&amp;deg;C, 50 &amp;plusmn;10%RH(Option)&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;background-color: #ffffff;&quot; colspan=&quot;1&quot; rowspan=&quot;1&quot;&gt;
&lt;div&gt;&lt;span&gt;&lt;span style=&quot;background-color: #ffffff; color: #666666;&quot;&gt;&lt;b&gt;Temperature accuracy&lt;/b&gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;
&lt;/td&gt;
&lt;td style=&quot;background-color: #ffffff;&quot; colspan=&quot;1&quot; rowspan=&quot;1&quot;&gt;
&lt;div&gt;&lt;span&gt;&lt;span style=&quot;background-color: #ffffff; color: #666666;&quot;&gt;&amp;plusmn;0.4 &amp;deg;C (max), &amp;ndash;10 ~ 85 &amp;deg;C &lt;/span&gt;&lt;/span&gt;&lt;/div&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;background-color: #ffffff;&quot; colspan=&quot;1&quot; rowspan=&quot;1&quot;&gt;
&lt;div&gt;&lt;span&gt;&lt;span style=&quot;background-color: #ffffff; color: #666666;&quot;&gt;&lt;b&gt;Humidity accuracy&lt;/b&gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;
&lt;/td&gt;
&lt;td style=&quot;background-color: #ffffff;&quot; colspan=&quot;1&quot; rowspan=&quot;1&quot;&gt;
&lt;div&gt;&lt;span&gt;&lt;span style=&quot;background-color: #ffffff; color: #666666;&quot;&gt;&amp;plusmn; 3% RH (max), 0~ 80% RH&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;background-color: #ffffff;&quot; colspan=&quot;1&quot; rowspan=&quot;1&quot;&gt;
&lt;div&gt;&lt;span&gt;&lt;span style=&quot;background-color: #ffffff; color: #666666;&quot;&gt;&lt;b&gt;PM preheating time&lt;/b&gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;
&lt;/td&gt;
&lt;td style=&quot;background-color: #ffffff;&quot; colspan=&quot;1&quot; rowspan=&quot;1&quot;&gt;
&lt;div&gt;&lt;span&gt;&lt;span style=&quot;background-color: #ffffff; color: #666666;&quot;&gt;&amp;le;8 sec&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;background-color: #ffffff;&quot; colspan=&quot;1&quot; rowspan=&quot;1&quot;&gt;
&lt;div&gt;&lt;span&gt;&lt;span style=&quot;background-color: #ffffff; color: #666666;&quot;&gt;&lt;b&gt;CO2 preheating time&lt;/b&gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;
&lt;/td&gt;
&lt;td style=&quot;background-color: #ffffff;&quot; colspan=&quot;1&quot; rowspan=&quot;1&quot;&gt;
&lt;div&gt;&lt;span&gt;&lt;span style=&quot;background-color: #ffffff; color: #666666;&quot;&gt;&amp;le;30 sec&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;background-color: #ffffff;&quot; colspan=&quot;1&quot; rowspan=&quot;1&quot;&gt;
&lt;div&gt;&lt;span&gt;&lt;span style=&quot;background-color: #ffffff; color: #666666;&quot;&gt;&lt;b&gt;VOC preheating time&lt;/b&gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;
&lt;/td&gt;
&lt;td style=&quot;background-color: #ffffff;&quot; colspan=&quot;1&quot; rowspan=&quot;1&quot;&gt;
&lt;div&gt;&lt;span&gt;&lt;span style=&quot;background-color: #ffffff; color: #666666;&quot;&gt;&amp;le;120 sec&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;background-color: #ffffff;&quot; colspan=&quot;1&quot; rowspan=&quot;1&quot;&gt;
&lt;div&gt;&lt;span&gt;&lt;span style=&quot;background-color: #ffffff; color: #666666;&quot;&gt;&lt;b&gt;Data refresh rate&lt;/b&gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;
&lt;/td&gt;
&lt;td style=&quot;background-color: #ffffff;&quot; colspan=&quot;1&quot; rowspan=&quot;1&quot;&gt;
&lt;div&gt;&lt;span&gt;&lt;span style=&quot;background-color: #ffffff; color: #666666;&quot;&gt;1 sec&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;background-color: #ffffff;&quot; colspan=&quot;1&quot; rowspan=&quot;1&quot;&gt;
&lt;div&gt;&lt;span&gt;&lt;span style=&quot;background-color: #ffffff; color: #666666;&quot;&gt;&lt;b&gt;Working condition&lt;/b&gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;
&lt;/td&gt;
&lt;td style=&quot;background-color: #ffffff;&quot; colspan=&quot;1&quot; rowspan=&quot;1&quot;&gt;
&lt;div&gt;&lt;span&gt;&lt;span style=&quot;background-color: #ffffff; color: #666666;&quot;&gt;-10 ~ 50&amp;deg;C, 0 ~ 99%RH (Non-condensing)&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;background-color: #ffffff;&quot; colspan=&quot;1&quot; rowspan=&quot;1&quot;&gt;
&lt;div&gt;&lt;span&gt;&lt;span style=&quot;background-color: #ffffff; color: #666666;&quot;&gt;&lt;b&gt;Storage condition&lt;/b&gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;
&lt;/td&gt;
&lt;td style=&quot;background-color: #ffffff;&quot; colspan=&quot;1&quot; rowspan=&quot;1&quot;&gt;
&lt;div&gt;&lt;span&gt;&lt;span style=&quot;background-color: #ffffff; color: #666666;&quot;&gt;-20 ~ 60&amp;deg;C, 0 ~ 99%RH (Non-condensing)&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;background-color: #ffffff;&quot; colspan=&quot;1&quot; rowspan=&quot;1&quot;&gt;
&lt;div&gt;&lt;span&gt;&lt;span style=&quot;background-color: #ffffff; color: #666666;&quot;&gt;&lt;b&gt;Working voltage&lt;/b&gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;
&lt;/td&gt;
&lt;td style=&quot;background-color: #ffffff;&quot; colspan=&quot;1&quot; rowspan=&quot;1&quot;&gt;
&lt;div&gt;&lt;span&gt;&lt;span style=&quot;background-color: #ffffff; color: #666666;&quot;&gt;DC 5V &amp;plusmn;0.1V, ripple wave &amp;lt; 50mV&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;background-color: #ffffff;&quot; colspan=&quot;1&quot; rowspan=&quot;1&quot;&gt;
&lt;div&gt;&lt;span&gt;&lt;span style=&quot;background-color: #ffffff; color: #666666;&quot;&gt;&lt;b&gt;Average working current&lt;/b&gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;
&lt;/td&gt;
&lt;td style=&quot;background-color: #ffffff;&quot; colspan=&quot;1&quot; rowspan=&quot;1&quot;&gt;
&lt;div&gt;&lt;span&gt;&lt;span style=&quot;background-color: #ffffff; color: #666666;&quot;&gt;&amp;le;300mA&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;background-color: #ffffff;&quot; colspan=&quot;1&quot; rowspan=&quot;1&quot;&gt;
&lt;div&gt;&lt;span&gt;&lt;span style=&quot;background-color: #ffffff; color: #666666;&quot;&gt;&lt;b&gt;Signal output&lt;/b&gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;
&lt;/td&gt;
&lt;td style=&quot;background-color: #ffffff;&quot; colspan=&quot;1&quot; rowspan=&quot;1&quot;&gt;
&lt;div&gt;&lt;span&gt;&lt;span style=&quot;background-color: #ffffff; color: #666666;&quot;&gt;UART TTL (3.3V TTL), I2C&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;background-color: #ffffff;&quot; colspan=&quot;1&quot; rowspan=&quot;1&quot;&gt;
&lt;div&gt;&lt;span&gt;&lt;span style=&quot;background-color: #ffffff; color: #666666;&quot;&gt;&lt;b&gt;Dimension&lt;/b&gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;
&lt;/td&gt;
&lt;td style=&quot;background-color: #ffffff;&quot; colspan=&quot;1&quot; rowspan=&quot;1&quot;&gt;
&lt;div&gt;&lt;span&gt;&lt;span style=&quot;background-color: #ffffff; color: #666666;&quot;&gt;W80mm &amp;times;H50mm &amp;times;D13.6mm&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;background-color: #ffffff;&quot; colspan=&quot;1&quot; rowspan=&quot;1&quot;&gt;
&lt;div&gt;&lt;span&gt;&lt;span style=&quot;background-color: #ffffff; color: #666666;&quot;&gt;&lt;b&gt;Life span&lt;/b&gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;
&lt;/td&gt;
&lt;td style=&quot;background-color: #ffffff;&quot; colspan=&quot;1&quot; rowspan=&quot;1&quot;&gt;
&lt;div&gt;&lt;span&gt;&lt;span style=&quot;background-color: #ffffff; color: #666666;&quot;&gt;MTTF of PM sensor= 110,000Hrs (continuous turn on)&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;&lt;span&gt;&lt;span style=&quot;background-color: #ffffff; color: #666666;&quot;&gt;CO2 &amp;ge;10 years&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;&lt;span&gt;&lt;span style=&quot;background-color: #ffffff; color: #666666;&quot;&gt;VOC &amp;ge;10 years&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;해당&amp;nbsp;센서를&amp;nbsp;STM32&amp;nbsp;I2C&amp;nbsp;통신을&amp;nbsp;이용해&amp;nbsp;제어하기&amp;nbsp;위해선&amp;nbsp;간단히&amp;nbsp;데이터시트를&amp;nbsp;참고할&amp;nbsp;필요가&amp;nbsp;있다.&amp;nbsp;구현에&amp;nbsp;중요한&amp;nbsp;부분은&amp;nbsp;간단히&amp;nbsp;설명하고자&amp;nbsp;한다. &lt;br /&gt;&lt;br /&gt;자세히&amp;nbsp;보고&amp;nbsp;싶다면&amp;nbsp;해당&amp;nbsp;첨부파일을&amp;nbsp;참고하길&amp;nbsp;바란다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;fileblock&quot; data-ke-align=&quot;alignCenter&quot;&gt;&lt;a href=&quot;https://blog.kakaocdn.net/dn/bbzulf/btsK8pMZYjz/HgppLZR1mcSUV2LGQuVkek/Complex_air_quality_measurement_module_AM1008W-K_Specification_210312.pdf?attach=1&amp;amp;knm=tfile.pdf&quot; class=&quot;&quot;&gt;
    &lt;div class=&quot;image&quot;&gt;&lt;/div&gt;
    &lt;div class=&quot;desc&quot;&gt;&lt;div class=&quot;filename&quot;&gt;&lt;span class=&quot;name&quot;&gt;Complex_air_quality_measurement_module_AM1008W-K_Specification_210312.pdf&lt;/span&gt;&lt;/div&gt;
&lt;div class=&quot;size&quot;&gt;0.78MB&lt;/div&gt;
&lt;/div&gt;
  &lt;/a&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;제품의&amp;nbsp;케이스를&amp;nbsp;벗기게&amp;nbsp;되면&amp;nbsp;아래&amp;nbsp;사진과&amp;nbsp;같이&amp;nbsp;PCB&amp;nbsp;상태의&amp;nbsp;센서를&amp;nbsp;확인할&amp;nbsp;수&amp;nbsp;있다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock widthContent&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;966&quot; data-origin-height=&quot;367&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/8tpnW/btsK6ACx5dR/DjthLVsiolCna9KlcMmvAK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/8tpnW/btsK6ACx5dR/DjthLVsiolCna9KlcMmvAK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/8tpnW/btsK6ACx5dR/DjthLVsiolCna9KlcMmvAK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2F8tpnW%2FbtsK6ACx5dR%2FDjthLVsiolCna9KlcMmvAK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;966&quot; height=&quot;367&quot; data-origin-width=&quot;966&quot; data-origin-height=&quot;367&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;선을&amp;nbsp;연결하기&amp;nbsp;위해선&amp;nbsp;아래와&amp;nbsp;같이&amp;nbsp;구성해야&amp;nbsp;한다.&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock widthContent&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;966&quot; data-origin-height=&quot;307&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/zh86v/btsK8ogfbKT/L4gyykZLdpygd93jTVkoA0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/zh86v/btsK8ogfbKT/L4gyykZLdpygd93jTVkoA0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/zh86v/btsK8ogfbKT/L4gyykZLdpygd93jTVkoA0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fzh86v%2FbtsK8ogfbKT%2FL4gyykZLdpygd93jTVkoA0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;966&quot; height=&quot;307&quot; data-origin-width=&quot;966&quot; data-origin-height=&quot;307&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;검정색&amp;nbsp;&amp;nbsp;- GND&lt;/li&gt;
&lt;li&gt;흰색&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;-&amp;nbsp;&amp;nbsp;SDA&lt;/li&gt;
&lt;li&gt;초록색&amp;nbsp;&amp;nbsp;- SCL&lt;/li&gt;
&lt;li&gt;빨강색&amp;nbsp;&amp;nbsp;- &lt;span style=&quot;color: #ee2323;&quot;&gt;VCC (5V)&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;데이터시트에&amp;nbsp;친절하게&amp;nbsp;3.3V&amp;nbsp;MCU와&amp;nbsp;5V로&amp;nbsp;동작하는&amp;nbsp;센서를&amp;nbsp;제어할&amp;nbsp;때&amp;nbsp;구현해야할&amp;nbsp;회로도를&amp;nbsp;넣어주었다.&amp;nbsp;회로도를&amp;nbsp;보니&amp;nbsp;HOST&amp;nbsp;MCU(나의&amp;nbsp;경우&amp;nbsp;:&amp;nbsp;STM32F103)에&amp;nbsp;외부&amp;nbsp;풀업저항을&amp;nbsp;통해&amp;nbsp;I2C&amp;nbsp;통신을&amp;nbsp;제어하는&amp;nbsp;것과&amp;nbsp;해당&amp;nbsp;센서는&amp;nbsp;5V로&amp;nbsp;동작하는&amp;nbsp;것을&amp;nbsp;확인하였다.&amp;nbsp;회로도에서는&amp;nbsp;10K옴을&amp;nbsp;사용하였는데&amp;nbsp;나의&amp;nbsp;경우&amp;nbsp;4.7K옴을&amp;nbsp;사용하였다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock widthContent&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;966&quot; data-origin-height=&quot;434&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bgM5Sc/btsK7Hgs5sd/A5T5QRbFnx2lEIyVizblUK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bgM5Sc/btsK7Hgs5sd/A5T5QRbFnx2lEIyVizblUK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bgM5Sc/btsK7Hgs5sd/A5T5QRbFnx2lEIyVizblUK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbgM5Sc%2FbtsK7Hgs5sd%2FA5T5QRbFnx2lEIyVizblUK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;966&quot; height=&quot;434&quot; data-origin-width=&quot;966&quot; data-origin-height=&quot;434&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;주의&amp;nbsp;사항을&amp;nbsp;확인한다.&amp;nbsp;UART와&amp;nbsp;I2C&amp;nbsp;통신을&amp;nbsp;하기&amp;nbsp;위해선&amp;nbsp;전원&amp;nbsp;공급&amp;nbsp;이&amp;nbsp;후&amp;nbsp;10초라는&amp;nbsp;대기시간이&amp;nbsp;필요한&amp;nbsp;듯&amp;nbsp;싶다.&amp;nbsp;이&amp;nbsp;글에서&amp;nbsp;가장&amp;nbsp;중요한&amp;nbsp;문구가&amp;nbsp;다음에&amp;nbsp;나온다.&amp;nbsp;기본&amp;nbsp;구매했을&amp;nbsp;때&amp;nbsp;제품은&amp;nbsp;UART&amp;nbsp;통신을&amp;nbsp;사용하며&amp;nbsp;점퍼를&amp;nbsp;이용해&amp;nbsp;UART와&amp;nbsp;I2C&amp;nbsp;모드를&amp;nbsp;선택하라고&amp;nbsp;한다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock widthContent&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;966&quot; data-origin-height=&quot;453&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/L48E0/btsK6SXdXFr/9whho3kKegBKOJgrDVHaVk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/L48E0/btsK6SXdXFr/9whho3kKegBKOJgrDVHaVk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/L48E0/btsK6SXdXFr/9whho3kKegBKOJgrDVHaVk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FL48E0%2FbtsK6SXdXFr%2F9whho3kKegBKOJgrDVHaVk%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;966&quot; height=&quot;453&quot; data-origin-width=&quot;966&quot; data-origin-height=&quot;453&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;해당&amp;nbsp;사진을&amp;nbsp;보면&amp;nbsp;간단히&amp;nbsp;알&amp;nbsp;수&amp;nbsp;있다.&amp;nbsp;UART를&amp;nbsp;사용하기&amp;nbsp;위해선&amp;nbsp;해당&amp;nbsp;핀을&amp;nbsp;쇼트시키고,&amp;nbsp;I2C를&amp;nbsp;사용하기&amp;nbsp;위해선&amp;nbsp;점퍼를&amp;nbsp;제거하라고&amp;nbsp;한다.&amp;nbsp;우린&amp;nbsp;I2C&amp;nbsp;통신을&amp;nbsp;사용하니&amp;nbsp;점퍼를&amp;nbsp;아래&amp;nbsp;사진과&amp;nbsp;같이&amp;nbsp;제거하였다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock widthContent&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;701&quot; data-origin-height=&quot;450&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/Fa2ob/btsK7Deakaj/JChzMx2YuziT6xfXCLP5k0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/Fa2ob/btsK7Deakaj/JChzMx2YuziT6xfXCLP5k0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/Fa2ob/btsK7Deakaj/JChzMx2YuziT6xfXCLP5k0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FFa2ob%2FbtsK7Deakaj%2FJChzMx2YuziT6xfXCLP5k0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;701&quot; height=&quot;450&quot; data-origin-width=&quot;701&quot; data-origin-height=&quot;450&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그&amp;nbsp;다음으로&amp;nbsp;가장&amp;nbsp;중요한&amp;nbsp;것은&amp;nbsp;이제&amp;nbsp;이&amp;nbsp;센서(슬레이브)의&amp;nbsp;주소이다.&amp;nbsp; &lt;br /&gt;&lt;br /&gt;쭉쭉&amp;nbsp;내려다&amp;nbsp;보면&amp;nbsp;센서의&amp;nbsp;주소를&amp;nbsp;알&amp;nbsp;수&amp;nbsp;있다. &lt;br /&gt;&lt;br /&gt;해당&amp;nbsp;센서에게&amp;nbsp;Write&amp;nbsp;명령을&amp;nbsp;하기&amp;nbsp;위해서는&amp;nbsp;0x50을&amp;nbsp;쏘라고&amp;nbsp;한다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock widthContent&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;966&quot; data-origin-height=&quot;218&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/nE5Sg/btsK7OsYIeY/qlzrouV9ZCnkf6GioIFj7k/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/nE5Sg/btsK7OsYIeY/qlzrouV9ZCnkf6GioIFj7k/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/nE5Sg/btsK7OsYIeY/qlzrouV9ZCnkf6GioIFj7k/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FnE5Sg%2FbtsK7OsYIeY%2FqlzrouV9ZCnkf6GioIFj7k%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;966&quot; height=&quot;218&quot; data-origin-width=&quot;966&quot; data-origin-height=&quot;218&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;해당&amp;nbsp;선서에게&amp;nbsp;Read&amp;nbsp;명령을&amp;nbsp;하기&amp;nbsp;위해서는&amp;nbsp;0x51을&amp;nbsp;쏘라고&amp;nbsp;한다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock widthContent&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;966&quot; data-origin-height=&quot;204&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/dELC4c/btsK8IZRhwi/5lxpYwhacXfFz1buXwtYsK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/dELC4c/btsK8IZRhwi/5lxpYwhacXfFz1buXwtYsK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/dELC4c/btsK8IZRhwi/5lxpYwhacXfFz1buXwtYsK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FdELC4c%2FbtsK8IZRhwi%2F5lxpYwhacXfFz1buXwtYsK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;966&quot; height=&quot;204&quot; data-origin-width=&quot;966&quot; data-origin-height=&quot;204&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;여기서&amp;nbsp;우리들은&amp;nbsp;센서의&amp;nbsp;주소를&amp;nbsp;알기&amp;nbsp;위해&amp;nbsp;계산을&amp;nbsp;조금해야&amp;nbsp;한다.&amp;nbsp;이&amp;nbsp;전&amp;nbsp;글에서&amp;nbsp;7bit&amp;nbsp;주소와&amp;nbsp;1bit&amp;nbsp;W/R&amp;nbsp;플레그로&amp;nbsp;구성된&amp;nbsp;것으로&amp;nbsp;공부했다. &lt;br /&gt;&lt;br /&gt;그&amp;nbsp;때&amp;nbsp;계산이&amp;nbsp;(7bit&amp;nbsp;주소&amp;nbsp;&amp;lt;&amp;lt;&amp;nbsp;1)&amp;nbsp;|&amp;nbsp;W/R&amp;nbsp;Flag&amp;nbsp;였다.&amp;nbsp;이제&amp;nbsp;역으로&amp;nbsp;계산하면&amp;nbsp;해당&amp;nbsp;센서의&amp;nbsp;주소를&amp;nbsp;알&amp;nbsp;수&amp;nbsp;있다. &lt;br /&gt;&lt;br /&gt;0x50에서&amp;nbsp;오른쪽으로&amp;nbsp;쉬프트&amp;nbsp;연산을&amp;nbsp;한&amp;nbsp;번&amp;nbsp;하면&amp;nbsp;주소이다.&amp;nbsp;0x28이&amp;nbsp;주소임을&amp;nbsp;확인했다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;397&quot; data-origin-height=&quot;222&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cyDmeu/btsK7elldad/8wBr33MKuEXIklXRQW4PG0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cyDmeu/btsK7elldad/8wBr33MKuEXIklXRQW4PG0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cyDmeu/btsK7elldad/8wBr33MKuEXIklXRQW4PG0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FcyDmeu%2FbtsK7elldad%2F8wBr33MKuEXIklXRQW4PG0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;397&quot; height=&quot;222&quot; data-origin-width=&quot;397&quot; data-origin-height=&quot;222&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;우리는&amp;nbsp;데이터시트에서&amp;nbsp;얻은&amp;nbsp;정보를&amp;nbsp;통해&amp;nbsp;STM32&amp;nbsp;I2C&amp;nbsp;통신으로&amp;nbsp;제어할&amp;nbsp;준비가&amp;nbsp;50%가&amp;nbsp;되었다.&amp;nbsp;나머지&amp;nbsp;50%는&amp;nbsp;바로&amp;nbsp;소스코드이다.&amp;nbsp;STM32&amp;nbsp;CubeIDE를&amp;nbsp;통해&amp;nbsp;간단히&amp;nbsp;구현할&amp;nbsp;수&amp;nbsp;있지만,&amp;nbsp;임베디드에서&amp;nbsp;처음&amp;nbsp;구매한&amp;nbsp;센서를&amp;nbsp;뚫는&amp;nbsp;것은&amp;nbsp;만만치&amp;nbsp;않은&amp;nbsp;작업이다. &lt;br /&gt;&lt;br /&gt;가장&amp;nbsp;베스트는&amp;nbsp;누군가&amp;nbsp;이미&amp;nbsp;만들어&amp;nbsp;놓은&amp;nbsp;소스&amp;nbsp;코드를&amp;nbsp;참고하여&amp;nbsp;만드는&amp;nbsp;것이다. &lt;br /&gt;&lt;br /&gt;해당&amp;nbsp;제품은&amp;nbsp;운이&amp;nbsp;좋게도&amp;nbsp;Github에&amp;nbsp;아두이노로&amp;nbsp;구현된&amp;nbsp;라이브러리가&amp;nbsp;이미&amp;nbsp;존재한다.&amp;nbsp;다음&amp;nbsp;글은&amp;nbsp;간단히&amp;nbsp;라이브러리를&amp;nbsp;이용하여&amp;nbsp;아두이노로&amp;nbsp;센서를&amp;nbsp;테스트해보겠다.&lt;/p&gt;</description>
      <category>  STM32</category>
      <category>am1008-w-k</category>
      <category>i2c</category>
      <category>STM32</category>
      <category>UART</category>
      <category>공기질</category>
      <category>미세먼지</category>
      <category>센서</category>
      <category>소개</category>
      <category>오픈소스</category>
      <author>18진수</author>
      <guid isPermaLink="true">https://coding-yoon.tistory.com/300</guid>
      <comments>https://coding-yoon.tistory.com/300#entry300comment</comments>
      <pubDate>Wed, 4 Dec 2024 23:37:06 +0900</pubDate>
    </item>
    <item>
      <title>[STM32] 15. I2C 통신 개요</title>
      <link>https://coding-yoon.tistory.com/299</link>
      <description>&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;600&quot; data-origin-height=&quot;600&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/dmm03a/btsK7FXlP15/BrsKPSkMRc5COkdi5ATljk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/dmm03a/btsK7FXlP15/BrsKPSkMRc5COkdi5ATljk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/dmm03a/btsK7FXlP15/BrsKPSkMRc5COkdi5ATljk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fdmm03a%2FbtsK7FXlP15%2FBrsKPSkMRc5COkdi5ATljk%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;600&quot; height=&quot;600&quot; data-origin-width=&quot;600&quot; data-origin-height=&quot;600&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;  1. I2C(Inter-Integrated Circuit)란 무엇인가?&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;I2C는 원래 1982년 필립스 반도체가 만든 집적 회로 사이에 사용되는 2선 직렬 통신 시스템이다.&lt;br /&gt;I2C는&amp;nbsp;다중&amp;nbsp;마스터,&amp;nbsp;다중&amp;nbsp;슬레이브,&amp;nbsp;동기식,&amp;nbsp;양방향,&amp;nbsp;반이중&amp;nbsp;직렬&amp;nbsp;통신&amp;nbsp;버스이다. &lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;SDA(Serial Data)는 마스터와 슬레이브가 정보(비트 시퀀스)를 전송하거나 수신하는 라인이다.&lt;/li&gt;
&lt;li&gt;SCL(Serial Clock)은 데이터 흐름 동기화를 위한 클럭 전용 라인이다.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock widthContent&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;608&quot; data-origin-height=&quot;250&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/kXKru/btsK64pwNni/TvElSeBTRNSAQCgbz3Ibv0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/kXKru/btsK64pwNni/TvElSeBTRNSAQCgbz3Ibv0/img.png&quot; data-alt=&quot;I2C 통신 회로&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/kXKru/btsK64pwNni/TvElSeBTRNSAQCgbz3Ibv0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FkXKru%2FbtsK64pwNni%2FTvElSeBTRNSAQCgbz3Ibv0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;608&quot; height=&quot;250&quot; data-origin-width=&quot;608&quot; data-origin-height=&quot;250&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;I2C 통신 회로&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;SDA 및 SCL 라인은 저항으로 끌어올려야 한다. 이 저항의 값은 버스 길이(버스 커패시턴스)와 전송 속도에 따라 달라진다. 보통 4.7K옴에서 10K옴 사이를 사용한다.&lt;br /&gt;위&amp;nbsp;I2C&amp;nbsp;통신&amp;nbsp;회로도를&amp;nbsp;&amp;nbsp;보면,&amp;nbsp;VDD(전원)&amp;nbsp;측에&amp;nbsp;Rp(저항)이&amp;nbsp;풀업으로&amp;nbsp;달려있는&amp;nbsp;것을&amp;nbsp;확인할&amp;nbsp;수&amp;nbsp;있다.&amp;nbsp;이는&amp;nbsp;IDLE&amp;nbsp;상태(통신을&amp;nbsp;하고&amp;nbsp;있지&amp;nbsp;않을&amp;nbsp;때)에서&amp;nbsp;신호가&amp;nbsp;HIGH&amp;nbsp;레벨을&amp;nbsp;유지하고&amp;nbsp;있으며,&amp;nbsp;통신을&amp;nbsp;개시하면&amp;nbsp;신호가&amp;nbsp;LOW&amp;nbsp;레벨로&amp;nbsp;떨어지는&amp;nbsp;것을&amp;nbsp;의미한다.&amp;nbsp;소프트웨어&amp;nbsp;구현하는&amp;nbsp;것도&amp;nbsp;중요하지만&amp;nbsp;I2C는&amp;nbsp;풀업&amp;nbsp;저항이&amp;nbsp;굉장히&amp;nbsp;중요하므로&amp;nbsp;이를&amp;nbsp;간과해서는&amp;nbsp;안된다.&amp;nbsp; &lt;br /&gt;&lt;br /&gt;​I2C는 세가지 모드를 지원한다. 대부분 I2C를 지원하는 MCU는 Fast Mode를 지원한다. &lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;최대 100kbit/s의 비트 전송률을 가진 표준 모드(Standard mode)&lt;/li&gt;
&lt;li&gt;최대 400kbit/s의 비트 전송 속도를 제공하는 Fm(Fast-Mode)&lt;/li&gt;
&lt;li&gt;최대 1Mbit/s의 비트 전송 속도를 제공하는 Fm+(Fast-Mode Plus)&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;  2. I2C 데이터 전송 포맷&lt;/h2&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock widthContent&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;481&quot; data-origin-height=&quot;124&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bHILro/btsK79jhGAC/y5lHfGuzV7yTIoLeIrAOWK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bHILro/btsK79jhGAC/y5lHfGuzV7yTIoLeIrAOWK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bHILro/btsK79jhGAC/y5lHfGuzV7yTIoLeIrAOWK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbHILro%2FbtsK79jhGAC%2Fy5lHfGuzV7yTIoLeIrAOWK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;481&quot; height=&quot;124&quot; data-origin-width=&quot;481&quot; data-origin-height=&quot;124&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;I2C 통신에서는 하기 신호들을 통해 마스터와 슬레이브가 통신을 한다.&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;Start Condition (&lt;i&gt;S&lt;/i&gt;)&lt;/li&gt;
&lt;li&gt;Stop Condition (&lt;i&gt;P&lt;/i&gt;)&lt;/li&gt;
&lt;li&gt;Repeated Start (Restart) Condition (&lt;i&gt;Sr&lt;/i&gt;)&lt;/li&gt;
&lt;li&gt;Acknowledge ACK (&lt;i&gt;A&lt;/i&gt;)&lt;/li&gt;
&lt;li&gt;Not Acknowledge NACK (&lt;i&gt;/A&lt;/i&gt;)&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;⚙️ 1. Start Condition (&lt;i&gt;S&lt;/i&gt;)&lt;/h3&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;Start Condition은 I2C 통신이 시작될 때 생성된다.&lt;/li&gt;
&lt;li&gt;마스터 장치가 데이터 전송을 시작할 때 SCL이 HIGH인 동안 SDA 라인이 HIGH에서 LOW로 전환된다.&lt;/li&gt;
&lt;li&gt;이&amp;nbsp;신호는&amp;nbsp;모든&amp;nbsp;슬레이브&amp;nbsp;장치에게&amp;nbsp;데이터&amp;nbsp;전송이&amp;nbsp;시작되었음을&amp;nbsp;알린다.&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;⚙️ 2. Stop Condition (&lt;i&gt;P&lt;/i&gt;)&lt;/h3&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;Stop Condition은 I2C 통신이 종료될 때 생성된다.&lt;/li&gt;
&lt;li&gt;마스터 장치가 데이터 전송을 종료할 때 SCL이 HIGH인 동안 SDA 라인이 LOW에서 HIGH로 전환된다.&lt;/li&gt;
&lt;li&gt;이 신호는 모든 슬레이브 장치에게 데이터 전송이 끝났음을 알린다.&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;⚙️ 3. Repeated Start (Restart) Condition (&lt;i&gt;Sr&lt;/i&gt;)&lt;/h3&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;Repeated Start Condition은 통신 중에 연속된 데이터 전송을 위해 사용된다.&lt;/li&gt;
&lt;li&gt;마스터 장치가 데이터 전송을 중단하지 않고 다음 전송을 시작하고자 할 때 사용된다.&lt;/li&gt;
&lt;li&gt;이는 일반적인 Start Condition과 동일하게 SCL이 HIGH인 동안 SDA 라인이 HIGH에서 LOW로 전환된다.&lt;/li&gt;
&lt;li&gt;Repeated Start는 슬레이브 장치에게 통신이 계속 진행 중임을 알리며, 새로운 주소나 데이터 전송을 시작할 수 있게 한다.&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;⚙️ 4. Acknowledge ACK (&lt;i&gt;A&lt;/i&gt;)&lt;/h3&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;Acknowledge는 수신 장치가 데이터를 성공적으로 수신했음을 나타내는 신호이다.&lt;/li&gt;
&lt;li&gt;데이터 바이트가 전송된 후 수신 장치는 SCL의 HIGH 동안 SDA 라인을 LOW로 유지하여 ACK 신호를 보낸다.&lt;/li&gt;
&lt;li&gt;이는 마스터에게 데이터가 올바르게 수신되었음을 알린다.&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;⚙️ 5. Not Acknowledge NACK (&lt;i&gt;/A&lt;/i&gt;)&lt;/h3&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;Not Acknowledge는 수신 장치가 데이터를 성공적으로 수신하지 못했거나 더 이상 데이터를 받을 준비가 되지 않았음을 나타내는 신호이다.&lt;/li&gt;
&lt;li&gt;데이터 바이트가 전송된 후 수신 장치는 SCL의 HIGH 동안 SDA 라인을 HIGH로 유지하여 NACK 신호를 보낸다.&lt;/li&gt;
&lt;li&gt;이는 마스터에게 데이터가 제대로 수신되지 않았음을 알리거나, 통신을 종료하도록 요청하는 신호이다.&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;  3. I2C 데이터 전송 시퀀스&lt;/h2&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock widthContent&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;745&quot; data-origin-height=&quot;192&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/ddDzgl/btsK7HgsRZH/nTNY1y066tC4zvmSe185Wk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/ddDzgl/btsK7HgsRZH/nTNY1y066tC4zvmSe185Wk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/ddDzgl/btsK7HgsRZH/nTNY1y066tC4zvmSe185Wk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FddDzgl%2FbtsK7HgsRZH%2FnTNY1y066tC4zvmSe185Wk%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;745&quot; height=&quot;192&quot; data-origin-width=&quot;745&quot; data-origin-height=&quot;192&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;b&gt;시작:&lt;/b&gt; Start Condition (&lt;i&gt;S&lt;/i&gt;)
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;주소 전송: 슬레이브 주소 (7비트) + R/W 비트 (0: Wirte)&lt;/li&gt;
&lt;li&gt;0x28u 주소를 가지는 슬레이브에게 Write를 하고 싶다면, 아래와 같이 주소를 쉬프트 하면 된다.&lt;/li&gt;
&lt;li&gt;0x28u &amp;lt;&amp;lt; 1 = 0x50u&lt;/li&gt;
&lt;li&gt;0x28u 주소를 가지는 슬레이브에게 Read를 하고 싶다면, 아래와 같이 주소를 쉬프트하고 LSB를 0x1로 OR 연산을 하면 된다.&lt;/li&gt;
&lt;li&gt;(0x28u &amp;lt;&amp;lt; 1) | 0x01u = 0x51u&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;b&gt;슬레이브 ACK:&lt;/b&gt; 슬레이브가 ACK 전송&lt;/li&gt;
&lt;li&gt;&lt;b&gt;데이터 전송:&lt;/b&gt; 데이터 바이트 (8비트)&lt;/li&gt;
&lt;li&gt;&lt;b&gt;슬레이브 ACK:&lt;/b&gt; 슬레이브가 ACK 전송&lt;/li&gt;
&lt;li&gt;&lt;b&gt;추가 데이터 전송 (필요 시):&lt;/b&gt; 반복적으로 데이터 바이트와 ACK 전송&lt;/li&gt;
&lt;li&gt;&lt;b&gt;종료:&lt;/b&gt; Stop Condition (&lt;i&gt;P&lt;/i&gt;)&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이해하고&amp;nbsp;나면&amp;nbsp;별거&amp;nbsp;없다.&amp;nbsp;STM32로&amp;nbsp;위&amp;nbsp;정보들을&amp;nbsp;이해할&amp;nbsp;수&amp;nbsp;있다면&amp;nbsp;충분히&amp;nbsp;MCU로&amp;nbsp;I2C&amp;nbsp;통신을&amp;nbsp;사용하는&amp;nbsp;센서들을&amp;nbsp;충분히&amp;nbsp;제어할&amp;nbsp;수&amp;nbsp;있다.&amp;nbsp;다음&amp;nbsp;글은&amp;nbsp;I2C&amp;nbsp;통신을&amp;nbsp;사용하는&amp;nbsp;센서&amp;nbsp;하나를&amp;nbsp;소개하고자&amp;nbsp;한다.&amp;nbsp;남들처럼&amp;nbsp;LCD&amp;nbsp;제어,&amp;nbsp;RTC,&amp;nbsp;EEPROM이&amp;nbsp;아닌&amp;nbsp;재미난걸&amp;nbsp;소개하려&amp;nbsp;한다.&amp;nbsp;&lt;/p&gt;</description>
      <category>  STM32</category>
      <category>i2c</category>
      <category>STM32</category>
      <category>개요</category>
      <category>설명</category>
      <category>이론</category>
      <author>18진수</author>
      <guid isPermaLink="true">https://coding-yoon.tistory.com/299</guid>
      <comments>https://coding-yoon.tistory.com/299#entry299comment</comments>
      <pubDate>Wed, 4 Dec 2024 23:23:41 +0900</pubDate>
    </item>
    <item>
      <title>[STM32] 14. 콜백 함수 호출 과정</title>
      <link>https://coding-yoon.tistory.com/298</link>
      <description>&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;600&quot; data-origin-height=&quot;600&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/evr7Zp/btsK2V0aDdg/ZiVUSISFWZA4RZ1vkkkBl1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/evr7Zp/btsK2V0aDdg/ZiVUSISFWZA4RZ1vkkkBl1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/evr7Zp/btsK2V0aDdg/ZiVUSISFWZA4RZ1vkkkBl1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fevr7Zp%2FbtsK2V0aDdg%2FZiVUSISFWZA4RZ1vkkkBl1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;600&quot; height=&quot;600&quot; data-origin-width=&quot;600&quot; data-origin-height=&quot;600&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이&amp;nbsp;전&amp;nbsp;포스팅에서&amp;nbsp;HAL&amp;nbsp;라이브러리가&amp;nbsp;제공하는&amp;nbsp;인터페이스(HAL_UART_RxCpltCallback)를&amp;nbsp;사용하여&amp;nbsp;UART&amp;nbsp;Interrupt를&amp;nbsp;간단한&amp;nbsp;기능을&amp;nbsp;구현하였다.&amp;nbsp;HAL_UART_RxCpltCallback&amp;nbsp;함수는&amp;nbsp;STM32&amp;nbsp;HAL&amp;nbsp;라이브러리에서&amp;nbsp;UART&amp;nbsp;데이터를&amp;nbsp;수신할&amp;nbsp;때&amp;nbsp;사용되는&amp;nbsp;콜백&amp;nbsp;함수이다.&amp;nbsp;이&amp;nbsp;함수는&amp;nbsp;UART&amp;nbsp;인터럽트를&amp;nbsp;사용하여&amp;nbsp;데이터를&amp;nbsp;비동기적으로&amp;nbsp;수신할&amp;nbsp;때&amp;nbsp;호출된다.&amp;nbsp;임베디드&amp;nbsp;시스템&amp;nbsp;관점에서&amp;nbsp;이&amp;nbsp;콜백&amp;nbsp;함수가&amp;nbsp;호출되는&amp;nbsp;과정을&amp;nbsp;간단히&amp;nbsp;설명하겠다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock widthContent&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1024&quot; data-origin-height=&quot;577&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/ddFIIJ/btsK1Qshl2v/3i6HE1hjpqv6MKSByRgsu0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/ddFIIJ/btsK1Qshl2v/3i6HE1hjpqv6MKSByRgsu0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/ddFIIJ/btsK1Qshl2v/3i6HE1hjpqv6MKSByRgsu0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FddFIIJ%2FbtsK1Qshl2v%2F3i6HE1hjpqv6MKSByRgsu0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1024&quot; height=&quot;577&quot; data-origin-width=&quot;1024&quot; data-origin-height=&quot;577&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;1. HAL_UART_RxCpltCallback 함수 호출 과정&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;1.&amp;nbsp;UART&amp;nbsp;인터럽트&amp;nbsp;활성화&lt;/b&gt;:&amp;nbsp;먼저,&amp;nbsp;UART&amp;nbsp;인터럽트를&amp;nbsp;활성화한다.&amp;nbsp;이는&amp;nbsp;HAL_UART_Receive_IT&amp;nbsp;함수를&amp;nbsp;호출하여&amp;nbsp;UART&amp;nbsp;모듈이&amp;nbsp;데이터를&amp;nbsp;수신할&amp;nbsp;때&amp;nbsp;인터럽트를&amp;nbsp;발생시킬&amp;nbsp;수&amp;nbsp;있도록&amp;nbsp;설정한다. &lt;br /&gt;&lt;br /&gt;이&amp;nbsp;동작은&amp;nbsp;소프트웨어적으로&amp;nbsp;수행되지만,&amp;nbsp;이&amp;nbsp;설정이&amp;nbsp;하드웨어&amp;nbsp;레벨에서&amp;nbsp;UART&amp;nbsp;인터럽트&amp;nbsp;기능을&amp;nbsp;활성화한다.&lt;/p&gt;
&lt;pre id=&quot;code_1732949119605&quot; class=&quot;cpp&quot; data-ke-language=&quot;cpp&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;HAL_UART_Receive_IT(&amp;amp;huart1, &amp;amp;received_byte, 1);&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;2. 데이터 수신 준비:&lt;/b&gt;&amp;nbsp;UART&amp;nbsp;모듈은&amp;nbsp;설정된&amp;nbsp;비트레이트,&amp;nbsp;데이터&amp;nbsp;비트,&amp;nbsp;패리티&amp;nbsp;비트&amp;nbsp;등을&amp;nbsp;기반으로&amp;nbsp;데이터를&amp;nbsp;수신할&amp;nbsp;준비를&amp;nbsp;한다. &lt;br /&gt;&lt;br /&gt;&lt;b&gt;3.&amp;nbsp;데이터&amp;nbsp;수신:&lt;/b&gt;&amp;nbsp;UART&amp;nbsp;모듈이&amp;nbsp;데이터를&amp;nbsp;수신(UART&amp;nbsp;모듈의&amp;nbsp;Rx&amp;nbsp;핀으로&amp;nbsp;시리얼&amp;nbsp;데이터가&amp;nbsp;들어옴)하면,&amp;nbsp;수신&amp;nbsp;버퍼에&amp;nbsp;데이터가&amp;nbsp;저장된다.&amp;nbsp;UART&amp;nbsp;모듈은&amp;nbsp;수신이&amp;nbsp;완료되었음을&amp;nbsp;알리기&amp;nbsp;위해&amp;nbsp;UART&amp;nbsp;인터럽트를&amp;nbsp;발생시킨다. &lt;br /&gt;&lt;br /&gt;&lt;b&gt;4.&amp;nbsp;인터럽트&amp;nbsp;발생:&lt;/b&gt;&amp;nbsp;UART&amp;nbsp;데이터&amp;nbsp;수신이&amp;nbsp;완료되면,&amp;nbsp;UART&amp;nbsp;하드웨어는&amp;nbsp;인터럽트를&amp;nbsp;발생시킨다.&amp;nbsp;이&amp;nbsp;인터럽트는&amp;nbsp;프로세서를&amp;nbsp;중단시키고&amp;nbsp;인터럽트&amp;nbsp;서비스&amp;nbsp;루틴(ISR)으로&amp;nbsp;제어를&amp;nbsp;이동시킨다. &lt;br /&gt;&lt;br /&gt;&lt;b&gt;5.&amp;nbsp;인터럽트&amp;nbsp;서비스&amp;nbsp;루틴(ISR):&lt;/b&gt;&amp;nbsp;USARTx_IRQHandler&amp;nbsp;함수는&amp;nbsp;UART&amp;nbsp;인터럽트가&amp;nbsp;발생했을&amp;nbsp;때&amp;nbsp;호출되는&amp;nbsp;ISR이다.&amp;nbsp;이&amp;nbsp;함수는&amp;nbsp;HAL&amp;nbsp;라이브러리의&amp;nbsp;HAL_UART_IRQHandler&amp;nbsp;함수를&amp;nbsp;호출하여&amp;nbsp;인터럽트를&amp;nbsp;처리한다.&amp;nbsp;(MCU의&amp;nbsp;현재&amp;nbsp;실행을&amp;nbsp;중단시키고,&amp;nbsp;관련&amp;nbsp;인터럽트&amp;nbsp;벡터로&amp;nbsp;제어를&amp;nbsp;이동시킨다.)&lt;/p&gt;
&lt;pre id=&quot;code_1732949186132&quot; class=&quot;cpp&quot; data-ke-language=&quot;cpp&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;void USART1_IRQHandler(void)
{
    HAL_UART_IRQHandler(&amp;amp;huart1);
}&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;6.&amp;nbsp;콜백&amp;nbsp;함수&amp;nbsp;호출:&lt;/b&gt;&amp;nbsp;HAL_UART_IRQHandler&amp;nbsp;함수는&amp;nbsp;인터럽트를&amp;nbsp;처리하는&amp;nbsp;동안,&amp;nbsp;데이터&amp;nbsp;수신이&amp;nbsp;완료되었음을&amp;nbsp;감지하고&amp;nbsp;HAL_UART_RxCpltCallback&amp;nbsp;콜백&amp;nbsp;함수를&amp;nbsp;호출한다.&lt;/p&gt;
&lt;pre id=&quot;code_1732949794348&quot; class=&quot;cpp&quot; data-ke-language=&quot;cpp&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;void HAL_UART_IRQHandler(UART_HandleTypeDef *huart)
{
    // 인터럽트 처리 코드
    // ...

    if (/* 수신 완료 조건 */)
    {
        HAL_UART_RxCpltCallback(huart);
    }
}&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;7.&amp;nbsp;콜백&amp;nbsp;함수&amp;nbsp;실행:&amp;nbsp;&lt;/b&gt;HAL_UART_RxCpltCallback&amp;nbsp;함수는&amp;nbsp;사용자가&amp;nbsp;정의한&amp;nbsp;동작을&amp;nbsp;수행한다.&amp;nbsp;예를&amp;nbsp;들어,&amp;nbsp;수신된&amp;nbsp;데이터를&amp;nbsp;처리하고,&amp;nbsp;다음&amp;nbsp;데이터를&amp;nbsp;수신하기&amp;nbsp;위해&amp;nbsp;HAL_UART_Receive_IT&amp;nbsp;함수를&amp;nbsp;다시&amp;nbsp;호출하여&amp;nbsp;인터럽트를&amp;nbsp;재설정할&amp;nbsp;수&amp;nbsp;있다.&lt;/p&gt;
&lt;pre id=&quot;code_1732949830820&quot; class=&quot;cpp&quot; data-ke-language=&quot;cpp&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart)
{
    if (huart-&amp;gt;Instance == USART1)
    {
        // 수신된 데이터를 처리하는 코드
        // ...

        // 다음 수신을 위한 인터럽트 재설정
        HAL_UART_Receive_IT(huart, &amp;amp;received_byte, 1);
    }
}&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이&amp;nbsp;과정은&amp;nbsp;UART&amp;nbsp;데이터를&amp;nbsp;비동기적으로&amp;nbsp;수신하고&amp;nbsp;처리하는&amp;nbsp;방법을&amp;nbsp;간단히&amp;nbsp;설명한&amp;nbsp;것이다.&amp;nbsp;HAL_UART_RxCpltCallback&amp;nbsp;콜백&amp;nbsp;함수는&amp;nbsp;데이터&amp;nbsp;수신이&amp;nbsp;완료될&amp;nbsp;때마다&amp;nbsp;자동으로&amp;nbsp;호출되며,&amp;nbsp;이를&amp;nbsp;통해&amp;nbsp;데이터를&amp;nbsp;효율적으로&amp;nbsp;처리할&amp;nbsp;수&amp;nbsp;있다.&lt;/p&gt;</description>
      <category>  STM32</category>
      <category>Callback</category>
      <category>STM32</category>
      <category>과정</category>
      <category>함수</category>
      <category>호출</category>
      <author>18진수</author>
      <guid isPermaLink="true">https://coding-yoon.tistory.com/298</guid>
      <comments>https://coding-yoon.tistory.com/298#entry298comment</comments>
      <pubDate>Sat, 30 Nov 2024 15:57:49 +0900</pubDate>
    </item>
    <item>
      <title>[STM32] 13. UART Interrupt 구현</title>
      <link>https://coding-yoon.tistory.com/297</link>
      <description>&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;600&quot; data-origin-height=&quot;600&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/xlKvI/btsK2wfnnS5/LyEKZD03odNkuZshXMlo0K/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/xlKvI/btsK2wfnnS5/LyEKZD03odNkuZshXMlo0K/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/xlKvI/btsK2wfnnS5/LyEKZD03odNkuZshXMlo0K/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FxlKvI%2FbtsK2wfnnS5%2FLyEKZD03odNkuZshXMlo0K%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;600&quot; height=&quot;600&quot; data-origin-width=&quot;600&quot; data-origin-height=&quot;600&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;UART&amp;nbsp;통신에서&amp;nbsp;Polling&amp;nbsp;방식은&amp;nbsp;간단하지만&amp;nbsp;효율성이&amp;nbsp;떨어질&amp;nbsp;수&amp;nbsp;있다.&amp;nbsp;이를&amp;nbsp;해결하기&amp;nbsp;위해&amp;nbsp;Interrupt&amp;nbsp;방식과&amp;nbsp;DMA&amp;nbsp;방식을&amp;nbsp;사용할&amp;nbsp;수&amp;nbsp;있다.&amp;nbsp;이&amp;nbsp;번&amp;nbsp;포스팅은&amp;nbsp;Interrupt&amp;nbsp;방식을&amp;nbsp;통해&amp;nbsp;이&amp;nbsp;전&amp;nbsp;포스팅인&amp;nbsp;Polling&amp;nbsp;방식&amp;nbsp;기능을&amp;nbsp;그대로&amp;nbsp;구현하는&amp;nbsp;방식으로&amp;nbsp;진행한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이전&amp;nbsp;포스팅&amp;nbsp;:&amp;nbsp;&lt;a href=&quot;https://blog.naver.com/younjung1996/223477638132&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://blog.naver.com/younjung1996/223477638132&lt;/a&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1732947628867&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-ke-align=&quot;alignCenter&quot; data-og-type=&quot;article&quot; data-og-title=&quot;12. STM32 시리얼 모니터를 위한 UART 통신 구현 (2)&quot; data-og-description=&quot;기본적인 UART 통신은 폴링(Polling) 방식으로 수행할 수 있다. 폴링 방식에서는 MCU가 계속해서 ...&quot; data-og-host=&quot;blog.naver.com&quot; data-og-source-url=&quot;https://blog.naver.com/younjung1996/223477638132&quot; data-og-url=&quot;https://blog.naver.com/younjung1996/223477638132&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/t5w1m/hyXDfTsz6G/9vdBYwf3Nc997fpSYFftdk/img.png?width=600&amp;amp;height=600&amp;amp;face=0_0_600_600&quot;&gt;&lt;a href=&quot;https://blog.naver.com/younjung1996/223477638132&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://blog.naver.com/younjung1996/223477638132&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/t5w1m/hyXDfTsz6G/9vdBYwf3Nc997fpSYFftdk/img.png?width=600&amp;amp;height=600&amp;amp;face=0_0_600_600');&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot; data-ke-size=&quot;size16&quot;&gt;12. STM32 시리얼 모니터를 위한 UART 통신 구현 (2)&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;기본적인 UART 통신은 폴링(Polling) 방식으로 수행할 수 있다. 폴링 방식에서는 MCU가 계속해서 ...&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;blog.naver.com&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;사용된&amp;nbsp;보드는&amp;nbsp;STM32F103이며,&amp;nbsp;UART&amp;nbsp;1번을&amp;nbsp;사용한다.&amp;nbsp;(&lt;b&gt;PA10&lt;/b&gt;&amp;nbsp;-&amp;nbsp;UART1_RX,&amp;nbsp;&lt;b&gt;PA9&lt;/b&gt;&amp;nbsp;-&amp;nbsp;UART1_TX)&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;  1. Polling 방식의 문제점&lt;/h3&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;b&gt;CPU 자원 소모:&lt;/b&gt; Polling 방식에서는 CPU가 지속적으로 UART 상태 레지스터를 확인해야 한다. 이는 CPU 자원을 많이 소모하여 다른 작업을 수행할 시간이 줄어든다.&lt;/li&gt;
&lt;li&gt;&lt;b&gt;응답 시간 지연:&lt;/b&gt; 데이터가 준비될 때까지 대기해야 하므로, 실시간 응답이 필요한 시스템에서는 비효율적이다.&lt;/li&gt;
&lt;li&gt;&lt;b&gt;전력 소모:&lt;/b&gt; CPU가 계속해서 UART 상태를 확인해야 하므로, 저전력 모드로 전환하기 어렵다.&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size23&quot;&gt;  2. Interrupt 방식&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Interrupt&amp;nbsp;방식은&amp;nbsp;UART&amp;nbsp;전송이나&amp;nbsp;수신이&amp;nbsp;완료될&amp;nbsp;때마다&amp;nbsp;인터럽트가&amp;nbsp;발생하여,&amp;nbsp;인터럽트&amp;nbsp;서비스&amp;nbsp;루틴(ISR)이&amp;nbsp;실행되어&amp;nbsp;데이터를&amp;nbsp;처리한다.&amp;nbsp;이는&amp;nbsp;Polling&amp;nbsp;방식의&amp;nbsp;문제점을&amp;nbsp;해결할&amp;nbsp;수&amp;nbsp;있다. &lt;br /&gt;&lt;br /&gt;장점&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;효율적인 CPU 사용: 데이터 전송이나 수신이 완료될 때까지 CPU가 다른 작업을 수행할 수 있다.&lt;/li&gt;
&lt;li&gt;실시간 처리: 데이터 전송이나 수신이 완료될 때 즉시 인터럽트가 발생하여 실시간으로 데이터를 처리할 수 있다.&lt;/li&gt;
&lt;li&gt;전력 절감: CPU가 필요할 때만 깨어나므로, 저전력 모드로 전환하기 쉽다.&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;단점&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;구현 복잡성: 인터럽트 기반 코드는 Polling 방식보다 구현이 다소 복잡할 수 있다.&lt;/li&gt;
&lt;li&gt;인터럽트 오버헤드: 인터럽트가 빈번하게 발생하면 인터럽트 오버헤드가 발생할 수 있다.&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size23&quot;&gt;⚙️ 3. 레지스터 설정&lt;/h3&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock widthContent&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;960&quot; data-origin-height=&quot;656&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cPPz5I/btsK2DFonxE/XrxHq2CGNBGmaphrLSoQT0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cPPz5I/btsK2DFonxE/XrxHq2CGNBGmaphrLSoQT0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cPPz5I/btsK2DFonxE/XrxHq2CGNBGmaphrLSoQT0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FcPPz5I%2FbtsK2DFonxE%2FXrxHq2CGNBGmaphrLSoQT0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;960&quot; height=&quot;656&quot; data-origin-width=&quot;960&quot; data-origin-height=&quot;656&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;[Pin&amp;amp;Out&amp;nbsp;Configuration]&amp;nbsp;-&amp;nbsp;[Connectivity]&amp;nbsp;-&amp;nbsp;[USART1]을&amp;nbsp;설정하는&amp;nbsp;것은&amp;nbsp;이전&amp;nbsp;포스팅(Polling&amp;nbsp;방식)과&amp;nbsp;동일하다.&amp;nbsp;다만,&amp;nbsp;차이가&amp;nbsp;있다면&amp;nbsp;global&amp;nbsp;interrupt를&amp;nbsp;활성화시켜&amp;nbsp;주어야&amp;nbsp;한다. &lt;br /&gt;&lt;br /&gt;[Pin&amp;amp;Out&amp;nbsp;Configuration]&amp;nbsp;-&amp;nbsp;[System&amp;nbsp;Core]&amp;nbsp;-&amp;nbsp;[NVIC]&amp;nbsp;-&amp;nbsp;[USART1&amp;nbsp;global&amp;nbsp;Interrupt]&amp;nbsp;-&amp;nbsp;Enabled&amp;nbsp;체크&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock widthContent&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;957&quot; data-origin-height=&quot;661&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/by4kDb/btsK2x6fYGl/tguXSUxIhxaPm9yH8jKB90/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/by4kDb/btsK2x6fYGl/tguXSUxIhxaPm9yH8jKB90/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/by4kDb/btsK2x6fYGl/tguXSUxIhxaPm9yH8jKB90/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fby4kDb%2FbtsK2x6fYGl%2FtguXSUxIhxaPm9yH8jKB90%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;957&quot; height=&quot;661&quot; data-origin-width=&quot;957&quot; data-origin-height=&quot;661&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;위&amp;nbsp;처럼&amp;nbsp;설정을&amp;nbsp;완료했다면,&amp;nbsp;UART&amp;nbsp;Interrupt를&amp;nbsp;사용할&amp;nbsp;준비가&amp;nbsp;끝났다.&amp;nbsp;&lt;/p&gt;
&lt;h3 style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size23&quot;&gt;⚙️ 4. 코드&lt;/h3&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;249&quot; data-origin-height=&quot;332&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/XZlQq/btsK3RCIHnh/tlVG6c42KRmYE0VenakeL0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/XZlQq/btsK3RCIHnh/tlVG6c42KRmYE0VenakeL0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/XZlQq/btsK3RCIHnh/tlVG6c42KRmYE0VenakeL0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FXZlQq%2FbtsK3RCIHnh%2FtlVG6c42KRmYE0VenakeL0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;249&quot; height=&quot;332&quot; data-origin-width=&quot;249&quot; data-origin-height=&quot;332&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;[Core]&amp;nbsp;-[Src]&amp;nbsp;-&amp;nbsp;[stm32f1xx_it.c&amp;nbsp;파일]에&amp;nbsp;USART1_IRQHandler&amp;nbsp;함수에&amp;nbsp;UART1이&amp;nbsp;연결되어있는&amp;nbsp;것을&amp;nbsp;확인할&amp;nbsp;수&amp;nbsp;있다.&amp;nbsp;해당&amp;nbsp;함수에서&amp;nbsp;인터럽트&amp;nbsp;핸들러에&amp;nbsp;직접&amp;nbsp;코드를&amp;nbsp;작성하여&amp;nbsp;수동으로&amp;nbsp;관리할&amp;nbsp;수&amp;nbsp;있으나&amp;nbsp;복잡성이&amp;nbsp;증가할&amp;nbsp;수&amp;nbsp;있고,&amp;nbsp;다른&amp;nbsp;STM32&amp;nbsp;시리즈에서는&amp;nbsp;사용할&amp;nbsp;수&amp;nbsp;없는&amp;nbsp;문제가&amp;nbsp;발생할&amp;nbsp;수&amp;nbsp;있으므로&amp;nbsp;이는&amp;nbsp;추천하지&amp;nbsp;않는&amp;nbsp;방법이다.&lt;/p&gt;
&lt;pre id=&quot;code_1732948067465&quot; class=&quot;cpp&quot; data-ke-language=&quot;cpp&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;/**
  * @brief This function handles USART1 global interrupt.
  */
void USART1_IRQHandler(void)
{
  /* USER CODE BEGIN USART1_IRQn 0 */

  /* USER CODE END USART1_IRQn 0 */
  HAL_UART_IRQHandler(&amp;amp;huart1);
  /* USER CODE BEGIN USART1_IRQn 1 */

  /* USER CODE END USART1_IRQn 1 */
}&lt;/code&gt;&lt;/pre&gt;
&lt;p id=&quot;SE-ae92e947-d020-4caa-b45f-c2f18e0bea88&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;추천하는 방법으로 HAL 라이브러리가 아래와 같이 제공하는 하드웨어 인터페이스를 사용하는 것이다. (이번 포스팅은 HAL_UART_RxCpltCallback 콜백함수만 사용할 예정이다.)&lt;/span&gt;&lt;/p&gt;
&lt;p id=&quot;SE-87f694e7-3b13-4420-accb-edbe590e3c8b&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;HAL_UART_RxCpltCallback, HAL_UART_TxCpltCallback&lt;/span&gt;&lt;/p&gt;
&lt;p id=&quot;SE-21c62c3a-90b3-49ff-8033-10f6d2800a4c&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;콜백함수의 장점은 아래와 같다.&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;추상화와 유연성: HAL 라이브러리는 하드웨어 추상화 계층을 제공하여 다양한 STM32 장치에서 일관된 인터페이스를 제공한다. HAL_UART_RxCpltCallback을 사용하면 코드가 더 유연하고 이식성이 높아진다.&lt;/li&gt;
&lt;li&gt;안정성: HAL 라이브러리는 많은 경우에 대해 이미 검증되어 있으며, 잘 테스트된 코드를 제공한다. 직접 인터럽트 핸들러에서 코드를 작성하는 것보다 안정적이다.&lt;/li&gt;
&lt;li&gt;코드 유지보수: 콜백을 사용하면 코드가 더 모듈화되어 유지보수가 용이하다. 인터럽트 핸들러는 보통 HAL 라이브러리에서 관리하므로, 콜백 함수만 관리하면 된다.&lt;/li&gt;
&lt;li&gt;중첩 인터럽트 관리: HAL 라이브러리는 중첩 인터럽트를 관리하는 기능을 제공하므로, 콜백 함수 내에서 추가적인 처리를 수행할 때 안전하다. &lt;br /&gt;&lt;br /&gt;콜백함수&amp;nbsp;사용하는&amp;nbsp;방법은&amp;nbsp;간단하다.&amp;nbsp; &lt;br /&gt;&lt;br /&gt;&lt;/li&gt;
&lt;li&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;258&quot; data-origin-height=&quot;364&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/2g6zV/btsK2vnjw01/zmBVH2IsUSXsThRVRBX1UK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/2g6zV/btsK2vnjw01/zmBVH2IsUSXsThRVRBX1UK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/2g6zV/btsK2vnjw01/zmBVH2IsUSXsThRVRBX1UK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2F2g6zV%2FbtsK2vnjw01%2FzmBVH2IsUSXsThRVRBX1UK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;258&quot; height=&quot;364&quot; data-origin-width=&quot;258&quot; data-origin-height=&quot;364&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;[Driver] - [stm32f1xx_hal_uart.c]에서 정의된 콜백함수를 찾을 수 있다.&lt;/p&gt;
&lt;pre id=&quot;code_1732948233847&quot; class=&quot;cpp&quot; data-ke-language=&quot;cpp&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;/**
  * @brief  Rx Transfer completed callbacks.
  * @param  huart  Pointer to a UART_HandleTypeDef structure that contains
  *                the configuration information for the specified UART module.
  * @retval None
  */
__weak void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart)
{
  /* Prevent unused argument(s) compilation warning */
  UNUSED(huart);
  /* NOTE: This function should not be modified, when the callback is needed,
           the HAL_UART_RxCpltCallback could be implemented in the user file
   */
}&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;해당&amp;nbsp;콜백함수를&amp;nbsp;main&amp;nbsp;함수에서&amp;nbsp;재정의하여&amp;nbsp;사용하면&amp;nbsp;된다.&lt;/p&gt;
&lt;pre id=&quot;code_1732948266159&quot; class=&quot;cpp&quot; data-ke-language=&quot;cpp&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;/* Private function prototypes -----------------------------------------------*/
void SystemClock_Config(void);
static void MX_GPIO_Init(void);
static void MX_USART1_UART_Init(void);
void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart);
/* USER CODE BEGIN PFP */

/* USER CODE END PFP */

/* Private user code ---------------------------------------------------------*/
/* USER CODE BEGIN 0 */
// Define buffer
#define MAX_BUFFER_SIZE 100
uint8_t enterKey = '\r'; // Enter key is carriage return (0x0D)
uint8_t inputBuffer[MAX_BUFFER_SIZE];
uint16_t bufferIndex = 0;
uint8_t received_byte;

...
...
...

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 */

  /* 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_USART1_UART_Init();
  /* USER CODE BEGIN 2 */
  HAL_UART_Receive_IT(&amp;amp;huart1, &amp;amp;received_byte, 1);
  /* USER CODE END 2 */

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

    /* USER CODE BEGIN 3 */
  }
  /* USER CODE END 3 */
}

...
...
...

/* USER CODE BEGIN 4 */
void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart)
{
    if (huart-&amp;gt;Instance == USART1)
    {
        if (received_byte == enterKey)
        {
            // 스페이스바 입력 시 버퍼에 저장된 문자열 출력
        	HAL_UART_Transmit_IT(&amp;amp;huart1, inputBuffer, bufferIndex);
            // 새로운 줄 추가
            uint8_t newline[] = &quot;\r\n&quot;;
            HAL_UART_Transmit_IT(&amp;amp;huart1, newline, 2);
            // 버퍼 인덱스 초기화
            bufferIndex = 0;
        }
        else
        {
            // 버퍼에 문자 저장
            if (bufferIndex &amp;lt; MAX_BUFFER_SIZE)
            {
                inputBuffer[bufferIndex++] = received_byte;
            }
        }

        // 다음 문자 수신 시작
        HAL_UART_Receive_IT(&amp;amp;huart1, &amp;amp;received_byte, 1);
    }
}

// UART transmit complete callback function
void HAL_UART_TxCpltCallback(UART_HandleTypeDef *huart)
{
	/* Reserved */
}
/* USER CODE END 4 */&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;테스트했을&amp;nbsp;때&amp;nbsp;제대로&amp;nbsp;동작하는&amp;nbsp;것을&amp;nbsp;확인할&amp;nbsp;수&amp;nbsp;있다. &lt;br /&gt;&lt;br /&gt;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock widthContent&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;966&quot; data-origin-height=&quot;695&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bDglNM/btsK1WltM5o/mJPtHJsRqNgfLhqgJCE1A0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bDglNM/btsK1WltM5o/mJPtHJsRqNgfLhqgJCE1A0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bDglNM/btsK1WltM5o/mJPtHJsRqNgfLhqgJCE1A0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbDglNM%2FbtsK1WltM5o%2FmJPtHJsRqNgfLhqgJCE1A0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;966&quot; height=&quot;695&quot; data-origin-width=&quot;966&quot; data-origin-height=&quot;695&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;HAL_UART_RxCpltCallback를&amp;nbsp;재정의&amp;nbsp;해주면,&amp;nbsp;간단하게&amp;nbsp;UART&amp;nbsp;Interrupt를&amp;nbsp;구현할&amp;nbsp;수&amp;nbsp;있다.&amp;nbsp; &lt;br /&gt;&lt;br /&gt;다음&amp;nbsp;포스팅은&amp;nbsp;UART&amp;nbsp;Interrupt&amp;nbsp;동작&amp;nbsp;순서에&amp;nbsp;대해&amp;nbsp;자세히&amp;nbsp;포스팅해볼&amp;nbsp;예정이다.&lt;/p&gt;</description>
      <category>  STM32</category>
      <category>interrupt</category>
      <category>polling</category>
      <category>UART</category>
      <category>구현</category>
      <category>방식</category>
      <category>설계</category>
      <category>코드</category>
      <author>18진수</author>
      <guid isPermaLink="true">https://coding-yoon.tistory.com/297</guid>
      <comments>https://coding-yoon.tistory.com/297#entry297comment</comments>
      <pubDate>Sat, 30 Nov 2024 15:37:15 +0900</pubDate>
    </item>
    <item>
      <title>[BLE 실내 측위 프로젝트] 7. NRF51822 비콘 테스트 및 초기 설정</title>
      <link>https://coding-yoon.tistory.com/296</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;드디어&amp;nbsp;알리에서&amp;nbsp;구매한&amp;nbsp;NRF51822&amp;nbsp;BLE4.2&amp;nbsp;비콘이&amp;nbsp;도착했다.&amp;nbsp;개당&amp;nbsp;6000원에&amp;nbsp;배터리&amp;nbsp;4개&amp;nbsp;정도&amp;nbsp;해서&amp;nbsp;3만&amp;nbsp;원&amp;nbsp;정도에&amp;nbsp;구매했다.&amp;nbsp;다음&amp;nbsp;글로&amp;nbsp;삼변측량에&amp;nbsp;대해&amp;nbsp;포스팅할&amp;nbsp;예정이지만,&amp;nbsp;비콘으로&amp;nbsp;실내&amp;nbsp;측위를&amp;nbsp;위해선&amp;nbsp;최소&amp;nbsp;3개의&amp;nbsp;비콘이&amp;nbsp;필요하다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;448&quot; data-origin-height=&quot;437&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/wUrpz/btsKV10J2eo/enaU7pzm3ULNCxPf7dWdQ1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/wUrpz/btsKV10J2eo/enaU7pzm3ULNCxPf7dWdQ1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/wUrpz/btsKV10J2eo/enaU7pzm3ULNCxPf7dWdQ1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FwUrpz%2FbtsKV10J2eo%2FenaU7pzm3ULNCxPf7dWdQ1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;448&quot; height=&quot;437&quot; data-origin-width=&quot;448&quot; data-origin-height=&quot;437&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;조립은 간단하다 배터리 장착 후 나사 3개만 조여주면 된다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;822&quot; data-origin-height=&quot;359&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/UWyZi/btsKVvnCX5T/EWRRB78SvNFpcLiR0AJ7lk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/UWyZi/btsKVvnCX5T/EWRRB78SvNFpcLiR0AJ7lk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/UWyZi/btsKVvnCX5T/EWRRB78SvNFpcLiR0AJ7lk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FUWyZi%2FbtsKVvnCX5T%2FEWRRB78SvNFpcLiR0AJ7lk%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;822&quot; height=&quot;359&quot; data-origin-width=&quot;822&quot; data-origin-height=&quot;359&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;beacon&amp;nbsp;구매&amp;nbsp;후&amp;nbsp;beacon을&amp;nbsp;초기&amp;nbsp;설정할&amp;nbsp;필요가&amp;nbsp;있다.&amp;nbsp;설정&amp;nbsp;방법은&amp;nbsp;제작사에서&amp;nbsp;제공하는&amp;nbsp;Holyiot-beacon을&amp;nbsp;설치하면&amp;nbsp;된다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;283&quot; data-origin-height=&quot;406&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bRIKNm/btsKWUUg6qo/zyessurdvxDTxfpd3BcL7k/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bRIKNm/btsKWUUg6qo/zyessurdvxDTxfpd3BcL7k/img.png&quot; data-alt=&quot;Holyiot-beacon&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bRIKNm/btsKWUUg6qo/zyessurdvxDTxfpd3BcL7k/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbRIKNm%2FbtsKWUUg6qo%2FzyessurdvxDTxfpd3BcL7k%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;283&quot; height=&quot;406&quot; data-origin-width=&quot;283&quot; data-origin-height=&quot;406&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;Holyiot-beacon&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;우선, 하나의 비콘만 동작 중이며 다운로드한 앱을 실행할 경우 아래와 같이 화면에 표시된다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;287&quot; data-origin-height=&quot;332&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/Uwm9Z/btsKVTWgDEW/tpYc4mfhCheRWZPPl7t3Sk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/Uwm9Z/btsKVTWgDEW/tpYc4mfhCheRWZPPl7t3Sk/img.png&quot; data-alt=&quot;Device Scanner&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/Uwm9Z/btsKVTWgDEW/tpYc4mfhCheRWZPPl7t3Sk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FUwm9Z%2FbtsKVTWgDEW%2FtpYc4mfhCheRWZPPl7t3Sk%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;287&quot; height=&quot;332&quot; data-origin-width=&quot;287&quot; data-origin-height=&quot;332&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;Device Scanner&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;비콘의&amp;nbsp;연결을&amp;nbsp;위해선&amp;nbsp;최초의&amp;nbsp;비밀번호를&amp;nbsp;요구한다.&amp;nbsp;내가&amp;nbsp;구매한&amp;nbsp;비콘의&amp;nbsp;경우&amp;nbsp;초기&amp;nbsp;비밀번호는&amp;nbsp;aa14061112&amp;nbsp;이다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;288&quot; data-origin-height=&quot;385&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/WkAuE/btsKVACxx72/gDM5dsN3iwqnWiWK0f1M70/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/WkAuE/btsKVACxx72/gDM5dsN3iwqnWiWK0f1M70/img.png&quot; data-alt=&quot;Password&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/WkAuE/btsKVACxx72/gDM5dsN3iwqnWiWK0f1M70/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FWkAuE%2FbtsKVACxx72%2FgDM5dsN3iwqnWiWK0f1M70%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;288&quot; height=&quot;385&quot; data-origin-width=&quot;288&quot; data-origin-height=&quot;385&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;Password&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;비콘을&amp;nbsp;연결하고&amp;nbsp;나면,&amp;nbsp;password,&amp;nbsp;major,&amp;nbsp;minor,&amp;nbsp;MAC&amp;nbsp;주소&amp;nbsp;등&amp;nbsp;다양한&amp;nbsp;값을&amp;nbsp;변경할&amp;nbsp;수&amp;nbsp;있다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;300&quot; data-origin-height=&quot;409&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/O7juY/btsKVzKs99o/UCCgmnTBmk9Y7rFYOmBOmK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/O7juY/btsKVzKs99o/UCCgmnTBmk9Y7rFYOmBOmK/img.png&quot; data-alt=&quot;Feature List&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/O7juY/btsKVzKs99o/UCCgmnTBmk9Y7rFYOmBOmK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FO7juY%2FbtsKVzKs99o%2FUCCgmnTBmk9Y7rFYOmBOmK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;300&quot; height=&quot;409&quot; data-origin-width=&quot;300&quot; data-origin-height=&quot;409&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;Feature List&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;내게 필요한 정보는 name, Tx Power, advertising interval이며, 변경할 수 있다. 아직은 Tx power와 advertisng interval은 필요 없으므로 건들지 않고, 비콘을 구별하기 위해 이름을 변경한다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;296&quot; data-origin-height=&quot;375&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/b4OD8k/btsKV17p7Kl/h91duDaFyDmKj2siv7S2vK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/b4OD8k/btsKV17p7Kl/h91duDaFyDmKj2siv7S2vK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/b4OD8k/btsKV17p7Kl/h91duDaFyDmKj2siv7S2vK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fb4OD8k%2FbtsKV17p7Kl%2Fh91duDaFyDmKj2siv7S2vK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;296&quot; height=&quot;375&quot; data-origin-width=&quot;296&quot; data-origin-height=&quot;375&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;아래&amp;nbsp;그림과&amp;nbsp;같이&amp;nbsp;이름을&amp;nbsp;Anchor0로&amp;nbsp;변경했다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;289&quot; data-origin-height=&quot;312&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/c8bKaW/btsKW7soRgK/14o2DTjdTfm2QBnfLdCjfk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/c8bKaW/btsKW7soRgK/14o2DTjdTfm2QBnfLdCjfk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/c8bKaW/btsKW7soRgK/14o2DTjdTfm2QBnfLdCjfk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fc8bKaW%2FbtsKW7soRgK%2F14o2DTjdTfm2QBnfLdCjfk%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;289&quot; height=&quot;312&quot; data-origin-width=&quot;289&quot; data-origin-height=&quot;312&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이제&amp;nbsp;위&amp;nbsp;세&amp;nbsp;개의&amp;nbsp;비콘으로&amp;nbsp;실내&amp;nbsp;측위&amp;nbsp;프로젝트를&amp;nbsp;수행할&amp;nbsp;예정이다.&lt;/p&gt;</description>
      <category> Project/✅ BLE Indoor Positioning</category>
      <category>anchor</category>
      <category>BLE</category>
      <category>nrf51822</category>
      <category>비밀번호</category>
      <category>비콘</category>
      <category>설정</category>
      <category>초기테스트</category>
      <author>18진수</author>
      <guid isPermaLink="true">https://coding-yoon.tistory.com/296</guid>
      <comments>https://coding-yoon.tistory.com/296#entry296comment</comments>
      <pubDate>Mon, 25 Nov 2024 23:45:38 +0900</pubDate>
    </item>
    <item>
      <title>[BLE 실내 측위 프로젝트] 6. RSSI 변동을 해결하기 위한 이동 평균 필터</title>
      <link>https://coding-yoon.tistory.com/295</link>
      <description>&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;762&quot; data-origin-height=&quot;408&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/19RPb/btsKVqtqpS6/B5huoz5gMbCWXv2D9EIxnK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/19RPb/btsKVqtqpS6/B5huoz5gMbCWXv2D9EIxnK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/19RPb/btsKVqtqpS6/B5huoz5gMbCWXv2D9EIxnK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2F19RPb%2FbtsKVqtqpS6%2FB5huoz5gMbCWXv2D9EIxnK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;762&quot; height=&quot;408&quot; data-origin-width=&quot;762&quot; data-origin-height=&quot;408&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;BLE&amp;nbsp;RSSI의&amp;nbsp;문제점은&amp;nbsp;위&amp;nbsp;그림과&amp;nbsp;같다.&lt;/p&gt;
&lt;ol style=&quot;list-style-type: decimal;&quot; data-ke-list-type=&quot;decimal&quot;&gt;
&lt;li&gt;4.5m 이상에서는 제대로 된 거리를 계산할 수 없음. (나중에는 통신 거리가 더 길어진 BLE5.0에 대해 알아볼 예정)&lt;/li&gt;
&lt;li&gt;실제 환경에서는 많은 외부 요인으로 인해 RSSI 변동이 발생해 거리의 오차가 발생함.&lt;/li&gt;
&lt;/ol&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;  1. 이동 평균 필터&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;RSSI 변동을 해결하기 위한 방법은 여러 가지가 있는데 그 중 가장 간단한 이동평균 필터이다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;602&quot; data-origin-height=&quot;333&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bkzBZ0/btsKW7MGWxC/iTXm8e4sEwnOcGemPK2KWK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bkzBZ0/btsKW7MGWxC/iTXm8e4sEwnOcGemPK2KWK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bkzBZ0/btsKW7MGWxC/iTXm8e4sEwnOcGemPK2KWK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbkzBZ0%2FbtsKW7MGWxC%2FiTXm8e4sEwnOcGemPK2KWK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;602&quot; height=&quot;333&quot; data-origin-width=&quot;602&quot; data-origin-height=&quot;333&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;ol style=&quot;list-style-type: decimal;&quot; data-ke-list-type=&quot;decimal&quot;&gt;
&lt;li&gt;원리는 간단하다. 하나의 윈도우 사이즈만큼 그룹을 묶는다.&lt;/li&gt;
&lt;li&gt;그룹의 평균 값을 대푯값으로 잡는다.&lt;/li&gt;
&lt;li&gt;한 칸씩 이동한다. (Convolution 1D와 같은 원리)&lt;/li&gt;
&lt;/ol&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이&amp;nbsp;간단한&amp;nbsp;방법으로&amp;nbsp;스무딩&amp;nbsp;효과를&amp;nbsp;낼&amp;nbsp;수&amp;nbsp;있다.&amp;nbsp;RSSI&amp;nbsp;값이&amp;nbsp;확&amp;nbsp;튀었을&amp;nbsp;때&amp;nbsp;이를&amp;nbsp;완화시켜주는&amp;nbsp;효과를&amp;nbsp;낸다. &lt;br /&gt;&lt;br /&gt;당연히&amp;nbsp;단점도&amp;nbsp;존재한다.&amp;nbsp; &lt;br /&gt;&lt;br /&gt;delay가&amp;nbsp;발생한다.&amp;nbsp;윈도우&amp;nbsp;사이즈만큼&amp;nbsp;평균&amp;nbsp;내기&amp;nbsp;때문에&amp;nbsp;현재의&amp;nbsp;값이&amp;nbsp;바로&amp;nbsp;반영되지&amp;nbsp;않음.&amp;nbsp;윈도우&amp;nbsp;사이즈가&amp;nbsp;크면&amp;nbsp;클수록&amp;nbsp;delay는&amp;nbsp;점점&amp;nbsp;더&amp;nbsp;늘어난다. &lt;br /&gt;&lt;br /&gt;delay를&amp;nbsp;해결하기&amp;nbsp;위해&amp;nbsp;현재의&amp;nbsp;값에&amp;nbsp;가중치를&amp;nbsp;곱할&amp;nbsp;수&amp;nbsp;있고,&amp;nbsp;칼만&amp;nbsp;필터를&amp;nbsp;이용할&amp;nbsp;수도&amp;nbsp;있다.&lt;/p&gt;
&lt;h3 style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size23&quot;&gt;  2. Code&lt;/h3&gt;
&lt;pre id=&quot;code_1732545482805&quot; class=&quot;cpp&quot; data-ke-language=&quot;cpp&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;  var movingAverageWindow = [];

  num movingAverageFilter(int rssi, int windowSize) {
    if (movingAverageWindow.length != windowSize) {
      movingAverageWindow.add(rssi);
    } else {
      movingAverageWindow.add(rssi);
      movingAverageWindow.removeAt(0);
    }
    return (movingAverageWindow.reduce((a, b) =&amp;gt; (a + b)) / windowSize);
  }&lt;/code&gt;&lt;/pre&gt;</description>
      <category> Project/✅ BLE Indoor Positioning</category>
      <category>BLE</category>
      <category>flutter</category>
      <category>구현</category>
      <category>이동평균</category>
      <category>필터</category>
      <author>18진수</author>
      <guid isPermaLink="true">https://coding-yoon.tistory.com/295</guid>
      <comments>https://coding-yoon.tistory.com/295#entry295comment</comments>
      <pubDate>Mon, 25 Nov 2024 23:39:21 +0900</pubDate>
    </item>
    <item>
      <title>[BLE 실내 측위 프로젝트] 5. BLE Beacon의 RSSI 값에서 거리를 계산하는 방법 (feat.log distance path los</title>
      <link>https://coding-yoon.tistory.com/294</link>
      <description>&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;span style=&quot;font-family: Noto Serif KR;&quot;&gt;  1. &lt;i&gt;Log distance path loss model&lt;/i&gt;&lt;/span&gt;&lt;/h2&gt;&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;i&gt;RSSI&lt;/i&gt;는&amp;nbsp;수신&amp;nbsp;신호&amp;nbsp;강도&amp;nbsp;표시기를&amp;nbsp;나타낸다.&amp;nbsp;스마트폰과&amp;nbsp;같은&amp;nbsp;수신&amp;nbsp;장치에서&amp;nbsp;볼&amp;nbsp;수&amp;nbsp;있는&amp;nbsp;비콘의&amp;nbsp;신호&amp;nbsp;강도이다.&amp;nbsp;신호&amp;nbsp;강도는&amp;nbsp;거리와&amp;nbsp;전송&amp;nbsp;세기에&amp;nbsp;따라&amp;nbsp;다르다.&amp;nbsp; &lt;br&gt;&lt;br&gt;&lt;i&gt;RSSI&lt;/i&gt;를&amp;nbsp;이용하여&amp;nbsp;거리를&amp;nbsp;구하는&amp;nbsp;식은&amp;nbsp;아래와&amp;nbsp;같다.&lt;/p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;189&quot; data-origin-height=&quot;79&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/qEJF5/btsKT5WK8En/rrj1k8MCGZdajifpYOQ1p1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/qEJF5/btsKT5WK8En/rrj1k8MCGZdajifpYOQ1p1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/qEJF5/btsKT5WK8En/rrj1k8MCGZdajifpYOQ1p1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FqEJF5%2FbtsKT5WK8En%2Frrj1k8MCGZdajifpYOQ1p1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;189&quot; height=&quot;79&quot; data-origin-width=&quot;189&quot; data-origin-height=&quot;79&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;ul style=&quot;list-style-type: circle;&quot; data-ke-list-type=&quot;circle&quot;&gt;&lt;li&gt;&lt;b&gt;&lt;i&gt;&lt;span style=&quot;font-family: Noto Serif KR;&quot;&gt;d&lt;/span&gt;&lt;/i&gt;&lt;/b&gt; : distance(거리)&lt;/li&gt;&lt;li&gt;&lt;b&gt;&lt;i&gt;&lt;span style=&quot;font-family: Noto Serif KR;&quot;&gt;n&lt;/span&gt;&lt;/i&gt;&lt;/b&gt; : 보정 상수 (2~4: 보통 2를 사용)&lt;/li&gt;&lt;li&gt;&lt;b&gt;α&lt;/b&gt;&amp;nbsp;: 1m에서 측정된 &lt;i&gt;&lt;span style=&quot;font-family: Noto Serif KR;&quot;&gt;RSSI&lt;/span&gt;&lt;/i&gt;&lt;/li&gt;&lt;li&gt;&lt;b&gt;&lt;i&gt;&lt;span style=&quot;font-family: Noto Serif KR;&quot;&gt;RSSI&lt;/span&gt; &lt;/i&gt;&lt;/b&gt;: 측정된 현재 &lt;i&gt;&lt;span style=&quot;font-family: Noto Serif KR;&quot;&gt;RSSI&lt;/span&gt;&lt;/i&gt;&lt;/li&gt;&lt;/ul&gt;&lt;h2 data-ke-size=&quot;size26&quot;&gt;  2. Code&lt;/h2&gt;&lt;pre data-ke-type=&quot;codeblock&quot; class=&quot;cpp&quot; data-ke-language=&quot;cpp&quot;&gt;&lt;code&gt;import &quot;dart:math&quot;;

void main() {
&amp;nbsp;&amp;nbsp;int n = 2;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;// constant N
&amp;nbsp;&amp;nbsp;int alpha = -63;&amp;nbsp;&amp;nbsp;// rssi at 1m
&amp;nbsp;&amp;nbsp;int rssi = -80;&amp;nbsp;&amp;nbsp; // measured rssi
&amp;nbsp;&amp;nbsp;num m = pow(10.0,((alpha-rssi)/(10*n)));
&amp;nbsp;&amp;nbsp;print(m);
}

// result
// 3.548133892335755 [m]&lt;/code&gt;&lt;/pre&gt;&lt;h2 data-ke-size=&quot;size26&quot;&gt;  3. 한계&lt;/h2&gt;&lt;p data-ke-size=&quot;size16&quot;&gt;흡수,&amp;nbsp;간섭&amp;nbsp;또는&amp;nbsp;회절과&amp;nbsp;같은&amp;nbsp;전파에&amp;nbsp;영향을&amp;nbsp;미치는&amp;nbsp;외부&amp;nbsp;요인으로&amp;nbsp;인해&amp;nbsp;RSSI는&amp;nbsp;변동하는&amp;nbsp;경향이&amp;nbsp;있다.&amp;nbsp;장치가&amp;nbsp;비콘에서&amp;nbsp;멀어질수록&amp;nbsp;RSSI가&amp;nbsp;더&amp;nbsp;불안정해진다.&lt;/p&gt;&lt;figure class=&quot;imageblock widthContent&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;762&quot; data-origin-height=&quot;412&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/IaFZX/btsKU8ymyWX/AYb5k7ocm6kdzTfDf9hkF1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/IaFZX/btsKU8ymyWX/AYb5k7ocm6kdzTfDf9hkF1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/IaFZX/btsKU8ymyWX/AYb5k7ocm6kdzTfDf9hkF1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FIaFZX%2FbtsKU8ymyWX%2FAYb5k7ocm6kdzTfDf9hkF1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;762&quot; height=&quot;412&quot; data-origin-width=&quot;762&quot; data-origin-height=&quot;412&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;위&amp;nbsp;그래프는&amp;nbsp;예전에&amp;nbsp;실험으로&amp;nbsp;측정한&amp;nbsp;비콘과&amp;nbsp;스마트폰&amp;nbsp;사이의&amp;nbsp;거리&amp;nbsp;별&amp;nbsp;&lt;i&gt;RSSI&lt;/i&gt;를&lt;b&gt;&amp;nbsp;boxplot&lt;/b&gt;으로&amp;nbsp;표시한&amp;nbsp;것이다. &lt;br&gt;&lt;br&gt;4.5m부터&amp;nbsp;7m&amp;nbsp;구간의&amp;nbsp;boxplot을&amp;nbsp;보게&amp;nbsp;되면&amp;nbsp;정확한&amp;nbsp;거리를&amp;nbsp;계산할&amp;nbsp;수&amp;nbsp;없을&amp;nbsp;뿐더러,&amp;nbsp;무선&amp;nbsp;신호는&amp;nbsp;non-line&amp;nbsp;of&amp;nbsp;sight,&amp;nbsp;흡수,&amp;nbsp;간섭&amp;nbsp;등의&amp;nbsp;외부&amp;nbsp;요인에&amp;nbsp;굉장에&amp;nbsp;취약하다.&amp;nbsp; &lt;br&gt;&lt;br&gt;이를&amp;nbsp;해결하기&amp;nbsp;위해서는&amp;nbsp;여러&amp;nbsp;방법이&amp;nbsp;있다.&lt;/p&gt;&lt;ol style=&quot;list-style-type: decimal;&quot; data-ke-list-type=&quot;decimal&quot;&gt;&lt;li&gt;비콘을 최대한 촘촘히 설치한다. (다다익선) ➡️ 비용 문제&lt;/li&gt;&lt;li&gt;핑거 프린팅 ➡️ 사전 준비 필요&lt;/li&gt;&lt;li&gt;필터 사용 (이동 평균 필터, 칼만 필터 등)&lt;/li&gt;&lt;li&gt;맵 매칭 ➡️ 사전 준비 필요&lt;/li&gt;&lt;li&gt;인공지능 ➡️ 사전 데이터 필요 &lt;/li&gt;&lt;/ol&gt;</description>
      <category> Project/✅ BLE Indoor Positioning</category>
      <category>BLE</category>
      <category>distance</category>
      <category>indoor</category>
      <category>Log</category>
      <category>loss</category>
      <category>model</category>
      <category>PATH</category>
      <category>positioning</category>
      <author>18진수</author>
      <guid isPermaLink="true">https://coding-yoon.tistory.com/294</guid>
      <comments>https://coding-yoon.tistory.com/294#entry294comment</comments>
      <pubDate>Sun, 24 Nov 2024 22:56:00 +0900</pubDate>
    </item>
    <item>
      <title>[BLE 실내 측위 프로젝트] 4. BLE advertising packet 기본 구성</title>
      <link>https://coding-yoon.tistory.com/293</link>
      <description>&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;span&gt;   &lt;span&gt;1. BLE Packet&lt;/span&gt; &lt;/span&gt;&lt;/h2&gt;
&lt;p id=&quot;SE-b92e1ef6-ad26-4433-8cb0-bbae49a55046&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;BLE의 패킷 타입은 두 가지가 있다. &lt;/span&gt;&lt;/p&gt;
&lt;ol style=&quot;list-style-type: decimal;&quot; data-ke-list-type=&quot;decimal&quot;&gt;
&lt;li id=&quot;SE-cb2a165e-20db-4e43-aafe-49bb1d4346af&quot;&gt;&lt;span&gt;Advertising channl PDUs : 기기 감지 및 브로드캐스팅&lt;/span&gt;&lt;/li&gt;
&lt;li id=&quot;SE-01aca778-0a49-46c1-b48e-57d2217d3458&quot;&gt;&lt;span&gt;Data channel PDUs : 데이터 전송용&lt;/span&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;p id=&quot;SE-520ee79f-7884-48bb-84c2-1acf90a62d94&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;​실내 측위에서는 데이터 전송이 따로 필요 없으므로 Advertising channel PDUs에 대해서만 언급한다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;​&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock widthContent&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;488&quot; data-origin-height=&quot;192&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bxt3iU/btsKUGba2da/TDKmaD2LkiJZAdhEqrJNwk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bxt3iU/btsKUGba2da/TDKmaD2LkiJZAdhEqrJNwk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bxt3iU/btsKUGba2da/TDKmaD2LkiJZAdhEqrJNwk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fbxt3iU%2FbtsKUGba2da%2FTDKmaD2LkiJZAdhEqrJNwk%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;488&quot; height=&quot;192&quot; data-origin-width=&quot;488&quot; data-origin-height=&quot;192&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt; Packet types은 아래 테이블과 같다. &lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock widthContent&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;773&quot; data-origin-height=&quot;172&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/kRn5T/btsKU8ZBKlX/COKu6NjLk6i7niEeCxE2q0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/kRn5T/btsKU8ZBKlX/COKu6NjLk6i7niEeCxE2q0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/kRn5T/btsKU8ZBKlX/COKu6NjLk6i7niEeCxE2q0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FkRn5T%2FbtsKU8ZBKlX%2FCOKu6NjLk6i7niEeCxE2q0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;773&quot; height=&quot;172&quot; data-origin-width=&quot;773&quot; data-origin-height=&quot;172&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p id=&quot;SE-c35410c2-8186-4a88-8bca-222ea5d0e3a8&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;보통 비콘의 타입은 ADV_IND가 일반적이다. 특정 중앙 장치를 특정하지 않고 모든 주변 기기와 연결할 수 있다.&lt;/span&gt;&lt;/p&gt;
&lt;p id=&quot;SE-9119cc0a-d0e7-40a4-be52-1771446e2067&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;&lt;span&gt;Payload는 최대 37바이트 중에서 6바이트는 &lt;/span&gt;&lt;span&gt;&lt;b&gt;Advertisement Address&lt;/b&gt;&lt;/span&gt;&lt;span&gt;, 나머지 0 ~ 31바이트는 &lt;/span&gt;&lt;span&gt;&lt;b&gt;Advertisement Data이다.&lt;/b&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock widthContent&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;781&quot; data-origin-height=&quot;113&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bovDz3/btsKU8LUtzI/qUS4NzOJRViZvb75nDrN9k/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bovDz3/btsKU8LUtzI/qUS4NzOJRViZvb75nDrN9k/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bovDz3/btsKU8LUtzI/qUS4NzOJRViZvb75nDrN9k/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbovDz3%2FbtsKU8LUtzI%2FqUS4NzOJRViZvb75nDrN9k%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;781&quot; height=&quot;113&quot; data-origin-width=&quot;781&quot; data-origin-height=&quot;113&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p id=&quot;SE-3d0faa59-29df-4fef-9a62-702a7cb1b662&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;BLE 비콘에는 각 제조사에 따라 다양한 패킷 포맷을 가진다. 그중 가장 유명한 것이 애플의 iBeacon, 구글의 EddyStone이다.&lt;/span&gt;&lt;/p&gt;
&lt;p id=&quot;SE-e4885f95-3c6b-4648-979a-37a28d1374aa&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;이 글은 iBeacon의 패킷에 대해 이야기한다.&lt;/span&gt;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;span&gt;   2. iBeacon - Apple &lt;/span&gt;&lt;/h2&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock widthContent&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;779&quot; data-origin-height=&quot;182&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/T5Ug1/btsKU7sHhld/F4GQvpDm5ieFMDXFwWhba1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/T5Ug1/btsKU7sHhld/F4GQvpDm5ieFMDXFwWhba1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/T5Ug1/btsKU7sHhld/F4GQvpDm5ieFMDXFwWhba1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FT5Ug1%2FbtsKU7sHhld%2FF4GQvpDm5ieFMDXFwWhba1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;779&quot; height=&quot;182&quot; data-origin-width=&quot;779&quot; data-origin-height=&quot;182&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt; iBeacon 비콘 packet format (모든 BLE 비콘이 위 패킷 포맷을 따라가지 않는다.) &lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock widthContent&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;697&quot; data-origin-height=&quot;320&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/R2VzU/btsKUhCUlJc/U9k8txwLrp3YMPC8fPgku0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/R2VzU/btsKUhCUlJc/U9k8txwLrp3YMPC8fPgku0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/R2VzU/btsKUhCUlJc/U9k8txwLrp3YMPC8fPgku0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FR2VzU%2FbtsKUhCUlJc%2FU9k8txwLrp3YMPC8fPgku0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;697&quot; height=&quot;320&quot; data-origin-width=&quot;697&quot; data-origin-height=&quot;320&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;div id=&quot;SE-5a1fdcb0-aa61-45ff-a569-d907dc7613bb&quot;&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;p id=&quot;SE-836faa06-0329-422f-8a80-d5bb321478c7&quot; style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;iBeacon의 패킷에서는 다양한 값을 알 수 있다. &lt;/span&gt;&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div id=&quot;SE-50f3630a-3682-4de7-ade3-11ce359913b4&quot;&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;&lt;figure class=&quot;imageblock widthContent&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;495&quot; data-origin-height=&quot;145&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/SRx8c/btsKTZvwtqk/0tTNMAKQm9P0sCxcKdXov1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/SRx8c/btsKTZvwtqk/0tTNMAKQm9P0sCxcKdXov1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/SRx8c/btsKTZvwtqk/0tTNMAKQm9P0sCxcKdXov1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FSRx8c%2FbtsKTZvwtqk%2F0tTNMAKQm9P0sCxcKdXov1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;495&quot; height=&quot;145&quot; data-origin-width=&quot;495&quot; data-origin-height=&quot;145&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div id=&quot;SE-0d525bd3-aace-478a-a62a-5592dc558716&quot;&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;p id=&quot;SE-7a7f38c1-3858-401a-bc71-8ccd9d457618&quot; style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;눈여겨봐야 하는 것은 Manufacturer data와 TX power이다. 플래그, 데이터 길이를 제외하고 대부분은 비콘의 고유 주소라고 봐도 무방하다. (제조사, 기기 번호 등등)&lt;/span&gt;&lt;/p&gt;
&lt;p id=&quot;SE-ecdd07d9-d6bb-4503-acd5-fd55e5c3e940&quot; style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;Manufacturer data는 개발자들이 임의로 넣을 수 있는 패킷 공간이다. iBeacon이 아닌 자신만의 BLE 비콘을 만들어도 되지만, 나는 RSSI만 필요하므로 기존의 비콘을 사용한다.&lt;/span&gt;&lt;/p&gt;
&lt;p id=&quot;SE-ac9ebd4b-1046-4c21-9acc-d371e7f9d322&quot; style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;그리고 TX Power는 비콘의 송신 세기이다. 이는 실내 측위 분석에 있어 중요한 파라미터가 될 수 있다.&lt;/span&gt;&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style2&quot; /&gt;
&lt;p id=&quot;SE-98f5967b-caa9-4d42-b4e5-216647154271&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;이 전 코드에서는 기기 ID, Mac address, RSSI 정도만 볼 수 있었다면 이 번 코드는 Payload에서 manufacturer data, UUID, TX Power를 확인할 수 있다. &lt;/span&gt;&lt;/p&gt;
&lt;p id=&quot;SE-bc5cfc58-7ad1-45b3-91ae-5943d9bcd647&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;플러터를 공부한 지 일주일이 넘어갔는데, 여러 가지 애로사항이 있었다. 패킷 구조를 C의 Struct 구조와 같이 만들고 싶었는데, Dart에서는 struct이 없다고 한다. 그냥 class를 사용하라고 하는데, 그냥 배열 선언해서 무식하게 접근했다. 누가 이 글을 보고 조언해주면 좋겠다.&lt;/span&gt;&lt;/p&gt;
&lt;p id=&quot;SE-d4e4df19-bc00-4550-adcb-788b173cb5a0&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;새롭게 추가한 것은 provider이다. flutter에서 관리 용이성을 위해 전역 공간을 하나 만들어 준 것이다.&lt;/span&gt;&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;</description>
      <category> Project/✅ BLE Indoor Positioning</category>
      <category>BLE</category>
      <category>i-beacon</category>
      <category>indoor</category>
      <category>Position</category>
      <author>18진수</author>
      <guid isPermaLink="true">https://coding-yoon.tistory.com/293</guid>
      <comments>https://coding-yoon.tistory.com/293#entry293comment</comments>
      <pubDate>Sun, 24 Nov 2024 22:45:30 +0900</pubDate>
    </item>
    <item>
      <title>[BLE 실내 측위 프로젝트] 3. Flutter BLE Scan Demo Program, RSSI monitoring</title>
      <link>https://coding-yoon.tistory.com/292</link>
      <description>&lt;p id=&quot;SE-ecdc6814-5c03-484c-9bc0-f348d672f08b&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;하이제니스 님의 포스팅에 포함된 코드를 일부 수정하였습니다.&lt;/span&gt;&lt;/p&gt;
&lt;blockquote id=&quot;SE-8e9d9472-9d80-4d4f-b5ad-279147cb5eb1&quot; data-ke-style=&quot;style3&quot;&gt;&lt;a href=&quot;https://blog.naver.com/chandong83/222414483554&quot;&gt;https://blog.naver.com/chandong83/222414483554&lt;/a&gt;&lt;/blockquote&gt;
&lt;p id=&quot;SE-15852c58-06ee-451e-8198-4d974e070902&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;BLE 통신 스케줄 및 안드로이드 동작에 관한 포스팅을 보고 와야 어느 정도 이해하기 편하다.&lt;/span&gt;&lt;/p&gt;
&lt;h2 id=&quot;SE-6c350613-20d0-4ded-860a-1f3e4a247a06&quot; data-ke-size=&quot;size26&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt; &amp;nbsp; ​1. &amp;nbsp;&lt;span style=&quot;background-color: #ffffff; text-align: left;&quot;&gt;패키지 설치 및 설정&lt;/span&gt;&lt;/span&gt;&lt;/h2&gt;
&lt;p id=&quot;SE-071e2785-c027-4ab8-9ac9-0752babc7cc3&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;flutter_blue 대신 flutter_blue_plus 패키지를 설치한다.&lt;/span&gt;&lt;/p&gt;
&lt;p id=&quot;SE-e501194d-b752-4304-8141-15c0da499382&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;flutter_blue는 더 이상 업데이트하지 않고 안드로이드 12 권한 이슈가 있으므로, flutter_blue_plus를 설치한다.&lt;/span&gt;&lt;/p&gt;
&lt;pre id=&quot;code_1732454897566&quot; class=&quot;cpp&quot; data-ke-language=&quot;cpp&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;$ flutter pub add flutter_blue_plus&lt;/code&gt;&lt;/pre&gt;
&lt;p id=&quot;SE-95dea94f-3d1c-4abf-9f0f-2455b1384bb4&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;설치하게 되면 알아서 &lt;/span&gt;&lt;span style=&quot;background-color: #ffffff; color: #555555;&quot;&gt;dependecies가 추가된다.&lt;/span&gt;&lt;/p&gt;
&lt;h3 id=&quot;SE-aa16a6eb-8d4d-448a-9260-93c620d7b4ea&quot; data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;background-color: #ffffff; color: #4a4a4a;&quot;&gt;&lt;b&gt;⚙️ 1. android/app/build.gradle &lt;/b&gt;&lt;/span&gt;&lt;span style=&quot;background-color: #ffffff; color: #4a4a4a;&quot;&gt;: SDK 최소 버전 19로 설정&lt;/span&gt;&lt;/h3&gt;
&lt;pre id=&quot;code_1732454914653&quot; class=&quot;cpp&quot; data-ke-language=&quot;cpp&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;Android {
  defaultConfig {
     minSdkVersion: 19&lt;/code&gt;&lt;/pre&gt;
&lt;h3 style=&quot;text-align: justify;&quot; data-ke-size=&quot;size23&quot;&gt;⚙️ &lt;span style=&quot;background-color: #ffffff; color: #4a4a4a; text-align: center;&quot;&gt;&lt;b&gt;2. android/app/src/main/AndroidManifest.xml &lt;/b&gt;&lt;/span&gt;&lt;span style=&quot;background-color: #ffffff; color: #4a4a4a; text-align: center;&quot;&gt;: Bluetooth 권한 설정&lt;/span&gt;&lt;/h3&gt;
&lt;pre id=&quot;code_1732454929662&quot; class=&quot;cpp&quot; data-ke-language=&quot;cpp&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt; &amp;lt;uses-permission android:name=&quot;android.permission.BLUETOOTH&quot; /&amp;gt;  
	 &amp;lt;uses-permission android:name=&quot;android.permission.BLUETOOTH_ADMIN&quot; /&amp;gt;  
	 &amp;lt;uses-permission android:name=&quot;android.permission.ACCESS_COARSE_LOCATION&quot;/&amp;gt;  
 &amp;lt;application&lt;/code&gt;&lt;/pre&gt;
&lt;h2 style=&quot;text-align: justify;&quot; data-ke-size=&quot;size26&quot;&gt;  &lt;span style=&quot;background-color: #ffffff; color: #000000; text-align: left;&quot;&gt;2. Code&lt;/span&gt;&lt;/h2&gt;
&lt;p id=&quot;SE-ecc539fe-f897-4b95-84d0-4ad2951ee927&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;하이 제닉스님 같은 경우는 버튼을 누르고 4초 동안 스캔하고, 결과가 보인다면, 내 코드는 스캔을 계속 진행하면서, RSSI 변화량을 모니터링하는 것이다.&lt;/span&gt;&lt;/p&gt;
&lt;p id=&quot;SE-b4c4e7d7-aa5f-4f41-b6ae-bdeea451bd35&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;코드에서 큰 차이는 없지만, startScan 함수에서 allowDuplicates 파라미터를 true 설정한 것이다.&lt;/span&gt;&lt;/p&gt;
&lt;p id=&quot;SE-a1dbcbe1-abc5-4bd0-ab7f-c64d287cfa8a&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;allowDuplicates는 기본 false로, 한 번 발견된 기기는 더 이상 업데이트되지 않고 RSSI 값이 고정된다. &lt;/span&gt;&lt;/p&gt;
&lt;p id=&quot;SE-fe2bd1c0-4d74-441d-be1d-4cced0721395&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;이를 true로 설정하게 되면, 이미 발견된 기기라 할지라도 업데이트되므로 RSSI 변화량을 확인할 수 있다.&lt;/span&gt;&lt;/p&gt;
&lt;p id=&quot;SE-55f55018-1603-4c96-965e-961d9912e591&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;ScanMode는 실내 측위를 위해 LowLatency를 사용했다. 모드의 동작을 확인하고 싶으면 목차에서 두번 째 글을 보면 된다.&lt;/span&gt;&lt;/p&gt;
&lt;pre id=&quot;code_1732454972318&quot; class=&quot;cpp&quot; data-ke-language=&quot;cpp&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;import 'package:flutter/material.dart';
import 'package:flutter_blue_plus/flutter_blue_plus.dart';

void main() {
  runApp(const MyApp());
}

class MyApp extends StatelessWidget {
  const MyApp({Key? key}) : super(key: key);

  final title = 'Flutter BLE Scan Demo';
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: title,
      home: MyHomePage(title: title),
    );
  }
}

class MyHomePage extends StatefulWidget {
  const MyHomePage({Key? key, required this.title}) : super(key: key);
  final String title;

  @override
  _MyHomePageState createState() =&amp;gt; _MyHomePageState();
}

class _MyHomePageState extends State&amp;lt;MyHomePage&amp;gt; {
  FlutterBluePlus flutterBlue = FlutterBluePlus.instance;
  List&amp;lt;ScanResult&amp;gt; scanResultList = [];
  
  int scan_mode = 2;   // scan mode
  bool isScanning = false;

  /* 생성자 */
  @override
  void initState() {
    super.initState();
  }

  /* 시작, 정지 */
  void toggleState() {
    isScanning = !isScanning;

    if (isScanning) {
      flutterBlue.startScan(
          scanMode: ScanMode(scan_mode), allowDuplicates: true);
      scan();
    } else {
      flutterBlue.stopScan();
    }
    setState(() {});
  }

  /* 
  Scan Mode
  Ts = scan interval 
  Ds = duration of every scan window
             | Ts [s] | Ds [s]
  LowPower   | 5.120  | 1.024
  BALANCED   | 4.096  | 1.024
  LowLatency | 4.096  | 4.096

  LowPower = ScanMode(0);
  BALANCED = ScanMode(1);
  LowLatency = ScanMode(2);

  opportunistic = ScanMode(-1);
   */

  /* Scan */
  void scan() async {
    if (isScanning) {
      // Listen to scan results

      flutterBlue.scanResults.listen((results) {
        // do something with scan results
        scanResultList = results;
        // update state
        setState(() {});
      });
    }
  }

  /* 장치의 RSSI */
  Widget deviceSignal(ScanResult r) {
    return Text(r.rssi.toString());
  }

  /* 장치의 MAC 주소 위젯  */
  Widget deviceMacAddress(ScanResult r) {
    return Text(r.device.id.id);
  }

  /* 장치의 명 위젯  */
  Widget deviceName(ScanResult r) {
    String name;

    if (r.device.name.isNotEmpty) {
      // device.name에 값이 있다면
      name = r.device.name;
    } else if (r.advertisementData.localName.isNotEmpty) {
      // advertisementData.localName에 값이 있다면
      name = r.advertisementData.localName;
    } else {
      // 둘다 없다면 이름 알 수 없음...
      name = 'N/A';
    }
    return Text(name);
  }

  /* BLE 아이콘 위젯 */
  Widget leading(ScanResult r) {
    return const CircleAvatar(
      backgroundColor: Colors.cyan,
      child: Icon(
        Icons.bluetooth,
        color: Colors.white,
      ),
    );
  }

  /* 장치 아이템을 탭 했을때 호출 되는 함수 */
  void onTap(ScanResult r) {
    // 단순히 이름만 출력
    print('${r.device.name}');
  }

  /* 장치 아이템 위젯 */
  Widget listItem(ScanResult r) {
    return ListTile(
      onTap: () =&amp;gt; onTap(r),
      leading: leading(r),
      title: deviceName(r),
      subtitle: deviceMacAddress(r),
      trailing: deviceSignal(r),
    );
  }

  /* UI */
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text(widget.title),
      ),
      body: Center(
        /* 장치 리스트 출력 */
        child: ListView.separated(
          itemCount: scanResultList.length,
          itemBuilder: (context, index) {
            return listItem(scanResultList[index]);
          },
          separatorBuilder: (BuildContext context, int index) {
            return const Divider();
          },
        ),
      ),
      /* 장치 검색 or 검색 중지  */
      floatingActionButton: FloatingActionButton(
        onPressed: toggleState,
        // 스캔 중이라면 stop 아이콘을, 정지상태라면 search 아이콘으로 표시
        child: Icon(isScanning ? Icons.stop : Icons.search),
      ),
    );
  }
}&lt;/code&gt;&lt;/pre&gt;
&lt;h2 style=&quot;text-align: justify;&quot; data-ke-size=&quot;size26&quot;&gt; &amp;nbsp; &lt;span style=&quot;background-color: #ffffff; color: #000000; text-align: left;&quot;&gt;3. Demo Video&lt;/span&gt;&lt;/h2&gt;
&lt;p style=&quot;text-align: justify;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://www.youtube.com/shorts/vdjfelsk_Ug&quot;&gt;https://www.youtube.com/shorts/vdjfelsk_Ug&lt;/a&gt;&lt;/p&gt;
&lt;figure data-ke-type=&quot;video&quot; data-ke-style=&quot;alignLeft&quot; data-video-host=&quot;youtube&quot; data-video-url=&quot;https://www.youtube.com/shorts/vdjfelsk_Ug&quot; data-video-thumbnail=&quot;https://scrap.kakaocdn.net/dn/4KPUc/hyXDeeDcgV/Jz2zKbaifIYYd0XxSCyFV0/img.jpg?width=324&amp;amp;height=720&amp;amp;face=0_0_324_720,https://scrap.kakaocdn.net/dn/kk3T0/hyXDapKXWw/8LTSpr15jo8Z2c21qNlKYk/img.jpg?width=324&amp;amp;height=720&amp;amp;face=0_0_324_720&quot; data-video-width=&quot;324&quot; data-video-height=&quot;720&quot; data-video-origin-width=&quot;324&quot; data-video-origin-height=&quot;720&quot; data-ke-mobilestyle=&quot;widthContent&quot; data-video-title=&quot;Flutter BLE scan demo1 for RSSI&quot; data-original-url=&quot;&quot;&gt;&lt;iframe src=&quot;https://www.youtube.com/embed/vdjfelsk_Ug&quot; width=&quot;324&quot; height=&quot;720&quot; frameborder=&quot;&quot; allowfullscreen=&quot;true&quot;&gt;&lt;/iframe&gt;
&lt;figcaption style=&quot;display: none;&quot;&gt;&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;p style=&quot;text-align: justify;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category> Project/✅ BLE Indoor Positioning</category>
      <category>BLE</category>
      <category>flutter</category>
      <category>monitoring</category>
      <category>RSSI</category>
      <author>18진수</author>
      <guid isPermaLink="true">https://coding-yoon.tistory.com/292</guid>
      <comments>https://coding-yoon.tistory.com/292#entry292comment</comments>
      <pubDate>Sun, 24 Nov 2024 22:35:31 +0900</pubDate>
    </item>
    <item>
      <title>[BLE 실내 측위 프로젝트] 2. Bluetooth Low Energy(BLE) 통신 스케줄, 안드로이드 함께 이해하기</title>
      <link>https://coding-yoon.tistory.com/291</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;BLE&amp;nbsp;통신을&amp;nbsp;하기&amp;nbsp;전에&amp;nbsp;통신&amp;nbsp;스케줄에&amp;nbsp;대해&amp;nbsp;이해하고&amp;nbsp;가면&amp;nbsp;좋다. &lt;br /&gt;&lt;br /&gt;BLE의&amp;nbsp;물리&amp;nbsp;계층&amp;nbsp;먼저&amp;nbsp;간단하게&amp;nbsp;짚고&amp;nbsp;간다. &lt;br /&gt;&lt;br /&gt;BLE는&amp;nbsp;2.4GHz&amp;nbsp;대역을&amp;nbsp;사용하며,&amp;nbsp;(2.402&amp;nbsp;GHz&amp;nbsp;~&amp;nbsp;2.4835&amp;nbsp;GHz)&amp;nbsp;:&amp;nbsp;2&amp;nbsp;MHz&amp;nbsp;간격으로&amp;nbsp;40개&amp;nbsp;채널로&amp;nbsp;구성된다. &lt;br /&gt;&lt;br /&gt;Advertising&amp;nbsp;채널은&amp;nbsp;37,&amp;nbsp;38,&amp;nbsp;39&amp;nbsp;(2402&amp;nbsp;MHz,&amp;nbsp;2426&amp;nbsp;MHz,&amp;nbsp;2480&amp;nbsp;MHz)를,&amp;nbsp;Adaptive&amp;nbsp;Frequency&amp;nbsp;Hopping&amp;nbsp;방식을&amp;nbsp;사용한다.&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;  실내 측위 (Indoor Positioning)&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Advertiser은&amp;nbsp;송신부,&amp;nbsp;Scanner는&amp;nbsp;수신부라고&amp;nbsp;생각하면&amp;nbsp;편하다.&amp;nbsp;실내&amp;nbsp;측위&amp;nbsp;프로젝트는&amp;nbsp;따로&amp;nbsp;기기&amp;nbsp;간&amp;nbsp;연결을&amp;nbsp;필요로&amp;nbsp;하지&amp;nbsp;않고,&amp;nbsp;Device&amp;nbsp;discovery&amp;nbsp;모드만&amp;nbsp;사용한다. &lt;br /&gt;&lt;br /&gt;실내&amp;nbsp;측위에&amp;nbsp;간략히&amp;nbsp;설명하자면,&amp;nbsp;Advertiser가&amp;nbsp;모든&amp;nbsp;방향으로&amp;nbsp;Advertising&amp;nbsp;패킷을&amp;nbsp;브로드캐스팅하면,&amp;nbsp;수신&amp;nbsp;받는&amp;nbsp;Scanner는&amp;nbsp;패킷에&amp;nbsp;대한&amp;nbsp;RSS(수신신호세기)를&amp;nbsp;얻을&amp;nbsp;수&amp;nbsp;있다.&amp;nbsp; &lt;br /&gt;&lt;br /&gt;알려진&amp;nbsp;Log&amp;nbsp;distance&amp;nbsp;path&amp;nbsp;loss&amp;nbsp;model을&amp;nbsp;이용해&amp;nbsp;RSS로&amp;nbsp;거리를&amp;nbsp;구할&amp;nbsp;수&amp;nbsp;있다.&amp;nbsp;그리고&amp;nbsp;최소&amp;nbsp;3개&amp;nbsp;이상의&amp;nbsp;거리가&amp;nbsp;있으면,&amp;nbsp;삼변&amp;nbsp;측량을&amp;nbsp;통해&amp;nbsp;위치를&amp;nbsp;구하는&amp;nbsp;방식이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;  BLE device discovery&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;아래&amp;nbsp;그림은&amp;nbsp;통신(device&amp;nbsp;discovery)&amp;nbsp;스케줄에&amp;nbsp;대한&amp;nbsp;도식이다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;773&quot; data-origin-height=&quot;392&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/pskU6/btsKTzjPwlD/HrtDDNBHeR1JWkWXK8V8qK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/pskU6/btsKTzjPwlD/HrtDDNBHeR1JWkWXK8V8qK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/pskU6/btsKTzjPwlD/HrtDDNBHeR1JWkWXK8V8qK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FpskU6%2FbtsKTzjPwlD%2FHrtDDNBHeR1JWkWXK8V8qK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;773&quot; height=&quot;392&quot; data-origin-width=&quot;773&quot; data-origin-height=&quot;392&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;ul style=&quot;list-style-type: circle;&quot; data-ke-list-type=&quot;circle&quot;&gt;
&lt;li&gt;&lt;i&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;Ad&lt;/span&gt;&lt;/i&gt; = advertiser&lt;/li&gt;
&lt;li&gt;&lt;i&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;Sc&lt;/span&gt;&lt;/i&gt; = scanner&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;&lt;i&gt;ch&lt;/i&gt;&lt;/span&gt; =&amp;nbsp;channel&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Advertising은&amp;nbsp;advertising&amp;nbsp;interval,&amp;nbsp;advertising&amp;nbsp;delay라는&amp;nbsp;값을&amp;nbsp;가진다.&amp;nbsp; &lt;br /&gt;&lt;br /&gt;위&amp;nbsp;도식은&amp;nbsp;advertising&amp;nbsp;delay가&amp;nbsp;0인&amp;nbsp;상태로&amp;nbsp;가장&amp;nbsp;빠르게&amp;nbsp;많은&amp;nbsp;패킷을&amp;nbsp;전송한다고&amp;nbsp;볼&amp;nbsp;수&amp;nbsp;있다.&amp;nbsp;그러므로&amp;nbsp;advertising&amp;nbsp;interval&amp;nbsp;동안&amp;nbsp;패킷을&amp;nbsp;지속적으로&amp;nbsp;송신한다.&amp;nbsp;특징으로&amp;nbsp;한&amp;nbsp;advertising&amp;nbsp;interval&amp;nbsp;동안&amp;nbsp;패킷을&amp;nbsp;채널을&amp;nbsp;37,&amp;nbsp;38,&amp;nbsp;39로&amp;nbsp;변경해가면서&amp;nbsp;전송한다. &lt;br /&gt;&lt;br /&gt;Scanner는&amp;nbsp;scan&amp;nbsp;window,&amp;nbsp;scan&amp;nbsp;interval이라는&amp;nbsp;값을&amp;nbsp;가진다.&amp;nbsp;scan&amp;nbsp;window는&amp;nbsp;실제&amp;nbsp;패킷을&amp;nbsp;받는&amp;nbsp;시간이며,&amp;nbsp;scan&amp;nbsp;interval은&amp;nbsp;반복되는&amp;nbsp;횟수이다.&amp;nbsp; &lt;br /&gt;&lt;br /&gt;그러므로&amp;nbsp;scan&amp;nbsp;window는&amp;nbsp;scan&amp;nbsp;interval보다&amp;nbsp;큰&amp;nbsp;값을&amp;nbsp;가질&amp;nbsp;수&amp;nbsp;없다.&amp;nbsp;특징으로&amp;nbsp;scan&amp;nbsp;window는&amp;nbsp;한&amp;nbsp;채널에&amp;nbsp;대해서만&amp;nbsp;열린다. &lt;br /&gt;&lt;br /&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;&lt;i&gt;ex)&amp;nbsp;Advertiser가&amp;nbsp;37,&amp;nbsp;38,&amp;nbsp;39&amp;nbsp;채널에&amp;nbsp;대한&amp;nbsp;패킷을&amp;nbsp;보냈다&amp;nbsp;하더라도,&amp;nbsp;Scan&amp;nbsp;window의&amp;nbsp;채널이&amp;nbsp;37이라면,&amp;nbsp;37에&amp;nbsp;대한&amp;nbsp;패킷만을&amp;nbsp;받을&amp;nbsp;수&amp;nbsp;있다.&lt;/i&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;  Android&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;안드로이드&amp;nbsp;BLE&amp;nbsp;개발&amp;nbsp;공식&amp;nbsp;문서를&amp;nbsp;보면&amp;nbsp;Scan&amp;nbsp;window,&amp;nbsp;Scan&amp;nbsp;interval,&amp;nbsp;channel은&amp;nbsp;변경하지&amp;nbsp;&amp;nbsp;못하고,&amp;nbsp;mode로&amp;nbsp;선택할&amp;nbsp;수&amp;nbsp;있다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;335&quot; data-origin-height=&quot;92&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/mEwS2/btsKVIMI13R/0Nk2a4yxRfXdAYZKOy7nI0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/mEwS2/btsKVIMI13R/0Nk2a4yxRfXdAYZKOy7nI0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/mEwS2/btsKVIMI13R/0Nk2a4yxRfXdAYZKOy7nI0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FmEwS2%2FbtsKVIMI13R%2F0Nk2a4yxRfXdAYZKOy7nI0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;335&quot; height=&quot;92&quot; data-origin-width=&quot;335&quot; data-origin-height=&quot;92&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;ul style=&quot;list-style-type: circle;&quot; data-ke-list-type=&quot;circle&quot;&gt;
&lt;li&gt;&lt;i&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;Ta&lt;/span&gt;&lt;/i&gt; = advertising interval&lt;/li&gt;
&lt;li&gt;&lt;i&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;Ts&lt;/span&gt;&lt;/i&gt; = scan interval&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;&lt;i&gt;Ds&lt;/i&gt;&lt;/span&gt; = scan window&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;안드로이드&amp;nbsp;개발에서는&amp;nbsp;전력&amp;nbsp;소모에&amp;nbsp;따라&amp;nbsp;모드를&amp;nbsp;나눠&amp;nbsp;놓았다. &lt;br /&gt;&lt;br /&gt;도식으로&amp;nbsp;간단히&amp;nbsp;표현할&amp;nbsp;수&amp;nbsp;있다.&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt; Low Power&lt;/h3&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;773&quot; data-origin-height=&quot;43&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bW9o7H/btsKTAiKPnP/PyVqWvEXSBFQz6qOGqZUdk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bW9o7H/btsKTAiKPnP/PyVqWvEXSBFQz6qOGqZUdk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bW9o7H/btsKTAiKPnP/PyVqWvEXSBFQz6qOGqZUdk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbW9o7H%2FbtsKTAiKPnP%2FPyVqWvEXSBFQz6qOGqZUdk%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;773&quot; height=&quot;43&quot; data-origin-width=&quot;773&quot; data-origin-height=&quot;43&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt; Balanced Power&lt;/h3&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;773&quot; data-origin-height=&quot;43&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/lN1wN/btsKTx7oLcA/kKYSQizgdqpg6mahHMKCK0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/lN1wN/btsKTx7oLcA/kKYSQizgdqpg6mahHMKCK0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/lN1wN/btsKTx7oLcA/kKYSQizgdqpg6mahHMKCK0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FlN1wN%2FbtsKTx7oLcA%2FkKYSQizgdqpg6mahHMKCK0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;773&quot; height=&quot;43&quot; data-origin-width=&quot;773&quot; data-origin-height=&quot;43&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt; Low Latency&lt;/h3&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;773&quot; data-origin-height=&quot;43&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/ydgqV/btsKVxxYaS1/0kKQ1WKxGBJtAEdXNtK5N0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/ydgqV/btsKVxxYaS1/0kKQ1WKxGBJtAEdXNtK5N0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/ydgqV/btsKVxxYaS1/0kKQ1WKxGBJtAEdXNtK5N0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FydgqV%2FbtsKVxxYaS1%2F0kKQ1WKxGBJtAEdXNtK5N0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;773&quot; height=&quot;43&quot; data-origin-width=&quot;773&quot; data-origin-height=&quot;43&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;scan&amp;nbsp;interval이&amp;nbsp;길면&amp;nbsp;길수록,&amp;nbsp;수신&amp;nbsp;받을&amp;nbsp;수&amp;nbsp;있는&amp;nbsp;패킷의&amp;nbsp;양은&amp;nbsp;늘어나지만&amp;nbsp;전력&amp;nbsp;소모는&amp;nbsp;크다. &lt;br /&gt;&lt;br /&gt;scan&amp;nbsp;interval이&amp;nbsp;짧으면&amp;nbsp;짧을수록,&amp;nbsp;수신&amp;nbsp;받을&amp;nbsp;수&amp;nbsp;있는&amp;nbsp;패킷의&amp;nbsp;양은&amp;nbsp;줄어들지만&amp;nbsp;전력&amp;nbsp;소모는&amp;nbsp;작다.&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt; PDR (Packet Delivery Ratio)&lt;/h3&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;Low&amp;nbsp;power&amp;nbsp;mode&amp;nbsp;&amp;lt;&amp;nbsp;Balanced&amp;nbsp;mode&amp;nbsp;&amp;lt;&amp;nbsp;Low&amp;nbsp;latency&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt; Power efficiency&lt;/h3&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;Low&amp;nbsp;power&amp;nbsp;mode&amp;nbsp;&amp;gt;&amp;nbsp;Balanced&amp;nbsp;mode&amp;nbsp;&amp;gt;&amp;nbsp;Low&amp;nbsp;latency&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;당연히&amp;nbsp;애플리케이션에&amp;nbsp;알맞은&amp;nbsp;모드를&amp;nbsp;사용하는&amp;nbsp;것이&amp;nbsp;좋다.&amp;nbsp;하지만&amp;nbsp;실내&amp;nbsp;측위의&amp;nbsp;같은&amp;nbsp;경우&amp;nbsp;PDR에&amp;nbsp;따라&amp;nbsp;성능을&amp;nbsp;크게&amp;nbsp;차지하므로,&amp;nbsp;Low&amp;nbsp;latency&amp;nbsp;모드를&amp;nbsp;사용하는&amp;nbsp;것이&amp;nbsp;더&amp;nbsp;좋다.&lt;/p&gt;</description>
      <category> Project/✅ BLE Indoor Positioning</category>
      <category>Android</category>
      <category>balanced</category>
      <category>BLE</category>
      <category>Efficiency</category>
      <category>IPS</category>
      <category>Latency</category>
      <category>low</category>
      <category>PDR</category>
      <category>Power</category>
      <author>18진수</author>
      <guid isPermaLink="true">https://coding-yoon.tistory.com/291</guid>
      <comments>https://coding-yoon.tistory.com/291#entry291comment</comments>
      <pubDate>Sun, 24 Nov 2024 22:25:24 +0900</pubDate>
    </item>
    <item>
      <title>[BLE 실내 측위 프로젝트] 1. Flutter_blue 설정 (feat.안드로이드12 권한 이슈)</title>
      <link>https://coding-yoon.tistory.com/290</link>
      <description>&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;554&quot; data-origin-height=&quot;483&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/siuYE/btsKTIHsxPi/HKS9RSzHQGyVtmWThMMqaK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/siuYE/btsKTIHsxPi/HKS9RSzHQGyVtmWThMMqaK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/siuYE/btsKTIHsxPi/HKS9RSzHQGyVtmWThMMqaK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FsiuYE%2FbtsKTIHsxPi%2FHKS9RSzHQGyVtmWThMMqaK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;554&quot; height=&quot;483&quot; data-origin-width=&quot;554&quot; data-origin-height=&quot;483&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p style=&quot;text-align: justify;&quot; data-ke-size=&quot;size16&quot;&gt;개인&amp;nbsp;프로젝트인&amp;nbsp;BLE&amp;nbsp;실내&amp;nbsp;측위&amp;nbsp;첫&amp;nbsp;글이다. &lt;br /&gt;&lt;br /&gt;우선,&amp;nbsp;flutter에서&amp;nbsp;ble&amp;nbsp;관련&amp;nbsp;패키지를&amp;nbsp;설치한다.&amp;nbsp;대표적으로&amp;nbsp;ble&amp;nbsp;관련&amp;nbsp;패키지는&amp;nbsp;3개가&amp;nbsp;있다. &lt;/p&gt;
&lt;ul style=&quot;list-style-type: circle;&quot; data-ke-list-type=&quot;circle&quot;&gt;
&lt;li&gt;flutter_ble_lib&lt;/li&gt;
&lt;li&gt;flutter_reactive_ble&lt;/li&gt;
&lt;li&gt;flutter_blue&lt;/li&gt;
&lt;/ul&gt;
&lt;p style=&quot;text-align: justify;&quot; data-ke-size=&quot;size16&quot;&gt;flutter_ble_lib는&amp;nbsp;업데이트가&amp;nbsp;느려,&amp;nbsp;2번과&amp;nbsp;3번&amp;nbsp;중&amp;nbsp;골라야&amp;nbsp;하는데,&amp;nbsp;오늘&amp;nbsp;자&amp;nbsp;기준으로&amp;nbsp;flutter_blue가&amp;nbsp;최신&amp;nbsp;버전이&amp;nbsp;있어&amp;nbsp;flutter_blue를&amp;nbsp;사용한다. &lt;br /&gt;&lt;br /&gt;flutter&amp;nbsp;패키지는&amp;nbsp;pub.dev에서&amp;nbsp;설치할&amp;nbsp;수&amp;nbsp;있다.&amp;nbsp;혹은&amp;nbsp;아래&amp;nbsp;명령어를&amp;nbsp;통해&amp;nbsp;설치할&amp;nbsp;수&amp;nbsp;있다.&lt;/p&gt;
&lt;pre id=&quot;code_1732453003506&quot; class=&quot;cpp&quot; data-ke-language=&quot;cpp&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;$ flutter pub add flutter_blue&lt;/code&gt;&lt;/pre&gt;
&lt;p style=&quot;text-align: justify;&quot; data-ke-size=&quot;size16&quot;&gt;설치하게&amp;nbsp;되면&amp;nbsp;자동적으로&amp;nbsp;pubspec.yaml&amp;nbsp;파일의&amp;nbsp;dependecies에&amp;nbsp;추가된다.&amp;nbsp; &lt;br /&gt;&lt;br /&gt;하지만, flutter_blue의 경우 안드로이드 12에서 권한 이슈가 있다. 안타깝게도 내 스마트폰도 안드로이드 12였고 AndroidManifest.xml에 별에 별짓을 다했지만 되지 않았다. 결국 아래 git에서 다른 방법으로 문제를 해결했다.&lt;/p&gt;
&lt;p style=&quot;text-align: justify;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://github.com/pauldemarco/flutter_blue/issues/864&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://github.com/pauldemarco/flutter_blue/issues/864&lt;/a&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;pubspec.yaml&amp;nbsp;파일에&amp;nbsp;아래와&amp;nbsp;같이&amp;nbsp;수정했다.&lt;/p&gt;
&lt;pre id=&quot;code_1732453111944&quot; class=&quot;cpp&quot; data-ke-language=&quot;cpp&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;  flutter_blue:
    git: https://github.com/espresso3389/flutter_blue&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;문제를&amp;nbsp;해결했지만,&amp;nbsp;별로&amp;nbsp;내가&amp;nbsp;좋아하지&amp;nbsp;않는&amp;nbsp;방법이다.&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style2&quot; /&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;다시&amp;nbsp;구글링해서&amp;nbsp;찾아보니&amp;nbsp;내가&amp;nbsp;바보&amp;nbsp;같은&amp;nbsp;짓을&amp;nbsp;했다. &lt;br /&gt;&lt;br /&gt;flutter_blue는&amp;nbsp;0.8.0에서&amp;nbsp;개발을&amp;nbsp;멈춘&amp;nbsp;상태이고,&amp;nbsp;flutter_blue_plus&amp;nbsp;최신&amp;nbsp;버전이&amp;nbsp;있다는&amp;nbsp;것을&amp;nbsp;인제야&amp;nbsp;알게&amp;nbsp;되었다. &lt;br /&gt;&lt;br /&gt;&lt;a href=&quot;https://pub.dev/packages/flutter_blue_plus&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://pub.dev/packages/flutter_blue_plus&lt;/a&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1732453191705&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-ke-align=&quot;alignCenter&quot; data-og-type=&quot;website&quot; data-og-title=&quot;flutter_blue_plus | Flutter package&quot; data-og-description=&quot;Flutter plugin for connecting and communicationg with Bluetooth Low Energy devices, on Android, iOS, and MacOS.&quot; data-og-host=&quot;pub.dev&quot; data-og-source-url=&quot;https://pub.dev/packages/flutter_blue_plus&quot; data-og-url=&quot;https://pub.dev/packages/flutter_blue_plus&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/bdlCS9/hyXDj1hMUN/dbjqljGbhKWlB7V4MGdcCk/img.png?width=1280&amp;amp;height=640&amp;amp;face=0_0_1280_640,https://scrap.kakaocdn.net/dn/s8BzX/hyXDjNLWNp/gUFMchveUwkTcErnWHh4yk/img.png?width=1280&amp;amp;height=640&amp;amp;face=0_0_1280_640&quot;&gt;&lt;a href=&quot;https://pub.dev/packages/flutter_blue_plus&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://pub.dev/packages/flutter_blue_plus&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/bdlCS9/hyXDj1hMUN/dbjqljGbhKWlB7V4MGdcCk/img.png?width=1280&amp;amp;height=640&amp;amp;face=0_0_1280_640,https://scrap.kakaocdn.net/dn/s8BzX/hyXDjNLWNp/gUFMchveUwkTcErnWHh4yk/img.png?width=1280&amp;amp;height=640&amp;amp;face=0_0_1280_640');&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot; data-ke-size=&quot;size16&quot;&gt;flutter_blue_plus | Flutter package&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;Flutter plugin for connecting and communicationg with Bluetooth Low Energy devices, on Android, iOS, and MacOS.&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;pub.dev&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;아래&amp;nbsp;명령어로&amp;nbsp;flutter_blue_plus를&amp;nbsp;설치할&amp;nbsp;수&amp;nbsp;있다.&lt;/p&gt;
&lt;pre id=&quot;code_1732453207648&quot; class=&quot;cpp&quot; data-ke-language=&quot;cpp&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;$ flutter pub add flutter_blue_plus&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;자동적으로&amp;nbsp;pubspec.yaml&amp;nbsp;파일의&amp;nbsp;depencies에&amp;nbsp;추가된다. &lt;/p&gt;
&lt;pre id=&quot;code_1732453226760&quot; class=&quot;cpp&quot; data-ke-language=&quot;cpp&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;dependencies:
  flutter_blue_plus: ^1.1.3&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;plus를&amp;nbsp;사용하니&amp;nbsp;안드로이드&amp;nbsp;12&amp;nbsp;권한&amp;nbsp;문제도&amp;nbsp;자동으로&amp;nbsp;해결된다. &lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style2&quot;&gt;android/app/build.gradle 버전&lt;/blockquote&gt;
&lt;pre id=&quot;code_1732453284495&quot; class=&quot;cpp&quot; data-ke-language=&quot;cpp&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;Android {
  defaultConfig {
     minSdkVersion: 19&lt;/code&gt;&lt;/pre&gt;
&lt;blockquote data-ke-style=&quot;style2&quot;&gt;android/app/src/main/AndroidManifest.xml 권한 추가&lt;/blockquote&gt;
&lt;pre id=&quot;code_1732453322680&quot; class=&quot;cpp&quot; data-ke-language=&quot;cpp&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;&amp;lt;uses-permission android:name=&quot;android.permission.BLUETOOTH&quot; /&amp;gt;  
	 &amp;lt;uses-permission android:name=&quot;android.permission.BLUETOOTH_ADMIN&quot; /&amp;gt;  
	 &amp;lt;uses-permission android:name=&quot;android.permission.ACCESS_COARSE_LOCATION&quot;/&amp;gt;  
 &amp;lt;application&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;flutter_blue_plus&amp;nbsp;관련&amp;nbsp;이슈는&amp;nbsp;아래&amp;nbsp;링크에서&amp;nbsp;참고하여&amp;nbsp;해결할&amp;nbsp;수&amp;nbsp;있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://flutterrepos.com/lib/boskokg-flutter_blue_plus&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://flutterrepos.com/lib/boskokg-flutter_blue_plus&lt;/a&gt;&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style1&quot;&gt;
&lt;p id=&quot;SE-85e9ce59-eb6f-4c5a-984d-7bdc77a67194&quot; style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;해당 프로젝트는 2022년에 진행한 것으로 버전 차이가 존재할 수 있다.&lt;/span&gt;&lt;/p&gt;
&lt;/blockquote&gt;</description>
      <category> Project/✅ BLE Indoor Positioning</category>
      <category>BLE</category>
      <category>flutter</category>
      <category>flutter_blue</category>
      <category>indoor</category>
      <category>IPS</category>
      <category>positioning</category>
      <author>18진수</author>
      <guid isPermaLink="true">https://coding-yoon.tistory.com/290</guid>
      <comments>https://coding-yoon.tistory.com/290#entry290comment</comments>
      <pubDate>Sun, 24 Nov 2024 22:05:16 +0900</pubDate>
    </item>
    <item>
      <title>[STM32] 12. 시리얼 모니터를 위한 UART 통신 구현 (2)</title>
      <link>https://coding-yoon.tistory.com/289</link>
      <description>&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;600&quot; data-origin-height=&quot;600&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/b12IJV/btsKSu3v0Fs/jqdyCdtJSYRnobH0phiLl0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/b12IJV/btsKSu3v0Fs/jqdyCdtJSYRnobH0phiLl0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/b12IJV/btsKSu3v0Fs/jqdyCdtJSYRnobH0phiLl0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fb12IJV%2FbtsKSu3v0Fs%2FjqdyCdtJSYRnobH0phiLl0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;600&quot; height=&quot;600&quot; data-origin-width=&quot;600&quot; data-origin-height=&quot;600&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;⚙️&amp;nbsp;1. UART 설정&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;기본적인&amp;nbsp;UART&amp;nbsp;통신은&amp;nbsp;폴링(Polling)&amp;nbsp;방식으로&amp;nbsp;수행할&amp;nbsp;수&amp;nbsp;있다.&amp;nbsp;폴링&amp;nbsp;방식에서는&amp;nbsp;MCU가&amp;nbsp;계속해서&amp;nbsp;UART&amp;nbsp;상태&amp;nbsp;레지스터를&amp;nbsp;확인하여&amp;nbsp;데이터가&amp;nbsp;수신되었는지&amp;nbsp;또는&amp;nbsp;전송이&amp;nbsp;완료되었는지를&amp;nbsp;확인한다.&amp;nbsp;하지만&amp;nbsp;폴링&amp;nbsp;방식은&amp;nbsp;MCU&amp;nbsp;리소스를&amp;nbsp;많이&amp;nbsp;소비하므로&amp;nbsp;보통은&amp;nbsp;Interrut&amp;nbsp;방식이나&amp;nbsp;DMA&amp;nbsp;방식을&amp;nbsp;주로&amp;nbsp;사용한다.&amp;nbsp;이번&amp;nbsp;글은&amp;nbsp;폴링&amp;nbsp;방식으로&amp;nbsp;간단히&amp;nbsp;구현할&amp;nbsp;수&amp;nbsp;있으므로&amp;nbsp;소개해보려&amp;nbsp;한다. &lt;br /&gt;&lt;br /&gt;이번&amp;nbsp;예제는&amp;nbsp;UART&amp;nbsp;1번을&amp;nbsp;사용한다.&amp;nbsp;(PA10&amp;nbsp;-&amp;nbsp;UART1_RX,&amp;nbsp;PA9&amp;nbsp;-&amp;nbsp;UART1_TX)&amp;nbsp;&amp;nbsp; &lt;br /&gt;&lt;br /&gt;사용된&amp;nbsp;보드는&amp;nbsp;STM32F103이다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock widthContent&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;966&quot; data-origin-height=&quot;529&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/dRFeIr/btsKSmq0OTR/WRfjEBv0xp1yGz1G9X54CK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/dRFeIr/btsKSmq0OTR/WRfjEBv0xp1yGz1G9X54CK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/dRFeIr/btsKSmq0OTR/WRfjEBv0xp1yGz1G9X54CK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FdRFeIr%2FbtsKSmq0OTR%2FWRfjEBv0xp1yGz1G9X54CK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;966&quot; height=&quot;529&quot; data-origin-width=&quot;966&quot; data-origin-height=&quot;529&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;설정은&amp;nbsp;아래와&amp;nbsp;같다.&amp;nbsp;폴링&amp;nbsp;방식을&amp;nbsp;사용하기&amp;nbsp;때문에&amp;nbsp;아래&amp;nbsp;테이블&amp;nbsp;이외에&amp;nbsp;별도로&amp;nbsp;설정할건&amp;nbsp;없다.&lt;/p&gt;
&lt;table border=&quot;1&quot; data-ke-align=&quot;alignLeft&quot;&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td colspan=&quot;1&quot; rowspan=&quot;1&quot;&gt;
&lt;div&gt;&lt;span&gt;&lt;span&gt;&lt;b&gt;Baud Rate&lt;/b&gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;
&lt;/td&gt;
&lt;td colspan=&quot;1&quot; rowspan=&quot;1&quot;&gt;
&lt;div&gt;&lt;span&gt;&lt;span&gt;115200 Bit/s&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td colspan=&quot;1&quot; rowspan=&quot;1&quot;&gt;
&lt;div&gt;&lt;span&gt;&lt;span&gt;&lt;b&gt;World Length&lt;/b&gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;
&lt;/td&gt;
&lt;td colspan=&quot;1&quot; rowspan=&quot;1&quot;&gt;
&lt;div&gt;&lt;span&gt;&lt;span&gt;8 Bits (including Parity)&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td colspan=&quot;1&quot; rowspan=&quot;1&quot;&gt;
&lt;div&gt;&lt;span&gt;&lt;span&gt;&lt;b&gt;Parity&lt;/b&gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;
&lt;/td&gt;
&lt;td colspan=&quot;1&quot; rowspan=&quot;1&quot;&gt;
&lt;div&gt;&lt;span&gt;&lt;span&gt;None&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td colspan=&quot;1&quot; rowspan=&quot;1&quot;&gt;
&lt;div&gt;&lt;span&gt;&lt;span&gt;&lt;b&gt;Stop Bits&lt;/b&gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;
&lt;/td&gt;
&lt;td colspan=&quot;1&quot; rowspan=&quot;1&quot;&gt;
&lt;div&gt;&lt;span&gt;&lt;span&gt;1&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td colspan=&quot;1&quot; rowspan=&quot;1&quot;&gt;
&lt;div&gt;&lt;span&gt;&lt;span&gt;&lt;b&gt;Data Directions&lt;/b&gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;
&lt;/td&gt;
&lt;td colspan=&quot;1&quot; rowspan=&quot;1&quot;&gt;
&lt;div&gt;&lt;span&gt;&lt;span&gt;Receive and Transmit&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td colspan=&quot;1&quot; rowspan=&quot;1&quot;&gt;
&lt;div&gt;&lt;span&gt;&lt;span&gt;&lt;b&gt;Over Sampling&lt;/b&gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;
&lt;/td&gt;
&lt;td colspan=&quot;1&quot; rowspan=&quot;1&quot;&gt;
&lt;div&gt;&lt;span&gt;&lt;span&gt;16 Samples&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;h3 style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size23&quot;&gt;  2. 코드&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이&amp;nbsp;코드는&amp;nbsp;사용자가&amp;nbsp;엔터&amp;nbsp;키를&amp;nbsp;누를&amp;nbsp;때마다&amp;nbsp;입력된&amp;nbsp;문자열을&amp;nbsp;전송하고,&amp;nbsp;그&amp;nbsp;뒤에&amp;nbsp;줄바꿈&amp;nbsp;문자를&amp;nbsp;추가하여&amp;nbsp;터미널&amp;nbsp;창에서&amp;nbsp;출력이&amp;nbsp;깔끔하게&amp;nbsp;줄바꿈되도록&amp;nbsp;한다.&lt;/p&gt;
&lt;pre id=&quot;code_1732256352880&quot; class=&quot;cpp&quot; data-ke-language=&quot;cpp&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;  /* USER CODE BEGIN 2 */

  /* USER CODE END 2 */

  uint8_t received = '\0';
  HAL_StatusTypeDef rcvStat;
  uint8_t enterKey = '\r'; 
  uint8_t newLine[] = &quot;\r\n&quot;; 

  #define MAX_BUFFER_SIZE 100
  uint8_t inputBuffer[MAX_BUFFER_SIZE];
  uint16_t bufferIndex = 0;

  while (1)
  {
	  //HAL_UART_Transmit(&amp;amp;huart1, buf, strlen(buf), 1000);
	  //HAL_Delay(1000);
	    rcvStat = HAL_UART_Receive(&amp;amp;huart1, &amp;amp;received, 1, 10);
	    if(rcvStat == HAL_OK)
	    {
	        // If received character is Enter key
	        if(received == enterKey)
	        {
	            // Transmit the buffered string
	            HAL_UART_Transmit(&amp;amp;huart1, inputBuffer, bufferIndex, 1000);
	            HAL_UART_Transmit(&amp;amp;huart1, newLine, 2, 1000);
	            // Clear the buffer
	            bufferIndex = 0;
	        }
	        else
	        {
	            // Store received character in buffer
	            if(bufferIndex &amp;lt; MAX_BUFFER_SIZE)
	            {
	                inputBuffer[bufferIndex++] = received;
	            }
	        }
	    }
    /* USER CODE END WHILE */

    /* USER CODE BEGIN 3 */
  }&lt;/code&gt;&lt;/pre&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;b&gt;엔터 키 처리:&lt;/b&gt; 수신된 문자가 엔터 키 (\r)일 경우, 버퍼에 저장된 문자열을 UART로 전송한 후, 개행 (\r\n) 문자를 추가로 전송한다.&lt;/li&gt;
&lt;li&gt;&lt;b&gt;개행 문자 추가:&lt;/b&gt; 문자열 뒤에 개행(\r\n) 문자를 추가하여 터미널 창에서 줄바꿈을 보장한다.&lt;/li&gt;
&lt;li&gt;&lt;b&gt;버퍼 관리:&lt;/b&gt; 문자열 전송 후 버퍼를 초기화하여 다음 입력을 받을 준비를 한다.&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;STM32와&amp;nbsp;FTDI의&amp;nbsp;연결은&amp;nbsp;Tx,&amp;nbsp;Rx&amp;nbsp;서로&amp;nbsp;역으로&amp;nbsp;연결하고&amp;nbsp;VCC는&amp;nbsp;별도로&amp;nbsp;연결하지&amp;nbsp;않아도&amp;nbsp;통신은&amp;nbsp;된다.&amp;nbsp;(USB로&amp;nbsp;전원이&amp;nbsp;들어가는&amp;nbsp;듯&amp;nbsp;하다.) &lt;br /&gt;&lt;br /&gt;하지만&amp;nbsp;VCC는&amp;nbsp;연결하지&amp;nbsp;않더라도&amp;nbsp;GND는&amp;nbsp;무조건&amp;nbsp;연결해야&amp;nbsp;한다.&amp;nbsp;(기준점이&amp;nbsp;있어야&amp;nbsp;5V,&amp;nbsp;0V를&amp;nbsp;구분할&amp;nbsp;수&amp;nbsp;있음.)&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock widthContent&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;966&quot; data-origin-height=&quot;477&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/J5s4T/btsKTZVmt7V/BIDb1cqMyy2qQPsGiIrsg0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/J5s4T/btsKTZVmt7V/BIDb1cqMyy2qQPsGiIrsg0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/J5s4T/btsKTZVmt7V/BIDb1cqMyy2qQPsGiIrsg0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FJ5s4T%2FbtsKTZVmt7V%2FBIDb1cqMyy2qQPsGiIrsg0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;966&quot; height=&quot;477&quot; data-origin-width=&quot;966&quot; data-origin-height=&quot;477&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이제 PC에서 시리얼 모니터를 할 수 있는 프로그램을 설치해야 한다. 보통 Putty나 XShell 등을 많이 사용하는데 나는 개인적으로 MobaXterm을 주로 애용한다.&lt;br /&gt;&lt;br /&gt;STM32에서&amp;nbsp;동일하게&amp;nbsp;설정한&amp;nbsp;것과&amp;nbsp;같이&amp;nbsp;시리얼&amp;nbsp;모니터링&amp;nbsp;프로그램에서도&amp;nbsp;설정한다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;68&quot; data-origin-height=&quot;79&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/clxvMd/btsKUjsvEcE/XtYogoqO4w8t32Popfsyd0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/clxvMd/btsKUjsvEcE/XtYogoqO4w8t32Popfsyd0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/clxvMd/btsKUjsvEcE/XtYogoqO4w8t32Popfsyd0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FclxvMd%2FbtsKUjsvEcE%2FXtYogoqO4w8t32Popfsyd0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;68&quot; height=&quot;79&quot; data-origin-width=&quot;68&quot; data-origin-height=&quot;79&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://mobaxterm.mobatek.net/&quot;&gt;https://mobaxterm.mobatek.net/&lt;/a&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1732256541560&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-ke-align=&quot;alignCenter&quot; data-og-type=&quot;website&quot; data-og-title=&quot;MobaXterm free Xserver and tabbed SSH client for Windows&quot; data-og-description=&quot;The ultimate toolbox for remote computing - includes X server, enhanced SSH client and much more!&quot; data-og-host=&quot;mobaxterm.mobatek.net&quot; data-og-source-url=&quot;https://mobaxterm.mobatek.net/&quot; data-og-url=&quot;https://mobaxterm.mobatek.net/&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/crKfUi/hyXDkZQilk/IkPVDeoH0rEkrDrKJUHNZ1/img.png?width=764&amp;amp;height=489&amp;amp;face=0_0_764_489,https://scrap.kakaocdn.net/dn/hpbJq/hyXzTCP1BM/q9uSEjxPsaZvByNkZ9Qcv1/img.png?width=768&amp;amp;height=443&amp;amp;face=0_0_768_443,https://scrap.kakaocdn.net/dn/5gtwN/hyXzH3vSaX/sfRijGKQg1vo7nhFhHEomK/img.png?width=768&amp;amp;height=443&amp;amp;face=0_0_768_443&quot;&gt;&lt;a href=&quot;https://mobaxterm.mobatek.net/&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://mobaxterm.mobatek.net/&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/crKfUi/hyXDkZQilk/IkPVDeoH0rEkrDrKJUHNZ1/img.png?width=764&amp;amp;height=489&amp;amp;face=0_0_764_489,https://scrap.kakaocdn.net/dn/hpbJq/hyXzTCP1BM/q9uSEjxPsaZvByNkZ9Qcv1/img.png?width=768&amp;amp;height=443&amp;amp;face=0_0_768_443,https://scrap.kakaocdn.net/dn/5gtwN/hyXzH3vSaX/sfRijGKQg1vo7nhFhHEomK/img.png?width=768&amp;amp;height=443&amp;amp;face=0_0_768_443');&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot; data-ke-size=&quot;size16&quot;&gt;MobaXterm free Xserver and tabbed SSH client for Windows&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;The ultimate toolbox for remote computing - includes X server, enhanced SSH client and much more!&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;mobaxterm.mobatek.net&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock widthContent&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;898&quot; data-origin-height=&quot;604&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bJAbeO/btsKR4xuR1X/TPgNDgNCRy4HpJtKOVDIu1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bJAbeO/btsKR4xuR1X/TPgNDgNCRy4HpJtKOVDIu1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bJAbeO/btsKR4xuR1X/TPgNDgNCRy4HpJtKOVDIu1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbJAbeO%2FbtsKR4xuR1X%2FTPgNDgNCRy4HpJtKOVDIu1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;898&quot; height=&quot;604&quot; data-origin-width=&quot;898&quot; data-origin-height=&quot;604&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;h3 style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size23&quot;&gt;  3. 결과&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;background-color: #ffffff; color: #000000; text-align: left;&quot;&gt;시리얼 모니터에 값이 입력한대로 출력되는 것을 확인할 수 있다.&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock widthContent&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;966&quot; data-origin-height=&quot;695&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cgeM4Z/btsKTAIrZoh/BLb7SEPmdpTgQn6lnBSbE1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cgeM4Z/btsKTAIrZoh/BLb7SEPmdpTgQn6lnBSbE1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cgeM4Z/btsKTAIrZoh/BLb7SEPmdpTgQn6lnBSbE1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FcgeM4Z%2FbtsKTAIrZoh%2FBLb7SEPmdpTgQn6lnBSbE1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;966&quot; height=&quot;695&quot; data-origin-width=&quot;966&quot; data-origin-height=&quot;695&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;</description>
      <category>  STM32</category>
      <category>polling</category>
      <category>STM32</category>
      <category>UART</category>
      <author>18진수</author>
      <guid isPermaLink="true">https://coding-yoon.tistory.com/289</guid>
      <comments>https://coding-yoon.tistory.com/289#entry289comment</comments>
      <pubDate>Fri, 22 Nov 2024 15:23:59 +0900</pubDate>
    </item>
    <item>
      <title>[STM32] 11. 시리얼 모니터를 위한 UART 통신 구현 (1) FTDI (UART To USB)</title>
      <link>https://coding-yoon.tistory.com/288</link>
      <description>&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;600&quot; data-origin-height=&quot;600&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/13IJr/btsKSQd1UIA/Fe18TgPlkSNmIiGJ9xb5I1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/13IJr/btsKSQd1UIA/Fe18TgPlkSNmIiGJ9xb5I1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/13IJr/btsKSQd1UIA/Fe18TgPlkSNmIiGJ9xb5I1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2F13IJr%2FbtsKSQd1UIA%2FFe18TgPlkSNmIiGJ9xb5I1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;600&quot; height=&quot;600&quot; data-origin-width=&quot;600&quot; data-origin-height=&quot;600&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;FTDI&amp;nbsp;&lt;/b&gt;(Future&amp;nbsp;Technology&amp;nbsp;Devices&amp;nbsp;International&amp;nbsp;Ltd.)는&amp;nbsp;주로&amp;nbsp;&lt;b&gt;UART&amp;nbsp;&lt;/b&gt;(Universal&amp;nbsp;Asynchronous&amp;nbsp;Receiver-Transmitter)&amp;nbsp;신호를&amp;nbsp;USB&amp;nbsp;(Universal&amp;nbsp;Serial&amp;nbsp;Bus)로&amp;nbsp;변환하는데&amp;nbsp;사용되는&amp;nbsp;&lt;b&gt;IC&lt;/b&gt;&amp;nbsp;(Integrated&amp;nbsp;Circuit)&amp;nbsp;칩을&amp;nbsp;제조하는&amp;nbsp;회사이다.&amp;nbsp;&lt;b&gt;FTDI&amp;nbsp;&lt;/b&gt;칩을&amp;nbsp;사용하면&amp;nbsp;UART를&amp;nbsp;사용하는&amp;nbsp;장치를&amp;nbsp;USB&amp;nbsp;포트에&amp;nbsp;연결할&amp;nbsp;수&amp;nbsp;있다. &lt;br /&gt;&lt;br /&gt;임베디드&amp;nbsp;시스템에서&amp;nbsp;printf&amp;nbsp;함수를&amp;nbsp;사용하는&amp;nbsp;것은&amp;nbsp;디버깅,&amp;nbsp;로깅,&amp;nbsp;상태&amp;nbsp;확인&amp;nbsp;등을&amp;nbsp;위해&amp;nbsp;매우&amp;nbsp;유용하다.&amp;nbsp;printf&amp;nbsp;함수는&amp;nbsp;표준&amp;nbsp;C&amp;nbsp;라이브러리&amp;nbsp;함수로,&amp;nbsp;포맷된&amp;nbsp;출력을&amp;nbsp;생성하여&amp;nbsp;콘솔이나&amp;nbsp;터미널에&amp;nbsp;문자열을&amp;nbsp;출력하는데&amp;nbsp;사용된다.&amp;nbsp;그러나&amp;nbsp;임베디드&amp;nbsp;시스템에서는&amp;nbsp;일반적으로&amp;nbsp;디스플레이나&amp;nbsp;콘솔이&amp;nbsp;없기&amp;nbsp;때문에,&amp;nbsp;&lt;b&gt;UART&amp;nbsp;&lt;/b&gt;(Universal&amp;nbsp;Asynchronous&amp;nbsp;Receiver-Transmitter)&amp;nbsp;인터페이스를&amp;nbsp;통해&amp;nbsp;시리얼&amp;nbsp;통신을&amp;nbsp;사용하여&amp;nbsp;출력을&amp;nbsp;컴퓨터나&amp;nbsp;다른&amp;nbsp;디버깅&amp;nbsp;장치로&amp;nbsp;전송하는&amp;nbsp;경우가&amp;nbsp;많다.&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;b&gt;하드웨어 설정&lt;/b&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;마이크로컨트롤러의 UART 핀을 FTDI 칩의 UART 핀에 연결한다.&lt;/li&gt;
&lt;li&gt;FTDI 칩의 USB 포트를 컴퓨터에 연결하여, 컴퓨터가 USB를 통해 시리얼 데이터를 수신할 수 있도록 한다.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;b&gt;드라이버 설치&lt;/b&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;컴퓨터에 FTDI 드라이버를 설치한다. 드라이버는 FTDI의 공식 웹사이트에서 다운로드할 수 있다. 드라이버를 설치하면 컴퓨터의 장치 관리자에서 가상 COM 포트로 FTDI 장치가 나타난다.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;b&gt;소프트웨어 설정&lt;/b&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;임베디드 시스템의 펌웨어에서 UART를 초기화한다. UART 초기화 과정은 UART 속도(baud rate), 데이터 비트, 패리티 비트, 정지 비트 등을 설정하는 것이다.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;보통&amp;nbsp;STM32를&amp;nbsp;통해&amp;nbsp;콘솔에서&amp;nbsp;명령어를&amp;nbsp;주고&amp;nbsp;받을&amp;nbsp;때&amp;nbsp;보통&amp;nbsp;아래와&amp;nbsp;그림과&amp;nbsp;같다.&amp;nbsp;UART&amp;nbsp;To&amp;nbsp;USB가&amp;nbsp;UART&amp;nbsp;테스트를&amp;nbsp;할&amp;nbsp;때,&amp;nbsp;굉장히&amp;nbsp;좋은&amp;nbsp;점은&amp;nbsp;FTDI를&amp;nbsp;연결했을&amp;nbsp;때,&amp;nbsp;컴퓨터에서&amp;nbsp;장치&amp;nbsp;관리자로&amp;nbsp;손쉽게&amp;nbsp;접근하여&amp;nbsp;제어할&amp;nbsp;수&amp;nbsp;있다는&amp;nbsp;점이다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;781&quot; data-origin-height=&quot;572&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bDky91/btsKTG9yYRj/lrT96eq5E4iQcUtDBHJDv1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bDky91/btsKTG9yYRj/lrT96eq5E4iQcUtDBHJDv1/img.png&quot; data-alt=&quot;장치 관리자&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bDky91/btsKTG9yYRj/lrT96eq5E4iQcUtDBHJDv1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbDky91%2FbtsKTG9yYRj%2FlrT96eq5E4iQcUtDBHJDv1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;781&quot; height=&quot;572&quot; data-origin-width=&quot;781&quot; data-origin-height=&quot;572&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;장치 관리자&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;figure class=&quot;imageblock widthContent&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;966&quot; data-origin-height=&quot;317&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/AbvSR/btsKRDNxqjb/mitFbd47GcQV1a6kbWCCyk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/AbvSR/btsKRDNxqjb/mitFbd47GcQV1a6kbWCCyk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/AbvSR/btsKRDNxqjb/mitFbd47GcQV1a6kbWCCyk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FAbvSR%2FbtsKRDNxqjb%2FmitFbd47GcQV1a6kbWCCyk%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;966&quot; height=&quot;317&quot; data-origin-width=&quot;966&quot; data-origin-height=&quot;317&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;아래는&amp;nbsp;FTDI&amp;nbsp;제품이다.&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock widthContent&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1212&quot; data-origin-height=&quot;466&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/BUdpZ/btsKUfDHsCr/UGSi1FOQrXzZDfFfvhmlw1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/BUdpZ/btsKUfDHsCr/UGSi1FOQrXzZDfFfvhmlw1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/BUdpZ/btsKUfDHsCr/UGSi1FOQrXzZDfFfvhmlw1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FBUdpZ%2FbtsKUfDHsCr%2FUGSi1FOQrXzZDfFfvhmlw1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1212&quot; height=&quot;466&quot; data-origin-width=&quot;1212&quot; data-origin-height=&quot;466&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;figure class=&quot;imagegridblock&quot;&gt;
  &lt;div class=&quot;image-container&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/ckENSI/btsKSFRpcqq/QtIa6lOoYl6mRfnYMNx3A1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/ckENSI/btsKSFRpcqq/QtIa6lOoYl6mRfnYMNx3A1/img.png&quot; data-origin-width=&quot;466&quot; data-origin-height=&quot;621&quot; data-is-animation=&quot;false&quot; style=&quot;width: 49.4186%; margin-right: 10px;&quot; data-widthpercent=&quot;50&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/ckENSI/btsKSFRpcqq/QtIa6lOoYl6mRfnYMNx3A1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FckENSI%2FbtsKSFRpcqq%2FQtIa6lOoYl6mRfnYMNx3A1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;466&quot; height=&quot;621&quot;/&gt;&lt;/span&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/v6OQJ/btsKT5BfkT3/O15a58NBpnOjBKMAnZhkV1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/v6OQJ/btsKT5BfkT3/O15a58NBpnOjBKMAnZhkV1/img.png&quot; data-origin-width=&quot;466&quot; data-origin-height=&quot;621&quot; data-is-animation=&quot;false&quot; style=&quot;width: 49.4186%;&quot; data-widthpercent=&quot;50&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/v6OQJ/btsKT5BfkT3/O15a58NBpnOjBKMAnZhkV1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fv6OQJ%2FbtsKT5BfkT3%2FO15a58NBpnOjBKMAnZhkV1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;466&quot; height=&quot;621&quot;/&gt;&lt;/span&gt;&lt;/div&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이&amp;nbsp;제품의&amp;nbsp;장점으로는&amp;nbsp;VCC&amp;nbsp;(5V,&amp;nbsp;3.3V)&amp;nbsp;고를&amp;nbsp;수&amp;nbsp;있다는&amp;nbsp;장점이&amp;nbsp;있고,&amp;nbsp;FTDI에서&amp;nbsp;Tx,&amp;nbsp;Rx&amp;nbsp;Signal이&amp;nbsp;들어올&amp;nbsp;때마다&amp;nbsp;해당&amp;nbsp;LED가&amp;nbsp;불이&amp;nbsp;들어와서&amp;nbsp;디버깅할&amp;nbsp;때&amp;nbsp;편하다.&amp;nbsp; &lt;br /&gt;&lt;br /&gt;다음&amp;nbsp;글은&amp;nbsp;해당&amp;nbsp;FTDI&amp;nbsp;제품을&amp;nbsp;이용하여&amp;nbsp;UART&amp;nbsp;테스트를&amp;nbsp;진행해보려&amp;nbsp;한다.&lt;/p&gt;</description>
      <category>  STM32</category>
      <category>FTDI</category>
      <category>STM32</category>
      <category>UART</category>
      <category>구현</category>
      <author>18진수</author>
      <guid isPermaLink="true">https://coding-yoon.tistory.com/288</guid>
      <comments>https://coding-yoon.tistory.com/288#entry288comment</comments>
      <pubDate>Fri, 22 Nov 2024 15:08:28 +0900</pubDate>
    </item>
    <item>
      <title>[STM32] 10. UART, USART 동작 원리 설명</title>
      <link>https://coding-yoon.tistory.com/287</link>
      <description>&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;600&quot; data-origin-height=&quot;600&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/xpodL/btsKSKkvHcZ/3pDJp2Je3RumWLivEGvZwK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/xpodL/btsKSKkvHcZ/3pDJp2Je3RumWLivEGvZwK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/xpodL/btsKSKkvHcZ/3pDJp2Je3RumWLivEGvZwK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FxpodL%2FbtsKSKkvHcZ%2F3pDJp2Je3RumWLivEGvZwK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;600&quot; height=&quot;600&quot; data-origin-width=&quot;600&quot; data-origin-height=&quot;600&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;UART/USART 설명&lt;/h2&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;  1. UART (Universal Asynchronous Receiver/Transmitter) 란?&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;UART&lt;/b&gt;는&amp;nbsp;Universal&amp;nbsp;Asynchronous&amp;nbsp;Receiver/Transmitter의&amp;nbsp;약자로,&amp;nbsp;직렬&amp;nbsp;통신을&amp;nbsp;위한&amp;nbsp;하드웨어&amp;nbsp;프로토콜이다.&amp;nbsp;UART는&amp;nbsp;데이터를&amp;nbsp;두&amp;nbsp;개의&amp;nbsp;핀,&amp;nbsp;송신(&lt;i&gt;Tx&lt;/i&gt;)과&amp;nbsp;수신(&lt;i&gt;Rx&lt;/i&gt;)을&amp;nbsp;통해&amp;nbsp;비동기적으로&amp;nbsp;전송한다.&amp;nbsp;비동기식&amp;nbsp;통신이란&amp;nbsp;송신&amp;nbsp;측과&amp;nbsp;수신&amp;nbsp;측&amp;nbsp;간의&amp;nbsp;동기화를&amp;nbsp;위해&amp;nbsp;별도의&amp;nbsp;클럭&amp;nbsp;신호가&amp;nbsp;필요하지&amp;nbsp;않은&amp;nbsp;통신&amp;nbsp;방식을&amp;nbsp;의미한다.&amp;nbsp;보통&amp;nbsp;기본&amp;nbsp;C언어에서&amp;nbsp;printf를&amp;nbsp;구현할&amp;nbsp;때&amp;nbsp;많이들&amp;nbsp;소개하므로&amp;nbsp;기본적인&amp;nbsp;동작을&amp;nbsp;알아두면&amp;nbsp;좋다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;582&quot; data-origin-height=&quot;211&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/uiALT/btsKS3RIX0O/XAd8B9fWiNFETzBYdQ8kok/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/uiALT/btsKS3RIX0O/XAd8B9fWiNFETzBYdQ8kok/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/uiALT/btsKS3RIX0O/XAd8B9fWiNFETzBYdQ8kok/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FuiALT%2FbtsKS3RIX0O%2FXAd8B9fWiNFETzBYdQ8kok%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;582&quot; height=&quot;211&quot; data-origin-width=&quot;582&quot; data-origin-height=&quot;211&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;200&quot; data-origin-height=&quot;125&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bvC9cw/btsKSELDdIS/aNiJ8BEJyuG8UZO4oxwcA1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bvC9cw/btsKSELDdIS/aNiJ8BEJyuG8UZO4oxwcA1/img.png&quot; data-alt=&quot;기본 UART 회로 구성&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bvC9cw/btsKSELDdIS/aNiJ8BEJyuG8UZO4oxwcA1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbvC9cw%2FbtsKSELDdIS%2FaNiJ8BEJyuG8UZO4oxwcA1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;200&quot; height=&quot;125&quot; data-origin-width=&quot;200&quot; data-origin-height=&quot;125&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;기본 UART 회로 구성&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;h3 style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size23&quot;&gt; &lt;span&gt;&amp;nbsp;&lt;/span&gt;2. UART의 기본 작동 원리&lt;/h3&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;b&gt;비동기 통신:&lt;/b&gt; 별도의 클럭 신호 없이 송신기와 수신기가 동일한 전송 속도(&lt;b&gt;baud rate&lt;/b&gt;)로 설정되어야 한다.&lt;/li&gt;
&lt;li&gt;&lt;b&gt;전송 속도(Baud Rate):&lt;/b&gt; 일반적으로 9600, 19200, 38400, 57600, 115200 baud 등이 사용된다.&lt;/li&gt;
&lt;li&gt;&lt;b&gt;단방향 또는 양방향 통신:&lt;/b&gt; UART는 반이중(&lt;b&gt;half-duplex&lt;/b&gt;) 또는 전이중(&lt;b&gt;full-duplex&lt;/b&gt;) 통신을 지원한다.&lt;/li&gt;
&lt;li&gt;&lt;b&gt;단순한 배선:&lt;/b&gt; 데이터 전송을 위해 두 개의 핀만 필요하다.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;578&quot; data-origin-height=&quot;244&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/d8yr7p/btsKTlYVrIV/E1baOnEr2EPPYf6NxJLTN0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/d8yr7p/btsKTlYVrIV/E1baOnEr2EPPYf6NxJLTN0/img.png&quot; data-alt=&quot;비동기 통신을 이용할 때 전송 속도에 따른 비트를 구분하는 타이밍 문제&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/d8yr7p/btsKTlYVrIV/E1baOnEr2EPPYf6NxJLTN0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fd8yr7p%2FbtsKTlYVrIV%2FE1baOnEr2EPPYf6NxJLTN0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;578&quot; height=&quot;244&quot; data-origin-width=&quot;578&quot; data-origin-height=&quot;244&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;비동기 통신을 이용할 때 전송 속도에 따른 비트를 구분하는 타이밍 문제&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;h3 style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size23&quot;&gt; &lt;span&gt; 3&lt;/span&gt;.&lt;span&gt; &amp;nbsp;&lt;/span&gt;보안&amp;nbsp;고려사항&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;많은 산업용 시스템에서 UART 포트는 디버깅 및 유지보수를 위해 사용되지만, 보안 취약점을 막기 위해 다음과 같은 조치를 취하는 경우가 많다.&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;b&gt;디버깅 포트 비활성화:&lt;/b&gt; 제품 출하 시, 디버깅 포트를 비활성화하거나 제거한다.&lt;/li&gt;
&lt;li&gt;&lt;b&gt;펌웨어 보안: &lt;/b&gt;UART를 통한 펌웨어 업데이트 시, 디지털 서명 및 암호화된 펌웨어를 사용한다.&lt;/li&gt;
&lt;li&gt;&lt;b&gt;네트워크 방화벽:&lt;/b&gt; 네트워크 연결된 UART의 경우, 방화벽을 설정하여 불법 접근을 방지한다.&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size23&quot;&gt; &lt;span&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;4&lt;/span&gt;.&lt;span&gt;&lt;span&gt; &amp;nbsp;&lt;/span&gt;&lt;/span&gt;USART&amp;nbsp;(Universal&amp;nbsp;Synchronous/Asynchronous&amp;nbsp;Receiver/Transmitter)&amp;nbsp;란?&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;USART는&amp;nbsp;Universal&amp;nbsp;Synchronous/Asynchronous&amp;nbsp;Receiver/Transmitter의&amp;nbsp;약자로,&amp;nbsp;비동기&amp;nbsp;통신(UART)와&amp;nbsp;다르게&amp;nbsp;&amp;nbsp;동기&amp;nbsp;통신을&amp;nbsp;지원하는&amp;nbsp;직렬&amp;nbsp;통신&amp;nbsp;인터페이스이다.&amp;nbsp;USART는&amp;nbsp;클럭&amp;nbsp;신호를&amp;nbsp;사용하여&amp;nbsp;송신기와&amp;nbsp;수신기를&amp;nbsp;동기화함으로써&amp;nbsp;더&amp;nbsp;빠르고&amp;nbsp;안정적인&amp;nbsp;데이터&amp;nbsp;전송을&amp;nbsp;제공한다. &lt;br /&gt;&lt;br /&gt;동기 통신에서는 데이터 전송을 위해 추가적인 클럭 신호를 사용한다. USART는 송신기와 수신기 간의 클럭 신호를 통해 정확한 타이밍으로 데이터를 전송하고 수신할 수 있다.&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;b&gt;동기/비동기 통신 지원:&lt;/b&gt; USART는 클럭 신호를 사용한 동기 통신과 클럭 신호 없이 데이터 전송 속도(&lt;b&gt;baud rate&lt;/b&gt;)로 설정된 비동기 통신(UART)을 모두 지원한다.&lt;/li&gt;
&lt;li&gt;&lt;b&gt;더 빠른 전송 속도:&lt;/b&gt; 동기 통신에서는 클럭 신호를 사용하여 데이터 전송이 이루어지므로, 비동기 통신보다 더 빠르고 안정적인 데이터 전송이 가능하다.&lt;/li&gt;
&lt;li&gt;&lt;b&gt;Full-duplex &amp;nbsp;통신:&lt;/b&gt; 동기 모드에서는 송신과 수신이 동시에 이루어질 수 있다.&lt;/li&gt;
&lt;li&gt;&lt;b&gt;클럭 신호 라인:&lt;/b&gt; 동기 통신에서는 추가적인 클럭 신호 라인(예: SCLK)이 필요하다.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;492&quot; data-origin-height=&quot;128&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bqM3B3/btsKS6npSBC/pPlDShip1RR9OSLYpKhqr1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bqM3B3/btsKS6npSBC/pPlDShip1RR9OSLYpKhqr1/img.png&quot; data-alt=&quot;CLOCK 선을 통한 동기 방식&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bqM3B3/btsKS6npSBC/pPlDShip1RR9OSLYpKhqr1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbqM3B3%2FbtsKS6npSBC%2FpPlDShip1RR9OSLYpKhqr1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;492&quot; height=&quot;128&quot; data-origin-width=&quot;492&quot; data-origin-height=&quot;128&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;CLOCK 선을 통한 동기 방식&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;h3 style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size23&quot;&gt; &lt;span&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;5&lt;/span&gt;. 동기 통신의 장단점&lt;/h3&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;⚙️ 장점&lt;/h4&gt;
&lt;ul style=&quot;list-style-type: circle;&quot; data-ke-list-type=&quot;circle&quot;&gt;
&lt;li&gt;&lt;b&gt;높은 전송 속도:&lt;/b&gt; 클럭 신호를 사용하여 더 높은 데이터 전송 속도를 구현할 수 있다.&lt;/li&gt;
&lt;li&gt;&lt;b&gt;안정성:&lt;/b&gt; 클럭 신호에 의해 동기화되므로 데이터 전송의 안정성이 높다.&lt;/li&gt;
&lt;li&gt;&lt;b&gt;노이즈&amp;nbsp;저항성:&lt;/b&gt;&amp;nbsp;동기화된&amp;nbsp;클럭&amp;nbsp;신호로&amp;nbsp;인해&amp;nbsp;외부&amp;nbsp;노이즈에&amp;nbsp;강하다.&lt;/li&gt;
&lt;/ul&gt;
&lt;h4 style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size20&quot;&gt;⚙️ 단점&lt;/h4&gt;
&lt;ul style=&quot;list-style-type: circle;&quot; data-ke-list-type=&quot;circle&quot;&gt;
&lt;li&gt;&lt;b&gt;복잡성:&lt;/b&gt; 추가적인 클럭 신호 라인이 필요하여 배선이 복잡해질 수 있다.&lt;/li&gt;
&lt;li&gt;&lt;b&gt;하드웨어 요구 사항:&lt;/b&gt; 클럭 신호 생성 및 처리를 위한 추가적인 하드웨어가 필요하다.&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size23&quot;&gt; &lt;span&gt;&lt;span&gt; 6. UART와 USART 비교&lt;/span&gt;&lt;/span&gt;&lt;/h3&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;b&gt;UART:&lt;/b&gt; 클럭 신호 없이 비동기 통신만 지원.&lt;/li&gt;
&lt;li&gt;&lt;b&gt;USART:&lt;/b&gt; 클럭 신호를 사용한 동기 통신과 클럭 신호 없이 비동기 통신을 모두 지원.&lt;/li&gt;
&lt;li&gt;USART는 동기 통신의 장점을 살려 더 높은 전송 속도와 안정성을 제공하며, 다양한 산업용 애플리케이션에서 널리 사용된다. 반면, 단순한 배선과 구현의 용이성을 원한다면 UART가 더 적합할 수 있다.&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>  STM32</category>
      <category>STM32</category>
      <category>UART</category>
      <category>usart</category>
      <category>비교</category>
      <category>설명</category>
      <author>18진수</author>
      <guid isPermaLink="true">https://coding-yoon.tistory.com/287</guid>
      <comments>https://coding-yoon.tistory.com/287#entry287comment</comments>
      <pubDate>Fri, 22 Nov 2024 14:55:13 +0900</pubDate>
    </item>
    <item>
      <title>[STM32] 9. Volatile 키워드</title>
      <link>https://coding-yoon.tistory.com/286</link>
      <description>&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;600&quot; data-origin-height=&quot;600&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cGYwjY/btsKTXC4GxH/AcCeDfEmMCYVjQFdBT0vHK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cGYwjY/btsKTXC4GxH/AcCeDfEmMCYVjQFdBT0vHK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cGYwjY/btsKTXC4GxH/AcCeDfEmMCYVjQFdBT0vHK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FcGYwjY%2FbtsKTXC4GxH%2FAcCeDfEmMCYVjQFdBT0vHK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;600&quot; height=&quot;600&quot; data-origin-width=&quot;600&quot; data-origin-height=&quot;600&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;Volatile 키워드&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;C 언어에서 &lt;b&gt;volatile&lt;/b&gt; 키워드는 임베디드 소프트웨어 개발에서 중요한 역할을 한다. 이 키워드는 변수가 최적화 과정에서 컴파일러에 의해 수정되지 않도록 보장하며, 프로그램의 실행 도중에 변수의 값이 예상치 못하게 변경될 수 있다는 것을 컴파일러에 알린다. 이러한 변경은 외부 이벤트나 하드웨어 등에 의해 발생할 수 있다.&lt;br /&gt;&lt;br /&gt;C&amp;nbsp;언어에서&amp;nbsp;&lt;b&gt;volatile&amp;nbsp;&lt;/b&gt;키워드는&amp;nbsp;임베디드&amp;nbsp;소프트웨어&amp;nbsp;개발에서&amp;nbsp;중요한&amp;nbsp;역할을&amp;nbsp;한다.&amp;nbsp;이&amp;nbsp;키워드는&amp;nbsp;변수가&amp;nbsp;최적화&amp;nbsp;과정에서&amp;nbsp;컴파일러에&amp;nbsp;의해&amp;nbsp;수정되지&amp;nbsp;않도록&amp;nbsp;보장하며,&amp;nbsp;프로그램의&amp;nbsp;실행&amp;nbsp;도중에&amp;nbsp;변수의&amp;nbsp;값이&amp;nbsp;예상치&amp;nbsp;못하게&amp;nbsp;변경될&amp;nbsp;수&amp;nbsp;있다는&amp;nbsp;것을&amp;nbsp;컴파일러에&amp;nbsp;알린다.&amp;nbsp;이러한&amp;nbsp;변경은&amp;nbsp;외부&amp;nbsp;이벤트나&amp;nbsp;하드웨어&amp;nbsp;등에&amp;nbsp;의해&amp;nbsp;발생할&amp;nbsp;수&amp;nbsp;있다.&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;  1. volatile의 중요성&lt;/h3&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;b&gt;메모리 맵핑된 입출력:&lt;/b&gt; 임베디드 시스템에서는 하드웨어 장치를 메모리 주소에 매핑하여 제어하는 경우가 많다. volatile은 이러한 메모리 주소에 위치한 데이터가 언제든지 변경될 수 있음을 나타내므로, 컴파일러가 해당 변수에 대한 접근을 최적화하지 않도록 한다.&lt;/li&gt;
&lt;li&gt;&lt;b&gt;인터럽트 서비스 루틴:&lt;/b&gt; 인터럽트 서비스 루틴(&lt;b&gt;ISR&lt;/b&gt;)에서 사용되는 변수는 인터럽트에 의해 언제든지 변경될 수 있다. 이런 변수들을 volatile로 선언함으로써, 컴파일러는 이 변수들을 캐싱하지 않고 항상 메모리에서 직접 읽거나 쓰도록 처리한다.&lt;/li&gt;
&lt;li&gt;&lt;b&gt;멀티 스레딩:&lt;/b&gt; 여러 스레드나 프로세스가 동일한 변수를 공유할 때, 한 스레드에서의 변경이 다른 스레드에 즉시 보이도록 하기 위해 &lt;b&gt;volatile&lt;/b&gt;을 사용할 수 있다. 그러나, &lt;b&gt;volatile&lt;/b&gt;은 동시성을 완전히 관리하지는 못하므로 일반적으로는 락이나 다른 동기화 메커니즘과 함께 사용해야 한다.&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;  2. 코드&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;다음은&amp;nbsp;volatile&amp;nbsp;키워드가&amp;nbsp;사용된&amp;nbsp;C&amp;nbsp;코드의&amp;nbsp;예제이다. &lt;br /&gt;&lt;br /&gt;이&amp;nbsp;코드에서&amp;nbsp;flag&amp;nbsp;변수는&amp;nbsp;외부&amp;nbsp;이벤트(가정된&amp;nbsp;인터럽트)에&amp;nbsp;의해&amp;nbsp;언제든지&amp;nbsp;변경될&amp;nbsp;수&amp;nbsp;있으므로&amp;nbsp;volatile로&amp;nbsp;선언되어&amp;nbsp;있다.&amp;nbsp;이는&amp;nbsp;컴파일러에게&amp;nbsp;flag&amp;nbsp;변수의&amp;nbsp;값을&amp;nbsp;캐시하지&amp;nbsp;말고&amp;nbsp;매번&amp;nbsp;메모리에서&amp;nbsp;직접&amp;nbsp;읽어야&amp;nbsp;함을&amp;nbsp;알린다.&lt;/p&gt;
&lt;pre id=&quot;code_1732253338322&quot; class=&quot;cpp&quot; data-ke-language=&quot;cpp&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;#include &amp;lt;stdio.h&amp;gt;

// 가정: 외부 하드웨어 이벤트에 의해 변경될 수 있는 변수
volatile int flag = 0;

// 인터럽트 서비스 루틴이라고 가정
void interrupt_handler() {
    flag = 1;  // 인터럽트 발생 시 flag를 1로 설정
}

int main() {
    while (flag == 0) {
        // flag 값이 변경될 때까지 기다림
    }
    printf(&quot;Flag was set!\n&quot;);
    return 0;
}&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;만약&amp;nbsp;코드에서&amp;nbsp;&lt;b&gt;flag&lt;/b&gt;&amp;nbsp;변수를&amp;nbsp;&lt;b&gt;volatile&lt;/b&gt;로&amp;nbsp;선언하지&amp;nbsp;않는다면,&amp;nbsp;컴파일러가&amp;nbsp;최적화&amp;nbsp;과정에서&amp;nbsp;이&amp;nbsp;변수의&amp;nbsp;사용&amp;nbsp;방식을&amp;nbsp;잘못&amp;nbsp;해석할&amp;nbsp;수&amp;nbsp;있다.&amp;nbsp;컴파일러는&amp;nbsp;코드를&amp;nbsp;최적화할&amp;nbsp;때&amp;nbsp;변수&amp;nbsp;값이&amp;nbsp;변경되지&amp;nbsp;않을&amp;nbsp;것으로&amp;nbsp;예측하여,&amp;nbsp;메모리에서&amp;nbsp;매번&amp;nbsp;변수를&amp;nbsp;읽지&amp;nbsp;않고&amp;nbsp;대신&amp;nbsp;레지스터에&amp;nbsp;값을&amp;nbsp;저장할&amp;nbsp;수&amp;nbsp;있다.&amp;nbsp;이&amp;nbsp;경우,&amp;nbsp;flag&amp;nbsp;변수의&amp;nbsp;값이&amp;nbsp;외부&amp;nbsp;이벤트(예를&amp;nbsp;들어,&amp;nbsp;인터럽트)에&amp;nbsp;의해&amp;nbsp;변경되었음에도&amp;nbsp;불구하고,&amp;nbsp;메인&amp;nbsp;함수의&amp;nbsp;&lt;b&gt;while&amp;nbsp;&lt;/b&gt;루프는&amp;nbsp;레지스터에&amp;nbsp;저장된&amp;nbsp;구식&amp;nbsp;값에&amp;nbsp;의존하여&amp;nbsp;계속해서&amp;nbsp;무한&amp;nbsp;루프에&amp;nbsp;빠질&amp;nbsp;수&amp;nbsp;있다. &lt;br /&gt;&lt;br /&gt;이는&amp;nbsp;프로그램이&amp;nbsp;&lt;b&gt;flag&amp;nbsp;&lt;/b&gt;변수의&amp;nbsp;변화를&amp;nbsp;감지하지&amp;nbsp;못하고,&amp;nbsp;while&amp;nbsp;루프에서&amp;nbsp;탈출하지&amp;nbsp;못하는&amp;nbsp;상황으로&amp;nbsp;이어질&amp;nbsp;수&amp;nbsp;있다.&amp;nbsp;결과적으로&amp;nbsp;프로그램이&amp;nbsp;&quot;&lt;b&gt;hang&lt;/b&gt;&quot;되거나&amp;nbsp;예상치&amp;nbsp;못한&amp;nbsp;동작을&amp;nbsp;할&amp;nbsp;수&amp;nbsp;있다.&lt;/p&gt;
&lt;h3 style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size23&quot;&gt;  3. 주의사항&lt;/h3&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;b&gt;불필요한 사용:&lt;/b&gt; &lt;b&gt;volatile&lt;/b&gt;은 필요한 곳에만 사용해야 한다. 불필요하게 사용하면 프로그램의 성능이 저하될 수 있다.&lt;/li&gt;
&lt;li&gt;&lt;b&gt;동시성 제어 미흡:&lt;/b&gt; &lt;b&gt;volatile&lt;/b&gt;만으로는 멀티 스레딩 환경에서의 동시성 문제를 해결할 수 없다. 동기화 메커니즘이 필요하다.&lt;/li&gt;
&lt;li&gt;&lt;b&gt;컴파일러 의존성:&lt;/b&gt; &lt;b&gt;volatile&lt;/b&gt;의 효과는 컴파일러마다 약간씩 다를 수 있으므로, 사용하는 컴파일러의 문서를 참고하는 것이 좋다.&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;volatile&amp;nbsp;키워드의&amp;nbsp;사용은&amp;nbsp;임베디드&amp;nbsp;시스템의&amp;nbsp;신뢰성을&amp;nbsp;높이고&amp;nbsp;하드웨어와의&amp;nbsp;상호&amp;nbsp;작용을&amp;nbsp;정확하게&amp;nbsp;제어하는&amp;nbsp;데&amp;nbsp;중요한&amp;nbsp;역할을&amp;nbsp;한다.&lt;/p&gt;</description>
      <category>  STM32</category>
      <category>c</category>
      <category>STM32</category>
      <category>thread</category>
      <category>Volatile</category>
      <author>18진수</author>
      <guid isPermaLink="true">https://coding-yoon.tistory.com/286</guid>
      <comments>https://coding-yoon.tistory.com/286#entry286comment</comments>
      <pubDate>Fri, 22 Nov 2024 14:33:05 +0900</pubDate>
    </item>
    <item>
      <title>1. UDS(통합 진단 서비스) 소개</title>
      <link>https://coding-yoon.tistory.com/285</link>
      <description>&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;652&quot; data-origin-height=&quot;488&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/VcL3O/btsKN5BJpy7/z9aXKUJWE52iI4mSkeViXK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/VcL3O/btsKN5BJpy7/z9aXKUJWE52iI4mSkeViXK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/VcL3O/btsKN5BJpy7/z9aXKUJWE52iI4mSkeViXK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FVcL3O%2FbtsKN5BJpy7%2Fz9aXKUJWE52iI4mSkeViXK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;652&quot; height=&quot;488&quot; data-origin-width=&quot;652&quot; data-origin-height=&quot;488&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;UDS(Unified Diagnostic Services) : 통합 진단 서비스&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;UDS(Unified Diagnostic Services)는 차량의 전장 소프트웨어(ECU 소프트웨어) 개발 및 유지보수에서 매우 중요한 역할을 한다. 전장 SW 개발에서 UDS의 역할은 다음과 같다.&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;⚙️ 1. UDS 소개&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;현재 자동차들은 아래 사진과 같이 다양한 ECU(Electronic Cotrol Unit)들로 차량 곳곳에 도배가 되어 있다. ECU가 늘어날수록 전장(전자 장비) 회사도 다양해지며, 각 부품마다 제조하는 회사가 달라 규격이 서로 달랐다. 각 부품을 모아 자동차를 조립하기 때문에 같은 규격으로 개발할 필요가 있었다. &lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock widthContent&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;700&quot; data-origin-height=&quot;349&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/AbZth/btsKOLimQgP/cyqnleJwEGDmrtbBUxYokK/img.jpg&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/AbZth/btsKOLimQgP/cyqnleJwEGDmrtbBUxYokK/img.jpg&quot; data-alt=&quot;자동차를 완성시키는 전장 부품들&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/AbZth/btsKOLimQgP/cyqnleJwEGDmrtbBUxYokK/img.jpg&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FAbZth%2FbtsKOLimQgP%2FcyqnleJwEGDmrtbBUxYokK%2Fimg.jpg&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;700&quot; height=&quot;349&quot; data-origin-width=&quot;700&quot; data-origin-height=&quot;349&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;자동차를 완성시키는 전장 부품들&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Unified&amp;nbsp;Diagnostic&amp;nbsp;Services&amp;nbsp;(UDS&amp;nbsp;:&amp;nbsp;통합&amp;nbsp;진단&amp;nbsp;서비스)는&amp;nbsp;차량&amp;nbsp;내&amp;nbsp;통신&amp;nbsp;네트워크를&amp;nbsp;통해&amp;nbsp;전자&amp;nbsp;제어&amp;nbsp;장치(ECUs)&amp;nbsp;사이의&amp;nbsp;진단&amp;nbsp;통신을&amp;nbsp;표준화한&amp;nbsp;국제&amp;nbsp;표준인&amp;nbsp;ISO&amp;nbsp;14229에&amp;nbsp;정의되어&amp;nbsp;있다.&amp;nbsp;이&amp;nbsp;서비스는&amp;nbsp;차량의&amp;nbsp;진단,&amp;nbsp;프로그래밍,&amp;nbsp;모니터링&amp;nbsp;등&amp;nbsp;다양한&amp;nbsp;기능을&amp;nbsp;수행하도록&amp;nbsp;설계되었다.&amp;nbsp;UDS는&amp;nbsp;차량의&amp;nbsp;고장&amp;nbsp;진단,&amp;nbsp;소프트웨어&amp;nbsp;업데이트&amp;nbsp;및&amp;nbsp;매개변수&amp;nbsp;조정&amp;nbsp;등을&amp;nbsp;가능하게&amp;nbsp;하는&amp;nbsp;광범위한&amp;nbsp;명령&amp;nbsp;집합을&amp;nbsp;제공한다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock widthContent&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;874&quot; data-origin-height=&quot;415&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bIqEiK/btsKNtXsvVI/CebWbf1MX6ZUyxqkKZi1s1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bIqEiK/btsKNtXsvVI/CebWbf1MX6ZUyxqkKZi1s1/img.png&quot; data-alt=&quot;UDS&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bIqEiK/btsKNtXsvVI/CebWbf1MX6ZUyxqkKZi1s1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbIqEiK%2FbtsKNtXsvVI%2FCebWbf1MX6ZUyxqkKZi1s1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;874&quot; height=&quot;415&quot; data-origin-width=&quot;874&quot; data-origin-height=&quot;415&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;UDS&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;UDS는 아래와 같이 다양한 기능을 제공한다.&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;b&gt;1.&amp;nbsp;차량&amp;nbsp;진단&amp;nbsp;및&amp;nbsp;오류&amp;nbsp;관리&lt;/b&gt; &lt;br /&gt;UDS는 차량의 전자 제어 장치(ECU)에서 발생하는 오류를 진단하고 관리하는 표준 프로토콜이다. 오류가 발생했을 때, 이를 확인하고 수정하기 위해 UDS를 사용하여 DTC(Diagnostic Trouble Codes)를 읽어내고 분석할 수 있다. 이를 통해 차량 소프트웨어가 예상대로 작동하지 않을 때 신속한 문제 해결이 가능하다.&lt;/li&gt;
&lt;li&gt;&lt;b&gt;2.&amp;nbsp;서비스&amp;nbsp;및&amp;nbsp;유지보수&lt;/b&gt; &lt;br /&gt;UDS는 차량 서비스 및 유지보수 작업에서 필수적인 도구이다. 서비스 센터에서는 UDS 프로토콜을 통해 정비 데이터를 얻고, 차량의 특정 구성 요소를 점검하거나 리셋할 수 있다. 이를 통해 차량의 성능을 유지하고 정확한 유지보수를 수행할 수 있다.&lt;/li&gt;
&lt;li&gt;&lt;b&gt;3.&amp;nbsp;ECU&amp;nbsp;재프로그래밍&lt;/b&gt; &lt;br /&gt;UDS를 사용하여 ECU의 펌웨어 업데이트나 소프트웨어 재프로그래밍을 수행한다. 이는 차량의 새로운 기능을 추가하거나, 버그 수정 및 최적화를 위한 중요한 과정이다. 이를 통해 차량의 기능성을 향상시키고 최신 상태로 유지할 수 있다.&lt;/li&gt;
&lt;li&gt;&lt;b&gt;4.&amp;nbsp;보안성&amp;nbsp;강화&lt;/b&gt; &lt;br /&gt;최신 차량의 ECU 소프트웨어는 보안이 중요한 요소이며, UDS는 보안 진단 서비스를 통해 ECU에 안전하게 접근할 수 있는 방법을 제공한다. 인증된 장치만이 특정 진단 명령을 수행할 수 있도록 보안을 강화할 수 있으며, 이를 통해 해킹 및 비인가 접근을 방지할 수 있다.&lt;/li&gt;
&lt;li&gt;&lt;b&gt;5.&amp;nbsp;차량&amp;nbsp;네트워크&amp;nbsp;및&amp;nbsp;통신&amp;nbsp;관리&lt;/b&gt; &lt;br /&gt;UDS는 차량 내부 네트워크(CAN, LIN, FlexRay 등)를 통해 ECU 간에 통신을 관리한다. 차량의 전장 SW 개발 시, UDS를 사용하여 ECU 상태를 모니터링하고 제어할 수 있으며, 통신 오류 발생 시 이를 감지하고 수정하는 데 사용된다.&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;⚙️ 2. UDS와 ISO 14229&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;ISO&amp;nbsp;14229는&amp;nbsp;UDS&amp;nbsp;프로토콜의&amp;nbsp;사양을&amp;nbsp;정의하는&amp;nbsp;국제&amp;nbsp;표준이다.&amp;nbsp;이&amp;nbsp;표준은&amp;nbsp;진단&amp;nbsp;서비스의&amp;nbsp;프레임워크,&amp;nbsp;메시지&amp;nbsp;형식,&amp;nbsp;타이밍&amp;nbsp;요구&amp;nbsp;사항&amp;nbsp;등을&amp;nbsp;명시하여,&amp;nbsp;차량&amp;nbsp;진단&amp;nbsp;시스템의&amp;nbsp;설계와&amp;nbsp;구현을&amp;nbsp;지원한다.&amp;nbsp;ISO&amp;nbsp;14229&amp;nbsp;표준은&amp;nbsp;차량&amp;nbsp;진단과&amp;nbsp;관련된&amp;nbsp;다양한&amp;nbsp;작업을&amp;nbsp;위한&amp;nbsp;명확한&amp;nbsp;지침을&amp;nbsp;제공함으로써,&amp;nbsp;전&amp;nbsp;세계&amp;nbsp;차량&amp;nbsp;제조사&amp;nbsp;및&amp;nbsp;장비&amp;nbsp;공급업체들이&amp;nbsp;일관된&amp;nbsp;진단&amp;nbsp;접근&amp;nbsp;방식을&amp;nbsp;채택할&amp;nbsp;수&amp;nbsp;있도록&amp;nbsp;돕는다.&lt;/p&gt;
&lt;h3 style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size23&quot;&gt;⚙️ 3. UDS와 ISO 14229&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;UDS는&amp;nbsp;차량의&amp;nbsp;제품&amp;nbsp;수명&amp;nbsp;주기(PLC:&amp;nbsp;Product&amp;nbsp;Lifecycle)&amp;nbsp;동안&amp;nbsp;다양한&amp;nbsp;기능을&amp;nbsp;제공한다.&amp;nbsp;제조&amp;nbsp;단계에서는&amp;nbsp;차량의&amp;nbsp;초기&amp;nbsp;프로그래밍과&amp;nbsp;구성을&amp;nbsp;지원하고,&amp;nbsp;운영&amp;nbsp;단계에서는&amp;nbsp;정기적인&amp;nbsp;진단&amp;nbsp;검사,&amp;nbsp;오류&amp;nbsp;코드&amp;nbsp;해석,&amp;nbsp;소프트웨어&amp;nbsp;업데이트&amp;nbsp;등을&amp;nbsp;수행한다.&amp;nbsp;또한,&amp;nbsp;차량&amp;nbsp;폐기&amp;nbsp;단계에서도&amp;nbsp;중요한&amp;nbsp;정보&amp;nbsp;추출과&amp;nbsp;재설정을&amp;nbsp;가능하게&amp;nbsp;한다.&amp;nbsp;이러한&amp;nbsp;기능을&amp;nbsp;통해&amp;nbsp;UDS는&amp;nbsp;차량의&amp;nbsp;효율적인&amp;nbsp;관리와&amp;nbsp;유지보수에&amp;nbsp;필수적인&amp;nbsp;역할을&amp;nbsp;수행한다.&lt;/p&gt;</description>
      <category>  자동차 SW/ ️ 차량 UDS 진단</category>
      <author>18진수</author>
      <guid isPermaLink="true">https://coding-yoon.tistory.com/285</guid>
      <comments>https://coding-yoon.tistory.com/285#entry285comment</comments>
      <pubDate>Tue, 19 Nov 2024 00:50:33 +0900</pubDate>
    </item>
    <item>
      <title>[STM32] 8. 스위치 채터링 (소프트웨어 디바운싱)</title>
      <link>https://coding-yoon.tistory.com/284</link>
      <description>&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;600&quot; data-origin-height=&quot;600&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/wwcQj/btsKNAPIIsI/gBk74ikgZG2T77o5M0gdV0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/wwcQj/btsKNAPIIsI/gBk74ikgZG2T77o5M0gdV0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/wwcQj/btsKNAPIIsI/gBk74ikgZG2T77o5M0gdV0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FwwcQj%2FbtsKNAPIIsI%2FgBk74ikgZG2T77o5M0gdV0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;600&quot; height=&quot;600&quot; data-origin-width=&quot;600&quot; data-origin-height=&quot;600&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;스위치 채터링&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;푸쉬&amp;nbsp;리턴&amp;nbsp;스위치를&amp;nbsp;누를&amp;nbsp;때&amp;nbsp;발생할&amp;nbsp;수&amp;nbsp;있는&amp;nbsp;노이즈나&amp;nbsp;불안정한&amp;nbsp;신호로&amp;nbsp;인해&amp;nbsp;스위치가&amp;nbsp;여러&amp;nbsp;번&amp;nbsp;눌렸다고&amp;nbsp;인식되는&amp;nbsp;현상을&amp;nbsp;&quot;채터링&quot;&amp;nbsp;또는&amp;nbsp;&quot;디바운싱&quot;&amp;nbsp;문제라고&amp;nbsp;한다.&amp;nbsp;이를&amp;nbsp;해결하기&amp;nbsp;위해&amp;nbsp;디바운싱&amp;nbsp;필터링을&amp;nbsp;적용해야&amp;nbsp;한다.&amp;nbsp;디바운싱을&amp;nbsp;효과적으로&amp;nbsp;처리하는&amp;nbsp;방법에는&amp;nbsp;하드웨어적&amp;nbsp;방법과&amp;nbsp;소프트웨어적&amp;nbsp;방법이&amp;nbsp;있다.&amp;nbsp;이번&amp;nbsp;포스팅은&amp;nbsp;소프트웨어&amp;nbsp;디바운싱을&amp;nbsp;통해&amp;nbsp;채터링&amp;nbsp;문제를&amp;nbsp;해결&amp;nbsp;방법을&amp;nbsp;소개하려&amp;nbsp;한다. &lt;br /&gt;&lt;br /&gt;소프트웨어&amp;nbsp;디바운싱은&amp;nbsp;코드로&amp;nbsp;디바운싱을&amp;nbsp;구현하는&amp;nbsp;방법아다.&amp;nbsp;주로&amp;nbsp;타이머를&amp;nbsp;이용하여&amp;nbsp;일정&amp;nbsp;시간&amp;nbsp;동안&amp;nbsp;신호가&amp;nbsp;안정적인지&amp;nbsp;확인하는&amp;nbsp;방식으로&amp;nbsp;처리한다.&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;  1. 코드&lt;/h3&gt;
&lt;pre id=&quot;code_1731941541076&quot; class=&quot;cpp&quot; data-ke-language=&quot;cpp&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;/* USER CODE BEGIN PTD */
#define DEBOUNCE_DELAY 30 /* 30ms */
/* USER CODE END PTD */

...

/* USER CODE BEGIN 0 */
void HAL_GPIO_EXTI_Callback(uint16_t GPIO_Pin);

volatile uint32_t lastInterruptTime = 0;
/* USER CODE END 0 */

...

/* USER CODE BEGIN 4 */
void HAL_GPIO_EXTI_Callback(uint16_t GPIO_Pin)
{
	if(GPIO_Pin == BTN_Pin)
	{
		 uint32_t currentTime = HAL_GetTick(); /* check current time */
		 if ((currentTime - lastInterruptTime) &amp;gt; DEBOUNCE_DELAY){ /* check filtering 30ms time */
			 lastInterruptTime = currentTime; /* update interrupt time */
			 if (HAL_GPIO_ReadPin(GPIOA, BTN_Pin) == GPIO_PIN_SET){
				 HAL_GPIO_WritePin(GPIO_LED_GPIO_Port, GPIO_LED_Pin, GPIO_PIN_SET);
			 }else{
				 HAL_GPIO_WritePin(GPIO_LED_GPIO_Port, GPIO_LED_Pin, GPIO_PIN_RESET);
			 }
		 }
	}
}
/* USER CODE END 4 */&lt;/code&gt;&lt;/pre&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;b&gt;타이머&amp;nbsp;사용:&lt;/b&gt; HAL_GetTick()&amp;nbsp;함수를&amp;nbsp;사용하여&amp;nbsp;현재&amp;nbsp;시간을&amp;nbsp;가져온다.&amp;nbsp;이&amp;nbsp;함수는&amp;nbsp;시스템이&amp;nbsp;부팅된&amp;nbsp;이후의&amp;nbsp;밀리초(ms)&amp;nbsp;단위&amp;nbsp;시간을&amp;nbsp;반환한다.&lt;/li&gt;
&lt;li&gt;&lt;b&gt;인터럽트 핸들러에서 디바운싱 적용:&lt;/b&gt; 인터럽트가 발생할 때마다 현재 시간과 마지막 인터럽트 발생 시간을 비교하여 디바운싱 시간을 초과한 경우에만 버튼 입력을 처리한다.&lt;/li&gt;
&lt;li&gt;&lt;b&gt;디바운싱 시간 설정:&lt;/b&gt; DEBOUNCE_DELAY 매크로를 사용하여 디바운싱 시간을 설정한다. 여기서는 50ms로 설정하였다.&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;  2. 특징&lt;/h3&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;b&gt;디바운싱 시간 선택:&lt;/b&gt; 너무 짧으면 채터링을 완전히 제거하지 못하고, 너무 길면 버튼 입력에 대한 응답성이 떨어질 수 있다. 일반적으로 10ms에서 50ms 사이의 값이 적절하다.&lt;/li&gt;
&lt;li&gt;&lt;b&gt;타이머 사용:&lt;/b&gt; 소프트웨어 디바운싱을 구현할 때 타이머를 사용하여 인터럽트 발생 후 일정 시간 동안 버튼 입력을 무시할 수 있다.&lt;/li&gt;
&lt;li&gt;&lt;b&gt;상태 확인:&lt;/b&gt; 버튼의 현재 상태를 저장하고, 일정 시간 동안 상태가 변하지 않는 경우에만 입력을 처리하는 방법도 있다.&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이러한&amp;nbsp;방법들을&amp;nbsp;통해&amp;nbsp;버튼의&amp;nbsp;채터링&amp;nbsp;문제를&amp;nbsp;효과적으로&amp;nbsp;해결할&amp;nbsp;수&amp;nbsp;있다.&amp;nbsp;소프트웨어&amp;nbsp;디바운싱은&amp;nbsp;코드로&amp;nbsp;간단히&amp;nbsp;구현할&amp;nbsp;수&amp;nbsp;있다.&amp;nbsp;코드를&amp;nbsp;자세히&amp;nbsp;보면&amp;nbsp;volatile&amp;nbsp;키워드를&amp;nbsp;사용한&amp;nbsp;것을&amp;nbsp;확인할&amp;nbsp;수&amp;nbsp;있다.&amp;nbsp;다음&amp;nbsp;포스팅은&amp;nbsp;volatile&amp;nbsp;키워드에&amp;nbsp;대해&amp;nbsp;소개해보려&amp;nbsp;한다.&lt;/p&gt;</description>
      <category>  STM32</category>
      <category>STM32</category>
      <category>디바운싱</category>
      <category>스위치</category>
      <category>채터링 방식</category>
      <category>필터</category>
      <author>18진수</author>
      <guid isPermaLink="true">https://coding-yoon.tistory.com/284</guid>
      <comments>https://coding-yoon.tistory.com/284#entry284comment</comments>
      <pubDate>Mon, 18 Nov 2024 23:58:58 +0900</pubDate>
    </item>
    <item>
      <title>[STM32] 7.  외부 인터럽트(External Interrupt)</title>
      <link>https://coding-yoon.tistory.com/283</link>
      <description>&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;600&quot; data-origin-height=&quot;600&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/DLExp/btsKOb2TMwH/mVG0Ahz0senhKUNfOH2SZ0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/DLExp/btsKOb2TMwH/mVG0Ahz0senhKUNfOH2SZ0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/DLExp/btsKOb2TMwH/mVG0Ahz0senhKUNfOH2SZ0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FDLExp%2FbtsKOb2TMwH%2FmVG0Ahz0senhKUNfOH2SZ0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;600&quot; height=&quot;600&quot; data-origin-width=&quot;600&quot; data-origin-height=&quot;600&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;외부 인터럽트&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;외부&amp;nbsp;인터럽트는&amp;nbsp;마이크로컨트롤러가&amp;nbsp;외부&amp;nbsp;신호(예:&amp;nbsp;버튼&amp;nbsp;입력,&amp;nbsp;센서&amp;nbsp;신호&amp;nbsp;등)에&amp;nbsp;의해&amp;nbsp;프로그램의&amp;nbsp;흐름을&amp;nbsp;중단하고,&amp;nbsp;특정&amp;nbsp;인터럽트&amp;nbsp;서비스&amp;nbsp;루틴(ISR,&amp;nbsp;Interrupt&amp;nbsp;Service&amp;nbsp;Routine)을&amp;nbsp;실행하도록&amp;nbsp;하는&amp;nbsp;메커니즘이다.&amp;nbsp;STM32&amp;nbsp;마이크로컨트롤러에서도&amp;nbsp;이러한&amp;nbsp;외부&amp;nbsp;인터럽트를&amp;nbsp;효과적으로&amp;nbsp;사용할&amp;nbsp;수&amp;nbsp;있다.&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;  1. 외부 인터럽트 란?&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;외부 인터럽트는 마이크로컨트롤러의 특정 핀으로 들어오는 신호를 감지하여 발생하는 인터럽트이다. 이러한 인터럽트는 다음과 같은 경우에 유용하다.&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;버튼 누름 감지&lt;/li&gt;
&lt;li&gt;센서의 신호 변화 감지&lt;/li&gt;
&lt;li&gt;외부 장치와의 통신 신호 감지&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;외부 인터럽트는 일반적으로 다음과 같은 방식으로 설정되고 사용된다.&lt;/p&gt;
&lt;ol style=&quot;list-style-type: decimal;&quot; data-ke-list-type=&quot;decimal&quot;&gt;
&lt;li&gt;&lt;b&gt;인터럽트 소스 설정:&lt;/b&gt; 특정 GPIO 핀을 인터럽트 소스로 설정한다.&lt;/li&gt;
&lt;li&gt;&lt;b&gt;인터럽트 모드 설정:&lt;/b&gt; 상승 엣지, 하강 엣지, 또는 양엽(둘 다)을 감지하도록 설정한다.&lt;/li&gt;
&lt;li&gt;&lt;b&gt;인터럽트 활성화:&lt;/b&gt; NVIC(중앙 인터럽트 컨트롤러)에서 해당 인터럽트를 활성화한다.&lt;/li&gt;
&lt;li&gt;&lt;b&gt;인터럽트 서비스 루틴(ISR)&lt;/b&gt; &lt;b&gt;작성:&lt;/b&gt; 인터럽트가 발생했을 때 실행될 코드를 작성한다.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock widthContent&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;966&quot; data-origin-height=&quot;636&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bJq5gh/btsKNrleuYb/AKaLZ9x42bfDN7pwka7eD0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bJq5gh/btsKNrleuYb/AKaLZ9x42bfDN7pwka7eD0/img.png&quot; data-alt=&quot;인터럽트 소스 설정&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bJq5gh/btsKNrleuYb/AKaLZ9x42bfDN7pwka7eD0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbJq5gh%2FbtsKNrleuYb%2FAKaLZ9x42bfDN7pwka7eD0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;966&quot; height=&quot;636&quot; data-origin-width=&quot;966&quot; data-origin-height=&quot;636&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;인터럽트 소스 설정&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;figure class=&quot;imageblock widthContent&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;966&quot; data-origin-height=&quot;636&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/IK1C9/btsKOM9o1qT/xsEg13exg9TAm5hg8XADb0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/IK1C9/btsKOM9o1qT/xsEg13exg9TAm5hg8XADb0/img.png&quot; data-alt=&quot;상승 엣지, 하강 엣지, 또는 양엽(둘 다)을 감지하도록 설정&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/IK1C9/btsKOM9o1qT/xsEg13exg9TAm5hg8XADb0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FIK1C9%2FbtsKOM9o1qT%2FxsEg13exg9TAm5hg8XADb0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;966&quot; height=&quot;636&quot; data-origin-width=&quot;966&quot; data-origin-height=&quot;636&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;상승 엣지, 하강 엣지, 또는 양엽(둘 다)을 감지하도록 설정&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;figure class=&quot;imageblock widthContent&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;966&quot; data-origin-height=&quot;636&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/kP63D/btsKNbCyPta/kOAwp8MEk1pHfo5TxKkQV0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/kP63D/btsKNbCyPta/kOAwp8MEk1pHfo5TxKkQV0/img.png&quot; data-alt=&quot;인터럽트 활성화&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/kP63D/btsKNbCyPta/kOAwp8MEk1pHfo5TxKkQV0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FkP63D%2FbtsKNbCyPta%2FkOAwp8MEk1pHfo5TxKkQV0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;966&quot; height=&quot;636&quot; data-origin-width=&quot;966&quot; data-origin-height=&quot;636&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;인터럽트 활성화&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;pre id=&quot;code_1731940467520&quot; class=&quot;cpp&quot; data-ke-language=&quot;cpp&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;/* USER CODE BEGIN 4 */
void HAL_GPIO_EXTI_Callback(uint16_t GPIO_Pin)
{
	if(GPIO_Pin == BTN_Pin)
	{
		 if (HAL_GPIO_ReadPin(GPIOA, BTN_Pin) == GPIO_PIN_SET){
			 HAL_GPIO_WritePin(GPIO_LED_GPIO_Port, GPIO_LED_Pin, GPIO_PIN_SET);
		 }else{
			 HAL_GPIO_WritePin(GPIO_LED_GPIO_Port, GPIO_LED_Pin, GPIO_PIN_RESET);
		 }
	}
}
/* USER CODE END 4 */&lt;/code&gt;&lt;/pre&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;  2. 외부 인터럽트를 사용하는 이유&lt;/h3&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;b&gt;실시간 응답:&lt;/b&gt; 외부 이벤트에 대해 즉각적으로 응답할 수 있다. 프로그램의 메인 루프를 기다릴 필요 없이 바로 처리할 수 있다.&lt;/li&gt;
&lt;li&gt;&lt;b&gt;전력 효율성:&lt;/b&gt; 저전력 모드에서 마이크로컨트롤러가 대기 상태로 있다가 인터럽트가 발생하면 깨어나서 처리할 수 있다.&lt;/li&gt;
&lt;li&gt;&lt;b&gt;효율적인&amp;nbsp;자원&amp;nbsp;사용:&lt;/b&gt;&amp;nbsp;지속적으로&amp;nbsp;이벤트를&amp;nbsp;폴링(polling)하는&amp;nbsp;대신,&amp;nbsp;인터럽트를&amp;nbsp;사용하면&amp;nbsp;CPU&amp;nbsp;시간을&amp;nbsp;절약할&amp;nbsp;수&amp;nbsp;있다.&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;  3. while문 대신 외부 인터럽트를 사용하는 이유&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;일반적인 프로그램에서는 메인 루프(while 문)에서 특정 조건을 지속적으로 확인하는 방식으로 버튼 입력을 처리할 수 있다. 그러나 이는 비효율적이다. 폴링 방식으로 버튼 입력을 확인하면 CPU 자원을 낭비하게 된다. 다음은 외부 인터럽트를 사용하는 이유이다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock widthContent&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;807&quot; data-origin-height=&quot;438&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/E4beG/btsKOnoFW5J/plEfHekXVZkUpLLXrKorF0/img.jpg&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/E4beG/btsKOnoFW5J/plEfHekXVZkUpLLXrKorF0/img.jpg&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/E4beG/btsKOnoFW5J/plEfHekXVZkUpLLXrKorF0/img.jpg&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FE4beG%2FbtsKOnoFW5J%2FplEfHekXVZkUpLLXrKorF0%2Fimg.jpg&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;807&quot; height=&quot;438&quot; data-origin-width=&quot;807&quot; data-origin-height=&quot;438&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;</description>
      <category>  STM32</category>
      <category>STM32</category>
      <category>외부</category>
      <category>인터럽트</category>
      <author>18진수</author>
      <guid isPermaLink="true">https://coding-yoon.tistory.com/283</guid>
      <comments>https://coding-yoon.tistory.com/283#entry283comment</comments>
      <pubDate>Mon, 18 Nov 2024 23:42:45 +0900</pubDate>
    </item>
    <item>
      <title>[STM32] 6. 풀업 저항 기본 원리</title>
      <link>https://coding-yoon.tistory.com/282</link>
      <description>&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;600&quot; data-origin-height=&quot;600&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cAMzWv/btsKL80mqID/FKcWskKSEPTNVtezaAIp21/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cAMzWv/btsKL80mqID/FKcWskKSEPTNVtezaAIp21/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cAMzWv/btsKL80mqID/FKcWskKSEPTNVtezaAIp21/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FcAMzWv%2FbtsKL80mqID%2FFKcWskKSEPTNVtezaAIp21%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;600&quot; height=&quot;600&quot; data-origin-width=&quot;600&quot; data-origin-height=&quot;600&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;풀업 저항 (Pull-Up)&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;풀업&amp;nbsp;저항은&amp;nbsp;디지털&amp;nbsp;회로에서&amp;nbsp;입력&amp;nbsp;핀의&amp;nbsp;기본&amp;nbsp;상태를&amp;nbsp;높은&amp;nbsp;전압(논리적&amp;nbsp;'1')으로&amp;nbsp;설정하기&amp;nbsp;위해&amp;nbsp;사용된다.&amp;nbsp;풀업&amp;nbsp;저항이&amp;nbsp;없으면&amp;nbsp;입력&amp;nbsp;핀이&amp;nbsp;떠다니는&amp;nbsp;상태(floating)가&amp;nbsp;되어&amp;nbsp;예기치&amp;nbsp;않은&amp;nbsp;전압&amp;nbsp;값을&amp;nbsp;가질&amp;nbsp;수&amp;nbsp;있다.&amp;nbsp;풀업&amp;nbsp;저항을&amp;nbsp;사용하면&amp;nbsp;입력&amp;nbsp;핀이&amp;nbsp;안정된&amp;nbsp;높은&amp;nbsp;전압&amp;nbsp;상태를&amp;nbsp;유지하게&amp;nbsp;된다.&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;  1. 풀업 저항의 역할&lt;/h3&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;b&gt;기본 상태 유지:&lt;/b&gt; 풀업 저항은 입력 핀이 아무 신호도 받지 않을 때 기본적으로 논리 '1' 상태(높은 전압)를 유지하도록 한다.&lt;/li&gt;
&lt;li&gt;&lt;b&gt;안정성 향상:&lt;/b&gt; 회로의 안정성을 높여, 입력 핀이 불안정한 상태(플로팅 현상)에서 예기치 않은 동작을 방지한다.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock widthContent&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;442&quot; data-origin-height=&quot;276&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/84wTB/btsKL3dH3KY/gxKrzNd0HebvdunSqHF4l1/img.jpg&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/84wTB/btsKL3dH3KY/gxKrzNd0HebvdunSqHF4l1/img.jpg&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/84wTB/btsKL3dH3KY/gxKrzNd0HebvdunSqHF4l1/img.jpg&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2F84wTB%2FbtsKL3dH3KY%2FgxKrzNd0HebvdunSqHF4l1%2Fimg.jpg&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;442&quot; height=&quot;276&quot; data-origin-width=&quot;442&quot; data-origin-height=&quot;276&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;b&gt;풀업 저항(R):&lt;/b&gt; 저항이 INPUT 핀과 Vcc(+5V) 사이에 연결된다.&lt;/li&gt;
&lt;li&gt;&lt;b&gt;스위치:&lt;/b&gt; 스위치가 닫히면 INPUT 핀은 GND와 연결되어 논리 '0'이 된다.&lt;/li&gt;
&lt;li&gt;&lt;b&gt;기본 상태:&lt;/b&gt; 스위치가 열려 있으면 풀업 저항에 의해 INPUT 핀은 논리 '1' 상태를 유지한다.&amp;nbsp;&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;  2. 풀업 저항 예시&lt;/h3&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;스위치를 사용한 입력 회로&lt;/li&gt;
&lt;li&gt;센서 입력 회로&lt;/li&gt;
&lt;li&gt;I2C 통신 회로 등&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;요즘 임베디드는 전장 업계가 호황인데, 대게 자동차 부품에 스위치가 있다면 내가 말하는 대부분의 회로 구성이 아닐까 싶다. 자동차 배터리는 +12V 이므로 5V나 3.3V 동작하는 MCU를 위해 전압 강하를 하고, 그 사이에 풀업 저항을 통해 스위치를 제어한다. 차량이 IGN1이나 Engine On 상태일 때, MCU는 Normal 모드로 동작하며 스위치가 눌리지 않는 상태에서는 해당 스위치의 GPIO Input 핀에 동작 전압(5V 및 3.3V, Output High)이 흐르다가 스위치가 눌리게 되면 Input 핀에는 0V(Output Low)가 흐른다. (정확히는 실제 Input 핀에 오실로스코프를 이용하여 전압을 측정하면 0V가 아닌 0V(10mV~ 100mV)에 가까운 전압이다.)&amp;nbsp; 이는 스위치가 눌리지 않았을 때 Output High이고, 스위치가 눌렸을 때 Output Low 이므로, 이를 Active Low라고 한다. 나는 소프트웨어 개발자로 회로 설계자 만큼 깊은 지식을 소유하고 있지는 않지만, 회로 설계자가 회로도를 제공했을 때, 소프트쟁이가 읽어야만 하는 몇 안되는 기본 회로(전압 분배, 스위칭 회로, 필터 회로 등) 중 하나라 생각한다.&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;  3. 풀업 저항과 플로팅 현상&lt;/h3&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;b&gt;플로팅(Floating) 현상&lt;/b&gt; &lt;br /&gt;디지털 회로에서 입력 핀이 플로팅 상태가 되면 핀이 어떠한 고정된 전압 수준(논리 '1' 또는 논리 '0')으로 연결되지 않아 불안정한 상태에 놓이게 된다. 이는 입력 핀이 외부 신호에 의해 드라이브되지 않을 때 발생한다. 이러한 상태에서는 입력 핀이 노이즈에 민감해지고, 임의의 전압 수준을 가지게 되어 예기치 않은 동작이 발생할 수 있다.&lt;/li&gt;
&lt;li&gt;&lt;b&gt;풀업 저항(Pull-up Resistor)&lt;/b&gt;&lt;br /&gt;풀업&amp;nbsp;저항은&amp;nbsp;입력&amp;nbsp;핀을&amp;nbsp;전원&amp;nbsp;전압(Vcc)에&amp;nbsp;연결하여&amp;nbsp;기본적으로&amp;nbsp;높은&amp;nbsp;전압&amp;nbsp;수준(논리&amp;nbsp;'1')을&amp;nbsp;유지하도록&amp;nbsp;하는&amp;nbsp;저항이다.&amp;nbsp;이를&amp;nbsp;통해&amp;nbsp;입력&amp;nbsp;핀이&amp;nbsp;플로팅&amp;nbsp;상태에&amp;nbsp;놓이는&amp;nbsp;것을&amp;nbsp;방지한다.&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size23&quot;&gt;  4. 장점&lt;/h3&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;b&gt;안정적인 신호 유지:&lt;/b&gt; 풀업 저항을 사용하면 입력 핀이 항상 안정된 전압 수준을 유지하여 신호의 일관성을 보장한다.&lt;/li&gt;
&lt;li&gt;&lt;b&gt;디지털 회로 보호:&lt;/b&gt; 풀업 저항은 입력 핀이 불안정한 상태에서 발생할 수 있는 불안정한 신호로 인한 회로 오작동을 방지한다.&lt;/li&gt;
&lt;li&gt;&lt;b&gt;전력 소모 최소화:&lt;/b&gt; 적절한 저항 값을 사용하면 전력 소모를 최소화하면서도 안정적인 입력 신호를 유지할 수 있다.&lt;/li&gt;
&lt;li&gt;&lt;b&gt;노이즈 방지:&lt;/b&gt; 플로팅 상태의 입력 핀은 환경 노이즈에 민감하므로, 풀업 저항을 사용하면 이러한 노이즈 영향을 최소화할 수 있다.&lt;/li&gt;
&lt;li&gt;&lt;b&gt;예측 가능한 동작:&lt;/b&gt; 입력 핀이 항상 논리 '1' 상태를 유지하도록 하여 예기치 않은 동작을 방지할 수 있다.&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size23&quot;&gt;  5. 팁&lt;/h3&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;b&gt;내부 풀업 저항 사용:&lt;/b&gt; STM32의 GPIO 설정에서 내부 풀업 저항을 활성화하면 외부 저항 없이 회로를 간단하게 만들 수 있다.&lt;/li&gt;
&lt;li&gt;&lt;b&gt;디바운싱 처리:&lt;/b&gt; 스위치를 사용할 때 노이즈로 인해 잘못된 입력이 발생할 수 있으므로 디바운싱(SW, HW) 처리를 고려해야 한다.&lt;/li&gt;
&lt;li&gt;&lt;b&gt;적절한&amp;nbsp;저항&amp;nbsp;값&amp;nbsp;선택:&amp;nbsp;&lt;/b&gt;외부 풀업 저항을 사용할 경우, 저항 값은 일반적으로 4.7~10k&amp;Omega; 정도가 적당하지만 회로 요구사항에 따라 다를 수 있다.&lt;/li&gt;
&lt;/ul&gt;</description>
      <category>  STM32</category>
      <category>STM32</category>
      <category>강의</category>
      <category>공부</category>
      <category>저항</category>
      <category>풀업</category>
      <category>회로</category>
      <author>18진수</author>
      <guid isPermaLink="true">https://coding-yoon.tistory.com/282</guid>
      <comments>https://coding-yoon.tistory.com/282#entry282comment</comments>
      <pubDate>Mon, 18 Nov 2024 00:50:28 +0900</pubDate>
    </item>
    <item>
      <title>[STM32] 5. 내장 스위치 제어</title>
      <link>https://coding-yoon.tistory.com/281</link>
      <description>&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;600&quot; data-origin-height=&quot;600&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bNxNDN/btsKM0mHTJh/fJ3nk70mTzKesrmo4UfnKk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bNxNDN/btsKM0mHTJh/fJ3nk70mTzKesrmo4UfnKk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bNxNDN/btsKM0mHTJh/fJ3nk70mTzKesrmo4UfnKk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbNxNDN%2FbtsKM0mHTJh%2FfJ3nk70mTzKesrmo4UfnKk%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;600&quot; height=&quot;600&quot; data-origin-width=&quot;600&quot; data-origin-height=&quot;600&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;STM32 내장 스위치 제어&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이번 포스팅은 STM32 보드에 있는 내장 스위치의 기능을 설명하고, 스위치 입력을 받아 처리하는 간단한 프로젝트를 포함한다. 하기 이미지와 같이 Arduino UNO, ATMega328P, STM32 Board 등 대부분의 개발 보드들은 테스트를 해볼 수 있게끔 스위치를 내장하고 있다. 다음 포스팅에 소개할 예정이지만 이런 보드들의 스위치들은 풀업 저항 회로로 구성되어 있다. 풀업 저항은 전원단에 저항이 있는 회로로 노이즈에 강하다는 장점을 가지고 있으며 대부분의 양산 제품들이 이 회로를 사용하고 있다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;600&quot; data-origin-height=&quot;600&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/kJ4Bj/btsKM6tGsp7/JgDuak6xLfVVNvixx04xH0/img.webp&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/kJ4Bj/btsKM6tGsp7/JgDuak6xLfVVNvixx04xH0/img.webp&quot; data-alt=&quot;NUCLEO-64 STM32U083RC EVAL BRD&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/kJ4Bj/btsKM6tGsp7/JgDuak6xLfVVNvixx04xH0/img.webp&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FkJ4Bj%2FbtsKM6tGsp7%2FJgDuak6xLfVVNvixx04xH0%2Fimg.webp&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;522&quot; height=&quot;522&quot; data-origin-width=&quot;600&quot; data-origin-height=&quot;600&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;NUCLEO-64 STM32U083RC EVAL BRD&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;442&quot; data-origin-height=&quot;276&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/oEFtE/btsKMN8WYIc/QOkRoWRnSC2LEuh1KzR8S0/img.jpg&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/oEFtE/btsKMN8WYIc/QOkRoWRnSC2LEuh1KzR8S0/img.jpg&quot; data-alt=&quot;풀업 저항 회로&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/oEFtE/btsKMN8WYIc/QOkRoWRnSC2LEuh1KzR8S0/img.jpg&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FoEFtE%2FbtsKMN8WYIc%2FQOkRoWRnSC2LEuh1KzR8S0%2Fimg.jpg&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;442&quot; height=&quot;276&quot; data-origin-width=&quot;442&quot; data-origin-height=&quot;276&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;풀업 저항 회로&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;  1. STM32 내장 스위치&lt;/h3&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;b&gt;스위치의 역할:&lt;/b&gt; 스위치는 사용자가 전자 장치에 명령을 내릴 수 있는 간단하고 직관적인 인터페이스를 제공한다.&lt;/li&gt;
&lt;li&gt;&lt;b&gt;물리적 구성:&lt;/b&gt; 대부분의 STM32 보드에는 일반적으로 &quot;USER&quot; 라벨이 붙은 누를 수 있는 버튼 형태의 스위치가 하나 이상 포함되어 있다.&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;  2. STM32에서 스위치 연결&lt;/h3&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;b&gt;보드의 스위치 핀 위치와 기능 확인:&lt;/b&gt; STM32 보드의 데이터시트 또는 사용자 매뉴얼을 통해 스위치가 연결된 GPIO 핀을 확인한다. 예를 들어, 많은 STM32F4 Discovery 보드에서는 스위치가 PA0 핀에 연결되어 있다.&lt;/li&gt;
&lt;li&gt;&lt;b&gt;스위치의 전기적 특성:&lt;/b&gt; 대부분의 스위치는 기본적으로 풀업(pull-up) 저항과 연결되어 있어, 스위치가 눌리지 않은 상태에서는 핀이 높은 전압(HIGH) 상태를 유지하고, 눌렸을 때는 낮은 전압(LOW) 상태가 된다.&amp;nbsp;&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;  3. 스위치 입력을 위한 GPIO 설정&lt;/h3&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;Cube IDE에서 GPIO 설정:
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;b&gt;Mode:&lt;/b&gt; Input (입력 모드로 설정)&lt;/li&gt;
&lt;li&gt;&lt;b&gt;Pull:&lt;/b&gt; Pull-up (내부 풀업 저항 활성화)&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock widthContent&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;966&quot; data-origin-height=&quot;423&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/uFkJA/btsKMHnoXQS/DjyDgkMaCQneeHQPMlsdzk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/uFkJA/btsKMHnoXQS/DjyDgkMaCQneeHQPMlsdzk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/uFkJA/btsKMHnoXQS/DjyDgkMaCQneeHQPMlsdzk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FuFkJA%2FbtsKMHnoXQS%2FDjyDgkMaCQneeHQPMlsdzk%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;966&quot; height=&quot;423&quot; data-origin-width=&quot;966&quot; data-origin-height=&quot;423&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;위 이미지처럼 설정하면 하기와 같이 코드가 자동생성된다.&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt; &amp;nbsp;4. Configuration Code 설명&lt;/h3&gt;
&lt;pre id=&quot;code_1731853611556&quot; class=&quot;cpp&quot; data-ke-language=&quot;cpp&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;/* GPIO_SW_Pin 핀을 구성하는 코드 */
GPIO_InitStruct.Pin = GPIO_SW_Pin;  // GPIO 초기화 구조체에서 제어할 핀을 지정 (GPIO_SW_Pin)
GPIO_InitStruct.Mode = GPIO_MODE_INPUT;  // 핀의 모드를 입력 모드 (Input Mode)로 설정
GPIO_InitStruct.Pull = GPIO_PULLUP;  // 내부 풀업 저항을 활성화하여 기본적으로 핀이 HIGH 상태가 되도록 설정
HAL_GPIO_Init(GPIO_SW_GPIO_Port, &amp;amp;GPIO_InitStruct);  // HAL 라이브러리의 초기화 함수 호출, 설정된 구조체를 사용하여 GPIO_SW_GPIO_Port의 핀을 초기화&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;pre id=&quot;code_1731854095822&quot; class=&quot;cpp&quot; data-ke-language=&quot;cpp&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;GPIO_InitStruct.Pin = GPIO_SW_Pin;&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;br /&gt;&lt;i&gt;GPIO_InitStruct&lt;/i&gt;는 &lt;i&gt;GPIO_InitTypeDef&lt;/i&gt;라는 구조체이며, GPIO 핀의 설정을 정의하는 데 사용된다. &lt;br /&gt;Pin 필드는 설정하려는 특정 핀을 지정한다. 여기서는 &lt;i&gt;GPIO_SW_Pin&lt;/i&gt;이 스위치에 연결된 핀을 나타낸다.&lt;/p&gt;
&lt;pre id=&quot;code_1731854138084&quot; class=&quot;cpp&quot; data-ke-language=&quot;cpp&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;GPIO_InitStruct.Mode = GPIO_MODE_INPUT;&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;br /&gt;Mode 필드는 핀의 동작 모드를 지정한다. &lt;br /&gt;&lt;i&gt;GPIO_MODE_INPUT&lt;/i&gt;은 핀을 입력 모드로 설정하며, 외부 신호(스위치)를 읽을 수 있도록 한다.&lt;/p&gt;
&lt;pre id=&quot;code_1731854174684&quot; class=&quot;cpp&quot; data-ke-language=&quot;cpp&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;GPIO_InitStruct.Pull = GPIO_PULLUP;&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;br /&gt;Pull 필드는 핀의 내부 풀업 또는 풀다운 저항을 활성화할지 설정한다. &lt;br /&gt;&lt;i&gt;GPIO_PULLUP&lt;/i&gt;을 설정하면 내부 풀업 저항이 활성화되어 핀의 기본 상태가 HIGH(1)로 유지된다. &lt;br /&gt;스위치가 눌리지 않았을 때 핀의 상태가 HIGH로 유지되며, 스위치를 누르면 LOW(0)로 전환된다. (Active Low)&lt;/p&gt;
&lt;pre id=&quot;code_1731854206290&quot; class=&quot;cpp&quot; data-ke-language=&quot;cpp&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;HAL_GPIO_Init(GPIO_SW_GPIO_Port, &amp;amp;GPIO_InitStruct);&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;br /&gt;&lt;i&gt;HAL_GPIO_Init() &lt;/i&gt;함수는 설정된 구조체(&lt;i&gt;GPIO_InitStruct&lt;/i&gt;)를 사용하여 지정된 포트에서 핀을 초기화한다. &lt;br /&gt;첫 번째 인자 &lt;i&gt;GPIO_SW_GPIO_Port&lt;/i&gt;는 초기화할 포트의 레지스터 주소이며, 두 번째 인자는 초기화 설정이 포함된 구조체의 포인터이다. &lt;br /&gt;이를 통해 입력 핀의 모드와 풀업 저항 설정을 적용한다.&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;  5. Switch 로직 설명&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;해당&amp;nbsp;코드는&amp;nbsp;내장&amp;nbsp;스위치가&amp;nbsp;눌렸을&amp;nbsp;때,&amp;nbsp;내장&amp;nbsp;LED를&amp;nbsp;제어하는&amp;nbsp;코드이다.&amp;nbsp;&lt;/p&gt;
&lt;pre id=&quot;code_1731853648026&quot; class=&quot;cpp&quot; data-ke-language=&quot;cpp&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;// GPIO 포트를 읽어 스위치 상태에 따라 LED를 제어하는 코드
if(!HAL_GPIO_ReadPin(GPIO_SW_GPIO_Port, GPIO_SW_Pin)) {
    // HAL_GPIO_ReadPin() 함수는 지정된 GPIO 포트의 핀 상태를 읽음
    // 여기서는 GPIO_SW_GPIO_Port 포트의 GPIO_SW_Pin 핀의 상태를 읽음
    // HAL_GPIO_ReadPin()은 핀의 상태가 LOW(0)일 경우 0을 반환
    // 조건문에서 '!'(논리 NOT)를 사용하여 핀이 LOW일 때 조건이 참이 되도록 설정

    HAL_GPIO_WritePin(GPIO_LED_GPIO_Port, GPIO_LED_Pin, 0);
    // HAL_GPIO_WritePin() 함수는 지정된 GPIO 포트의 핀 상태를 설정함
    // 여기서는 GPIO_LED_GPIO_Port 포트의 GPIO_LED_Pin 핀을 LOW(0)으로 설정하여 LED를 켬
} else {
    HAL_GPIO_WritePin(GPIO_LED_GPIO_Port, GPIO_LED_Pin, 1);
    // 스위치 핀이 HIGH(1)일 경우, GPIO_LED_GPIO_Port의 GPIO_LED_Pin을 HIGH(1)으로 설정하여 LED를 끔
}&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;pre id=&quot;code_1731854607350&quot; class=&quot;cpp&quot; data-ke-language=&quot;cpp&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;HAL_GPIO_ReadPin(GPIO_SW_GPIO_Port, GPIO_SW_Pin)&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;br /&gt;지정된 포트(&lt;i&gt;GPIO_SW_GPIO_Port&lt;/i&gt;)의 핀(&lt;i&gt;GPIO_SW_Pin&lt;/i&gt;)에서 현재 상태를 읽는다. &lt;br /&gt;- 반환 값이 0일 때 핀의 상태가 LOW(0)이며, 스위치가 눌려진 상태임을 의미합니다. &lt;br /&gt;- 반환 값이 1일 때 핀의 상태가 HIGH(1)이며, 스위치가 눌리지 않은 상태입니다.&lt;/p&gt;
&lt;pre id=&quot;code_1731854636861&quot; class=&quot;cpp&quot; data-ke-language=&quot;cpp&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;HAL_GPIO_WritePin(GPIO_LED_GPIO_Port, GPIO_LED_Pin, 0)&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;br /&gt;LED 제어 핀을 LOW로 설정하여 LED를 켠다.&lt;/p&gt;
&lt;pre id=&quot;code_1731854659190&quot; class=&quot;cpp&quot; data-ke-language=&quot;cpp&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;HAL_GPIO_WritePin(GPIO_LED_GPIO_Port, GPIO_LED_Pin, 1)&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;br /&gt;LED&amp;nbsp;제어&amp;nbsp;핀을&amp;nbsp;HIGH로&amp;nbsp;설정하여&amp;nbsp;LED를&amp;nbsp;끈다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이 방식을 사용하면 간단하게 GPIO_INPUT, OUTPUT을 간단하게 제어할 수 있다.&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>  STM32</category>
      <category>pull</category>
      <category>STM32</category>
      <category>up</category>
      <category>내장</category>
      <category>스위치</category>
      <category>저항</category>
      <category>제어</category>
      <author>18진수</author>
      <guid isPermaLink="true">https://coding-yoon.tistory.com/281</guid>
      <comments>https://coding-yoon.tistory.com/281#entry281comment</comments>
      <pubDate>Sun, 17 Nov 2024 23:51:12 +0900</pubDate>
    </item>
    <item>
      <title>[C/C++ Tip] 30. C언어 Unit Test 종류</title>
      <link>https://coding-yoon.tistory.com/280</link>
      <description>&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;600&quot; data-origin-height=&quot;600&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/dANZns/btsKFkeNlVc/NVvU9RmOvuoAlygLknPPYk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/dANZns/btsKFkeNlVc/NVvU9RmOvuoAlygLknPPYk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/dANZns/btsKFkeNlVc/NVvU9RmOvuoAlygLknPPYk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FdANZns%2FbtsKFkeNlVc%2FNVvU9RmOvuoAlygLknPPYk%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;600&quot; height=&quot;600&quot; data-origin-width=&quot;600&quot; data-origin-height=&quot;600&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;단위 테스트 종류&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;위&amp;nbsp;테스트의&amp;nbsp;각&amp;nbsp;유형을&amp;nbsp;좀&amp;nbsp;더&amp;nbsp;상세하게&amp;nbsp;설명하고,&amp;nbsp;각&amp;nbsp;유형이&amp;nbsp;어떤&amp;nbsp;문제를&amp;nbsp;잡기&amp;nbsp;위해&amp;nbsp;사용되는지,&amp;nbsp;그리고&amp;nbsp;각각에&amp;nbsp;대한&amp;nbsp;깔끔한&amp;nbsp;코드&amp;nbsp;예제를&amp;nbsp;제공하겠다.&amp;nbsp;여기서는&amp;nbsp;간단한&amp;nbsp;함수를&amp;nbsp;사용하여&amp;nbsp;여러&amp;nbsp;단위&amp;nbsp;테스트에&amp;nbsp;대해&amp;nbsp;설명한다.&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;⭐ 1. 대상 함수&lt;/h3&gt;
&lt;pre id=&quot;code_1731337626403&quot; class=&quot;cpp&quot; data-ke-language=&quot;cpp&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;// calculateDiscount 함수는 구매 금액(amount)에 따라 할인율을 적용함.
// 100 이상일 때는 10% 할인, 50 이상 100 미만일 때는 5% 할인, 그 외에는 할인 없음.
double calculateDiscount(double amount) {
    if (amount &amp;gt;= 100) return amount * 0.9;
    else if (amount &amp;gt;= 50) return amount * 0.95;
    else return amount;
}&lt;/code&gt;&lt;/pre&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;⭐ 2. Positive UT&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;긍정&amp;nbsp;테스트는&amp;nbsp;함수가&amp;nbsp;올바른&amp;nbsp;입력에&amp;nbsp;대해&amp;nbsp;예상된&amp;nbsp;동작을&amp;nbsp;수행하는지&amp;nbsp;확인하기&amp;nbsp;위해&amp;nbsp;사용된다.&amp;nbsp;이는&amp;nbsp;기본적으로&amp;nbsp;함수의&amp;nbsp;&quot;정상적인&quot;&amp;nbsp;사용&amp;nbsp;사례를&amp;nbsp;테스트한다.&lt;/p&gt;
&lt;pre id=&quot;code_1731337681391&quot; class=&quot;cpp&quot; data-ke-language=&quot;cpp&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;void testCalculateDiscountPositive() {
    assert(calculateDiscount(150) == 135);  // 100 이상의 금액에 대해 10% 할인이 적용되어야 함.
    assert(calculateDiscount(75) == 71.25);  // 50 이상 100 미만의 금액에 대해 5% 할인이 적용되어야 함.
    assert(calculateDiscount(25) == 25);     // 50 미만의 금액에는 할인이 적용되지 않아야 함.
    printf(&quot;Positive tests passed.\n&quot;);
}&lt;/code&gt;&lt;/pre&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;⭐ 3. Negative UT&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;부정&amp;nbsp;테스트는&amp;nbsp;함수가&amp;nbsp;잘못된&amp;nbsp;입력이나&amp;nbsp;예외적인&amp;nbsp;상황을&amp;nbsp;적절하게&amp;nbsp;처리하는지&amp;nbsp;확인하기&amp;nbsp;위해&amp;nbsp;사용된다.&amp;nbsp;이는&amp;nbsp;함수의&amp;nbsp;오류&amp;nbsp;처리&amp;nbsp;능력을&amp;nbsp;테스트한다.&lt;/p&gt;
&lt;pre id=&quot;code_1731337747216&quot; class=&quot;cpp&quot; data-ke-language=&quot;cpp&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;void testCalculateDiscountNegative() {
    // 이 함수는 잘못된 입력에 대한 예외 처리를 구현하지 않았기 때문에, 의도적으로 오류 상황을 만들어 볼 수 없음.
    // 만약 calculateDiscount 함수가 음수 입력에 대해 에러를 반환하도록 설계되었다면, 그것을 테스트하는 코드가 여기에 위치할 것임.
}&lt;/code&gt;&lt;/pre&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;⭐ 4. Boundary UT&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;경계&amp;nbsp;테스트는&amp;nbsp;입력&amp;nbsp;값이나&amp;nbsp;출력&amp;nbsp;값이&amp;nbsp;경계에&amp;nbsp;위치할&amp;nbsp;때&amp;nbsp;함수의&amp;nbsp;동작을&amp;nbsp;검증하기&amp;nbsp;위해&amp;nbsp;사용된다.&amp;nbsp;이는&amp;nbsp;함수가&amp;nbsp;경계&amp;nbsp;조건에서도&amp;nbsp;올바르게&amp;nbsp;동작하는지&amp;nbsp;확인한다.&lt;/p&gt;
&lt;pre id=&quot;code_1731337798682&quot; class=&quot;cpp&quot; data-ke-language=&quot;cpp&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;void testCalculateDiscountBoundary() {
    assert(calculateDiscount(100) == 90);   // 정확히 100인 경우, 10% 할인이 적용되어야 함.
    assert(calculateDiscount(50) == 47.5);  // 정확히 50인 경우, 5% 할인이 적용되어야 함.
    assert(calculateDiscount(49.99) == 49.99); // 50 미만의 경계값에서 할인이 적용되지 않아야 함.
    printf(&quot;Boundary tests passed.\n&quot;);
}&lt;/code&gt;&lt;/pre&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;⭐ 5. Equivalence Partitioning UT&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;동등&amp;nbsp;분할&amp;nbsp;테스트는&amp;nbsp;입력&amp;nbsp;데이터를&amp;nbsp;유효한&amp;nbsp;값의&amp;nbsp;집합(할인이&amp;nbsp;적용되는&amp;nbsp;금액&amp;nbsp;범위)과&amp;nbsp;유효하지&amp;nbsp;않은&amp;nbsp;값의&amp;nbsp;집합(할인이&amp;nbsp;적용되지&amp;nbsp;않는&amp;nbsp;금액&amp;nbsp;범위)으로&amp;nbsp;나뉜다.&amp;nbsp;여기서는&amp;nbsp;모든&amp;nbsp;입력이&amp;nbsp;유효하므로,&amp;nbsp;할인율이&amp;nbsp;적용되는&amp;nbsp;범위를&amp;nbsp;기준으로&amp;nbsp;나눌&amp;nbsp;수&amp;nbsp;있다.&lt;/p&gt;
&lt;pre id=&quot;code_1731337837550&quot; class=&quot;cpp&quot; data-ke-language=&quot;cpp&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;void testCalculateDiscountEquivalence() {
    assert(calculateDiscount(25) == 25);     // 할인 없음
    assert(calculateDiscount(75) == 71.25);  // 5% 할인 적용
    assert(calculateDiscount(150) == 135);   // 10% 할인 적용
    printf(&quot;Equivalence partitioning tests passed.\n&quot;);
}&lt;/code&gt;&lt;/pre&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;⭐ 6. Min/Max Unit Test&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;경계&amp;nbsp;테스트는&amp;nbsp;할인율&amp;nbsp;변경점&amp;nbsp;근처의&amp;nbsp;값들을&amp;nbsp;테스트한다.&amp;nbsp;또한,&amp;nbsp;Min/Max&amp;nbsp;테스트로는&amp;nbsp;구매&amp;nbsp;금액의&amp;nbsp;합리적인&amp;nbsp;최소값과&amp;nbsp;최대값을&amp;nbsp;고려할&amp;nbsp;수&amp;nbsp;있다.&lt;/p&gt;
&lt;pre id=&quot;code_1731337880191&quot; class=&quot;cpp&quot; data-ke-language=&quot;cpp&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;void testCalculateDiscountBoundary() {
    assert(calculateDiscount(0) == 0);       // 최소값 테스트
    assert(calculateDiscount(1000) == 900);  // 예시로 든 최대값 테스트
    printf(&quot;Boundary and Min/Max tests passed.\n&quot;);
}&lt;/code&gt;&lt;/pre&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;⭐ 7. Fault Injection Unit Test&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;고의적으로 함수에 잘못된 값을 주입하여, 함수가 예외 상황을 적절히 처리하는지 확인하는 테스트이다. calculateDiscount 함수의 경우, 음수 금액을 처리하는 능력을 테스트할 수 있다. 하지만 현재 함수 구현에서는 음수 입력에 대한 명시적 처리가 없으므로, 이 예제는 함수가 예외를 처리하도록 설계된 상황을 가정하고 작성된다.&lt;/p&gt;
&lt;pre id=&quot;code_1731337922480&quot; class=&quot;cpp&quot; data-ke-language=&quot;cpp&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;void testCalculateDiscountFaultInjection() {
    // 가정: 음수 금액에 대해서는 0을 반환하도록 함수가 수정되었다고 가정
    assert(calculateDiscount(-50) == 0);  // 잘못된 입력 처리 테스트
    printf(&quot;Fault injection tests passed.\n&quot;);
}&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;실제&amp;nbsp;개발&amp;nbsp;환경에서는&amp;nbsp;이러한&amp;nbsp;테스트들을&amp;nbsp;통해&amp;nbsp;함수의&amp;nbsp;다양한&amp;nbsp;측면을&amp;nbsp;검증하여,&amp;nbsp;오류&amp;nbsp;가능성을&amp;nbsp;줄이고&amp;nbsp;코드의&amp;nbsp;신뢰성을&amp;nbsp;높일&amp;nbsp;수&amp;nbsp;있다.&amp;nbsp;Fault&amp;nbsp;Injection의&amp;nbsp;경우,&amp;nbsp;실제&amp;nbsp;구현에&amp;nbsp;따라&amp;nbsp;다르게&amp;nbsp;적용될&amp;nbsp;수&amp;nbsp;있으며,&amp;nbsp;함수가&amp;nbsp;예외&amp;nbsp;상황을&amp;nbsp;올바르게&amp;nbsp;처리할&amp;nbsp;수&amp;nbsp;있도록&amp;nbsp;보장하는&amp;nbsp;중요한&amp;nbsp;방법&amp;nbsp;중&amp;nbsp;하나이다.&lt;/p&gt;</description>
      <category>  C언어 30강</category>
      <category>Boundary</category>
      <category>C언어</category>
      <category>fault</category>
      <category>injection</category>
      <category>Negative</category>
      <category>positive</category>
      <category>test</category>
      <author>18진수</author>
      <guid isPermaLink="true">https://coding-yoon.tistory.com/280</guid>
      <comments>https://coding-yoon.tistory.com/280#entry280comment</comments>
      <pubDate>Tue, 12 Nov 2024 00:13:59 +0900</pubDate>
    </item>
    <item>
      <title>[C/C++ Tip] 29. C언어 Unit Test</title>
      <link>https://coding-yoon.tistory.com/279</link>
      <description>&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;600&quot; data-origin-height=&quot;600&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/buaM0I/btsKEXxtdv6/VN1yPAiIKRQBgfWbOTGb9k/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/buaM0I/btsKEXxtdv6/VN1yPAiIKRQBgfWbOTGb9k/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/buaM0I/btsKEXxtdv6/VN1yPAiIKRQBgfWbOTGb9k/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbuaM0I%2FbtsKEXxtdv6%2FVN1yPAiIKRQBgfWbOTGb9k%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;600&quot; height=&quot;600&quot; data-origin-width=&quot;600&quot; data-origin-height=&quot;600&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;Unit Test&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;C언어에서&amp;nbsp;단위&amp;nbsp;테스트(Unit&amp;nbsp;Test)를&amp;nbsp;구현하는&amp;nbsp;방법&amp;nbsp;중&amp;nbsp;하나는&amp;nbsp;간단한&amp;nbsp;함수와&amp;nbsp;함께&amp;nbsp;assert&amp;nbsp;매크로를&amp;nbsp;사용하는&amp;nbsp;것이다.&amp;nbsp;assert&amp;nbsp;매크로는&amp;nbsp;조건이&amp;nbsp;참이&amp;nbsp;아닐&amp;nbsp;경우&amp;nbsp;프로그램을&amp;nbsp;종료시키므로,&amp;nbsp;예상된&amp;nbsp;결과가&amp;nbsp;실제&amp;nbsp;결과와&amp;nbsp;일치하는지&amp;nbsp;검증하는&amp;nbsp;데&amp;nbsp;유용하다.&amp;nbsp;더&amp;nbsp;복잡한&amp;nbsp;테스트&amp;nbsp;요구&amp;nbsp;사항이&amp;nbsp;있는&amp;nbsp;경우,&amp;nbsp;C언어용&amp;nbsp;테스트&amp;nbsp;프레임워크(예:&amp;nbsp;CUnit,&amp;nbsp;Unity,&amp;nbsp;CMocka&amp;nbsp;등)를&amp;nbsp;사용할&amp;nbsp;수&amp;nbsp;있다. &lt;br /&gt;&lt;br /&gt;여기에는&amp;nbsp;간단한&amp;nbsp;add&amp;nbsp;함수와&amp;nbsp;이&amp;nbsp;함수에&amp;nbsp;대한&amp;nbsp;단위&amp;nbsp;테스트&amp;nbsp;예제가&amp;nbsp;포함되어&amp;nbsp;있다.&amp;nbsp;이&amp;nbsp;예제는&amp;nbsp;assert를&amp;nbsp;사용하여&amp;nbsp;구현된다. &lt;br /&gt;&lt;br /&gt;asset&amp;nbsp;함수를&amp;nbsp;사용하기&amp;nbsp;위해선&amp;nbsp;assert.h를&amp;nbsp;include&amp;nbsp;해야&amp;nbsp;한다.&lt;/p&gt;
&lt;pre id=&quot;code_1731337377705&quot; class=&quot;cpp&quot; data-ke-language=&quot;cpp&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;#include &amp;lt;stdio.h&amp;gt;
#include &amp;lt;assert.h&amp;gt;

// 간단한 덧셈 함수 정의
int add(int a, int b) {
    return a + b;
}

// add 함수를 테스트하기 위한 단위 테스트 함수
void test_add() {
    assert(add(0, 0) == 0); // 0 + 0 = 0
    assert(add(-1, 1) == 0); // -1 + 1 = 0
    assert(add(10, 20) == 30); // 10 + 20 = 30
    assert(add(-5, -10) == -15); // -5 + -10 = -15
    // 테스트가 여기까지 진행되면 모든 assert 조건이 참이라는 의미이며, 함수가 예상대로 작동한다는 것을 의미합니다.
    printf(&quot;All tests passed.\n&quot;);
}

int main() {
    test_add(); // 단위 테스트 실행
    return 0;
}&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이&amp;nbsp;예제에서&amp;nbsp;add&amp;nbsp;함수는&amp;nbsp;두&amp;nbsp;정수를&amp;nbsp;입력받아&amp;nbsp;그&amp;nbsp;합을&amp;nbsp;반환한다.&amp;nbsp;test_add&amp;nbsp;함수는&amp;nbsp;add&amp;nbsp;함수가&amp;nbsp;올바르게&amp;nbsp;작동하는지&amp;nbsp;검증하기&amp;nbsp;위해&amp;nbsp;몇&amp;nbsp;가지&amp;nbsp;사례를&amp;nbsp;테스트한다.&amp;nbsp;각&amp;nbsp;assert&amp;nbsp;호출은&amp;nbsp;add&amp;nbsp;함수에&amp;nbsp;특정&amp;nbsp;입력을&amp;nbsp;제공하고,&amp;nbsp;예상되는&amp;nbsp;출력과&amp;nbsp;실제&amp;nbsp;출력이&amp;nbsp;일치하는지&amp;nbsp;확인한다.&amp;nbsp;만약&amp;nbsp;일치하지&amp;nbsp;않는&amp;nbsp;경우,&amp;nbsp;assert는&amp;nbsp;프로그램을&amp;nbsp;즉시&amp;nbsp;종료시키며,&amp;nbsp;이는&amp;nbsp;테스트&amp;nbsp;실패를&amp;nbsp;의미한다. &lt;br /&gt;&lt;br /&gt;단위&amp;nbsp;테스트는&amp;nbsp;코드의&amp;nbsp;각&amp;nbsp;부분이&amp;nbsp;예상대로&amp;nbsp;작동하는지&amp;nbsp;확인하는&amp;nbsp;데&amp;nbsp;매우&amp;nbsp;중요하다.&amp;nbsp;이는&amp;nbsp;특히&amp;nbsp;프로젝트&amp;nbsp;규모가&amp;nbsp;커짐에&amp;nbsp;따라&amp;nbsp;더욱&amp;nbsp;중요해지며,&amp;nbsp;이를&amp;nbsp;통해&amp;nbsp;더&amp;nbsp;복잡한&amp;nbsp;시스템에서도&amp;nbsp;신뢰할&amp;nbsp;수&amp;nbsp;있는&amp;nbsp;코드를&amp;nbsp;유지할&amp;nbsp;수&amp;nbsp;있다. &lt;br /&gt;&lt;br /&gt;이&amp;nbsp;포스팅을&amp;nbsp;Unit&amp;nbsp;Test에&amp;nbsp;대해&amp;nbsp;간단히&amp;nbsp;소개했다.&amp;nbsp;하지만&amp;nbsp;Unit&amp;nbsp;Test에도&amp;nbsp;다양한&amp;nbsp;종류가&amp;nbsp;있으며&amp;nbsp;이를&amp;nbsp;통해&amp;nbsp;자신이&amp;nbsp;설계한&amp;nbsp;코드의&amp;nbsp;신뢰성을&amp;nbsp;높이는&amp;nbsp;것은&amp;nbsp;중요한&amp;nbsp;작업이다.&lt;/p&gt;</description>
      <category>  C언어 30강</category>
      <category>C언어</category>
      <category>test</category>
      <category>Unit</category>
      <author>18진수</author>
      <guid isPermaLink="true">https://coding-yoon.tistory.com/279</guid>
      <comments>https://coding-yoon.tistory.com/279#entry279comment</comments>
      <pubDate>Tue, 12 Nov 2024 00:03:32 +0900</pubDate>
    </item>
    <item>
      <title>[C/C++ Tip] 28. C언어 포인터의 다양한 표현들</title>
      <link>https://coding-yoon.tistory.com/278</link>
      <description>&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;600&quot; data-origin-height=&quot;600&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/dRO0pL/btsKEkfCu9p/Cl1nlyAYrvXZReTB72FLg1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/dRO0pL/btsKEkfCu9p/Cl1nlyAYrvXZReTB72FLg1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/dRO0pL/btsKEkfCu9p/Cl1nlyAYrvXZReTB72FLg1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FdRO0pL%2FbtsKEkfCu9p%2FCl1nlyAYrvXZReTB72FLg1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;600&quot; height=&quot;600&quot; data-origin-width=&quot;600&quot; data-origin-height=&quot;600&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;포인터의 다양한 표현&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;C언어의&amp;nbsp;포인터를&amp;nbsp;이해하고&amp;nbsp;활용하는&amp;nbsp;것은&amp;nbsp;처음&amp;nbsp;접하는&amp;nbsp;사람들에게&amp;nbsp;다소&amp;nbsp;어려울&amp;nbsp;수&amp;nbsp;있는데,&amp;nbsp;그&amp;nbsp;중&amp;nbsp;하나의&amp;nbsp;원인은&amp;nbsp;여러가지&amp;nbsp;다양한&amp;nbsp;표현법&amp;nbsp;때문이다.&amp;nbsp;특히,&amp;nbsp;같은&amp;nbsp;메모리&amp;nbsp;주소를&amp;nbsp;가리키는&amp;nbsp;다양한&amp;nbsp;방법이&amp;nbsp;존재하는데,&amp;nbsp;이는&amp;nbsp;때로는&amp;nbsp;혼란을&amp;nbsp;줄&amp;nbsp;수&amp;nbsp;있다.&amp;nbsp;여기&amp;nbsp;몇&amp;nbsp;가지&amp;nbsp;대표적인&amp;nbsp;예시를&amp;nbsp;들어본다.&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;⭐ 1. 배열의 첫 번째 요소의 주소&lt;/h3&gt;
&lt;pre id=&quot;code_1731336478405&quot; class=&quot;cpp&quot; data-ke-language=&quot;cpp&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;int A[10];&lt;/code&gt;&lt;/pre&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;표현법 1: A​
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;배열의 이름만 사용하면, 배열의 첫 번째 요소의 주소를 나타낸다.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;표현법 2: &amp;amp;A[0]
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;배열의 첫 번째 요소의 주소를 명시적으로 나타낸다.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;⭐ 2. 함수 포인터&lt;/h3&gt;
&lt;pre id=&quot;code_1731336589592&quot; class=&quot;cpp&quot; data-ke-language=&quot;cpp&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;int func(int x) {
  return x * 2;
}&lt;/code&gt;&lt;/pre&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;표현법 1: ​func
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;함수 이름만을 사용하여 해당 함수의 주소를 나타낸다.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;표현법 2: &amp;amp;func
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;함수의 주소를 명시적으로 나타내기 위해 함수 이름 앞에 &amp;amp;를 붙여 사용한다.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;⭐ 3. 구조체 멤버의 주소&lt;/h3&gt;
&lt;pre id=&quot;code_1731336697675&quot; class=&quot;cpp&quot; data-ke-language=&quot;cpp&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;struct MyStruct {
  int x;
};

struct MyStruct *ptr = &amp;amp;myStruct;&lt;/code&gt;&lt;/pre&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;표현법 1: (*ptr).x
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;구조체 멤버 x의 주소를 직접 나타낸다.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;표현법 2: ptr-&amp;gt;x
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;구조체의 시작 주소를 int *로 캐스팅하여, 첫 번째 멤버 x의 주소를 얻는다. 이는 구조체가 x로 시작한다고 가정할 때 유효하다.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;⭐ 4. 포인터를 통한 배열 접근&lt;/h3&gt;
&lt;pre id=&quot;code_1731336771336&quot; class=&quot;cpp&quot; data-ke-language=&quot;cpp&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;int arr[3] = {10, 20, 30};
int *ptr = arr;&lt;/code&gt;&lt;/pre&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;표현법 1: ptr[0]
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;포인터를 배열처럼 인덱싱하여 첫 번째 요소에 접근한다.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;표현법 2: *ptr​
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;포인터를 역참조하여 첫 번째 요소의 값을 얻는다.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;⭐ 5. 문자열과 포인터&lt;/h3&gt;
&lt;pre id=&quot;code_1731336839678&quot; class=&quot;cpp&quot; data-ke-language=&quot;cpp&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;char *str = &quot;Hello&quot;;&lt;/code&gt;&lt;/pre&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;표현법 1: str
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;포인터 변수 str을 사용하여 문자열의 첫 번째 문자의 주소를 나타낸다.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;표현법 2: &amp;amp;str[0]
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;문자열의 첫 번째 문자의 주소를 명시적으로 나타낸다.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;br /&gt;이러한&amp;nbsp;예시들은&amp;nbsp;C언어에서&amp;nbsp;포인터와&amp;nbsp;관련된&amp;nbsp;다양한&amp;nbsp;표현법들이&amp;nbsp;어떻게&amp;nbsp;유사한&amp;nbsp;결과를&amp;nbsp;제공할&amp;nbsp;수&amp;nbsp;있는지를&amp;nbsp;보여준다.&amp;nbsp;포인터는&amp;nbsp;강력하지만,&amp;nbsp;그&amp;nbsp;사용법을&amp;nbsp;정확히&amp;nbsp;이해하고&amp;nbsp;사용하는&amp;nbsp;것이&amp;nbsp;중요하다.&lt;/p&gt;</description>
      <category>  C언어 30강</category>
      <category>C언어</category>
      <category>다양한</category>
      <category>모습</category>
      <category>포인터의</category>
      <category>표현</category>
      <author>18진수</author>
      <guid isPermaLink="true">https://coding-yoon.tistory.com/278</guid>
      <comments>https://coding-yoon.tistory.com/278#entry278comment</comments>
      <pubDate>Mon, 11 Nov 2024 23:56:18 +0900</pubDate>
    </item>
    <item>
      <title>[C/C++ Tip] 27. C언어 데이터 형식 범위</title>
      <link>https://coding-yoon.tistory.com/277</link>
      <description>&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;600&quot; data-origin-height=&quot;600&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/dFH4ZO/btsKDPf34fe/LsOm1mIL0k1o5svP4iOpwk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/dFH4ZO/btsKDPf34fe/LsOm1mIL0k1o5svP4iOpwk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/dFH4ZO/btsKDPf34fe/LsOm1mIL0k1o5svP4iOpwk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FdFH4ZO%2FbtsKDPf34fe%2FLsOm1mIL0k1o5svP4iOpwk%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;600&quot; height=&quot;600&quot; data-origin-width=&quot;600&quot; data-origin-height=&quot;600&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;데이터 형식의 범위&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;C언어는&amp;nbsp;다양한&amp;nbsp;데이터&amp;nbsp;타입을&amp;nbsp;제공하며,&amp;nbsp;이러한&amp;nbsp;데이터&amp;nbsp;타입들은&amp;nbsp;메모리의&amp;nbsp;효율적&amp;nbsp;사용과&amp;nbsp;연산의&amp;nbsp;정확성을&amp;nbsp;위해&amp;nbsp;설계되었다.&amp;nbsp;각&amp;nbsp;데이터&amp;nbsp;타입은&amp;nbsp;표현할&amp;nbsp;수&amp;nbsp;있는&amp;nbsp;값의&amp;nbsp;범위가&amp;nbsp;정해져&amp;nbsp;있으며,&amp;nbsp;이는&amp;nbsp;해당&amp;nbsp;타입이&amp;nbsp;메모리에서&amp;nbsp;차지하는&amp;nbsp;바이트&amp;nbsp;크기에&amp;nbsp;의해&amp;nbsp;결정된.&amp;nbsp;C언어의&amp;nbsp;기본&amp;nbsp;단위는&amp;nbsp;1바이트이며,&amp;nbsp;여기서&amp;nbsp;1바이트는&amp;nbsp;8비트와&amp;nbsp;동일하다. &lt;br /&gt;&lt;br /&gt;아래에서는&amp;nbsp;몇&amp;nbsp;가지&amp;nbsp;주요&amp;nbsp;데이터&amp;nbsp;타입의&amp;nbsp;최소값과&amp;nbsp;최대값을&amp;nbsp;살펴보겠다.&amp;nbsp;이&amp;nbsp;값들은&amp;nbsp;데이터&amp;nbsp;타입이&amp;nbsp;양수만을&amp;nbsp;저장할&amp;nbsp;수&amp;nbsp;있는지(부호&amp;nbsp;없음,&amp;nbsp;unsigned),&amp;nbsp;아니면&amp;nbsp;음수와&amp;nbsp;양수&amp;nbsp;모두를&amp;nbsp;저장할&amp;nbsp;수&amp;nbsp;있는지(부호&amp;nbsp;있음,&amp;nbsp;signed)에&amp;nbsp;따라&amp;nbsp;달라진다.&amp;nbsp;이&amp;nbsp;예시에서는&amp;nbsp;일반적인&amp;nbsp;32비트&amp;nbsp;및&amp;nbsp;64비트&amp;nbsp;시스템을&amp;nbsp;기준으로&amp;nbsp;설명한다.&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;⭐ 1. unsigned char&lt;/h3&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;크기: 1바이트 (8비트)&lt;/li&gt;
&lt;li&gt;범위: 0 ~ 255&lt;/li&gt;
&lt;li&gt;설명:&amp;nbsp;unsigned&amp;nbsp;char는&amp;nbsp;부호&amp;nbsp;없는&amp;nbsp;8비트&amp;nbsp;정수로,&amp;nbsp;0부터&amp;nbsp;255까지의&amp;nbsp;값을&amp;nbsp;저장할&amp;nbsp;수&amp;nbsp;있다.&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;⭐ 2. signed char&lt;/h3&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;크기: 1바이트 (8비트)&lt;/li&gt;
&lt;li&gt;범위: -128 ~ 127&lt;/li&gt;
&lt;li&gt;설명:&amp;nbsp;signed&amp;nbsp;char는&amp;nbsp;부호&amp;nbsp;있는&amp;nbsp;8비트&amp;nbsp;정수로,&amp;nbsp;-128부터&amp;nbsp;127까지의&amp;nbsp;값을&amp;nbsp;저장할&amp;nbsp;수&amp;nbsp;있다.&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;⭐ 3. int16_t&amp;nbsp;(또는&amp;nbsp;short)&lt;/h3&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;크기: 2바이트 (16비트)&lt;/li&gt;
&lt;li&gt;범위: -32,768 ~ 32,767&lt;/li&gt;
&lt;li&gt;설명:&amp;nbsp;int16_t는&amp;nbsp;부호&amp;nbsp;있는&amp;nbsp;16비트&amp;nbsp;정수로,&amp;nbsp;-32,768부터&amp;nbsp;32,767까지의&amp;nbsp;값을&amp;nbsp;저장할&amp;nbsp;수&amp;nbsp;있다.&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;⭐ 4. int32_t (또는 int)&lt;/h3&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;크기: 4바이트 (32비트)&lt;/li&gt;
&lt;li&gt;범위: -2,147,483,648 ~ 2,147,483,647&lt;/li&gt;
&lt;li&gt;설명:&amp;nbsp;int32_t는&amp;nbsp;부호&amp;nbsp;있는&amp;nbsp;32비트&amp;nbsp;정수로,&amp;nbsp;약&amp;nbsp;-2.1억부터&amp;nbsp;2.1억까지의&amp;nbsp;값을&amp;nbsp;저장할&amp;nbsp;수&amp;nbsp;있다.&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;⭐ 5. uint32_t&amp;nbsp;(또는&amp;nbsp;unsigned&amp;nbsp;int)&lt;/h3&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;크기: 4바이트 (32비트)&lt;/li&gt;
&lt;li&gt;범위: 0 ~ 4,294,967,295&lt;/li&gt;
&lt;li&gt;설명:&amp;nbsp;uint32_t는&amp;nbsp;부호&amp;nbsp;없는&amp;nbsp;32비트&amp;nbsp;정수로,&amp;nbsp;0부터&amp;nbsp;약&amp;nbsp;42억까지의&amp;nbsp;값을&amp;nbsp;저장할&amp;nbsp;수&amp;nbsp;있다.&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;⭐ 6. float&lt;/h3&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;크기: 4바이트 (32비트)&lt;/li&gt;
&lt;li&gt;범위: 대략 -3.4E+38 ~ 3.4E+38 (유효 숫자 약 7자리)&lt;/li&gt;
&lt;li&gt;설명:&amp;nbsp;float는&amp;nbsp;부동&amp;nbsp;소수점&amp;nbsp;수로,&amp;nbsp;매우&amp;nbsp;크거나&amp;nbsp;매우&amp;nbsp;작은&amp;nbsp;수를&amp;nbsp;표현할&amp;nbsp;수&amp;nbsp;있으며,&amp;nbsp;주로&amp;nbsp;과학&amp;nbsp;계산에&amp;nbsp;사용된다.&amp;nbsp;float는&amp;nbsp;유효&amp;nbsp;숫자가&amp;nbsp;약&amp;nbsp;7자리인&amp;nbsp;실수&amp;nbsp;값을&amp;nbsp;저장할&amp;nbsp;수&amp;nbsp;있다.&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;⭐ 7. 고려사항&lt;/h3&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;메모리 사용 최적화: 가능한 한 적은 메모리를 사용하는 타입을 선택하세요. 예를 들어, 값의 범위가 0~255 사이라면 unsigned char를 사용하는 것이 좋다.&lt;/li&gt;
&lt;li&gt;수치 범위 고려: 변수가 저장해야 할 값의 범위를 고려하여 적절한 타입을 선택하세요. 예를 들어, 양수만 필요한 경우 unsigned 타입을 고려해야 한다.&lt;/li&gt;
&lt;li&gt;표준 타입 사용: 표준화된 데이터 타입(int16_t, uint32_t 등)을 사용하면 코드의 이식성이 향상된다.&lt;/li&gt;
&lt;li&gt;성능 고려: 목표 플랫폼에서의 연산 성능도 고려하세요. 일부 시스템에서는 특정 크기의 데이터 타입을 더 효율적으로 처리할 수 있다.&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;각&amp;nbsp;데이터&amp;nbsp;타입의&amp;nbsp;선택은&amp;nbsp;애플리케이션의&amp;nbsp;요구&amp;nbsp;사항,&amp;nbsp;메모리&amp;nbsp;효율성,&amp;nbsp;처리&amp;nbsp;속도&amp;nbsp;등&amp;nbsp;여러&amp;nbsp;요소를&amp;nbsp;고려해야&amp;nbsp;한다.&amp;nbsp;C언어&amp;nbsp;프로그래밍에서&amp;nbsp;올바른&amp;nbsp;데이터&amp;nbsp;타입을&amp;nbsp;선택하는&amp;nbsp;것은&amp;nbsp;프로그램의&amp;nbsp;성능과&amp;nbsp;안정성을&amp;nbsp;크게&amp;nbsp;향상시킬&amp;nbsp;수&amp;nbsp;있다.&lt;/p&gt;</description>
      <category>  C언어 30강</category>
      <category>C언어</category>
      <category>데이터</category>
      <category>범위</category>
      <category>사이즈</category>
      <category>형식</category>
      <author>18진수</author>
      <guid isPermaLink="true">https://coding-yoon.tistory.com/277</guid>
      <comments>https://coding-yoon.tistory.com/277#entry277comment</comments>
      <pubDate>Mon, 11 Nov 2024 23:44:21 +0900</pubDate>
    </item>
    <item>
      <title>[C/C++ Tip] 26. Char, String 기본 사용법</title>
      <link>https://coding-yoon.tistory.com/276</link>
      <description>&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;652&quot; data-origin-height=&quot;488&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/dL8BRX/btsKDyxsVNB/X8FnKKKQ8w6YdeM43BxjJK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/dL8BRX/btsKDyxsVNB/X8FnKKKQ8w6YdeM43BxjJK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/dL8BRX/btsKDyxsVNB/X8FnKKKQ8w6YdeM43BxjJK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FdL8BRX%2FbtsKDyxsVNB%2FX8FnKKKQ8w6YdeM43BxjJK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;652&quot; height=&quot;488&quot; data-origin-width=&quot;652&quot; data-origin-height=&quot;488&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;char, string&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;C언어에서&amp;nbsp;char과&amp;nbsp;string의&amp;nbsp;개념은&amp;nbsp;상당히&amp;nbsp;기본적이면서도&amp;nbsp;중요하다.&amp;nbsp;이&amp;nbsp;두&amp;nbsp;가지는&amp;nbsp;데이터를&amp;nbsp;다룰&amp;nbsp;때&amp;nbsp;자주&amp;nbsp;사용되기&amp;nbsp;때문에&amp;nbsp;그&amp;nbsp;차이점을&amp;nbsp;이해하는&amp;nbsp;것이&amp;nbsp;중요하다.&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;⭐ 1. char&lt;/h3&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;char은 C언어에서 한 개의 문자를 저장하기 위한 데이터 타입이다.&lt;/li&gt;
&lt;li&gt;메모리에서 1바이트(대부분의 시스템에서)를 차지한다.&lt;/li&gt;
&lt;li&gt;단일 따옴표(' ')를 사용하여 표현한다. 예: char letter = 'A';&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;⭐ 2. string&lt;/h3&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;C언어는 원래 string 타입을 지원하지 않는다. 대신, 문자열은 char 타입의 배열로 표현된다.&lt;/li&gt;
&lt;li&gt;문자열은 끝에 널 문자(\0)를 포함하여 이것이 문자열의 끝임을 나타낸다.&lt;/li&gt;
&lt;li&gt;문자열은 쌍따옴표(&quot; &quot;)로 둘러싸여 표현된다. 예: char name[] = &quot;Hello&quot;;&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;⭐ 3. Code&lt;/h3&gt;
&lt;pre id=&quot;code_1731235354624&quot; class=&quot;cpp&quot; data-ke-language=&quot;cpp&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;#include &amp;lt;stdio.h&amp;gt;

int main() {
    // char 예시
    char letter = 'A';
    printf(&quot;The letter is: %c\n&quot;, letter);

    // string (char 배열) 예시
    char name[] = &quot;Hello&quot;;
    printf(&quot;The name is: %s\n&quot;, name);

    return 0;
}&lt;/code&gt;&lt;/pre&gt;
&lt;h3 style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size23&quot;&gt;⭐ 4. 주의사항&lt;/h3&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;문자열을 다룰 때 널 문자(\0, null)의 존재를 항상 기억해야 한다. 이것이 없으면 문자열이 제대로 끝나지 않아 예기치 않은 동작을 일으킬 수 있다.&lt;/li&gt;
&lt;li&gt;char 배열을 사용하여 문자열을 다룰 때는 배열의 크기가 저장하려는 문자열의 길이보다 크거나 같아야 한다.&lt;/li&gt;
&lt;li&gt;char 사용: 단일 문자 처리가 필요할 때 사용한다. 예를 들어, 사용자 입력에서 특정 문자를 검사하거나, 문자를 하나씩 조작할 필요가 있을 때 유용하다.&lt;/li&gt;
&lt;li&gt;string&amp;nbsp;(char&amp;nbsp;배열)&amp;nbsp;사용:&amp;nbsp;사용자&amp;nbsp;이름,&amp;nbsp;주소&amp;nbsp;등과&amp;nbsp;같이&amp;nbsp;여러&amp;nbsp;문자로&amp;nbsp;이루어진&amp;nbsp;데이터를&amp;nbsp;저장하고&amp;nbsp;싶을&amp;nbsp;때&amp;nbsp;사용한다.&amp;nbsp;또한,&amp;nbsp;파일에서&amp;nbsp;텍스트를&amp;nbsp;읽거나&amp;nbsp;콘솔에&amp;nbsp;메시지를&amp;nbsp;출력할&amp;nbsp;때도&amp;nbsp;자주&amp;nbsp;사용된다. &lt;br /&gt;&lt;br /&gt;​&lt;/li&gt;
&lt;/ul&gt;</description>
      <category>  C언어 30강</category>
      <category>char</category>
      <category>C언어</category>
      <category>String</category>
      <author>18진수</author>
      <guid isPermaLink="true">https://coding-yoon.tistory.com/276</guid>
      <comments>https://coding-yoon.tistory.com/276#entry276comment</comments>
      <pubDate>Sun, 10 Nov 2024 19:43:44 +0900</pubDate>
    </item>
    <item>
      <title>[C/C++ Tip] 25. C언어 2차원 배열</title>
      <link>https://coding-yoon.tistory.com/275</link>
      <description>&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;652&quot; data-origin-height=&quot;488&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bjoLJo/btsKDeGkqxA/zhcR2KlX3ZeRGyqGE7N6Y1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bjoLJo/btsKDeGkqxA/zhcR2KlX3ZeRGyqGE7N6Y1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bjoLJo/btsKDeGkqxA/zhcR2KlX3ZeRGyqGE7N6Y1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbjoLJo%2FbtsKDeGkqxA%2FzhcR2KlX3ZeRGyqGE7N6Y1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;652&quot; height=&quot;488&quot; data-origin-width=&quot;652&quot; data-origin-height=&quot;488&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;2차원 배열&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;C언어에서&amp;nbsp;2차원&amp;nbsp;배열을&amp;nbsp;다루는&amp;nbsp;것은&amp;nbsp;프로그래밍의&amp;nbsp;기본이면서도,&amp;nbsp;다양한&amp;nbsp;응용&amp;nbsp;분야에서&amp;nbsp;필수적으로&amp;nbsp;사용되는&amp;nbsp;중요한&amp;nbsp;개념이다.&amp;nbsp;이&amp;nbsp;글에서는&amp;nbsp;2차원&amp;nbsp;배열의&amp;nbsp;기본적인&amp;nbsp;사용법,&amp;nbsp;몇&amp;nbsp;가지&amp;nbsp;팁과&amp;nbsp;코드&amp;nbsp;예시를&amp;nbsp;통해&amp;nbsp;이해를&amp;nbsp;돕는다.&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;⭐ 1. 2차원 배열 구조&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;2차원&amp;nbsp;배열은&amp;nbsp;데이터를&amp;nbsp;행렬의&amp;nbsp;형태로&amp;nbsp;저장할&amp;nbsp;때&amp;nbsp;사용되며,&amp;nbsp;타입&amp;nbsp;배열이름[행의&amp;nbsp;개수][열의&amp;nbsp;개수];의&amp;nbsp;형태로&amp;nbsp;선언한다.&amp;nbsp;예를&amp;nbsp;들어,&amp;nbsp;3행&amp;nbsp;4열의&amp;nbsp;정수형&amp;nbsp;2차원&amp;nbsp;배열은&amp;nbsp;다음과&amp;nbsp;같이&amp;nbsp;선언한다.&lt;/p&gt;
&lt;pre id=&quot;code_1731233261572&quot; class=&quot;cpp&quot; data-ke-language=&quot;cpp&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;int matrix[3][4];&lt;/code&gt;&lt;/pre&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;⭐ 2. 초기화&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;2차원&amp;nbsp;배열은&amp;nbsp;선언과&amp;nbsp;동시에&amp;nbsp;초기화할&amp;nbsp;수&amp;nbsp;있다.&amp;nbsp;배열을&amp;nbsp;초기화할&amp;nbsp;때는&amp;nbsp;중괄호&amp;nbsp;{}를&amp;nbsp;사용하여&amp;nbsp;각&amp;nbsp;행의&amp;nbsp;요소를&amp;nbsp;나열한다. &lt;/p&gt;
&lt;pre id=&quot;code_1731233318223&quot; class=&quot;cpp&quot; data-ke-language=&quot;cpp&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;int matrix[3][4] = {
    {1, 2, 3, 4},
    {5, 6, 7, 8},
    {9, 10, 11, 12}
};&lt;/code&gt;&lt;/pre&gt;
&lt;h3 style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size23&quot;&gt;⭐ 3. 배열의 접근&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;2차원&amp;nbsp;배열의&amp;nbsp;각&amp;nbsp;요소에&amp;nbsp;접근하려면&amp;nbsp;두&amp;nbsp;개의&amp;nbsp;인덱스를&amp;nbsp;사용한다.&amp;nbsp;첫&amp;nbsp;번째&amp;nbsp;인덱스는&amp;nbsp;행을,&amp;nbsp;두&amp;nbsp;번째&amp;nbsp;인덱스는&amp;nbsp;열을&amp;nbsp;가리킨다.&amp;nbsp;다음은&amp;nbsp;2차원&amp;nbsp;배열의&amp;nbsp;모든&amp;nbsp;값을&amp;nbsp;출력하는&amp;nbsp;예제이다.&lt;/p&gt;
&lt;pre id=&quot;code_1731233342931&quot; class=&quot;cpp&quot; data-ke-language=&quot;cpp&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;for(int i = 0; i &amp;lt; 3; i++) {
    for(int j = 0; j &amp;lt; 4; j++) {
        printf(&quot;%d &quot;, matrix[i][j]);
    }
    printf(&quot;\n&quot;);
}&lt;/code&gt;&lt;/pre&gt;
&lt;h3 style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size23&quot;&gt;⭐ 4. 동적 할당&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;고정된&amp;nbsp;크기의&amp;nbsp;배열&amp;nbsp;대신,&amp;nbsp;프로그램&amp;nbsp;실행&amp;nbsp;중에&amp;nbsp;배열의&amp;nbsp;크기를&amp;nbsp;결정해야&amp;nbsp;하는&amp;nbsp;경우가&amp;nbsp;있다.&amp;nbsp;이럴&amp;nbsp;때는&amp;nbsp;malloc&amp;nbsp;또는&amp;nbsp;calloc&amp;nbsp;함수를&amp;nbsp;사용하여&amp;nbsp;2차원&amp;nbsp;배열을&amp;nbsp;동적으로&amp;nbsp;할당할&amp;nbsp;수&amp;nbsp;있다.&amp;nbsp;ex)&amp;nbsp;행렬&amp;nbsp;계산&lt;/p&gt;
&lt;pre id=&quot;code_1731233365547&quot; class=&quot;cpp&quot; data-ke-language=&quot;cpp&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;int **matrix = (int **)malloc(3 * sizeof(int *));
for(int i = 0; i &amp;lt; 3; i++) {
    matrix[i] = (int *)malloc(4 * sizeof(int));
}&lt;/code&gt;&lt;/pre&gt;
&lt;h3 style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size23&quot;&gt;⭐ 5. 배열의 포인터&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;2차원&amp;nbsp;배열을&amp;nbsp;함수의&amp;nbsp;인자로&amp;nbsp;전달할&amp;nbsp;때는,&amp;nbsp;배열의&amp;nbsp;포인터를&amp;nbsp;사용하는&amp;nbsp;것이&amp;nbsp;효율적이다.&amp;nbsp;이를&amp;nbsp;통해&amp;nbsp;큰&amp;nbsp;데이터의&amp;nbsp;복사&amp;nbsp;없이&amp;nbsp;배열에&amp;nbsp;접근할&amp;nbsp;수&amp;nbsp;있다.&lt;/p&gt;
&lt;pre id=&quot;code_1731233391426&quot; class=&quot;cpp&quot; data-ke-language=&quot;cpp&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;#include &amp;lt;stdio.h&amp;gt;
#include &amp;lt;stdlib.h&amp;gt;

void printMatrix(int* matrix[4], int rows) {
    for (int i = 0; i &amp;lt; rows; i++) {
        for (int j = 0; j &amp;lt; 4; j++) {
            printf(&quot;%d &quot;, matrix[i][j]);
        }
        printf(&quot;\n&quot;);
    }
}

int main() {
    int* matrix[4];
    for (int i = 0; i &amp;lt; 4; i++) {
        matrix[i] = (int*)malloc(4 * sizeof(int)); // 각 행을 동적으로 할당
        for (int j = 0; j &amp;lt; 4; j++) {
            matrix[i][j] = i * 4 + j; // 예시 데이터
        }
    }

    printMatrix(matrix, 4);

    // 할당 해제
    for (int i = 0; i &amp;lt; 4; i++) {
        free(matrix[i]);
    }

    return 0;
}&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;2차원&amp;nbsp;배열은&amp;nbsp;데이터를&amp;nbsp;구조화하고,&amp;nbsp;다루는&amp;nbsp;데&amp;nbsp;있어&amp;nbsp;매우&amp;nbsp;유용하다.&amp;nbsp;C언어를&amp;nbsp;사용하여&amp;nbsp;2차원&amp;nbsp;배열을&amp;nbsp;효과적으로&amp;nbsp;활용하려면,&amp;nbsp;배열의&amp;nbsp;선언과&amp;nbsp;초기화,&amp;nbsp;메모리&amp;nbsp;할당,&amp;nbsp;그리고&amp;nbsp;함수와의&amp;nbsp;상호작용&amp;nbsp;방법을&amp;nbsp;정확히&amp;nbsp;이해하는&amp;nbsp;것이&amp;nbsp;중요하다.&lt;/p&gt;</description>
      <category>  C언어 30강</category>
      <category>2차원</category>
      <category>C언어</category>
      <category>동적</category>
      <category>배열</category>
      <category>터의 배열</category>
      <category>포인</category>
      <category>할당</category>
      <author>18진수</author>
      <guid isPermaLink="true">https://coding-yoon.tistory.com/275</guid>
      <comments>https://coding-yoon.tistory.com/275#entry275comment</comments>
      <pubDate>Sun, 10 Nov 2024 19:15:22 +0900</pubDate>
    </item>
    <item>
      <title>[C/C++ Tip] 24. C언어 파일 입출력</title>
      <link>https://coding-yoon.tistory.com/274</link>
      <description>&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;652&quot; data-origin-height=&quot;488&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/ccXwmE/btsKC6VulVr/0fCXF26SKK80TINTGmJgOK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/ccXwmE/btsKC6VulVr/0fCXF26SKK80TINTGmJgOK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/ccXwmE/btsKC6VulVr/0fCXF26SKK80TINTGmJgOK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FccXwmE%2FbtsKC6VulVr%2F0fCXF26SKK80TINTGmJgOK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;652&quot; height=&quot;488&quot; data-origin-width=&quot;652&quot; data-origin-height=&quot;488&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;파일 입출력&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이번&amp;nbsp;포스팅은&amp;nbsp;간단한&amp;nbsp;사용자&amp;nbsp;정보(이름,&amp;nbsp;나이,&amp;nbsp;이메일)를&amp;nbsp;CSV&amp;nbsp;형식으로&amp;nbsp;&amp;nbsp;txt&amp;nbsp;파일에&amp;nbsp;저장하고,&amp;nbsp;저장된&amp;nbsp;파일을&amp;nbsp;다시&amp;nbsp;읽어와서&amp;nbsp;화면에&amp;nbsp;출력하는&amp;nbsp;예제를&amp;nbsp;다룬다.&amp;nbsp;실제&amp;nbsp;C언어에서&amp;nbsp;파일&amp;nbsp;입출력을&amp;nbsp;사용한&amp;nbsp;적은&amp;nbsp;크게&amp;nbsp;없다.&amp;nbsp;하지만&amp;nbsp;파일이&amp;nbsp;쓰고&amp;nbsp;읽히는&amp;nbsp;기본&amp;nbsp;원리를&amp;nbsp;이해하기&amp;nbsp;위해&amp;nbsp;작성하게&amp;nbsp;되었다.&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;⭐ 1. 파일 쓰기 예제&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;먼저&amp;nbsp;사용자&amp;nbsp;정보를&amp;nbsp;txt&amp;nbsp;파일에&amp;nbsp;저장하는&amp;nbsp;예제부터&amp;nbsp;시작한다.&amp;nbsp;파일에&amp;nbsp;데이터를&amp;nbsp;쓰기&amp;nbsp;위해&amp;nbsp;fprintf&amp;nbsp;함수를&amp;nbsp;사용한다.&amp;nbsp;각&amp;nbsp;필드는&amp;nbsp;쉼표로&amp;nbsp;구분하고,&amp;nbsp;각&amp;nbsp;레코드는&amp;nbsp;새로운&amp;nbsp;줄에&amp;nbsp;위치한다.&lt;/p&gt;
&lt;pre id=&quot;code_1731125301502&quot; class=&quot;cpp&quot; data-ke-language=&quot;cpp&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;#include &amp;lt;stdio.h&amp;gt;

int main() {
    // 파일 포인터 선언
    FILE *fp = fopen(&quot;test.txt&quot;, &quot;w&quot;);
    if (fp == NULL) {
        perror(&quot;파일 열기 실패&quot;);
        return -1;
    }

    // 데이터 쓰기 (이름, 나이, 이메일)
    fprintf(fp, &quot;이름,나이,이메일\n&quot;); // 헤더 작성
    fprintf(fp, &quot;홍길동,30,hong@example.com\n&quot;);
    fprintf(fp, &quot;김철수,25,kim@example.com\n&quot;);

    // 파일 닫기
    fclose(fp);

    printf(&quot;데이터가 성공적으로 저장되었습니다.\n&quot;);

    return 0;
}&lt;/code&gt;&lt;/pre&gt;
&lt;table style=&quot;background-color: #ffffff; color: #000000; text-align: left; border-collapse: collapse; width: 100%;&quot; border=&quot;1&quot; data-ke-align=&quot;alignLeft&quot;&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td style=&quot;background-color: #ededed;&quot; colspan=&quot;1&quot; rowspan=&quot;1&quot;&gt;
&lt;div&gt;&lt;span&gt;&lt;span style=&quot;background-color: #ededed; color: #0d0d0d;&quot;&gt;&lt;b&gt;모드&lt;/b&gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;
&lt;/td&gt;
&lt;td style=&quot;background-color: #ededed;&quot; colspan=&quot;1&quot; rowspan=&quot;1&quot;&gt;
&lt;div&gt;&lt;span&gt;&lt;span style=&quot;background-color: #ededed; color: #0d0d0d;&quot;&gt;&lt;b&gt;설명&lt;/b&gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;background-color: #ffffff;&quot; colspan=&quot;1&quot; rowspan=&quot;1&quot;&gt;
&lt;div&gt;&lt;span&gt;&lt;span style=&quot;background-color: #ffffff; color: #0d0d0d;&quot;&gt;&lt;b&gt;r&lt;/b&gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;
&lt;/td&gt;
&lt;td style=&quot;background-color: #ffffff;&quot; colspan=&quot;1&quot; rowspan=&quot;1&quot;&gt;
&lt;div&gt;&lt;span&gt;&lt;span style=&quot;background-color: #ffffff; color: #0d0d0d;&quot;&gt;읽기 전용으로 파일 열기. 파일이 존재하지 않으면 열기 실패.&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;background-color: #ffffff;&quot; colspan=&quot;1&quot; rowspan=&quot;1&quot;&gt;
&lt;div&gt;&lt;span&gt;&lt;span style=&quot;background-color: #ffffff; color: #0d0d0d;&quot;&gt;&lt;b&gt;w&lt;/b&gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;
&lt;/td&gt;
&lt;td style=&quot;background-color: #ffffff;&quot; colspan=&quot;1&quot; rowspan=&quot;1&quot;&gt;
&lt;div&gt;&lt;span&gt;&lt;span style=&quot;background-color: #ffffff; color: #0d0d0d;&quot;&gt;쓰기 전용으로 파일 열기. 파일이 이미 존재하면 내용을 지우고, 없으면 새 파일 생성.&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;background-color: #ffffff;&quot; colspan=&quot;1&quot; rowspan=&quot;1&quot;&gt;
&lt;div&gt;&lt;span&gt;&lt;span style=&quot;background-color: #ffffff; color: #0d0d0d;&quot;&gt;&lt;b&gt;a&lt;/b&gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;
&lt;/td&gt;
&lt;td style=&quot;background-color: #ffffff;&quot; colspan=&quot;1&quot; rowspan=&quot;1&quot;&gt;
&lt;div&gt;&lt;span&gt;&lt;span style=&quot;background-color: #ffffff; color: #0d0d0d;&quot;&gt;추가 모드로 파일 열기. 파일이 이미 존재하면 데이터를 파일 끝에 추가하고, 없으면 새 파일 생성.&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;background-color: #ffffff;&quot; colspan=&quot;1&quot; rowspan=&quot;1&quot;&gt;
&lt;div&gt;&lt;span&gt;&lt;span style=&quot;background-color: #ffffff; color: #0d0d0d;&quot;&gt;&lt;b&gt;r+&lt;/b&gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;
&lt;/td&gt;
&lt;td style=&quot;background-color: #ffffff;&quot; colspan=&quot;1&quot; rowspan=&quot;1&quot;&gt;
&lt;div&gt;&lt;span&gt;&lt;span style=&quot;background-color: #ffffff; color: #0d0d0d;&quot;&gt;읽기/쓰기 모드로 파일 열기. 파일이 존재하지 않으면 열기 실패.&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;background-color: #ffffff;&quot; colspan=&quot;1&quot; rowspan=&quot;1&quot;&gt;
&lt;div&gt;&lt;span&gt;&lt;span style=&quot;background-color: #ffffff; color: #0d0d0d;&quot;&gt;&lt;b&gt;w+&lt;/b&gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;
&lt;/td&gt;
&lt;td style=&quot;background-color: #ffffff;&quot; colspan=&quot;1&quot; rowspan=&quot;1&quot;&gt;
&lt;div&gt;&lt;span&gt;&lt;span style=&quot;background-color: #ffffff; color: #0d0d0d;&quot;&gt;읽기/쓰기 모드로 파일 열기. 파일이 이미 존재하면 내용을 지우고, 없으면 새 파일 생성.&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;background-color: #ffffff;&quot; colspan=&quot;1&quot; rowspan=&quot;1&quot;&gt;
&lt;div&gt;&lt;span&gt;&lt;span style=&quot;background-color: #ffffff; color: #0d0d0d;&quot;&gt;&lt;b&gt;a+&lt;/b&gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;
&lt;/td&gt;
&lt;td style=&quot;background-color: #ffffff;&quot; colspan=&quot;1&quot; rowspan=&quot;1&quot;&gt;
&lt;div&gt;&lt;span&gt;&lt;span style=&quot;background-color: #ffffff; color: #0d0d0d;&quot;&gt;추가/읽기 모드로 파일 열기. 파일 끝에 데이터를 추가하고, 파일이 없으면 새 파일 생성.&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;background-color: #ffffff;&quot; colspan=&quot;1&quot; rowspan=&quot;1&quot;&gt;
&lt;div&gt;&lt;span&gt;&lt;span style=&quot;background-color: #ffffff; color: #0d0d0d;&quot;&gt;&lt;b&gt;rb&lt;/b&gt;&lt;/span&gt;&lt;span style=&quot;background-color: #ffffff; color: #0d0d0d;&quot;&gt;, &lt;/span&gt;&lt;span style=&quot;background-color: #ffffff; color: #0d0d0d;&quot;&gt;&lt;b&gt;wb&lt;/b&gt;&lt;/span&gt;&lt;span style=&quot;background-color: #ffffff; color: #0d0d0d;&quot;&gt;, &lt;/span&gt;&lt;span style=&quot;background-color: #ffffff; color: #0d0d0d;&quot;&gt;&lt;b&gt;ab&lt;/b&gt;&lt;/span&gt;&lt;span style=&quot;background-color: #ffffff; color: #0d0d0d;&quot;&gt;, &lt;/span&gt;&lt;span style=&quot;background-color: #ffffff; color: #0d0d0d;&quot;&gt;&lt;b&gt;rb+&lt;/b&gt;&lt;/span&gt;&lt;span style=&quot;background-color: #ffffff; color: #0d0d0d;&quot;&gt;, &lt;/span&gt;&lt;span style=&quot;background-color: #ffffff; color: #0d0d0d;&quot;&gt;&lt;b&gt;wb+&lt;/b&gt;&lt;/span&gt;&lt;span style=&quot;background-color: #ffffff; color: #0d0d0d;&quot;&gt;, &lt;/span&gt;&lt;span style=&quot;background-color: #ffffff; color: #0d0d0d;&quot;&gt;&lt;b&gt;ab+&lt;/b&gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;
&lt;/td&gt;
&lt;td style=&quot;background-color: #ffffff;&quot; colspan=&quot;1&quot; rowspan=&quot;1&quot;&gt;
&lt;div&gt;&lt;span&gt;&lt;span style=&quot;background-color: #ffffff; color: #0d0d0d;&quot;&gt;위 모드들에 &lt;/span&gt;&lt;span style=&quot;background-color: #ffffff; color: #0d0d0d;&quot;&gt;&lt;b&gt;b&lt;/b&gt;&lt;/span&gt;&lt;span style=&quot;background-color: #ffffff; color: #0d0d0d;&quot;&gt;를 추가하여 이진 파일로 작업할 때 사용. 예: &lt;/span&gt;&lt;span style=&quot;background-color: #ffffff; color: #0d0d0d;&quot;&gt;&lt;b&gt;rb&lt;/b&gt;&lt;/span&gt;&lt;span style=&quot;background-color: #ffffff; color: #0d0d0d;&quot;&gt;는 이진 파일을 읽기 전용으로 열기.&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이&amp;nbsp;코드는&amp;nbsp;test.txt라는&amp;nbsp;파일을&amp;nbsp;생성하고,&amp;nbsp;파일에&amp;nbsp;이름,&amp;nbsp;나이,&amp;nbsp;이메일&amp;nbsp;정보를&amp;nbsp;쉼표로&amp;nbsp;구분하여&amp;nbsp;차례로&amp;nbsp;파일에&amp;nbsp;쓴다.&amp;nbsp;위&amp;nbsp;코드에서&amp;nbsp;중요한&amp;nbsp;포인트는&amp;nbsp;순서이다.&amp;nbsp;우선,&amp;nbsp;파일을&amp;nbsp;열어야&amp;nbsp;한다.&amp;nbsp;파일이&amp;nbsp;열렸다면&amp;nbsp;이제는&amp;nbsp;파일에&amp;nbsp;읽기&amp;nbsp;쓰기를&amp;nbsp;할&amp;nbsp;준비가&amp;nbsp;된&amp;nbsp;셈이다.&amp;nbsp;그리고&amp;nbsp;데이터를&amp;nbsp;순서대로&amp;nbsp;파일에&amp;nbsp;쓴다.&amp;nbsp;쓰기&amp;nbsp;작업이&amp;nbsp;마무리가&amp;nbsp;되었다면,&amp;nbsp;꼭&amp;nbsp;파일을&amp;nbsp;닫아야&amp;nbsp;한다.&amp;nbsp;제대로&amp;nbsp;닫지&amp;nbsp;않은&amp;nbsp;상태에서&amp;nbsp;프로그램을&amp;nbsp;종료한다면&amp;nbsp;파일이&amp;nbsp;깨지거나&amp;nbsp;올바르게&amp;nbsp;저장되지&amp;nbsp;않을&amp;nbsp;수&amp;nbsp;있다.&amp;nbsp;이&amp;nbsp;원리는&amp;nbsp;c언어는&amp;nbsp;고사하고&amp;nbsp;파이썬,&amp;nbsp;자바와&amp;nbsp;동일하니&amp;nbsp;꼭&amp;nbsp;기억해야&amp;nbsp;한다.&lt;/p&gt;
&lt;h3 style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size23&quot;&gt;⭐ 2. 파일 읽기 예제&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;다음으로&amp;nbsp;저장된&amp;nbsp;txt&amp;nbsp;파일을&amp;nbsp;읽어와&amp;nbsp;콘솔에&amp;nbsp;출력한다.&amp;nbsp;파일로부터&amp;nbsp;데이터를&amp;nbsp;읽기&amp;nbsp;위해&amp;nbsp;fscanf&amp;nbsp;함수를&amp;nbsp;사용한다.&amp;nbsp;파일의&amp;nbsp;끝에&amp;nbsp;도달할&amp;nbsp;때까지&amp;nbsp;반복하여&amp;nbsp;데이터를&amp;nbsp;읽는다.&lt;/p&gt;
&lt;pre id=&quot;code_1731125353302&quot; class=&quot;cpp&quot; data-ke-language=&quot;cpp&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;#include &amp;lt;stdio.h&amp;gt;

int main() {
    // 파일 포인터 선언
    FILE *fp = fopen(&quot;users.csv&quot;, &quot;r&quot;);
    if (fp == NULL) {
        perror(&quot;파일 열기 실패&quot;);
        return -1;
    }

    char name[100], email[100];
    int age;

    // 헤더 읽기
    fscanf(fp, &quot;%*s %*s %*s\n&quot;); // 첫 번째 줄(헤더)는 건너뜁니다.

    // 데이터 읽기 (이름, 나이, 이메일)
    while (fscanf(fp, &quot;%[^,],%d,%[^,\n]\n&quot;, name, &amp;amp;age, email) != EOF) {
        printf(&quot;이름: %s, 나이: %d, 이메일: %s\n&quot;, name, age, email);
    }

    // 파일 닫기
    fclose(fp);

    return 0;
}&lt;/code&gt;&lt;/pre&gt;
&lt;h3 style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size23&quot;&gt;⭐ 3. 주의사항&lt;/h3&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;◆&amp;nbsp; 잘못된 예시 코드&lt;/h4&gt;
&lt;pre id=&quot;code_1731125503778&quot; class=&quot;cpp&quot; data-ke-language=&quot;cpp&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;#include &amp;lt;stdio.h&amp;gt;

int main() {
    FILE *file;
    char buffer[100];

    // 파일 열기 (파일 포인터 NULL 체크 없음)
    file = fopen(&quot;example.txt&quot;, &quot;r&quot;);

    // 파일로부터 데이터 읽기 (파일 포인터가 NULL인지 확인하지 않음)
    fscanf(file, &quot;%s&quot;, buffer);
    printf(&quot;파일 내용: %s\n&quot;, buffer);

    // 파일 닫기 (fclose 없음)
    return 0;
}&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;위 코드는 다음과 같은 문제가 있다:&amp;nbsp;&lt;br /&gt;&lt;br /&gt;&lt;b&gt;파일 포인터 NULL 검사 없음:&lt;/b&gt; fopen() 함수가 실패할 경우 file 포인터는 NULL이 되는데, 이를 확인하지 않으면 프로그램이 비정상적으로 동작할 수 있다. &lt;br /&gt;&lt;b&gt;파일 닫기(fclose) 없음:&lt;/b&gt; 파일 작업이 끝난 후 fclose()를 호출하지 않으면 파일 리소스가 반환되지 않아 메모리 누수가 발생할 수 있다.&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;◇ 올바른 예시 코드&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;아래는 파일을 성공적으로 열었는지 확인하고, 작업 후 파일을 제대로 닫는 수정된 코드이다.&lt;/p&gt;
&lt;pre id=&quot;code_1731125670217&quot; class=&quot;cpp&quot; data-ke-language=&quot;cpp&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;#include &amp;lt;stdio.h&amp;gt;

int main() {
    FILE *file;
    char buffer[100];

    // 파일 열기
    file = fopen(&quot;example.txt&quot;, &quot;r&quot;);
    
    // 파일 포인터 NULL 검사
    if (file == NULL) {
        perror(&quot;파일 열기 오류&quot;);
        return 1; // 파일 열기에 실패한 경우 프로그램 종료
    }

    // 파일로부터 데이터 읽기
    if (fscanf(file, &quot;%99s&quot;, buffer) == 1) {
        printf(&quot;파일 내용: %s\n&quot;, buffer);
    } else {
        printf(&quot;파일 읽기 실패 또는 빈 파일입니다.\n&quot;);
    }

    // 파일 닫기
    fclose(file);

    return 0;
}&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이 수정된 코드는 다음과 같은 점에서 수정되었다.&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;파일 포인터 NULL 검사: fopen()이 실패할 경우 file이 NULL이 되므로, if (file == NULL)을 통해 파일이 제대로 열렸는지 확인한다. 실패 시 오류 메시지를 출력하고 프로그램을 종료한다.&lt;/li&gt;
&lt;li&gt;fclose 사용: 파일 작업이 끝난 후 반드시 fclose(file)을 호출하여 파일을 닫고, 리소스를 반환한다.&lt;/li&gt;
&lt;li&gt;입력 데이터 제한: fscanf(file, &quot;%99s&quot;, buffer)로 최대 입력 크기를 지정하여 버퍼 오버플로우를 방지했다.&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이 코드는 파일 작업을 안전하게 처리하여 파일 입출력 중 발생할 수 있는 오류를 방지한다.&lt;/p&gt;</description>
      <category>  C언어 30강</category>
      <category>C언어</category>
      <category>File</category>
      <category>예시</category>
      <category>입출력</category>
      <category>주의사항</category>
      <author>18진수</author>
      <guid isPermaLink="true">https://coding-yoon.tistory.com/274</guid>
      <comments>https://coding-yoon.tistory.com/274#entry274comment</comments>
      <pubDate>Sat, 9 Nov 2024 13:17:14 +0900</pubDate>
    </item>
    <item>
      <title>[C/C++ Tip] 23. 지역 변수, 전역 변수, 정적 변수</title>
      <link>https://coding-yoon.tistory.com/273</link>
      <description>&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;652&quot; data-origin-height=&quot;488&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bv80PZ/btsKEcNTjDU/Uckv5LIKJAtIkekw0FZvAk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bv80PZ/btsKEcNTjDU/Uckv5LIKJAtIkekw0FZvAk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bv80PZ/btsKEcNTjDU/Uckv5LIKJAtIkekw0FZvAk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fbv80PZ%2FbtsKEcNTjDU%2FUckv5LIKJAtIkekw0FZvAk%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;652&quot; height=&quot;488&quot; data-origin-width=&quot;652&quot; data-origin-height=&quot;488&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;지역 변수, 전역 변수, 정적 변수&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;C언어에서&amp;nbsp;변수의&amp;nbsp;유효&amp;nbsp;범위와&amp;nbsp;수명은&amp;nbsp;프로그램의&amp;nbsp;동작을&amp;nbsp;이해하고&amp;nbsp;제어하는&amp;nbsp;데&amp;nbsp;중요한&amp;nbsp;역할을&amp;nbsp;한다.&amp;nbsp;이&amp;nbsp;글에서는&amp;nbsp;C언어에서&amp;nbsp;사용되는&amp;nbsp;세&amp;nbsp;가지&amp;nbsp;주요&amp;nbsp;변수&amp;nbsp;유형인&amp;nbsp;지역&amp;nbsp;변수(Local&amp;nbsp;Variables),&amp;nbsp;전역&amp;nbsp;변수(Global&amp;nbsp;Variables),&amp;nbsp;정적&amp;nbsp;변수(Static&amp;nbsp;Variables)에&amp;nbsp;대해&amp;nbsp;설명한다.&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;⭐ 1. 지역 변수 (Local Variables)&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;지역&amp;nbsp;변수는&amp;nbsp;함수&amp;nbsp;내부에서&amp;nbsp;선언되며,&amp;nbsp;해당&amp;nbsp;함수&amp;nbsp;내에서만&amp;nbsp;접근할&amp;nbsp;수&amp;nbsp;있다.&amp;nbsp;함수의&amp;nbsp;호출이&amp;nbsp;시작될&amp;nbsp;때&amp;nbsp;메모리에&amp;nbsp;할당되고,&amp;nbsp;함수의&amp;nbsp;실행이&amp;nbsp;끝나면&amp;nbsp;메모리에서&amp;nbsp;해제된다.&amp;nbsp;이러한&amp;nbsp;특성&amp;nbsp;때문에&amp;nbsp;지역&amp;nbsp;변수는&amp;nbsp;함수의&amp;nbsp;독립성과&amp;nbsp;재사용성을&amp;nbsp;높이는&amp;nbsp;데&amp;nbsp;기여한다.&lt;/p&gt;
&lt;pre id=&quot;code_1731124471402&quot; class=&quot;cpp&quot; data-ke-language=&quot;cpp&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;void function() {
    int localVariable = 5; // 지역 변수 선언
    printf(&quot;%d\n&quot;, localVariable); // 지역 변수 사용
}&lt;/code&gt;&lt;/pre&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;⭐ 2. 전역 변수 (Global Variables)&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;전역&amp;nbsp;변수는&amp;nbsp;함수&amp;nbsp;외부에서&amp;nbsp;선언되며,&amp;nbsp;프로그램의&amp;nbsp;어느&amp;nbsp;곳에서나&amp;nbsp;접근할&amp;nbsp;수&amp;nbsp;있다.&amp;nbsp;프로그램의&amp;nbsp;시작&amp;nbsp;시&amp;nbsp;메모리에&amp;nbsp;할당되고&amp;nbsp;프로그램이&amp;nbsp;종료될&amp;nbsp;때까지&amp;nbsp;유지된다.&amp;nbsp;전역&amp;nbsp;변수는&amp;nbsp;여러&amp;nbsp;함수들&amp;nbsp;사이에서&amp;nbsp;데이터를&amp;nbsp;공유할&amp;nbsp;필요가&amp;nbsp;있을&amp;nbsp;때&amp;nbsp;유용하지만,&amp;nbsp;과도한&amp;nbsp;사용은&amp;nbsp;프로그램의&amp;nbsp;복잡성을&amp;nbsp;증가시키고&amp;nbsp;디버깅을&amp;nbsp;어렵게&amp;nbsp;할&amp;nbsp;수&amp;nbsp;있다.&lt;/p&gt;
&lt;pre id=&quot;code_1731124653558&quot; class=&quot;cpp&quot; data-ke-language=&quot;cpp&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;int globalVariable = 10; // 전역 변수 선언

void function() {
    printf(&quot;%d\n&quot;, globalVariable); // 전역 변수 사용
}&lt;/code&gt;&lt;/pre&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;⭐ 3. 정적 변수 (Static Variables)&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;정적&amp;nbsp;변수는&amp;nbsp;static&amp;nbsp;키워드를&amp;nbsp;사용하여&amp;nbsp;선언된다.&amp;nbsp;정적&amp;nbsp;변수는&amp;nbsp;지역&amp;nbsp;정적&amp;nbsp;변수와&amp;nbsp;전역&amp;nbsp;정적&amp;nbsp;변수의&amp;nbsp;두&amp;nbsp;가지&amp;nbsp;형태로&amp;nbsp;나뉜다. &lt;br /&gt;&lt;br /&gt;&lt;b&gt;1.&amp;nbsp;지역&amp;nbsp;정적&amp;nbsp;변수:&amp;nbsp;&lt;/b&gt;함수&amp;nbsp;내부에&amp;nbsp;선언되며,&amp;nbsp;프로그램&amp;nbsp;실행이&amp;nbsp;시작될&amp;nbsp;때&amp;nbsp;메모리에&amp;nbsp;할당되고&amp;nbsp;프로그램이&amp;nbsp;종료될&amp;nbsp;때까지&amp;nbsp;유지된다.&amp;nbsp;그러나&amp;nbsp;해당&amp;nbsp;변수는&amp;nbsp;선언된&amp;nbsp;함수&amp;nbsp;내에서만&amp;nbsp;접근할&amp;nbsp;수&amp;nbsp;있다.&amp;nbsp;함수&amp;nbsp;호출&amp;nbsp;간에&amp;nbsp;변수의&amp;nbsp;값이&amp;nbsp;유지된다.&amp;nbsp;실제&amp;nbsp;프로젝트에서는&amp;nbsp;사용해본&amp;nbsp;적&amp;nbsp;없는&amp;nbsp;케이스이다.&lt;/p&gt;
&lt;pre id=&quot;code_1731124716612&quot; class=&quot;cpp&quot; data-ke-language=&quot;cpp&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;void function() {
    static int staticLocalVariable = 0; // 지역 정적 변수 선언
    staticLocalVariable++;
    printf(&quot;%d\n&quot;, staticLocalVariable); // 값은 함수 호출 간 유지됨
}&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;2.&amp;nbsp;전역&amp;nbsp;정적&amp;nbsp;변수:&lt;/b&gt;&amp;nbsp;함수&amp;nbsp;외부에&amp;nbsp;선언되지만&amp;nbsp;파일&amp;nbsp;내부에서만&amp;nbsp;접근할&amp;nbsp;수&amp;nbsp;있다.&amp;nbsp;프로그램의&amp;nbsp;다른&amp;nbsp;파일들에서는&amp;nbsp;접근할&amp;nbsp;수&amp;nbsp;없어,&amp;nbsp;해당&amp;nbsp;변수를&amp;nbsp;사용하는&amp;nbsp;코드의&amp;nbsp;범위를&amp;nbsp;제한하는&amp;nbsp;데&amp;nbsp;도움이&amp;nbsp;된다.&lt;/p&gt;
&lt;pre id=&quot;code_1731124742225&quot; class=&quot;cpp&quot; data-ke-language=&quot;cpp&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;static int staticGlobalVariable = 20; // 전역 정적 변수 선언

void function() {
    printf(&quot;%d\n&quot;, staticGlobalVariable); // 전역 정적 변수 사용
}&lt;/code&gt;&lt;/pre&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;⭐ 4. Code&lt;/h3&gt;
&lt;pre id=&quot;code_1731124772470&quot; class=&quot;cpp&quot; data-ke-language=&quot;cpp&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;#include &amp;lt;stdio.h&amp;gt;

// 전역 변수 선언
int globalVariable = 10;

// 전역 정적 변수 선언: 이 파일 내에서만 접근 가능
static int staticGlobalVariable = 20;

// 함수 선언
void function(void);
void staticFunction(void);

int main() {
    printf(&quot;전역 변수 초기값: %d\n&quot;, globalVariable);
    printf(&quot;전역 정적 변수 초기값: %d\n\n&quot;, staticGlobalVariable);

    function();
    function();
    function();

    staticFunction();
    staticFunction();

    return 0;
}

void function() {
    // 지역 변수 선언
    int localVariable = 5;
    printf(&quot;지역 변수: %d\n&quot;, localVariable);

    // 지역 정적 변수 선언: 함수 호출 간 값 유지
    static int staticLocalVariable = 0;
    staticLocalVariable++;
    printf(&quot;지역 정적 변수: %d\n&quot;, staticLocalVariable);

    // 전역 변수와 전역 정적 변수 사용
    globalVariable += 10;
    staticGlobalVariable += 10;
    printf(&quot;전역 변수: %d\n&quot;, globalVariable);
    printf(&quot;전역 정적 변수: %d\n\n&quot;, staticGlobalVariable);
}

void staticFunction() {
    // 이 함수는 전역 변수와 전역 정적 변수의 현재 값을 보여준다.
    printf(&quot;staticFunction에서 본 전역 변수: %d\n&quot;, globalVariable);
    printf(&quot;staticFunction에서 본 전역 정적 변수: %d\n\n&quot;, staticGlobalVariable);
}&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;지역&amp;nbsp;변수,&amp;nbsp;전역&amp;nbsp;변수,&amp;nbsp;정적&amp;nbsp;변수는&amp;nbsp;각각&amp;nbsp;다른&amp;nbsp;유효&amp;nbsp;범위와&amp;nbsp;수명을&amp;nbsp;가지며,&amp;nbsp;C언어&amp;nbsp;프로그래밍에서&amp;nbsp;중요한&amp;nbsp;역할을&amp;nbsp;한다.&amp;nbsp;지역&amp;nbsp;변수는&amp;nbsp;함수의&amp;nbsp;독립성을&amp;nbsp;지원하고,&amp;nbsp;전역&amp;nbsp;변수는&amp;nbsp;데이터&amp;nbsp;공유를&amp;nbsp;용이하게&amp;nbsp;하며,&amp;nbsp;정적&amp;nbsp;변수는&amp;nbsp;메모리의&amp;nbsp;효율적&amp;nbsp;사용과&amp;nbsp;변수의&amp;nbsp;접근&amp;nbsp;범위를&amp;nbsp;제한하는&amp;nbsp;데&amp;nbsp;사용된다.&amp;nbsp;이러한&amp;nbsp;변수들을&amp;nbsp;적절히&amp;nbsp;사용하는&amp;nbsp;것은&amp;nbsp;프로그램의&amp;nbsp;효율성과&amp;nbsp;유지보수성을&amp;nbsp;높이는&amp;nbsp;데&amp;nbsp;기여한다.&lt;/p&gt;</description>
      <category>  C언어 30강</category>
      <category>C언어</category>
      <category>전역변수</category>
      <category>정적변수</category>
      <category>지역변수</category>
      <author>18진수</author>
      <guid isPermaLink="true">https://coding-yoon.tistory.com/273</guid>
      <comments>https://coding-yoon.tistory.com/273#entry273comment</comments>
      <pubDate>Sat, 9 Nov 2024 13:00:18 +0900</pubDate>
    </item>
    <item>
      <title>[C/C++ Tip] 22. C언어 반복문 : While문</title>
      <link>https://coding-yoon.tistory.com/272</link>
      <description>&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;652&quot; data-origin-height=&quot;488&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cMxh7i/btsKC1NogwY/uOImrThgdOtllKxVCyBXYK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cMxh7i/btsKC1NogwY/uOImrThgdOtllKxVCyBXYK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cMxh7i/btsKC1NogwY/uOImrThgdOtllKxVCyBXYK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FcMxh7i%2FbtsKC1NogwY%2FuOImrThgdOtllKxVCyBXYK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;652&quot; height=&quot;488&quot; data-origin-width=&quot;652&quot; data-origin-height=&quot;488&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;반복문 : While문&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;C언어에서&amp;nbsp;while문은&amp;nbsp;주어진&amp;nbsp;조건이&amp;nbsp;참(true)인&amp;nbsp;동안&amp;nbsp;코드&amp;nbsp;블록을&amp;nbsp;반복&amp;nbsp;실행하는&amp;nbsp;데&amp;nbsp;사용된다.&amp;nbsp;while문은&amp;nbsp;조건이&amp;nbsp;반복의&amp;nbsp;시작에&amp;nbsp;평가되므로,&amp;nbsp;조건이&amp;nbsp;처음부터&amp;nbsp;거짓인&amp;nbsp;경우&amp;nbsp;코드&amp;nbsp;블록은&amp;nbsp;한&amp;nbsp;번도&amp;nbsp;실행되지&amp;nbsp;않을&amp;nbsp;수&amp;nbsp;있다.&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;⭐ 1. While문의 기본 구조&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;While문의 기본 구조는 다음과 같다.&lt;/span&gt;&lt;/p&gt;
&lt;pre id=&quot;code_1731123717664&quot; class=&quot;cpp&quot; data-ke-language=&quot;cpp&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;while (조건) {
    // 조건이 참인 동안 실행할 코드
}&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;조건: 반복문의 계속 여부를 결정하는 조건이다. 이 조건이 거짓이 되면 반복문이 종료된다.&lt;/p&gt;
&lt;pre id=&quot;code_1731123803214&quot; class=&quot;cpp&quot; data-ke-language=&quot;cpp&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;#include &amp;lt;stdio.h&amp;gt;

int main() {
    int i = 0; // 반복문 제어를 위한 변수 초기화

    while (i &amp;lt; 5) {
        printf(&quot;%d\n&quot;, i);
        i++; // 변수를 증가시켜 eventually 반복문 종료 조건에 도달하게 함
    }

    return 0;
}&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;위의&amp;nbsp;코드는&amp;nbsp;i가&amp;nbsp;5보다&amp;nbsp;작은&amp;nbsp;동안&amp;nbsp;i의&amp;nbsp;값을&amp;nbsp;출력하고,&amp;nbsp;i를&amp;nbsp;하나씩&amp;nbsp;증가시킨다.&amp;nbsp;i가&amp;nbsp;5에&amp;nbsp;도달하면&amp;nbsp;조건이&amp;nbsp;거짓이&amp;nbsp;되어&amp;nbsp;while&amp;nbsp;반복문이&amp;nbsp;종료된다.&lt;/p&gt;
&lt;h3 style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size23&quot;&gt;⭐ 2. Break&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;break 문은 while 반복문 (또는 다른 반복문) 내부에서 반복을 즉시 종료시키는 데 사용된다. 이는 특정 조건이 충족될 때 반복문을 빠져나오고 싶을 때 유용하게 활용된다. 예를 들어, 사용자로부터 입력을 받아 특정 값이 입력되면 반복을 중단하는 상황에서 break를 사용할 수 있다.&lt;br /&gt;다음은&amp;nbsp;break&amp;nbsp;문을&amp;nbsp;사용하는&amp;nbsp;간단한&amp;nbsp;C&amp;nbsp;코드&amp;nbsp;예시이다.&amp;nbsp;이&amp;nbsp;예제에서는&amp;nbsp;사용자가&amp;nbsp;0을&amp;nbsp;입력할&amp;nbsp;때까지&amp;nbsp;숫자를&amp;nbsp;계속&amp;nbsp;입력받아&amp;nbsp;그&amp;nbsp;합을&amp;nbsp;출력한다.&amp;nbsp;사용자가&amp;nbsp;0을&amp;nbsp;입력하면,&amp;nbsp;break&amp;nbsp;문이&amp;nbsp;실행되어&amp;nbsp;while&amp;nbsp;반복문을&amp;nbsp;즉시&amp;nbsp;종료한다.&lt;/p&gt;
&lt;pre id=&quot;code_1731123858030&quot; class=&quot;cpp&quot; data-ke-language=&quot;cpp&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;#include &amp;lt;stdio.h&amp;gt;

int main() {
    int sum = 0, number;

    while (1) { // 무한 루프
        printf(&quot;숫자를 입력하세요 (종료하려면 0을 입력): &quot;);
        scanf(&quot;%d&quot;, &amp;amp;number);

        if (number == 0) {
            break; // 사용자가 0을 입력하면 반복문을 빠져나옴
        }

        sum += number; // 사용자가 0이 아닌 수를 입력하면 sum에 더함
    }

    printf(&quot;입력한 숫자의 합은: %d\n&quot;, sum);
    return 0;
}&lt;/code&gt;&lt;/pre&gt;
&lt;h3 style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size23&quot;&gt;⭐ 3. Continue&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;continue 문은 C언어에서 반복문 (for, while, do-while) 내에서 현재 반복을 즉시 종료하고, 다음 반복으로 넘어가게 하는 데 사용된다. 이는 특정 조건 하에서 반복문의 나머지 부분을 건너뛰고 싶을 때 유용하다. 반복문의 조건 평가로 직접 이동하여 다음 반복이 시작된다.&lt;br /&gt;다음&amp;nbsp;예제는&amp;nbsp;0부터&amp;nbsp;9까지&amp;nbsp;숫자&amp;nbsp;중에서&amp;nbsp;홀수만&amp;nbsp;출력하는&amp;nbsp;간단한&amp;nbsp;while&amp;nbsp;반복문을&amp;nbsp;보여준다.&amp;nbsp;여기서&amp;nbsp;continue&amp;nbsp;문은&amp;nbsp;짝수일&amp;nbsp;경우&amp;nbsp;반복문의&amp;nbsp;나머지&amp;nbsp;부분을&amp;nbsp;실행하지&amp;nbsp;않고&amp;nbsp;다음&amp;nbsp;반복으로&amp;nbsp;넘어가도록&amp;nbsp;한다.&lt;/p&gt;
&lt;pre id=&quot;code_1731124017183&quot; class=&quot;cpp&quot; data-ke-language=&quot;cpp&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;#include &amp;lt;stdio.h&amp;gt;

int main() {
    int i = 0;

    while (i &amp;lt; 10) {
        i++; // 먼저 증가시키면 홀수 판별 가능
        if (i % 2 == 0) {
            continue; // i가 짝수이면 출력을 건너뛰고 다음 반복으로 넘어감
        }
        printf(&quot;%d\n&quot;, i); // 홀수인 경우에만 실행됨
    }

    return 0;
}&lt;/code&gt;&lt;/pre&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;⭐ 4. 주의사항&lt;/h3&gt;
&lt;pre id=&quot;code_1731124131846&quot; class=&quot;cpp&quot; data-ke-language=&quot;cpp&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;#include &amp;lt;stdio.h&amp;gt;

int main() {
    int count = 0;

    // 예시 1: 무한 루프 발생
    while (count &amp;gt;= 0) { // count가 0보다 크거나 같기 때문에 종료되지 않음
        printf(&quot;무한 루프 예시: count = %d\n&quot;, count);
        // count를 업데이트하지 않아서 무한 루프 발생
    }

    // 예시 2: 조건 업데이트 누락
    int limit = 5;
    while (limit &amp;gt; 0) {
        printf(&quot;조건 업데이트 누락 예시: limit = %d\n&quot;, limit);
        // limit 값을 업데이트하지 않아서 무한 루프에 빠질 수 있음
    }

    // 예시 3: 복잡한 조건 사용
    int x = 10, y = 20;
    while ((x &amp;gt; 0 &amp;amp;&amp;amp; y &amp;gt; 0) || (x % 2 == 0 &amp;amp;&amp;amp; y % 3 != 1) || (x - y != 10)) {
        printf(&quot;복잡한 조건 예시: x = %d, y = %d\n&quot;, x, y);
        x--;  // x는 감소하지만 조건이 너무 복잡하여 가독성이 떨어짐
    }

    // 예시 4: break와 continue의 부적절한 사용
    int i = 0;
    while (i &amp;lt; 10) {
        printf(&quot;break와 continue 예시: i = %d\n&quot;, i);
        if (i % 2 == 0) {
            continue; // i를 업데이트하기 전에 continue 실행 -&amp;gt; 무한 루프 발생 가능
        }
        if (i &amp;gt; 5) {
            break; // 불필요한 지점에서 break를 사용하여 반복문의 흐름을 혼란스럽게 함
        }
        i++; // i를 적절히 업데이트하지 않아 반복문이 제대로 동작하지 않음
    }

    return 0;
}&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이 코드의 문제점은 다음과 같다.&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;무한 루프 발생: count를 업데이트하지 않거나 조건이 항상 참이 되어 무한 루프가 발생한다.&lt;/li&gt;
&lt;li&gt;조건 업데이트 누락: limit 값을 반복문 내부에서 업데이트하지 않아 무한 루프에 빠질 수 있다.&lt;/li&gt;
&lt;li&gt;복잡한 조건 사용: 조건식이 너무 복잡해서 코드의 흐름이 이해하기 어려워지고, 유지보수성이 떨어진다.&lt;/li&gt;
&lt;li&gt;break와 continue의 부적절한 사용: continue와 break를 잘못 사용하여 변수 업데이트가 누락되거나, 불필요한 지점에서 반복문이 종료될 수 있다.&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;letter-spacing: 0px;&quot;&gt;이와 같은 실수를 피하려면, while문을 사용할 때 조건과 변수 업데이트를 명확하게 작성하는 것이 중요하다.&lt;/span&gt;&lt;/p&gt;</description>
      <category>  C언어 30강</category>
      <category>C언어</category>
      <category>while</category>
      <category>While문</category>
      <category>강좌</category>
      <category>교육</category>
      <category>주의사항</category>
      <author>18진수</author>
      <guid isPermaLink="true">https://coding-yoon.tistory.com/272</guid>
      <comments>https://coding-yoon.tistory.com/272#entry272comment</comments>
      <pubDate>Sat, 9 Nov 2024 12:51:09 +0900</pubDate>
    </item>
    <item>
      <title>[C/C++ Tip] 21. C언어 반복문: For문</title>
      <link>https://coding-yoon.tistory.com/271</link>
      <description>&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;652&quot; data-origin-height=&quot;488&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cD61iI/btsKDdmvtmy/kEe8q0nMz6Jl0LDnWkDS1K/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cD61iI/btsKDdmvtmy/kEe8q0nMz6Jl0LDnWkDS1K/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cD61iI/btsKDdmvtmy/kEe8q0nMz6Jl0LDnWkDS1K/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FcD61iI%2FbtsKDdmvtmy%2FkEe8q0nMz6Jl0LDnWkDS1K%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;652&quot; height=&quot;488&quot; data-origin-width=&quot;652&quot; data-origin-height=&quot;488&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;반복문:&amp;nbsp;For문&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;C언어에서&amp;nbsp;for문은&amp;nbsp;반복적인&amp;nbsp;작업을&amp;nbsp;처리하는&amp;nbsp;데&amp;nbsp;필수적인&amp;nbsp;도구이다.&amp;nbsp;강력하고&amp;nbsp;유연한&amp;nbsp;이&amp;nbsp;반복문을&amp;nbsp;통해&amp;nbsp;코드의&amp;nbsp;효율성을&amp;nbsp;극대화하고,&amp;nbsp;가독성을&amp;nbsp;향상시킬&amp;nbsp;수&amp;nbsp;있다.&amp;nbsp;이&amp;nbsp;포스팅에서는&amp;nbsp;for문의&amp;nbsp;기본&amp;nbsp;사용법,&amp;nbsp;고급&amp;nbsp;활용법,&amp;nbsp;그리고&amp;nbsp;주의사항을&amp;nbsp;포함한&amp;nbsp;종합&amp;nbsp;가이드를&amp;nbsp;제공한다.&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;⭐ 1. For문의 기본 구조&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;for문의 기본 구조는 다음과 같다.&lt;/p&gt;
&lt;pre id=&quot;code_1731123084532&quot; class=&quot;cpp&quot; data-ke-language=&quot;cpp&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;for (초기화; 조건; 증감) {
    // 반복할 코드 블록
}&lt;/code&gt;&lt;/pre&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;초기화: 반복문이 시작할 때 한 번 실행되며, 반복문의 제어 변수를 초기화한다.&lt;/li&gt;
&lt;li&gt;조건: 반복문의 계속 여부를 결정하는 조건이다. 이 조건이 거짓이 되면 반복문이 종료된다.&lt;/li&gt;
&lt;li&gt;증감: 반복문의 각 반복이 끝날 때마다 실행되어 제어 변수를 증가시키거나 감소시킨다.&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;⭐ 2. Code&lt;/h3&gt;
&lt;pre id=&quot;code_1731123119037&quot; class=&quot;cpp&quot; data-ke-language=&quot;cpp&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;#include &amp;lt;stdio.h&amp;gt;

int main() {
    int numbers[] = {1, 2, 3, 4, 5};
    int sum = 0;
    
    for (int i = 0; i &amp;lt; 5; i++) {
        sum += numbers[i];
    }
    
    printf(&quot;Sum: %d\n&quot;, sum);
    return 0;
}&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이&amp;nbsp;예제는&amp;nbsp;배열의&amp;nbsp;모든&amp;nbsp;요소를&amp;nbsp;합하는&amp;nbsp;간단한&amp;nbsp;프로그램이다.&amp;nbsp;for문을&amp;nbsp;사용하여&amp;nbsp;배열의&amp;nbsp;각&amp;nbsp;요소에&amp;nbsp;접근하고,&amp;nbsp;sum&amp;nbsp;변수에&amp;nbsp;누적하여&amp;nbsp;최종&amp;nbsp;합을&amp;nbsp;구한다.&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;⭐ 3. For문 주의사항&lt;/h3&gt;
&lt;pre id=&quot;code_1731123236635&quot; class=&quot;cpp&quot; data-ke-language=&quot;cpp&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;#include &amp;lt;stdio.h&amp;gt;

int main() {
    // 예시 1: 무한 루프 발생
    for (int i = 0; i &amp;gt;= 0; i++) { // i가 항상 0 이상이므로 종료되지 않음
        printf(&quot;무한 루프: i = %d\n&quot;, i);
    }

    // 예시 2: 복잡한 조건문 사용
    int limit = 10;
    for (int i = 0; i &amp;lt; limit * 2 &amp;amp;&amp;amp; (i % 3 != 0 || i % 2 == 0); i++) { 
        // 복잡한 조건식으로 가독성이 떨어짐
        printf(&quot;복잡한 조건문: i = %d\n&quot;, i);
    }

    // 예시 3: 증감 부분의 잘못된 활용
    for (int i = 0; i &amp;lt; 10; i = i + 2 * 3 - 1) { // 증감 부분이 복잡하여 반복문 흐름이 명확하지 않음
        printf(&quot;복잡한 증감 부분: i = %d\n&quot;, i);
    }

    return 0;
}&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이 코드에서는 다음과 같은 문제점이 있다:&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;무한 루프 발생: for (int i = 0; i &amp;gt;= 0; i++)처럼 종료 조건을 설정하지 않으면, i가 항상 0 이상이기 때문에 무한히 반복될 수 있다.&lt;/li&gt;
&lt;li&gt;복잡한 조건문 사용: 조건문이 지나치게 복잡하여 코드 가독성이 떨어집니다. 이로 인해 반복문이 어떻게 동작하는지 이해하기 어렵다.&lt;/li&gt;
&lt;li&gt;증감 부분의 잘못된 활용: 증감 부분이 지나치게 복잡해서 반복문의 흐름이 명확하지 않으며, 예기치 않은 결과를 초래할 수 있다.&amp;nbsp;&amp;nbsp;&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이와 같은 실수를 피하려면, for문을 간결하고 명확하게 작성하는 것이 좋다.&lt;/p&gt;
&lt;h3 style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size23&quot;&gt;⭐ 4. 반복문과 조건문 결합&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;for문은&amp;nbsp;다중&amp;nbsp;반복문과&amp;nbsp;조건문과&amp;nbsp;결합하여&amp;nbsp;더&amp;nbsp;복잡한&amp;nbsp;반복&amp;nbsp;구조를&amp;nbsp;만들&amp;nbsp;수&amp;nbsp;있다.&amp;nbsp;예를&amp;nbsp;들어,&amp;nbsp;2차원&amp;nbsp;배열을&amp;nbsp;처리하거나,&amp;nbsp;특정&amp;nbsp;조건에&amp;nbsp;따라&amp;nbsp;반복문을&amp;nbsp;조기&amp;nbsp;종료하는&amp;nbsp;등의&amp;nbsp;작업이&amp;nbsp;가능하다.&lt;/p&gt;
&lt;pre id=&quot;code_1731123346003&quot; class=&quot;cpp&quot; data-ke-language=&quot;cpp&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;for (int i = 0; i &amp;lt; N; i++) {
    for (int j = 0; j &amp;lt; M; j++) {
        if (someCondition) {
            break; // 내부 반복문 종료
        }
        // 반복 작업 수행
    }
}&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이 코드는 2중 for문을 사용한 예제로, 특정 조건이 만족되면 내부 반복문을 종료한다. 이와 같은 방식으로 for문을 활용하면, 복잡한 데이터 구조를 효과적으로 다룰 수 있다. for문은 C언어에서 반복 작업을 수행하기 위한 강력한 도구이다. 그러나 그 효율성과 유용성을 극대화하기 위해서는 주의사항을 잘 지키며 사용해야 한다.&lt;/p&gt;</description>
      <category>  C언어 30강</category>
      <category>C언어</category>
      <category>for문</category>
      <category>강좌</category>
      <category>교육</category>
      <category>예시</category>
      <category>초기화</category>
      <author>18진수</author>
      <guid isPermaLink="true">https://coding-yoon.tistory.com/271</guid>
      <comments>https://coding-yoon.tistory.com/271#entry271comment</comments>
      <pubDate>Sat, 9 Nov 2024 12:37:23 +0900</pubDate>
    </item>
    <item>
      <title>[C/C++ Tip] 20. C언어 조건문 마스터하기 : Switch문</title>
      <link>https://coding-yoon.tistory.com/270</link>
      <description>&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;652&quot; data-origin-height=&quot;488&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/b7W50C/btsKwtJXM4S/PXnZAt7oOQ96cKzJHPf5KK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/b7W50C/btsKwtJXM4S/PXnZAt7oOQ96cKzJHPf5KK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/b7W50C/btsKwtJXM4S/PXnZAt7oOQ96cKzJHPf5KK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fb7W50C%2FbtsKwtJXM4S%2FPXnZAt7oOQ96cKzJHPf5KK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;652&quot; height=&quot;488&quot; data-origin-width=&quot;652&quot; data-origin-height=&quot;488&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;Switch문&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;C언어에서&amp;nbsp;switch문은&amp;nbsp;여러&amp;nbsp;조건&amp;nbsp;분기를&amp;nbsp;관리하는&amp;nbsp;데&amp;nbsp;있어&amp;nbsp;매우&amp;nbsp;유용한&amp;nbsp;도구이다.&amp;nbsp;특히,&amp;nbsp;하나의&amp;nbsp;변수를&amp;nbsp;여러&amp;nbsp;값과&amp;nbsp;비교해야&amp;nbsp;할&amp;nbsp;때&amp;nbsp;if-else문보다&amp;nbsp;더&amp;nbsp;간결하고&amp;nbsp;명확한&amp;nbsp;코드를&amp;nbsp;작성할&amp;nbsp;수&amp;nbsp;있게&amp;nbsp;해준다.&amp;nbsp;이번&amp;nbsp;포스팅에서는&amp;nbsp;switch문의&amp;nbsp;기본&amp;nbsp;사용법,&amp;nbsp;장점,&amp;nbsp;그리고&amp;nbsp;주의해야&amp;nbsp;할&amp;nbsp;사항에&amp;nbsp;대해&amp;nbsp;자세히&amp;nbsp;알아보겠다.&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;⭐&lt;span&gt; 1. Switch문 기본 사용법&lt;/span&gt;&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;switch문은 표현식의 결과값에 따라 다양한 분기(case)로 코드의 실행 경로를 결정한다. 기본 구조는 다음과 같다.&lt;/span&gt;&lt;/p&gt;
&lt;pre id=&quot;code_1730735045197&quot; class=&quot;cpp&quot; data-ke-language=&quot;cpp&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;switch (표현식) {
    case 값1:
        // 값1일 때 실행할 코드
        break;
    case 값2:
        // 값2일 때 실행할 코드
        break;
    // 여러 case 추가 가능
    default:
        // 어떤 case도 매칭되지 않을 때 실행할 코드
}&lt;/code&gt;&lt;/pre&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;⭐&lt;span&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;2. Switch문 장점&lt;/span&gt;&lt;/b&gt;&lt;/h3&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;가독성: switch문은 여러 if-else문을 사용하는 것보다 훨씬 가독성이 좋은 코드를 작성할 수 있게 한다.&lt;/li&gt;
&lt;li&gt;효율성:&amp;nbsp;컴파일러는&amp;nbsp;switch문을&amp;nbsp;최적화하여,&amp;nbsp;조건&amp;nbsp;분기를&amp;nbsp;더&amp;nbsp;효율적으로&amp;nbsp;처리할&amp;nbsp;수&amp;nbsp;있다.&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;⭐&lt;span&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;3. 주의사항&lt;/span&gt;&lt;/b&gt;&lt;/h3&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;switch문에서 사용할 수 있는 표현식은 정수형 타입이나 열거형(enum)으로 평가될 수 있는 것에 한정된다.&lt;/li&gt;
&lt;li&gt;각 case 뒤에는 반드시 break문을 사용하여, 다음 case로의 실행이 이어지지 않도록 해야 한다. break문을 생략하면, 아래의 case로 &quot;fall through&quot;되어 의도하지 않은 결과를 초래할 수 있다.&lt;/li&gt;
&lt;li&gt;default는 모든 case와 매칭되지 않을 때 실행되는 선택적인 부분이다. 모든 경우를 다루고 싶다면 default를 사용하는 것이 좋다.&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;⭐&lt;span&gt;&lt;span&gt; 4&lt;/span&gt;. 코드&lt;/span&gt;&lt;/b&gt;&lt;/h3&gt;
&lt;pre id=&quot;code_1730735171247&quot; class=&quot;cpp&quot; data-ke-language=&quot;cpp&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;#include &amp;lt;stdio.h&amp;gt;

int main() {
    int day = 3;
    switch (day) {
        case 1:
            printf(&quot;Monday\n&quot;);
            break;
        case 2:
            printf(&quot;Tuesday\n&quot;);
            break;
        case 3:
            printf(&quot;Wednesday\n&quot;);
            break;
        case 4:
            printf(&quot;Thursday\n&quot;);
            break;
        case 5:
            printf(&quot;Friday\n&quot;);
            break;
        case 6:
            printf(&quot;Saturday\n&quot;);
            break;
        case 7:
            printf(&quot;Sunday\n&quot;);
            break;
        default:
            printf(&quot;Invalid day\n&quot;);
    }
    return 0;
}&lt;/code&gt;&lt;/pre&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;⭐&lt;span&gt;&lt;span&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;5&lt;/span&gt;. Fall Through&lt;/span&gt;&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Fall through는 때때로 다음과 같은 상황에서 유용하게 사용됩니다.&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;여러 case 조건이 같은 동작을 수행해야 할 때 코드 중복을 피하기 위해&lt;/li&gt;
&lt;li&gt;한 case에서 추가 작업을 수행한 후 공통 작업을 수행하는 다음 case로 진행해야 할 때&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;주의사항은 아래와 같다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;lt;ul&quot;text-align: left;&quot; data-ke-list-type=&quot;disc&quot;&amp;gt;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;Fall through는 코드의 의도를 명확히 하기 위해 주석을 달아 사용 의도를 명시하는 것이 좋다.&lt;/li&gt;
&lt;li&gt;복잡한 &lt;span&gt;&lt;b&gt;switch&lt;/b&gt;&lt;/span&gt;&lt;span&gt; 문에서는 가독성을 저하시키고 오류를 유발할 수 있으므로, 사용 시 주의가 필요하다.&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;pre id=&quot;code_1730735295949&quot; class=&quot;cpp&quot; data-ke-language=&quot;cpp&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;#include &amp;lt;stdio.h&amp;gt;

int main() {
    int userChoice;
    
    printf(&quot;메뉴를 선택하세요:\n&quot;);
    printf(&quot;1 - 기본 정보 보기\n&quot;);
    printf(&quot;2 - 상세 정보 보기\n&quot;);
    printf(&quot;3 - 추가 정보 보기\n&quot;);
    printf(&quot;4 - 프로그램 종료\n&quot;);
    scanf(&quot;%d&quot;, &amp;amp;userChoice);
    
    switch (userChoice) {
        case 1:
            printf(&quot;기본 정보를 출력합니다.\n&quot;);
            // 여기에 기본 정보 출력 로직을 추가합니다.
            // break가 없으므로 case 2로 fall through합니다.
        case 2:
            printf(&quot;상세 정보를 출력합니다.\n&quot;);
            // 여기에 상세 정보 출력 로직을 추가합니다.
            // case 1을 선택한 경우 기본 정보와 상세 정보 모두 출력됩니다.
            // break가 없으므로 case 3로 fall through합니다.
        case 3:
            printf(&quot;추가 정보를 출력합니다.\n&quot;);
            // 여기에 추가 정보 출력 로직을 추가합니다.
            // case 1 또는 2를 선택한 경우, 상응하는 정보와 함께 추가 정보도 출력됩니다.
            break;
        case 4:
            printf(&quot;프로그램을 종료합니다.\n&quot;);
            break;
        default:
            printf(&quot;잘못된 선택입니다. 다시 시도해주세요.\n&quot;);
    }
    
    return 0;
}&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;switch문은&amp;nbsp;특정&amp;nbsp;변수가&amp;nbsp;다양한&amp;nbsp;값을&amp;nbsp;가질&amp;nbsp;수&amp;nbsp;있을&amp;nbsp;때,&amp;nbsp;각각의&amp;nbsp;경우에&amp;nbsp;대해&amp;nbsp;별도의&amp;nbsp;로직을&amp;nbsp;실행하고&amp;nbsp;싶을&amp;nbsp;때&amp;nbsp;매우&amp;nbsp;유용하다.&amp;nbsp;특히,&amp;nbsp;가능한&amp;nbsp;값이&amp;nbsp;많고,&amp;nbsp;그&amp;nbsp;중&amp;nbsp;하나를&amp;nbsp;선택해야&amp;nbsp;할&amp;nbsp;때&amp;nbsp;if-else문보다&amp;nbsp;훨씬&amp;nbsp;깔끔한&amp;nbsp;코드를&amp;nbsp;작성할&amp;nbsp;수&amp;nbsp;있다.&amp;nbsp;그러나,&amp;nbsp;사용&amp;nbsp;시에는&amp;nbsp;break문을&amp;nbsp;적절히&amp;nbsp;사용하는&amp;nbsp;것과&amp;nbsp;정수형&amp;nbsp;또는&amp;nbsp;열거형으로&amp;nbsp;평가될&amp;nbsp;수&amp;nbsp;있는&amp;nbsp;표현식만을&amp;nbsp;사용하는&amp;nbsp;것을&amp;nbsp;기억해야&amp;nbsp;한다.&amp;nbsp; &lt;br /&gt;&lt;br /&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>  C언어 30강</category>
      <category>C언어</category>
      <category>Fall</category>
      <category>Through</category>
      <category>스위치문</category>
      <author>18진수</author>
      <guid isPermaLink="true">https://coding-yoon.tistory.com/270</guid>
      <comments>https://coding-yoon.tistory.com/270#entry270comment</comments>
      <pubDate>Tue, 5 Nov 2024 00:51:39 +0900</pubDate>
    </item>
    <item>
      <title>[C/C++ Tip] 19. C언어 조건문 마스터하기 : 삼항연산자</title>
      <link>https://coding-yoon.tistory.com/269</link>
      <description>&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;652&quot; data-origin-height=&quot;488&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bjhH9f/btsKvHa432h/K8FhOhnkKgOfA6yIL9fAOK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bjhH9f/btsKvHa432h/K8FhOhnkKgOfA6yIL9fAOK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bjhH9f/btsKvHa432h/K8FhOhnkKgOfA6yIL9fAOK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbjhH9f%2FbtsKvHa432h%2FK8FhOhnkKgOfA6yIL9fAOK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;652&quot; height=&quot;488&quot; data-origin-width=&quot;652&quot; data-origin-height=&quot;488&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;삼항연산자&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;C언어에서&amp;nbsp;삼항&amp;nbsp;연산자는&amp;nbsp;조건문을&amp;nbsp;더&amp;nbsp;간결하게&amp;nbsp;표현할&amp;nbsp;수&amp;nbsp;있는&amp;nbsp;유용한&amp;nbsp;도구이다.&amp;nbsp;기본&amp;nbsp;구조는&amp;nbsp;조건&amp;nbsp;?&amp;nbsp;참일&amp;nbsp;때의&amp;nbsp;값&amp;nbsp;:&amp;nbsp;거짓일&amp;nbsp;때의&amp;nbsp;값으로,&amp;nbsp;조건이&amp;nbsp;참이면&amp;nbsp;첫&amp;nbsp;번째&amp;nbsp;값을,&amp;nbsp;거짓이면&amp;nbsp;두&amp;nbsp;번째&amp;nbsp;값을&amp;nbsp;반환한다.&amp;nbsp;이&amp;nbsp;포스팅에서는&amp;nbsp;삼항&amp;nbsp;연산자의&amp;nbsp;사용법과&amp;nbsp;if문과&amp;nbsp;비교했을&amp;nbsp;때의&amp;nbsp;장단점을&amp;nbsp;살펴본다.&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;⭐1. 삼항&amp;nbsp;연산자&amp;nbsp;사용법&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;삼항 연산자는 주로 간단한 조건에 따른 값을 선택할 때 사용된다. 예를 들어, 두 수 중 큰 수를 찾거나, 조건에 따라 변수에 다른 값을 할당하는 경우 등에 사용할 수 있다&lt;/p&gt;
&lt;pre id=&quot;code_1730732968343&quot; class=&quot;cpp&quot; data-ke-language=&quot;cpp&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;int max = (a &amp;gt; b) ? a : b; // a와 b 중 더 큰 값을 max에 할당&lt;/code&gt;&lt;/pre&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;⭐2. 삼항 연산자 장점&lt;/h3&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;간결성: 삼항 연산자는 if-else문에 비해 더 간결한 코드를 작성할 수 있다.&lt;/li&gt;
&lt;li&gt;표현력:&amp;nbsp;한&amp;nbsp;줄로&amp;nbsp;조건에&amp;nbsp;따른&amp;nbsp;값을&amp;nbsp;표현할&amp;nbsp;수&amp;nbsp;있어,&amp;nbsp;코드의&amp;nbsp;의도를&amp;nbsp;명확하게&amp;nbsp;전달할&amp;nbsp;수&amp;nbsp;있다.&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;⭐3. 고려사항&lt;/h3&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;삼항 연산자는 간단한 조건 판단에 유용하지만, 복잡한 로직이나 여러 조건을 평가해야 하는 경우에는 if-else문을 사용하는 것이 더 적합하다.&lt;/li&gt;
&lt;li&gt;가독성이&amp;nbsp;중요한&amp;nbsp;상황에서는&amp;nbsp;삼항&amp;nbsp;연산자의&amp;nbsp;과도한&amp;nbsp;사용이&amp;nbsp;코드를&amp;nbsp;이해하기&amp;nbsp;어렵게&amp;nbsp;만들&amp;nbsp;수&amp;nbsp;있다.&amp;nbsp;따라서,&amp;nbsp;사용&amp;nbsp;시에는&amp;nbsp;가독성을&amp;nbsp;유지하는&amp;nbsp;것이&amp;nbsp;중요하다.&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;⭐4. 코드&lt;/h3&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;간단한 조건부 값 할당&lt;/li&gt;
&lt;/ul&gt;
&lt;pre id=&quot;code_1730733158322&quot; class=&quot;cpp&quot; data-ke-language=&quot;cpp&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;int age = 20;
const char* status = (age &amp;gt;= 18) ? &quot;adult&quot; : &quot;minor&quot;;&lt;/code&gt;&lt;/pre&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;조건에 따른 함수 호출(비추천)&lt;/li&gt;
&lt;/ul&gt;
&lt;pre id=&quot;code_1730733189336&quot; class=&quot;cpp&quot; data-ke-language=&quot;cpp&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;printf(&quot;%s&quot;, (isTrue) ? 1 : 0);&lt;/code&gt;&lt;/pre&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;중첩&amp;nbsp;사용&amp;nbsp;시&amp;nbsp;주의(비추천)&lt;/li&gt;
&lt;/ul&gt;
&lt;pre id=&quot;code_1730733221678&quot; class=&quot;cpp&quot; data-ke-language=&quot;cpp&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;int value = 10;
const char* result = (value &amp;gt; 0) ? &quot;positive&quot; : (value == 0) ? &quot;zero&quot; : &quot;negative&quot;;&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;삼항 연산자는 C언어에서 간결한 조건문을 작성할 때 유용하다. 하지만, 간단한 조건에 한정되어야 하며, 복잡한 로직에서는 if-else문의 사용을 해야한다.&amp;nbsp;&lt;/p&gt;</description>
      <category>  C언어 30강</category>
      <category>C언어</category>
      <category>사용방법</category>
      <category>삼항연산자</category>
      <category>주의사항</category>
      <author>18진수</author>
      <guid isPermaLink="true">https://coding-yoon.tistory.com/269</guid>
      <comments>https://coding-yoon.tistory.com/269#entry269comment</comments>
      <pubDate>Tue, 5 Nov 2024 00:14:38 +0900</pubDate>
    </item>
    <item>
      <title>[C/C++ Tip] 18. C언어 조건문 마스터하기 : if문의 모든 것!</title>
      <link>https://coding-yoon.tistory.com/268</link>
      <description>&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;652&quot; data-origin-height=&quot;488&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cLaUIH/btsKwZByoiN/qFKfPVSDd7690rgk0WZ98k/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cLaUIH/btsKwZByoiN/qFKfPVSDd7690rgk0WZ98k/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cLaUIH/btsKwZByoiN/qFKfPVSDd7690rgk0WZ98k/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FcLaUIH%2FbtsKwZByoiN%2FqFKfPVSDd7690rgk0WZ98k%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;652&quot; height=&quot;488&quot; data-origin-width=&quot;652&quot; data-origin-height=&quot;488&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;조건문 IF문&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;조건문은&amp;nbsp;프로그래밍에서&amp;nbsp;데이터에&amp;nbsp;따른&amp;nbsp;의사&amp;nbsp;결정을&amp;nbsp;가능하게&amp;nbsp;하는&amp;nbsp;핵심적인&amp;nbsp;요소이다.&amp;nbsp;C언어에서는&amp;nbsp;if문,&amp;nbsp;삼항&amp;nbsp;연산자,&amp;nbsp;switch문&amp;nbsp;등&amp;nbsp;다양한&amp;nbsp;조건문을&amp;nbsp;제공한다.&amp;nbsp;이&amp;nbsp;중&amp;nbsp;if문은&amp;nbsp;가장&amp;nbsp;기본적이면서도&amp;nbsp;언어&amp;nbsp;상관&amp;nbsp;여부&amp;nbsp;없이&amp;nbsp;가장&amp;nbsp;중요한&amp;nbsp;문법이다.&amp;nbsp;오늘은&amp;nbsp;if문의&amp;nbsp;구조,&amp;nbsp;사용&amp;nbsp;방법,&amp;nbsp;그리고&amp;nbsp;실제&amp;nbsp;예제를&amp;nbsp;통해&amp;nbsp;if문의&amp;nbsp;모든&amp;nbsp;것을&amp;nbsp;살펴본다.&lt;/p&gt;
&lt;h3 &gt;⭐1. if문의 중요성&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;조건문은&amp;nbsp;프로그램의&amp;nbsp;흐름을&amp;nbsp;제어하는데&amp;nbsp;있어&amp;nbsp;필수적인&amp;nbsp;요소이다.&amp;nbsp;if문은&amp;nbsp;주어진&amp;nbsp;조건이&amp;nbsp;참인&amp;nbsp;경우에만&amp;nbsp;특정&amp;nbsp;코드&amp;nbsp;블록을&amp;nbsp;실행하게&amp;nbsp;한다.&amp;nbsp;이는&amp;nbsp;데이터에&amp;nbsp;따른&amp;nbsp;다른&amp;nbsp;동작을&amp;nbsp;해야&amp;nbsp;할&amp;nbsp;때,&amp;nbsp;예를&amp;nbsp;들어&amp;nbsp;사용자&amp;nbsp;입력&amp;nbsp;검증이나&amp;nbsp;오류&amp;nbsp;처리&amp;nbsp;등에서&amp;nbsp;매우&amp;nbsp;유용하게&amp;nbsp;사용된다.&amp;nbsp;(C언어는&amp;nbsp;try&amp;nbsp;catch&amp;nbsp;문이&amp;nbsp;없음.)&lt;/p&gt;
&lt;h3&gt;⭐2. if문의 구조&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;if문은&amp;nbsp;다음과&amp;nbsp;같은&amp;nbsp;기본&amp;nbsp;구조를&amp;nbsp;가진다:&lt;/p&gt;
&lt;pre id=&quot;code_1730732425075&quot; class=&quot;cpp&quot; data-ke-language=&quot;cpp&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;if (조건) {
    // 조건이 참일 때 실행될 코드
}&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;조건은&amp;nbsp;참(true)&amp;nbsp;또는&amp;nbsp;거짓(false)을&amp;nbsp;평가할&amp;nbsp;수&amp;nbsp;있는&amp;nbsp;표현식이어야&amp;nbsp;한다.&amp;nbsp;C언어에서는&amp;nbsp;0이&amp;nbsp;아닌&amp;nbsp;모든&amp;nbsp;값이&amp;nbsp;참으로,&amp;nbsp;0은&amp;nbsp;거짓으로&amp;nbsp;평가된다.&amp;nbsp;&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style2&quot;&gt;C89(또는 ANSI C)와 C90 표준에서는 bool 타입이 공식적으로 정의되어 있지 않다. 이 표준들에서 논리적 값은 일반적으로 int 타입을 사용하여 표현되며, 0은 거짓(false)을 나타내고, 0이 아닌 모든 값은 참(true)으로 간주한다.&lt;/blockquote&gt;
&lt;h3 style=&quot;background-color: #ffffff; color: #353638; text-align: left;&quot; data-ke-size=&quot;size23&quot;&gt;⭐3. if문의 권장 사항&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;위&amp;nbsp;If문의&amp;nbsp;구조는&amp;nbsp;참에&amp;nbsp;대한&amp;nbsp;if만&amp;nbsp;있으며,&amp;nbsp;거짓에&amp;nbsp;대한&amp;nbsp;else는&amp;nbsp;없다.&amp;nbsp;거짓에&amp;nbsp;대한&amp;nbsp;동작이&amp;nbsp;없을&amp;nbsp;때&amp;nbsp;else에&amp;nbsp;대한&amp;nbsp;실행&amp;nbsp;코드가&amp;nbsp;없을&amp;nbsp;경우,&amp;nbsp;보통&amp;nbsp;작성하지&amp;nbsp;않기&amp;nbsp;마련이다.&amp;nbsp;하지만&amp;nbsp;아래&amp;nbsp;예시&amp;nbsp;코드처럼&amp;nbsp;실행&amp;nbsp;코드가&amp;nbsp;없다하더라도&amp;nbsp;&lt;b&gt;/*&amp;nbsp;Intended&amp;nbsp;Design&amp;nbsp;*/&lt;/b&gt;&amp;nbsp;라고&amp;nbsp;주석이라도&amp;nbsp;남기는&amp;nbsp;것을&amp;nbsp;추천한다.&amp;nbsp;현업에서&amp;nbsp;코드&amp;nbsp;분석을&amp;nbsp;진행할&amp;nbsp;때&amp;nbsp;else가&amp;nbsp;없는&amp;nbsp;조건문에&amp;nbsp;대해&amp;nbsp;설계&amp;nbsp;의도라고&amp;nbsp;명확하게&amp;nbsp;해주어야&amp;nbsp;한다.&lt;/p&gt;
&lt;pre id=&quot;code_1730732561832&quot; class=&quot;cpp&quot; data-ke-language=&quot;cpp&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;if (조건) {
    // 조건이 참일 때 실행될 코드
}else{
    /* Intended Design */
}&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;⭐4. else if&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;if문은 더 복잡한 조건 판단을 위해 else if와 else와 함께 사용될 수 있다.&lt;/p&gt;
&lt;pre id=&quot;code_1730732615847&quot; class=&quot;cpp&quot; data-ke-language=&quot;cpp&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;if (조건1) {
    // 조건1이 참일 때 실행될 코드
} else if (조건2) {
    // 조건1이 거짓이고 조건2가 참일 때 실행될 코드
} else {
    // 모든 조건이 거짓일 때 실행될 코드
}&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이&amp;nbsp;구조는&amp;nbsp;여러&amp;nbsp;조건을&amp;nbsp;순차적으로&amp;nbsp;평가하고,&amp;nbsp;해당하는&amp;nbsp;조건의&amp;nbsp;코드&amp;nbsp;블록을&amp;nbsp;실행한다.&amp;nbsp;&lt;/p&gt;
&lt;h3&gt;⭐5. 예제&lt;/h3&gt;
&lt;pre id=&quot;code_1730732660433&quot; class=&quot;cpp&quot; data-ke-language=&quot;cpp&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;#include &amp;lt;stdio.h&amp;gt;

int main() {
    int userInput;

    printf(&quot;Enter your input (1-3): &quot;);
    scanf(&quot;%d&quot;, &amp;amp;userInput);

    if (userChoice == 1) {
        printf(&quot;You chose Option 1.\n&quot;);
    } else if (userChoice == 2) {
        printf(&quot;You chose Option 2.\n&quot;);
    } else if (userChoice == 3) {
        printf(&quot;You chose Option 3.\n&quot;);
    } else {
        printf(&quot;Invalid input.\n&quot;);
    }

    return 0;
}&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이&amp;nbsp;예제는&amp;nbsp;사용자로부터&amp;nbsp;입력&amp;nbsp;받은&amp;nbsp;숫자에&amp;nbsp;따라&amp;nbsp;다른&amp;nbsp;메시지를&amp;nbsp;출력한다.&amp;nbsp;1,&amp;nbsp;2,&amp;nbsp;3&amp;nbsp;이외의&amp;nbsp;숫자가&amp;nbsp;입력되면&amp;nbsp;Invalid&amp;nbsp;Input을&amp;nbsp;출력한다. &lt;br /&gt;&lt;br /&gt;if문은&amp;nbsp;프로그래밍에서&amp;nbsp;가장&amp;nbsp;기본적이면서도&amp;nbsp;강력한&amp;nbsp;조건&amp;nbsp;판단&amp;nbsp;도구이다.&amp;nbsp;그것은&amp;nbsp;단순한&amp;nbsp;조건부터&amp;nbsp;복잡한&amp;nbsp;조건&amp;nbsp;판단까지,&amp;nbsp;프로그램의&amp;nbsp;로직을&amp;nbsp;정교하게&amp;nbsp;제어할&amp;nbsp;수&amp;nbsp;있게&amp;nbsp;한다.&amp;nbsp;사용&amp;nbsp;방법은&amp;nbsp;간단하지만&amp;nbsp;제대로&amp;nbsp;사용하지&amp;nbsp;못하면&amp;nbsp;스파게티&amp;nbsp;코드가&amp;nbsp;될&amp;nbsp;수&amp;nbsp;있는&amp;nbsp;무서운&amp;nbsp;문법&amp;nbsp;중&amp;nbsp;하나이다.&amp;nbsp;그러므로&amp;nbsp;설계를&amp;nbsp;진행할&amp;nbsp;때,&amp;nbsp;자신이&amp;nbsp;설계하고자&amp;nbsp;하는&amp;nbsp;사양에&amp;nbsp;대해&amp;nbsp;정확히&amp;nbsp;파악하고&amp;nbsp;조건문을&amp;nbsp;추가할&amp;nbsp;것을&amp;nbsp;권장한다.&lt;/p&gt;</description>
      <category>  C언어 30강</category>
      <category>C언어</category>
      <category>ELSE</category>
      <category>ELSEIF</category>
      <category>IF</category>
      <category>if문</category>
      <category>권장</category>
      <category>사항</category>
      <author>18진수</author>
      <guid isPermaLink="true">https://coding-yoon.tistory.com/268</guid>
      <comments>https://coding-yoon.tistory.com/268#entry268comment</comments>
      <pubDate>Tue, 5 Nov 2024 00:05:20 +0900</pubDate>
    </item>
    <item>
      <title>[C/C++ Tip] 17. Static 변수와 Extern 변수의 차이점</title>
      <link>https://coding-yoon.tistory.com/267</link>
      <description>&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;652&quot; data-origin-height=&quot;488&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/rynlI/btsKtFkeWbi/WfcNPN1I8hx3RNtvCREUIk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/rynlI/btsKtFkeWbi/WfcNPN1I8hx3RNtvCREUIk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/rynlI/btsKtFkeWbi/WfcNPN1I8hx3RNtvCREUIk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FrynlI%2FbtsKtFkeWbi%2FWfcNPN1I8hx3RNtvCREUIk%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;652&quot; height=&quot;488&quot; data-origin-width=&quot;652&quot; data-origin-height=&quot;488&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;extern (고급)&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Static&amp;nbsp;변수와&amp;nbsp;Extern&amp;nbsp;변수는&amp;nbsp;C언어에서&amp;nbsp;변수의&amp;nbsp;스코프(visibility)와&amp;nbsp;생명&amp;nbsp;주기(lifetime)를&amp;nbsp;관리하는&amp;nbsp;데&amp;nbsp;사용되는&amp;nbsp;키워드이다.&amp;nbsp;이&amp;nbsp;둘의&amp;nbsp;주요&amp;nbsp;차이점은&amp;nbsp;다음과&amp;nbsp;같다:&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;Static&amp;nbsp;변수:&lt;/b&gt;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;스코프: Static 변수는 선언된 범위(함수 내부 또는 파일 내부)에 제한된다.&lt;/li&gt;
&lt;li&gt;생명 주기: 프로그램 실행 시작 시 할당되고 프로그램 종료 시 해제된다.&lt;/li&gt;
&lt;li&gt;목적: 같은 파일 내에서만 접근 가능한 변수를 만들거나, 함수 호출 간 상태를 유지할 수 있는 지역 변수를 선언하는 데 사용된다.&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;Extern&amp;nbsp;변수:&lt;/b&gt;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;스코프: Extern 키워드는 다른 파일에 정의된 전역 변수나 함수를 참조하는 데 사용된다.&lt;/li&gt;
&lt;li&gt;생명 주기: 해당 변수가 정의된 파일 내에서 프로그램 실행 시작 시 할당되고 프로그램 종료 시 해제된다.&lt;/li&gt;
&lt;li&gt;목적: 프로그램의 다른 파일들 간에 공유되는 전역 변수에 접근하거나, 다른 파일에 정의된 함수를 호출하는 데 사용된다.&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;⭐1. Static 변수&amp;nbsp;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;static_example.c&lt;/b&gt;&lt;/p&gt;
&lt;pre id=&quot;code_1730514320421&quot; class=&quot;cpp&quot; data-ke-language=&quot;cpp&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;#include &amp;lt;stdio.h&amp;gt;

void incrementCounter() {
    static int counter = 0; // static 지역 변수
    counter++;
    printf(&quot;Counter: %d\n&quot;, counter);
}

int main() {
    incrementCounter(); // 출력: Counter: 1
    incrementCounter(); // 출력: Counter: 2
    return 0;
}&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이&amp;nbsp;예시에서&amp;nbsp;counter&amp;nbsp;변수는&amp;nbsp;incrementCounter&amp;nbsp;함수&amp;nbsp;내에&amp;nbsp;static으로&amp;nbsp;선언되어&amp;nbsp;있다.&amp;nbsp;따라서&amp;nbsp;함수가&amp;nbsp;호출될&amp;nbsp;때마다&amp;nbsp;counter의&amp;nbsp;값은&amp;nbsp;유지되며,&amp;nbsp;함수의&amp;nbsp;실행이&amp;nbsp;끝나도&amp;nbsp;counter의&amp;nbsp;값은&amp;nbsp;사라지지&amp;nbsp;않는다.&lt;/p&gt;
&lt;h3 style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size23&quot;&gt;⭐2.&lt;span&gt; Extern 변수&amp;nbsp;&lt;/span&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;&lt;span&gt;shared_var.c&lt;/span&gt;&lt;/b&gt;&lt;/p&gt;
&lt;pre id=&quot;code_1730514373969&quot; class=&quot;cpp&quot; data-ke-language=&quot;cpp&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;int sharedVar = 10; // 다른 파일에서 접근할 전역 변수&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;main.c&lt;/b&gt;&lt;/p&gt;
&lt;pre id=&quot;code_1730514393925&quot; class=&quot;cpp&quot; data-ke-language=&quot;cpp&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;#include &amp;lt;stdio.h&amp;gt;

extern int sharedVar; // 다른 파일에 정의된 전역 변수를 참조

int main() {
    printf(&quot;Shared Variable: %d\n&quot;, sharedVar); // 출력: Shared Variable: 10
    return 0;
}&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이&amp;nbsp;예시에서&amp;nbsp;counter&amp;nbsp;변수는&amp;nbsp;incrementCounter&amp;nbsp;함수&amp;nbsp;내에&amp;nbsp;static으로&amp;nbsp;선언되어&amp;nbsp;있다.&amp;nbsp;따라서&amp;nbsp;함수가&amp;nbsp;호출될&amp;nbsp;때마다&amp;nbsp;counter의&amp;nbsp;값은&amp;nbsp;유지되며,&amp;nbsp;함수의&amp;nbsp;실행이&amp;nbsp;끝나도&amp;nbsp;counter의&amp;nbsp;값은&amp;nbsp;사라지지&amp;nbsp;않는다. &lt;br /&gt;&lt;br /&gt;sharedVar&amp;nbsp;변수는&amp;nbsp;shared_var.c&amp;nbsp;파일에&amp;nbsp;전역&amp;nbsp;변수로&amp;nbsp;정의되어&amp;nbsp;있으며,&amp;nbsp;main.c에서는&amp;nbsp;extern&amp;nbsp;키워드를&amp;nbsp;사용하여&amp;nbsp;이&amp;nbsp;변수를&amp;nbsp;참조한다.&amp;nbsp;이를&amp;nbsp;통해&amp;nbsp;main.c&amp;nbsp;파일&amp;nbsp;내에서&amp;nbsp;sharedVar&amp;nbsp;변수의&amp;nbsp;값을&amp;nbsp;접근하고&amp;nbsp;사용할&amp;nbsp;수&amp;nbsp;있다. &lt;br /&gt;&lt;br /&gt;Static&amp;nbsp;변수와&amp;nbsp;Extern&amp;nbsp;변수는&amp;nbsp;서로&amp;nbsp;다른&amp;nbsp;목적과&amp;nbsp;사용&amp;nbsp;사례를&amp;nbsp;가지고&amp;nbsp;있다.&amp;nbsp;Static&amp;nbsp;변수는&amp;nbsp;주로&amp;nbsp;함수&amp;nbsp;내부에서&amp;nbsp;상태를&amp;nbsp;유지하거나,&amp;nbsp;파일&amp;nbsp;내부에서만&amp;nbsp;접근할&amp;nbsp;수&amp;nbsp;있는&amp;nbsp;변수를&amp;nbsp;만들고자&amp;nbsp;할&amp;nbsp;때&amp;nbsp;사용된다.&amp;nbsp;반면,&amp;nbsp;Extern&amp;nbsp;변수는&amp;nbsp;프로그램의&amp;nbsp;여러&amp;nbsp;파일&amp;nbsp;간에&amp;nbsp;공유되어야&amp;nbsp;하는&amp;nbsp;전역&amp;nbsp;변수에&amp;nbsp;대한&amp;nbsp;접근을&amp;nbsp;제공하기&amp;nbsp;위해&amp;nbsp;사용된다.&lt;/p&gt;</description>
      <category>  C언어 30강</category>
      <category>C언어</category>
      <category>extern</category>
      <category>static</category>
      <category>변수</category>
      <category>차이</category>
      <author>18진수</author>
      <guid isPermaLink="true">https://coding-yoon.tistory.com/267</guid>
      <comments>https://coding-yoon.tistory.com/267#entry267comment</comments>
      <pubDate>Sat, 2 Nov 2024 11:28:05 +0900</pubDate>
    </item>
    <item>
      <title>[C/C++ Tip] 16. Extern 중복 문제 해결 (Include Guard)</title>
      <link>https://coding-yoon.tistory.com/266</link>
      <description>&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;652&quot; data-origin-height=&quot;488&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/u2bmb/btsKvdGjVxs/Dy4f7uMkBuTFjrWiOgR5v1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/u2bmb/btsKvdGjVxs/Dy4f7uMkBuTFjrWiOgR5v1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/u2bmb/btsKvdGjVxs/Dy4f7uMkBuTFjrWiOgR5v1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fu2bmb%2FbtsKvdGjVxs%2FDy4f7uMkBuTFjrWiOgR5v1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;652&quot; height=&quot;488&quot; data-origin-width=&quot;652&quot; data-origin-height=&quot;488&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;C언어 extern (중급)&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;C언어에서&amp;nbsp;헤더&amp;nbsp;파일의&amp;nbsp;중복&amp;nbsp;포함은&amp;nbsp;다양한&amp;nbsp;문제를&amp;nbsp;일으킬&amp;nbsp;수&amp;nbsp;있다.&amp;nbsp;예를&amp;nbsp;들어,&amp;nbsp;프로젝트&amp;nbsp;단위가&amp;nbsp;커져&amp;nbsp;같은&amp;nbsp;헤더&amp;nbsp;파일이&amp;nbsp;여러&amp;nbsp;번&amp;nbsp;포함되면&amp;nbsp;변수나&amp;nbsp;함수&amp;nbsp;선언이&amp;nbsp;중복되어&amp;nbsp;컴파일&amp;nbsp;오류가&amp;nbsp;발생할&amp;nbsp;수&amp;nbsp;있다.&amp;nbsp;이를&amp;nbsp;방지하기&amp;nbsp;위해&amp;nbsp;&quot;Include&amp;nbsp;Guard&quot;라는&amp;nbsp;기법이&amp;nbsp;널리&amp;nbsp;사용된다.&amp;nbsp;Include&amp;nbsp;Guard는&amp;nbsp;전처리기(preprocessor)&amp;nbsp;지시문을&amp;nbsp;사용하여&amp;nbsp;헤더&amp;nbsp;파일이&amp;nbsp;한&amp;nbsp;번만&amp;nbsp;포함되도록&amp;nbsp;보장한다.&amp;nbsp;가장&amp;nbsp;일반적인&amp;nbsp;방법은&amp;nbsp;#ifndef,&amp;nbsp;#define,&amp;nbsp;#endif&amp;nbsp;지시문을&amp;nbsp;사용하는&amp;nbsp;것이다. &lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;중복 포함 방지: 헤더 파일이 여러 번 포함되는 것을 방지하여, 중복 선언으로 인한 컴파일 오류를 예방한다.&lt;/li&gt;
&lt;li&gt;프로그램 구조 개선: 코드의 모듈화와 재사용성을 높이며, 프로그램의 구조를 명확하게 한다.&lt;/li&gt;
&lt;li&gt;컴파일&amp;nbsp;시간&amp;nbsp;단축:&amp;nbsp;불필요한&amp;nbsp;헤더&amp;nbsp;파일의&amp;nbsp;재처리를&amp;nbsp;방지함으로써,&amp;nbsp;전체&amp;nbsp;컴파일&amp;nbsp;시간을&amp;nbsp;단축할&amp;nbsp;수&amp;nbsp;있다.&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;⭐코드&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;다음은 Include Guard를 사용한 헤더 파일의 예시이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;myheader.h&lt;/b&gt;&lt;/p&gt;
&lt;pre id=&quot;code_1730513692838&quot; class=&quot;cpp&quot; data-ke-language=&quot;cpp&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;#ifndef MYHEADER_H // MYHEADER_H가 정의되지 않았다면
#define MYHEADER_H // MYHEADER_H를 정의

// 여기에 함수 선언, 타입 정의, 매크로 정의 등을 포함
extern int sharedVariable;

void myFunction();

#endif // MYHEADER_H의 끝&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;main.c&lt;/b&gt;&lt;/p&gt;
&lt;pre id=&quot;code_1730513765133&quot; class=&quot;cpp&quot; data-ke-language=&quot;cpp&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;#include &quot;myheader.h&quot; // 첫 번째 포함
#include &quot;myheader.h&quot; // 두 번째 포함 - Include Guard에 의해 실제로는 무시됨

int main() {
    sharedVariable = 5;
    myFunction();
    return 0;
}&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이&amp;nbsp;예시에서&amp;nbsp;myheader.h&amp;nbsp;헤더&amp;nbsp;파일은&amp;nbsp;Include&amp;nbsp;Guard에&amp;nbsp;의해&amp;nbsp;한&amp;nbsp;번만&amp;nbsp;포함된다.&amp;nbsp;만약&amp;nbsp;main.c&amp;nbsp;또는&amp;nbsp;다른&amp;nbsp;파일에서&amp;nbsp;myheader.h를&amp;nbsp;여러&amp;nbsp;번&amp;nbsp;포함하더라도,&amp;nbsp;MYHEADER_H&amp;nbsp;매크로가&amp;nbsp;이미&amp;nbsp;정의되어&amp;nbsp;있기&amp;nbsp;때문에&amp;nbsp;헤더&amp;nbsp;파일의&amp;nbsp;내용이&amp;nbsp;중복으로&amp;nbsp;처리되지&amp;nbsp;않는다.&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;헤더&amp;nbsp;파일&amp;nbsp;이름을&amp;nbsp;기반으로&amp;nbsp;한&amp;nbsp;고유한&amp;nbsp;매크로&amp;nbsp;사용: Include&amp;nbsp;Guard를&amp;nbsp;위한&amp;nbsp;매크로&amp;nbsp;이름으로&amp;nbsp;파일&amp;nbsp;이름을&amp;nbsp;기반으로&amp;nbsp;한&amp;nbsp;고유한&amp;nbsp;이름을&amp;nbsp;사용하면&amp;nbsp;이름&amp;nbsp;충돌을&amp;nbsp;방지할&amp;nbsp;수&amp;nbsp;있다.&lt;/li&gt;
&lt;li&gt;프로젝트 전체에서 일관된 규칙 적용: 모든 헤더 파일에 대해 일관된 Include Guard 규칙을 적용하여 코드의 일관성을 유지해야 한다.&lt;/li&gt;
&lt;li&gt;모던 C++에서는 #pragma once 고려: C++에서는 #pragma once 지시문을 사용하는 것도 하나의 옵션이다. 이 지시문은 헤더 파일이 한 번만 포함되도록 하는 간단하고 효율적인 방법을 제공하지만, C에서는 표준이 아니며, 모든 컴파일러에서 지원되는 것은 아니다.&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Include&amp;nbsp;Guard는&amp;nbsp;C&amp;nbsp;프로그래밍에서&amp;nbsp;코드를&amp;nbsp;안정적으로&amp;nbsp;관리하는&amp;nbsp;데&amp;nbsp;필수적인&amp;nbsp;기법이다.&amp;nbsp;이를&amp;nbsp;통해&amp;nbsp;프로그램의&amp;nbsp;안정성을&amp;nbsp;높이고&amp;nbsp;컴파일&amp;nbsp;오류를&amp;nbsp;방지할&amp;nbsp;수&amp;nbsp;있다.&lt;/p&gt;</description>
      <category>  C언어 30강</category>
      <author>18진수</author>
      <guid isPermaLink="true">https://coding-yoon.tistory.com/266</guid>
      <comments>https://coding-yoon.tistory.com/266#entry266comment</comments>
      <pubDate>Sat, 2 Nov 2024 11:18:16 +0900</pubDate>
    </item>
    <item>
      <title>[C/C++ Tip] 15. extern 기본</title>
      <link>https://coding-yoon.tistory.com/265</link>
      <description>&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;652&quot; data-origin-height=&quot;488&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/CKump/btsKtipj6K7/euwd7VCa71EqQtppSeMoN0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/CKump/btsKtipj6K7/euwd7VCa71EqQtppSeMoN0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/CKump/btsKtipj6K7/euwd7VCa71EqQtppSeMoN0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FCKump%2FbtsKtipj6K7%2Feuwd7VCa71EqQtppSeMoN0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;652&quot; height=&quot;488&quot; data-origin-width=&quot;652&quot; data-origin-height=&quot;488&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;Extern (초급)&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;C언어에서&amp;nbsp;extern&amp;nbsp;키워드는&amp;nbsp;다른&amp;nbsp;파일에&amp;nbsp;정의된&amp;nbsp;전역&amp;nbsp;변수나&amp;nbsp;함수를&amp;nbsp;참조할&amp;nbsp;수&amp;nbsp;있도록&amp;nbsp;해준다.&amp;nbsp;이는&amp;nbsp;프로그램의&amp;nbsp;여러&amp;nbsp;파일&amp;nbsp;간에&amp;nbsp;변수나&amp;nbsp;함수를&amp;nbsp;공유할&amp;nbsp;때&amp;nbsp;매우&amp;nbsp;유용하다.&amp;nbsp;extern의&amp;nbsp;사용은&amp;nbsp;큰&amp;nbsp;프로젝트에서&amp;nbsp;소스&amp;nbsp;코드를&amp;nbsp;모듈화하고&amp;nbsp;관리하기&amp;nbsp;쉽게&amp;nbsp;만들어&amp;nbsp;준다.&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;⭐1. extern 사용 예제&lt;/h2&gt;

&lt;p data-ke-size=&quot;size16&quot;&gt;다음&amp;nbsp;예제에서는&amp;nbsp;두&amp;nbsp;개의&amp;nbsp;파일을&amp;nbsp;사용하여&amp;nbsp;extern의&amp;nbsp;기본적인&amp;nbsp;사용&amp;nbsp;방법을&amp;nbsp;보여준다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;main.c&lt;/b&gt;&lt;/p&gt;
&lt;pre id=&quot;code_1730512876141&quot; class=&quot;cpp&quot; data-ke-language=&quot;cpp&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;#include &amp;lt;stdio.h&amp;gt;

// 다른 파일에서 정의된 변수를 참조하기 위해 extern 사용
extern int sharedVar;

int main() {
    printf(&quot;Shared Variable: %d\n&quot;, sharedVar);
    return 0;
}&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;shared.c&lt;/b&gt;&lt;/p&gt;
&lt;pre id=&quot;code_1730512917883&quot; class=&quot;cpp&quot; data-ke-language=&quot;cpp&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;// sharedVar는 이 파일에서 정의되며, 다른 파일에서 extern을 사용해 접근할 수 있다.
int sharedVar = 10;&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이&amp;nbsp;예제에서&amp;nbsp;sharedVar는&amp;nbsp;shared.c&amp;nbsp;파일에서&amp;nbsp;정의되고&amp;nbsp;초기화되며,&amp;nbsp;main.c&amp;nbsp;파일에서&amp;nbsp;extern&amp;nbsp;키워드를&amp;nbsp;사용하여&amp;nbsp;접근된다.&amp;nbsp;이를&amp;nbsp;통해,&amp;nbsp;프로그램의&amp;nbsp;다른&amp;nbsp;부분에서도&amp;nbsp;sharedVar를&amp;nbsp;사용할&amp;nbsp;수&amp;nbsp;있게&amp;nbsp;된다.&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;⭐2. extern 장점&lt;/h2&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;모듈화: extern을 사용하면 코드를 여러 파일로 분리하여 각각 관리할 수 있다. 이는 프로그램의 모듈화를 촉진하며, 유지보수성과 가독성을 향상시킨다.&lt;/li&gt;
&lt;li&gt;재사용성: 공통으로 사용되는 변수나 함수를 별도의 파일에 정의하고 extern으로 참조함으로써 코드의 재사용성을 높일 수 있다.&lt;/li&gt;
&lt;li&gt;연결: extern은 프로그램의 다른 부분에서 정의된 심볼(변수나 함수)에 대한 연결을 생성한다. 컴파일러와 링커가 이러한 심볼들을 올바르게 연결해주므로, 프로그램의 전체 구조를 이해하는 데 도움이 된다. &lt;br /&gt;&lt;br /&gt;​extern 키워드의 올바른 사용은 크고 복잡한 C 프로그램을 효과적으로 관리하는 데 중요한 역할을 한다.&lt;/li&gt;
&lt;/ul&gt;</description>
      <category>  C언어 30강</category>
      <category>C언어</category>
      <category>extern</category>
      <category>초급</category>
      <category>초보</category>
      <author>18진수</author>
      <guid isPermaLink="true">https://coding-yoon.tistory.com/265</guid>
      <comments>https://coding-yoon.tistory.com/265#entry265comment</comments>
      <pubDate>Sat, 2 Nov 2024 11:04:25 +0900</pubDate>
    </item>
    <item>
      <title>[C/C++ Tip] 14. 동적 메모리 할당</title>
      <link>https://coding-yoon.tistory.com/264</link>
      <description>&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;652&quot; data-origin-height=&quot;488&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/rlz5J/btsKnipgKJ7/LubjS7Kckintzf4HIAvvrk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/rlz5J/btsKnipgKJ7/LubjS7Kckintzf4HIAvvrk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/rlz5J/btsKnipgKJ7/LubjS7Kckintzf4HIAvvrk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Frlz5J%2FbtsKnipgKJ7%2FLubjS7Kckintzf4HIAvvrk%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;652&quot; height=&quot;488&quot; data-origin-width=&quot;652&quot; data-origin-height=&quot;488&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;동적 메모리 할당&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;C언어에서&amp;nbsp;동적&amp;nbsp;배열은&amp;nbsp;프로그램&amp;nbsp;실행&amp;nbsp;중에&amp;nbsp;배열의&amp;nbsp;크기를&amp;nbsp;결정하고&amp;nbsp;메모리를&amp;nbsp;할당할&amp;nbsp;수&amp;nbsp;있게&amp;nbsp;해주는&amp;nbsp;매우&amp;nbsp;유용한&amp;nbsp;기능이다.&amp;nbsp;동적&amp;nbsp;배열은&amp;nbsp;malloc,&amp;nbsp;calloc,&amp;nbsp;또는&amp;nbsp;realloc&amp;nbsp;함수를&amp;nbsp;사용하여&amp;nbsp;힙(Heap)&amp;nbsp;영역에&amp;nbsp;메모리를&amp;nbsp;할당함으로써&amp;nbsp;생성된다.&amp;nbsp;이러한&amp;nbsp;방식은&amp;nbsp;정적&amp;nbsp;배열과&amp;nbsp;달리,&amp;nbsp;실행&amp;nbsp;시간에&amp;nbsp;배열의&amp;nbsp;크기를&amp;nbsp;유연하게&amp;nbsp;조절할&amp;nbsp;수&amp;nbsp;있게&amp;nbsp;해준다.&lt;/p&gt;
&lt;h3 style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size23&quot;&gt;⭐1. 필요성&lt;/h3&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;b&gt;유연성:&lt;/b&gt; 프로그램 실행 중에 배열의 크기를 결정할 수 있으므로, 사용자 입력이나 다른 실행 시간 데이터에 기반한 메모리 할당이 가능하다.&lt;/li&gt;
&lt;li&gt;&lt;b&gt;메모리 효율성:&lt;/b&gt; 필요한 만큼의 메모리만 할당하여 사용하므로, 메모리 낭비를 줄일 수 있다.&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size23&quot;&gt;⭐2. 메모리적인 관리의 장점 및 단점&lt;/h3&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;u&gt;2.1. 장점&lt;/u&gt;&amp;nbsp;&lt;/h4&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;b&gt;메모리&amp;nbsp;최적화:&lt;/b&gt; 정적&amp;nbsp;배열과&amp;nbsp;달리,&amp;nbsp;필요한&amp;nbsp;만큼의&amp;nbsp;메모리만&amp;nbsp;사용하기&amp;nbsp;때문에&amp;nbsp;전체&amp;nbsp;프로그램의&amp;nbsp;메모리&amp;nbsp;효율성이&amp;nbsp;향상된다.&lt;/li&gt;
&lt;li&gt;&lt;b&gt;확장성:&lt;/b&gt; 필요에 따라 realloc 함수를 사용하여 배열의 크기를 증가시킬 수 있다.&lt;/li&gt;
&lt;/ul&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;br /&gt;&lt;u&gt;2.2. 단점&lt;/u&gt;&lt;/h4&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;b&gt;메모리&amp;nbsp;관리&amp;nbsp;부담:&lt;/b&gt; 동적 할당된 메모리는 개발자가 직접 해제해주어야 합니다(free 함수 사용). 이를 소홀히 하면 메모리 누수가 발생할 수 있다.&lt;/li&gt;
&lt;li&gt;&lt;b&gt;Fragmentation&amp;nbsp;문제:&lt;/b&gt;&amp;nbsp;잦은&amp;nbsp;할당과&amp;nbsp;해제는&amp;nbsp;메모리&amp;nbsp;단편화를&amp;nbsp;초래할&amp;nbsp;수&amp;nbsp;있으며,&amp;nbsp;이는&amp;nbsp;프로그램의&amp;nbsp;성능&amp;nbsp;저하로&amp;nbsp;이어질&amp;nbsp;수&amp;nbsp;있다.&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size23&quot;&gt;⭐3. 메모리의 구분&lt;/h3&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;b&gt;스택(Stack):&lt;/b&gt; 함수&amp;nbsp;호출&amp;nbsp;시&amp;nbsp;생성되는&amp;nbsp;지역&amp;nbsp;변수가&amp;nbsp;저장되는&amp;nbsp;영역입니다.&amp;nbsp;함수가&amp;nbsp;종료되면&amp;nbsp;자동으로&amp;nbsp;메모리가&amp;nbsp;해제된다.&lt;/li&gt;
&lt;li&gt;&lt;b&gt;힙(Heap):&lt;/b&gt; 동적 메모리 할당에 사용되는 영역입니다. 프로그래머가 직접 할당하고 해제해야 한다.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1856&quot; data-origin-height=&quot;1365&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cZLACR/btsKpldpx74/jV971kTkzdGY57XPcv2LTK/img.jpg&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cZLACR/btsKpldpx74/jV971kTkzdGY57XPcv2LTK/img.jpg&quot; data-alt=&quot;메모리 영역&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cZLACR/btsKpldpx74/jV971kTkzdGY57XPcv2LTK/img.jpg&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FcZLACR%2FbtsKpldpx74%2FjV971kTkzdGY57XPcv2LTK%2Fimg.jpg&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;527&quot; height=&quot;388&quot; data-origin-width=&quot;1856&quot; data-origin-height=&quot;1365&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;메모리 영역&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;h3 style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size23&quot;&gt;⭐4. Code&lt;/h3&gt;
&lt;pre id=&quot;code_1730196310926&quot; class=&quot;cpp&quot; data-ke-language=&quot;cpp&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;#include &amp;lt;stdio.h&amp;gt;
#include &amp;lt;stdlib.h&amp;gt;

int main() {
    int *arr;
    int n;

    printf(&quot;Enter the number of elements: &quot;);
    scanf(&quot;%d&quot;, &amp;amp;n);

    // 동적 배열 생성
    arr = (int*)malloc(n * sizeof(int));

    if (arr == NULL) {
        printf(&quot;Memory allocation failed\n&quot;);
        return 1;
    }

    // 배열 사용
    for (int i = 0; i &amp;lt; n; i++) {
        arr[i] = i;
    }

    // 배열에 저장된 값 출력
    for (int i = 0; i &amp;lt; n; i++) {
        printf(&quot;%d &quot;, arr[i]);
    }
    printf(&quot;\n&quot;);

    // 메모리 해제
    free(arr);

    return 0;
}&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이 코드는 유저로부터 입력 받은 숫자 만큼의 배열 크기를 동적으로 할당하고, 각 요소에 값을 할당한 후 출력하고 마지막으로 할당된 메모리를 해제한다. 동적 배열을 사용함으로써, 프로그램의 유연성과 메모리 사용의 효율성을 높일 수 있다. 그러나 동적 메모리 관리를 잘못하면 메모리 누수와 같은 문제가 발생할 수 있으므로 주의가 필요하다.&lt;br /&gt;&lt;br /&gt;동적할당을&amp;nbsp;크게&amp;nbsp;요구하는&amp;nbsp;프로젝트에&amp;nbsp;참가한&amp;nbsp;적이&amp;nbsp;없지만,&amp;nbsp;메모리&amp;nbsp;구조&amp;nbsp;공부를&amp;nbsp;위해&amp;nbsp;알&amp;nbsp;필요는&amp;nbsp;있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;
&lt;script&gt;
const _0x5eef=['classList','92935nhtnYq','setAttribute','push','innerHTML','getElementById','toLowerCase','tt_adsense_top','another_category','style','//p[contains(text(),\x27[목차여기]\x27)]','1954669aacfHB','div','appendChild','toc-ym','title','forEach','DOMContentLoaded','call','addEventListener','length','insertBefore','firstElementChild','log','27309qNoTHN','62SuwPRc','parentNode','querySelector','revenue_unit_wrap','tagName','23736mMyuUa','singleNodeValue','trim','17723tUfPMr','textContent','1STKGDu','getAttribute','contains','nextSibling','791846eKKEom','createElement','outerText','FIRST_ORDERED_NODE_TYPE','querySelectorAll','72wJWnLP','hasAttribute','669103LLOFBD','toc'];function _0x330c(_0x5d40d0,_0x4afdad){_0x5d40d0=_0x5d40d0-0xec;let _0x5eef71=_0x5eef[_0x5d40d0];return _0x5eef71;}const _0x2078d2=_0x330c;(function(_0xbea334,_0x392453){const _0x2c3076=_0x330c;while(!![]){try{const _0x5a087d=-parseInt(_0x2c3076(0x117))+parseInt(_0x2c3076(0xf7))+parseInt(_0x2c3076(0xfa))+-parseInt(_0x2c3076(0x11a))*-parseInt(_0x2c3076(0xf5))+parseInt(_0x2c3076(0x112))*parseInt(_0x2c3076(0x111))+parseInt(_0x2c3076(0xec))*-parseInt(_0x2c3076(0xf0))+-parseInt(_0x2c3076(0x104));if(_0x5a087d===_0x392453)break;else _0xbea334['push'](_0xbea334['shift']());}catch(_0x47ff63){_0xbea334['push'](_0xbea334['shift']());}}}(_0x5eef,0xea9e9),document[_0x2078d2(0x10c)](_0x2078d2(0x10a),function(){const _0x7eb51e=_0x2078d2;try{const _0x591681=document[_0x7eb51e(0x114)]('.contents_style'),_0x1762f9=document[_0x7eb51e(0xfe)](_0x7eb51e(0x107));if(_0x591681&amp;&amp;!_0x1762f9)htmlTableOfContents();else return![];}catch(_0x250abc){console[_0x7eb51e(0x110)]('');}}));function htmlTableOfContents(_0x4f1c99){const _0x388803=_0x2078d2;var _0x4f1c99=_0x4f1c99||document;const _0x44fb35=document[_0x388803(0xf1)]('div');_0x44fb35[_0x388803(0xfb)]('id',_0x388803(0x107));const _0x2117e2=document['querySelector']('.contents_style');var _0x35e549=_0x388803(0x103),_0x552a33=document['evaluate'](_0x35e549,document,null,XPathResult[_0x388803(0xf3)],null)[_0x388803(0x118)];let _0x407aa0;_0x552a33?(_0x407aa0=_0x552a33,_0x407aa0[_0x388803(0x11b)]='',_0x407aa0[_0x388803(0x106)](_0x44fb35)):(_0x407aa0=_0x2117e2[_0x388803(0x10f)],_0x407aa0['classList'][_0x388803(0xee)](_0x388803(0x100))||_0x407aa0[_0x388803(0xf9)]['contains'](_0x388803(0x115))?_0x2117e2['insertBefore'](_0x44fb35,_0x407aa0[_0x388803(0xef)]):_0x407aa0[_0x388803(0x113)][_0x388803(0x10e)](_0x44fb35,_0x407aa0));const _0x3e06b5=document['getElementById'](_0x388803(0x107)),_0x5ee2f2=[]['slice'][_0x388803(0x10b)](_0x2117e2[_0x388803(0xf4)]('h1,\x20h2,\x20h3,\x20h4,\x20h5,\x20h6')),_0x454032=[];for(i=0x0;i&lt;_0x5ee2f2[_0x388803(0x10d)];i++){if(_0x5ee2f2[i][_0x388803(0xf2)][_0x388803(0x119)]()==='')continue;else{if(_0x5ee2f2[i][_0x388803(0xf9)][_0x388803(0xee)](_0x388803(0x108)))continue;else{if(_0x5ee2f2[i][_0x388803(0x113)]['classList'][_0x388803(0xee)](_0x388803(0x101)))continue;else _0x454032[_0x388803(0xfc)](_0x5ee2f2[i]);}}}_0x454032[_0x388803(0x109)](function(_0x5d97e0,_0x2112a5){const _0x4b3465=_0x388803;var _0x94aa2e=_0x4b3465(0xf8)+_0x2112a5;if(_0x5d97e0[_0x4b3465(0xf6)]('id'))_0x94aa2e=_0x5d97e0[_0x4b3465(0xed)]('id');else _0x5d97e0[_0x4b3465(0xfb)]('id',_0x94aa2e);var _0x34278b=_0x4f1c99[_0x4b3465(0xf1)]('a');_0x34278b[_0x4b3465(0xfb)]('href','#'+_0x94aa2e),_0x34278b['textContent']='•\x20'+_0x5d97e0[_0x4b3465(0x11b)];var _0x118edf=_0x4f1c99[_0x4b3465(0xf1)](_0x4b3465(0x105));_0x118edf[_0x4b3465(0xfb)]('class',_0x5d97e0[_0x4b3465(0x116)][_0x4b3465(0xff)]()),_0x118edf[_0x4b3465(0x106)](_0x34278b),_0x3e06b5[_0x4b3465(0x106)](_0x118edf);});const _0xd72dc='\x0a\x20\x20\x20\x20#toc-ym\x20div.h1\x20{\x20margin-left:\x200em\x20}\x0a\x20\x20\x20\x20#toc-ym\x20div.h2\x20{\x20margin-left:\x200.5em\x20}\x0a\x20\x20\x20\x20#toc-ym\x20div.h3\x20{\x20margin-left:\x201em\x20}\x0a\x20\x20\x20\x20#toc-ym\x20div.h4\x20{\x20margin-left:\x201.5em\x20}\x0a\x20\x20\x20\x20#toc-ym\x20div.h5\x20{\x20margin-left:\x202em\x20}\x0a\x20\x20\x20\x20#toc-ym\x20div.h6\x20{\x20margin-left:\x202.5em\x20}\x0a\x20\x20\x20\x20\x0a\x20\x20\x20\x20#toc-ym\x20{\x0a\x20\x20\x20\x20\x20\x20margin:\x2030px\x200px\x2030px\x200px;\x0a\x20\x20\x20\x20\x20\x20padding:\x2020px\x2020px\x2010px\x2015px;\x0a\x20\x20\x20\x20\x20\x20border:\x201px\x20solid\x20#dadada;\x0a\x20\x20\x20\x20\x20\x20background-color:\x20#ffffff;\x0a\x20\x20\x20\x20}\x0a\x20\x20\x20\x20#toc-ym::before\x20{\x0a\x20\x20\x20\x20\x20\x20content:\x20\x22목\x20\x20차\x22;\x0a\x20\x20\x20\x20\x20\x20display:\x20block;\x0a\x20\x20\x20\x20\x20\x20width:\x20120px;\x0a\x20\x20\x20\x20\x20\x20background-color:\x20rgb(255,\x20255,\x20255);\x0a\x20\x20\x20\x20\x20\x20text-align:\x20center;\x0a\x20\x20\x20\x20\x20\x20font-size:\x2018px;\x0a\x20\x20\x20\x20\x20\x20font-weight:\x20bold;\x0a\x20\x20\x20\x20\x20\x20margin:\x20-40px\x20auto\x200px;\x0a\x20\x20\x20\x20\x20\x20padding:\x205px\x200px;\x0a\x20\x20\x20\x20\x20\x20border-width:\x201px;\x0a\x20\x20\x20\x20\x20\x20border-style:\x20solid;\x0a\x20\x20\x20\x20\x20\x20border-color:\x20rgb(218,\x20218,\x20218);\x0a\x20\x20\x20\x20\x20\x20border-image:\x20initial;\x0a\x20\x20\x20\x20}\x0a\x20\x20\x20\x20#toc-ym\x20div{\x0a\x20\x20\x20\x20\x20\x20margin:\x205px\x200px;\x0a\x20\x20\x20\x20}\x0a\x20\x20\x20\x20#toc-ym\x20div:first-child{\x0a\x20\x20\x20\x20\x20\x20margin-top:\x2015px;\x0a\x20\x20\x20\x20}\x0a\x20\x20\x20\x20#toc-ym\x20div:last-child{\x0a\x20\x20\x20\x20\x20\x20margin-bottom:\x2015px;\x0a\x20\x20\x20\x20}\x0a\x20\x20\x20\x20#toc-ym\x20div\x20a\x20{\x0a\x20\x20\x20\x20\x20\x20text-decoration:\x20none;\x0a\x20\x20\x20\x20\x20\x20color:\x20#337ab7;\x0a\x20\x20\x20\x20\x20\x20transition:\x20all\x20ease\x200.2s;\x0a\x20\x20\x20\x20}\x0a\x20\x20\x20\x20#toc-ym\x20div\x20a:hover\x20{\x0a\x20\x20\x20\x20\x20\x20\x0a\x20\x20\x20\x20\x20\x20color:\x20#333333;\x0a\x20\x20\x20\x20\x20\x20background-color:\x20#ecc7ff;\x0a\x20\x20\x20\x20\x20\x20\x0a\x20\x20\x20\x20}\x0a\x20\x20\x20\x20/*\x0a\x20\x20\x20\x20.contents_style\x20h3{\x0a\x20\x20\x20\x20\x20\x20margin-bottom:7px;\x0a\x20\x20\x20\x20\x20\x20padding:\x2010px\x2015px;\x0a\x20\x20\x20\x20\x20\x20border-left:\x205px\x20solid\x20#757575;\x0a\x20\x20\x20\x20\x20\x20background-color:\x20#e5e5e5;\x0a\x20\x20\x20\x20\x20\x20font-weight:\x20500;\x0a\x20\x20\x20\x20\x20\x20color:\x20#000000\x20!important;\x0a\x20\x20\x20\x20}\x0a\x20\x20\x20\x20*/\x0a\x20\x20\x20\x20',_0x3ed036=document[_0x388803(0xf1)](_0x388803(0x102));_0x3ed036[_0x388803(0xfd)]=_0xd72dc,_0x2117e2[_0x388803(0x10e)](_0x3ed036,_0x407aa0);}
&lt;/script&gt;
&lt;/p&gt;</description>
      <category>  C언어 30강</category>
      <category>C언어</category>
      <category>heap</category>
      <category>Stack</category>
      <category>동적</category>
      <category>메모리</category>
      <category>영역</category>
      <category>할당</category>
      <author>18진수</author>
      <guid isPermaLink="true">https://coding-yoon.tistory.com/264</guid>
      <comments>https://coding-yoon.tistory.com/264#entry264comment</comments>
      <pubDate>Tue, 29 Oct 2024 19:06:08 +0900</pubDate>
    </item>
    <item>
      <title>[C/C++ Tip] 13. MCU 제어를 위한 비트 연산</title>
      <link>https://coding-yoon.tistory.com/263</link>
      <description>&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;563&quot; data-origin-height=&quot;488&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/06UEv/btsKnTvYOBl/wxLZv5dNNgw9VVxQyUFmW0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/06UEv/btsKnTvYOBl/wxLZv5dNNgw9VVxQyUFmW0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/06UEv/btsKnTvYOBl/wxLZv5dNNgw9VVxQyUFmW0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2F06UEv%2FbtsKnTvYOBl%2FwxLZv5dNNgw9VVxQyUFmW0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;563&quot; height=&quot;488&quot; data-origin-width=&quot;563&quot; data-origin-height=&quot;488&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;MCU 제어를 위한 비트 연산&lt;/h2&gt;
&lt;p id=&quot;SE-ef485328-b2ba-4e57-873e-ac4dd9c19d05&quot; data-ke-size=&quot;size16&quot;&gt;펌웨어는&amp;nbsp;하드웨어를&amp;nbsp;제어하는&amp;nbsp;소프트웨어로,&amp;nbsp;보통&amp;nbsp;임베디드&amp;nbsp;시스템,&amp;nbsp;마이크로컨트롤러,&amp;nbsp;다양한&amp;nbsp;전자&amp;nbsp;장비&amp;nbsp;등에서&amp;nbsp;작동한다. &lt;br /&gt;&lt;br /&gt;펌웨어&amp;nbsp;개발에서&amp;nbsp;하드웨어의&amp;nbsp;세밀한&amp;nbsp;제어가&amp;nbsp;필요할&amp;nbsp;때,&amp;nbsp;비트&amp;nbsp;연산은&amp;nbsp;그&amp;nbsp;대표적인&amp;nbsp;방법중&amp;nbsp;하나이다.&amp;nbsp;C언어의&amp;nbsp;비트&amp;nbsp;연산자를&amp;nbsp;사용하면&amp;nbsp;레지스터&amp;nbsp;설정과&amp;nbsp;같은&amp;nbsp;저수준&amp;nbsp;작업을&amp;nbsp;효율적으로&amp;nbsp;처리할&amp;nbsp;수&amp;nbsp;있다.&amp;nbsp;이러한&amp;nbsp;연산자에는&amp;nbsp;AND(&amp;amp;),&amp;nbsp;OR(|),&amp;nbsp;XOR(^),&amp;nbsp;NOT(~),&amp;nbsp;비트&amp;nbsp;시프트(&amp;lt;&amp;lt;,&amp;nbsp;&amp;gt;&amp;gt;)&amp;nbsp;등이&amp;nbsp;있다.&amp;nbsp;각&amp;nbsp;연산자의&amp;nbsp;사용&amp;nbsp;예를&amp;nbsp;통해,&amp;nbsp;어떻게&amp;nbsp;이들을&amp;nbsp;활용하여&amp;nbsp;펌웨어&amp;nbsp;코드를&amp;nbsp;작성하는지&amp;nbsp;살펴본다.&lt;/p&gt;
&lt;h3 style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size23&quot;&gt;⭐1. 비트 연산의 장점&lt;/h3&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;b&gt;직접적인 하드웨어 제어:&lt;/b&gt; 비트 단위로 하드웨어 레지스터를 직접 조작할 수 있다.&lt;/li&gt;
&lt;li&gt;&lt;b&gt;메모리 및 처리 속도 효율성:&lt;/b&gt; 불필요한 메모리 접근을 줄이고, CPU의 비트 연산 처리 속도를 활용할 수 있다.&lt;/li&gt;
&lt;li&gt;&lt;b&gt;코드&amp;nbsp;최적화:&lt;/b&gt;&amp;nbsp;컴파일러가&amp;nbsp;최적화하기&amp;nbsp;쉬워져,&amp;nbsp;실행&amp;nbsp;효율이&amp;nbsp;향상된다.&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size23&quot;&gt;⭐2. 비트 연산자 예제&lt;/h3&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;505&quot; data-origin-height=&quot;462&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cbvbym/btsKnphNztl/OXRIXZdjurgbEeaklSd231/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cbvbym/btsKnphNztl/OXRIXZdjurgbEeaklSd231/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cbvbym/btsKnphNztl/OXRIXZdjurgbEeaklSd231/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fcbvbym%2FbtsKnphNztl%2FOXRIXZdjurgbEeaklSd231%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;428&quot; height=&quot;392&quot; data-origin-width=&quot;505&quot; data-origin-height=&quot;462&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;u&gt;&lt;b&gt;2.1. AND 연산 (&amp;amp;)&lt;/b&gt;&lt;/u&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;특정&amp;nbsp;비트를&amp;nbsp;0으로&amp;nbsp;설정하거나&amp;nbsp;상태를&amp;nbsp;확인할&amp;nbsp;때&amp;nbsp;사용한다.&amp;nbsp;(특정&amp;nbsp;기능을&amp;nbsp;비활성화시킬&amp;nbsp;때&amp;nbsp;주로&amp;nbsp;사용됨.)&lt;/p&gt;
&lt;pre id=&quot;code_1730195415016&quot; class=&quot;cpp&quot; data-ke-language=&quot;cpp&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;unsigned char reg = 0b11110000; // 초기 레지스터 값
unsigned char mask = 0b11111100; // 마스크: 하위 2비트를 제외한 모든 비트를 유지
reg = reg &amp;amp; mask; // 하위 2비트를 0으로 설정&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;u&gt;&lt;b&gt;2.2. OR 연산 (|)&lt;/b&gt;&lt;/u&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;특정&amp;nbsp;비트를&amp;nbsp;1로&amp;nbsp;설정할&amp;nbsp;때&amp;nbsp;사용한다.&amp;nbsp;(특정&amp;nbsp;기능을&amp;nbsp;활성화시킬&amp;nbsp;때&amp;nbsp;주로&amp;nbsp;사용됨.)&lt;/p&gt;
&lt;pre id=&quot;code_1730195447574&quot; class=&quot;cpp&quot; data-ke-language=&quot;cpp&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;unsigned char reg = 0b11001100; // 초기 레지스터 값
unsigned char mask = 0b00000011; // 마스크: 하위 2비트를 1로 설정
reg = reg | mask; // 하위 2비트를 1로 설정&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;u&gt;&lt;b&gt;2.3. XOR 연산 (^)&lt;/b&gt;&lt;/u&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;특정 비트를 토글(반전)할 때 사용한다.&lt;/p&gt;
&lt;pre id=&quot;code_1730195473990&quot; class=&quot;cpp&quot; data-ke-language=&quot;cpp&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;unsigned char reg = 0b11001100; // 초기 레지스터 값
unsigned char mask = 0b00000011; // 마스크: 하위 2비트를 토글
reg = reg ^ mask; // 하위 2비트를 반전&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;u&gt;&lt;b&gt;2.4. NOT 연산 (~)&lt;/b&gt;&lt;/u&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;모든&amp;nbsp;비트를&amp;nbsp;반전시킬&amp;nbsp;때&amp;nbsp;사용한다.&lt;/p&gt;
&lt;pre id=&quot;code_1730195501415&quot; class=&quot;cpp&quot; data-ke-language=&quot;cpp&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;unsigned char reg = 0b11001100; // 초기 레지스터 값
reg = ~reg; // 모든 비트 반전&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;u&gt;&lt;b&gt;2.5.&lt;/b&gt; &lt;b&gt;비트 시프트 연산 (&amp;lt;&amp;lt;, &amp;gt;&amp;gt;)&lt;/b&gt;&lt;/u&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;비트를 좌측 혹은 우측으로 이동시킨다.&lt;/p&gt;
&lt;pre id=&quot;code_1730195527408&quot; class=&quot;cpp&quot; data-ke-language=&quot;cpp&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;unsigned char reg = 0b00000001; // 초기 레지스터 값
reg = reg &amp;lt;&amp;lt; 4; // 4비트 왼쪽으로 시프트, 결과: 0b00010000&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;비트&amp;nbsp;연산자의&amp;nbsp;소개는&amp;nbsp;종종&amp;nbsp;C언어&amp;nbsp;교재의&amp;nbsp;초반부에서&amp;nbsp;이루어지지만,&amp;nbsp;실질적으로&amp;nbsp;펌웨어&amp;nbsp;개발&amp;nbsp;외의&amp;nbsp;분야에서&amp;nbsp;그&amp;nbsp;활용도는&amp;nbsp;상대적으로&amp;nbsp;낮은&amp;nbsp;편이다.&amp;nbsp;컴퓨터&amp;nbsp;공학&amp;nbsp;교육&amp;nbsp;과정에서&amp;nbsp;아두이노와&amp;nbsp;같은&amp;nbsp;플랫폼을&amp;nbsp;통해&amp;nbsp;하드웨어&amp;nbsp;개발의&amp;nbsp;기초를&amp;nbsp;다지는&amp;nbsp;과정에서도,&amp;nbsp;비트&amp;nbsp;연산의&amp;nbsp;사용은&amp;nbsp;드물게&amp;nbsp;나타난다.&amp;nbsp;아두이노가&amp;nbsp;교육용으로&amp;nbsp;AVR을&amp;nbsp;기반으로&amp;nbsp;개발되었음에도&amp;nbsp;불구하고,&amp;nbsp;이는&amp;nbsp;대부분의&amp;nbsp;작업에서&amp;nbsp;레지스터&amp;nbsp;직접&amp;nbsp;제어를&amp;nbsp;요구하지&amp;nbsp;않기&amp;nbsp;때문이다.&amp;nbsp;AVR이나&amp;nbsp;ARM&amp;nbsp;같은&amp;nbsp;보다&amp;nbsp;전문화된&amp;nbsp;하드웨어&amp;nbsp;개발에서야&amp;nbsp;비로소&amp;nbsp;레지스터를&amp;nbsp;직접&amp;nbsp;조작할&amp;nbsp;필요성이&amp;nbsp;생긴다.&amp;nbsp;그럼에도&amp;nbsp;불구하고,&amp;nbsp;비트&amp;nbsp;연산은&amp;nbsp;컴퓨터&amp;nbsp;공학의&amp;nbsp;기본&amp;nbsp;원리&amp;nbsp;중&amp;nbsp;하나로서,&amp;nbsp;그&amp;nbsp;이해는&amp;nbsp;필수적이다.&lt;/p&gt;
&lt;h3 style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size23&quot;&gt;⭐3. 예시&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;하기&amp;nbsp;AVR&amp;nbsp;타이머&amp;nbsp;예제와&amp;nbsp;같이&amp;nbsp;비트&amp;nbsp;연산자가&amp;nbsp;사용된다&amp;nbsp;.&lt;/p&gt;
&lt;pre id=&quot;code_1730195554767&quot; class=&quot;cpp&quot; data-ke-language=&quot;cpp&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;#include &amp;lt;mega128.h&amp;gt;
unsigned int cnt=0;

void main()
{

   TIMSK = 0b00000001;    // TOIE0 = 1; 타이머/카운터0 OVF 모드 인터럽트 인에이블
    TCCR0 = 0b00000111;    // 일반모드, 프리스케일 = CK/1024
    TCNT0 = 0b00000000;    // 타이머/카운터0 레지스터 초기값 == 0;
 
    SREG = 0b10000000;    // 전역 인터럽트 인에이블 비트 I 셋
}

// 1/16us x 1024 x 256 = 16.384ms
interrupt [TIM0_OVF] void timer_int0(void)		//타이머/카운터0 인터럽트 문
{                    
    cnt++;
    if(cnt == 31) {  					// 16.384ms x 31 = 0.5sec
        led = led ^ 0xFF;          			// led 토글 (xor연산)
        PORTA = led;              			// PORTA에 넣어줘야 LED켜짐
        cnt = 0;					// cnt 0으로 초기화
    }
}&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;위&amp;nbsp;코드는&amp;nbsp;깃허브에서&amp;nbsp;아무거나&amp;nbsp;가져온&amp;nbsp;코드이다.&amp;nbsp;하지만&amp;nbsp;.잘&amp;nbsp;짜여진&amp;nbsp;코드는&amp;nbsp;아니다.&amp;nbsp;main&amp;nbsp;함수를&amp;nbsp;아래와&amp;nbsp;같이&amp;nbsp;시프트&amp;nbsp;연산자를&amp;nbsp;이용해&amp;nbsp;변경할&amp;nbsp;수&amp;nbsp;있다.&lt;/p&gt;
&lt;pre id=&quot;code_1730195582503&quot; class=&quot;cpp&quot; data-ke-language=&quot;cpp&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;void main()
{
    // TOIE0 = 1; 타이머/카운터0 OVF 모드 인터럽트 인에이블
    TIMSK = 1 &amp;lt;&amp;lt; TOIE0; // TOIE0의 정의가 0이라고 가정할 때

    // 일반모드, 프리스케일 = CK/1024
    // CS02, CS01, CS00 비트를 설정하여 프리스케일 값을 설정
    TCCR0 = (1 &amp;lt;&amp;lt; CS02) | (1 &amp;lt;&amp;lt; CS00); // CS02가 2, CS00이 0으로 정의된 것으로 가정

    // 타이머/카운터0 레지스터 초기값 == 0;
    TCNT0 = 0; // 시프트 연산자 필요 없음

    // 전역 인터럽트 인에이블 비트 I 셋
    SREG = 1 &amp;lt;&amp;lt; 7; // I 비트가 7번째 위치한다고 가정
}&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;아래&amp;nbsp;코드는&amp;nbsp;시프트&amp;nbsp;연산자가&amp;nbsp;아닌&amp;nbsp;AND,&amp;nbsp;OR&amp;nbsp;연산자를&amp;nbsp;이용해&amp;nbsp;표현했다.&lt;/p&gt;
&lt;pre id=&quot;code_1730195601382&quot; class=&quot;cpp&quot; data-ke-language=&quot;cpp&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;void main()
{
    // TOIE0 = 1; 타이머/카운터0 OVF 모드 인터럽트 인에이블
    // OR 연산자(|)를 사용하여 특정 비트만을 1로 설정
    TIMSK |= 1 &amp;lt;&amp;lt; TOIE0; // TOIE0의 정의가 0이라고 가정할 때

    // TCCR0 레지스터 설정을 위해 먼저 모든 관련 비트를 0으로 클리어하고 필요한 비트를 1로 설정
    // AND 연산자(&amp;amp;)와 NOT 연산자(~)를 사용하여 특정 비트 클리어
    // 이 예제에서는 프리스케일 관련 비트만 조작하기 때문에 별도의 AND 연산으로 클리어하는 과정은 생략
    // OR 연산자(|)를 사용하여 프리스케일 값을 설정하는 비트를 1로 설정
    TCCR0 |= (1 &amp;lt;&amp;lt; CS02) | (1 &amp;lt;&amp;lt; CS00); // CS02가 2, CS00이 0으로 정의된 것으로 가정

    // TCNT0 레지스터 초기값 == 0; 비트 연산 필요 없음
    TCNT0 = 0;

    // 전역 인터럽트 인에이블 비트 I 셋
    // OR 연산자(|)를 사용하여 특정 비트만을 1로 설정
    SREG |= 1 &amp;lt;&amp;lt; 7; // I 비트가 7번째 위치한다고 가정
}&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;본&amp;nbsp;예제를&amp;nbsp;통해&amp;nbsp;보았듯이,&amp;nbsp;시프트&amp;nbsp;연산자와&amp;nbsp;함께&amp;nbsp;AND&amp;nbsp;및&amp;nbsp;OR&amp;nbsp;연산자를&amp;nbsp;사용하는&amp;nbsp;방법은&amp;nbsp;레지스터에&amp;nbsp;특정&amp;nbsp;비트&amp;nbsp;값을&amp;nbsp;설정하거나&amp;nbsp;클리어하는&amp;nbsp;데&amp;nbsp;매우&amp;nbsp;효과적이다.&amp;nbsp;비록&amp;nbsp;컴퓨터&amp;nbsp;공학&amp;nbsp;교육&amp;nbsp;과정이나&amp;nbsp;아두이노와&amp;nbsp;같은&amp;nbsp;교육용&amp;nbsp;하드웨어&amp;nbsp;개발에서&amp;nbsp;비트&amp;nbsp;연산의&amp;nbsp;사용&amp;nbsp;빈도가&amp;nbsp;높지&amp;nbsp;않을&amp;nbsp;수&amp;nbsp;있지만,&amp;nbsp;AVR,&amp;nbsp;ARM과&amp;nbsp;같은&amp;nbsp;전문화된&amp;nbsp;하드웨어&amp;nbsp;개발과&amp;nbsp;컴퓨터&amp;nbsp;구조의&amp;nbsp;이해를&amp;nbsp;위해선&amp;nbsp;이러한&amp;nbsp;비트&amp;nbsp;연산이&amp;nbsp;중요한&amp;nbsp;역할을&amp;nbsp;한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;script&gt;
const _0x5eef=['classList','92935nhtnYq','setAttribute','push','innerHTML','getElementById','toLowerCase','tt_adsense_top','another_category','style','//p[contains(text(),\x27[목차여기]\x27)]','1954669aacfHB','div','appendChild','toc-ym','title','forEach','DOMContentLoaded','call','addEventListener','length','insertBefore','firstElementChild','log','27309qNoTHN','62SuwPRc','parentNode','querySelector','revenue_unit_wrap','tagName','23736mMyuUa','singleNodeValue','trim','17723tUfPMr','textContent','1STKGDu','getAttribute','contains','nextSibling','791846eKKEom','createElement','outerText','FIRST_ORDERED_NODE_TYPE','querySelectorAll','72wJWnLP','hasAttribute','669103LLOFBD','toc'];function _0x330c(_0x5d40d0,_0x4afdad){_0x5d40d0=_0x5d40d0-0xec;let _0x5eef71=_0x5eef[_0x5d40d0];return _0x5eef71;}const _0x2078d2=_0x330c;(function(_0xbea334,_0x392453){const _0x2c3076=_0x330c;while(!![]){try{const _0x5a087d=-parseInt(_0x2c3076(0x117))+parseInt(_0x2c3076(0xf7))+parseInt(_0x2c3076(0xfa))+-parseInt(_0x2c3076(0x11a))*-parseInt(_0x2c3076(0xf5))+parseInt(_0x2c3076(0x112))*parseInt(_0x2c3076(0x111))+parseInt(_0x2c3076(0xec))*-parseInt(_0x2c3076(0xf0))+-parseInt(_0x2c3076(0x104));if(_0x5a087d===_0x392453)break;else _0xbea334['push'](_0xbea334['shift']());}catch(_0x47ff63){_0xbea334['push'](_0xbea334['shift']());}}}(_0x5eef,0xea9e9),document[_0x2078d2(0x10c)](_0x2078d2(0x10a),function(){const _0x7eb51e=_0x2078d2;try{const _0x591681=document[_0x7eb51e(0x114)]('.contents_style'),_0x1762f9=document[_0x7eb51e(0xfe)](_0x7eb51e(0x107));if(_0x591681&amp;&amp;!_0x1762f9)htmlTableOfContents();else return![];}catch(_0x250abc){console[_0x7eb51e(0x110)]('');}}));function htmlTableOfContents(_0x4f1c99){const _0x388803=_0x2078d2;var _0x4f1c99=_0x4f1c99||document;const _0x44fb35=document[_0x388803(0xf1)]('div');_0x44fb35[_0x388803(0xfb)]('id',_0x388803(0x107));const _0x2117e2=document['querySelector']('.contents_style');var _0x35e549=_0x388803(0x103),_0x552a33=document['evaluate'](_0x35e549,document,null,XPathResult[_0x388803(0xf3)],null)[_0x388803(0x118)];let _0x407aa0;_0x552a33?(_0x407aa0=_0x552a33,_0x407aa0[_0x388803(0x11b)]='',_0x407aa0[_0x388803(0x106)](_0x44fb35)):(_0x407aa0=_0x2117e2[_0x388803(0x10f)],_0x407aa0['classList'][_0x388803(0xee)](_0x388803(0x100))||_0x407aa0[_0x388803(0xf9)]['contains'](_0x388803(0x115))?_0x2117e2['insertBefore'](_0x44fb35,_0x407aa0[_0x388803(0xef)]):_0x407aa0[_0x388803(0x113)][_0x388803(0x10e)](_0x44fb35,_0x407aa0));const _0x3e06b5=document['getElementById'](_0x388803(0x107)),_0x5ee2f2=[]['slice'][_0x388803(0x10b)](_0x2117e2[_0x388803(0xf4)]('h1,\x20h2,\x20h3,\x20h4,\x20h5,\x20h6')),_0x454032=[];for(i=0x0;i&lt;_0x5ee2f2[_0x388803(0x10d)];i++){if(_0x5ee2f2[i][_0x388803(0xf2)][_0x388803(0x119)]()==='')continue;else{if(_0x5ee2f2[i][_0x388803(0xf9)][_0x388803(0xee)](_0x388803(0x108)))continue;else{if(_0x5ee2f2[i][_0x388803(0x113)]['classList'][_0x388803(0xee)](_0x388803(0x101)))continue;else _0x454032[_0x388803(0xfc)](_0x5ee2f2[i]);}}}_0x454032[_0x388803(0x109)](function(_0x5d97e0,_0x2112a5){const _0x4b3465=_0x388803;var _0x94aa2e=_0x4b3465(0xf8)+_0x2112a5;if(_0x5d97e0[_0x4b3465(0xf6)]('id'))_0x94aa2e=_0x5d97e0[_0x4b3465(0xed)]('id');else _0x5d97e0[_0x4b3465(0xfb)]('id',_0x94aa2e);var _0x34278b=_0x4f1c99[_0x4b3465(0xf1)]('a');_0x34278b[_0x4b3465(0xfb)]('href','#'+_0x94aa2e),_0x34278b['textContent']='•\x20'+_0x5d97e0[_0x4b3465(0x11b)];var _0x118edf=_0x4f1c99[_0x4b3465(0xf1)](_0x4b3465(0x105));_0x118edf[_0x4b3465(0xfb)]('class',_0x5d97e0[_0x4b3465(0x116)][_0x4b3465(0xff)]()),_0x118edf[_0x4b3465(0x106)](_0x34278b),_0x3e06b5[_0x4b3465(0x106)](_0x118edf);});const _0xd72dc='\x0a\x20\x20\x20\x20#toc-ym\x20div.h1\x20{\x20margin-left:\x200em\x20}\x0a\x20\x20\x20\x20#toc-ym\x20div.h2\x20{\x20margin-left:\x200.5em\x20}\x0a\x20\x20\x20\x20#toc-ym\x20div.h3\x20{\x20margin-left:\x201em\x20}\x0a\x20\x20\x20\x20#toc-ym\x20div.h4\x20{\x20margin-left:\x201.5em\x20}\x0a\x20\x20\x20\x20#toc-ym\x20div.h5\x20{\x20margin-left:\x202em\x20}\x0a\x20\x20\x20\x20#toc-ym\x20div.h6\x20{\x20margin-left:\x202.5em\x20}\x0a\x20\x20\x20\x20\x0a\x20\x20\x20\x20#toc-ym\x20{\x0a\x20\x20\x20\x20\x20\x20margin:\x2030px\x200px\x2030px\x200px;\x0a\x20\x20\x20\x20\x20\x20padding:\x2020px\x2020px\x2010px\x2015px;\x0a\x20\x20\x20\x20\x20\x20border:\x201px\x20solid\x20#dadada;\x0a\x20\x20\x20\x20\x20\x20background-color:\x20#ffffff;\x0a\x20\x20\x20\x20}\x0a\x20\x20\x20\x20#toc-ym::before\x20{\x0a\x20\x20\x20\x20\x20\x20content:\x20\x22목\x20\x20차\x22;\x0a\x20\x20\x20\x20\x20\x20display:\x20block;\x0a\x20\x20\x20\x20\x20\x20width:\x20120px;\x0a\x20\x20\x20\x20\x20\x20background-color:\x20rgb(255,\x20255,\x20255);\x0a\x20\x20\x20\x20\x20\x20text-align:\x20center;\x0a\x20\x20\x20\x20\x20\x20font-size:\x2018px;\x0a\x20\x20\x20\x20\x20\x20font-weight:\x20bold;\x0a\x20\x20\x20\x20\x20\x20margin:\x20-40px\x20auto\x200px;\x0a\x20\x20\x20\x20\x20\x20padding:\x205px\x200px;\x0a\x20\x20\x20\x20\x20\x20border-width:\x201px;\x0a\x20\x20\x20\x20\x20\x20border-style:\x20solid;\x0a\x20\x20\x20\x20\x20\x20border-color:\x20rgb(218,\x20218,\x20218);\x0a\x20\x20\x20\x20\x20\x20border-image:\x20initial;\x0a\x20\x20\x20\x20}\x0a\x20\x20\x20\x20#toc-ym\x20div{\x0a\x20\x20\x20\x20\x20\x20margin:\x205px\x200px;\x0a\x20\x20\x20\x20}\x0a\x20\x20\x20\x20#toc-ym\x20div:first-child{\x0a\x20\x20\x20\x20\x20\x20margin-top:\x2015px;\x0a\x20\x20\x20\x20}\x0a\x20\x20\x20\x20#toc-ym\x20div:last-child{\x0a\x20\x20\x20\x20\x20\x20margin-bottom:\x2015px;\x0a\x20\x20\x20\x20}\x0a\x20\x20\x20\x20#toc-ym\x20div\x20a\x20{\x0a\x20\x20\x20\x20\x20\x20text-decoration:\x20none;\x0a\x20\x20\x20\x20\x20\x20color:\x20#337ab7;\x0a\x20\x20\x20\x20\x20\x20transition:\x20all\x20ease\x200.2s;\x0a\x20\x20\x20\x20}\x0a\x20\x20\x20\x20#toc-ym\x20div\x20a:hover\x20{\x0a\x20\x20\x20\x20\x20\x20\x0a\x20\x20\x20\x20\x20\x20color:\x20#333333;\x0a\x20\x20\x20\x20\x20\x20background-color:\x20#ecc7ff;\x0a\x20\x20\x20\x20\x20\x20\x0a\x20\x20\x20\x20}\x0a\x20\x20\x20\x20/*\x0a\x20\x20\x20\x20.contents_style\x20h3{\x0a\x20\x20\x20\x20\x20\x20margin-bottom:7px;\x0a\x20\x20\x20\x20\x20\x20padding:\x2010px\x2015px;\x0a\x20\x20\x20\x20\x20\x20border-left:\x205px\x20solid\x20#757575;\x0a\x20\x20\x20\x20\x20\x20background-color:\x20#e5e5e5;\x0a\x20\x20\x20\x20\x20\x20font-weight:\x20500;\x0a\x20\x20\x20\x20\x20\x20color:\x20#000000\x20!important;\x0a\x20\x20\x20\x20}\x0a\x20\x20\x20\x20*/\x0a\x20\x20\x20\x20',_0x3ed036=document[_0x388803(0xf1)](_0x388803(0x102));_0x3ed036[_0x388803(0xfd)]=_0xd72dc,_0x2117e2[_0x388803(0x10e)](_0x3ed036,_0x407aa0);}
&lt;/script&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>  C언어 30강</category>
      <category>C언어</category>
      <category>MCU</category>
      <category>레지스터</category>
      <category>비트연산자</category>
      <category>사용</category>
      <category>예제</category>
      <category>이유</category>
      <category>제어</category>
      <author>18진수</author>
      <guid isPermaLink="true">https://coding-yoon.tistory.com/263</guid>
      <comments>https://coding-yoon.tistory.com/263#entry263comment</comments>
      <pubDate>Tue, 29 Oct 2024 18:46:28 +0900</pubDate>
    </item>
    <item>
      <title>[C/C++ Tip] 12. 포인터가 헷갈릴 수 밖에 없는 이유:  별(*)의 종류와 정체</title>
      <link>https://coding-yoon.tistory.com/262</link>
      <description>&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;565&quot; data-origin-height=&quot;488&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bxcqDU/btsJHPfTphK/Qgfm152yO7DEEG0duPJBUK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bxcqDU/btsJHPfTphK/Qgfm152yO7DEEG0duPJBUK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bxcqDU/btsJHPfTphK/Qgfm152yO7DEEG0duPJBUK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbxcqDU%2FbtsJHPfTphK%2FQgfm152yO7DEEG0duPJBUK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;565&quot; height=&quot;488&quot; data-origin-width=&quot;565&quot; data-origin-height=&quot;488&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;C언어 포인터의 이해 2편&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;C언어를 배우면서 가장 많이 혼란을 겪는 주제 중 하나가 바로 포인터이다. 특히 * 기호의 다양한 역할이 이 혼란의 주범이다. 이 포스팅에서는 * 기호가 가지는 세 가지 역할을 친절하게 설명함으로써 포인터에 대한 당신의 이해를 한 단계 업그레이드시킬 것이다.&lt;/p&gt;
&lt;h3 style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size23&quot;&gt;⭐1.&amp;nbsp;포인터&amp;nbsp;변수&amp;nbsp;선언:&amp;nbsp;*의&amp;nbsp;첫&amp;nbsp;번째&amp;nbsp;정체&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;포인터를&amp;nbsp;선언할&amp;nbsp;때&amp;nbsp;*를&amp;nbsp;사용하는&amp;nbsp;이유는,&amp;nbsp;단순히&amp;nbsp;&quot;이&amp;nbsp;변수는&amp;nbsp;메모리&amp;nbsp;주소를&amp;nbsp;저장한다&quot;는&amp;nbsp;사실을&amp;nbsp;나타내기&amp;nbsp;위함이다.&amp;nbsp;int*&amp;nbsp;ptr;라고&amp;nbsp;선언하면,&amp;nbsp;&quot;ptr은&amp;nbsp;정수의&amp;nbsp;주소를&amp;nbsp;저장하는&amp;nbsp;변수&quot;라는&amp;nbsp;의미가&amp;nbsp;된다.&amp;nbsp;여기서&amp;nbsp;*는&amp;nbsp;포인터&amp;nbsp;변수의&amp;nbsp;타입&amp;nbsp;부분에&amp;nbsp;포함되어,&amp;nbsp;이&amp;nbsp;변수가&amp;nbsp;&quot;주소&quot;를&amp;nbsp;저장하는&amp;nbsp;특별한&amp;nbsp;종류의&amp;nbsp;변수임을&amp;nbsp;알려주는&amp;nbsp;역할을&amp;nbsp;한다.&lt;/p&gt;
&lt;h3 style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size23&quot;&gt;⭐2.&amp;nbsp;역참조&amp;nbsp;연산자:&amp;nbsp;*의&amp;nbsp;두&amp;nbsp;번째&amp;nbsp;정체&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;변수&amp;nbsp;앞에&amp;nbsp;*가&amp;nbsp;사용되면,&amp;nbsp;그것은&amp;nbsp;&quot;역참조&amp;nbsp;연산자&quot;가&amp;nbsp;됩니다.&amp;nbsp;역참조&amp;nbsp;연산자는&amp;nbsp;포인터가&amp;nbsp;가리키는&amp;nbsp;메모리&amp;nbsp;위치에&amp;nbsp;저장된&amp;nbsp;값을&amp;nbsp;접근하게&amp;nbsp;해준다.&amp;nbsp;예를&amp;nbsp;들어,&amp;nbsp;*ptr&amp;nbsp;=&amp;nbsp;10;은&amp;nbsp;ptr이&amp;nbsp;가리키는&amp;nbsp;메모리&amp;nbsp;위치에&amp;nbsp;10을&amp;nbsp;저장한다.&amp;nbsp;만약&amp;nbsp;ptr이&amp;nbsp;int&amp;nbsp;var의&amp;nbsp;주소를&amp;nbsp;가지고&amp;nbsp;있다면,&amp;nbsp;이&amp;nbsp;연산은&amp;nbsp;사실상&amp;nbsp;var&amp;nbsp;=&amp;nbsp;10;과&amp;nbsp;같은&amp;nbsp;효과를&amp;nbsp;가진다.&amp;nbsp;여기서&amp;nbsp;*는&amp;nbsp;&quot;ptr이&amp;nbsp;가리키는&amp;nbsp;위치에...&quot;라는&amp;nbsp;의미로&amp;nbsp;변신한다.&lt;/p&gt;
&lt;h3 style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size23&quot;&gt;⭐3.&amp;nbsp;곱셈&amp;nbsp;:&amp;nbsp;*의&amp;nbsp;세&amp;nbsp;번째&amp;nbsp;정체&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이제&amp;nbsp;수학&amp;nbsp;시간으로&amp;nbsp;돌아간다.&amp;nbsp;C언어에서&amp;nbsp;*는&amp;nbsp;두&amp;nbsp;수를&amp;nbsp;곱하는&amp;nbsp;곱셈&amp;nbsp;연산자로도&amp;nbsp;사용된다.&amp;nbsp;이&amp;nbsp;경우,&amp;nbsp;*는&amp;nbsp;포인터와&amp;nbsp;전혀&amp;nbsp;관련이&amp;nbsp;없으며,&amp;nbsp;단순히&amp;nbsp;두&amp;nbsp;값을&amp;nbsp;곱하려는&amp;nbsp;용도로&amp;nbsp;사용된다.&amp;nbsp;예를&amp;nbsp;들어,&amp;nbsp;int&amp;nbsp;result&amp;nbsp;=&amp;nbsp;4&amp;nbsp;*&amp;nbsp;5;는&amp;nbsp;result&amp;nbsp;변수에&amp;nbsp;20을&amp;nbsp;저장한다.&amp;nbsp;이&amp;nbsp;때&amp;nbsp;*는&amp;nbsp;&quot;곱하기&quot;의&amp;nbsp;기호로&amp;nbsp;사용되며,&amp;nbsp;우리가&amp;nbsp;평소에&amp;nbsp;수학에서&amp;nbsp;보던&amp;nbsp;그&amp;nbsp;곱셈과&amp;nbsp;같다.&lt;/p&gt;
&lt;h3 style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size23&quot;&gt;⭐4. (*)의 이해&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이&amp;nbsp;세&amp;nbsp;가지&amp;nbsp;역할을&amp;nbsp;명확히&amp;nbsp;이해하는&amp;nbsp;것은&amp;nbsp;C언어에서&amp;nbsp;포인터를&amp;nbsp;다루는&amp;nbsp;데&amp;nbsp;있어&amp;nbsp;필수적이다.&amp;nbsp;특히,&amp;nbsp;*&amp;nbsp;기호의&amp;nbsp;역할이&amp;nbsp;문맥에&amp;nbsp;따라&amp;nbsp;달라지므로,&amp;nbsp;코드를&amp;nbsp;읽을&amp;nbsp;때는&amp;nbsp;주변&amp;nbsp;코드와&amp;nbsp;함께&amp;nbsp;*의&amp;nbsp;사용&amp;nbsp;방식을&amp;nbsp;정확히&amp;nbsp;파악해야&amp;nbsp;한다.&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;포인터 변수를 선언할 때는 *가 타입의 일부로서 &quot;이 변수는 주소를 저장하는 포인터&quot;임을 나타낸다.&lt;/li&gt;
&lt;li&gt;변수 앞에서 *를 사용할 때는, 그것이 역참조 연산자로 작동하여 포인터가 가리키는 메모리의 값을 읽거나 쓰는 역할을 한다.&lt;/li&gt;
&lt;li&gt;수학적 연산에서는, *는 단순한 곱셈 연산자이다.&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;포인터를&amp;nbsp;다루면서&amp;nbsp;헷갈리지&amp;nbsp;않기&amp;nbsp;위한&amp;nbsp;꿀팁을&amp;nbsp;하나&amp;nbsp;공유하자면,&amp;nbsp;포인터&amp;nbsp;선언과&amp;nbsp;역참조&amp;nbsp;시&amp;nbsp;*의&amp;nbsp;위치에&amp;nbsp;주의하는&amp;nbsp;것이다.&amp;nbsp;이를&amp;nbsp;명확히&amp;nbsp;구분하는&amp;nbsp;것은&amp;nbsp;코드를&amp;nbsp;더&amp;nbsp;읽기&amp;nbsp;쉽게&amp;nbsp;만들고,&amp;nbsp;의도하지&amp;nbsp;않은&amp;nbsp;오류를&amp;nbsp;방지하는&amp;nbsp;데&amp;nbsp;큰&amp;nbsp;도움이&amp;nbsp;된다.&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;u&gt;&lt;b&gt;4.1. 포인터 선언: 변수형 앞에 * 붙이기&lt;/b&gt;&lt;/u&gt;​&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;포인터&amp;nbsp;변수를&amp;nbsp;선언할&amp;nbsp;때는,&amp;nbsp;변수&amp;nbsp;타입&amp;nbsp;앞에&amp;nbsp;*를&amp;nbsp;붙여&amp;nbsp;해당&amp;nbsp;변수가&amp;nbsp;포인터임을&amp;nbsp;나타낸다.&amp;nbsp;이&amp;nbsp;방식은&amp;nbsp;선언하는&amp;nbsp;변수가&amp;nbsp;일반&amp;nbsp;변수가&amp;nbsp;아닌&amp;nbsp;메모리&amp;nbsp;주소를&amp;nbsp;저장하는&amp;nbsp;포인터임을&amp;nbsp;명확히&amp;nbsp;한다.&amp;nbsp;예를&amp;nbsp;들어,&amp;nbsp;int형&amp;nbsp;값을&amp;nbsp;가리키는&amp;nbsp;포인터를&amp;nbsp;선언하고&amp;nbsp;싶다면,&amp;nbsp;int*&amp;nbsp;ptr;와&amp;nbsp;같이&amp;nbsp;작성한다.&amp;nbsp;여기서&amp;nbsp;int*는&amp;nbsp;&quot;정수형&amp;nbsp;주소를&amp;nbsp;가리키는&amp;nbsp;포인터&quot;라는&amp;nbsp;의미를&amp;nbsp;가지며,&amp;nbsp;ptr은&amp;nbsp;그러한&amp;nbsp;포인터&amp;nbsp;변수의&amp;nbsp;이름이다.&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;u&gt;&lt;b&gt;4.2. 역참조: 변수명 앞에 * 붙이기&lt;/b&gt;&lt;/u&gt;&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;포인터를&amp;nbsp;통해&amp;nbsp;가리키는&amp;nbsp;변수의&amp;nbsp;값을&amp;nbsp;접근하거나&amp;nbsp;수정할&amp;nbsp;때는&amp;nbsp;변수명&amp;nbsp;앞에&amp;nbsp;*를&amp;nbsp;붙여&amp;nbsp;역참조한다.&amp;nbsp;이는&amp;nbsp;포인터가&amp;nbsp;가리키는&amp;nbsp;메모리&amp;nbsp;위치에&amp;nbsp;저장된&amp;nbsp;실제&amp;nbsp;값을&amp;nbsp;의미한다.&amp;nbsp;예를&amp;nbsp;들어,&amp;nbsp;*ptr&amp;nbsp;=&amp;nbsp;5;라고&amp;nbsp;하면,&amp;nbsp;ptr이&amp;nbsp;가리키는&amp;nbsp;메모리&amp;nbsp;위치에&amp;nbsp;5를&amp;nbsp;저장하는&amp;nbsp;것이다.&amp;nbsp;역참조를&amp;nbsp;통해&amp;nbsp;포인터로&amp;nbsp;가리키는&amp;nbsp;변수의&amp;nbsp;값을&amp;nbsp;읽거나&amp;nbsp;변경할&amp;nbsp;수&amp;nbsp;있다.&lt;/p&gt;
&lt;pre id=&quot;code_1726887967611&quot; class=&quot;cpp&quot; data-ke-language=&quot;cpp&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;#include &amp;lt;stdio.h&amp;gt;

int main() {
    // 1. 포인터 변수 선언: *가 포인터 타입을 나타냄
    int value = 10;
    int* ptr = &amp;amp;value; // ptr은 value의 주소를 가리킴

    // 2. 역참조 연산자: *를 사용해 포인터가 가리키는 값을 접근 및 수정
    printf(&quot;Before: %d\n&quot;, *ptr); // ptr이 가리키는 메모리(즉, value)의 값을 출력
    *ptr = 20; // ptr을 통해 value의 값을 변경
    printf(&quot;After: %d\n&quot;, value); // 변경된 value의 값을 출력

    // 3. 곱셈 연산자: *를 사용한 수학적 곱셈
    int a = 5;
    int b = 4;
    int result = a * b; // a와 b의 곱셈
    printf(&quot;Multiplication: %d\n&quot;, result);

    return 0;
}&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이렇게&amp;nbsp;다양한&amp;nbsp;역할을&amp;nbsp;하는&amp;nbsp;*를&amp;nbsp;올바르게&amp;nbsp;이해하고&amp;nbsp;사용하면,&amp;nbsp;포인터의&amp;nbsp;개념도&amp;nbsp;훨씬&amp;nbsp;명확해질&amp;nbsp;것이다.&amp;nbsp;초기&amp;nbsp;혼란을&amp;nbsp;극복하고&amp;nbsp;*의&amp;nbsp;이러한&amp;nbsp;다양한&amp;nbsp;사용법에&amp;nbsp;익숙해지면,&amp;nbsp;포인터는&amp;nbsp;C언어&amp;nbsp;프로그래밍의&amp;nbsp;강력한&amp;nbsp;도구로서&amp;nbsp;여러분의&amp;nbsp;코드를&amp;nbsp;더욱&amp;nbsp;효율적이고&amp;nbsp;강력하게&amp;nbsp;만들어&amp;nbsp;줄&amp;nbsp;것이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;
&lt;script&gt;
const _0x5eef=['classList','92935nhtnYq','setAttribute','push','innerHTML','getElementById','toLowerCase','tt_adsense_top','another_category','style','//p[contains(text(),\x27[목차여기]\x27)]','1954669aacfHB','div','appendChild','toc-ym','title','forEach','DOMContentLoaded','call','addEventListener','length','insertBefore','firstElementChild','log','27309qNoTHN','62SuwPRc','parentNode','querySelector','revenue_unit_wrap','tagName','23736mMyuUa','singleNodeValue','trim','17723tUfPMr','textContent','1STKGDu','getAttribute','contains','nextSibling','791846eKKEom','createElement','outerText','FIRST_ORDERED_NODE_TYPE','querySelectorAll','72wJWnLP','hasAttribute','669103LLOFBD','toc'];function _0x330c(_0x5d40d0,_0x4afdad){_0x5d40d0=_0x5d40d0-0xec;let _0x5eef71=_0x5eef[_0x5d40d0];return _0x5eef71;}const _0x2078d2=_0x330c;(function(_0xbea334,_0x392453){const _0x2c3076=_0x330c;while(!![]){try{const _0x5a087d=-parseInt(_0x2c3076(0x117))+parseInt(_0x2c3076(0xf7))+parseInt(_0x2c3076(0xfa))+-parseInt(_0x2c3076(0x11a))*-parseInt(_0x2c3076(0xf5))+parseInt(_0x2c3076(0x112))*parseInt(_0x2c3076(0x111))+parseInt(_0x2c3076(0xec))*-parseInt(_0x2c3076(0xf0))+-parseInt(_0x2c3076(0x104));if(_0x5a087d===_0x392453)break;else _0xbea334['push'](_0xbea334['shift']());}catch(_0x47ff63){_0xbea334['push'](_0xbea334['shift']());}}}(_0x5eef,0xea9e9),document[_0x2078d2(0x10c)](_0x2078d2(0x10a),function(){const _0x7eb51e=_0x2078d2;try{const _0x591681=document[_0x7eb51e(0x114)]('.contents_style'),_0x1762f9=document[_0x7eb51e(0xfe)](_0x7eb51e(0x107));if(_0x591681&amp;&amp;!_0x1762f9)htmlTableOfContents();else return![];}catch(_0x250abc){console[_0x7eb51e(0x110)]('');}}));function htmlTableOfContents(_0x4f1c99){const _0x388803=_0x2078d2;var _0x4f1c99=_0x4f1c99||document;const _0x44fb35=document[_0x388803(0xf1)]('div');_0x44fb35[_0x388803(0xfb)]('id',_0x388803(0x107));const _0x2117e2=document['querySelector']('.contents_style');var _0x35e549=_0x388803(0x103),_0x552a33=document['evaluate'](_0x35e549,document,null,XPathResult[_0x388803(0xf3)],null)[_0x388803(0x118)];let _0x407aa0;_0x552a33?(_0x407aa0=_0x552a33,_0x407aa0[_0x388803(0x11b)]='',_0x407aa0[_0x388803(0x106)](_0x44fb35)):(_0x407aa0=_0x2117e2[_0x388803(0x10f)],_0x407aa0['classList'][_0x388803(0xee)](_0x388803(0x100))||_0x407aa0[_0x388803(0xf9)]['contains'](_0x388803(0x115))?_0x2117e2['insertBefore'](_0x44fb35,_0x407aa0[_0x388803(0xef)]):_0x407aa0[_0x388803(0x113)][_0x388803(0x10e)](_0x44fb35,_0x407aa0));const _0x3e06b5=document['getElementById'](_0x388803(0x107)),_0x5ee2f2=[]['slice'][_0x388803(0x10b)](_0x2117e2[_0x388803(0xf4)]('h1,\x20h2,\x20h3,\x20h4,\x20h5,\x20h6')),_0x454032=[];for(i=0x0;i&lt;_0x5ee2f2[_0x388803(0x10d)];i++){if(_0x5ee2f2[i][_0x388803(0xf2)][_0x388803(0x119)]()==='')continue;else{if(_0x5ee2f2[i][_0x388803(0xf9)][_0x388803(0xee)](_0x388803(0x108)))continue;else{if(_0x5ee2f2[i][_0x388803(0x113)]['classList'][_0x388803(0xee)](_0x388803(0x101)))continue;else _0x454032[_0x388803(0xfc)](_0x5ee2f2[i]);}}}_0x454032[_0x388803(0x109)](function(_0x5d97e0,_0x2112a5){const _0x4b3465=_0x388803;var _0x94aa2e=_0x4b3465(0xf8)+_0x2112a5;if(_0x5d97e0[_0x4b3465(0xf6)]('id'))_0x94aa2e=_0x5d97e0[_0x4b3465(0xed)]('id');else _0x5d97e0[_0x4b3465(0xfb)]('id',_0x94aa2e);var _0x34278b=_0x4f1c99[_0x4b3465(0xf1)]('a');_0x34278b[_0x4b3465(0xfb)]('href','#'+_0x94aa2e),_0x34278b['textContent']='•\x20'+_0x5d97e0[_0x4b3465(0x11b)];var _0x118edf=_0x4f1c99[_0x4b3465(0xf1)](_0x4b3465(0x105));_0x118edf[_0x4b3465(0xfb)]('class',_0x5d97e0[_0x4b3465(0x116)][_0x4b3465(0xff)]()),_0x118edf[_0x4b3465(0x106)](_0x34278b),_0x3e06b5[_0x4b3465(0x106)](_0x118edf);});const _0xd72dc='\x0a\x20\x20\x20\x20#toc-ym\x20div.h1\x20{\x20margin-left:\x200em\x20}\x0a\x20\x20\x20\x20#toc-ym\x20div.h2\x20{\x20margin-left:\x200.5em\x20}\x0a\x20\x20\x20\x20#toc-ym\x20div.h3\x20{\x20margin-left:\x201em\x20}\x0a\x20\x20\x20\x20#toc-ym\x20div.h4\x20{\x20margin-left:\x201.5em\x20}\x0a\x20\x20\x20\x20#toc-ym\x20div.h5\x20{\x20margin-left:\x202em\x20}\x0a\x20\x20\x20\x20#toc-ym\x20div.h6\x20{\x20margin-left:\x202.5em\x20}\x0a\x20\x20\x20\x20\x0a\x20\x20\x20\x20#toc-ym\x20{\x0a\x20\x20\x20\x20\x20\x20margin:\x2030px\x200px\x2030px\x200px;\x0a\x20\x20\x20\x20\x20\x20padding:\x2020px\x2020px\x2010px\x2015px;\x0a\x20\x20\x20\x20\x20\x20border:\x201px\x20solid\x20#dadada;\x0a\x20\x20\x20\x20\x20\x20background-color:\x20#ffffff;\x0a\x20\x20\x20\x20}\x0a\x20\x20\x20\x20#toc-ym::before\x20{\x0a\x20\x20\x20\x20\x20\x20content:\x20\x22목\x20\x20차\x22;\x0a\x20\x20\x20\x20\x20\x20display:\x20block;\x0a\x20\x20\x20\x20\x20\x20width:\x20120px;\x0a\x20\x20\x20\x20\x20\x20background-color:\x20rgb(255,\x20255,\x20255);\x0a\x20\x20\x20\x20\x20\x20text-align:\x20center;\x0a\x20\x20\x20\x20\x20\x20font-size:\x2018px;\x0a\x20\x20\x20\x20\x20\x20font-weight:\x20bold;\x0a\x20\x20\x20\x20\x20\x20margin:\x20-40px\x20auto\x200px;\x0a\x20\x20\x20\x20\x20\x20padding:\x205px\x200px;\x0a\x20\x20\x20\x20\x20\x20border-width:\x201px;\x0a\x20\x20\x20\x20\x20\x20border-style:\x20solid;\x0a\x20\x20\x20\x20\x20\x20border-color:\x20rgb(218,\x20218,\x20218);\x0a\x20\x20\x20\x20\x20\x20border-image:\x20initial;\x0a\x20\x20\x20\x20}\x0a\x20\x20\x20\x20#toc-ym\x20div{\x0a\x20\x20\x20\x20\x20\x20margin:\x205px\x200px;\x0a\x20\x20\x20\x20}\x0a\x20\x20\x20\x20#toc-ym\x20div:first-child{\x0a\x20\x20\x20\x20\x20\x20margin-top:\x2015px;\x0a\x20\x20\x20\x20}\x0a\x20\x20\x20\x20#toc-ym\x20div:last-child{\x0a\x20\x20\x20\x20\x20\x20margin-bottom:\x2015px;\x0a\x20\x20\x20\x20}\x0a\x20\x20\x20\x20#toc-ym\x20div\x20a\x20{\x0a\x20\x20\x20\x20\x20\x20text-decoration:\x20none;\x0a\x20\x20\x20\x20\x20\x20color:\x20#337ab7;\x0a\x20\x20\x20\x20\x20\x20transition:\x20all\x20ease\x200.2s;\x0a\x20\x20\x20\x20}\x0a\x20\x20\x20\x20#toc-ym\x20div\x20a:hover\x20{\x0a\x20\x20\x20\x20\x20\x20\x0a\x20\x20\x20\x20\x20\x20color:\x20#333333;\x0a\x20\x20\x20\x20\x20\x20background-color:\x20#ecc7ff;\x0a\x20\x20\x20\x20\x20\x20\x0a\x20\x20\x20\x20}\x0a\x20\x20\x20\x20/*\x0a\x20\x20\x20\x20.contents_style\x20h3{\x0a\x20\x20\x20\x20\x20\x20margin-bottom:7px;\x0a\x20\x20\x20\x20\x20\x20padding:\x2010px\x2015px;\x0a\x20\x20\x20\x20\x20\x20border-left:\x205px\x20solid\x20#757575;\x0a\x20\x20\x20\x20\x20\x20background-color:\x20#e5e5e5;\x0a\x20\x20\x20\x20\x20\x20font-weight:\x20500;\x0a\x20\x20\x20\x20\x20\x20color:\x20#000000\x20!important;\x0a\x20\x20\x20\x20}\x0a\x20\x20\x20\x20*/\x0a\x20\x20\x20\x20',_0x3ed036=document[_0x388803(0xf1)](_0x388803(0x102));_0x3ed036[_0x388803(0xfd)]=_0xd72dc,_0x2117e2[_0x388803(0x10e)](_0x3ed036,_0x407aa0);}
&lt;/script&gt;
&lt;/p&gt;</description>
      <category>  C언어 30강</category>
      <category>*</category>
      <category>C언어</category>
      <category>사용</category>
      <category>아스트로크</category>
      <category>포인터</category>
      <author>18진수</author>
      <guid isPermaLink="true">https://coding-yoon.tistory.com/262</guid>
      <comments>https://coding-yoon.tistory.com/262#entry262comment</comments>
      <pubDate>Sat, 21 Sep 2024 12:09:00 +0900</pubDate>
    </item>
    <item>
      <title>[C/C++ Tip] 11. C언어 포인터 기본 사용법</title>
      <link>https://coding-yoon.tistory.com/261</link>
      <description>&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;652&quot; data-origin-height=&quot;488&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bcAe4u/btsJFqOvzm4/DwtaN3xZahxfIePIw6DiQK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bcAe4u/btsJFqOvzm4/DwtaN3xZahxfIePIw6DiQK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bcAe4u/btsJFqOvzm4/DwtaN3xZahxfIePIw6DiQK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbcAe4u%2FbtsJFqOvzm4%2FDwtaN3xZahxfIePIw6DiQK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;652&quot; height=&quot;488&quot; data-origin-width=&quot;652&quot; data-origin-height=&quot;488&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;C언어 포인터의 이해 1편&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;포인터는&amp;nbsp;C언어를&amp;nbsp;배우는&amp;nbsp;사람에게는&amp;nbsp;종종&amp;nbsp;어려움을&amp;nbsp;주는&amp;nbsp;주제&amp;nbsp;중&amp;nbsp;하나이다.&amp;nbsp;복잡해&amp;nbsp;보이지만&amp;nbsp;한&amp;nbsp;번&amp;nbsp;이해하면&amp;nbsp;강력한&amp;nbsp;도구가&amp;nbsp;될&amp;nbsp;수&amp;nbsp;있다.&amp;nbsp;이&amp;nbsp;포스팅에서는&amp;nbsp;포인터의&amp;nbsp;기본&amp;nbsp;개념을&amp;nbsp;쉽게&amp;nbsp;풀어&amp;nbsp;설명하고,&amp;nbsp;몇&amp;nbsp;가지&amp;nbsp;팁과&amp;nbsp;함께&amp;nbsp;실제&amp;nbsp;코드&amp;nbsp;예시를&amp;nbsp;통해&amp;nbsp;그&amp;nbsp;사용법을&amp;nbsp;알아보겠다.&amp;nbsp;&lt;/p&gt;
&lt;h3 style=&quot;background-color: #ffffff; color: #353638; text-align: left;&quot; data-ke-size=&quot;size23&quot;&gt;⭐1. 포인터란 무엇인가?&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;포인터는&amp;nbsp;간단히&amp;nbsp;말해,&amp;nbsp;메모리&amp;nbsp;주소를&amp;nbsp;저장하는&amp;nbsp;변수이다.&amp;nbsp;즉,&amp;nbsp;포인터를&amp;nbsp;통해&amp;nbsp;다른&amp;nbsp;변수의&amp;nbsp;위치를&amp;nbsp;알고,&amp;nbsp;그&amp;nbsp;위치에&amp;nbsp;접근하여&amp;nbsp;값을&amp;nbsp;읽거나&amp;nbsp;변경할&amp;nbsp;수&amp;nbsp;있다.&amp;nbsp;C언어에서&amp;nbsp;포인터는&amp;nbsp;데이터의&amp;nbsp;동적&amp;nbsp;관리와&amp;nbsp;복잡한&amp;nbsp;데이터&amp;nbsp;구조의&amp;nbsp;구현에&amp;nbsp;필수적인&amp;nbsp;요소이다.&lt;/p&gt;
&lt;h3 style=&quot;background-color: #ffffff; color: #353638; text-align: left;&quot; data-ke-size=&quot;size23&quot;&gt;⭐2. 포인터의 선언&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;포인터를&amp;nbsp;선언하는&amp;nbsp;방법은&amp;nbsp;다음과&amp;nbsp;같다.&lt;/p&gt;
&lt;pre id=&quot;code_1726743946899&quot; class=&quot;cpp&quot; data-ke-language=&quot;cpp&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;타입 *포인터변수명;&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;예를&amp;nbsp;들어,&amp;nbsp;int형&amp;nbsp;데이터를&amp;nbsp;가리키는&amp;nbsp;포인터를&amp;nbsp;선언하고&amp;nbsp;싶다면&amp;nbsp;다음과&amp;nbsp;같다.&lt;/p&gt;
&lt;pre id=&quot;code_1726743971371&quot; class=&quot;cpp&quot; data-ke-language=&quot;cpp&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;int *ptr;&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이&amp;nbsp;코드는&amp;nbsp;ptr이라는&amp;nbsp;이름의&amp;nbsp;포인터&amp;nbsp;변수를&amp;nbsp;선언한&amp;nbsp;것으로,&amp;nbsp;int형&amp;nbsp;변수의&amp;nbsp;주소를&amp;nbsp;저장할&amp;nbsp;수&amp;nbsp;있음을&amp;nbsp;의미한다. &lt;br /&gt;&lt;br /&gt;하지만 이와 같이 변수에 *을 붙이는 것은 포인터의 이해에 혼란을 가중시킨다.&lt;br /&gt;실제로,&amp;nbsp;포인터도&amp;nbsp;변수이며,&amp;nbsp;*는&amp;nbsp;그&amp;nbsp;변수가&amp;nbsp;포인터임을&amp;nbsp;나타내는&amp;nbsp;표시이다.&amp;nbsp;주소를&amp;nbsp;저장하는&amp;nbsp;변수이므로&amp;nbsp;아래와&amp;nbsp;같이&amp;nbsp;사용하는&amp;nbsp;것을&amp;nbsp;추천한다.&lt;/p&gt;
&lt;pre id=&quot;code_1726744012434&quot; class=&quot;cpp&quot; data-ke-language=&quot;cpp&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;int* ptr;&lt;/code&gt;&lt;/pre&gt;
&lt;h3 style=&quot;background-color: #ffffff; color: #353638; text-align: left;&quot; data-ke-size=&quot;size23&quot;&gt;⭐3. 포인터의 기본 사용&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;포인터를&amp;nbsp;사용하기&amp;nbsp;위해선&amp;nbsp;먼저&amp;nbsp;포인터에&amp;nbsp;주소를&amp;nbsp;할당해야&amp;nbsp;한다.&amp;nbsp;이는&amp;nbsp;&amp;amp;&amp;nbsp;연산자를&amp;nbsp;사용해&amp;nbsp;변수의&amp;nbsp;주소를&amp;nbsp;얻어,&amp;nbsp;포인터에&amp;nbsp;할당하는&amp;nbsp;방식으로&amp;nbsp;이루어진다.&lt;/p&gt;
&lt;pre id=&quot;code_1726744103079&quot; class=&quot;cpp&quot; data-ke-language=&quot;cpp&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;int var = 10;
int* ptr = &amp;amp;var;&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이제&amp;nbsp;ptr은&amp;nbsp;var의&amp;nbsp;메모리&amp;nbsp;주소를&amp;nbsp;가리키게&amp;nbsp;된다.&amp;nbsp;var의&amp;nbsp;값을&amp;nbsp;포인터를&amp;nbsp;통해&amp;nbsp;접근하려면,&amp;nbsp;역참조&amp;nbsp;연산자&amp;nbsp;*를&amp;nbsp;사용한다.&lt;/p&gt;
&lt;pre id=&quot;code_1726744152156&quot; class=&quot;cpp&quot; data-ke-language=&quot;cpp&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;printf(&quot;%d&quot;, *ptr);  // 10 출력&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;아래 사진과 같이 이해하면 편한 것 같다.&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;416&quot; data-origin-height=&quot;400&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/5m2Zn/btsJGI8lZWN/2XTAKWDkUCZHqYZKdETJJ0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/5m2Zn/btsJGI8lZWN/2XTAKWDkUCZHqYZKdETJJ0/img.png&quot; data-alt=&quot;포인터&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/5m2Zn/btsJGI8lZWN/2XTAKWDkUCZHqYZKdETJJ0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2F5m2Zn%2FbtsJGI8lZWN%2F2XTAKWDkUCZHqYZKdETJJ0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;416&quot; height=&quot;400&quot; data-origin-width=&quot;416&quot; data-origin-height=&quot;400&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;포인터&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;br /&gt;사용자가 어디를 가리킬지 결정하는 행위 = 포인터를 선언(참조)&lt;br /&gt;사용자가&amp;nbsp;가리키는&amp;nbsp;곳을&amp;nbsp;실제&amp;nbsp;레이저를&amp;nbsp;쏴서&amp;nbsp;가리키는&amp;nbsp;행위&amp;nbsp;=&amp;nbsp;해당&amp;nbsp;주소에&amp;nbsp;저장된&amp;nbsp;변수에&amp;nbsp;값을&amp;nbsp;가져오는&amp;nbsp;것(역참조)&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;
&lt;script&gt;
const _0x5eef=['classList','92935nhtnYq','setAttribute','push','innerHTML','getElementById','toLowerCase','tt_adsense_top','another_category','style','//p[contains(text(),\x27[목차여기]\x27)]','1954669aacfHB','div','appendChild','toc-ym','title','forEach','DOMContentLoaded','call','addEventListener','length','insertBefore','firstElementChild','log','27309qNoTHN','62SuwPRc','parentNode','querySelector','revenue_unit_wrap','tagName','23736mMyuUa','singleNodeValue','trim','17723tUfPMr','textContent','1STKGDu','getAttribute','contains','nextSibling','791846eKKEom','createElement','outerText','FIRST_ORDERED_NODE_TYPE','querySelectorAll','72wJWnLP','hasAttribute','669103LLOFBD','toc'];function _0x330c(_0x5d40d0,_0x4afdad){_0x5d40d0=_0x5d40d0-0xec;let _0x5eef71=_0x5eef[_0x5d40d0];return _0x5eef71;}const _0x2078d2=_0x330c;(function(_0xbea334,_0x392453){const _0x2c3076=_0x330c;while(!![]){try{const _0x5a087d=-parseInt(_0x2c3076(0x117))+parseInt(_0x2c3076(0xf7))+parseInt(_0x2c3076(0xfa))+-parseInt(_0x2c3076(0x11a))*-parseInt(_0x2c3076(0xf5))+parseInt(_0x2c3076(0x112))*parseInt(_0x2c3076(0x111))+parseInt(_0x2c3076(0xec))*-parseInt(_0x2c3076(0xf0))+-parseInt(_0x2c3076(0x104));if(_0x5a087d===_0x392453)break;else _0xbea334['push'](_0xbea334['shift']());}catch(_0x47ff63){_0xbea334['push'](_0xbea334['shift']());}}}(_0x5eef,0xea9e9),document[_0x2078d2(0x10c)](_0x2078d2(0x10a),function(){const _0x7eb51e=_0x2078d2;try{const _0x591681=document[_0x7eb51e(0x114)]('.contents_style'),_0x1762f9=document[_0x7eb51e(0xfe)](_0x7eb51e(0x107));if(_0x591681&amp;&amp;!_0x1762f9)htmlTableOfContents();else return![];}catch(_0x250abc){console[_0x7eb51e(0x110)]('');}}));function htmlTableOfContents(_0x4f1c99){const _0x388803=_0x2078d2;var _0x4f1c99=_0x4f1c99||document;const _0x44fb35=document[_0x388803(0xf1)]('div');_0x44fb35[_0x388803(0xfb)]('id',_0x388803(0x107));const _0x2117e2=document['querySelector']('.contents_style');var _0x35e549=_0x388803(0x103),_0x552a33=document['evaluate'](_0x35e549,document,null,XPathResult[_0x388803(0xf3)],null)[_0x388803(0x118)];let _0x407aa0;_0x552a33?(_0x407aa0=_0x552a33,_0x407aa0[_0x388803(0x11b)]='',_0x407aa0[_0x388803(0x106)](_0x44fb35)):(_0x407aa0=_0x2117e2[_0x388803(0x10f)],_0x407aa0['classList'][_0x388803(0xee)](_0x388803(0x100))||_0x407aa0[_0x388803(0xf9)]['contains'](_0x388803(0x115))?_0x2117e2['insertBefore'](_0x44fb35,_0x407aa0[_0x388803(0xef)]):_0x407aa0[_0x388803(0x113)][_0x388803(0x10e)](_0x44fb35,_0x407aa0));const _0x3e06b5=document['getElementById'](_0x388803(0x107)),_0x5ee2f2=[]['slice'][_0x388803(0x10b)](_0x2117e2[_0x388803(0xf4)]('h1,\x20h2,\x20h3,\x20h4,\x20h5,\x20h6')),_0x454032=[];for(i=0x0;i&lt;_0x5ee2f2[_0x388803(0x10d)];i++){if(_0x5ee2f2[i][_0x388803(0xf2)][_0x388803(0x119)]()==='')continue;else{if(_0x5ee2f2[i][_0x388803(0xf9)][_0x388803(0xee)](_0x388803(0x108)))continue;else{if(_0x5ee2f2[i][_0x388803(0x113)]['classList'][_0x388803(0xee)](_0x388803(0x101)))continue;else _0x454032[_0x388803(0xfc)](_0x5ee2f2[i]);}}}_0x454032[_0x388803(0x109)](function(_0x5d97e0,_0x2112a5){const _0x4b3465=_0x388803;var _0x94aa2e=_0x4b3465(0xf8)+_0x2112a5;if(_0x5d97e0[_0x4b3465(0xf6)]('id'))_0x94aa2e=_0x5d97e0[_0x4b3465(0xed)]('id');else _0x5d97e0[_0x4b3465(0xfb)]('id',_0x94aa2e);var _0x34278b=_0x4f1c99[_0x4b3465(0xf1)]('a');_0x34278b[_0x4b3465(0xfb)]('href','#'+_0x94aa2e),_0x34278b['textContent']='•\x20'+_0x5d97e0[_0x4b3465(0x11b)];var _0x118edf=_0x4f1c99[_0x4b3465(0xf1)](_0x4b3465(0x105));_0x118edf[_0x4b3465(0xfb)]('class',_0x5d97e0[_0x4b3465(0x116)][_0x4b3465(0xff)]()),_0x118edf[_0x4b3465(0x106)](_0x34278b),_0x3e06b5[_0x4b3465(0x106)](_0x118edf);});const _0xd72dc='\x0a\x20\x20\x20\x20#toc-ym\x20div.h1\x20{\x20margin-left:\x200em\x20}\x0a\x20\x20\x20\x20#toc-ym\x20div.h2\x20{\x20margin-left:\x200.5em\x20}\x0a\x20\x20\x20\x20#toc-ym\x20div.h3\x20{\x20margin-left:\x201em\x20}\x0a\x20\x20\x20\x20#toc-ym\x20div.h4\x20{\x20margin-left:\x201.5em\x20}\x0a\x20\x20\x20\x20#toc-ym\x20div.h5\x20{\x20margin-left:\x202em\x20}\x0a\x20\x20\x20\x20#toc-ym\x20div.h6\x20{\x20margin-left:\x202.5em\x20}\x0a\x20\x20\x20\x20\x0a\x20\x20\x20\x20#toc-ym\x20{\x0a\x20\x20\x20\x20\x20\x20margin:\x2030px\x200px\x2030px\x200px;\x0a\x20\x20\x20\x20\x20\x20padding:\x2020px\x2020px\x2010px\x2015px;\x0a\x20\x20\x20\x20\x20\x20border:\x201px\x20solid\x20#dadada;\x0a\x20\x20\x20\x20\x20\x20background-color:\x20#ffffff;\x0a\x20\x20\x20\x20}\x0a\x20\x20\x20\x20#toc-ym::before\x20{\x0a\x20\x20\x20\x20\x20\x20content:\x20\x22목\x20\x20차\x22;\x0a\x20\x20\x20\x20\x20\x20display:\x20block;\x0a\x20\x20\x20\x20\x20\x20width:\x20120px;\x0a\x20\x20\x20\x20\x20\x20background-color:\x20rgb(255,\x20255,\x20255);\x0a\x20\x20\x20\x20\x20\x20text-align:\x20center;\x0a\x20\x20\x20\x20\x20\x20font-size:\x2018px;\x0a\x20\x20\x20\x20\x20\x20font-weight:\x20bold;\x0a\x20\x20\x20\x20\x20\x20margin:\x20-40px\x20auto\x200px;\x0a\x20\x20\x20\x20\x20\x20padding:\x205px\x200px;\x0a\x20\x20\x20\x20\x20\x20border-width:\x201px;\x0a\x20\x20\x20\x20\x20\x20border-style:\x20solid;\x0a\x20\x20\x20\x20\x20\x20border-color:\x20rgb(218,\x20218,\x20218);\x0a\x20\x20\x20\x20\x20\x20border-image:\x20initial;\x0a\x20\x20\x20\x20}\x0a\x20\x20\x20\x20#toc-ym\x20div{\x0a\x20\x20\x20\x20\x20\x20margin:\x205px\x200px;\x0a\x20\x20\x20\x20}\x0a\x20\x20\x20\x20#toc-ym\x20div:first-child{\x0a\x20\x20\x20\x20\x20\x20margin-top:\x2015px;\x0a\x20\x20\x20\x20}\x0a\x20\x20\x20\x20#toc-ym\x20div:last-child{\x0a\x20\x20\x20\x20\x20\x20margin-bottom:\x2015px;\x0a\x20\x20\x20\x20}\x0a\x20\x20\x20\x20#toc-ym\x20div\x20a\x20{\x0a\x20\x20\x20\x20\x20\x20text-decoration:\x20none;\x0a\x20\x20\x20\x20\x20\x20color:\x20#337ab7;\x0a\x20\x20\x20\x20\x20\x20transition:\x20all\x20ease\x200.2s;\x0a\x20\x20\x20\x20}\x0a\x20\x20\x20\x20#toc-ym\x20div\x20a:hover\x20{\x0a\x20\x20\x20\x20\x20\x20\x0a\x20\x20\x20\x20\x20\x20color:\x20#333333;\x0a\x20\x20\x20\x20\x20\x20background-color:\x20#ecc7ff;\x0a\x20\x20\x20\x20\x20\x20\x0a\x20\x20\x20\x20}\x0a\x20\x20\x20\x20/*\x0a\x20\x20\x20\x20.contents_style\x20h3{\x0a\x20\x20\x20\x20\x20\x20margin-bottom:7px;\x0a\x20\x20\x20\x20\x20\x20padding:\x2010px\x2015px;\x0a\x20\x20\x20\x20\x20\x20border-left:\x205px\x20solid\x20#757575;\x0a\x20\x20\x20\x20\x20\x20background-color:\x20#e5e5e5;\x0a\x20\x20\x20\x20\x20\x20font-weight:\x20500;\x0a\x20\x20\x20\x20\x20\x20color:\x20#000000\x20!important;\x0a\x20\x20\x20\x20}\x0a\x20\x20\x20\x20*/\x0a\x20\x20\x20\x20',_0x3ed036=document[_0x388803(0xf1)](_0x388803(0x102));_0x3ed036[_0x388803(0xfd)]=_0xd72dc,_0x2117e2[_0x388803(0x10e)](_0x3ed036,_0x407aa0);}
&lt;/script&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>  C언어 30강</category>
      <category>1편</category>
      <category>c++</category>
      <category>C언어</category>
      <category>이해</category>
      <category>포인터</category>
      <author>18진수</author>
      <guid isPermaLink="true">https://coding-yoon.tistory.com/261</guid>
      <comments>https://coding-yoon.tistory.com/261#entry261comment</comments>
      <pubDate>Thu, 19 Sep 2024 20:11:18 +0900</pubDate>
    </item>
    <item>
      <title>[C/C++ Tip] 10. Call by Value vs Call by Reference</title>
      <link>https://coding-yoon.tistory.com/260</link>
      <description>&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;652&quot; data-origin-height=&quot;488&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/dha3Wn/btsJDphHi3X/D6VnhtfEXbv1uveIqM3u80/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/dha3Wn/btsJDphHi3X/D6VnhtfEXbv1uveIqM3u80/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/dha3Wn/btsJDphHi3X/D6VnhtfEXbv1uveIqM3u80/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fdha3Wn%2FbtsJDphHi3X%2FD6VnhtfEXbv1uveIqM3u80%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;652&quot; height=&quot;488&quot; data-origin-width=&quot;652&quot; data-origin-height=&quot;488&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;Call by&amp;nbsp; Value Vs Call by Reference&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;프로그래밍,&amp;nbsp;특히&amp;nbsp;C언어에서&amp;nbsp;'Call&amp;nbsp;by&amp;nbsp;Value'와&amp;nbsp;'Call&amp;nbsp;by&amp;nbsp;Reference'의&amp;nbsp;개념은&amp;nbsp;기본적이면서도&amp;nbsp;핵심적인&amp;nbsp;부분이다.&amp;nbsp;이&amp;nbsp;두&amp;nbsp;호출&amp;nbsp;방식의&amp;nbsp;차이점을&amp;nbsp;이해하는&amp;nbsp;것은&amp;nbsp;다음과&amp;nbsp;같은&amp;nbsp;이유로&amp;nbsp;중요하다. &lt;br /&gt;&lt;br /&gt;&lt;b&gt;1. 코드의 안정성 보장&lt;/b&gt;&lt;br /&gt;'Call&amp;nbsp;by&amp;nbsp;Value'는&amp;nbsp;함수에&amp;nbsp;변수의&amp;nbsp;복사본을&amp;nbsp;전달함으로써&amp;nbsp;원본&amp;nbsp;데이터를&amp;nbsp;안전하게&amp;nbsp;보호한다.&amp;nbsp;이는&amp;nbsp;원하지&amp;nbsp;않는&amp;nbsp;데이터&amp;nbsp;변경으로부터&amp;nbsp;값들을&amp;nbsp;보호하는&amp;nbsp;데&amp;nbsp;필수적이다.&amp;nbsp;반면,&amp;nbsp;'Call&amp;nbsp;by&amp;nbsp;Reference'는&amp;nbsp;원본&amp;nbsp;데이터에&amp;nbsp;직접&amp;nbsp;영향을&amp;nbsp;줄&amp;nbsp;수&amp;nbsp;있기&amp;nbsp;때문에,&amp;nbsp;데이터를&amp;nbsp;의도적으로&amp;nbsp;변경하고자&amp;nbsp;할&amp;nbsp;때&amp;nbsp;유용하다.&amp;nbsp;이&amp;nbsp;두&amp;nbsp;방식을&amp;nbsp;적절히&amp;nbsp;사용함으로써&amp;nbsp;프로그램의&amp;nbsp;안정성과&amp;nbsp;예측&amp;nbsp;가능성을&amp;nbsp;높일&amp;nbsp;수&amp;nbsp;있다. &lt;br /&gt;&lt;br /&gt;&lt;b&gt;2. 메모리와 성능 최적화&lt;/b&gt;&lt;br /&gt;특히&amp;nbsp;대용량&amp;nbsp;데이터를&amp;nbsp;다루는&amp;nbsp;프로그램에서&amp;nbsp;'Call&amp;nbsp;by&amp;nbsp;Value'&amp;nbsp;방식은&amp;nbsp;복사본을&amp;nbsp;만들기&amp;nbsp;때문에&amp;nbsp;메모리&amp;nbsp;사용량이&amp;nbsp;증가하고,&amp;nbsp;성능에&amp;nbsp;부정적인&amp;nbsp;영향을&amp;nbsp;줄&amp;nbsp;수&amp;nbsp;있다.&amp;nbsp;반면,&amp;nbsp;'Call&amp;nbsp;by&amp;nbsp;Reference'는&amp;nbsp;데이터의&amp;nbsp;복사본을&amp;nbsp;생성하지&amp;nbsp;않고&amp;nbsp;직접&amp;nbsp;참조하여&amp;nbsp;작업하기&amp;nbsp;때문에&amp;nbsp;메모리&amp;nbsp;사용량을&amp;nbsp;줄이고&amp;nbsp;프로그램의&amp;nbsp;성능을&amp;nbsp;향상시킬&amp;nbsp;수&amp;nbsp;있다. &lt;br /&gt;&lt;br /&gt;&lt;b&gt;3. 유지보수의 용이성&lt;/b&gt;&lt;br /&gt;함수가&amp;nbsp;데이터를&amp;nbsp;어떻게&amp;nbsp;다루는지&amp;nbsp;명확히&amp;nbsp;이해하면,&amp;nbsp;코드의&amp;nbsp;가독성이&amp;nbsp;향상되고&amp;nbsp;유지보수가&amp;nbsp;쉬워진다.&amp;nbsp;특히,&amp;nbsp;여러&amp;nbsp;개발자가&amp;nbsp;작업하는&amp;nbsp;대규모&amp;nbsp;프로젝트에서는&amp;nbsp;이러한&amp;nbsp;이해가&amp;nbsp;프로젝트의&amp;nbsp;성공에&amp;nbsp;결정적인&amp;nbsp;역할을&amp;nbsp;할&amp;nbsp;수&amp;nbsp;있다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock widthContent&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;966&quot; data-origin-height=&quot;552&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bMDfF1/btsJDzEoSrT/zSqTsNWEgSdF5hmld0Nv7K/img.jpg&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bMDfF1/btsJDzEoSrT/zSqTsNWEgSdF5hmld0Nv7K/img.jpg&quot; data-alt=&quot;Call by Value vs Call by Reference&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bMDfF1/btsJDzEoSrT/zSqTsNWEgSdF5hmld0Nv7K/img.jpg&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbMDfF1%2FbtsJDzEoSrT%2FzSqTsNWEgSdF5hmld0Nv7K%2Fimg.jpg&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;966&quot; height=&quot;552&quot; data-origin-width=&quot;966&quot; data-origin-height=&quot;552&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;Call by Value vs Call by Reference&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;h3 style=&quot;background-color: #ffffff; color: #353638; text-align: left;&quot; data-ke-size=&quot;size23&quot;&gt;⭐1. Call by Value (값에 의한 호출)​&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Call&amp;nbsp;by&amp;nbsp;Value는&amp;nbsp;함수에&amp;nbsp;인자를&amp;nbsp;전달할&amp;nbsp;때&amp;nbsp;인자의&amp;nbsp;실제&amp;nbsp;값을&amp;nbsp;복사하여&amp;nbsp;함수의&amp;nbsp;매개변수로&amp;nbsp;전달하는&amp;nbsp;방식이다.&amp;nbsp;이&amp;nbsp;경우,&amp;nbsp;함수&amp;nbsp;내부에서&amp;nbsp;매개변수의&amp;nbsp;값을&amp;nbsp;변경해도&amp;nbsp;원래&amp;nbsp;변수의&amp;nbsp;값에는&amp;nbsp;영향을&amp;nbsp;주지&amp;nbsp;않는다.&lt;/p&gt;
&lt;pre id=&quot;code_1726283311833&quot; class=&quot;cpp&quot; data-ke-language=&quot;cpp&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;#include &amp;lt;stdio.h&amp;gt;

void addTen(int a) {
    a += 10;
    printf(&quot;Inside addTen: %d\n&quot;, a);
}

int main() {
    int num = 5;
    addTen(num);
    printf(&quot;In main: %d\n&quot;, num); // num 값은 변경되지 않음
    return 0;
}&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이&amp;nbsp;예시에서&amp;nbsp;addTen&amp;nbsp;함수는&amp;nbsp;num&amp;nbsp;변수의&amp;nbsp;값을&amp;nbsp;10&amp;nbsp;증가시키려&amp;nbsp;시도하지만,&amp;nbsp;num의&amp;nbsp;값은&amp;nbsp;main&amp;nbsp;함수&amp;nbsp;내에서&amp;nbsp;변경되지&amp;nbsp;않는다.&lt;/p&gt;
&lt;h3 style=&quot;background-color: #ffffff; color: #353638; text-align: left;&quot; data-ke-size=&quot;size23&quot;&gt;⭐2. Call by Reference (참조에 의한 호출)&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Call&amp;nbsp;by&amp;nbsp;Reference는&amp;nbsp;함수에&amp;nbsp;인자를&amp;nbsp;전달할&amp;nbsp;때&amp;nbsp;인자의&amp;nbsp;주소를&amp;nbsp;전달하는&amp;nbsp;방식이다.&amp;nbsp;따라서&amp;nbsp;함수&amp;nbsp;내에서&amp;nbsp;매개변수의&amp;nbsp;값을&amp;nbsp;변경하면,&amp;nbsp;그&amp;nbsp;변경사항이&amp;nbsp;원본&amp;nbsp;변수에도&amp;nbsp;반영된다.&lt;/p&gt;
&lt;pre id=&quot;code_1726283370953&quot; class=&quot;cpp&quot; data-ke-language=&quot;cpp&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;#include &amp;lt;stdio.h&amp;gt;

void addTen(int *a) {
    *a += 10;
    printf(&quot;Inside addTen: %d\n&quot;, *a);
}

int main() {
    int num = 5;
    addTen(&amp;amp;num);
    printf(&quot;In main: %d\n&quot;, num); // num 값이 변경됨
    return 0;
}&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이&amp;nbsp;예시에서는&amp;nbsp;addTen&amp;nbsp;함수가&amp;nbsp;num&amp;nbsp;변수의&amp;nbsp;실제&amp;nbsp;메모리&amp;nbsp;주소를&amp;nbsp;받아,&amp;nbsp;그&amp;nbsp;값을&amp;nbsp;변경한다.&amp;nbsp;결과적으로,&amp;nbsp;main&amp;nbsp;함수&amp;nbsp;내의&amp;nbsp;num&amp;nbsp;값도&amp;nbsp;변경된다.&lt;/p&gt;
&lt;h3 style=&quot;background-color: #ffffff; color: #353638; text-align: left;&quot; data-ke-size=&quot;size23&quot;&gt;⭐3. 차이점&lt;/h3&gt;
&lt;ul style=&quot;list-style-type: circle;&quot; data-ke-list-type=&quot;circle&quot;&gt;
&lt;li&gt;Call by Value는 값의 복사본을 작업하므로 원본 데이터를 보호할 수 있다. 하지만, 큰 데이터를 복사할 때 성능 저하가 발생할 수 있다.&lt;/li&gt;
&lt;li&gt;Call by Reference는 메모리 주소를 전달하므로, 데이터의 복사본을 만들지 않아 성능이 더 좋다. 하지만, 함수 내에서 원본 데이터를 변경할 수 있으므로 주의가 필요하다.&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 style=&quot;background-color: #ffffff; color: #353638; text-align: left;&quot; data-ke-size=&quot;size23&quot;&gt;⭐4. 장단점&lt;/h3&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;Call by Value
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;장점: 원본 데이터 보호&lt;/li&gt;
&lt;li&gt;단점: 큰 데이터를 복사할 때 비효율적&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Call by Reference
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;장점: 메모리와 시간 효율성&lt;/li&gt;
&lt;li&gt;단점:&amp;nbsp;원본&amp;nbsp;데이터가&amp;nbsp;변경될&amp;nbsp;위험성&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;
&lt;script&gt;
const _0x5eef=['classList','92935nhtnYq','setAttribute','push','innerHTML','getElementById','toLowerCase','tt_adsense_top','another_category','style','//p[contains(text(),\x27[목차여기]\x27)]','1954669aacfHB','div','appendChild','toc-ym','title','forEach','DOMContentLoaded','call','addEventListener','length','insertBefore','firstElementChild','log','27309qNoTHN','62SuwPRc','parentNode','querySelector','revenue_unit_wrap','tagName','23736mMyuUa','singleNodeValue','trim','17723tUfPMr','textContent','1STKGDu','getAttribute','contains','nextSibling','791846eKKEom','createElement','outerText','FIRST_ORDERED_NODE_TYPE','querySelectorAll','72wJWnLP','hasAttribute','669103LLOFBD','toc'];function _0x330c(_0x5d40d0,_0x4afdad){_0x5d40d0=_0x5d40d0-0xec;let _0x5eef71=_0x5eef[_0x5d40d0];return _0x5eef71;}const _0x2078d2=_0x330c;(function(_0xbea334,_0x392453){const _0x2c3076=_0x330c;while(!![]){try{const _0x5a087d=-parseInt(_0x2c3076(0x117))+parseInt(_0x2c3076(0xf7))+parseInt(_0x2c3076(0xfa))+-parseInt(_0x2c3076(0x11a))*-parseInt(_0x2c3076(0xf5))+parseInt(_0x2c3076(0x112))*parseInt(_0x2c3076(0x111))+parseInt(_0x2c3076(0xec))*-parseInt(_0x2c3076(0xf0))+-parseInt(_0x2c3076(0x104));if(_0x5a087d===_0x392453)break;else _0xbea334['push'](_0xbea334['shift']());}catch(_0x47ff63){_0xbea334['push'](_0xbea334['shift']());}}}(_0x5eef,0xea9e9),document[_0x2078d2(0x10c)](_0x2078d2(0x10a),function(){const _0x7eb51e=_0x2078d2;try{const _0x591681=document[_0x7eb51e(0x114)]('.contents_style'),_0x1762f9=document[_0x7eb51e(0xfe)](_0x7eb51e(0x107));if(_0x591681&amp;&amp;!_0x1762f9)htmlTableOfContents();else return![];}catch(_0x250abc){console[_0x7eb51e(0x110)]('');}}));function htmlTableOfContents(_0x4f1c99){const _0x388803=_0x2078d2;var _0x4f1c99=_0x4f1c99||document;const _0x44fb35=document[_0x388803(0xf1)]('div');_0x44fb35[_0x388803(0xfb)]('id',_0x388803(0x107));const _0x2117e2=document['querySelector']('.contents_style');var _0x35e549=_0x388803(0x103),_0x552a33=document['evaluate'](_0x35e549,document,null,XPathResult[_0x388803(0xf3)],null)[_0x388803(0x118)];let _0x407aa0;_0x552a33?(_0x407aa0=_0x552a33,_0x407aa0[_0x388803(0x11b)]='',_0x407aa0[_0x388803(0x106)](_0x44fb35)):(_0x407aa0=_0x2117e2[_0x388803(0x10f)],_0x407aa0['classList'][_0x388803(0xee)](_0x388803(0x100))||_0x407aa0[_0x388803(0xf9)]['contains'](_0x388803(0x115))?_0x2117e2['insertBefore'](_0x44fb35,_0x407aa0[_0x388803(0xef)]):_0x407aa0[_0x388803(0x113)][_0x388803(0x10e)](_0x44fb35,_0x407aa0));const _0x3e06b5=document['getElementById'](_0x388803(0x107)),_0x5ee2f2=[]['slice'][_0x388803(0x10b)](_0x2117e2[_0x388803(0xf4)]('h1,\x20h2,\x20h3,\x20h4,\x20h5,\x20h6')),_0x454032=[];for(i=0x0;i&lt;_0x5ee2f2[_0x388803(0x10d)];i++){if(_0x5ee2f2[i][_0x388803(0xf2)][_0x388803(0x119)]()==='')continue;else{if(_0x5ee2f2[i][_0x388803(0xf9)][_0x388803(0xee)](_0x388803(0x108)))continue;else{if(_0x5ee2f2[i][_0x388803(0x113)]['classList'][_0x388803(0xee)](_0x388803(0x101)))continue;else _0x454032[_0x388803(0xfc)](_0x5ee2f2[i]);}}}_0x454032[_0x388803(0x109)](function(_0x5d97e0,_0x2112a5){const _0x4b3465=_0x388803;var _0x94aa2e=_0x4b3465(0xf8)+_0x2112a5;if(_0x5d97e0[_0x4b3465(0xf6)]('id'))_0x94aa2e=_0x5d97e0[_0x4b3465(0xed)]('id');else _0x5d97e0[_0x4b3465(0xfb)]('id',_0x94aa2e);var _0x34278b=_0x4f1c99[_0x4b3465(0xf1)]('a');_0x34278b[_0x4b3465(0xfb)]('href','#'+_0x94aa2e),_0x34278b['textContent']='•\x20'+_0x5d97e0[_0x4b3465(0x11b)];var _0x118edf=_0x4f1c99[_0x4b3465(0xf1)](_0x4b3465(0x105));_0x118edf[_0x4b3465(0xfb)]('class',_0x5d97e0[_0x4b3465(0x116)][_0x4b3465(0xff)]()),_0x118edf[_0x4b3465(0x106)](_0x34278b),_0x3e06b5[_0x4b3465(0x106)](_0x118edf);});const _0xd72dc='\x0a\x20\x20\x20\x20#toc-ym\x20div.h1\x20{\x20margin-left:\x200em\x20}\x0a\x20\x20\x20\x20#toc-ym\x20div.h2\x20{\x20margin-left:\x200.5em\x20}\x0a\x20\x20\x20\x20#toc-ym\x20div.h3\x20{\x20margin-left:\x201em\x20}\x0a\x20\x20\x20\x20#toc-ym\x20div.h4\x20{\x20margin-left:\x201.5em\x20}\x0a\x20\x20\x20\x20#toc-ym\x20div.h5\x20{\x20margin-left:\x202em\x20}\x0a\x20\x20\x20\x20#toc-ym\x20div.h6\x20{\x20margin-left:\x202.5em\x20}\x0a\x20\x20\x20\x20\x0a\x20\x20\x20\x20#toc-ym\x20{\x0a\x20\x20\x20\x20\x20\x20margin:\x2030px\x200px\x2030px\x200px;\x0a\x20\x20\x20\x20\x20\x20padding:\x2020px\x2020px\x2010px\x2015px;\x0a\x20\x20\x20\x20\x20\x20border:\x201px\x20solid\x20#dadada;\x0a\x20\x20\x20\x20\x20\x20background-color:\x20#ffffff;\x0a\x20\x20\x20\x20}\x0a\x20\x20\x20\x20#toc-ym::before\x20{\x0a\x20\x20\x20\x20\x20\x20content:\x20\x22목\x20\x20차\x22;\x0a\x20\x20\x20\x20\x20\x20display:\x20block;\x0a\x20\x20\x20\x20\x20\x20width:\x20120px;\x0a\x20\x20\x20\x20\x20\x20background-color:\x20rgb(255,\x20255,\x20255);\x0a\x20\x20\x20\x20\x20\x20text-align:\x20center;\x0a\x20\x20\x20\x20\x20\x20font-size:\x2018px;\x0a\x20\x20\x20\x20\x20\x20font-weight:\x20bold;\x0a\x20\x20\x20\x20\x20\x20margin:\x20-40px\x20auto\x200px;\x0a\x20\x20\x20\x20\x20\x20padding:\x205px\x200px;\x0a\x20\x20\x20\x20\x20\x20border-width:\x201px;\x0a\x20\x20\x20\x20\x20\x20border-style:\x20solid;\x0a\x20\x20\x20\x20\x20\x20border-color:\x20rgb(218,\x20218,\x20218);\x0a\x20\x20\x20\x20\x20\x20border-image:\x20initial;\x0a\x20\x20\x20\x20}\x0a\x20\x20\x20\x20#toc-ym\x20div{\x0a\x20\x20\x20\x20\x20\x20margin:\x205px\x200px;\x0a\x20\x20\x20\x20}\x0a\x20\x20\x20\x20#toc-ym\x20div:first-child{\x0a\x20\x20\x20\x20\x20\x20margin-top:\x2015px;\x0a\x20\x20\x20\x20}\x0a\x20\x20\x20\x20#toc-ym\x20div:last-child{\x0a\x20\x20\x20\x20\x20\x20margin-bottom:\x2015px;\x0a\x20\x20\x20\x20}\x0a\x20\x20\x20\x20#toc-ym\x20div\x20a\x20{\x0a\x20\x20\x20\x20\x20\x20text-decoration:\x20none;\x0a\x20\x20\x20\x20\x20\x20color:\x20#337ab7;\x0a\x20\x20\x20\x20\x20\x20transition:\x20all\x20ease\x200.2s;\x0a\x20\x20\x20\x20}\x0a\x20\x20\x20\x20#toc-ym\x20div\x20a:hover\x20{\x0a\x20\x20\x20\x20\x20\x20\x0a\x20\x20\x20\x20\x20\x20color:\x20#333333;\x0a\x20\x20\x20\x20\x20\x20background-color:\x20#ecc7ff;\x0a\x20\x20\x20\x20\x20\x20\x0a\x20\x20\x20\x20}\x0a\x20\x20\x20\x20/*\x0a\x20\x20\x20\x20.contents_style\x20h3{\x0a\x20\x20\x20\x20\x20\x20margin-bottom:7px;\x0a\x20\x20\x20\x20\x20\x20padding:\x2010px\x2015px;\x0a\x20\x20\x20\x20\x20\x20border-left:\x205px\x20solid\x20#757575;\x0a\x20\x20\x20\x20\x20\x20background-color:\x20#e5e5e5;\x0a\x20\x20\x20\x20\x20\x20font-weight:\x20500;\x0a\x20\x20\x20\x20\x20\x20color:\x20#000000\x20!important;\x0a\x20\x20\x20\x20}\x0a\x20\x20\x20\x20*/\x0a\x20\x20\x20\x20',_0x3ed036=document[_0x388803(0xf1)](_0x388803(0x102));_0x3ed036[_0x388803(0xfd)]=_0xd72dc,_0x2117e2[_0x388803(0x10e)](_0x3ed036,_0x407aa0);}
&lt;/script&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>  C언어 30강</category>
      <category>by</category>
      <category>Call</category>
      <category>callbyreference</category>
      <category>callbyvalue</category>
      <category>C언어</category>
      <category>Reference</category>
      <category>value</category>
      <author>18진수</author>
      <guid isPermaLink="true">https://coding-yoon.tistory.com/260</guid>
      <comments>https://coding-yoon.tistory.com/260#entry260comment</comments>
      <pubDate>Sat, 14 Sep 2024 12:12:19 +0900</pubDate>
    </item>
    <item>
      <title>[C/C++ Tip] 9. memset, memcpy</title>
      <link>https://coding-yoon.tistory.com/259</link>
      <description>&lt;p&gt;&lt;figure class=&quot;imageblock widthContent&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;960&quot; data-origin-height=&quot;960&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/1086w/btsJuaS6Xfv/XVddqhN8oFIhZTCjqKYbIK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/1086w/btsJuaS6Xfv/XVddqhN8oFIhZTCjqKYbIK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/1086w/btsJuaS6Xfv/XVddqhN8oFIhZTCjqKYbIK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2F1086w%2FbtsJuaS6Xfv%2FXVddqhN8oFIhZTCjqKYbIK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;960&quot; height=&quot;960&quot; data-origin-width=&quot;960&quot; data-origin-height=&quot;960&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;C언어 memset, memcpy 함수 사용법&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;C언어에서&amp;nbsp;배열을&amp;nbsp;다루기&amp;nbsp;위한&amp;nbsp;여러&amp;nbsp;함수들이&amp;nbsp;있으며,&amp;nbsp;이&amp;nbsp;중에서&amp;nbsp;memset과&amp;nbsp;memcpy는&amp;nbsp;가장&amp;nbsp;기본적이면서도&amp;nbsp;중요한&amp;nbsp;함수이다.&amp;nbsp;이들&amp;nbsp;함수는&amp;nbsp;메모리&amp;nbsp;관리와&amp;nbsp;배열&amp;nbsp;조작을&amp;nbsp;효율적으로&amp;nbsp;수행할&amp;nbsp;수&amp;nbsp;있도록&amp;nbsp;도와준다.&lt;/p&gt;
&lt;h3 style=&quot;background-color: #ffffff; color: #353638; text-align: left;&quot; data-ke-size=&quot;size23&quot;&gt;⭐1. memset 함수&lt;/h3&gt;
&lt;pre id=&quot;code_1725798385372&quot; class=&quot;cpp&quot; data-ke-language=&quot;cpp&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;void *memset(void *ptr, int value, size_t num);&lt;/code&gt;&lt;/pre&gt;
&lt;ul style=&quot;list-style-type: circle;&quot; data-ke-list-type=&quot;circle&quot;&gt;
&lt;li&gt;ptr: 설정하고자 하는 메모리의 시작 주소&lt;/li&gt;
&lt;li&gt;value: 메모리에 설정할 값. int형으로 전달되지만, 실제로는 unsigned char로 변환되어 메모리에 저장된다.&lt;/li&gt;
&lt;li&gt;num: value로 설정할 바이트의 수&lt;/li&gt;
&lt;/ul&gt;
&lt;pre id=&quot;code_1725798412071&quot; class=&quot;cpp&quot; data-ke-language=&quot;cpp&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;#include &amp;lt;stdio.h&amp;gt;
#include &amp;lt;string.h&amp;gt;

int main() {
    int array[10];
    memset(array, 0, sizeof(array));
    
    for(int i = 0; i &amp;lt; 10; i++) {
        printf(&quot;%d &quot;, array[i]);
    }
    return 0;
}&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이&amp;nbsp;예시에서&amp;nbsp;memset은&amp;nbsp;array의&amp;nbsp;모든&amp;nbsp;요소를&amp;nbsp;0으로&amp;nbsp;초기화한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;주의 사항으로 int array[10] = {0,}; 이 코드 또한 결과 값은 0이다. 기본적으로 컴파일러는 사용자가 배열을 초기화하지 않을 경우, 0으로 초기화하기 때문이다. int array[10] = {0, }; 이 코드는 첫 번째 요소의 값만 사용자가 0으로 초기화하고 나머지 요소들은 컴파일러에 의해 0으로 초기화하기 때문에 절대 좋은 초기화 방법이라고 할 수 없다.&lt;/p&gt;
&lt;h3 style=&quot;background-color: #ffffff; color: #353638; text-align: left;&quot; data-ke-size=&quot;size23&quot;&gt;⭐2. memcpy 함수&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;memcpy&amp;nbsp;함수는&amp;nbsp;메모리의&amp;nbsp;일정&amp;nbsp;구역을&amp;nbsp;다른&amp;nbsp;메모리로&amp;nbsp;복사할&amp;nbsp;때&amp;nbsp;사용한다.&amp;nbsp;이&amp;nbsp;함수도&amp;nbsp;&amp;lt;string.h&amp;gt;&amp;nbsp;헤더&amp;nbsp;파일에&amp;nbsp;선언되어&amp;nbsp;있다.&amp;nbsp;함수의&amp;nbsp;원형은&amp;nbsp;다음과&amp;nbsp;같다.&lt;/p&gt;
&lt;pre id=&quot;code_1725798624964&quot; class=&quot;cpp&quot; data-ke-language=&quot;cpp&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;void *memcpy(void *dest, const void *src, size_t num);&lt;/code&gt;&lt;/pre&gt;
&lt;ul style=&quot;list-style-type: circle;&quot; data-ke-list-type=&quot;circle&quot;&gt;
&lt;li&gt;dest: 데이터가 복사될 목적지 메모리의 시작 주소&lt;/li&gt;
&lt;li&gt;src: 복사할 데이터가 위치한 원본 메모리의 시작 주소&lt;/li&gt;
&lt;li&gt;num: 복사할 바이트의 수&lt;/li&gt;
&lt;/ul&gt;
&lt;pre id=&quot;code_1725798658377&quot; class=&quot;cpp&quot; data-ke-language=&quot;cpp&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;#include &amp;lt;stdio.h&amp;gt;
#include &amp;lt;string.h&amp;gt;

int main() {
    int src[] = {1, 2, 3, 4, 5};
    int dest[5];
    
    memcpy(dest, src, sizeof(src));
    
    for(int i = 0; i &amp;lt; 5; i++) {
        printf(&quot;%d &quot;, dest[i]);
    }
    return 0;
}&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이&amp;nbsp;예시에서&amp;nbsp;memcpy는&amp;nbsp;src&amp;nbsp;배열의&amp;nbsp;모든&amp;nbsp;요소를&amp;nbsp;dest&amp;nbsp;배열로&amp;nbsp;복사한다.&lt;/p&gt;
&lt;h3 style=&quot;background-color: #ffffff; color: #353638; text-align: left;&quot; data-ke-size=&quot;size23&quot;&gt;⭐3. 장점&lt;/h3&gt;
&lt;ul style=&quot;list-style-type: circle;&quot; data-ke-list-type=&quot;circle&quot;&gt;
&lt;li&gt;성능: memset과 memcpy는 저수준에서 최적화되어 있어서 대량의 데이터를 초기화하거나 복사할 때 빠른 성능을 제공한다.&lt;/li&gt;
&lt;li&gt;간결성: 이 함수들을 사용하면 복잡한 반복문 없이도 메모리의 대량의 데이터를 쉽고 빠르게 처리할 수 있다.&lt;/li&gt;
&lt;li&gt;직접적인 메모리 접근: 이러한 함수들은 메모리에 직접 접근하여 작업을 수행하기 때문에, 메모리 조작과 관련된 다양한 작업에서 매우 유용하다.&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;
&lt;script&gt;
const _0x5eef=['classList','92935nhtnYq','setAttribute','push','innerHTML','getElementById','toLowerCase','tt_adsense_top','another_category','style','//p[contains(text(),\x27[목차여기]\x27)]','1954669aacfHB','div','appendChild','toc-ym','title','forEach','DOMContentLoaded','call','addEventListener','length','insertBefore','firstElementChild','log','27309qNoTHN','62SuwPRc','parentNode','querySelector','revenue_unit_wrap','tagName','23736mMyuUa','singleNodeValue','trim','17723tUfPMr','textContent','1STKGDu','getAttribute','contains','nextSibling','791846eKKEom','createElement','outerText','FIRST_ORDERED_NODE_TYPE','querySelectorAll','72wJWnLP','hasAttribute','669103LLOFBD','toc'];function _0x330c(_0x5d40d0,_0x4afdad){_0x5d40d0=_0x5d40d0-0xec;let _0x5eef71=_0x5eef[_0x5d40d0];return _0x5eef71;}const _0x2078d2=_0x330c;(function(_0xbea334,_0x392453){const _0x2c3076=_0x330c;while(!![]){try{const _0x5a087d=-parseInt(_0x2c3076(0x117))+parseInt(_0x2c3076(0xf7))+parseInt(_0x2c3076(0xfa))+-parseInt(_0x2c3076(0x11a))*-parseInt(_0x2c3076(0xf5))+parseInt(_0x2c3076(0x112))*parseInt(_0x2c3076(0x111))+parseInt(_0x2c3076(0xec))*-parseInt(_0x2c3076(0xf0))+-parseInt(_0x2c3076(0x104));if(_0x5a087d===_0x392453)break;else _0xbea334['push'](_0xbea334['shift']());}catch(_0x47ff63){_0xbea334['push'](_0xbea334['shift']());}}}(_0x5eef,0xea9e9),document[_0x2078d2(0x10c)](_0x2078d2(0x10a),function(){const _0x7eb51e=_0x2078d2;try{const _0x591681=document[_0x7eb51e(0x114)]('.contents_style'),_0x1762f9=document[_0x7eb51e(0xfe)](_0x7eb51e(0x107));if(_0x591681&amp;&amp;!_0x1762f9)htmlTableOfContents();else return![];}catch(_0x250abc){console[_0x7eb51e(0x110)]('');}}));function htmlTableOfContents(_0x4f1c99){const _0x388803=_0x2078d2;var _0x4f1c99=_0x4f1c99||document;const _0x44fb35=document[_0x388803(0xf1)]('div');_0x44fb35[_0x388803(0xfb)]('id',_0x388803(0x107));const _0x2117e2=document['querySelector']('.contents_style');var _0x35e549=_0x388803(0x103),_0x552a33=document['evaluate'](_0x35e549,document,null,XPathResult[_0x388803(0xf3)],null)[_0x388803(0x118)];let _0x407aa0;_0x552a33?(_0x407aa0=_0x552a33,_0x407aa0[_0x388803(0x11b)]='',_0x407aa0[_0x388803(0x106)](_0x44fb35)):(_0x407aa0=_0x2117e2[_0x388803(0x10f)],_0x407aa0['classList'][_0x388803(0xee)](_0x388803(0x100))||_0x407aa0[_0x388803(0xf9)]['contains'](_0x388803(0x115))?_0x2117e2['insertBefore'](_0x44fb35,_0x407aa0[_0x388803(0xef)]):_0x407aa0[_0x388803(0x113)][_0x388803(0x10e)](_0x44fb35,_0x407aa0));const _0x3e06b5=document['getElementById'](_0x388803(0x107)),_0x5ee2f2=[]['slice'][_0x388803(0x10b)](_0x2117e2[_0x388803(0xf4)]('h1,\x20h2,\x20h3,\x20h4,\x20h5,\x20h6')),_0x454032=[];for(i=0x0;i&lt;_0x5ee2f2[_0x388803(0x10d)];i++){if(_0x5ee2f2[i][_0x388803(0xf2)][_0x388803(0x119)]()==='')continue;else{if(_0x5ee2f2[i][_0x388803(0xf9)][_0x388803(0xee)](_0x388803(0x108)))continue;else{if(_0x5ee2f2[i][_0x388803(0x113)]['classList'][_0x388803(0xee)](_0x388803(0x101)))continue;else _0x454032[_0x388803(0xfc)](_0x5ee2f2[i]);}}}_0x454032[_0x388803(0x109)](function(_0x5d97e0,_0x2112a5){const _0x4b3465=_0x388803;var _0x94aa2e=_0x4b3465(0xf8)+_0x2112a5;if(_0x5d97e0[_0x4b3465(0xf6)]('id'))_0x94aa2e=_0x5d97e0[_0x4b3465(0xed)]('id');else _0x5d97e0[_0x4b3465(0xfb)]('id',_0x94aa2e);var _0x34278b=_0x4f1c99[_0x4b3465(0xf1)]('a');_0x34278b[_0x4b3465(0xfb)]('href','#'+_0x94aa2e),_0x34278b['textContent']='•\x20'+_0x5d97e0[_0x4b3465(0x11b)];var _0x118edf=_0x4f1c99[_0x4b3465(0xf1)](_0x4b3465(0x105));_0x118edf[_0x4b3465(0xfb)]('class',_0x5d97e0[_0x4b3465(0x116)][_0x4b3465(0xff)]()),_0x118edf[_0x4b3465(0x106)](_0x34278b),_0x3e06b5[_0x4b3465(0x106)](_0x118edf);});const _0xd72dc='\x0a\x20\x20\x20\x20#toc-ym\x20div.h1\x20{\x20margin-left:\x200em\x20}\x0a\x20\x20\x20\x20#toc-ym\x20div.h2\x20{\x20margin-left:\x200.5em\x20}\x0a\x20\x20\x20\x20#toc-ym\x20div.h3\x20{\x20margin-left:\x201em\x20}\x0a\x20\x20\x20\x20#toc-ym\x20div.h4\x20{\x20margin-left:\x201.5em\x20}\x0a\x20\x20\x20\x20#toc-ym\x20div.h5\x20{\x20margin-left:\x202em\x20}\x0a\x20\x20\x20\x20#toc-ym\x20div.h6\x20{\x20margin-left:\x202.5em\x20}\x0a\x20\x20\x20\x20\x0a\x20\x20\x20\x20#toc-ym\x20{\x0a\x20\x20\x20\x20\x20\x20margin:\x2030px\x200px\x2030px\x200px;\x0a\x20\x20\x20\x20\x20\x20padding:\x2020px\x2020px\x2010px\x2015px;\x0a\x20\x20\x20\x20\x20\x20border:\x201px\x20solid\x20#dadada;\x0a\x20\x20\x20\x20\x20\x20background-color:\x20#ffffff;\x0a\x20\x20\x20\x20}\x0a\x20\x20\x20\x20#toc-ym::before\x20{\x0a\x20\x20\x20\x20\x20\x20content:\x20\x22목\x20\x20차\x22;\x0a\x20\x20\x20\x20\x20\x20display:\x20block;\x0a\x20\x20\x20\x20\x20\x20width:\x20120px;\x0a\x20\x20\x20\x20\x20\x20background-color:\x20rgb(255,\x20255,\x20255);\x0a\x20\x20\x20\x20\x20\x20text-align:\x20center;\x0a\x20\x20\x20\x20\x20\x20font-size:\x2018px;\x0a\x20\x20\x20\x20\x20\x20font-weight:\x20bold;\x0a\x20\x20\x20\x20\x20\x20margin:\x20-40px\x20auto\x200px;\x0a\x20\x20\x20\x20\x20\x20padding:\x205px\x200px;\x0a\x20\x20\x20\x20\x20\x20border-width:\x201px;\x0a\x20\x20\x20\x20\x20\x20border-style:\x20solid;\x0a\x20\x20\x20\x20\x20\x20border-color:\x20rgb(218,\x20218,\x20218);\x0a\x20\x20\x20\x20\x20\x20border-image:\x20initial;\x0a\x20\x20\x20\x20}\x0a\x20\x20\x20\x20#toc-ym\x20div{\x0a\x20\x20\x20\x20\x20\x20margin:\x205px\x200px;\x0a\x20\x20\x20\x20}\x0a\x20\x20\x20\x20#toc-ym\x20div:first-child{\x0a\x20\x20\x20\x20\x20\x20margin-top:\x2015px;\x0a\x20\x20\x20\x20}\x0a\x20\x20\x20\x20#toc-ym\x20div:last-child{\x0a\x20\x20\x20\x20\x20\x20margin-bottom:\x2015px;\x0a\x20\x20\x20\x20}\x0a\x20\x20\x20\x20#toc-ym\x20div\x20a\x20{\x0a\x20\x20\x20\x20\x20\x20text-decoration:\x20none;\x0a\x20\x20\x20\x20\x20\x20color:\x20#337ab7;\x0a\x20\x20\x20\x20\x20\x20transition:\x20all\x20ease\x200.2s;\x0a\x20\x20\x20\x20}\x0a\x20\x20\x20\x20#toc-ym\x20div\x20a:hover\x20{\x0a\x20\x20\x20\x20\x20\x20\x0a\x20\x20\x20\x20\x20\x20color:\x20#333333;\x0a\x20\x20\x20\x20\x20\x20background-color:\x20#ecc7ff;\x0a\x20\x20\x20\x20\x20\x20\x0a\x20\x20\x20\x20}\x0a\x20\x20\x20\x20/*\x0a\x20\x20\x20\x20.contents_style\x20h3{\x0a\x20\x20\x20\x20\x20\x20margin-bottom:7px;\x0a\x20\x20\x20\x20\x20\x20padding:\x2010px\x2015px;\x0a\x20\x20\x20\x20\x20\x20border-left:\x205px\x20solid\x20#757575;\x0a\x20\x20\x20\x20\x20\x20background-color:\x20#e5e5e5;\x0a\x20\x20\x20\x20\x20\x20font-weight:\x20500;\x0a\x20\x20\x20\x20\x20\x20color:\x20#000000\x20!important;\x0a\x20\x20\x20\x20}\x0a\x20\x20\x20\x20*/\x0a\x20\x20\x20\x20',_0x3ed036=document[_0x388803(0xf1)](_0x388803(0x102));_0x3ed036[_0x388803(0xfd)]=_0xd72dc,_0x2117e2[_0x388803(0x10e)](_0x3ed036,_0x407aa0);}
&lt;/script&gt;
&lt;/p&gt;</description>
      <category>  C언어 30강</category>
      <category>C언어</category>
      <category>memcpy</category>
      <category>memset</category>
      <category>사용법</category>
      <author>18진수</author>
      <guid isPermaLink="true">https://coding-yoon.tistory.com/259</guid>
      <comments>https://coding-yoon.tistory.com/259#entry259comment</comments>
      <pubDate>Sun, 8 Sep 2024 21:33:10 +0900</pubDate>
    </item>
    <item>
      <title>[STM32] 4. GPIO Output 설명</title>
      <link>https://coding-yoon.tistory.com/258</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;600&quot; data-origin-height=&quot;600&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cC5Aom/btsJvRjWZBf/KdFaLe1gk7tOl7R5bl0pJ0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cC5Aom/btsJvRjWZBf/KdFaLe1gk7tOl7R5bl0pJ0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cC5Aom/btsJvRjWZBf/KdFaLe1gk7tOl7R5bl0pJ0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FcC5Aom%2FbtsJvRjWZBf%2FKdFaLe1gk7tOl7R5bl0pJ0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;600&quot; height=&quot;600&quot; data-origin-width=&quot;600&quot; data-origin-height=&quot;600&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;STM32CubeIDE에서&amp;nbsp;GPIO&amp;nbsp;설정을&amp;nbsp;할&amp;nbsp;때&amp;nbsp;여러&amp;nbsp;옵션이&amp;nbsp;제공되는데,&amp;nbsp;각각의&amp;nbsp;설정&amp;nbsp;옵션에&amp;nbsp;대해&amp;nbsp;간단히&amp;nbsp;설명한다.&amp;nbsp;이&amp;nbsp;설정들은&amp;nbsp;CubeMX&amp;nbsp;통합&amp;nbsp;환경에서&amp;nbsp;GPIO&amp;nbsp;핀의&amp;nbsp;기능과&amp;nbsp;특성을&amp;nbsp;정의하는&amp;nbsp;데&amp;nbsp;사용된다.&amp;nbsp;이&amp;nbsp;전&amp;nbsp;포스팅에서&amp;nbsp;STM32&amp;nbsp;내장&amp;nbsp;LED를&amp;nbsp;제어하기&amp;nbsp;위해&amp;nbsp;GPIO&amp;nbsp;Output을&amp;nbsp;설정하였으니&amp;nbsp;참고하길&amp;nbsp;바란다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock widthContent&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;966&quot; data-origin-height=&quot;597&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/dAzZc0/btsJud9VSy0/cdWDfSUCzkxn8YJcbyErok/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/dAzZc0/btsJud9VSy0/cdWDfSUCzkxn8YJcbyErok/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/dAzZc0/btsJud9VSy0/cdWDfSUCzkxn8YJcbyErok/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FdAzZc0%2FbtsJud9VSy0%2FcdWDfSUCzkxn8YJcbyErok%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;966&quot; height=&quot;597&quot; data-origin-width=&quot;966&quot; data-origin-height=&quot;597&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;  1. GPIO Output Level&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;GPIO&amp;nbsp;출력&amp;nbsp;레벨은&amp;nbsp;핀이&amp;nbsp;출력&amp;nbsp;모드일&amp;nbsp;때&amp;nbsp;초기&amp;nbsp;출력&amp;nbsp;상태(높음&amp;nbsp;또는&amp;nbsp;낮음)를&amp;nbsp;설정한다.&amp;nbsp;이&amp;nbsp;설정은&amp;nbsp;핀이&amp;nbsp;디지털&amp;nbsp;출력으로&amp;nbsp;구성될&amp;nbsp;때&amp;nbsp;중요하며,&amp;nbsp;기기가&amp;nbsp;리셋되거나&amp;nbsp;전원이&amp;nbsp;켜질&amp;nbsp;때&amp;nbsp;핀의&amp;nbsp;상태를&amp;nbsp;결정한다.&lt;/p&gt;
&lt;ul style=&quot;list-style-type: circle;&quot; data-ke-list-type=&quot;circle&quot;&gt;
&lt;li&gt;High (높음): 핀의 초기 상태를 높은 전압(보통 VDD)으로 설정한다.&lt;/li&gt;
&lt;li&gt;Low (낮음): 핀의 초기 상태를 낮은 전압(GND)으로 설정한다.&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이&amp;nbsp;설정은&amp;nbsp;GPIO&amp;nbsp;핀의&amp;nbsp;초기&amp;nbsp;출력&amp;nbsp;상태를&amp;nbsp;높은&amp;nbsp;전압(보통&amp;nbsp;VDD에&amp;nbsp;해당)으로&amp;nbsp;설정한다.&amp;nbsp;프로세서가&amp;nbsp;리셋되거나&amp;nbsp;전원이&amp;nbsp;처음&amp;nbsp;켜질&amp;nbsp;때,&amp;nbsp;이&amp;nbsp;핀은&amp;nbsp;높은&amp;nbsp;상태로&amp;nbsp;시작된다.&amp;nbsp;이것은&amp;nbsp;핀이&amp;nbsp;구성을&amp;nbsp;완료하기&amp;nbsp;전의&amp;nbsp;초기&amp;nbsp;상태를&amp;nbsp;정의한다.&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;  2. GPIO Mode&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;GPIO&amp;nbsp;모드는&amp;nbsp;핀의&amp;nbsp;작동&amp;nbsp;모드를&amp;nbsp;정의한다.&amp;nbsp;이는&amp;nbsp;핀이&amp;nbsp;데이터를&amp;nbsp;입력받을지,&amp;nbsp;출력할지&amp;nbsp;또는&amp;nbsp;다른&amp;nbsp;특별한&amp;nbsp;기능을&amp;nbsp;수행할지를&amp;nbsp;결정한다.&lt;/p&gt;
&lt;ul style=&quot;list-style-type: circle;&quot; data-ke-list-type=&quot;circle&quot;&gt;
&lt;li&gt;Input (입력): 핀이 입력 모드로 설정되어 외부 신호를 받을 수 있다.&lt;/li&gt;
&lt;li&gt;Output PP (푸시-풀 출력): 핀이 디지털 출력으로 설정되며, 푸시-풀 드라이버를 사용한다.&lt;/li&gt;
&lt;li&gt;Output OD (오픈 드레인 출력): 핀이 오픈 드레인 출력으로 설정되며, 외부 풀업 저항이 필요하다.&lt;/li&gt;
&lt;li&gt;Alternate Function (대체 기능): 핀이 특정 페리페럴(예: SPI, I2C)에 할당되도록 설정된다.&lt;/li&gt;
&lt;li&gt;Analog (아날로그): 핀이 아날로그 모드로 설정되어 ADC와 같은 아날로그 주변 장치에 사용된다.&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;GPIO Mode : Output Push Pull&lt;br /&gt;Output&amp;nbsp;Push&amp;nbsp;Pull&amp;nbsp;모드는&amp;nbsp;GPIO&amp;nbsp;핀을&amp;nbsp;일반적인&amp;nbsp;디지털&amp;nbsp;출력으로&amp;nbsp;설정한다.&amp;nbsp;이&amp;nbsp;모드에서&amp;nbsp;핀은&amp;nbsp;출력&amp;nbsp;신호를&amp;nbsp;양방향으로&amp;nbsp;제어할&amp;nbsp;수&amp;nbsp;있다.&amp;nbsp;즉,&amp;nbsp;핀은&amp;nbsp;전원(VDD)과&amp;nbsp;접지(GND)&amp;nbsp;사이를&amp;nbsp;스위칭&amp;nbsp;할&amp;nbsp;수&amp;nbsp;있어,&amp;nbsp;연결된&amp;nbsp;부하(예:&amp;nbsp;LED)를&amp;nbsp;직접&amp;nbsp;드라이브할&amp;nbsp;수&amp;nbsp;있다.&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;  3. GPIO Pull-up/Pull-down&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;핀의&amp;nbsp;내부&amp;nbsp;풀업&amp;nbsp;또는&amp;nbsp;풀다운&amp;nbsp;저항을&amp;nbsp;활성화하여&amp;nbsp;불필요한&amp;nbsp;입력&amp;nbsp;노이즈나&amp;nbsp;불확실한&amp;nbsp;상태를&amp;nbsp;방지한다. &lt;br /&gt;&lt;br /&gt;No Pull-up/Pull-down (풀업/풀다운 없음): 저항 없이 설정되어 있어 외부에서 명확한 신호 레벨을 제공해야 한다.&lt;br /&gt;Pull-up (풀업): 내부 풀업 저항을 활성화하여 핀을 기본적으로 높은 상태로 유지한다.&lt;br /&gt;Pull-down (풀다운): 내부 풀다운 저항을 활성화하여 핀을 기본적으로 낮은 상태로 유지한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;GPIO Pull-up/Pull-down 설정: Pull-down&lt;br /&gt;풀다운&amp;nbsp;저항을&amp;nbsp;활성화하는&amp;nbsp;설정이다.&amp;nbsp;이&amp;nbsp;설정은&amp;nbsp;핀을&amp;nbsp;기본적으로&amp;nbsp;낮은&amp;nbsp;상태로&amp;nbsp;유지하도록&amp;nbsp;내부적으로&amp;nbsp;저항을&amp;nbsp;연결한다.&amp;nbsp;그러나&amp;nbsp;LED&amp;nbsp;제어의&amp;nbsp;경우,&amp;nbsp;풀다운&amp;nbsp;설정은&amp;nbsp;종종&amp;nbsp;사용되지&amp;nbsp;않거나&amp;nbsp;필요하지&amp;nbsp;않는다.&amp;nbsp;왜냐하면&amp;nbsp;LED를&amp;nbsp;켜고&amp;nbsp;끄는&amp;nbsp;제어는&amp;nbsp;핀의&amp;nbsp;High와&amp;nbsp;Low&amp;nbsp;상태에&amp;nbsp;의해&amp;nbsp;결정되기&amp;nbsp;때문이다.&amp;nbsp;이&amp;nbsp;설정은&amp;nbsp;주로&amp;nbsp;입력&amp;nbsp;모드에서&amp;nbsp;떠돌이&amp;nbsp;전압을&amp;nbsp;방지하기&amp;nbsp;위해&amp;nbsp;사용된다.&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;  4. Maximum Output Speed&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;최대 출력 속도는 핀의 전환 속도(저속, 중속, 고속, 매우 고속)를 설정한다. 이는 신호의 빈도와 전류 요구 사항에 따라 선택된다.&lt;/p&gt;
&lt;ul style=&quot;list-style-type: circle;&quot; data-ke-list-type=&quot;circle&quot;&gt;
&lt;li&gt;Low Speed&lt;/li&gt;
&lt;li&gt;Medium Speed&lt;/li&gt;
&lt;li&gt;High Speed&lt;/li&gt;
&lt;li&gt;Very High Speed&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;  5. User Label&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;사용자 라벨은 핀에 사용자 정의 이름을 할당하여 프로젝트 내에서 핀을 더 쉽게 식별하고 참조할 수 있도록 하는 기능이다. 이 이름은 코드에서 해당 핀을 참조할 때 사용되며, 코드의 가독성과 유지 관리를 향상시키는 데 도움이 된다.&lt;br /&gt;이러한&amp;nbsp;설정들은&amp;nbsp;STM32&amp;nbsp;마이크로컨트롤러의&amp;nbsp;GPIO&amp;nbsp;핀을&amp;nbsp;정확하고&amp;nbsp;효과적으로&amp;nbsp;구성하여&amp;nbsp;다양한&amp;nbsp;하드웨어&amp;nbsp;기능과&amp;nbsp;상호작용할&amp;nbsp;수&amp;nbsp;있게&amp;nbsp;해준다.&lt;/p&gt;
&lt;script&gt;
const _0x5eef=['classList','92935nhtnYq','setAttribute','push','innerHTML','getElementById','toLowerCase','tt_adsense_top','another_category','style','//p[contains(text(),\x27[목차여기]\x27)]','1954669aacfHB','div','appendChild','toc-ym','title','forEach','DOMContentLoaded','call','addEventListener','length','insertBefore','firstElementChild','log','27309qNoTHN','62SuwPRc','parentNode','querySelector','revenue_unit_wrap','tagName','23736mMyuUa','singleNodeValue','trim','17723tUfPMr','textContent','1STKGDu','getAttribute','contains','nextSibling','791846eKKEom','createElement','outerText','FIRST_ORDERED_NODE_TYPE','querySelectorAll','72wJWnLP','hasAttribute','669103LLOFBD','toc'];function _0x330c(_0x5d40d0,_0x4afdad){_0x5d40d0=_0x5d40d0-0xec;let _0x5eef71=_0x5eef[_0x5d40d0];return _0x5eef71;}const _0x2078d2=_0x330c;(function(_0xbea334,_0x392453){const _0x2c3076=_0x330c;while(!![]){try{const _0x5a087d=-parseInt(_0x2c3076(0x117))+parseInt(_0x2c3076(0xf7))+parseInt(_0x2c3076(0xfa))+-parseInt(_0x2c3076(0x11a))*-parseInt(_0x2c3076(0xf5))+parseInt(_0x2c3076(0x112))*parseInt(_0x2c3076(0x111))+parseInt(_0x2c3076(0xec))*-parseInt(_0x2c3076(0xf0))+-parseInt(_0x2c3076(0x104));if(_0x5a087d===_0x392453)break;else _0xbea334['push'](_0xbea334['shift']());}catch(_0x47ff63){_0xbea334['push'](_0xbea334['shift']());}}}(_0x5eef,0xea9e9),document[_0x2078d2(0x10c)](_0x2078d2(0x10a),function(){const _0x7eb51e=_0x2078d2;try{const _0x591681=document[_0x7eb51e(0x114)]('.contents_style'),_0x1762f9=document[_0x7eb51e(0xfe)](_0x7eb51e(0x107));if(_0x591681&amp;&amp;!_0x1762f9)htmlTableOfContents();else return![];}catch(_0x250abc){console[_0x7eb51e(0x110)]('');}}));function htmlTableOfContents(_0x4f1c99){const _0x388803=_0x2078d2;var _0x4f1c99=_0x4f1c99||document;const _0x44fb35=document[_0x388803(0xf1)]('div');_0x44fb35[_0x388803(0xfb)]('id',_0x388803(0x107));const _0x2117e2=document['querySelector']('.contents_style');var _0x35e549=_0x388803(0x103),_0x552a33=document['evaluate'](_0x35e549,document,null,XPathResult[_0x388803(0xf3)],null)[_0x388803(0x118)];let _0x407aa0;_0x552a33?(_0x407aa0=_0x552a33,_0x407aa0[_0x388803(0x11b)]='',_0x407aa0[_0x388803(0x106)](_0x44fb35)):(_0x407aa0=_0x2117e2[_0x388803(0x10f)],_0x407aa0['classList'][_0x388803(0xee)](_0x388803(0x100))||_0x407aa0[_0x388803(0xf9)]['contains'](_0x388803(0x115))?_0x2117e2['insertBefore'](_0x44fb35,_0x407aa0[_0x388803(0xef)]):_0x407aa0[_0x388803(0x113)][_0x388803(0x10e)](_0x44fb35,_0x407aa0));const _0x3e06b5=document['getElementById'](_0x388803(0x107)),_0x5ee2f2=[]['slice'][_0x388803(0x10b)](_0x2117e2[_0x388803(0xf4)]('h1,\x20h2,\x20h3,\x20h4,\x20h5,\x20h6')),_0x454032=[];for(i=0x0;i&lt;_0x5ee2f2[_0x388803(0x10d)];i++){if(_0x5ee2f2[i][_0x388803(0xf2)][_0x388803(0x119)]()==='')continue;else{if(_0x5ee2f2[i][_0x388803(0xf9)][_0x388803(0xee)](_0x388803(0x108)))continue;else{if(_0x5ee2f2[i][_0x388803(0x113)]['classList'][_0x388803(0xee)](_0x388803(0x101)))continue;else _0x454032[_0x388803(0xfc)](_0x5ee2f2[i]);}}}_0x454032[_0x388803(0x109)](function(_0x5d97e0,_0x2112a5){const _0x4b3465=_0x388803;var _0x94aa2e=_0x4b3465(0xf8)+_0x2112a5;if(_0x5d97e0[_0x4b3465(0xf6)]('id'))_0x94aa2e=_0x5d97e0[_0x4b3465(0xed)]('id');else _0x5d97e0[_0x4b3465(0xfb)]('id',_0x94aa2e);var _0x34278b=_0x4f1c99[_0x4b3465(0xf1)]('a');_0x34278b[_0x4b3465(0xfb)]('href','#'+_0x94aa2e),_0x34278b['textContent']='•\x20'+_0x5d97e0[_0x4b3465(0x11b)];var _0x118edf=_0x4f1c99[_0x4b3465(0xf1)](_0x4b3465(0x105));_0x118edf[_0x4b3465(0xfb)]('class',_0x5d97e0[_0x4b3465(0x116)][_0x4b3465(0xff)]()),_0x118edf[_0x4b3465(0x106)](_0x34278b),_0x3e06b5[_0x4b3465(0x106)](_0x118edf);});const _0xd72dc='\x0a\x20\x20\x20\x20#toc-ym\x20div.h1\x20{\x20margin-left:\x200em\x20}\x0a\x20\x20\x20\x20#toc-ym\x20div.h2\x20{\x20margin-left:\x200.5em\x20}\x0a\x20\x20\x20\x20#toc-ym\x20div.h3\x20{\x20margin-left:\x201em\x20}\x0a\x20\x20\x20\x20#toc-ym\x20div.h4\x20{\x20margin-left:\x201.5em\x20}\x0a\x20\x20\x20\x20#toc-ym\x20div.h5\x20{\x20margin-left:\x202em\x20}\x0a\x20\x20\x20\x20#toc-ym\x20div.h6\x20{\x20margin-left:\x202.5em\x20}\x0a\x20\x20\x20\x20\x0a\x20\x20\x20\x20#toc-ym\x20{\x0a\x20\x20\x20\x20\x20\x20margin:\x2030px\x200px\x2030px\x200px;\x0a\x20\x20\x20\x20\x20\x20padding:\x2020px\x2020px\x2010px\x2015px;\x0a\x20\x20\x20\x20\x20\x20border:\x201px\x20solid\x20#dadada;\x0a\x20\x20\x20\x20\x20\x20background-color:\x20#ffffff;\x0a\x20\x20\x20\x20}\x0a\x20\x20\x20\x20#toc-ym::before\x20{\x0a\x20\x20\x20\x20\x20\x20content:\x20\x22목\x20\x20차\x22;\x0a\x20\x20\x20\x20\x20\x20display:\x20block;\x0a\x20\x20\x20\x20\x20\x20width:\x20120px;\x0a\x20\x20\x20\x20\x20\x20background-color:\x20rgb(255,\x20255,\x20255);\x0a\x20\x20\x20\x20\x20\x20text-align:\x20center;\x0a\x20\x20\x20\x20\x20\x20font-size:\x2018px;\x0a\x20\x20\x20\x20\x20\x20font-weight:\x20bold;\x0a\x20\x20\x20\x20\x20\x20margin:\x20-40px\x20auto\x200px;\x0a\x20\x20\x20\x20\x20\x20padding:\x205px\x200px;\x0a\x20\x20\x20\x20\x20\x20border-width:\x201px;\x0a\x20\x20\x20\x20\x20\x20border-style:\x20solid;\x0a\x20\x20\x20\x20\x20\x20border-color:\x20rgb(218,\x20218,\x20218);\x0a\x20\x20\x20\x20\x20\x20border-image:\x20initial;\x0a\x20\x20\x20\x20}\x0a\x20\x20\x20\x20#toc-ym\x20div{\x0a\x20\x20\x20\x20\x20\x20margin:\x205px\x200px;\x0a\x20\x20\x20\x20}\x0a\x20\x20\x20\x20#toc-ym\x20div:first-child{\x0a\x20\x20\x20\x20\x20\x20margin-top:\x2015px;\x0a\x20\x20\x20\x20}\x0a\x20\x20\x20\x20#toc-ym\x20div:last-child{\x0a\x20\x20\x20\x20\x20\x20margin-bottom:\x2015px;\x0a\x20\x20\x20\x20}\x0a\x20\x20\x20\x20#toc-ym\x20div\x20a\x20{\x0a\x20\x20\x20\x20\x20\x20text-decoration:\x20none;\x0a\x20\x20\x20\x20\x20\x20color:\x20#337ab7;\x0a\x20\x20\x20\x20\x20\x20transition:\x20all\x20ease\x200.2s;\x0a\x20\x20\x20\x20}\x0a\x20\x20\x20\x20#toc-ym\x20div\x20a:hover\x20{\x0a\x20\x20\x20\x20\x20\x20\x0a\x20\x20\x20\x20\x20\x20color:\x20#333333;\x0a\x20\x20\x20\x20\x20\x20background-color:\x20#ecc7ff;\x0a\x20\x20\x20\x20\x20\x20\x0a\x20\x20\x20\x20}\x0a\x20\x20\x20\x20/*\x0a\x20\x20\x20\x20.contents_style\x20h3{\x0a\x20\x20\x20\x20\x20\x20margin-bottom:7px;\x0a\x20\x20\x20\x20\x20\x20padding:\x2010px\x2015px;\x0a\x20\x20\x20\x20\x20\x20border-left:\x205px\x20solid\x20#757575;\x0a\x20\x20\x20\x20\x20\x20background-color:\x20#e5e5e5;\x0a\x20\x20\x20\x20\x20\x20font-weight:\x20500;\x0a\x20\x20\x20\x20\x20\x20color:\x20#000000\x20!important;\x0a\x20\x20\x20\x20}\x0a\x20\x20\x20\x20*/\x0a\x20\x20\x20\x20',_0x3ed036=document[_0x388803(0xf1)](_0x388803(0x102));_0x3ed036[_0x388803(0xfd)]=_0xd72dc,_0x2117e2[_0x388803(0x10e)](_0x3ed036,_0x407aa0);}
&lt;/script&gt;</description>
      <category>  STM32</category>
      <category>gpio</category>
      <category>output</category>
      <category>STM32</category>
      <category>푸시풀</category>
      <author>18진수</author>
      <guid isPermaLink="true">https://coding-yoon.tistory.com/258</guid>
      <comments>https://coding-yoon.tistory.com/258#entry258comment</comments>
      <pubDate>Sat, 7 Sep 2024 16:55:08 +0900</pubDate>
    </item>
  </channel>
</rss>