<?xml version="1.0" encoding="utf-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
    <channel>
        <title>sang_yun_911.log</title>
        <link>https://velog.io/</link>
        <description></description>
        <lastBuildDate>Thu, 24 Nov 2022 08:59:00 GMT</lastBuildDate>
        <docs>https://validator.w3.org/feed/docs/rss2.html</docs>
        <generator>https://github.com/jpmonette/feed</generator>
        <image>
            <title>sang_yun_911.log</title>
            <url>https://images.velog.io/images/sang_yun_911/profile/4a331327-d3d7-484e-af89-71f4c651aa1e/social.png</url>
            <link>https://velog.io/</link>
        </image>
        <copyright>Copyright (C) 2019. sang_yun_911.log. All rights reserved.</copyright>
        <atom:link href="https://v2.velog.io/rss/sang_yun_911" rel="self" type="application/rss+xml"/>
        <item>
            <title><![CDATA[[STM32] USART CLI (4)]]></title>
            <link>https://velog.io/@sang_yun_911/STM32-USART-CLI-4</link>
            <guid>https://velog.io/@sang_yun_911/STM32-USART-CLI-4</guid>
            <pubDate>Thu, 24 Nov 2022 08:59:00 GMT</pubDate>
            <description><![CDATA[<p>이전에 만들어 두었던 CLI 펌웨어에 IAP 기능을 추가해보았다.
보통은 ST-Link 디버거를 통해 코드를 보드에 다운받는데,
이 기능을 추가 하면서 디버거 없이, USART 통신만을 이용해 코드 다운이 가능하다.</p>
<blockquote>
<p>게다가 Nucleo-f429ZI는 전원 USB케이블을 연결하면 Virtual Comport를 제공해준다.
따라서 별도의 Serial 선 없이 가능하다. 참고로 이 보드에서는 USART3으로 제공한다.)</p>
</blockquote>
<p><img src="https://velog.velcdn.com/images/sang_yun_911/post/ff6119fc-ed53-43aa-834a-6b07359bdccc/image.png" alt=""></p>
<p><img src="https://velog.velcdn.com/images/sang_yun_911/post/b4023346-ee47-4d21-a5ff-3d4338b96997/image.png" alt=""></p>
<blockquote>
<p>md 0x08000000 126 명령을 이용해 Flash memory 영역을 읽어온다.
0x08000000 부터 0x0801FFFF 까지의 영역을 BootLoader, 즉 이 CLI 프로그램에게 할당해주었다.</p>
</blockquote>
<p><img src="https://velog.velcdn.com/images/sang_yun_911/post/9612d30e-b72a-49ad-b067-6fafa0a17b6d/image.png" alt=""></p>
<blockquote>
<p>Flash memory 0x08020000 영역부터는 사용자 Application이 올라가는 영역이다.
최초에 확인해보니 초기화가 되어있는 것을 확인했다.</p>
</blockquote>
<p><img src="https://velog.velcdn.com/images/sang_yun_911/post/8d8b9ec5-b75f-49b4-a8ae-3990f282022a/image.png" alt=""></p>
<blockquote>
<p>download 명령어 입력하고, Teraterm의 File -&gt; Transfer -&gt; YModem -&gt; Send에서
미리 STM32CubeIDE에서 추출해둔 .bin파일을 선택한다.</p>
</blockquote>
<p><img src="https://velog.velcdn.com/images/sang_yun_911/post/ccddca88-72e6-46d1-be04-f65614a41d5a/image.png" alt=""></p>
<blockquote>
<p>가만히 기다리면 된다. 성공하면 성공한다고 결과가 출력된다.</p>
</blockquote>
<p><img src="https://velog.velcdn.com/images/sang_yun_911/post/d7369f73-80af-4df4-a5fe-d79f47bb78da/image.png" alt=""></p>
<blockquote>
<p>다운로드 후 0x08020000 부분을 출력해보면 무언가 write 되었다.
마지막으로 run 명령을 실행 하게 되면 다운받았던 .bin 파일의 동작이 실행된다.</p>
</blockquote>
<h3 id="주의">주의</h3>
<ol>
<li>.bin 파일 생성하기
<img src="https://velog.velcdn.com/images/sang_yun_911/post/b0a065ea-e51d-4fc7-8664-a4823db97fb2/image.png" alt=""></li>
</ol>
<p><img src="https://velog.velcdn.com/images/sang_yun_911/post/e9c300f0-fae2-41ab-9e91-98418d8c489e/image.png" alt=""></p>
<pre><code>위 사진처럼 Convert to binary file에 체크해야 한다.</code></pre><ol start="2">
<li>Flash 시작 주소 설정</li>
</ol>
<p>사용자 Application을 만들 때 주의할 사항은 </p>
<p><img src="https://velog.velcdn.com/images/sang_yun_911/post/9527e2ec-3d59-49f2-9019-8219fff260c1/image.png" alt=""></p>
<p><img src="https://velog.velcdn.com/images/sang_yun_911/post/0f947591-1dfe-48ff-878f-1eda74d305a2/image.png" alt=""></p>
<pre><code>프로젝트에 xxxFLASH.ld 파일이 존재 할텐데 시작주소와 크기를 변경해주어야 한다.</code></pre><ol start="3">
<li>Vector 설정</li>
</ol>
<p><img src="https://velog.velcdn.com/images/sang_yun_911/post/366f5ccb-d398-4352-8980-529b05b4c686/image.png" alt="">
<img src="blob:https://velog.io/a262844a-1faa-45ae-a66a-365aae965487" alt="업로드중.."></p>
<pre><code>system_stm32f4xx.c 파일에 들어가 94번 줄이 주석처리 되어 있는 경우가 있다. 
주석 처리를 해제한 뒤 Vector offset을 변경해주어야 한다.
지금 같은 경우는 FLASH 메모리 시작주소가 0x08000000이고 사용자 APPLICATION은 0x08020000에 위치하길 원한다.
따라서 차이가 0x20000만큼 난다.</code></pre><ul>
<li><p>링크
<a href="https://github.com/2Sangyun/USART_CLI.git">https://github.com/2Sangyun/USART_CLI.git</a></p>
</li>
<li><p>참고
<a href="https://blog.naver.com/PostView.nhn?blogId=eziya76&amp;logNo=221552811740">https://blog.naver.com/PostView.nhn?blogId=eziya76&amp;logNo=221552811740</a>
<a href="https://www.st.com/en/embedded-software/stsw-stm32067.html">https://www.st.com/en/embedded-software/stsw-stm32067.html</a></p>
</li>
</ul>
]]></description>
        </item>
        <item>
            <title><![CDATA[[C#] 자주썼던 코드 정리]]></title>
            <link>https://velog.io/@sang_yun_911/C-%EC%9E%90%EC%A3%BC%EC%8D%BC%EB%8D%98-%EC%BD%94%EB%93%9C-%EC%A0%95%EB%A6%AC</link>
            <guid>https://velog.io/@sang_yun_911/C-%EC%9E%90%EC%A3%BC%EC%8D%BC%EB%8D%98-%EC%BD%94%EB%93%9C-%EC%A0%95%EB%A6%AC</guid>
            <pubDate>Wed, 23 Nov 2022 01:18:45 GMT</pubDate>
            <description><![CDATA[<h1 id="자주썼던-코드들">자주썼던 코드들</h1>
<h2 id="invoke">Invoke</h2>
<blockquote>
<p>Invoke 사용하기</p>
</blockquote>
<pre><code class="language-csharp">object.Invoke((MethodInvoker)delegate ()
{
    object.Text += BitConverter.ToString(packet) + &quot;\r\n&quot;;
});</code></pre>
<h2 id="listview">ListView</h2>
<pre><code class="language-csharp">LstvwDataReceive.Columns.Add(&quot;주소&quot;);
LstvwDataReceive.Columns.Add(&quot;값&quot;);
LstvwDataReceive.View = View.Details;
LstvwDataReceive.GridLines = true;
LstvwDataReceive.FullRowSelect = true;
LstvwDataReceive.CheckBoxes = false;</code></pre>
]]></description>
        </item>
        <item>
            <title><![CDATA[[STM32] Ethernet 통신]]></title>
            <link>https://velog.io/@sang_yun_911/STM32-Ethernet-%ED%86%B5%EC%8B%A0-1</link>
            <guid>https://velog.io/@sang_yun_911/STM32-Ethernet-%ED%86%B5%EC%8B%A0-1</guid>
            <pubDate>Mon, 17 Oct 2022 06:22:35 GMT</pubDate>
            <description><![CDATA[<p><a href="https://www.youtube.com/watch?v=4_xE-ZnIefQ&amp;list=PLUaCOzp6U-RqMo-QEJQOkVOl1Us8BNgXk&amp;index=19">참고영상</a>
이 실습은 위의 링크를 보고 실습을 진행한 내용을 정리해보았다.</p>
<h3 id="환경">환경</h3>
<p>MCU 모델 :  STM32F429ZIT6U
보드 : NUCLEO-F429ZI</p>
<p><img src="https://velog.velcdn.com/images/sang_yun_911/post/58aa9612-efd2-449f-b93c-dd9a184c7449/image.png" alt=""></p>
<h3 id="1-target-select">1. Target Select</h3>
<p><img src="https://velog.velcdn.com/images/sang_yun_911/post/0a379977-febe-40ba-b928-bbf0a03ca229/image.png" alt=""></p>
<p>최초에 프로젝트를 생성하게 되면 MCU Selector 화면이 나온다.
이때, MCU selector로 진행할 경우 <code>STM32F429ZIT6U</code> 모델을 선택하거나</p>
<p><img src="https://velog.velcdn.com/images/sang_yun_911/post/2074cdee-0a30-4b50-9d98-c0e6bbd95faa/image.png" alt=""></p>
<p>Board Selector로 진행할 경우 <code>NUCLEO-F429ZI</code> 보드를 선택하고 <code>Next</code> 버튼을 누르면 프로젝트가 생성된다.</p>
<h3 id="2-pinout--configuaration">2. Pinout &amp; Configuaration</h3>
<p><img src="https://velog.velcdn.com/images/sang_yun_911/post/6499878f-d40b-4bee-b542-74aead4b069f/image.png" alt=""></p>
<p>Connectivity -&gt; ETH 에서
Mode는 Disable -&gt; RMII
Advanced Parameters의 PHY를 LAN8742로 선택해준다.</p>
<p><img src="https://velog.velcdn.com/images/sang_yun_911/post/f9e0790e-cb62-4fb1-a985-29789dc8e644/image.png" alt=""></p>
<blockquote>
<p>LAN8742로 선택해주는 이유는 <code>UM1974</code> 문서에 의하면 해당 Nucleo보드는 
external PHY로 <code>LAN8742A-CZ-TR</code> 모델을 사용한다고 한다.</p>
</blockquote>
<ul>
<li>이때, 주의해야 할 사항이 하나 있다.
Board Selector로 NUCLEO-F429ZI를 선택해서 진행한 경우는 괜찮지만 
MCU Selecotor로 STM32F429ZIT6U를 선택해서 진행한 경우는
ETH의 Pin을 선택할 때</li>
</ul>
<p><img src="https://velog.velcdn.com/images/sang_yun_911/post/54fab546-0cc3-48ac-b5ef-81a4f0c50187/image.png" alt=""></p>
<p>위와 같이 선택되었는데 <code>UM1974</code>문서에 의하면 아래와 같다.
<img src="https://velog.velcdn.com/images/sang_yun_911/post/aa48a1e5-a39a-463f-a36d-5aef9461b703/image.png" alt=""></p>
<blockquote>
<p><strong><em>ETH_TXD0는 PG13</em></strong>핀에 
<strong><em>ETH_TX_EN은 PG11</em></strong>에 매칭이 되어야 한다.</p>
</blockquote>
<p><img src="https://velog.velcdn.com/images/sang_yun_911/post/52369554-8b1a-479c-acb8-5be4fc2046e9/image.png" alt=""></p>
<p>다음은 Middleware -&gt; LWIP에서
Enabled를 체크해주고 General Settings에서 DHCP를 Disabled로 선택하고
IP_ADDRESS, NETMASK, GATEWAY를 입력해준다.</p>
<blockquote>
<p>이때, Gateway 주소와 Netmask는 현재 연결된 네트위크의 정보와 동일하게 적어준다.
(커맨드 창에서 <code>ipconfig</code> 명령어를 통해 조회 가능)
IP 주소는 할당되지 않은 새 주소를 입력한다.</p>
</blockquote>
<p><img src="https://velog.velcdn.com/images/sang_yun_911/post/807cca87-4c39-4b34-9125-402f998ba95c/image.png" alt=""></p>
<p>Platform Settings까지 설정해준 뒤 Code Generation을 통해 코드를 생성해준다.</p>
<h3 id="3-코드-추가하기">3. 코드 추가하기</h3>
<p><img src="https://velog.velcdn.com/images/sang_yun_911/post/008b16ea-cb4b-4216-adc0-166d3f9541e4/image.png" alt=""></p>
<p>프로젝트에서 LWIP -&gt; APP -&gt; lwip.c 의 <code>struct netif gnetif</code>를 복사하고</p>
<p><img src="https://velog.velcdn.com/images/sang_yun_911/post/95df550d-a69d-4c4f-9481-1cb350112ff2/image.png" alt=""></p>
<p>LWIP -&gt; APP -&gt; lwip.h에 USER code 입력부분에 
<code>extern struct netif gnetif;</code>로 <code>extern</code> 키워드를 붙여 입력한다.</p>
<p><img src="https://velog.velcdn.com/images/sang_yun_911/post/5c5ef0d9-6f3e-4325-a310-a551f15df3ec/image.png" alt=""></p>
<p><a href="https://www.st.com/en/embedded-software/stm32cubef4.html">다운로드 링크</a>
위 링크로 들어가 압축파일을 다운로드한다.
다운로드한뒤 압축파일을 풀자.</p>
<p><img src="https://velog.velcdn.com/images/sang_yun_911/post/fc10ff60-a141-4f6b-a692-85c890511f0f/image.png" alt=""></p>
<p><img src="https://velog.velcdn.com/images/sang_yun_911/post/c4af1de1-02c1-4545-8892-aed525a75487/image.png" alt=""></p>
<p><img src="https://velog.velcdn.com/images/sang_yun_911/post/5aee206e-2dca-45d2-a047-15df4a90b64e/image.png" alt=""></p>
<p><img src="https://velog.velcdn.com/images/sang_yun_911/post/5b1a4ff1-ba12-4bae-bc15-d72bec14c937/image.png" alt=""></p>
<p><img src="https://velog.velcdn.com/images/sang_yun_911/post/27a9a11c-5d79-434e-b679-1e6525319dfd/image.png" alt=""></p>
<p><img src="https://velog.velcdn.com/images/sang_yun_911/post/0e29c997-9f13-42bd-b617-6a45a5885551/image.png" alt=""></p>
<p><img src="https://velog.velcdn.com/images/sang_yun_911/post/56b3c658-62b6-4cd0-9b7d-8908363cd98d/image.png" alt=""></p>
<p>위 사진처럼 순서대로 폴더를 타고 들어오면 Inc폴더와 Src폴더가 보인다.</p>
<p><img src="https://velog.velcdn.com/images/sang_yun_911/post/1815b718-292c-4ed4-880f-74d85cc31bf4/image.png" alt=""></p>
<p>Inc 폴더내부의 <code>udp_echoserver.h</code>를 복사한다.</p>
<p><img src="https://velog.velcdn.com/images/sang_yun_911/post/a03103ce-e4d8-42e8-a49f-3e521b763102/image.png" alt=""></p>
<p>마찬가지로 Src 폴더 내부의 <code>udp_echoserver.c</code>를 복사한다.</p>
<p>main.c 파일에서
<img src="https://velog.velcdn.com/images/sang_yun_911/post/cdfae709-4ad7-4997-9821-677832c74587/image.png" alt=""></p>
<p><code>#include &quot;udp_echoserver.h&quot;</code>를 입력한다.</p>
<p><img src="https://velog.velcdn.com/images/sang_yun_911/post/4ef2b0ce-03fb-4e99-9fb0-5fba10fa4550/image.png" alt=""></p>
<pre><code class="language-c">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_LWIP_Init();
  /* USER CODE BEGIN 2 */
  udp_echoserver_init();
  /* USER CODE END 2 */

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

    /* USER CODE BEGIN 3 */
      ethernetif_input(&amp;gnetif);
      sys_check_timeouts();
  }
  /* USER CODE END 3 */
}</code></pre>
<p>위와 같이 main 함수를 작성한다. 그리고 보드에 내려받고 실행시켜본다.</p>
<h3 id="4-실행-결과">4. 실행 결과</h3>
<p><img src="https://velog.velcdn.com/images/sang_yun_911/post/bbd34f04-ff3b-463f-9446-ae26de53906a/image.png" alt=""></p>
<p><img src="https://velog.velcdn.com/images/sang_yun_911/post/e4a5524c-9af8-4566-b06f-1af7d229ba92/image.png" alt=""></p>
<p>echo server로써 동작을 하는 것을 확인할 수 있었다.</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[[CS] UART통신]]></title>
            <link>https://velog.io/@sang_yun_911/CS-UART%ED%86%B5%EC%8B%A0</link>
            <guid>https://velog.io/@sang_yun_911/CS-UART%ED%86%B5%EC%8B%A0</guid>
            <pubDate>Thu, 06 Oct 2022 06:53:00 GMT</pubDate>
            <description><![CDATA[<h2 id="uart-통신이란">UART 통신이란</h2>
<pre><code>UART  : Universal Asynchronous Receiver/Transmitter
USART : Universal Synchronous Asynchronous Receiver/Transmitter</code></pre><p>UART와 더불어 데이터시트 같은 문서를 보게 되면 USART라고도 표기를 한다.
일반적으로 비동기식으로 많이 쓰기도 하여 UART통신 이라고 흔히 부르지만 동기적인 방식의 통신도 있으니 USART가 더 포괄적이고 일반적인 용어 인듯 하다.</p>
<p>또 UART 통신을 이야기 할 때, 꼭 RS-232, RS-422, RS-485도 항상 같이 이야기 되는 것 같다.
이번 글에서는 이것들에 대해 한번 정리 해보려고 한다.</p>
<h3 id="1-uartusart">1. UART/USART</h3>
<p>UART는 두 장치간 <em><strong>직렬(Serial)</strong></em> 데이터(디지털)를 어떻게 통신할 것인지, 
통신 _<strong>규약(프로토콜)</strong>_을 정해놓은 것이라고 생각하면 된다.</p>
<p>UART(비동기) 통신의 큰 특징은 송신부(Transmitter)와 수신부(Receiver)가 클럭 신호를 공유하지 않는다.
따라서 <strong><em>Baud Rate</em></strong>를 서로 동일하게 맞추어야 정확한 데이터를 송,수신할 수 있다.
그 외에도 _<strong>Parity, stop bit</strong>_를 서로 일치시켜야 한다.</p>
<p><img src="https://velog.velcdn.com/images/sang_yun_911/post/7e6a48b8-327c-437f-89a0-b42308ea7a6d/image.png" alt=""></p>
<pre><code>위 그림은 UART통신시 보내지는 패킷의 구조이다.
Start bit  (1 bit)
Data bits  (5~8 bit) : 일반적으로 8 bits
Parity bit (0~1 bit)
Stop bit   (1~2 bit)</code></pre><p>여기서 조금 더 자세히 기술하자면 start bit는 0이다.
반대로 stop bit는 1이다.
Parity bit는 사용하지 않거나 사용한다며 1 bit 이다.
그리고 가운데 Data bits가 껴있는 형식이다. D0부터 D7까지 8개 bit가 있다.</p>
<blockquote>
<h4 id="q-만약-a를-보낸다고-하면-어떤식으로-전송이-될까-parity-bit는-사용하지-않는다고-가정">Q) 만약 &#39;a&#39;를 보낸다고 하면 어떤식으로 전송이 될까?? (parity bit는 사용하지 않는다고 가정)</h4>
<p>A) &#39;a&#39;는 ASCII 문자로 Dec: 97, Hex: 0x61의 값을 갖는다.
이 1 byte(8 bit) 이진수 형식으로 나타나게 되면 0110 0001 이다.
UART 통신에서 Data는 LSB 부터 MSB 순으로 전송된다.
다시 말하자면 1-0-0-0 - 0-1-1-0 순서로 전송된다는 뜻이다. 
start bit와 stop bit를 합치면 <strong>[ (0) (1-0-0-0 - 0-1-1-0) (1) ]</strong> 총 10 bits가 전송되는 것이다.</p>
</blockquote>
<p><img src="https://velog.velcdn.com/images/sang_yun_911/post/28c0e6d2-6f66-456e-bc9a-52fef1d60589/image.png" alt=""></p>
<p><img src="https://velog.velcdn.com/images/sang_yun_911/post/d3d2329b-5559-43aa-afee-f07c04392761/image.png" alt=""></p>
<p><img src="https://velog.velcdn.com/images/sang_yun_911/post/abbd7b9d-37c1-4d80-a217-c495fbf392eb/image.png" alt=""></p>
<pre><code>    Tera Term 프로그램을 이용하여 실제 &#39;a&#39;를 전송 했을때 
    파형을 체크하면 위와 같다.</code></pre><h3 id="2-rs-232-422-485">2. RS-232, 422, 485</h3>
<p>RS-232라는 것은 직렬 통신에 사용되는 장비(HW)에 대한 표준 프로토콜이다.</p>
<p><img src="https://velog.velcdn.com/images/sang_yun_911/post/22d38112-bc1d-4f00-b95f-871912492494/image.png" alt=""></p>
<pre><code>위와 같이 각 프로토콜에 대한 규격이 정리되어 있다.
특이하게 RS-232의 경우 &#39;Contacts in use&#39;란의 핀이 정말 많은데, 여기에서 (TxD, RxD, GND) 3개의 핀만으로도 
전송가능하다. 나머지 핀은 data flow control에 필요한 핀이다.</code></pre><hr>
<h3 id="출처">출처</h3>
<p><a href="https://aticleworld.com/difference-between-uart-and-usart/">사진 출처 1 </a>
<a href="https://ipc2u.com/articles/knowledge-base/the-main-differences-between-rs-232-rs-422-and-rs-485/">사진 출처 2</a></p>
<hr>
]]></description>
        </item>
        <item>
            <title><![CDATA[[CS] DMA란?]]></title>
            <link>https://velog.io/@sang_yun_911/CS-DMA%EB%9E%80</link>
            <guid>https://velog.io/@sang_yun_911/CS-DMA%EB%9E%80</guid>
            <pubDate>Wed, 05 Oct 2022 04:06:52 GMT</pubDate>
            <description><![CDATA[<h3 id="dma란">DMA란</h3>
<blockquote>
<p>Direct Memory Access의 약자로 주변장치(I/O device)들이 메모리(RAM)에 직접 접근하는 방식이다.</p>
</blockquote>
<p>DMA방식과 대조되는 방식으로는 아래와 같다.</p>
<blockquote>
<ol>
<li>Programmed I/O (PIO)</li>
<li>Interrupt Initiated  I/O</li>
</ol>
</blockquote>
<p>두 방식모두 CPU의 개입이 필요한 방식이다.</p>
<h3 id="1-programmed-io">1. Programmed I/O</h3>
<p>이 방식에서는 CPU가 주변장치(I/O device)에 대한 지속적인 모니터링을 요구한다.
I/O device가 전송 준비가 될 때까지 Loop를 돌며 확인하기 때문에
CPU를 불필요하게 <strong>&#39;Busy&#39;</strong>하게 만들고 CPU 주기를 낭비하게 만든다.</p>
<blockquote>
<p><strong>Programmed I/O keeps the processor(CPU) busy needlessly and leads to <code>wastage</code> of the CPU cycles.</strong></p>
</blockquote>
<p>이는 Interrupt Initiated I/O 방식에 의해 극복 가능하다.</p>
<h3 id="2-interrupt-initiated--io">2. Interrupt Initiated  I/O</h3>
<p>앞선 방식에서는 I/O device의 상태를 계속 확인하였지만
이 방식에서는 device가 available 상태일 때, interrupt를 발생시킨다.
interrupt가 발생하기전 까지는 CPU는 다른 작업을 처리할 수 있다.
interrupt가 발생했다면, CPU는 처리중이던 작업을 일시중지하고 I/O작업을 수행한 뒤 원래 수행하던 작업으로 되돌아 간다.</p>
<blockquote>
<p><strong>There is no need for the CPU to stay in the loop as the interrupt command interrupts the CPU when the device is ready for the data transfer.
Thus, the CPU cycles are <code>not wasted</code>.</strong></p>
</blockquote>
<h3 id="3-dma">3. DMA</h3>
<p>DMA방식에서는 DMAC(DMA Controller)가 추가 된다.
device에서 메모리에 전송되는 과정은 DMA 컨트롤러가 관여한다. 
CPU는 이 I/O과정에 대해 개입하지 않으므로, 이 동안에 다른 작업을 수행할 수 있다.
DMA 컨트롤러는 작업 완료시 CPU에 interrupt를 발생시켜 작업이 완료되었음을 알린다.</p>
<blockquote>
<p><strong>The DMA Controller takes over the buses to manage the transfer directly between the I/O devices and the memory unit.</strong></p>
</blockquote>
<p>DMA는 아래 4가지 리소스를 필요로 한다.</p>
<blockquote>
<ul>
<li>I/O address</li>
</ul>
</blockquote>
<ul>
<li>Memory address</li>
<li>Interrupt request numbers (IRQ)</li>
<li>DMA channels</li>
</ul>
<p><img src="https://velog.velcdn.com/images/sang_yun_911/post/9ca6a2f0-b148-4bf8-8f3a-9478774c25ef/image.png" alt=""></p>
<h4 id="3-1-burst-mode">3-1. Burst-Mode</h4>
<p>burst 모드는 모든 데이터가 전송될때 까지 read, write를 반복한다.
DMA Mode중에서 가장 빠른 방법이다.</p>
<p>이 방식의 문제점은 burst mode 동안에는 CPU는 system bus를 이용할 수 없다는 점이다.
따라서 Data의 size가 크다면 CPU는 모든 Data가 전송될 때까지 System bus를 이용할 수 없다.</p>
<h4 id="3-2-cycle-stealing-mode">3-2. Cycle-stealing-Mode</h4>
<p>cycle-stealing 모드는 데이터 전송을 1 word씩 하게 된다.
저속 입출력 장치에 Burst-Mode사용하게 되면 bus 독점시간이 길어져 문제가 생긴다.
따라서 cycle-stealing 모드는 이를 방지한다.
CPU가 System Bus를 사용하다가 1 Word 전송이 준비되면 System Bus의 사용권한을
DMAC에게 되돌려 준다.</p>
<p>사진 출처 : <a href="http://recipes.egloos.com/5152867">사진출처링크</a></p>
]]></description>
        </item>
        <item>
            <title><![CDATA[[C#] string <-> byte 변환하기 (16진수)]]></title>
            <link>https://velog.io/@sang_yun_911/C-string-byte-%EB%B3%80%ED%99%98%ED%95%98%EA%B8%B0-16%EC%A7%84%EC%88%98</link>
            <guid>https://velog.io/@sang_yun_911/C-string-byte-%EB%B3%80%ED%99%98%ED%95%98%EA%B8%B0-16%EC%A7%84%EC%88%98</guid>
            <pubDate>Thu, 29 Sep 2022 01:05:50 GMT</pubDate>
            <description><![CDATA[<p>string을 16진수 형식의 byte로 바꾸거나 
byte를 16진수 형식의 string으로 바꾸고 싶은 경우가 많은데, 
매번 찾아보게 되어서 정리를 하게 되었다.</p>
<h3 id="1-string을-그대로-16진수-형식으로-변환하기">1. string을 그대로 16진수 형식으로 변환하기</h3>
<p><em>(단, string의 길이는 2이다.)</em></p>
<pre><code class="language-csharp">static void Main(string[] args)
{
    string str = &quot;79&quot;;
    byte dec, hex;

    // 10진수
    dec = Convert.ToByte(str);
    Console.WriteLine(dec);        // 79로 해석

    dec = byte.Parse(str);
    Console.WriteLine(dec);     // 79로 해석

    // 16진수
    hex = Convert.ToByte(str, 16);
    Console.WriteLine(hex);        // 0x79로 해석 -&gt; 121

    hex = byte.Parse(str, System.Globalization.NumberStyles.HexNumber);
    Console.WriteLine(hex);     // 0x79로 해석 -&gt; 121
}</code></pre>
<p><strong>output</strong></p>
<blockquote>
<p>79
79
121
121</p>
</blockquote>
<h3 id="2-string의-각-글자를-16진수-형식으로-변환">2. string의 각 글자를 16진수 형식으로 변환</h3>
<pre><code class="language-csharp">
static void Main(string[] args)
{
    string str = &quot;Hello&quot;;
    byte[] hex_bytes;

    hex_bytes = Encoding.Default.GetBytes(str);

    foreach(byte hb in hex_bytes)
        Console.WriteLine(hb);
}</code></pre>
<blockquote>
<p>ASCII 코드 표에 의하면 아래와 같다. 
&#39;H&#39; = 0x48 (72)
&#39;e&#39; = 0x65 (101)
&#39;l&#39; = 0x6C (108)
&#39;o&#39; = 0x6F (111)</p>
</blockquote>
<p><strong>output</strong></p>
<blockquote>
<p>72
101
108
108
111</p>
</blockquote>
<blockquote>
<p><code>Console.WriteLine(hb);</code>을 거치면서 10진수로 변환 되어 출력된다.
따라서 byte를 다시 16진수 형식의 string으로 출력해보자</p>
</blockquote>
<h3 id="3-1-byte를-16진수-형식의-string으로-출력하기">3. 1 byte를 16진수 형식의 string으로 출력하기</h3>
<pre><code class="language-csharp">static void Main(string[] args)
{
    byte hex = 0x79;

    Console.WriteLine(String.Format(&quot;{0:X2}&quot;, hex));
    Console.WriteLine(Convert.ToString(hex, 16));
    Console.WriteLine(hex.ToString(&quot;X2&quot;));
}</code></pre>
<p><strong>output</strong></p>
<blockquote>
<p>79
 79
 79</p>
</blockquote>
<h3 id="4-1-byte배열을-string으로-변환">4-1. byte배열을 String으로 변환</h3>
<pre><code class="language-csharp">static void Main(string[] args)
{
    string str = &quot;Hello&quot;;
    byte[] bytes;
    bytes = Encoding.Default.GetBytes(str);

    Console.WriteLine(Encoding.Default.GetString(bytes));
}</code></pre>
<p><strong>output</strong></p>
<blockquote>
<p>Hello</p>
</blockquote>
<h3 id="4-2-byte배열을-16진수-형식의-string으로-변환">4-2. byte배열을 16진수 형식의 String으로 변환</h3>
<pre><code class="language-csharp">static void Main(string[] args)
{
    string str = &quot;Hello&quot;;
    byte[] bytes;
    bytes = Encoding.Default.GetBytes(str);

    Console.WriteLine(BitConverter.ToString(bytes));
    Console.WriteLine(BitConverter.ToString(bytes).Replace(&quot;-&quot;,&quot;&quot;));
}</code></pre>
<blockquote>
<p><code>BitConverter.ToString(bytes)</code>에서 &quot;-&quot; 문자가 섞여있다.</p>
</blockquote>
<p><strong>output</strong></p>
<blockquote>
<p>48-65-6C-6C-6F
48656C6C6F</p>
</blockquote>
]]></description>
        </item>
        <item>
            <title><![CDATA[[C] Short Circuit Evaluation]]></title>
            <link>https://velog.io/@sang_yun_911/C-Short-Circuit-Evaluation</link>
            <guid>https://velog.io/@sang_yun_911/C-Short-Circuit-Evaluation</guid>
            <pubDate>Fri, 02 Sep 2022 01:09:39 GMT</pubDate>
            <description><![CDATA[<h2 id="배경지식">배경지식</h2>
<p><img src="https://velog.velcdn.com/images/sang_yun_911/post/6cf4a3b3-cdeb-4996-891d-86e12c1fd711/image.png" alt=""></p>
<p>위의 표는 AND 게이트와 OR 게이트의 진리표이다.
AND는 모두 참이면 참, OR는 하나라도 참이면 참을 반환한다.</p>
<p>이 정도 지식만 있으면 Short Circuit Evaluation을 이해할 수 있다.</p>
<h2 id="본론">본론</h2>
<ol>
<li>AND</li>
</ol>
<pre><code class="language-c">#include &lt;stdio.h&gt;


int ReturnTrue() {
    printf(&quot;Return True.\n&quot;);
    return 1;
}


int ReturnFalse() {
    printf(&quot;Return False.\n&quot;);
    return 0;
}


int main(void)
{
    printf(&quot;case 1\n&quot;);
    if (ReturnFalse() &amp;&amp; ReturnTrue()) {}

    printf(&quot;case 2\n&quot;);
    if (ReturnFalse() &amp;&amp; ReturnFalse()) {}

    printf(&quot;case 3\n&quot;);
    if (ReturnTrue() &amp;&amp; ReturnTrue()) {}

    printf(&quot;case 4\n&quot;);
    if (ReturnTrue() &amp;&amp; ReturnFalse()) {}

    return 0;
}</code></pre>
<p>위의 코드를 실행하게 된다면 결과는 아래와 같다.
<img src="https://velog.velcdn.com/images/sang_yun_911/post/dd98b6e0-9b29-4ff7-890d-a21da2d5d9a8/image.png" alt=""></p>
<ul>
<li><strong>case 1, 2의 경우</strong></li>
</ul>
<p>AND연산에서는 모두 참을 반환해야 참이다.</p>
<pre><code class="language-c">printf(&quot;case 1\n&quot;);
if (ReturnFalse() &amp;&amp; ReturnTrue()) {}

printf(&quot;case 2\n&quot;);
if (ReturnFalse() &amp;&amp; ReturnFalse()) {}</code></pre>
<p><code>ReturnFalse()</code> 함수의 경우엔 0을 반환하며 False이다.
따라서 뒤의 식에서 True가 나오던, False가 나오던 결국 False이다.</p>
<p>이때 뒤의 <code>ReturnTrue()</code>나 <code>ReturnFalse()</code>는 진행되지 않는다.</p>
<ul>
<li><strong>case 3, 4의 경우</strong><pre><code class="language-c">printf(&quot;case 3\n&quot;);
if (ReturnTrue() &amp;&amp; ReturnTrue()) {}
</code></pre>
</li>
</ul>
<p>printf(&quot;case 4\n&quot;);
if (ReturnTrue() &amp;&amp; ReturnFalse()) {}</p>
<pre><code>반대로 ```ReturnTrue()``` 함수의 경우 참이다.
그러므로 뒤의 식까지 진행을 해봐야 결과를 알 수 있다.

따라서 이 경우 ```ReturnTrue()```와 ```ReturnFalse()```모두 실행이 되는 것이다.


2. OR
```c
#include &lt;stdio.h&gt;


int ReturnTrue() {
    printf(&quot;Return True.\n&quot;);
    return 1;
}


int ReturnFalse() {
    printf(&quot;Return False.\n&quot;);
    return 0;
}


int main(void)
{
    printf(&quot;case 1\n&quot;);
    if (ReturnFalse() || ReturnTrue()) {}

    printf(&quot;case 2\n&quot;);
    if (ReturnFalse() || ReturnFalse()) {}

    printf(&quot;case 3\n&quot;);
    if (ReturnTrue() || ReturnTrue()) {}

    printf(&quot;case 4\n&quot;);
    if (ReturnTrue() || ReturnFalse()) {}

    return 0;
}</code></pre><p>위의 코드를 실행하게 되면 다음과 같다.</p>
<p><img src="https://velog.velcdn.com/images/sang_yun_911/post/caa9fbc9-df3a-48d4-84ee-cddf374d0d52/image.png" alt=""></p>
<p>OR연산은 하나만 True여도 True를 반환한다.</p>
<ul>
<li><strong>case1, 2 경우</strong><pre><code class="language-c">printf(&quot;case 1\n&quot;);
if (ReturnFalse() || ReturnTrue()) {}
</code></pre>
</li>
</ul>
<p>printf(&quot;case 2\n&quot;);
if (ReturnFalse() || ReturnFalse()) {}</p>
<pre><code>

```ReturnFalse()```에서 False를 반환하므로 뒤의 식까지 검사해야 전체 결과가
True인지 False인지 알 수 있다.

하지만

* __case3, 4경우__

```c
printf(&quot;case 3\n&quot;);
if (ReturnTrue() || ReturnTrue()) {}

printf(&quot;case 4\n&quot;);
if (ReturnTrue() || ReturnFalse()) {}</code></pre><p><code>ReturnTrue()</code>에서 True를 반환하므로 뒤의 식의 결과에 관계 없이 True를 반환하게 된다.
따라서 뒤는 볼 필요가 없이 실행하지 않는다.</p>
<h2 id="다른-예제">다른 예제</h2>
<h3 id="1번">1번</h3>
<pre><code class="language-c">#include &lt;stdio.h&gt;

int main()
{
    int x = 1;

    if (x || ++x) {
        printf(&quot;%d&quot;, x);
    }

    return 0;
}
</code></pre>
<p><strong>Output</strong></p>
<blockquote>
<p>1</p>
</blockquote>
<h3 id="2번">2번</h3>
<pre><code class="language-c">#include &lt;stdio.h&gt;

int main()
{
    float nr = 5, dr = 0;
    dr &amp;&amp; printf(&quot;a/b = %.2f&quot;, nr / dr);
}
</code></pre>
<p><strong>Output</strong></p>
<blockquote>
<p><em>// No Output</em></p>
</blockquote>
]]></description>
        </item>
        <item>
            <title><![CDATA[STM32-PWM]]></title>
            <link>https://velog.io/@sang_yun_911/STM32-PWM</link>
            <guid>https://velog.io/@sang_yun_911/STM32-PWM</guid>
            <pubDate>Tue, 30 Aug 2022 08:08:38 GMT</pubDate>
            <description><![CDATA[<h2 id="배경지식">배경지식</h2>
<p><img src="https://velog.velcdn.com/images/sang_yun_911/post/3a5f4ba4-2cd7-4876-8026-afb4f6485481/image.png" alt=""></p>
<p>PWM에서는 Capture Compare Register가 추가된다.
줄여서 CC 레지스터라고 하는데, 이 레지스터는 0부터 Period사이의 값을 갖는다.</p>
<blockquote>
<p>$0 &lt;= CC register &lt;= period &lt;= 2^{16} - 1$ 라고 정리해볼 수 있을 것 같다.</p>
</blockquote>
<p>CC 레지스터의 역할은 Duty 비를 조절하는데 쓰인다.</p>
<p><img src="https://velog.velcdn.com/images/sang_yun_911/post/9ce521f3-b5df-41e9-95b6-9d6206a2eb6f/image.png" alt=""></p>
<p><img src="https://velog.velcdn.com/images/sang_yun_911/post/48dbac94-1995-4c27-86ec-d13fd307f778/image.png" alt=""></p>
<p>위 두가지 경우처럼 CC 레지스터의 값과 Count 레지스터의 값이 같아질때 pin state가 토글된다.
따라서 CC 레지스터의 값을 조절하여 Duty 비를 조절한다.</p>
<h2 id="실습">실습</h2>
<p>PWM을 통해 LED의 밝기를 조절해보는 실습을 진행했다.</p>
<p><img src="https://velog.velcdn.com/images/sang_yun_911/post/e3b91fdd-c438-4040-b6b4-24ff9b3d5d18/image.png" alt=""></p>
<p>보드에서 LED는 A11핀에 연결되어 있다. STM32CubeIDE의 프로젝트에서 .ioc파일을 열고
Pinout &amp; Configuration 창에서 A11핀을 TIM1의 채널 4번으로 사용한다.</p>
<p><img src="https://velog.velcdn.com/images/sang_yun_911/post/165bea89-dd47-4857-9e3d-34ea3b827fca/image.png" alt=""></p>
<p>TIM1의 Parameter Settings에서 Prescaler와 Counter Period를 설정해준다.</p>
<blockquote>
<p>Counter Register가 1증가하는데 걸리는 시간은 System Clock에 의해 결정된다.
System Clock이 $90MHz$라면 1증가하는데 걸리는 시간은 $1/90,000,000 (sec)$이 걸릴 것이다.
$Prescaler = 20$ 이므로 $1/4,500,000(sec)$이 걸릴 것이라고 생각 할 수 있다.</p>
</blockquote>
<blockquote>
<p>$Period = 45,000$ 이므로 $45,000/4,500,000 = 1/100$ 이다.
따라서 한 주기는 $1/100(sec)$이므로 $100Hz$임을 알 수 있다.</p>
</blockquote>
<p>코드를 생성하고 메인함수 내부에 아래와 같이 코드를 작성하였다.</p>
<pre><code class="language-c">  HAL_TIM_PWM_Start(&amp;htim1, TIM_CHANNEL_4);
  uint16_t ccR = 0;

  while (1)
  {
      __HAL_TIM_SET_COMPARE(&amp;htim1, TIM_CHANNEL_4, ccR);
      if(ccR &gt; TIM1-&gt;ARR)
      {
          ccR = 0;
      }
      if(ccR == 0){
          HAL_Delay(2000);
      }
      else{
          HAL_Delay(1000);
      }
      ccR += 10000;

  }</code></pre>
<p>이때 <code>__HAL_TIM_SET_COMPARE(&amp;htim1, TIM_CHANNEL_4, ccR);</code> 함수는 아래와 같다.</p>
<pre><code class="language-c">#define __HAL_TIM_SET_COMPARE(__HANDLE__, __CHANNEL__, __COMPARE__) \
  (((__CHANNEL__) == TIM_CHANNEL_1) ? ((__HANDLE__)-&gt;Instance-&gt;CCR1 = (__COMPARE__)) :\
   ((__CHANNEL__) == TIM_CHANNEL_2) ? ((__HANDLE__)-&gt;Instance-&gt;CCR2 = (__COMPARE__)) :\
   ((__CHANNEL__) == TIM_CHANNEL_3) ? ((__HANDLE__)-&gt;Instance-&gt;CCR3 = (__COMPARE__)) :\
   ((__HANDLE__)-&gt;Instance-&gt;CCR4 = (__COMPARE__)))</code></pre>
<p>3항연산자를 중첩하여 만든 define 함수이다.
Channel 4를 사용하므로 마지막 줄이 실행되는 것이다.</p>
<h2 id="고찰">고찰</h2>
<p>코드 작성 뒤 보드에 올려 동작을 관찰해보았다. LED의 밝기가 시간에 따라 변하는 것을 확인하였다.</p>
<p>하지만 ccR의 값을 점점 키웠을 때, duty비 또한 점점 커져 LED가 점점 밝아질 것으로 기대하였는데 실제동작 결과는 LED가 점점 어두워졌다.</p>
<p>따라서 pin의 상태를 장비를 이용해 측정해보았다.
<img src="https://velog.velcdn.com/images/sang_yun_911/post/91597f14-5099-4e2c-9ea8-4b57e5569cb0/image.png" alt="">
<img src="https://velog.velcdn.com/images/sang_yun_911/post/ce0354f8-5063-495c-b92c-ca1e2c15996d/image.png" alt=""><img src="https://velog.velcdn.com/images/sang_yun_911/post/d14a17e4-8600-44dd-be53-f8366d6c3512/image.png" alt=""><img src="https://velog.velcdn.com/images/sang_yun_911/post/dfa1c0cc-510b-44b2-9292-49bd73425a33/image.png" alt=""><img src="https://velog.velcdn.com/images/sang_yun_911/post/c94a4554-d5ab-4e07-af01-2d728e86c039/image.png" alt=""><img src="https://velog.velcdn.com/images/sang_yun_911/post/562d16c1-646c-46b8-99a6-cb5b2f518308/image.png" alt=""></p>
<p>ccR이 0 -&gt; 10,000 -&gt; 20,000 -&gt; 30,000 -&gt; 40,000 총 5단계로 나눠볼 수 있는데,
파형 또한 내가 예상한대로 Duty비가 점점 커지는 것을 확인했다.</p>
<p>답은 회로도에 있었다.
<img src="https://velog.velcdn.com/images/sang_yun_911/post/74ff95a0-7289-4a0a-b36b-85f404e16ae0/image.png" alt=""></p>
<blockquote>
<p>Pin의 state가 Low일때 LED가 켜지고, High일때 꺼진다.
따라서 Duty비가 증가할 수록 어두워지는 것이 맞다.</p>
</blockquote>
]]></description>
        </item>
        <item>
            <title><![CDATA[STM32-TIM_Interrupt_2]]></title>
            <link>https://velog.io/@sang_yun_911/STM32-TIMInterrupt2</link>
            <guid>https://velog.io/@sang_yun_911/STM32-TIMInterrupt2</guid>
            <pubDate>Tue, 30 Aug 2022 00:54:09 GMT</pubDate>
            <description><![CDATA[<h2 id="구현실습">구현(실습)</h2>
<p><img src="https://velog.velcdn.com/images/sang_yun_911/post/c44fa832-80c7-4d9b-8091-5f585a942ace/image.png" alt=""></p>
<blockquote>
<p>TIM7을 Activated를 check한다.</p>
</blockquote>
<p><img src="https://velog.velcdn.com/images/sang_yun_911/post/c2807981-3ac3-4039-96c5-a779b7bf4ccf/image.png" alt=""></p>
<blockquote>
<p>값을 지정해줄 때, -1을 해준다.
Code generation 을 진행하면</p>
</blockquote>
<p><img src="https://velog.velcdn.com/images/sang_yun_911/post/830c20c3-0cf5-40d7-90a6-cf0109f73980/image.png" alt=""></p>
<blockquote>
<p>main함수 내부에 위의 함수가 사용되고 있다.</p>
</blockquote>
<pre><code class="language-c">static void MX_TIM7_Init(void)
{

  /* USER CODE BEGIN TIM7_Init 0 */

  /* USER CODE END TIM7_Init 0 */

  TIM_MasterConfigTypeDef sMasterConfig = {0};

  /* USER CODE BEGIN TIM7_Init 1 */

  /* USER CODE END TIM7_Init 1 */
  htim7.Instance = TIM7;
  htim7.Init.Prescaler = 10000-1;
  htim7.Init.CounterMode = TIM_COUNTERMODE_UP;
  htim7.Init.Period = 9000-1;
  htim7.Init.AutoReloadPreload = TIM_AUTORELOAD_PRELOAD_DISABLE;
  if (HAL_TIM_Base_Init(&amp;htim7) != HAL_OK)
  {
    Error_Handler();
  }
  sMasterConfig.MasterOutputTrigger = TIM_TRGO_RESET;
  sMasterConfig.MasterSlaveMode = TIM_MASTERSLAVEMODE_DISABLE;
  if (HAL_TIMEx_MasterConfigSynchronization(&amp;htim7, &amp;sMasterConfig) != HAL_OK)
  {
    Error_Handler();
  }
  /* USER CODE BEGIN TIM7_Init 2 */

  /* USER CODE END TIM7_Init 2 */

}</code></pre>
<blockquote>
<p>함수 내부를 보면 지정해주었던 Prescaler값과 Period 값이 사용자 설정대로 초기화 했다.</p>
</blockquote>
<blockquote>
<p>그리고 나서 update Interrupt가 발생했을 때, 어떻게 동작할 지 구현해야한다.
stm32f4xx_hal_tim.c에 보면 아래와 같이 구현되어 있다.</p>
</blockquote>
<pre><code class="language-c">__weak void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim)
{
  /* Prevent unused argument(s) compilation warning */
  UNUSED(htim);

  /* NOTE : This function should not be modified, when the callback is needed,
            the HAL_TIM_PeriodElapsedCallback could be implemented in the user file
   */
}</code></pre>
<blockquote>
<p>__weak 심볼이 설정되어 있는데 이는 프로그래머가 직접 다른 파일애서 재정의 할수 있고,
재정의 한다면 그 재정의한 함수대로 실행한다.</p>
</blockquote>
<p>따라서 main함수에서 아래와 같이 정의했다.</p>
<pre><code class="language-c">void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim)
{
  /* USER CODE BEGIN Callback 0 */

  /* USER CODE END Callback 0 */
  if (htim-&gt;Instance == TIM4) {
    HAL_IncTick();
  }
  /* USER CODE BEGIN Callback 1 */
  else if(htim-&gt;Instance == TIM7){
      printf(&quot;%d\n&quot;, tim);
      tim += 1;
   }
  /* USER CODE END Callback 1 */
}</code></pre>
<blockquote>
<p><code>else if</code> 부분이 TIM7에서 동작할 내용이다.
예상 동작은 1초 간격으로 0부터 1씩 증가하고, 해당 내용이 TeraTerm을 통해 출력될 것이다.</p>
</blockquote>
<p><img src="https://velog.velcdn.com/images/sang_yun_911/post/4871a078-5505-4384-8698-1a233042beed/image.png" alt=""></p>
<h2 id="참고">참고</h2>
<p><a href="https://www.inflearn.com/course/stm32f4/unit/15634?tab=curriculum">https://www.inflearn.com/course/stm32f4/unit/15634?tab=curriculum</a></p>
]]></description>
        </item>
        <item>
            <title><![CDATA[STM32-TIM_Interrupt_1]]></title>
            <link>https://velog.io/@sang_yun_911/STM32-TIMInterrupt</link>
            <guid>https://velog.io/@sang_yun_911/STM32-TIMInterrupt</guid>
            <pubDate>Fri, 26 Aug 2022 07:39:28 GMT</pubDate>
            <description><![CDATA[<p>stm32개발보드를 이용하여 타이머 인터럽트 실습을 진행하고 정리한 글이다.</p>
<h2 id="배경지식">배경지식</h2>
<p><img src="https://velog.velcdn.com/images/sang_yun_911/post/ebf85227-c334-4354-9cf8-c2ae681da5e3/image.png" alt=""></p>
<blockquote>
<p>위 그림에서 x축은 시간, y축은 Counter Register의 값이다.
stm32f4xx family 기준으로 Counter Register는 16bit로 0 ~ ${2^{16}-1}$ 의 값을 갖는다.</p>
</blockquote>
<blockquote>
<p>ARR은 Auto Reload Register의 약자로 Counter Register의 값이 ARR과 동일해질때,
 Update Interrupt가 발생한다. ARR역시 16bit이다.
 ( <strong>Period 라고도 한다.</strong>)</p>
</blockquote>
<blockquote>
</blockquote>
<p>  Counter Register는 0에서 시작해 1씩 증가하는데, 이때 1 증가하는데 걸리는 시간은 system Clock에 의해 결정된다.</p>
<blockquote>
</blockquote>
<p>  계산은 만약 system Clock이 $90MHz$라고 가정한다면 아래와 같다.
  $1/90,000,000(sec) = 1.11 * 10^{-8}(sec)$ 이므로 1증가하는데 약 $11ns$시간이 걸린다고 계산가능하다.</p>
<blockquote>
<h3 id="문제">문제..</h3>
<p>  값이 1이 증가하는데 매우 적은시간이 소모되므로 금방 ARR의 값에 도달하게 되고, 
  자연스레 Interrupt가 자주 발생하게 된다. 
  Interrupt가 수행되는 동안 다른 작업을 할 수 없기때문에 이는 System의 입장에서는 좋지 않다.
 때문에 <em><strong>Prescaler</strong></em> 라는 개념을 도입한다.</p>
</blockquote>
<p> <img src="https://velog.velcdn.com/images/sang_yun_911/post/f4756b2d-c520-4d0d-bcaf-2069c676e553/image.png" alt=""></p>
<blockquote>
<p>Prescaler를 이용하여 Counter Register의 값이 1증가하는데 걸리는 시간이 
$Clock Period * Prescaler$ 가 된다.
만약 $Prescaler = 10,000$ 이라고 가정했다면 $11ns * 10,000 = 11 * 10^{-5}(sec)$로 많이 커졌다.</p>
</blockquote>
<blockquote>
<p>정리하면 Counter Register값이 1증가하는데 걸리는 시간은 $Prescaler/System Colck$ 이므로
$1/9,000(sec)$ 인데, 이때 ARR(Period)의 값을 $9,000$으로 설정한다면
Update Interrupt가 일어나는 주기가 1초가 된다.</p>
</blockquote>
<h2 id="데이터시트">데이터시트</h2>
<blockquote>
<p>데이터시트에는 해당 칩에 대한 모든 내용이 나와있다. <em><strong>꼭 잘 읽어야 한다.</strong></em> (근데 양이 너무 많음..)</p>
</blockquote>
<blockquote>
<p>이번에 사용할 Timer는 Tim7이다. stm32f4xx의 데이터시트를 들여다 보면 다음과 같다.</p>
</blockquote>
<p><img src="https://velog.velcdn.com/images/sang_yun_911/post/e4226b55-ccde-4dce-8fe5-1a46ce1b7be7/image.png" alt="">
<img src="https://velog.velcdn.com/images/sang_yun_911/post/60f85e8d-9c82-4f60-a457-49eba7cd741e/image.png" alt=""></p>
<blockquote>
<p>앞서 설명한 Counter register, Prescaler, Auto-Reload register를 포함한다는 사실을 알 수 있다.</p>
</blockquote>
<p><img src="https://velog.velcdn.com/images/sang_yun_911/post/9ffa40d8-6cba-4488-a910-4423447b0431/image.png" alt="">
<img src="https://velog.velcdn.com/images/sang_yun_911/post/2f371f57-9702-47ef-8ba9-b66be3da511e/image.png" alt="">
<img src="https://velog.velcdn.com/images/sang_yun_911/post/938faadf-a822-4086-b1c4-db71b6292f4e/image.png" alt=""></p>
<blockquote>
<p>세 레지스터 모두 16bit임을 확인할 수 있고, reset value도 확인할 수 있다.</p>
</blockquote>
<p><img src="https://velog.velcdn.com/images/sang_yun_911/post/457c1e6f-ee6b-4a22-875d-5c45df44a453/image.png" alt=""></p>
<blockquote>
<p>TIM7은 APB1 Bus를 이용한다. 이와 관련하여 AMBA Bus에 대한 개념을 다루어야 하는데
이는 나중에 자세히 다루도록 하겠다.</p>
</blockquote>
<h2 id="구현실습">구현(실습)</h2>
<p>글이 너무 길어져서 2부에서 다루겠습니다.</p>
<h2 id="참고">참고</h2>
<p><a href="https://www.inflearn.com/course/stm32f4/unit/15634?tab=curriculum">https://www.inflearn.com/course/stm32f4/unit/15634?tab=curriculum</a></p>
]]></description>
        </item>
        <item>
            <title><![CDATA[[STM32] USART CLI (3)]]></title>
            <link>https://velog.io/@sang_yun_911/STM32-3</link>
            <guid>https://velog.io/@sang_yun_911/STM32-3</guid>
            <pubDate>Tue, 26 Jul 2022 06:46:16 GMT</pubDate>
            <description><![CDATA[<p>지난번에는 UART 통신을 이용해 한글자씩 입력 받고 다시 해당 문자를
출력해주는 간단한 실습을 진행해보았다.</p>
<p>이번에는 UART 통신 (인터럽트 방식)을 이용하여
CLI (Command Line Interface)를 구현해본다.</p>
<p>먼저 소스 코드는 아래 주소에 올려두었다.
<a href="https://github.com/2Sangyun/USART_CLI.git">https://github.com/2Sangyun/USART_CLI.git</a></p>
<blockquote>
<p>실제로 구현된 보드를 테스트 할때, 이런식으로 CLI환경을 구축하여
테스트를 할 수 있다고 한다.</p>
</blockquote>
<blockquote>
<p>이번에 CLI 기능 중 구현할 기능은 History기능, 자동완성 기능이다.</p>
</blockquote>
<p><img src="https://velog.velcdn.com/images/sang_yun_911/post/1b25ab34-a657-4fcc-a56d-ab3304dd29bc/image.png" alt=""></p>
<blockquote>
<p>구현한 코드의 전체적인 구조는 위와 같이 생각하면서 구현하였다.</p>
</blockquote>
<blockquote>
<ol>
<li>UART통신으로 입출력을 담당하는 부분과 <ol start="2">
<li>입력된 명령어를 수행하는 Command부분</li>
<li>마지막으로 입력되었던 명령어들을 저장하는 Queue 이다.</li>
</ol>
</li>
</ol>
</blockquote>
<p> 큐는 History 기능을 구현하기 위해 사용되었는데, 그냥 배열로 하게 될 경우 History 버퍼의 크기가 가득 찰 경우 처리가 힘들어져 큐를 사용하는 것이 구현하기에 용이하다고 생각했기 때문이다.</p>
<p> 방향키 위, 아래를 이용하여 이전명령들을 순회할 수 있다.</p>
<p> 자동완성은 TAB키를 이용한다. 현재 까지 적혀있는 문자열을 이용하여 구현하였다.
 최초에 명령어 set들을 만들어 놓고, 이 명령어들과 문자열을 비교한다.
 현재까지의 문자열과 일치하는 것이 1개라면 바로 해당 명령어를 입력하게 하고
 2개 이상이라면 해당하는 모든 명령어들을 출력한다.</p>
<p> <img src="https://velog.velcdn.com/images/sang_yun_911/post/40df7cd5-7adf-49ac-8fae-1647d559cd31/image.png" alt=""></p>
<blockquote>
<p>최초 시작 화면</p>
</blockquote>
<p> <img src="https://velog.velcdn.com/images/sang_yun_911/post/416b49fa-56dc-4869-8772-dd4d04a841f8/image.png" alt=""></p>
<blockquote>
<p>help 명령시 모든 명령어들을 출력해준다.</p>
</blockquote>
<p><img src="https://velog.velcdn.com/images/sang_yun_911/post/2c6c1ce4-0796-4d86-aae3-aea8cf7df2fc/image.png" alt=""></p>
<blockquote>
<p>md 명령어 입력시 메모리를 읽는다.</p>
</blockquote>
<p><img src="https://velog.velcdn.com/images/sang_yun_911/post/2b0eceef-b26d-4218-8ca0-ea4fd3498729/image.png" alt=""></p>
<blockquote>
<p>history 명령 시 여태 입력했던 기록들이 출력되고
방향키 위, 아래를 통해 history 기록을 확인할 수 있다.</p>
</blockquote>
<p>+IAP(In Application Programming) 기능 추가했다.</p>
<p>이후에는 led 명령을 구현할 예정
led 명령을 통해 실제로 보드에 달려있는 LED를 켰다 껐다 하도록 구현예정</p>
<h2 id="참고">참고</h2>
<p><a href="https://blog.naver.com/PostView.nhn?blogId=chcbaram&amp;logNo=222179120060">https://blog.naver.com/PostView.nhn?blogId=chcbaram&amp;logNo=222179120060</a></p>
]]></description>
        </item>
        <item>
            <title><![CDATA[[STM32] USART CLI (2)]]></title>
            <link>https://velog.io/@sang_yun_911/STM32-2</link>
            <guid>https://velog.io/@sang_yun_911/STM32-2</guid>
            <pubDate>Tue, 26 Jul 2022 06:08:17 GMT</pubDate>
            <description><![CDATA[<h4 id="stm32-칩을-이용하여-제작한-보드를-이용하여-실습을-진행했다">STM32 칩을 이용하여 제작한 보드를 이용하여 실습을 진행했다.</h4>
<h4 id="먼저-실습했던-내용은-uart통신을-이용해보는-것이었다">먼저 실습했던 내용은 UART통신을 이용해보는 것이었다.</h4>
<blockquote>
<p>teraterm을 이용하여 입출력 결과를 확인한다.</p>
</blockquote>
<p>2가지 방식을 통해 실습을 진행했다.</p>
<blockquote>
<ol>
<li>Polling 방식</li>
<li>Interrupt 방식</li>
</ol>
</blockquote>
<h3 id="polling-방식">Polling 방식</h3>
<p>Polling방식으로 구현하는 것을 굉장히 쉽고 간단하다. 하지만 실행시간이 길어질 수록 반응속도가 낮아진다. 비효율적인 방법이다.</p>
<p><img src="https://velog.velcdn.com/images/sang_yun_911/post/48187eb7-8f59-4035-b9bd-ff6964ca5250/image.png" alt="">
<img src="https://velog.velcdn.com/images/sang_yun_911/post/df4edbf1-825e-44e4-969f-a776993cfc60/image.png" alt=""></p>
<blockquote>
<p>size를 1만큼 읽고, 해당 입력된 문자를 다시 보내 터미널에 출력된다.
위 처럼 굉장히 간단하게 구현가능하다.</p>
</blockquote>
<h3 id="interrupt-방식">Interrupt 방식</h3>
<p>Interrupt방식으로 구현 하는 방식도 크게 어렵지 않다.</p>
<p>main 함수 내에서 while 루프가 시작하기 전
<img src="https://velog.velcdn.com/images/sang_yun_911/post/06b0b497-8113-4cf5-be69-92502a8bceab/image.png" alt="">
위와 같이 코드를 적어준다.
인터럽트방식으로 데이터를 받겠다는 의미이다.
현재는 size를 1로 설정해주었으므로 size가 1만큼을 수신받게되면
인터럽트가 발생한다.</p>
<p><img src="https://velog.velcdn.com/images/sang_yun_911/post/cdf7a06c-a91d-4cc5-a430-4931278eb0c8/image.png" alt="">
인터럽트가 발생하게 되면 위의 HAL_UART_RxCpltCallback 함수가 최종적으로 실행된다. 이 함수 내부에 원하는 동작을 구현하면 된다.
중요한 것은 다시 한번 HAL_UART_Receive_IT 함수를 호출 해야한다.</p>
<p>이 콜백 함수는 stm32f4xx_hal_uart.c에 정의되어 있다.</p>
<p><img src="https://velog.velcdn.com/images/sang_yun_911/post/23381ca7-e7fb-4913-aefe-7cf3aa70a31d/image.png" alt=""></p>
<blockquote>
<p>__weak로 정의 되어있는데 이는 user code에서 재정의하면 
재정의 된 코드로 실행된다.</p>
</blockquote>
<p><img src="https://velog.velcdn.com/images/sang_yun_911/post/ed188678-f8d8-4ae5-a86b-5840e4a3aef7/image.png" alt=""></p>
<blockquote>
<p>결과가 잘 출력되는 것을 확인하였다. </p>
</blockquote>
]]></description>
        </item>
        <item>
            <title><![CDATA[[STM32] USART-CLI (1)]]></title>
            <link>https://velog.io/@sang_yun_911/STM32-1</link>
            <guid>https://velog.io/@sang_yun_911/STM32-1</guid>
            <pubDate>Wed, 13 Jul 2022 02:13:25 GMT</pubDate>
            <description><![CDATA[<h2 id="개발환경-및-하드웨어보드">개발환경 및 하드웨어(보드)</h2>
<blockquote>
<p>보드는 Nucleo-F429ZI로 진행하였다.</p>
</blockquote>
<blockquote>
<p>개발 환경은 예전에는 Atollic True Studio + STM32 Cube MX 로 진행했으나,
현재는 통합된 STM32 Cube IDE가 있다. IDE로 진행한다.</p>
</blockquote>
<blockquote>
<p>HAL 라이브러리를 이용하여 진행할 예정.</p>
</blockquote>
]]></description>
        </item>
        <item>
            <title><![CDATA[회로이론_CH3]]></title>
            <link>https://velog.io/@sang_yun_911/%ED%9A%8C%EB%A1%9C%EC%9D%B4%EB%A1%A0CH3</link>
            <guid>https://velog.io/@sang_yun_911/%ED%9A%8C%EB%A1%9C%EC%9D%B4%EB%A1%A0CH3</guid>
            <pubDate>Tue, 15 Mar 2022 06:56:39 GMT</pubDate>
            <description><![CDATA[<h1 id="용어정리">용어정리</h1>
<blockquote>
<p>   Wire (또는 lead)    :    elements 사이의 Interconnection을 의미. (도선)</p>
<p>   Node             :     2개 이상의 elements들을 연결하는 점(point)이다.</p>
<p>   Branch            :    (Node)+(single element)+(Node) 를 Branch라고 함.</p>
<p>   Path            :    Node와 element가 반복되는 것이다.
                        Node(start) -&gt; element -&gt; Node -&gt; ... -&gt; Node(end)
                        Node로 시작해 Node로 끝나며 어떤 Node도 중복해서 나오면 안됨.</p>
<p>   Closed path        :    loop라고도 하며, Path인데 start와 end가 같은 것을 의미.</p>
</blockquote>
<h1 id="kirchhoffs-current-law-kcl">Kirchhoff&#39;s Current Law (KCL)</h1>
<blockquote>
<blockquote>
<p>$$\sum_{in=1}^{N}{i_{in}}
= 0$$</p>
</blockquote>
<p>   한 Node에 들어가는 Current의 합은 0이다.
<img src="https://images.velog.io/images/sang_yun_911/post/65e4bb25-7cec-4f1e-aa20-cf00442154f5/image.png" alt=""><img src="https://images.velog.io/images/sang_yun_911/post/8900f65a-82ea-4b54-af7d-4d70191bcd02/image.png" alt=""></p>
</blockquote>
<blockquote>
<p><img src="https://images.velog.io/images/sang_yun_911/post/d896843b-eb72-4528-bcad-7747ff26a3dc/image.png" alt=""></p>
<p>   위 예제의 풀이는 다음과 같다.
<img src="https://images.velog.io/images/sang_yun_911/post/7f89f372-07e8-474e-b55b-f47650d6e349/image.png" alt=""></p>
<p>   voltage source에 3A를 공급한다고 했다. 따라서 +극에서 나오는 방향으로 전류가 흐른다.
   Node (a)에 대해서 KCL을 적용한다면 3A가 들어가고 2A가 나왔으므로 1A가 더 나와야 한다.
   Node (b)에 대해서도 KCL을 적용하면 1A가 들어오고 오른편에서 Current Source에 의해 5A가 들어온다.
   따라서 i = 1 + 5 = 6, 6A이다.</p>
</blockquote>
<h1 id="kirchhoffs-voltage-law-kvl">Kirchhoff&#39;s Voltage Law (KVL)</h1>
<blockquote>
<blockquote>
<p>$$\sum_{drop=1}^{N}{v_{drop}}
= 0$$</p>
</blockquote>
<p>   Colsed path에서 Voltage drop의 합은 0 이다.
<img src="https://images.velog.io/images/sang_yun_911/post/ae9c4298-351c-49ff-9cb7-086af81f316c/image.png" alt=""></p>
<p>   주의할 점은 항상 기준방향을 정하고 그에 맞춰서 계산하면 된다.</p>
</blockquote>
]]></description>
        </item>
        <item>
            <title><![CDATA[회로이론_CH2_2]]></title>
            <link>https://velog.io/@sang_yun_911/%ED%9A%8C%EB%A1%9C%EC%9D%B4%EB%A1%A0CH22</link>
            <guid>https://velog.io/@sang_yun_911/%ED%9A%8C%EB%A1%9C%EC%9D%B4%EB%A1%A0CH22</guid>
            <pubDate>Tue, 15 Mar 2022 05:57:14 GMT</pubDate>
            <description><![CDATA[<h1 id="power">Power</h1>
<blockquote>
<p>   Power p [W] = [J/s] : 단위 시간당 에너지의 변화량</p>
<pre><code>그런데 이전에 배웠던 2가지를 떠올려보면
   1. Current(전류) i = [C/s]
   2. Voltage(전압) v=  [J/C]</code></pre><p>   따라서 power[J/s] = v * i [J/s] 이다.</p>
</blockquote>
<h1 id="voltage-and-current-sources">Voltage and Current Sources</h1>
<blockquote>
<p>   Passive element : 흡수한 에너지 이상의 에너지를 전달할 수 없다.
        ex) resistors(저항), capacitors, inductors 등</p>
<p>   Active element : 흡수한 에너지 이상의 에너지를 전달할 수 있다.
        ex) generator, battery 등</p>
</blockquote>
<h1 id="networks-and-circuits">Networks and Circuits</h1>
<blockquote>
<p>   Electrical Network 이란 2개 이상의 Element가 연결되있는 것을 의미한다.</p>
<p>   Electrical Network 중에서 최소 하나 이상의 closed path가 있을 때, Electrical Circuit 이라고 한다.</p>
<p>   하나 이상의 Active Element가 있다면 그 Network는 Active하다고 한다.
   즉, Active Element가 하나도 없다면 그 Network는 Passive하다고 한다.</p>
</blockquote>
<h1 id="ohms-law">Ohm&#39;s Law</h1>
<blockquote>
<p>   Resistor : 저항 [Ω], 저항은 항상 에너지를 흡수한다.</p>
<p>   Ohm&#39;s Law (옴의 법칙)
        v = i * R 이다.
        1[Ω] = 1[V/A]</p>
</blockquote>
]]></description>
        </item>
        <item>
            <title><![CDATA[회로이론_CH2_1]]></title>
            <link>https://velog.io/@sang_yun_911/%ED%9A%8C%EB%A1%9C%EC%9D%B4%EB%A1%A0CH21</link>
            <guid>https://velog.io/@sang_yun_911/%ED%9A%8C%EB%A1%9C%EC%9D%B4%EB%A1%A0CH21</guid>
            <pubDate>Tue, 15 Mar 2022 04:28:13 GMT</pubDate>
            <description><![CDATA[<h1 id="unit단위">Unit(단위)</h1>
<blockquote>
<p><img src="https://images.velog.io/images/sang_yun_911/post/ad1c44da-b1b5-4e52-ac39-ec1670802e3b/image.png" alt="">
위 사진은 국제 단위계 (SI)의 7개 기본단위이다.</p>
</blockquote>
<blockquote>
<p><img src="https://images.velog.io/images/sang_yun_911/post/58f86bc0-637d-43f1-ad78-5527b87b54f6/image.png" alt="">
단위에 위와 같은 SI Prefixes를 붙여 단위를 표현한다.</p>
</blockquote>
<blockquote>
<p>Units in Electric Circuits (전기 회로에서의 단위)</p>
<ol>
<li>Length [m] : 길이</li>
<li>Weight [kg] : 무게</li>
<li>Charge [C] : 전하량 (Coulomb)<ol start="4">
<li>Force [N] : 힘 (Newton)</li>
</ol>
</li>
<li>Energy [J] : 일 (Joule)
 -&gt; 1[J] = 1[N*m]<ol start="6">
<li>Current [A] : 전류 (Ampere)
-&gt; 1[A] = 1[C/s]</li>
</ol>
</li>
<li>Voltage [V] : 전압 (Volt)
  -&gt; 1[V] = 1[J/C]</li>
<li>Power [W] : 파워 (Watt)
  -&gt; 1[W] = 1[J/s]</li>
</ol>
</blockquote>
<h1 id="charge-conservation-전하량-보존">Charge Conservation (전하량 보존)</h1>
<blockquote>
<p>   전하의 2가지 종류
        1. 양전하 (proton)
        2. 음전하, 전자 (electron)</p>
<p>   전하량 보존
        - 전하들이 circuit(회로)의 서로 다른 부분에서 움직이더라도
          전하의 총량은 시간이 지나도 변하지 않는다.</p>
<p>   Charge in motion = Current
        - 전하가 움직이는 것이 곧 전류이다.</p>
</blockquote>
<h1 id="charge-와-current">Charge 와 Current</h1>
<blockquote>
<p>   Charge를 표기할 때 2가지 표기가 있음
       1. Q (대문자) : constant charge
        2. q (소문자) : time-varying charge (시간에 따라 변함)</p>
<p>   Electric current
        - Time rate of change of charge in the charge movment.
        - 즉, 단위 시간당 전하량의 변화 값 = 전류 이다.</p>
<p>   양전하가 움직이는 방향이 곧 전류의 방향이다.
       - 실제로는 양전하가 아닌 전자가 움직이는 것임
        - 즉, 전자가 움직이는 방향의 반대방향이 전류의 방향이다.</p>
</blockquote>
<h1 id="voltage">Voltage</h1>
<blockquote>
<p>   voltage = potential difference(위치 에너지 차이)
        - 주로 폭포에 비유를 많이 한다.</p>
<p>   voltage(전압) 이란 element를 통해 전하를 움직이게 하는 &quot;힘&quot; 이다.</p>
<pre><code>voltage의 단위는 1[V] = 1[J/C]이다.
    - 즉, 단위 전하당 할 수 있는 일의 양 이다.</code></pre></blockquote>
<blockquote>
<p><img src="https://images.velog.io/images/sang_yun_911/post/3192b7a2-4112-45ef-b39e-74d4741b8b32/image.png" alt=""></p>
<p>   다음과 같은 회로가 있을 때, v6 &lt; 0 이라면, 오른편의 potential이 더 높다.</p>
</blockquote>
<ul>
<li>Absorbing and Delivering Energies<pre><code>  - _**Element**_의 관점에서 에너지를 흡수하는지 방출하는지 구분한다.</code></pre></li>
</ul>
<blockquote>
<blockquote>
<p><img src="https://images.velog.io/images/sang_yun_911/post/99987026-5e08-4c14-a62b-16f334c678c4/image.png" alt=""></p>
</blockquote>
<p>   (a)의 상황에서는 전하들이 높은 곳에서 낮은 곳으로 떨어지는 중이다.
   다시 말해 전하들이 에너지를 잃는 중이고
    이는 Element 관점에서 보았을 때, 에너지를 흡수 하는 것이다. =&gt; Absorbing </p>
</blockquote>
<blockquote>
<blockquote>
<p><img src="https://images.velog.io/images/sang_yun_911/post/98dd7d9c-9de2-4d3a-9d29-5d9a726505d5/image.png" alt=""></p>
</blockquote>
<p>   (b)의 상황도 (a)의 상황과 방향만 다를 뿐 동일한 상황이다. =&gt; Absorbing </p>
</blockquote>
<blockquote>
<blockquote>
<p><img src="https://images.velog.io/images/sang_yun_911/post/2aa55cba-e1f2-4a14-8a4b-6dda46116ad3/image.png" alt=""></p>
</blockquote>
<p>   (c)의 상황에서는 전하들이 낮은 곳에서 높은 곳으로 올라가는 중이다.
   다시 말해 전하들이 에너지를 얻는 중이다.
   이는 Element 관점에서 보았을 때, 에너지를 (전하들에게) 전달, 방출 하는 것이다. =&gt; Delivering</p>
</blockquote>
<blockquote>
<blockquote>
<p><img src="https://images.velog.io/images/sang_yun_911/post/b8f69728-48a8-4ee4-aff2-3e0cbfc3809e/image.png" alt=""></p>
</blockquote>
<p>   (d)의 상황도 (c)의 상황과 방향만 다를 뿐 동일한 상황이다. =&gt; Delivering</p>
</blockquote>
]]></description>
        </item>
        <item>
            <title><![CDATA[회로이론_CH1]]></title>
            <link>https://velog.io/@sang_yun_911/%ED%9A%8C%EB%A1%9C%EC%9D%B4%EB%A1%A0CH1</link>
            <guid>https://velog.io/@sang_yun_911/%ED%9A%8C%EB%A1%9C%EC%9D%B4%EB%A1%A0CH1</guid>
            <pubDate>Tue, 15 Mar 2022 03:22:58 GMT</pubDate>
            <description><![CDATA[<h1 id="linearity">Linearity</h1>
<blockquote>
<p>Linearity(선형성)은 다음 2가지를 만족해야한다.</p>
<ol>
<li><p>Additivity(또는 Superposition property)
  f(x+y) = f(x) + f(y)</p>
</li>
<li><p>Homogenetiy
  f(ax) = af(x)</p>
</li>
</ol>
<pre><code>즉, 덧셈과 곱셈에 대해 닫혀있다.</code></pre></blockquote>
<blockquote>
<p>왜 Linear 해야 할까?</p>
<ol>
<li><p>어떤 System도 완벽히Linear하지 않다.</p>
</li>
<li><p>다행히도 제한된 조건(limited range)에서는 선형적으로 움직인다.</p>
<ul>
<li>모델링 가능하다.</li>
</ul>
<p>-&gt; Linear Problem은 풀기 쉽다!</p>
</li>
</ol>
</blockquote>
]]></description>
        </item>
    </channel>
</rss>