<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0">
  <channel>
    <title>파워 유튜버</title>
    <link>https://bota.tistory.com/</link>
    <description>애니메이션(원피스, 나루토 등등), 미니어쳐, 바둑 각종 컨텐츠 제작</description>
    <language>ko</language>
    <pubDate>Tue, 14 Jul 2026 00:03:19 +0900</pubDate>
    <generator>TISTORY</generator>
    <ttl>100</ttl>
    <managingEditor>덕력킹</managingEditor>
    <image>
      <title>파워 유튜버</title>
      <url>https://t1.daumcdn.net/cfile/tistory/224B3D455964859530</url>
      <link>https://bota.tistory.com</link>
    </image>
    <item>
      <title>[PCB#10] 아두이노(arduino) 보드를 직접 DIY할수 있는 PCB, PCBA 주문해보기 이어서 해보기!(녹칸다 easyeda시리즈)</title>
      <link>https://bota.tistory.com/2492</link>
      <description>&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;easyeda.png&quot; data-origin-width=&quot;1920&quot; data-origin-height=&quot;1080&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/caQjGN/dJMcaiXj7Jh/EG1f3zvElYbO3AO9qoGQp1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/caQjGN/dJMcaiXj7Jh/EG1f3zvElYbO3AO9qoGQp1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/caQjGN/dJMcaiXj7Jh/EG1f3zvElYbO3AO9qoGQp1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FcaQjGN%2FdJMcaiXj7Jh%2FEG1f3zvElYbO3AO9qoGQp1%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;1920&quot; height=&quot;1080&quot; data-filename=&quot;easyeda.png&quot; data-origin-width=&quot;1920&quot; data-origin-height=&quot;1080&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/live/WpEBJfxD1Zc&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://youtube.com/live/WpEBJfxD1Zc&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/watch?v=WpEBJfxD1Zc&quot; data-video-thumbnail=&quot;https://scrap.kakaocdn.net/dn/c55Wm4/dJMb8SpKigL/RhwACIBuUfPC2JGSmm7c2k/img.jpg?width=1280&amp;amp;height=720&amp;amp;face=0_0_1280_720,https://scrap.kakaocdn.net/dn/Vf7L2/dJMb8SpKigM/vLcK0fvKfTkyxsxc6G9yW1/img.jpg?width=1280&amp;amp;height=720&amp;amp;face=0_0_1280_720&quot; data-video-width=&quot;860&quot; data-video-height=&quot;484&quot; data-video-origin-width=&quot;860&quot; data-video-origin-height=&quot;484&quot; data-ke-mobilestyle=&quot;widthContent&quot; data-video-title=&quot;심심한녹칸다&quot; data-original-url=&quot;&quot;&gt;&lt;iframe src=&quot;https://www.youtube.com/embed/WpEBJfxD1Zc&quot; width=&quot;860&quot; height=&quot;484&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;[PCB#10]&amp;nbsp;아두이노(arduino)&amp;nbsp;보드를&amp;nbsp;직접&amp;nbsp;DIY할수&amp;nbsp;있는&amp;nbsp;PCB,&amp;nbsp;PCBA&amp;nbsp;주문해보기&amp;nbsp;이어서&amp;nbsp;해보기!(녹칸다&amp;nbsp;easyeda시리즈) &lt;br /&gt;&lt;br /&gt;심심한녹칸다의&amp;nbsp;easyeda로&amp;nbsp;PCB만들기&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;a href=&quot;https://docs.google.com/presentation/d/1UbMD0OMAamiVlwZupaN-_ZXcfirt9dmHdXeu39SRca0/edit?slide=id.g3d7fbab4ea2_1_120#slide=id.g3d7fbab4ea2_1_120&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://docs.google.com/presentation/d/1UbMD0OMAamiVlwZupaN-_ZXcfirt9dmHdXeu39SRca0/edit?slide=id.g3d7fbab4ea2_1_120#slide=id.g3d7fbab4ea2_1_120&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;아두이노&amp;nbsp;우노&amp;nbsp;SMT버전&amp;nbsp;만들어보기! &lt;br /&gt;&lt;br /&gt;00:00:00&amp;nbsp;전반적인&amp;nbsp;개요 &lt;br /&gt;00:07:16&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-filename=&quot;01.PNG&quot; data-origin-width=&quot;1153&quot; data-origin-height=&quot;562&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/btakvX/dJMcahD8tkV/X5NiQKqnHQleDTqDD5wnT0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/btakvX/dJMcahD8tkV/X5NiQKqnHQleDTqDD5wnT0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/btakvX/dJMcahD8tkV/X5NiQKqnHQleDTqDD5wnT0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbtakvX%2FdJMcahD8tkV%2FX5NiQKqnHQleDTqDD5wnT0%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;1153&quot; height=&quot;562&quot; data-filename=&quot;01.PNG&quot; data-origin-width=&quot;1153&quot; data-origin-height=&quot;562&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;02.PNG&quot; data-origin-width=&quot;813&quot; data-origin-height=&quot;577&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/mfUaw/dJMcadV1oGi/2G4jWzTqHnQy9IGLgHFkHK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/mfUaw/dJMcadV1oGi/2G4jWzTqHnQy9IGLgHFkHK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/mfUaw/dJMcadV1oGi/2G4jWzTqHnQy9IGLgHFkHK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FmfUaw%2FdJMcadV1oGi%2F2G4jWzTqHnQy9IGLgHFkHK%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;577&quot; data-filename=&quot;02.PNG&quot; data-origin-width=&quot;813&quot; data-origin-height=&quot;577&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;br /&gt;01:04:11&amp;nbsp;PCB편집하기! &lt;br /&gt;02:00:23&amp;nbsp;실크스크린넣기!02:10:22&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-filename=&quot;04.PNG&quot; data-origin-width=&quot;1149&quot; data-origin-height=&quot;525&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/dXxPzB/dJMcabDWP8O/YW7f8ONizkaGAMBkb0ajv0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/dXxPzB/dJMcabDWP8O/YW7f8ONizkaGAMBkb0ajv0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/dXxPzB/dJMcabDWP8O/YW7f8ONizkaGAMBkb0ajv0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FdXxPzB%2FdJMcabDWP8O%2FYW7f8ONizkaGAMBkb0ajv0%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;1149&quot; height=&quot;525&quot; data-filename=&quot;04.PNG&quot; data-origin-width=&quot;1149&quot; data-origin-height=&quot;525&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;br /&gt;02:20:03&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-filename=&quot;05.PNG&quot; data-origin-width=&quot;946&quot; data-origin-height=&quot;549&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/wtrcU/dJMcai34SDM/30Au8WLEpBR0a8V3sAN27K/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/wtrcU/dJMcai34SDM/30Au8WLEpBR0a8V3sAN27K/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/wtrcU/dJMcai34SDM/30Au8WLEpBR0a8V3sAN27K/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FwtrcU%2FdJMcai34SDM%2F30Au8WLEpBR0a8V3sAN27K%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;946&quot; height=&quot;549&quot; data-filename=&quot;05.PNG&quot; data-origin-width=&quot;946&quot; data-origin-height=&quot;549&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;</description>
      <category>프로그래밍/EasyEDA</category>
      <author>덕력킹</author>
      <guid isPermaLink="true">https://bota.tistory.com/2492</guid>
      <comments>https://bota.tistory.com/2492#entry2492comment</comments>
      <pubDate>Wed, 22 Apr 2026 21:01:29 +0900</pubDate>
    </item>
    <item>
      <title>[PCB#9] 아두이노(arduino) 보드를 직접 DIY할수 있는 PCB, PCBA 주문해보기!(녹칸다 easyeda시리즈)</title>
      <link>https://bota.tistory.com/2491</link>
      <description>&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;easyeda.png&quot; data-origin-width=&quot;1920&quot; data-origin-height=&quot;1080&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/2gsyg/dJMcai33hqg/cM8CPQsJMUcGP8ZDLVaMLk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/2gsyg/dJMcai33hqg/cM8CPQsJMUcGP8ZDLVaMLk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/2gsyg/dJMcai33hqg/cM8CPQsJMUcGP8ZDLVaMLk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2F2gsyg%2FdJMcai33hqg%2FcM8CPQsJMUcGP8ZDLVaMLk%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;1920&quot; height=&quot;1080&quot; data-filename=&quot;easyeda.png&quot; data-origin-width=&quot;1920&quot; data-origin-height=&quot;1080&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/live/7NV0KUawu6g&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://youtube.com/live/7NV0KUawu6g&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/watch?v=7NV0KUawu6g&quot; data-video-thumbnail=&quot;https://scrap.kakaocdn.net/dn/d54Umq/dJMb88e2KJG/ePPCHJTX1evkXsi8hSwkQk/img.jpg?width=1280&amp;amp;height=720&amp;amp;face=0_0_1280_720,https://scrap.kakaocdn.net/dn/ccJ6Hb/dJMb81fUIaV/wHQrzT1CAyK7tXjpMtB170/img.jpg?width=1280&amp;amp;height=720&amp;amp;face=0_0_1280_720,https://scrap.kakaocdn.net/dn/bqNGgw/dJMb81GZozy/ZBpbKnWjCwl8wVq9wKMAB0/img.jpg?width=1280&amp;amp;height=720&amp;amp;face=0_0_1280_720&quot; data-video-width=&quot;860&quot; data-video-height=&quot;484&quot; data-video-origin-width=&quot;860&quot; data-video-origin-height=&quot;484&quot; data-ke-mobilestyle=&quot;widthContent&quot; data-video-title=&quot;심심한녹칸다&quot; data-original-url=&quot;&quot;&gt;&lt;iframe src=&quot;https://www.youtube.com/embed/7NV0KUawu6g&quot; width=&quot;860&quot; height=&quot;484&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;[PCB#9]&amp;nbsp;아두이노(arduino)&amp;nbsp;보드를&amp;nbsp;직접&amp;nbsp;DIY할수&amp;nbsp;있는&amp;nbsp;PCB,&amp;nbsp;PCBA&amp;nbsp;주문해보기!(녹칸다&amp;nbsp;easyeda시리즈) &lt;br /&gt;&lt;br /&gt;심심한녹칸다의&amp;nbsp;easyeda로&amp;nbsp;PCB만들기&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;a href=&quot;https://docs.google.com/presentation/d/1UbMD0OMAamiVlwZupaN-_ZXcfirt9dmHdXeu39SRca0/edit?slide=id.g3d591aa4ff5_1_0#slide=id.g3d591aa4ff5_1_0&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://docs.google.com/presentation/d/1UbMD0OMAamiVlwZupaN-_ZXcfirt9dmHdXeu39SRca0/edit?slide=id.g3d591aa4ff5_1_0#slide=id.g3d591aa4ff5_1_0&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;아두이노&amp;nbsp;보드를&amp;nbsp;직접&amp;nbsp;만들어보기! &lt;br /&gt;&lt;br /&gt;00:00:00&amp;nbsp;전반적인&amp;nbsp;개요 &lt;br /&gt;00:10:26&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-filename=&quot;Schematic_easyeda09_01_2026-04-20.png&quot; data-origin-width=&quot;1169&quot; data-origin-height=&quot;827&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/byh9GZ/dJMcagFfQs7/keT5NqgFJ6Ixykp8goRtI1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/byh9GZ/dJMcagFfQs7/keT5NqgFJ6Ixykp8goRtI1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/byh9GZ/dJMcagFfQs7/keT5NqgFJ6Ixykp8goRtI1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fbyh9GZ%2FdJMcagFfQs7%2FkeT5NqgFJ6Ixykp8goRtI1%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;1169&quot; height=&quot;827&quot; data-filename=&quot;Schematic_easyeda09_01_2026-04-20.png&quot; data-origin-width=&quot;1169&quot; data-origin-height=&quot;827&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;01.PNG&quot; data-origin-width=&quot;1125&quot; data-origin-height=&quot;521&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/1Yx27/dJMcafM7mvL/M06Zx1c0sApZLhANWOzzC0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/1Yx27/dJMcafM7mvL/M06Zx1c0sApZLhANWOzzC0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/1Yx27/dJMcafM7mvL/M06Zx1c0sApZLhANWOzzC0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2F1Yx27%2FdJMcafM7mvL%2FM06Zx1c0sApZLhANWOzzC0%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;1125&quot; height=&quot;521&quot; data-filename=&quot;01.PNG&quot; data-origin-width=&quot;1125&quot; data-origin-height=&quot;521&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;br /&gt;01:52:17&amp;nbsp;DIY아두이노&amp;nbsp;보드&amp;nbsp;구동시키기! &lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;02.PNG&quot; data-origin-width=&quot;1060&quot; data-origin-height=&quot;529&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/7UMa1/dJMcad2Kwy5/Yuw9ILmulauX7hZiBeaFJ1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/7UMa1/dJMcad2Kwy5/Yuw9ILmulauX7hZiBeaFJ1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/7UMa1/dJMcad2Kwy5/Yuw9ILmulauX7hZiBeaFJ1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2F7UMa1%2FdJMcad2Kwy5%2FYuw9ILmulauX7hZiBeaFJ1%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;1060&quot; height=&quot;529&quot; data-filename=&quot;02.PNG&quot; data-origin-width=&quot;1060&quot; data-origin-height=&quot;529&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;</description>
      <category>프로그래밍/EasyEDA</category>
      <author>덕력킹</author>
      <guid isPermaLink="true">https://bota.tistory.com/2491</guid>
      <comments>https://bota.tistory.com/2491#entry2491comment</comments>
      <pubDate>Mon, 20 Apr 2026 23:07:10 +0900</pubDate>
    </item>
    <item>
      <title>[PCB#8] JLCPCB에서 PCB를 납땜까지 싹 해주는 PCBA주문하는 방법 알아보기!(녹칸다 easyeda시리즈)</title>
      <link>https://bota.tistory.com/2490</link>
      <description>&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;easyeda.png&quot; data-origin-width=&quot;1920&quot; data-origin-height=&quot;1080&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/baCCDo/dJMcaju0VI0/RpTJPXuy37MJfBYppfAP40/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/baCCDo/dJMcaju0VI0/RpTJPXuy37MJfBYppfAP40/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/baCCDo/dJMcaju0VI0/RpTJPXuy37MJfBYppfAP40/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbaCCDo%2FdJMcaju0VI0%2FRpTJPXuy37MJfBYppfAP40%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;1920&quot; height=&quot;1080&quot; data-filename=&quot;easyeda.png&quot; data-origin-width=&quot;1920&quot; data-origin-height=&quot;1080&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/live/DbeCEYEmf5g&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://youtube.com/live/DbeCEYEmf5g&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/watch?v=DbeCEYEmf5g&quot; data-video-thumbnail=&quot;https://scrap.kakaocdn.net/dn/cOtSHh/dJMb82eNSkV/I1uclmoOrQ6SNIS5xmkky0/img.jpg?width=1280&amp;amp;height=720&amp;amp;face=0_0_1280_720,https://scrap.kakaocdn.net/dn/cRb4O3/dJMb9bv282X/nUKosV5NjiIscvedADZBgk/img.jpg?width=1280&amp;amp;height=720&amp;amp;face=0_0_1280_720&quot; data-video-width=&quot;860&quot; data-video-height=&quot;484&quot; data-video-origin-width=&quot;860&quot; data-video-origin-height=&quot;484&quot; data-ke-mobilestyle=&quot;widthContent&quot; data-video-title=&quot;[PCB#8] JLCPCB에서 PCB를 납땜까지 싹 해주는 PCBA주문하는 방법 알아보기!(녹칸다 easyeda시리즈)&quot; data-original-url=&quot;&quot;&gt;&lt;iframe src=&quot;https://www.youtube.com/embed/DbeCEYEmf5g&quot; width=&quot;860&quot; height=&quot;484&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;[PCB#8]&amp;nbsp;JLCPCB에서&amp;nbsp;PCB를&amp;nbsp;납땜까지&amp;nbsp;싹&amp;nbsp;해주는&amp;nbsp;PCBA주문하는&amp;nbsp;방법&amp;nbsp;알아보기!(녹칸다&amp;nbsp;easyeda시리즈) &lt;br /&gt;&lt;br /&gt;심심한녹칸다의&amp;nbsp;easyeda로&amp;nbsp;PCB만들기&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;a href=&quot;https://docs.google.com/presentation/d/1UbMD0OMAamiVlwZupaN-_ZXcfirt9dmHdXeu39SRca0/edit?slide=id.g3d4bd6fa2c8_1_184#slide=id.g3d4bd6fa2c8_1_184&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://docs.google.com/presentation/d/1UbMD0OMAamiVlwZupaN-_ZXcfirt9dmHdXeu39SRca0/edit?slide=id.g3d4bd6fa2c8_1_184#slide=id.g3d4bd6fa2c8_1_184&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;PCBA주문&amp;nbsp;해보기! &lt;br /&gt;&lt;br /&gt;00:00:00&amp;nbsp;전반적인&amp;nbsp;개요 &lt;br /&gt;00:01:44&amp;nbsp;PCBA주문을&amp;nbsp;위한&amp;nbsp;사전&amp;nbsp;준비작업 &lt;br /&gt;00:14:24&amp;nbsp;PCBA주문&amp;nbsp;시나리오1 &lt;br /&gt;00:57:21&amp;nbsp;시나리오1번에서&amp;nbsp;수동으로&amp;nbsp;업로드&amp;nbsp;하는&amp;nbsp;경우! &lt;br /&gt;01:07:37&amp;nbsp;이코노믹&amp;nbsp;주문과&amp;nbsp;스탠다드&amp;nbsp;주문의&amp;nbsp;차이! &lt;br /&gt;01:18:04&amp;nbsp;다른사람이&amp;nbsp;만든&amp;nbsp;PCB를&amp;nbsp;PCBA주문해보기!(시나리오2) &lt;br /&gt;01:47:01&amp;nbsp;JLCPCB쪽&amp;nbsp;주문화면에서&amp;nbsp;실시간으로&amp;nbsp;부품을&amp;nbsp;교체하기!(시나리오3) &lt;br /&gt;02:00:33&amp;nbsp;JLCPCB엔지니어의&amp;nbsp;피드백 &lt;/p&gt;</description>
      <category>프로그래밍/EasyEDA</category>
      <author>덕력킹</author>
      <guid isPermaLink="true">https://bota.tistory.com/2490</guid>
      <comments>https://bota.tistory.com/2490#entry2490comment</comments>
      <pubDate>Wed, 8 Apr 2026 15:20:35 +0900</pubDate>
    </item>
    <item>
      <title>[PCB#7] 본격 PCB를 JLCPCB에 주문하는 방법과 절차를 알아보기!(녹칸다 easyeda시리즈)</title>
      <link>https://bota.tistory.com/2489</link>
      <description>&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;easyeda.png&quot; data-origin-width=&quot;1920&quot; data-origin-height=&quot;1080&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/pEfLt/dJMcaaLCcUP/8seDKBxeDgdk5w03knxnL0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/pEfLt/dJMcaaLCcUP/8seDKBxeDgdk5w03knxnL0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/pEfLt/dJMcaaLCcUP/8seDKBxeDgdk5w03knxnL0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FpEfLt%2FdJMcaaLCcUP%2F8seDKBxeDgdk5w03knxnL0%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;1920&quot; height=&quot;1080&quot; data-filename=&quot;easyeda.png&quot; data-origin-width=&quot;1920&quot; data-origin-height=&quot;1080&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/live/PA7uLXogXkE&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://youtube.com/live/PA7uLXogXkE&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/watch?v=PA7uLXogXkE&quot; data-video-thumbnail=&quot;https://scrap.kakaocdn.net/dn/GB401/dJMb9fZv1V5/cV2fxAk5aHNpnwaAzCOioK/img.jpg?width=1280&amp;amp;height=720&amp;amp;face=0_0_1280_720,https://scrap.kakaocdn.net/dn/J1pvz/dJMb8PGwPQf/4KWVcLek4kITm7NyQ3nhyk/img.jpg?width=1280&amp;amp;height=720&amp;amp;face=0_0_1280_720&quot; data-video-width=&quot;860&quot; data-video-height=&quot;484&quot; data-video-origin-width=&quot;860&quot; data-video-origin-height=&quot;484&quot; data-ke-mobilestyle=&quot;widthContent&quot; data-video-title=&quot;[PCB#7] 본격 PCB를 JLCPCB에 주문하는 방법과 절차를 알아보기!(녹칸다 easyeda시리즈)&quot; data-original-url=&quot;&quot;&gt;&lt;iframe src=&quot;https://www.youtube.com/embed/PA7uLXogXkE&quot; width=&quot;860&quot; height=&quot;484&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;[PCB#7]&amp;nbsp;본격&amp;nbsp;PCB를&amp;nbsp;JLCPCB에&amp;nbsp;주문하는&amp;nbsp;방법과&amp;nbsp;절차를&amp;nbsp;알아보기!(녹칸다&amp;nbsp;easyeda시리즈) &lt;br /&gt;&lt;br /&gt;심심한녹칸다의&amp;nbsp;easyeda로&amp;nbsp;PCB만들기&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;a href=&quot;https://docs.google.com/presentation/d/1UbMD0OMAamiVlwZupaN-_ZXcfirt9dmHdXeu39SRca0/edit?slide=id.g3d49c472ec1_1_0#slide=id.g3d49c472ec1_1_0&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://docs.google.com/presentation/d/1UbMD0OMAamiVlwZupaN-_ZXcfirt9dmHdXeu39SRca0/edit?slide=id.g3d49c472ec1_1_0#slide=id.g3d49c472ec1_1_0&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;PCB생산하기! &lt;br /&gt;&lt;br /&gt;00:00:00&amp;nbsp;전반적인&amp;nbsp;개요 &lt;br /&gt;00:04:31&amp;nbsp;녹칸다가&amp;nbsp;생각하는&amp;nbsp;PCB주문의&amp;nbsp;유형 &lt;br /&gt;00:09:11&amp;nbsp;PCB와&amp;nbsp;PCBA주문의&amp;nbsp;방식 &lt;br /&gt;00:19:23&amp;nbsp;PCB주문하기&amp;nbsp;간딴&amp;nbsp;방법&amp;nbsp;실습! &lt;br /&gt;00:59:18&amp;nbsp;주문이&amp;nbsp;완료된&amp;nbsp;상태에서&amp;nbsp;벌어지는일들 &lt;br /&gt;01:06:30&amp;nbsp;PCB를&amp;nbsp;거버파일로&amp;nbsp;주문하는&amp;nbsp;방식의&amp;nbsp;실습 &lt;br /&gt;01:11:36&amp;nbsp;패널화에&amp;nbsp;대해서&amp;nbsp;알아보기! &lt;br /&gt;01:26:59&amp;nbsp;V-CUT에&amp;nbsp;대해서&amp;nbsp;알아보기! &lt;br /&gt;01:53:46&amp;nbsp;마우스바이트에&amp;nbsp;대해서&amp;nbsp;알아보기!&lt;/p&gt;</description>
      <category>프로그래밍/EasyEDA</category>
      <author>덕력킹</author>
      <guid isPermaLink="true">https://bota.tistory.com/2489</guid>
      <comments>https://bota.tistory.com/2489#entry2489comment</comments>
      <pubDate>Mon, 6 Apr 2026 22:54:43 +0900</pubDate>
    </item>
    <item>
      <title>[PCB#6] PCB를 멋지게 꾸미기 위한 확장스크립트(Label Maker, Smooth Tracks, QRCode)에 대해 알아보기!(녹칸다 easyeda시리즈)</title>
      <link>https://bota.tistory.com/2488</link>
      <description>&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;easyeda.png&quot; data-origin-width=&quot;1920&quot; data-origin-height=&quot;1080&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/oYz3s/dJMcaaLyeOK/jjZXycsOnGAtvYpBfggJV1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/oYz3s/dJMcaaLyeOK/jjZXycsOnGAtvYpBfggJV1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/oYz3s/dJMcaaLyeOK/jjZXycsOnGAtvYpBfggJV1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FoYz3s%2FdJMcaaLyeOK%2FjjZXycsOnGAtvYpBfggJV1%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;1920&quot; height=&quot;1080&quot; data-filename=&quot;easyeda.png&quot; data-origin-width=&quot;1920&quot; data-origin-height=&quot;1080&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/live/wGWx_PczMaA&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://youtube.com/live/wGWx_PczMaA&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/watch?v=wGWx_PczMaA&quot; data-video-thumbnail=&quot;https://scrap.kakaocdn.net/dn/xLw20/dJMb9efecLc/kHObhL44UYcFdofCXeFAnK/img.jpg?width=1280&amp;amp;height=720&amp;amp;face=0_0_1280_720,https://scrap.kakaocdn.net/dn/bOhYAR/dJMb9iaRnOb/Z3kI8IJbsIehkhnG5fPHd1/img.jpg?width=1280&amp;amp;height=720&amp;amp;face=0_0_1280_720,https://scrap.kakaocdn.net/dn/HQNcq/dJMb89ydPiI/p3nBjteMq5d0kExeFkryI1/img.jpg?width=1280&amp;amp;height=720&amp;amp;face=0_0_1280_720&quot; data-video-width=&quot;860&quot; data-video-height=&quot;484&quot; data-video-origin-width=&quot;860&quot; data-video-origin-height=&quot;484&quot; data-ke-mobilestyle=&quot;widthContent&quot; data-video-title=&quot;[PCB#6] PCB를 멋지게 꾸미기 위한 확장스크립트(Label Maker, Smooth Tracks, QRCode)에 대해 알아보기!(녹칸&quot; data-original-url=&quot;&quot;&gt;&lt;iframe src=&quot;https://www.youtube.com/embed/wGWx_PczMaA&quot; width=&quot;860&quot; height=&quot;484&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;[PCB#6]&amp;nbsp;PCB를&amp;nbsp;멋지게&amp;nbsp;꾸미기&amp;nbsp;위한&amp;nbsp;확장스크립트(Label&amp;nbsp;Maker,&amp;nbsp;Smooth&amp;nbsp;Tracks,&amp;nbsp;QRCode)에&amp;nbsp;대해&amp;nbsp;알아보기!(녹칸다&amp;nbsp;easyeda시리즈) &lt;br /&gt;&lt;br /&gt;심심한녹칸다의&amp;nbsp;easyeda로&amp;nbsp;PCB만들기&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;a href=&quot;https://docs.google.com/presentation/d/1UbMD0OMAamiVlwZupaN-_ZXcfirt9dmHdXeu39SRca0/edit?slide=id.g3d363c4382e_1_219#slide=id.g3d363c4382e_1_219&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://docs.google.com/presentation/d/1UbMD0OMAamiVlwZupaN-_ZXcfirt9dmHdXeu39SRca0/edit?slide=id.g3d363c4382e_1_219#slide=id.g3d363c4382e_1_219&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;PCB꾸며보기! &lt;br /&gt;&lt;br /&gt;00:00:00&amp;nbsp;전반적인&amp;nbsp;개요 &lt;br /&gt;00:03:57&amp;nbsp;Label&amp;nbsp;Maker&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-filename=&quot;01.PNG&quot; data-origin-width=&quot;1363&quot; data-origin-height=&quot;701&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/3v4g9/dJMcafe3v6r/MAOGCWD6Pqc25ZWQaHUhGK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/3v4g9/dJMcafe3v6r/MAOGCWD6Pqc25ZWQaHUhGK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/3v4g9/dJMcafe3v6r/MAOGCWD6Pqc25ZWQaHUhGK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2F3v4g9%2FdJMcafe3v6r%2FMAOGCWD6Pqc25ZWQaHUhGK%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;1363&quot; height=&quot;701&quot; data-filename=&quot;01.PNG&quot; data-origin-width=&quot;1363&quot; data-origin-height=&quot;701&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;br /&gt;00:18:10&amp;nbsp;smooth&amp;nbsp;track&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-filename=&quot;02.PNG&quot; data-origin-width=&quot;1260&quot; data-origin-height=&quot;613&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/zJEkc/dJMcafe3v6w/KyZ2RV067kGN28vOw1PWcK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/zJEkc/dJMcafe3v6w/KyZ2RV067kGN28vOw1PWcK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/zJEkc/dJMcafe3v6w/KyZ2RV067kGN28vOw1PWcK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FzJEkc%2FdJMcafe3v6w%2FKyZ2RV067kGN28vOw1PWcK%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;1260&quot; height=&quot;613&quot; data-filename=&quot;02.PNG&quot; data-origin-width=&quot;1260&quot; data-origin-height=&quot;613&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;br /&gt;00:31:10&amp;nbsp;QRcode&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-filename=&quot;03.PNG&quot; data-origin-width=&quot;477&quot; data-origin-height=&quot;433&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/PUXuh/dJMcafe3v6B/9LnE57hk54yaBAgGYKzwp1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/PUXuh/dJMcafe3v6B/9LnE57hk54yaBAgGYKzwp1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/PUXuh/dJMcafe3v6B/9LnE57hk54yaBAgGYKzwp1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FPUXuh%2FdJMcafe3v6B%2F9LnE57hk54yaBAgGYKzwp1%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;477&quot; height=&quot;433&quot; data-filename=&quot;03.PNG&quot; data-origin-width=&quot;477&quot; data-origin-height=&quot;433&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;br /&gt;00:38:00&amp;nbsp;응용예제1&amp;nbsp;온습도센서&amp;nbsp;측정보드!&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;04.PNG&quot; data-origin-width=&quot;1300&quot; data-origin-height=&quot;483&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/QLE7j/dJMcafe3v6H/CsHuUAgecSlcyEDQlxfRtK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/QLE7j/dJMcafe3v6H/CsHuUAgecSlcyEDQlxfRtK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/QLE7j/dJMcafe3v6H/CsHuUAgecSlcyEDQlxfRtK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FQLE7j%2FdJMcafe3v6H%2FCsHuUAgecSlcyEDQlxfRtK%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;1300&quot; height=&quot;483&quot; data-filename=&quot;04.PNG&quot; data-origin-width=&quot;1300&quot; data-origin-height=&quot;483&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;br /&gt;01:19:46&amp;nbsp;응용예제2&amp;nbsp;부저보드!&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;05.PNG&quot; data-origin-width=&quot;1291&quot; data-origin-height=&quot;639&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/eqytQm/dJMb996Wnx4/w9vt4Kai1Hn4EeO3CsTUE0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/eqytQm/dJMb996Wnx4/w9vt4Kai1Hn4EeO3CsTUE0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/eqytQm/dJMb996Wnx4/w9vt4Kai1Hn4EeO3CsTUE0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FeqytQm%2FdJMb996Wnx4%2Fw9vt4Kai1Hn4EeO3CsTUE0%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;1291&quot; height=&quot;639&quot; data-filename=&quot;05.PNG&quot; data-origin-width=&quot;1291&quot; data-origin-height=&quot;639&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;br /&gt;02:02:10&amp;nbsp;응용예제3&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-filename=&quot;06.PNG&quot; data-origin-width=&quot;1276&quot; data-origin-height=&quot;560&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/noXaq/dJMcadVLbhq/Cfk6CEhJtFbjBf2n4v3aw0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/noXaq/dJMcadVLbhq/Cfk6CEhJtFbjBf2n4v3aw0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/noXaq/dJMcadVLbhq/Cfk6CEhJtFbjBf2n4v3aw0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FnoXaq%2FdJMcadVLbhq%2FCfk6CEhJtFbjBf2n4v3aw0%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;1276&quot; height=&quot;560&quot; data-filename=&quot;06.PNG&quot; data-origin-width=&quot;1276&quot; data-origin-height=&quot;560&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;</description>
      <category>프로그래밍/EasyEDA</category>
      <author>덕력킹</author>
      <guid isPermaLink="true">https://bota.tistory.com/2488</guid>
      <comments>https://bota.tistory.com/2488#entry2488comment</comments>
      <pubDate>Wed, 1 Apr 2026 15:58:43 +0900</pubDate>
    </item>
    <item>
      <title>[PCB#5] 녹칸다가 주로 사용하는 커넥터(connector)에 대해서 알아보기!(녹칸다 easyeda시리즈)</title>
      <link>https://bota.tistory.com/2487</link>
      <description>&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;easyeda.png&quot; data-origin-width=&quot;1920&quot; data-origin-height=&quot;1080&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/ylwbh/dJMcabcy9ND/bDorKieFQ0SBTJCXolCLB1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/ylwbh/dJMcabcy9ND/bDorKieFQ0SBTJCXolCLB1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/ylwbh/dJMcabcy9ND/bDorKieFQ0SBTJCXolCLB1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fylwbh%2FdJMcabcy9ND%2FbDorKieFQ0SBTJCXolCLB1%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;1920&quot; height=&quot;1080&quot; data-filename=&quot;easyeda.png&quot; data-origin-width=&quot;1920&quot; data-origin-height=&quot;1080&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/live/q0Gt68rqRp8&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://youtube.com/live/q0Gt68rqRp8&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/watch?v=q0Gt68rqRp8&quot; data-video-thumbnail=&quot;https://scrap.kakaocdn.net/dn/w1TC6/dJMb86nXDCe/4CAM00kAOLvrBDjBI7FMD1/img.jpg?width=1280&amp;amp;height=720&amp;amp;face=0_0_1280_720,https://scrap.kakaocdn.net/dn/r1E0T/dJMb86nXDCf/poqgJTN9PRxMFqXvXYjhcK/img.jpg?width=1280&amp;amp;height=720&amp;amp;face=0_0_1280_720,https://scrap.kakaocdn.net/dn/CjM30/dJMb84p8LdX/lfJrfcsc79KKa7H9VCyTok/img.jpg?width=1280&amp;amp;height=720&amp;amp;face=0_0_1280_720&quot; data-video-width=&quot;860&quot; data-video-height=&quot;484&quot; data-video-origin-width=&quot;860&quot; data-video-origin-height=&quot;484&quot; data-ke-mobilestyle=&quot;widthContent&quot; data-video-title=&quot;[PCB#5] 녹칸다가 주로 사용하는 커넥터(connector)에 대해서 알아보기!(녹칸다 easyeda시리즈)&quot; data-original-url=&quot;&quot;&gt;&lt;iframe src=&quot;https://www.youtube.com/embed/q0Gt68rqRp8&quot; width=&quot;860&quot; height=&quot;484&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;[PCB#5]&amp;nbsp;녹칸다가&amp;nbsp;주로&amp;nbsp;사용하는&amp;nbsp;커넥터(connector)에&amp;nbsp;대해서&amp;nbsp;알아보기!(녹칸다&amp;nbsp;easyeda시리즈) &lt;br /&gt;&lt;br /&gt;심심한녹칸다의&amp;nbsp;easyeda로&amp;nbsp;PCB만들기&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;a href=&quot;https://docs.google.com/presentation/d/1UbMD0OMAamiVlwZupaN-_ZXcfirt9dmHdXeu39SRca0/edit?slide=id.g3d339095204_1_160#slide=id.g3d339095204_1_160&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://docs.google.com/presentation/d/1UbMD0OMAamiVlwZupaN-_ZXcfirt9dmHdXeu39SRca0/edit?slide=id.g3d339095204_1_160#slide=id.g3d339095204_1_160&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;녹칸다가&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;00:00:00&amp;nbsp;전반적인&amp;nbsp;개요 &lt;br /&gt;00:07:28&amp;nbsp;피치가5.0mm인&amp;nbsp;터미널블록(KF301)&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;01.PNG&quot; data-origin-width=&quot;906&quot; data-origin-height=&quot;357&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bnzKiM/dJMcahKEZwM/NKFRRjpVPXGvwlWCvLBFqk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bnzKiM/dJMcahKEZwM/NKFRRjpVPXGvwlWCvLBFqk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bnzKiM/dJMcahKEZwM/NKFRRjpVPXGvwlWCvLBFqk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbnzKiM%2FdJMcahKEZwM%2FNKFRRjpVPXGvwlWCvLBFqk%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;906&quot; height=&quot;357&quot; data-filename=&quot;01.PNG&quot; data-origin-width=&quot;906&quot; data-origin-height=&quot;357&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;br /&gt;00:24:36&amp;nbsp;U자케이블을&amp;nbsp;PCB에&amp;nbsp;연결하는&amp;nbsp;터미널블록&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;02.PNG&quot; data-origin-width=&quot;1047&quot; data-origin-height=&quot;293&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/IRl3k/dJMcahw7Krn/SZeJnZ0xhCwnpSkbNioMm0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/IRl3k/dJMcahw7Krn/SZeJnZ0xhCwnpSkbNioMm0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/IRl3k/dJMcahw7Krn/SZeJnZ0xhCwnpSkbNioMm0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FIRl3k%2FdJMcahw7Krn%2FSZeJnZ0xhCwnpSkbNioMm0%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;1047&quot; height=&quot;293&quot; data-filename=&quot;02.PNG&quot; data-origin-width=&quot;1047&quot; data-origin-height=&quot;293&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;br /&gt;00:47:11&amp;nbsp;JST&amp;nbsp;XH2.54커넥터&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;03.PNG&quot; data-origin-width=&quot;1087&quot; data-origin-height=&quot;288&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cQaPKt/dJMcahw7Krp/dkRozaiCtDn5X4JjXZXQjK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cQaPKt/dJMcahw7Krp/dkRozaiCtDn5X4JjXZXQjK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cQaPKt/dJMcahw7Krp/dkRozaiCtDn5X4JjXZXQjK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FcQaPKt%2FdJMcahw7Krp%2FdkRozaiCtDn5X4JjXZXQjK%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;1087&quot; height=&quot;288&quot; data-filename=&quot;03.PNG&quot; data-origin-width=&quot;1087&quot; data-origin-height=&quot;288&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;br /&gt;01:12:27&amp;nbsp;MOLEX&amp;nbsp;5267&amp;nbsp;커넥터&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;04.PNG&quot; data-origin-width=&quot;1090&quot; data-origin-height=&quot;289&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/D08kQ/dJMcaard9Kz/jKniaidRsHg46j7hi4K6uK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/D08kQ/dJMcaard9Kz/jKniaidRsHg46j7hi4K6uK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/D08kQ/dJMcaard9Kz/jKniaidRsHg46j7hi4K6uK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FD08kQ%2FdJMcaard9Kz%2FjKniaidRsHg46j7hi4K6uK%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;1090&quot; height=&quot;289&quot; data-filename=&quot;04.PNG&quot; data-origin-width=&quot;1090&quot; data-origin-height=&quot;289&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;br /&gt;01:24:22&amp;nbsp;랜선&amp;nbsp;커넥터(RJ45)&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;05.PNG&quot; data-origin-width=&quot;1093&quot; data-origin-height=&quot;329&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/csyhNe/dJMcaard9KA/bFK508KGJZQ5DmK65fk571/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/csyhNe/dJMcaard9KA/bFK508KGJZQ5DmK65fk571/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/csyhNe/dJMcaard9KA/bFK508KGJZQ5DmK65fk571/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FcsyhNe%2FdJMcaard9KA%2FbFK508KGJZQ5DmK65fk571%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;1093&quot; height=&quot;329&quot; data-filename=&quot;05.PNG&quot; data-origin-width=&quot;1093&quot; data-origin-height=&quot;329&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;br /&gt;01:44:38&amp;nbsp;박스헤더커넥터&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;06.PNG&quot; data-origin-width=&quot;1107&quot; data-origin-height=&quot;328&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/beanxd/dJMcaard9KB/4VJMk4s9sLpWuYKknOZBa0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/beanxd/dJMcaard9KB/4VJMk4s9sLpWuYKknOZBa0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/beanxd/dJMcaard9KB/4VJMk4s9sLpWuYKknOZBa0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fbeanxd%2FdJMcaard9KB%2F4VJMk4s9sLpWuYKknOZBa0%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;1107&quot; height=&quot;328&quot; data-filename=&quot;06.PNG&quot; data-origin-width=&quot;1107&quot; data-origin-height=&quot;328&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;br /&gt;02:04:18&amp;nbsp;USB&amp;nbsp;A커넥터&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;07.PNG&quot; data-origin-width=&quot;972&quot; data-origin-height=&quot;372&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/che2j2/dJMcacP6w78/aqjj82JL88iwxbgGGNE1d1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/che2j2/dJMcacP6w78/aqjj82JL88iwxbgGGNE1d1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/che2j2/dJMcacP6w78/aqjj82JL88iwxbgGGNE1d1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fche2j2%2FdJMcacP6w78%2Faqjj82JL88iwxbgGGNE1d1%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;972&quot; height=&quot;372&quot; data-filename=&quot;07.PNG&quot; data-origin-width=&quot;972&quot; data-origin-height=&quot;372&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;br /&gt;02:16:34&amp;nbsp;USB&amp;nbsp;C커넥터&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;08.PNG&quot; data-origin-width=&quot;1059&quot; data-origin-height=&quot;489&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/PQtVy/dJMcac3BXtm/BTaMBgoAcfc5jOtgwlsNf0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/PQtVy/dJMcac3BXtm/BTaMBgoAcfc5jOtgwlsNf0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/PQtVy/dJMcac3BXtm/BTaMBgoAcfc5jOtgwlsNf0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FPQtVy%2FdJMcac3BXtm%2FBTaMBgoAcfc5jOtgwlsNf0%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;1059&quot; height=&quot;489&quot; data-filename=&quot;08.PNG&quot; data-origin-width=&quot;1059&quot; data-origin-height=&quot;489&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;br /&gt;02:19:46&amp;nbsp;MSL-1C2P&amp;nbsp;스위치&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;09.PNG&quot; data-origin-width=&quot;973&quot; data-origin-height=&quot;427&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cHk6Zd/dJMcaaEL9sh/DCHZnUKl1K0tldwnul6XF0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cHk6Zd/dJMcaaEL9sh/DCHZnUKl1K0tldwnul6XF0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cHk6Zd/dJMcaaEL9sh/DCHZnUKl1K0tldwnul6XF0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FcHk6Zd%2FdJMcaaEL9sh%2FDCHZnUKl1K0tldwnul6XF0%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;973&quot; height=&quot;427&quot; data-filename=&quot;09.PNG&quot; data-origin-width=&quot;973&quot; data-origin-height=&quot;427&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;br /&gt;02:30:19&amp;nbsp;로커&amp;nbsp;스위치&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;10.PNG&quot; data-origin-width=&quot;1063&quot; data-origin-height=&quot;403&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/dBbkxV/dJMcahDQWZf/2Al3H6Rk8KUrzrES99MRU1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/dBbkxV/dJMcahDQWZf/2Al3H6Rk8KUrzrES99MRU1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/dBbkxV/dJMcahDQWZf/2Al3H6Rk8KUrzrES99MRU1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FdBbkxV%2FdJMcahDQWZf%2F2Al3H6Rk8KUrzrES99MRU1%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;1063&quot; height=&quot;403&quot; data-filename=&quot;10.PNG&quot; data-origin-width=&quot;1063&quot; data-origin-height=&quot;403&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;</description>
      <category>프로그래밍/EasyEDA</category>
      <author>덕력킹</author>
      <guid isPermaLink="true">https://bota.tistory.com/2487</guid>
      <comments>https://bota.tistory.com/2487#entry2487comment</comments>
      <pubDate>Mon, 30 Mar 2026 23:01:50 +0900</pubDate>
    </item>
    <item>
      <title>[PCB#4] 심볼과 풋프린트를 직접 만들어서 사용해보기!(녹칸다 easyeda시리즈)</title>
      <link>https://bota.tistory.com/2486</link>
      <description>&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;easyeda.png&quot; data-origin-width=&quot;1920&quot; data-origin-height=&quot;1080&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/SWBYW/dJMcaaSe9OG/Rw2FSm2bHUXgMmKhHmoT4K/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/SWBYW/dJMcaaSe9OG/Rw2FSm2bHUXgMmKhHmoT4K/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/SWBYW/dJMcaaSe9OG/Rw2FSm2bHUXgMmKhHmoT4K/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FSWBYW%2FdJMcaaSe9OG%2FRw2FSm2bHUXgMmKhHmoT4K%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;1920&quot; height=&quot;1080&quot; data-filename=&quot;easyeda.png&quot; data-origin-width=&quot;1920&quot; data-origin-height=&quot;1080&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/live/7f7iAekQ17Q&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://youtube.com/live/7f7iAekQ17Q&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/watch?v=7f7iAekQ17Q&quot; data-video-thumbnail=&quot;https://scrap.kakaocdn.net/dn/sEMCz/dJMb9bv1Tga/NhSMyi2kcdlw69PXrVH7k1/img.jpg?width=1280&amp;amp;height=720&amp;amp;face=0_0_1280_720,https://scrap.kakaocdn.net/dn/1QVnW/dJMb9efdx4M/99NDfVdK95pPUB3BLIM2Mk/img.jpg?width=1280&amp;amp;height=720&amp;amp;face=0_0_1280_720,https://scrap.kakaocdn.net/dn/CNx7r/dJMb8U8Tb59/kbYOxdKnMgmQmwZT6NvaQk/img.jpg?width=1280&amp;amp;height=720&amp;amp;face=0_0_1280_720&quot; data-video-width=&quot;860&quot; data-video-height=&quot;484&quot; data-video-origin-width=&quot;860&quot; data-video-origin-height=&quot;484&quot; data-ke-mobilestyle=&quot;widthContent&quot; data-video-title=&quot;[PCB#4] 심볼과 풋프린트를 직접 만들어서 사용해보기!(녹칸다 easyeda시리즈)&quot; data-original-url=&quot;&quot;&gt;&lt;iframe src=&quot;https://www.youtube.com/embed/7f7iAekQ17Q&quot; width=&quot;860&quot; height=&quot;484&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;[PCB#4]&amp;nbsp;심볼과&amp;nbsp;풋프린트를&amp;nbsp;직접&amp;nbsp;만들어서&amp;nbsp;사용해보기!(녹칸다&amp;nbsp;easyeda시리즈) &lt;br /&gt;&lt;br /&gt;심심한녹칸다의&amp;nbsp;easyeda로&amp;nbsp;PCB만들기&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;a href=&quot;https://docs.google.com/presentation/d/1UbMD0OMAamiVlwZupaN-_ZXcfirt9dmHdXeu39SRca0/edit?slide=id.g3d1c0149169_1_210#slide=id.g3d1c0149169_1_210&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://docs.google.com/presentation/d/1UbMD0OMAamiVlwZupaN-_ZXcfirt9dmHdXeu39SRca0/edit?slide=id.g3d1c0149169_1_210#slide=id.g3d1c0149169_1_210&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;없으면&amp;nbsp;만들어서&amp;nbsp;쓰는&amp;nbsp;것! &lt;br /&gt;&lt;br /&gt;00:00:00 전반적인 개요&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;00:07:28&amp;nbsp;ADM101E라는&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-filename=&quot;11.PNG&quot; data-origin-width=&quot;422&quot; data-origin-height=&quot;427&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/r83SE/dJMcahcJuqT/bVI7lytx0mhPC0oUHA1dY0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/r83SE/dJMcahcJuqT/bVI7lytx0mhPC0oUHA1dY0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/r83SE/dJMcahcJuqT/bVI7lytx0mhPC0oUHA1dY0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fr83SE%2FdJMcahcJuqT%2FbVI7lytx0mhPC0oUHA1dY0%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;422&quot; height=&quot;427&quot; data-filename=&quot;11.PNG&quot; data-origin-width=&quot;422&quot; data-origin-height=&quot;427&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;22.PNG&quot; data-origin-width=&quot;329&quot; data-origin-height=&quot;266&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bztQk6/dJMcajn04y0/2LslEiK3ArSvIyM4ENC2s1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bztQk6/dJMcajn04y0/2LslEiK3ArSvIyM4ENC2s1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bztQk6/dJMcajn04y0/2LslEiK3ArSvIyM4ENC2s1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbztQk6%2FdJMcajn04y0%2F2LslEiK3ArSvIyM4ENC2s1%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;329&quot; height=&quot;266&quot; data-filename=&quot;22.PNG&quot; data-origin-width=&quot;329&quot; data-origin-height=&quot;266&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;br /&gt;00:39:39&amp;nbsp;10핀&amp;nbsp;헤더&amp;nbsp;그려보기!&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;33.PNG&quot; data-origin-width=&quot;473&quot; data-origin-height=&quot;470&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/TX2Ak/dJMcafeXJw2/qepr4brMq4EdlUjaHDReg1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/TX2Ak/dJMcafeXJw2/qepr4brMq4EdlUjaHDReg1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/TX2Ak/dJMcafeXJw2/qepr4brMq4EdlUjaHDReg1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FTX2Ak%2FdJMcafeXJw2%2Fqepr4brMq4EdlUjaHDReg1%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;473&quot; height=&quot;470&quot; data-filename=&quot;33.PNG&quot; data-origin-width=&quot;473&quot; data-origin-height=&quot;470&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;44.PNG&quot; data-origin-width=&quot;786&quot; data-origin-height=&quot;370&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bRQJSg/dJMcaibFzpK/uPURef1M3SExpbPE71hDzK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bRQJSg/dJMcaibFzpK/uPURef1M3SExpbPE71hDzK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bRQJSg/dJMcaibFzpK/uPURef1M3SExpbPE71hDzK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbRQJSg%2FdJMcaibFzpK%2FuPURef1M3SExpbPE71hDzK%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;786&quot; height=&quot;370&quot; data-filename=&quot;44.PNG&quot; data-origin-width=&quot;786&quot; data-origin-height=&quot;370&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;br /&gt;00:57:16&amp;nbsp;D55캐패시터&amp;nbsp;그려보기!&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;55.PNG&quot; data-origin-width=&quot;789&quot; data-origin-height=&quot;387&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/FbVJ4/dJMcacJian4/FGpnGvP5e2CUoX3w9Dz1m0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/FbVJ4/dJMcacJian4/FGpnGvP5e2CUoX3w9Dz1m0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/FbVJ4/dJMcacJian4/FGpnGvP5e2CUoX3w9Dz1m0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FFbVJ4%2FdJMcacJian4%2FFGpnGvP5e2CUoX3w9Dz1m0%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;789&quot; height=&quot;387&quot; data-filename=&quot;55.PNG&quot; data-origin-width=&quot;789&quot; data-origin-height=&quot;387&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;br /&gt;01:08:47&amp;nbsp;crystal그려보기!&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;66.PNG&quot; data-origin-width=&quot;1185&quot; data-origin-height=&quot;479&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/dKJDz2/dJMcagrmkkw/bvTnBG9CytoptIqwd4JJM1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/dKJDz2/dJMcagrmkkw/bvTnBG9CytoptIqwd4JJM1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/dKJDz2/dJMcagrmkkw/bvTnBG9CytoptIqwd4JJM1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FdKJDz2%2FdJMcagrmkkw%2FbvTnBG9CytoptIqwd4JJM1%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;1185&quot; height=&quot;479&quot; data-filename=&quot;66.PNG&quot; data-origin-width=&quot;1185&quot; data-origin-height=&quot;479&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;br /&gt;01:19:37&amp;nbsp;나머지&amp;nbsp;부품도&amp;nbsp;다&amp;nbsp;지정해서&amp;nbsp;전자캐드기능사를&amp;nbsp;easyeda버전으로&amp;nbsp;해보기!&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;Schematic_easyeda04_01_2026-03-24.png&quot; data-origin-width=&quot;1169&quot; data-origin-height=&quot;827&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/HioDS/dJMcajuPDhL/HeWN0K1Q9xQ9v3QBYeUeV0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/HioDS/dJMcajuPDhL/HeWN0K1Q9xQ9v3QBYeUeV0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/HioDS/dJMcajuPDhL/HeWN0K1Q9xQ9v3QBYeUeV0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FHioDS%2FdJMcajuPDhL%2FHeWN0K1Q9xQ9v3QBYeUeV0%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;1169&quot; height=&quot;827&quot; data-filename=&quot;Schematic_easyeda04_01_2026-03-24.png&quot; data-origin-width=&quot;1169&quot; data-origin-height=&quot;827&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;(그냥 오토라우팅 해버리기)&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;77.PNG&quot; data-origin-width=&quot;1242&quot; data-origin-height=&quot;546&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bqeldk/dJMcabcu8bJ/jWn0jy1tig8o7im8kYwsV0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bqeldk/dJMcabcu8bJ/jWn0jy1tig8o7im8kYwsV0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bqeldk/dJMcabcu8bJ/jWn0jy1tig8o7im8kYwsV0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fbqeldk%2FdJMcabcu8bJ%2FjWn0jy1tig8o7im8kYwsV0%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;1242&quot; height=&quot;546&quot; data-filename=&quot;77.PNG&quot; data-origin-width=&quot;1242&quot; data-origin-height=&quot;546&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;</description>
      <category>프로그래밍/EasyEDA</category>
      <author>덕력킹</author>
      <guid isPermaLink="true">https://bota.tistory.com/2486</guid>
      <comments>https://bota.tistory.com/2486#entry2486comment</comments>
      <pubDate>Wed, 25 Mar 2026 15:30:15 +0900</pubDate>
    </item>
    <item>
      <title>[PCB#3] 여러가지 상황별로 접근하는 방법과 해결하는 방법을 알아보기!(녹칸다 easyeda시리즈)</title>
      <link>https://bota.tistory.com/2485</link>
      <description>&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;easyeda.png&quot; data-origin-width=&quot;1920&quot; data-origin-height=&quot;1080&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/04DU4/dJMcahRiPzo/JAbcTnQ0lLV51YONYPSAKK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/04DU4/dJMcahRiPzo/JAbcTnQ0lLV51YONYPSAKK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/04DU4/dJMcahRiPzo/JAbcTnQ0lLV51YONYPSAKK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2F04DU4%2FdJMcahRiPzo%2FJAbcTnQ0lLV51YONYPSAKK%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;1920&quot; height=&quot;1080&quot; data-filename=&quot;easyeda.png&quot; data-origin-width=&quot;1920&quot; data-origin-height=&quot;1080&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/live/CMeNtMX9sm0&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://youtube.com/live/CMeNtMX9sm0&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/watch?v=CMeNtMX9sm0&quot; data-video-thumbnail=&quot;https://scrap.kakaocdn.net/dn/XghRd/dJMb9jOmn7L/8mNmZNZONJl9ErQXJe6GmK/img.jpg?width=1280&amp;amp;height=720&amp;amp;face=0_0_1280_720,https://scrap.kakaocdn.net/dn/ncH1K/dJMb9b3RuHc/JSgx2oP0wH9SjMOFLO0Pu1/img.jpg?width=1280&amp;amp;height=720&amp;amp;face=0_0_1280_720&quot; data-video-width=&quot;860&quot; data-video-height=&quot;484&quot; data-video-origin-width=&quot;860&quot; data-video-origin-height=&quot;484&quot; data-ke-mobilestyle=&quot;widthContent&quot; data-video-title=&quot;[PCB#3] 여러가지 상황별로 접근하는 방법과 해결하는 방법을 알아보기!(녹칸다 easyeda시리즈)&quot; data-original-url=&quot;&quot;&gt;&lt;iframe src=&quot;https://www.youtube.com/embed/CMeNtMX9sm0&quot; width=&quot;860&quot; height=&quot;484&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;[PCB#3]&amp;nbsp;여러가지&amp;nbsp;상황별로&amp;nbsp;접근하는&amp;nbsp;방법과&amp;nbsp;해결하는&amp;nbsp;방법을&amp;nbsp;알아보기!(녹칸다&amp;nbsp;easyeda시리즈) &lt;br /&gt;&lt;br /&gt;심심한녹칸다의&amp;nbsp;easyeda로&amp;nbsp;PCB만들기&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;a href=&quot;https://docs.google.com/presentation/d/1UbMD0OMAamiVlwZupaN-_ZXcfirt9dmHdXeu39SRca0/edit?slide=id.g3d19a36360e_1_0#slide=id.g3d19a36360e_1_0&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://docs.google.com/presentation/d/1UbMD0OMAamiVlwZupaN-_ZXcfirt9dmHdXeu39SRca0/edit?slide=id.g3d19a36360e_1_0#slide=id.g3d19a36360e_1_0&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;상황을&amp;nbsp;설정하고&amp;nbsp;해결하는&amp;nbsp;방법을&amp;nbsp;알아봅시다! &lt;br /&gt;&lt;br /&gt;00:00:00&amp;nbsp;전반적인&amp;nbsp;개요 &lt;br /&gt;00:03:15&amp;nbsp;클리어런스란&amp;nbsp;무엇인가요?&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;01.PNG&quot; data-origin-width=&quot;894&quot; data-origin-height=&quot;250&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bJRaLC/dJMcaciaTVm/tqW5EyFua1n8KZbxJ5GRfk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bJRaLC/dJMcaciaTVm/tqW5EyFua1n8KZbxJ5GRfk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bJRaLC/dJMcaciaTVm/tqW5EyFua1n8KZbxJ5GRfk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbJRaLC%2FdJMcaciaTVm%2FtqW5EyFua1n8KZbxJ5GRfk%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;894&quot; height=&quot;250&quot; data-filename=&quot;01.PNG&quot; data-origin-width=&quot;894&quot; data-origin-height=&quot;250&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;br /&gt;00:14:15&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-filename=&quot;02.PNG&quot; data-origin-width=&quot;1147&quot; data-origin-height=&quot;460&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/WGWNS/dJMcaciaTVo/uG14AzgRV7RqpiOoiltu40/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/WGWNS/dJMcaciaTVo/uG14AzgRV7RqpiOoiltu40/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/WGWNS/dJMcaciaTVo/uG14AzgRV7RqpiOoiltu40/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FWGWNS%2FdJMcaciaTVo%2FuG14AzgRV7RqpiOoiltu40%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;1147&quot; height=&quot;460&quot; data-filename=&quot;02.PNG&quot; data-origin-width=&quot;1147&quot; data-origin-height=&quot;460&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;br /&gt;00:21:36&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-filename=&quot;03.PNG&quot; data-origin-width=&quot;1097&quot; data-origin-height=&quot;255&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bDdxac/dJMcaciaTVr/NKs8o2xJdBUL6Poh7NREIK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bDdxac/dJMcaciaTVr/NKs8o2xJdBUL6Poh7NREIK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bDdxac/dJMcaciaTVr/NKs8o2xJdBUL6Poh7NREIK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbDdxac%2FdJMcaciaTVr%2FNKs8o2xJdBUL6Poh7NREIK%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;1097&quot; height=&quot;255&quot; data-filename=&quot;03.PNG&quot; data-origin-width=&quot;1097&quot; data-origin-height=&quot;255&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;br /&gt;00:29:55 배선이 완료된 상태에서 네트라벨이 변경되었을때 어떤 절차가 필요한가요?&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;00:39:20&amp;nbsp;배선을&amp;nbsp;하다보니&amp;nbsp;copper&amp;nbsp;pour에&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-filename=&quot;05.PNG&quot; data-origin-width=&quot;1102&quot; data-origin-height=&quot;360&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/ccN2we/dJMcagSpQP3/ofFweBuFr2ncGe9TlwCfo1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/ccN2we/dJMcagSpQP3/ofFweBuFr2ncGe9TlwCfo1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/ccN2we/dJMcagSpQP3/ofFweBuFr2ncGe9TlwCfo1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FccN2we%2FdJMcagSpQP3%2FofFweBuFr2ncGe9TlwCfo1%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;1102&quot; height=&quot;360&quot; data-filename=&quot;05.PNG&quot; data-origin-width=&quot;1102&quot; data-origin-height=&quot;360&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;br /&gt;00:51:03&amp;nbsp;내가&amp;nbsp;지정한&amp;nbsp;영역에&amp;nbsp;copper&amp;nbsp;pour를&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-filename=&quot;06.PNG&quot; data-origin-width=&quot;1068&quot; data-origin-height=&quot;353&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/JiZ3N/dJMcabDzs6k/vjHSQmPABhv1YXxUVqntt1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/JiZ3N/dJMcabDzs6k/vjHSQmPABhv1YXxUVqntt1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/JiZ3N/dJMcabDzs6k/vjHSQmPABhv1YXxUVqntt1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FJiZ3N%2FdJMcabDzs6k%2FvjHSQmPABhv1YXxUVqntt1%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;1068&quot; height=&quot;353&quot; data-filename=&quot;06.PNG&quot; data-origin-width=&quot;1068&quot; data-origin-height=&quot;353&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;br /&gt;01:06:58&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-filename=&quot;07.PNG&quot; data-origin-width=&quot;1141&quot; data-origin-height=&quot;333&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/ODM7q/dJMcafeVNXO/4otmG0WM2OAX2lMklRW6HK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/ODM7q/dJMcafeVNXO/4otmG0WM2OAX2lMklRW6HK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/ODM7q/dJMcafeVNXO/4otmG0WM2OAX2lMklRW6HK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FODM7q%2FdJMcafeVNXO%2F4otmG0WM2OAX2lMklRW6HK%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;1141&quot; height=&quot;333&quot; data-filename=&quot;07.PNG&quot; data-origin-width=&quot;1141&quot; data-origin-height=&quot;333&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;08.PNG&quot; data-origin-width=&quot;1159&quot; data-origin-height=&quot;379&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/b4Ffwo/dJMcafeVNXW/oGu1cePZRYkQbpQi59gPL0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/b4Ffwo/dJMcafeVNXW/oGu1cePZRYkQbpQi59gPL0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/b4Ffwo/dJMcafeVNXW/oGu1cePZRYkQbpQi59gPL0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fb4Ffwo%2FdJMcafeVNXW%2FoGu1cePZRYkQbpQi59gPL0%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;1159&quot; height=&quot;379&quot; data-filename=&quot;08.PNG&quot; data-origin-width=&quot;1159&quot; data-origin-height=&quot;379&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;br /&gt;&lt;br /&gt;01:25:16&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-filename=&quot;09.PNG&quot; data-origin-width=&quot;1137&quot; data-origin-height=&quot;340&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/RkNAM/dJMcafTvruc/CTnWX0o5Tj6WN2htKthFu0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/RkNAM/dJMcafTvruc/CTnWX0o5Tj6WN2htKthFu0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/RkNAM/dJMcafTvruc/CTnWX0o5Tj6WN2htKthFu0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FRkNAM%2FdJMcafTvruc%2FCTnWX0o5Tj6WN2htKthFu0%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;1137&quot; height=&quot;340&quot; data-filename=&quot;09.PNG&quot; data-origin-width=&quot;1137&quot; data-origin-height=&quot;340&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;br /&gt;&lt;br /&gt;01:36:49&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-filename=&quot;10.PNG&quot; data-origin-width=&quot;528&quot; data-origin-height=&quot;250&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bpCLos/dJMcaaxTNbW/NzMG1KBKQvscGytmznM8A1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bpCLos/dJMcaaxTNbW/NzMG1KBKQvscGytmznM8A1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bpCLos/dJMcaaxTNbW/NzMG1KBKQvscGytmznM8A1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbpCLos%2FdJMcaaxTNbW%2FNzMG1KBKQvscGytmznM8A1%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;250&quot; data-filename=&quot;10.PNG&quot; data-origin-width=&quot;528&quot; data-origin-height=&quot;250&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;br /&gt;02:00:30&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-filename=&quot;11.PNG&quot; data-origin-width=&quot;1120&quot; data-origin-height=&quot;571&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/QM1vZ/dJMcahRiPHt/N0Y4syFyUDKYqsXkWkpwg1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/QM1vZ/dJMcahRiPHt/N0Y4syFyUDKYqsXkWkpwg1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/QM1vZ/dJMcahRiPHt/N0Y4syFyUDKYqsXkWkpwg1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FQM1vZ%2FdJMcahRiPHt%2FN0Y4syFyUDKYqsXkWkpwg1%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;1120&quot; height=&quot;571&quot; data-filename=&quot;11.PNG&quot; data-origin-width=&quot;1120&quot; data-origin-height=&quot;571&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;br /&gt;02:17:22&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-filename=&quot;12.PNG&quot; data-origin-width=&quot;1145&quot; data-origin-height=&quot;576&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/botEc9/dJMcacvJcPB/khFYIHrK2bQJeZ3Vu1ZHI0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/botEc9/dJMcacvJcPB/khFYIHrK2bQJeZ3Vu1ZHI0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/botEc9/dJMcacvJcPB/khFYIHrK2bQJeZ3Vu1ZHI0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbotEc9%2FdJMcacvJcPB%2FkhFYIHrK2bQJeZ3Vu1ZHI0%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;1145&quot; height=&quot;576&quot; data-filename=&quot;12.PNG&quot; data-origin-width=&quot;1145&quot; data-origin-height=&quot;576&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;br /&gt;02:22:44&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 alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;13.PNG&quot; data-origin-width=&quot;1089&quot; data-origin-height=&quot;564&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/qyatW/dJMcabQ5nlS/zXPPJsCz2qyFlgT3vmehW0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/qyatW/dJMcabQ5nlS/zXPPJsCz2qyFlgT3vmehW0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/qyatW/dJMcabQ5nlS/zXPPJsCz2qyFlgT3vmehW0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FqyatW%2FdJMcabQ5nlS%2FzXPPJsCz2qyFlgT3vmehW0%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;1089&quot; height=&quot;564&quot; data-filename=&quot;13.PNG&quot; data-origin-width=&quot;1089&quot; data-origin-height=&quot;564&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;</description>
      <category>프로그래밍/EasyEDA</category>
      <author>덕력킹</author>
      <guid isPermaLink="true">https://bota.tistory.com/2485</guid>
      <comments>https://bota.tistory.com/2485#entry2485comment</comments>
      <pubDate>Mon, 23 Mar 2026 22:58:43 +0900</pubDate>
    </item>
    <item>
      <title>[PCB#2] 아두이노 나노(arduino nano)를 꽂아서 쓸수 있는 PCB보드 4종 디자인 해보기!(녹칸다 easyeda시리즈)</title>
      <link>https://bota.tistory.com/2484</link>
      <description>&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;easyeda.png&quot; data-origin-width=&quot;1920&quot; data-origin-height=&quot;1080&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/JP33J/dJMcaf6XcOX/z5HKrzdFX92QHqWqu6Ny7k/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/JP33J/dJMcaf6XcOX/z5HKrzdFX92QHqWqu6Ny7k/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/JP33J/dJMcaf6XcOX/z5HKrzdFX92QHqWqu6Ny7k/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FJP33J%2FdJMcaf6XcOX%2Fz5HKrzdFX92QHqWqu6Ny7k%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;1920&quot; height=&quot;1080&quot; data-filename=&quot;easyeda.png&quot; data-origin-width=&quot;1920&quot; data-origin-height=&quot;1080&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/live/FCLd38JWAwM&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://youtube.com/live/FCLd38JWAwM&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/watch?v=FCLd38JWAwM&quot; data-video-thumbnail=&quot;https://scrap.kakaocdn.net/dn/cyzxCU/dJMb9cBG6rE/sMEsRoreSJiR4xHpKz70jK/img.jpg?width=1280&amp;amp;height=720&amp;amp;face=0_0_1280_720,https://scrap.kakaocdn.net/dn/c9E2kX/dJMb9jgwctO/jPhrtgqkotdkItK4W8n1B0/img.jpg?width=1280&amp;amp;height=720&amp;amp;face=0_0_1280_720,https://scrap.kakaocdn.net/dn/6iWZX/dJMb9lMav91/c8mYHsmkSpi6KNgVp4tBj0/img.jpg?width=1280&amp;amp;height=720&amp;amp;face=0_0_1280_720&quot; data-video-width=&quot;860&quot; data-video-height=&quot;484&quot; data-video-origin-width=&quot;860&quot; data-video-origin-height=&quot;484&quot; data-ke-mobilestyle=&quot;widthContent&quot; data-video-title=&quot;[PCB#2] 아두이노 나노(arduino nano)를 꽂아서 쓸수 있는 PCB보드 4종 디자인 해보기!(녹칸다 easyeda시리&quot; data-original-url=&quot;&quot;&gt;&lt;iframe src=&quot;https://www.youtube.com/embed/FCLd38JWAwM&quot; width=&quot;860&quot; height=&quot;484&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;[PCB#2]&amp;nbsp;아두이노&amp;nbsp;나노(arduino&amp;nbsp;nano)를&amp;nbsp;꽂아서&amp;nbsp;쓸수&amp;nbsp;있는&amp;nbsp;PCB보드&amp;nbsp;4종&amp;nbsp;디자인&amp;nbsp;해보기!(녹칸다&amp;nbsp;easyeda시리즈) &lt;br /&gt;&lt;br /&gt;심심한녹칸다의&amp;nbsp;easyeda로&amp;nbsp;PCB만들기&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;a href=&quot;https://docs.google.com/presentation/d/1UbMD0OMAamiVlwZupaN-_ZXcfirt9dmHdXeu39SRca0/edit?slide=id.g3d7759b24b5_1_266#slide=id.g3d7759b24b5_1_266&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://docs.google.com/presentation/d/1UbMD0OMAamiVlwZupaN-_ZXcfirt9dmHdXeu39SRca0/edit?slide=id.g3d7759b24b5_1_266#slide=id.g3d7759b24b5_1_266&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;연습을&amp;nbsp;조금&amp;nbsp;해봅시다! &lt;br /&gt;&lt;br /&gt;1.아두이노&amp;nbsp;나노보드를&amp;nbsp;이용한&amp;nbsp;신호등&amp;nbsp;제어(LED3,&amp;nbsp;버튼3)&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;01.PNG&quot; data-origin-width=&quot;1001&quot; data-origin-height=&quot;647&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/OuvDJ/dJMcaadw23K/3gSu3F6E8kpvvv2ZNjCeu1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/OuvDJ/dJMcaadw23K/3gSu3F6E8kpvvv2ZNjCeu1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/OuvDJ/dJMcaadw23K/3gSu3F6E8kpvvv2ZNjCeu1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FOuvDJ%2FdJMcaadw23K%2F3gSu3F6E8kpvvv2ZNjCeu1%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;1001&quot; height=&quot;647&quot; data-filename=&quot;01.PNG&quot; data-origin-width=&quot;1001&quot; data-origin-height=&quot;647&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;02.PNG&quot; data-origin-width=&quot;1370&quot; data-origin-height=&quot;661&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bCKS0t/dJMcahcDqrG/wDhpp2jjbMD07JCJ8od6wK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bCKS0t/dJMcahcDqrG/wDhpp2jjbMD07JCJ8od6wK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bCKS0t/dJMcahcDqrG/wDhpp2jjbMD07JCJ8od6wK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbCKS0t%2FdJMcahcDqrG%2FwDhpp2jjbMD07JCJ8od6wK%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;1370&quot; height=&quot;661&quot; data-filename=&quot;02.PNG&quot; data-origin-width=&quot;1370&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;&lt;br /&gt;2.아두이노&amp;nbsp;나노보드를&amp;nbsp;이용한&amp;nbsp;서보모터&amp;nbsp;제어(with&amp;nbsp;가변저항)&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;03.PNG&quot; data-origin-width=&quot;945&quot; data-origin-height=&quot;532&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bKSj0T/dJMb996KMjV/tk1uKnd2VJAlT5QVxJJUF0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bKSj0T/dJMb996KMjV/tk1uKnd2VJAlT5QVxJJUF0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bKSj0T/dJMb996KMjV/tk1uKnd2VJAlT5QVxJJUF0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbKSj0T%2FdJMb996KMjV%2Ftk1uKnd2VJAlT5QVxJJUF0%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;945&quot; height=&quot;532&quot; data-filename=&quot;03.PNG&quot; data-origin-width=&quot;945&quot; data-origin-height=&quot;532&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;04.PNG&quot; data-origin-width=&quot;1355&quot; data-origin-height=&quot;605&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/B7gUb/dJMb996KMjU/2Etnm2UFlHPzNCGCkpuOyk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/B7gUb/dJMb996KMjU/2Etnm2UFlHPzNCGCkpuOyk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/B7gUb/dJMb996KMjU/2Etnm2UFlHPzNCGCkpuOyk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FB7gUb%2FdJMb996KMjU%2F2Etnm2UFlHPzNCGCkpuOyk%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;1355&quot; height=&quot;605&quot; data-filename=&quot;04.PNG&quot; data-origin-width=&quot;1355&quot; data-origin-height=&quot;605&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;br /&gt;3.아두이노&amp;nbsp;나노보드를&amp;nbsp;이용한&amp;nbsp;스탭모터&amp;nbsp;제어(버튼3)&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;05.PNG&quot; data-origin-width=&quot;825&quot; data-origin-height=&quot;657&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/buAbLO/dJMcacCpLWR/0DIRfEs0hw16OY446MUPI1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/buAbLO/dJMcacCpLWR/0DIRfEs0hw16OY446MUPI1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/buAbLO/dJMcacCpLWR/0DIRfEs0hw16OY446MUPI1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbuAbLO%2FdJMcacCpLWR%2F0DIRfEs0hw16OY446MUPI1%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;825&quot; height=&quot;657&quot; data-filename=&quot;05.PNG&quot; data-origin-width=&quot;825&quot; data-origin-height=&quot;657&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;06.PNG&quot; data-origin-width=&quot;1340&quot; data-origin-height=&quot;626&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bbic5l/dJMb99TcNuD/ABGmJlFS2kfsXi1bp5iARK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bbic5l/dJMb99TcNuD/ABGmJlFS2kfsXi1bp5iARK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bbic5l/dJMb99TcNuD/ABGmJlFS2kfsXi1bp5iARK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fbbic5l%2FdJMb99TcNuD%2FABGmJlFS2kfsXi1bp5iARK%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;1340&quot; height=&quot;626&quot; data-filename=&quot;06.PNG&quot; data-origin-width=&quot;1340&quot; data-origin-height=&quot;626&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;br /&gt;4.아두이노&amp;nbsp;나노보드를&amp;nbsp;이용한&amp;nbsp;모터드라이버&amp;nbsp;제어(버튼3,&amp;nbsp;가변저항)&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;07.PNG&quot; data-origin-width=&quot;932&quot; data-origin-height=&quot;644&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/dexpTS/dJMcajhbgOI/oKpOv0rdEh8v2zhQbR3Xck/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/dexpTS/dJMcajhbgOI/oKpOv0rdEh8v2zhQbR3Xck/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/dexpTS/dJMcajhbgOI/oKpOv0rdEh8v2zhQbR3Xck/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FdexpTS%2FdJMcajhbgOI%2FoKpOv0rdEh8v2zhQbR3Xck%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;932&quot; height=&quot;644&quot; data-filename=&quot;07.PNG&quot; data-origin-width=&quot;932&quot; data-origin-height=&quot;644&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;08.PNG&quot; data-origin-width=&quot;1288&quot; data-origin-height=&quot;607&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/C9xdd/dJMcajuJwiz/CHJlz3CevGysQQIYziHgwk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/C9xdd/dJMcajuJwiz/CHJlz3CevGysQQIYziHgwk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/C9xdd/dJMcajuJwiz/CHJlz3CevGysQQIYziHgwk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FC9xdd%2FdJMcajuJwiz%2FCHJlz3CevGysQQIYziHgwk%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;1288&quot; height=&quot;607&quot; data-filename=&quot;08.PNG&quot; data-origin-width=&quot;1288&quot; data-origin-height=&quot;607&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;</description>
      <category>프로그래밍/EasyEDA</category>
      <author>덕력킹</author>
      <guid isPermaLink="true">https://bota.tistory.com/2484</guid>
      <comments>https://bota.tistory.com/2484#entry2484comment</comments>
      <pubDate>Wed, 18 Mar 2026 19:00:31 +0900</pubDate>
    </item>
    <item>
      <title>[PCB#1] EasyEDA를 이용해서 취미용으로 PCB를 만드는 방법에 대해서 알아보자!(녹칸다 easyeda시리즈)</title>
      <link>https://bota.tistory.com/2483</link>
      <description>&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;easyeda.png&quot; data-origin-width=&quot;1920&quot; data-origin-height=&quot;1080&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bDRMT9/dJMcaflztSV/UiknErVQcyrZeMcukvfHtk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bDRMT9/dJMcaflztSV/UiknErVQcyrZeMcukvfHtk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bDRMT9/dJMcaflztSV/UiknErVQcyrZeMcukvfHtk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbDRMT9%2FdJMcaflztSV%2FUiknErVQcyrZeMcukvfHtk%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;1920&quot; height=&quot;1080&quot; data-filename=&quot;easyeda.png&quot; data-origin-width=&quot;1920&quot; data-origin-height=&quot;1080&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/live/I4hqlzPq2Cs&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://youtube.com/live/I4hqlzPq2Cs&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/watch?v=I4hqlzPq2Cs&quot; data-video-thumbnail=&quot;https://scrap.kakaocdn.net/dn/cnJwFk/dJMb8WMonIT/ttt69MPKV7LDuB21gakid1/img.jpg?width=1280&amp;amp;height=720&amp;amp;face=0_0_1280_720,https://scrap.kakaocdn.net/dn/cHIslO/dJMb8TB8okt/T92K3vyFXDDnBanzdsNVN1/img.jpg?width=1280&amp;amp;height=720&amp;amp;face=0_0_1280_720&quot; data-video-width=&quot;860&quot; data-video-height=&quot;484&quot; data-video-origin-width=&quot;860&quot; data-video-origin-height=&quot;484&quot; data-ke-mobilestyle=&quot;widthContent&quot; data-video-title=&quot;[PCB#1] EasyEDA를 이용해서 취미용으로 PCB를 만드는 방법에 대해서 알아보자!(녹칸다 easyeda시리즈)&quot; data-original-url=&quot;&quot;&gt;&lt;iframe src=&quot;https://www.youtube.com/embed/I4hqlzPq2Cs&quot; width=&quot;860&quot; height=&quot;484&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;[PCB#1]&amp;nbsp;EasyEDA를&amp;nbsp;이용해서&amp;nbsp;취미용으로&amp;nbsp;PCB를&amp;nbsp;만드는&amp;nbsp;방법에&amp;nbsp;대해서&amp;nbsp;알아보자!(녹칸다&amp;nbsp;easyeda시리즈) &lt;br /&gt;&lt;br /&gt;심심한녹칸다의&amp;nbsp;easyeda로&amp;nbsp;PCB만들기&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;a href=&quot;https://docs.google.com/presentation/d/1UbMD0OMAamiVlwZupaN-_ZXcfirt9dmHdXeu39SRca0/edit?slide=id.g3c5a9ea53db_0_6#slide=id.g3c5a9ea53db_0_6&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://docs.google.com/presentation/d/1UbMD0OMAamiVlwZupaN-_ZXcfirt9dmHdXeu39SRca0/edit?slide=id.g3c5a9ea53db_0_6#slide=id.g3c5a9ea53db_0_6&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;PCB만들기를&amp;nbsp;시작해봅시다! &lt;br /&gt;&lt;br /&gt;00:00:00&amp;nbsp;전반적인&amp;nbsp;목표&amp;nbsp;및&amp;nbsp;목적&amp;nbsp;설명 &lt;br /&gt;00:30:00&amp;nbsp;튜토리얼&amp;nbsp;예제&amp;nbsp;만들어보기! &lt;br /&gt;00:46:00&amp;nbsp;튜토리얼&amp;nbsp;예제&amp;nbsp;만들어보기! &lt;br /&gt;00:50:00&amp;nbsp;심볼,&amp;nbsp;전원&amp;nbsp;심볼,&amp;nbsp;네트,&amp;nbsp;네트라벨,&amp;nbsp;풋프린트,&amp;nbsp;참조라벨&amp;nbsp;용어&amp;nbsp;설명 &lt;br /&gt;01:27:00&amp;nbsp;TH부품과&amp;nbsp;SMD부품에&amp;nbsp;대해서&amp;nbsp;알아보기! &lt;br /&gt;01:34:00&amp;nbsp;패드(pad)와&amp;nbsp;비아(via)에&amp;nbsp;대해서&amp;nbsp;알아보기! &lt;br /&gt;01:50:00&amp;nbsp;레이어란&amp;nbsp;무엇인가? &lt;br /&gt;02:04:00&amp;nbsp;아두이노&amp;nbsp;나노를&amp;nbsp;이용한&amp;nbsp;간단한&amp;nbsp;PCB&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;(튜토리얼 예제의 PCB)&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;01.PNG&quot; data-origin-width=&quot;1038&quot; data-origin-height=&quot;597&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/baKsrR/dJMcadH0AEf/R3qG3MZxksPusjn8mm8rs0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/baKsrR/dJMcadH0AEf/R3qG3MZxksPusjn8mm8rs0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/baKsrR/dJMcadH0AEf/R3qG3MZxksPusjn8mm8rs0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbaKsrR%2FdJMcadH0AEf%2FR3qG3MZxksPusjn8mm8rs0%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;1038&quot; height=&quot;597&quot; data-filename=&quot;01.PNG&quot; data-origin-width=&quot;1038&quot; data-origin-height=&quot;597&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;02.PNG&quot; data-origin-width=&quot;777&quot; data-origin-height=&quot;578&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/mR3LD/dJMcadH0AEe/PDCUYQrliyMebPGrsKOqu1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/mR3LD/dJMcadH0AEe/PDCUYQrliyMebPGrsKOqu1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/mR3LD/dJMcadH0AEe/PDCUYQrliyMebPGrsKOqu1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FmR3LD%2FdJMcadH0AEe%2FPDCUYQrliyMebPGrsKOqu1%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;777&quot; height=&quot;578&quot; data-filename=&quot;02.PNG&quot; data-origin-width=&quot;777&quot; data-origin-height=&quot;578&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;(아두이노 나노를 연결해서 쓸수있는 PCB)&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;03.PNG&quot; data-origin-width=&quot;1167&quot; data-origin-height=&quot;528&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/c7sTpy/dJMcadBc3Ef/Y20KK8V8dCPgKQAkW3bHiK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/c7sTpy/dJMcadBc3Ef/Y20KK8V8dCPgKQAkW3bHiK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/c7sTpy/dJMcadBc3Ef/Y20KK8V8dCPgKQAkW3bHiK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fc7sTpy%2FdJMcadBc3Ef%2FY20KK8V8dCPgKQAkW3bHiK%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;1167&quot; height=&quot;528&quot; data-filename=&quot;03.PNG&quot; data-origin-width=&quot;1167&quot; data-origin-height=&quot;528&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;</description>
      <category>프로그래밍/EasyEDA</category>
      <author>덕력킹</author>
      <guid isPermaLink="true">https://bota.tistory.com/2483</guid>
      <comments>https://bota.tistory.com/2483#entry2483comment</comments>
      <pubDate>Mon, 16 Mar 2026 23:06:47 +0900</pubDate>
    </item>
    <item>
      <title>[STM32#40] TOUCHGFX와 CAN통신으로 PC와 통신하는 방법 알아보기!(녹칸다 내맘대로 STM32)</title>
      <link>https://bota.tistory.com/2482</link>
      <description>&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;stm32.png&quot; data-origin-width=&quot;1920&quot; data-origin-height=&quot;1080&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/uUneX/dJMcabjaarV/Bo6ZkJeW5BmnBkko64GPx1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/uUneX/dJMcabjaarV/Bo6ZkJeW5BmnBkko64GPx1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/uUneX/dJMcabjaarV/Bo6ZkJeW5BmnBkko64GPx1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FuUneX%2FdJMcabjaarV%2FBo6ZkJeW5BmnBkko64GPx1%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;1920&quot; height=&quot;1080&quot; data-filename=&quot;stm32.png&quot; data-origin-width=&quot;1920&quot; data-origin-height=&quot;1080&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/live/mpJLqsrDBf8&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://youtube.com/live/mpJLqsrDBf8&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/watch?v=mpJLqsrDBf8&quot; data-video-thumbnail=&quot;https://scrap.kakaocdn.net/dn/faupb/dJMb8U8R9u5/vcKdrshHqxoaokqHiYtpy1/img.jpg?width=1280&amp;amp;height=720&amp;amp;face=0_0_1280_720,https://scrap.kakaocdn.net/dn/KTCTZ/dJMb8PGuG9h/2ziHi4Wmzst5s0ng6Me7P0/img.jpg?width=1280&amp;amp;height=720&amp;amp;face=0_0_1280_720,https://scrap.kakaocdn.net/dn/cr1CuW/dJMb8Rj0sVf/rrkL0EWemLrCKHnZbi9Xy0/img.jpg?width=1280&amp;amp;height=720&amp;amp;face=0_0_1280_720&quot; data-video-width=&quot;860&quot; data-video-height=&quot;484&quot; data-video-origin-width=&quot;860&quot; data-video-origin-height=&quot;484&quot; data-ke-mobilestyle=&quot;widthContent&quot; data-video-title=&quot;[STM32#40] TOUCHGFX와 CAN통신으로 PC와 통신하는 방법 알아보기!(녹칸다 내맘대로 STM32)&quot; data-original-url=&quot;&quot;&gt;&lt;iframe src=&quot;https://www.youtube.com/embed/mpJLqsrDBf8&quot; width=&quot;860&quot; height=&quot;484&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;[STM32#40]&amp;nbsp;TOUCHGFX와&amp;nbsp;CAN통신으로&amp;nbsp;PC와&amp;nbsp;통신하는&amp;nbsp;방법&amp;nbsp;알아보기!(녹칸다&amp;nbsp;내맘대로&amp;nbsp;STM32) &lt;br /&gt;&lt;br /&gt;심심한녹칸다의&amp;nbsp;내맘대로&amp;nbsp;STM32시리즈이다! &lt;br /&gt;&lt;br /&gt;STM32시리즈의&amp;nbsp;모든&amp;nbsp;자료는&amp;nbsp;구글&amp;nbsp;슬라이드에&amp;nbsp;작성하고&amp;nbsp;모두에게&amp;nbsp;공유되어있음! &lt;br /&gt;&lt;a href=&quot;https://docs.google.com/presentation/d/1myA5iYbjuKsLWLqtRLKAiRfwUwvqB1d1RGjiMIIgp3I/edit?slide=id.g3c579db4ff3_1_219#slide=id.g3c579db4ff3_1_219&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://docs.google.com/presentation/d/1myA5iYbjuKsLWLqtRLKAiRfwUwvqB1d1RGjiMIIgp3I/edit?slide=id.g3c579db4ff3_1_219#slide=id.g3c579db4ff3_1_219&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;캔통신&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;span style=&quot;color: #ee2323;&quot;&gt;&lt;b&gt; (소스코드는 수정해야할 파일이 너무 많아서 위쪽 구글 슬라이드를 참고해주세용)&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;1.f746보드에&amp;nbsp;touchgfx로&amp;nbsp;버튼을&amp;nbsp;4개&amp;nbsp;생성하고&amp;nbsp;1번&amp;nbsp;버튼을&amp;nbsp;누르면&amp;nbsp;stm32가&amp;nbsp;전송하는&amp;nbsp;캔메시지에&amp;nbsp;1이라는&amp;nbsp;값이&amp;nbsp;포함되도록하고,&amp;nbsp;2번버튼을&amp;nbsp;누르면&amp;nbsp;2가&amp;nbsp;포함되도록&amp;nbsp;해서&amp;nbsp;PC쪽에서&amp;nbsp;데이터를&amp;nbsp;확인했을때&amp;nbsp;어떤&amp;nbsp;버튼이&amp;nbsp;눌려졌는지를&amp;nbsp;알수있도록&amp;nbsp;하시오!(STM32에서&amp;nbsp;터치해서&amp;nbsp;PC쪽으로&amp;nbsp;전송)&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;0.PNG&quot; data-origin-width=&quot;926&quot; data-origin-height=&quot;589&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bGNBsM/dJMcahKrqhw/vStGATVb3He30oceo1tEKK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bGNBsM/dJMcahKrqhw/vStGATVb3He30oceo1tEKK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bGNBsM/dJMcahKrqhw/vStGATVb3He30oceo1tEKK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbGNBsM%2FdJMcahKrqhw%2FvStGATVb3He30oceo1tEKK%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;926&quot; height=&quot;589&quot; data-filename=&quot;0.PNG&quot; data-origin-width=&quot;926&quot; data-origin-height=&quot;589&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;br /&gt;2.(예제1과&amp;nbsp;동시에&amp;nbsp;동작함)PC쪽&amp;nbsp;캔통신&amp;nbsp;프로그램에서&amp;nbsp;캔메시지를&amp;nbsp;전송하면&amp;nbsp;전송된&amp;nbsp;캔메시지를&amp;nbsp;touchgfx로&amp;nbsp;만든&amp;nbsp;UI에&amp;nbsp;출력되도록&amp;nbsp;하시오!&amp;nbsp;캔메시지는&amp;nbsp;8개의&amp;nbsp;byte로&amp;nbsp;구성되도록하고&amp;nbsp;8개의&amp;nbsp;byte값을&amp;nbsp;8개의&amp;nbsp;textarea를&amp;nbsp;이용해서&amp;nbsp;출력하시오!(PC에서&amp;nbsp;STM32쪽으로&amp;nbsp;전송)&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;02.PNG&quot; data-origin-width=&quot;1223&quot; data-origin-height=&quot;489&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bbqWbz/dJMcahRbkwp/rsl22DvvRuBj1UaSvEivQk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bbqWbz/dJMcahRbkwp/rsl22DvvRuBj1UaSvEivQk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bbqWbz/dJMcahRbkwp/rsl22DvvRuBj1UaSvEivQk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbbqWbz%2FdJMcahRbkwp%2Frsl22DvvRuBj1UaSvEivQk%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;1223&quot; height=&quot;489&quot; data-filename=&quot;02.PNG&quot; data-origin-width=&quot;1223&quot; data-origin-height=&quot;489&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;</description>
      <category>프로그래밍/STM32</category>
      <author>덕력킹</author>
      <guid isPermaLink="true">https://bota.tistory.com/2482</guid>
      <comments>https://bota.tistory.com/2482#entry2482comment</comments>
      <pubDate>Fri, 13 Mar 2026 19:17:06 +0900</pubDate>
    </item>
    <item>
      <title>[STM32#39] TOUCHGFX와 RS485통신으로 modbus rtu 4채널릴레이와 온습도센서를 연동시켜보기!(녹칸다 내맘대로 STM32)</title>
      <link>https://bota.tistory.com/2481</link>
      <description>&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;stm32.png&quot; data-origin-width=&quot;1920&quot; data-origin-height=&quot;1080&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/eA41Xi/dJMcabKbmWw/zsLKLp3iBQ4uxhuzsAvcK1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/eA41Xi/dJMcabKbmWw/zsLKLp3iBQ4uxhuzsAvcK1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/eA41Xi/dJMcabKbmWw/zsLKLp3iBQ4uxhuzsAvcK1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FeA41Xi%2FdJMcabKbmWw%2FzsLKLp3iBQ4uxhuzsAvcK1%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;1920&quot; height=&quot;1080&quot; data-filename=&quot;stm32.png&quot; data-origin-width=&quot;1920&quot; data-origin-height=&quot;1080&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/live/OakFHTboOmw&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://youtube.com/live/OakFHTboOmw&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/watch?v=OakFHTboOmw&quot; data-video-thumbnail=&quot;https://scrap.kakaocdn.net/dn/dfjMv6/dJMb82eLcn2/bHKfkPXA4vosmfIDbD8Amk/img.jpg?width=1280&amp;amp;height=720&amp;amp;face=0_0_1280_720,https://scrap.kakaocdn.net/dn/cIHZZI/dJMb8951KUU/ojYrpJsSSyR6EWKNSfFCIK/img.jpg?width=1280&amp;amp;height=720&amp;amp;face=0_0_1280_720,https://scrap.kakaocdn.net/dn/c2XFjr/dJMb9aKDgWu/OJ74KWGZpf9E2Ox2sQqOmk/img.jpg?width=1280&amp;amp;height=720&amp;amp;face=0_0_1280_720&quot; data-video-width=&quot;860&quot; data-video-height=&quot;484&quot; data-video-origin-width=&quot;860&quot; data-video-origin-height=&quot;484&quot; data-ke-mobilestyle=&quot;widthContent&quot; data-video-title=&quot;[STM32#39] TOUCHGFX와 RS485통신으로 modbus rtu 4채널릴레이와 온습도센서를 연동시켜보기!(녹칸다 내맘&quot; data-original-url=&quot;&quot;&gt;&lt;iframe src=&quot;https://www.youtube.com/embed/OakFHTboOmw&quot; width=&quot;860&quot; height=&quot;484&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;[STM32#39]&amp;nbsp;TOUCHGFX와&amp;nbsp;RS485통신으로&amp;nbsp;modbus&amp;nbsp;rtu&amp;nbsp;4채널릴레이와&amp;nbsp;온습도센서를&amp;nbsp;연동시켜보기!(녹칸다&amp;nbsp;내맘대로&amp;nbsp;STM32) &lt;br /&gt;&lt;br /&gt;심심한녹칸다의&amp;nbsp;내맘대로&amp;nbsp;STM32시리즈이다! &lt;br /&gt;&lt;br /&gt;STM32시리즈의&amp;nbsp;모든&amp;nbsp;자료는&amp;nbsp;구글&amp;nbsp;슬라이드에&amp;nbsp;작성하고&amp;nbsp;모두에게&amp;nbsp;공유되어있음! &lt;br /&gt;&lt;a href=&quot;https://docs.google.com/presentation/d/1myA5iYbjuKsLWLqtRLKAiRfwUwvqB1d1RGjiMIIgp3I/edit?slide=id.g3cde51f01c7_2_0#slide=id.g3cde51f01c7_2_0&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://docs.google.com/presentation/d/1myA5iYbjuKsLWLqtRLKAiRfwUwvqB1d1RGjiMIIgp3I/edit?slide=id.g3cde51f01c7_2_0#slide=id.g3cde51f01c7_2_0&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;RS485통신과&amp;nbsp;modbus&amp;nbsp;rtu!&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;br /&gt;&lt;br /&gt;1.RS485모듈을&amp;nbsp;F746보드의&amp;nbsp;uart7에&amp;nbsp;연결하고&amp;nbsp;touchgfx로&amp;nbsp;버튼&amp;nbsp;8개를&amp;nbsp;작화해서&amp;nbsp;버튼을&amp;nbsp;터치했을때&amp;nbsp;4채널릴레이의&amp;nbsp;0~3번&amp;nbsp;채널까지의&amp;nbsp;릴레이를&amp;nbsp;on/off하는&amp;nbsp;기능을&amp;nbsp;구현하시오!(4채널릴레이의&amp;nbsp;ID는&amp;nbsp;1로&amp;nbsp;지정되어있음)&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;01.PNG&quot; data-origin-width=&quot;822&quot; data-origin-height=&quot;490&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/clariM/dJMcadVst99/FjSNFymQH8D4TI8hmeY3p0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/clariM/dJMcadVst99/FjSNFymQH8D4TI8hmeY3p0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/clariM/dJMcadVst99/FjSNFymQH8D4TI8hmeY3p0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FclariM%2FdJMcadVst99%2FFjSNFymQH8D4TI8hmeY3p0%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;490&quot; data-filename=&quot;01.PNG&quot; data-origin-width=&quot;822&quot; data-origin-height=&quot;490&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;br /&gt;2.이번에는&amp;nbsp;modbus&amp;nbsp;rtu로&amp;nbsp;동작하는&amp;nbsp;온습도센서를&amp;nbsp;연결해서&amp;nbsp;측정한&amp;nbsp;온도와&amp;nbsp;습도값을&amp;nbsp;touchgfx를&amp;nbsp;이용해서&amp;nbsp;화면에&amp;nbsp;출력하고,&amp;nbsp;센서와&amp;nbsp;통신에&amp;nbsp;성공했는지&amp;nbsp;아닌지&amp;nbsp;여부를&amp;nbsp;알수있도록&amp;nbsp;하시오!(온습도센서의&amp;nbsp;ID는&amp;nbsp;1로&amp;nbsp;지정되어있음)&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;02.PNG&quot; data-origin-width=&quot;1086&quot; data-origin-height=&quot;310&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/be3hLT/dJMcadVsuaf/vD1l4iUSwUdNRrQ6EL7Q4K/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/be3hLT/dJMcadVsuaf/vD1l4iUSwUdNRrQ6EL7Q4K/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/be3hLT/dJMcadVsuaf/vD1l4iUSwUdNRrQ6EL7Q4K/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fbe3hLT%2FdJMcadVsuaf%2FvD1l4iUSwUdNRrQ6EL7Q4K%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;1086&quot; height=&quot;310&quot; data-filename=&quot;02.PNG&quot; data-origin-width=&quot;1086&quot; data-origin-height=&quot;310&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;</description>
      <category>프로그래밍/STM32</category>
      <author>덕력킹</author>
      <guid isPermaLink="true">https://bota.tistory.com/2481</guid>
      <comments>https://bota.tistory.com/2481#entry2481comment</comments>
      <pubDate>Mon, 9 Mar 2026 23:06:40 +0900</pubDate>
    </item>
    <item>
      <title>[STM32#38] STM32F746g-DISCO보드의 센서값을 TOUCHGFX를 이용해서 LCD에 출력하는 방법 계속 알아보기!(녹칸다 내맘대로 STM32)</title>
      <link>https://bota.tistory.com/2480</link>
      <description>&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;stm32.png&quot; data-origin-width=&quot;1920&quot; data-origin-height=&quot;1080&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cFBuxe/dJMcac91sdQ/y7PlB3MKMv9OWhMNGaW9k1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cFBuxe/dJMcac91sdQ/y7PlB3MKMv9OWhMNGaW9k1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cFBuxe/dJMcac91sdQ/y7PlB3MKMv9OWhMNGaW9k1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FcFBuxe%2FdJMcac91sdQ%2Fy7PlB3MKMv9OWhMNGaW9k1%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;1920&quot; height=&quot;1080&quot; data-filename=&quot;stm32.png&quot; data-origin-width=&quot;1920&quot; data-origin-height=&quot;1080&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/live/ECkkotogUdM&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://youtube.com/live/ECkkotogUdM&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/watch?v=ECkkotogUdM&quot; data-video-thumbnail=&quot;https://scrap.kakaocdn.net/dn/bk1hki/dJMb8WexlYA/crsUAGyKiCWiVVD3V4xeo1/img.jpg?width=1280&amp;amp;height=720&amp;amp;face=0_0_1280_720,https://scrap.kakaocdn.net/dn/4XDLw/dJMb8TB7jrO/uv6iZuqyrRKNtt18TuVnB0/img.jpg?width=1280&amp;amp;height=720&amp;amp;face=0_0_1280_720,https://scrap.kakaocdn.net/dn/trdJy/dJMb8YXJc13/kitoDWzz5WddSGsfvNx8Z1/img.jpg?width=1280&amp;amp;height=720&amp;amp;face=0_0_1280_720&quot; data-video-width=&quot;860&quot; data-video-height=&quot;484&quot; data-video-origin-width=&quot;860&quot; data-video-origin-height=&quot;484&quot; data-ke-mobilestyle=&quot;widthContent&quot; data-video-title=&quot;[STM32#38] STM32F746g-DISCO보드의 센서값을 TOUCHGFX를 이용해서 LCD에 출력하는 방법 계속 알아보기!(녹&quot; data-original-url=&quot;&quot;&gt;&lt;iframe src=&quot;https://www.youtube.com/embed/ECkkotogUdM&quot; width=&quot;860&quot; height=&quot;484&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;[STM32#38]&amp;nbsp;STM32F746g-DISCO보드의&amp;nbsp;센서값을&amp;nbsp;TOUCHGFX를&amp;nbsp;이용해서&amp;nbsp;LCD에&amp;nbsp;출력하는&amp;nbsp;방법&amp;nbsp;계속&amp;nbsp;알아보기!(녹칸다&amp;nbsp;내맘대로&amp;nbsp;STM32) &lt;br /&gt;&lt;br /&gt;심심한녹칸다의&amp;nbsp;내맘대로&amp;nbsp;STM32시리즈이다! &lt;br /&gt;&lt;br /&gt;STM32시리즈의&amp;nbsp;모든&amp;nbsp;자료는&amp;nbsp;구글&amp;nbsp;슬라이드에&amp;nbsp;작성하고&amp;nbsp;모두에게&amp;nbsp;공유되어있음! &lt;br /&gt;&lt;a href=&quot;https://docs.google.com/presentation/d/1myA5iYbjuKsLWLqtRLKAiRfwUwvqB1d1RGjiMIIgp3I/edit?slide=id.g386cae80b9f_3_353#slide=id.g386cae80b9f_3_353&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://docs.google.com/presentation/d/1myA5iYbjuKsLWLqtRLKAiRfwUwvqB1d1RGjiMIIgp3I/edit?slide=id.g386cae80b9f_3_353#slide=id.g386cae80b9f_3_353&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;하드웨어와&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;span style=&quot;color: #ee2323;&quot;&gt;&lt;b&gt;(소스코드는 수정해야할 파일이 너무 많아서 상단에 있는 구글 슬라이드에 내용을 참고하세용)&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;1.D2(PG6)와&amp;nbsp;D4(PG7)에&amp;nbsp;연결된&amp;nbsp;버튼이&amp;nbsp;있고&amp;nbsp;D2버튼을&amp;nbsp;누르면&amp;nbsp;기름이&amp;nbsp;주유된다!&amp;nbsp;그리고&amp;nbsp;D3버튼을&amp;nbsp;누르면&amp;nbsp;주유량이&amp;nbsp;초기화된다!&amp;nbsp;이때&amp;nbsp;D2버튼을&amp;nbsp;계속&amp;nbsp;누르고&amp;nbsp;있으면&amp;nbsp;주유가&amp;nbsp;되고,&amp;nbsp;안누르면&amp;nbsp;멈추도록&amp;nbsp;하시오! &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;-D2버튼을&amp;nbsp;누르면&amp;nbsp;주유속도가&amp;nbsp;몇이냐?(200ml/s)&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;-LCD화면에&amp;nbsp;출력할&amp;nbsp;정보가&amp;nbsp;무엇인가?&amp;nbsp;현재&amp;nbsp;주유량+금액(1650원/L)&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;01.PNG&quot; data-origin-width=&quot;821&quot; data-origin-height=&quot;520&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/xEu0t/dJMcafsbLrj/keeQjKtnKsGBQ4a57scxkK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/xEu0t/dJMcafsbLrj/keeQjKtnKsGBQ4a57scxkK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/xEu0t/dJMcafsbLrj/keeQjKtnKsGBQ4a57scxkK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FxEu0t%2FdJMcafsbLrj%2FkeeQjKtnKsGBQ4a57scxkK%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;821&quot; height=&quot;520&quot; data-filename=&quot;01.PNG&quot; data-origin-width=&quot;821&quot; data-origin-height=&quot;520&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;br /&gt;2.A0(PA0),A1(PF10),A2(PF9),A3(PF8)에&amp;nbsp;연결된&amp;nbsp;아날로그&amp;nbsp;4종세트의&amp;nbsp;값을&amp;nbsp;LCD화면에&amp;nbsp;보기좋게&amp;nbsp;textarea로&amp;nbsp;출력하시오![ADC설정참고자료]&amp;nbsp;[NTC서미스터참고자료] &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;-A0(가변저항),&amp;nbsp;A1(가변저항),&amp;nbsp;A2(CDS),&amp;nbsp;A3(NTC서미스터)&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;02.PNG&quot; data-origin-width=&quot;935&quot; data-origin-height=&quot;565&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cI5zuo/dJMcafsbLro/lhvHf6XTLFGlF8iKrz3Ik0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cI5zuo/dJMcafsbLro/lhvHf6XTLFGlF8iKrz3Ik0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cI5zuo/dJMcafsbLro/lhvHf6XTLFGlF8iKrz3Ik0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FcI5zuo%2FdJMcafsbLro%2FlhvHf6XTLFGlF8iKrz3Ik0%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;935&quot; height=&quot;565&quot; data-filename=&quot;02.PNG&quot; data-origin-width=&quot;935&quot; data-origin-height=&quot;565&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;br /&gt;3.D7(PI3)에&amp;nbsp;연결된&amp;nbsp;온습도센서(DHT-11)에서&amp;nbsp;측정한&amp;nbsp;온도와&amp;nbsp;습도값을&amp;nbsp;LCD화면에&amp;nbsp;보기&amp;nbsp;좋게&amp;nbsp;textarea로&amp;nbsp;출력하시오!&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;03.PNG&quot; data-origin-width=&quot;873&quot; data-origin-height=&quot;538&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bVg1I7/dJMcacPMykL/Il4lwOnCOyJKJlVAC2X3N1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bVg1I7/dJMcacPMykL/Il4lwOnCOyJKJlVAC2X3N1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bVg1I7/dJMcacPMykL/Il4lwOnCOyJKJlVAC2X3N1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbVg1I7%2FdJMcacPMykL%2FIl4lwOnCOyJKJlVAC2X3N1%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;873&quot; height=&quot;538&quot; data-filename=&quot;03.PNG&quot; data-origin-width=&quot;873&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;&lt;br /&gt;4.예제3에서&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-filename=&quot;04.PNG&quot; data-origin-width=&quot;906&quot; data-origin-height=&quot;581&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bPi1Ei/dJMcajnLdp3/KonLNksKl7GKdMwW6qENEk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bPi1Ei/dJMcajnLdp3/KonLNksKl7GKdMwW6qENEk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bPi1Ei/dJMcajnLdp3/KonLNksKl7GKdMwW6qENEk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbPi1Ei%2FdJMcajnLdp3%2FKonLNksKl7GKdMwW6qENEk%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;906&quot; height=&quot;581&quot; data-filename=&quot;04.PNG&quot; data-origin-width=&quot;906&quot; data-origin-height=&quot;581&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;</description>
      <category>프로그래밍/STM32</category>
      <author>덕력킹</author>
      <guid isPermaLink="true">https://bota.tistory.com/2480</guid>
      <comments>https://bota.tistory.com/2480#entry2480comment</comments>
      <pubDate>Wed, 4 Mar 2026 21:18:41 +0900</pubDate>
    </item>
    <item>
      <title>[STM32#37] STM32F746g-DISCO보드의 센서값을 TOUCHGFX를 이용해서 LCD에 출력하는 방법 알아보기!(녹칸다 내맘대로 STM32)</title>
      <link>https://bota.tistory.com/2479</link>
      <description>&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;stm32.png&quot; data-origin-width=&quot;1920&quot; data-origin-height=&quot;1080&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bJS21y/dJMcafMvs9C/BknJKyou33J0eDTdfLhzA0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bJS21y/dJMcafMvs9C/BknJKyou33J0eDTdfLhzA0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bJS21y/dJMcafMvs9C/BknJKyou33J0eDTdfLhzA0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbJS21y%2FdJMcafMvs9C%2FBknJKyou33J0eDTdfLhzA0%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;1920&quot; height=&quot;1080&quot; data-filename=&quot;stm32.png&quot; data-origin-width=&quot;1920&quot; data-origin-height=&quot;1080&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/live/JiKzsrZzkvs&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://youtube.com/live/JiKzsrZzkvs&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/watch?v=JiKzsrZzkvs&quot; data-video-thumbnail=&quot;https://scrap.kakaocdn.net/dn/CWbLZ/dJMb9kT0upL/l8GQc6o76g8GxKQwaALTXk/img.jpg?width=1280&amp;amp;height=720&amp;amp;face=0_0_1280_720,https://scrap.kakaocdn.net/dn/dav0Si/dJMb9iIEDcP/mh64lj7h8UEKDrbQxkmPqK/img.jpg?width=1280&amp;amp;height=720&amp;amp;face=0_0_1280_720,https://scrap.kakaocdn.net/dn/LKgu8/dJMb9kT0upK/ZPbYhJ9pmsNgLxvuKBWroK/img.jpg?width=1280&amp;amp;height=720&amp;amp;face=0_0_1280_720&quot; data-video-width=&quot;860&quot; data-video-height=&quot;484&quot; data-video-origin-width=&quot;860&quot; data-video-origin-height=&quot;484&quot; data-ke-mobilestyle=&quot;widthContent&quot; data-video-title=&quot;[STM32#37] STM32F746g-DISCO보드의 센서값을 TOUCHGFX를 이용해서 LCD에 출력하는 방법 알아보기!(녹칸다 &quot; data-original-url=&quot;&quot;&gt;&lt;iframe src=&quot;https://www.youtube.com/embed/JiKzsrZzkvs&quot; width=&quot;860&quot; height=&quot;484&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;[STM32#37]&amp;nbsp;STM32F746g-DISCO보드의&amp;nbsp;센서값을&amp;nbsp;TOUCHGFX를&amp;nbsp;이용해서&amp;nbsp;LCD에&amp;nbsp;출력하는&amp;nbsp;방법&amp;nbsp;알아보기!(녹칸다&amp;nbsp;내맘대로&amp;nbsp;STM32) &lt;br /&gt;&lt;br /&gt;심심한녹칸다의&amp;nbsp;내맘대로&amp;nbsp;STM32시리즈이다! &lt;br /&gt;&lt;br /&gt;STM32시리즈의&amp;nbsp;모든&amp;nbsp;자료는&amp;nbsp;구글&amp;nbsp;슬라이드에&amp;nbsp;작성하고&amp;nbsp;모두에게&amp;nbsp;공유되어있음! &lt;br /&gt;&lt;a href=&quot;https://docs.google.com/presentation/d/1myA5iYbjuKsLWLqtRLKAiRfwUwvqB1d1RGjiMIIgp3I/edit?slide=id.g3cbf92cef5c_2_1#slide=id.g3cbf92cef5c_2_1&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://docs.google.com/presentation/d/1myA5iYbjuKsLWLqtRLKAiRfwUwvqB1d1RGjiMIIgp3I/edit?slide=id.g3cbf92cef5c_2_1#slide=id.g3cbf92cef5c_2_1&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;하드웨어와&amp;nbsp;상호작용! &lt;br /&gt;&lt;br /&gt;(37편은&amp;nbsp;수정해야할&amp;nbsp;파일이&amp;nbsp;너무&amp;nbsp;방대해서&amp;nbsp;구글&amp;nbsp;슬라이드에&amp;nbsp;있는&amp;nbsp;코드를&amp;nbsp;참고해주세용) &lt;br /&gt;&lt;br /&gt;1.녹칸다가&amp;nbsp;버튼이&amp;nbsp;D2,D4,D5로&amp;nbsp;3개&amp;nbsp;있고&amp;nbsp;순서대로&amp;nbsp;STM32핀번호로&amp;nbsp;보면&amp;nbsp;PG6,PG7,PI0이렇게&amp;nbsp;될때&amp;nbsp;D2버튼을&amp;nbsp;누르면&amp;nbsp;값이&amp;nbsp;1씩&amp;nbsp;업카운트되고,&amp;nbsp;D4버튼을&amp;nbsp;누르면&amp;nbsp;다운카운트되고,&amp;nbsp;D5버튼을&amp;nbsp;누르면&amp;nbsp;0으로&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-filename=&quot;01.PNG&quot; data-origin-width=&quot;865&quot; data-origin-height=&quot;537&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cgGF9F/dJMcaaYHdyH/VtN3cpJaei59GD2zmhZFc1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cgGF9F/dJMcaaYHdyH/VtN3cpJaei59GD2zmhZFc1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cgGF9F/dJMcaaYHdyH/VtN3cpJaei59GD2zmhZFc1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FcgGF9F%2FdJMcaaYHdyH%2FVtN3cpJaei59GD2zmhZFc1%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;865&quot; height=&quot;537&quot; data-filename=&quot;01.PNG&quot; data-origin-width=&quot;865&quot; data-origin-height=&quot;537&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;br /&gt;2.가변저항이&amp;nbsp;A0과&amp;nbsp;A1에&amp;nbsp;연결되어있고&amp;nbsp;GPIO로&amp;nbsp;보면&amp;nbsp;순서대로&amp;nbsp;PA0,&amp;nbsp;PF10에&amp;nbsp;연결되어있을때&amp;nbsp;측정한&amp;nbsp;값을&amp;nbsp;100밀리초&amp;nbsp;간격으로&amp;nbsp;touchgfx화면에&amp;nbsp;textarea를&amp;nbsp;2개&amp;nbsp;이용해서&amp;nbsp;출력하시오!(전송값을&amp;nbsp;uint16_t로&amp;nbsp;전송함)&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;02.PNG&quot; data-origin-width=&quot;846&quot; data-origin-height=&quot;516&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bESUVi/dJMcaaLaLLW/OwAn3uCLlEEcKTAa8oR2hk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bESUVi/dJMcaaLaLLW/OwAn3uCLlEEcKTAa8oR2hk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bESUVi/dJMcaaLaLLW/OwAn3uCLlEEcKTAa8oR2hk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbESUVi%2FdJMcaaLaLLW%2FOwAn3uCLlEEcKTAa8oR2hk%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;846&quot; height=&quot;516&quot; data-filename=&quot;02.PNG&quot; data-origin-width=&quot;846&quot; data-origin-height=&quot;516&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;br /&gt;3.예제2번에&amp;nbsp;추가해서&amp;nbsp;측정한&amp;nbsp;2개의&amp;nbsp;아날로그값으로&amp;nbsp;A0은&amp;nbsp;막대형태의&amp;nbsp;프로그레스바의&amp;nbsp;값을&amp;nbsp;0~4095의&amp;nbsp;범위로&amp;nbsp;조정하고&amp;nbsp;A1의&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-filename=&quot;03.PNG&quot; data-origin-width=&quot;802&quot; data-origin-height=&quot;451&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/trfJI/dJMcaih7XSP/KPMpRkjKyA4HS2WC6H2dAk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/trfJI/dJMcaih7XSP/KPMpRkjKyA4HS2WC6H2dAk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/trfJI/dJMcaih7XSP/KPMpRkjKyA4HS2WC6H2dAk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FtrfJI%2FdJMcaih7XSP%2FKPMpRkjKyA4HS2WC6H2dAk%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;802&quot; height=&quot;451&quot; data-filename=&quot;03.PNG&quot; data-origin-width=&quot;802&quot; data-origin-height=&quot;451&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;br /&gt;4.예제2번에서&amp;nbsp;gauge위젯&amp;nbsp;2개를&amp;nbsp;touchgfx로&amp;nbsp;작화하고&amp;nbsp;A0과&amp;nbsp;A1의&amp;nbsp;값을&amp;nbsp;0~4095로&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-filename=&quot;04.PNG&quot; data-origin-width=&quot;745&quot; data-origin-height=&quot;456&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bKt4hZ/dJMcabww2zd/Mi5D3HXoUJb6mgjzCRSk41/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bKt4hZ/dJMcabww2zd/Mi5D3HXoUJb6mgjzCRSk41/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bKt4hZ/dJMcabww2zd/Mi5D3HXoUJb6mgjzCRSk41/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbKt4hZ%2FdJMcabww2zd%2FMi5D3HXoUJb6mgjzCRSk41%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;456&quot; data-filename=&quot;04.PNG&quot; data-origin-width=&quot;745&quot; data-origin-height=&quot;456&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;</description>
      <category>프로그래밍/STM32</category>
      <author>덕력킹</author>
      <guid isPermaLink="true">https://bota.tistory.com/2479</guid>
      <comments>https://bota.tistory.com/2479#entry2479comment</comments>
      <pubDate>Mon, 2 Mar 2026 23:04:16 +0900</pubDate>
    </item>
    <item>
      <title>[STM32#35] LCD가 내장된 STM32F746g-DISCO보드로 TOUCHGFX를 시작하는 방법 알아보기!(녹칸다 내맘대로 STM32)</title>
      <link>https://bota.tistory.com/2478</link>
      <description>&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;stm32.png&quot; data-origin-width=&quot;1920&quot; data-origin-height=&quot;1080&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cqtGgx/dJMcabwsTNG/okz9MKIY3WK1386fSGCY8K/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cqtGgx/dJMcabwsTNG/okz9MKIY3WK1386fSGCY8K/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cqtGgx/dJMcabwsTNG/okz9MKIY3WK1386fSGCY8K/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FcqtGgx%2FdJMcabwsTNG%2Fokz9MKIY3WK1386fSGCY8K%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;1920&quot; height=&quot;1080&quot; data-filename=&quot;stm32.png&quot; data-origin-width=&quot;1920&quot; data-origin-height=&quot;1080&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/live/BoOS2gsGBY0&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://youtube.com/live/BoOS2gsGBY0&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/watch?v=BoOS2gsGBY0&quot; data-video-thumbnail=&quot;https://scrap.kakaocdn.net/dn/klPE8/dJMb87f3k2A/AnujUfkC8EXnCMTBw1laP1/img.jpg?width=1280&amp;amp;height=720&amp;amp;face=0_0_1280_720,https://scrap.kakaocdn.net/dn/ctjW2T/dJMb9efaRgU/92t2kk2xNJZ3BN7nKChwSk/img.jpg?width=1280&amp;amp;height=720&amp;amp;face=0_0_1280_720,https://scrap.kakaocdn.net/dn/5SUpI/dJMb8950vI0/KM1KycebQoEp47ZSkg5ycK/img.jpg?width=1280&amp;amp;height=720&amp;amp;face=0_0_1280_720&quot; data-video-width=&quot;860&quot; data-video-height=&quot;484&quot; data-video-origin-width=&quot;860&quot; data-video-origin-height=&quot;484&quot; data-ke-mobilestyle=&quot;widthContent&quot; data-video-title=&quot;[STM32#35] LCD가 내장된 STM32F746g-DISCO보드로 TOUCHGFX를 시작하는 방법 알아보기!(녹칸다 내맘대로 STM32&quot; data-original-url=&quot;&quot;&gt;&lt;iframe src=&quot;https://www.youtube.com/embed/BoOS2gsGBY0&quot; width=&quot;860&quot; height=&quot;484&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;[STM32#35]&amp;nbsp;LCD가&amp;nbsp;내장된&amp;nbsp;STM32F746g-DISCO보드로&amp;nbsp;TOUCHGFX를&amp;nbsp;시작하는&amp;nbsp;방법&amp;nbsp;알아보기!(녹칸다&amp;nbsp;내맘대로&amp;nbsp;STM32) &lt;br /&gt;&lt;br /&gt;심심한녹칸다의&amp;nbsp;내맘대로&amp;nbsp;STM32시리즈이다! &lt;br /&gt;&lt;br /&gt;STM32시리즈의&amp;nbsp;모든&amp;nbsp;자료는&amp;nbsp;구글&amp;nbsp;슬라이드에&amp;nbsp;작성하고&amp;nbsp;모두에게&amp;nbsp;공유되어있음! &lt;br /&gt;&lt;a href=&quot;https://docs.google.com/presentation/d/1myA5iYbjuKsLWLqtRLKAiRfwUwvqB1d1RGjiMIIgp3I/edit?slide=id.g3c8649eefc9_1_37#slide=id.g3c8649eefc9_1_37&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://docs.google.com/presentation/d/1myA5iYbjuKsLWLqtRLKAiRfwUwvqB1d1RGjiMIIgp3I/edit?slide=id.g3c8649eefc9_1_37#slide=id.g3c8649eefc9_1_37&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;이제부터&amp;nbsp;touchgfx를&amp;nbsp;해보는&amp;nbsp;것입니다~! &lt;br /&gt;&lt;br /&gt;1.Touchgfx를&amp;nbsp;이용해서&amp;nbsp;button&amp;nbsp;2개와&amp;nbsp;textarea&amp;nbsp;1개를&amp;nbsp;생성하고&amp;nbsp;버튼1을&amp;nbsp;누르면&amp;nbsp;NOCKANDA라고&amp;nbsp;textarea에&amp;nbsp;출력하고&amp;nbsp;버튼2를&amp;nbsp;누르면&amp;nbsp;SUBSCRIBE라고&amp;nbsp;출력하시오!&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;1.PNG&quot; data-origin-width=&quot;1002&quot; data-origin-height=&quot;589&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bhOs2O/dJMcajaaihI/uLTarT2azPkZcPjL7OZnu0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bhOs2O/dJMcajaaihI/uLTarT2azPkZcPjL7OZnu0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bhOs2O/dJMcajaaihI/uLTarT2azPkZcPjL7OZnu0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbhOs2O%2FdJMcajaaihI%2FuLTarT2azPkZcPjL7OZnu0%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;447&quot; data-filename=&quot;1.PNG&quot; data-origin-width=&quot;1002&quot; data-origin-height=&quot;589&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;11.PNG&quot; data-origin-width=&quot;775&quot; data-origin-height=&quot;513&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/l21RG/dJMcahwIcp4/iGzhHj8Rny0BDVQXDkAJuK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/l21RG/dJMcahwIcp4/iGzhHj8Rny0BDVQXDkAJuK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/l21RG/dJMcahwIcp4/iGzhHj8Rny0BDVQXDkAJuK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fl21RG%2FdJMcahwIcp4%2FiGzhHj8Rny0BDVQXDkAJuK%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;775&quot; height=&quot;513&quot; data-filename=&quot;11.PNG&quot; data-origin-width=&quot;775&quot; data-origin-height=&quot;513&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;br /&gt;2.위젯중에&amp;nbsp;토글버튼을&amp;nbsp;하나&amp;nbsp;추가하고&amp;nbsp;토글버튼의&amp;nbsp;상태가&amp;nbsp;바뀔때&amp;nbsp;ON상태면&amp;nbsp;circleProgress1의&amp;nbsp;값이&amp;nbsp;50이&amp;nbsp;되고&amp;nbsp;OFF상태면&amp;nbsp;0이되도록&amp;nbsp;하시오!&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;2.PNG&quot; data-origin-width=&quot;749&quot; data-origin-height=&quot;483&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/kJ5H1/dJMcacPHdjR/1JKvjdpVH3wLAK74bBRSK0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/kJ5H1/dJMcacPHdjR/1JKvjdpVH3wLAK74bBRSK0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/kJ5H1/dJMcacPHdjR/1JKvjdpVH3wLAK74bBRSK0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FkJ5H1%2FdJMcacPHdjR%2F1JKvjdpVH3wLAK74bBRSK0%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;749&quot; height=&quot;483&quot; data-filename=&quot;2.PNG&quot; data-origin-width=&quot;749&quot; data-origin-height=&quot;483&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;pre id=&quot;code_1771855734500&quot; class=&quot;cpp&quot; data-ke-language=&quot;cpp&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;//Screen1View.hpp
#ifndef SCREEN1VIEW_HPP
#define SCREEN1VIEW_HPP
#include &amp;lt;gui_generated/screen1_screen/Screen1ViewBase.hpp&amp;gt;
#include &amp;lt;gui/screen1_screen/Screen1Presenter.hpp&amp;gt;
class Screen1View : public Screen1ViewBase
{
public:
   Screen1View();
   virtual ~Screen1View() {}
   virtual void setupScreen();
   virtual void tearDownScreen();
   virtual void test1(); //나 test1 오버라이딩 할꺼야!
protected:
};
#endif // SCREEN1VIEW_HPP&lt;/code&gt;&lt;/pre&gt;
&lt;pre id=&quot;code_1771855764916&quot; class=&quot;cpp&quot; data-ke-language=&quot;cpp&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;//Screen1View.cpp
#include &amp;lt;gui/screen1_screen/Screen1View.hpp&amp;gt;
Screen1View::Screen1View()
{
}
void Screen1View::setupScreen()
{
   Screen1ViewBase::setupScreen();
}
void Screen1View::tearDownScreen()
{
   Screen1ViewBase::tearDownScreen();
}
void Screen1View::test1(){
	if(!toggleButton1.getState()){
		//토글버튼이 ON이면 circleProgress1에 50출력
		circleProgress1.setValue(50);
	}else{
		//토글버튼이 OFF이면 circleProgress1에 0출력
		circleProgress1.setValue(0);
	}
}&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;br /&gt;3.위젯중에&amp;nbsp;슬라이더를&amp;nbsp;추가하고&amp;nbsp;0~100사이의&amp;nbsp;값으로&amp;nbsp;바뀌는&amp;nbsp;슬라이드의&amp;nbsp;현재값을&amp;nbsp;textarea1에&amp;nbsp;출력하시오!&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;3.PNG&quot; data-origin-width=&quot;825&quot; data-origin-height=&quot;528&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/xkjSv/dJMcabQLD9k/ENTKkC3XeJ5fF3q5WCpVtK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/xkjSv/dJMcabQLD9k/ENTKkC3XeJ5fF3q5WCpVtK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/xkjSv/dJMcabQLD9k/ENTKkC3XeJ5fF3q5WCpVtK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FxkjSv%2FdJMcabQLD9k%2FENTKkC3XeJ5fF3q5WCpVtK%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;825&quot; height=&quot;528&quot; data-filename=&quot;3.PNG&quot; data-origin-width=&quot;825&quot; data-origin-height=&quot;528&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;pre id=&quot;code_1771855781724&quot; class=&quot;cpp&quot; data-ke-language=&quot;cpp&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;//Screen1View.hpp
#ifndef SCREEN1VIEW_HPP
#define SCREEN1VIEW_HPP
#include &amp;lt;gui_generated/screen1_screen/Screen1ViewBase.hpp&amp;gt;
#include &amp;lt;gui/screen1_screen/Screen1Presenter.hpp&amp;gt;
class Screen1View : public Screen1ViewBase
{
public:
   Screen1View();
   virtual ~Screen1View() {}
   virtual void setupScreen();
   virtual void tearDownScreen();
   //textarea에 값을 출력하기 위한 중간변수
   touchgfx::Unicode::UnicodeChar testTextAreaBuffer[10];
   //슬라이더 값이 바뀌면 호출되는 함수
   virtual void test1(int value);
protected:
};
#endif // SCREEN1VIEW_HPP&lt;/code&gt;&lt;/pre&gt;
&lt;pre id=&quot;code_1771855792240&quot; class=&quot;cpp&quot; data-ke-language=&quot;cpp&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;//Screen1View.cpp
#include &amp;lt;gui/screen1_screen/Screen1View.hpp&amp;gt;
Screen1View::Screen1View()
{
}
void Screen1View::setupScreen()
{
   Screen1ViewBase::setupScreen();
   //textArea1에 추가한 와일드카드에 출력할 버퍼
   textArea1.setWildcard(testTextAreaBuffer);
   //처음 부팅될때 초기값 입력
   Unicode::snprintf(testTextAreaBuffer, 10,&quot;%d&quot;, 0);
	textArea1.invalidate(); //UI업데이트
	textArea1.resizeToCurrentText(); //UI업데이트
	textArea1.invalidate(); //UI업데이트
}
void Screen1View::tearDownScreen()
{
   Screen1ViewBase::tearDownScreen();
}
void Screen1View::test1(int value){
	//현재슬라이더값인 value를 textarea1에 출력한다!
	//현재 슬라이더값을 버퍼에 대입한다!
	Unicode::snprintf(testTextAreaBuffer, 10,&quot;%d&quot;, value);
	textArea1.invalidate(); //UI업데이트
	textArea1.resizeToCurrentText(); //UI업데이트
	textArea1.invalidate(); //UI업데이트
}&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;br /&gt;4.슬라이더값을&amp;nbsp;0~100사이로&amp;nbsp;바꿀수&amp;nbsp;있도록&amp;nbsp;하고,&amp;nbsp;박스프로그레스의&amp;nbsp;범위를&amp;nbsp;0~100사이로&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-filename=&quot;4.PNG&quot; data-origin-width=&quot;809&quot; data-origin-height=&quot;496&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cn110y/dJMcagYQxtc/mT8BK6RNeDqLB8XVDPy6u1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cn110y/dJMcagYQxtc/mT8BK6RNeDqLB8XVDPy6u1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cn110y/dJMcagYQxtc/mT8BK6RNeDqLB8XVDPy6u1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fcn110y%2FdJMcagYQxtc%2FmT8BK6RNeDqLB8XVDPy6u1%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;809&quot; height=&quot;496&quot; data-filename=&quot;4.PNG&quot; data-origin-width=&quot;809&quot; data-origin-height=&quot;496&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;pre id=&quot;code_1771855814882&quot; class=&quot;cpp&quot; data-ke-language=&quot;cpp&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;//Screen1View.hpp
#ifndef SCREEN1VIEW_HPP
#define SCREEN1VIEW_HPP
#include &amp;lt;gui_generated/screen1_screen/Screen1ViewBase.hpp&amp;gt;
#include &amp;lt;gui/screen1_screen/Screen1Presenter.hpp&amp;gt;
class Screen1View : public Screen1ViewBase
{
public:
   Screen1View();
   virtual ~Screen1View() {}
   virtual void setupScreen();
   virtual void tearDownScreen();
   //textarea에 값을 출력하기 위한 중간변수
   touchgfx::Unicode::UnicodeChar testTextAreaBuffer[10];
   //슬라이더 값이 바뀌면 호출되는 함수
   virtual void test1(int value);
protected:
};
#endif // SCREEN1VIEW_HPP&lt;/code&gt;&lt;/pre&gt;
&lt;pre id=&quot;code_1771855825697&quot; class=&quot;cpp&quot; data-ke-language=&quot;cpp&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;//Screen1View.cpp
#include &amp;lt;gui/screen1_screen/Screen1View.hpp&amp;gt;
Screen1View::Screen1View()
{
}
void Screen1View::setupScreen()
{
   Screen1ViewBase::setupScreen();
   //textArea1에 추가한 와일드카드에 출력할 버퍼
   textArea1.setWildcard(testTextAreaBuffer);
   //처음 부팅될때 초기값 입력
   Unicode::snprintf(testTextAreaBuffer, 10,&quot;%d&quot;, 0);
	textArea1.invalidate(); //UI업데이트
	textArea1.resizeToCurrentText(); //UI업데이트
	textArea1.invalidate(); //UI업데이트
}
void Screen1View::tearDownScreen()
{
   Screen1ViewBase::tearDownScreen();
}
void Screen1View::test1(int value){
	//현재슬라이더값인 value를 textarea1에 출력한다!
	//현재 슬라이더값을 버퍼에 대입한다!
	Unicode::snprintf(testTextAreaBuffer, 10,&quot;%d&quot;, value);
	textArea1.invalidate(); //UI업데이트
	textArea1.resizeToCurrentText(); //UI업데이트
	textArea1.invalidate(); //UI업데이트
               boxProgress1.setValue(value);//박스프로그레스바 값 업데이트
}&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;br /&gt;5.슬라이더값을&amp;nbsp;0~100사이로&amp;nbsp;바꿀때&amp;nbsp;gauge를&amp;nbsp;추가해서&amp;nbsp;0~100사이로&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-filename=&quot;5.PNG&quot; data-origin-width=&quot;880&quot; data-origin-height=&quot;508&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/tBvof/dJMcaadhpgQ/uFL1PzgaVWA7UR8SOgtTL1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/tBvof/dJMcaadhpgQ/uFL1PzgaVWA7UR8SOgtTL1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/tBvof/dJMcaadhpgQ/uFL1PzgaVWA7UR8SOgtTL1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FtBvof%2FdJMcaadhpgQ%2FuFL1PzgaVWA7UR8SOgtTL1%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;880&quot; height=&quot;508&quot; data-filename=&quot;5.PNG&quot; data-origin-width=&quot;880&quot; data-origin-height=&quot;508&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;pre id=&quot;code_1771855840052&quot; class=&quot;cpp&quot; data-ke-language=&quot;cpp&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;//Screen1View.hpp
#ifndef SCREEN1VIEW_HPP
#define SCREEN1VIEW_HPP
#include &amp;lt;gui_generated/screen1_screen/Screen1ViewBase.hpp&amp;gt;
#include &amp;lt;gui/screen1_screen/Screen1Presenter.hpp&amp;gt;
class Screen1View : public Screen1ViewBase
{
public:
   Screen1View();
   virtual ~Screen1View() {}
   virtual void setupScreen();
   virtual void tearDownScreen();
   //textarea에 값을 출력하기 위한 중간변수
   touchgfx::Unicode::UnicodeChar testTextAreaBuffer[10];
   //슬라이더 값이 바뀌면 호출되는 함수
   virtual void test1(int value);
protected:
};
#endif // SCREEN1VIEW_HPP&lt;/code&gt;&lt;/pre&gt;
&lt;pre id=&quot;code_1771855856529&quot; class=&quot;cpp&quot; data-ke-language=&quot;cpp&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;//Screen1View.cpp
#include &amp;lt;gui/screen1_screen/Screen1View.hpp&amp;gt;
Screen1View::Screen1View()
{
}
void Screen1View::setupScreen()
{
   Screen1ViewBase::setupScreen();
   //textArea1에 추가한 와일드카드에 출력할 버퍼
   textArea1.setWildcard(testTextAreaBuffer);
   //처음 부팅될때 초기값 입력
   Unicode::snprintf(testTextAreaBuffer, 10,&quot;%d&quot;, 0);
	textArea1.invalidate(); //UI업데이트
	textArea1.resizeToCurrentText(); //UI업데이트
	textArea1.invalidate(); //UI업데이트
}
void Screen1View::tearDownScreen()
{
   Screen1ViewBase::tearDownScreen();
}
void Screen1View::test1(int value){
	//현재슬라이더값인 value를 textarea1에 출력한다!
	//현재 슬라이더값을 버퍼에 대입한다!
	Unicode::snprintf(testTextAreaBuffer, 10,&quot;%d&quot;, value);
	textArea1.invalidate(); //UI업데이트
	textArea1.resizeToCurrentText(); //UI업데이트
	textArea1.invalidate(); //UI업데이트
               gauge1.setValue(value);//게이지 값 업데이트
}&lt;/code&gt;&lt;/pre&gt;</description>
      <category>프로그래밍/STM32</category>
      <author>덕력킹</author>
      <guid isPermaLink="true">https://bota.tistory.com/2478</guid>
      <comments>https://bota.tistory.com/2478#entry2478comment</comments>
      <pubDate>Mon, 23 Feb 2026 23:11:58 +0900</pubDate>
    </item>
    <item>
      <title>녹칸다의 STM32f746g-DISCO 테스트보드를 만들기위한 거버파일 파일</title>
      <link>https://bota.tistory.com/2477</link>
      <description>&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;20260217_200938.jpg&quot; data-origin-width=&quot;4000&quot; data-origin-height=&quot;3000&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/QG9k6/dJMcagqV8i4/3kFfPg7SSl9dgvCAzAtUiK/img.jpg&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/QG9k6/dJMcagqV8i4/3kFfPg7SSl9dgvCAzAtUiK/img.jpg&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/QG9k6/dJMcagqV8i4/3kFfPg7SSl9dgvCAzAtUiK/img.jpg&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FQG9k6%2FdJMcagqV8i4%2F3kFfPg7SSl9dgvCAzAtUiK%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;4000&quot; height=&quot;3000&quot; data-filename=&quot;20260217_200938.jpg&quot; data-origin-width=&quot;4000&quot; data-origin-height=&quot;3000&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;stm32f746g-disco보드는 LCD가 있는 STM32보드인데, GPIO가 뒷면에 있어서 연결하기가 불편했습니다!&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그래서 보드 뒷면에서 연장선을 이용해서 밖으로 GPIO를 빼면 좋을것 같아서 녹칸다는 PCB를 만들기로 했습니다!&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;board1은 stm32f746g-disco보드 뒷면에 부착되어서 IDC 플랫케이블로 외부로 GPIO를 연결하기 위한 목적으로 사용!&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;board1은 board2 혹은 board3과 선택적으로 연결해서 사용하는 구조입니당!&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;01.PNG&quot; data-origin-width=&quot;554&quot; data-origin-height=&quot;541&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/dfsdPj/dJMcaca1PiE/PGHzJ1CsYCbUiv5cax1gK1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/dfsdPj/dJMcaca1PiE/PGHzJ1CsYCbUiv5cax1gK1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/dfsdPj/dJMcaca1PiE/PGHzJ1CsYCbUiv5cax1gK1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FdfsdPj%2FdJMcaca1PiE%2FPGHzJ1CsYCbUiv5cax1gK1%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;541&quot; data-filename=&quot;01.PNG&quot; data-origin-width=&quot;554&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;&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/boTyjO/dJMcaaEhgSk/PFOKQeYfyT6HuKmSl8l08K/f746_board1.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;f746_board1.zip&lt;/span&gt;&lt;/div&gt;
&lt;div class=&quot;size&quot;&gt;0.75MB&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;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;20260217_200632.jpg&quot; data-origin-width=&quot;4000&quot; data-origin-height=&quot;3000&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/pZdII/dJMcai95rhS/zDJaAsaL1n0s0qdbTkXD9k/img.jpg&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/pZdII/dJMcai95rhS/zDJaAsaL1n0s0qdbTkXD9k/img.jpg&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/pZdII/dJMcai95rhS/zDJaAsaL1n0s0qdbTkXD9k/img.jpg&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FpZdII%2FdJMcai95rhS%2FzDJaAsaL1n0s0qdbTkXD9k%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;4000&quot; height=&quot;3000&quot; data-filename=&quot;20260217_200632.jpg&quot; data-origin-width=&quot;4000&quot; data-origin-height=&quot;3000&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;board1이 stm32에 부착된 모습!&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;board2는 board1과 플랫케이블로 연결되고 단순하게 GPIO를 사용하기 편하게 핀헤더로 빼놓은 형태!&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;02.PNG&quot; data-origin-width=&quot;1080&quot; data-origin-height=&quot;533&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bdg6wr/dJMcaca1PiF/fraRpkSZ64PCjIAj9SsUTk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bdg6wr/dJMcaca1PiF/fraRpkSZ64PCjIAj9SsUTk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bdg6wr/dJMcaca1PiF/fraRpkSZ64PCjIAj9SsUTk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fbdg6wr%2FdJMcaca1PiF%2FfraRpkSZ64PCjIAj9SsUTk%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;1080&quot; height=&quot;533&quot; data-filename=&quot;02.PNG&quot; data-origin-width=&quot;1080&quot; data-origin-height=&quot;533&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;figure class=&quot;fileblock&quot; data-ke-align=&quot;alignCenter&quot;&gt;&lt;a href=&quot;https://blog.kakaocdn.net/dn/cNXsOA/dJMcahwDvXK/CTdSsNBwJ8F5mhJLF1axck/f746_board2.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;f746_board2.zip&lt;/span&gt;&lt;/div&gt;
&lt;div class=&quot;size&quot;&gt;1.64MB&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;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;20260217_200855.jpg&quot; data-origin-width=&quot;4000&quot; data-origin-height=&quot;3000&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/QNcrt/dJMcagEu4DZ/ZjJ4j6lDKE2f6o1A1kUMe0/img.jpg&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/QNcrt/dJMcagEu4DZ/ZjJ4j6lDKE2f6o1A1kUMe0/img.jpg&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/QNcrt/dJMcagEu4DZ/ZjJ4j6lDKE2f6o1A1kUMe0/img.jpg&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FQNcrt%2FdJMcagEu4DZ%2FZjJ4j6lDKE2f6o1A1kUMe0%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;4000&quot; height=&quot;3000&quot; data-filename=&quot;20260217_200855.jpg&quot; data-origin-width=&quot;4000&quot; data-origin-height=&quot;3000&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;board1과 board2가 결합된 모습!&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;board3는 board1과 연장선으로 연결되고 테스트에 사용할 다양한것들이 이미 부착되어있는 형태임!&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;03.PNG&quot; data-origin-width=&quot;536&quot; data-origin-height=&quot;529&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/HyYpz/dJMcaaYyllz/kh9imL9Lyknu4fdLgwC0I0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/HyYpz/dJMcaaYyllz/kh9imL9Lyknu4fdLgwC0I0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/HyYpz/dJMcaaYyllz/kh9imL9Lyknu4fdLgwC0I0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FHyYpz%2FdJMcaaYyllz%2Fkh9imL9Lyknu4fdLgwC0I0%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;536&quot; height=&quot;529&quot; data-filename=&quot;03.PNG&quot; data-origin-width=&quot;536&quot; data-origin-height=&quot;529&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;figure class=&quot;fileblock&quot; data-ke-align=&quot;alignCenter&quot;&gt;&lt;a href=&quot;https://blog.kakaocdn.net/dn/97nR4/dJMcaca1PiQ/sGsvtF6iG0Bw2kg0SBD5h1/f746_board3.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;f746_board3.zip&lt;/span&gt;&lt;/div&gt;
&lt;div class=&quot;size&quot;&gt;2.56MB&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;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;20260217_200909.jpg&quot; data-origin-width=&quot;4000&quot; data-origin-height=&quot;3000&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/c9Mnmw/dJMcaiCgD4U/a8PQlLQ7HC99qKctoZqumK/img.jpg&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/c9Mnmw/dJMcaiCgD4U/a8PQlLQ7HC99qKctoZqumK/img.jpg&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/c9Mnmw/dJMcaiCgD4U/a8PQlLQ7HC99qKctoZqumK/img.jpg&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fc9Mnmw%2FdJMcaiCgD4U%2Fa8PQlLQ7HC99qKctoZqumK%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;4000&quot; height=&quot;3000&quot; data-filename=&quot;20260217_200909.jpg&quot; data-origin-width=&quot;4000&quot; data-origin-height=&quot;3000&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;board3이 납땜이 다된 모습!&lt;/p&gt;</description>
      <category>프로그래밍/STM32</category>
      <author>덕력킹</author>
      <guid isPermaLink="true">https://bota.tistory.com/2477</guid>
      <comments>https://bota.tistory.com/2477#entry2477comment</comments>
      <pubDate>Tue, 17 Feb 2026 20:28:00 +0900</pubDate>
    </item>
    <item>
      <title>[STM32#34] 블루필보드로 로봇하드웨어개발기사 공개문제에 있는 i2c가 아닌 1602lcd를 작동시키는 방법을 데이터시트로 알아보기!(녹칸다 내맘대로 STM32)</title>
      <link>https://bota.tistory.com/2476</link>
      <description>&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;stm32.png&quot; data-origin-width=&quot;1920&quot; data-origin-height=&quot;1080&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/pPadK/dJMcaihVZQG/dS5ZoskCGvttEwkzkIpizk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/pPadK/dJMcaihVZQG/dS5ZoskCGvttEwkzkIpizk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/pPadK/dJMcaihVZQG/dS5ZoskCGvttEwkzkIpizk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FpPadK%2FdJMcaihVZQG%2FdS5ZoskCGvttEwkzkIpizk%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;1920&quot; height=&quot;1080&quot; data-filename=&quot;stm32.png&quot; data-origin-width=&quot;1920&quot; data-origin-height=&quot;1080&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/live/X9i3F1bRd_M&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://youtube.com/live/X9i3F1bRd_M&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/watch?v=X9i3F1bRd_M&quot; data-video-thumbnail=&quot;https://scrap.kakaocdn.net/dn/wyCyz/dJMb9frBqyM/MABu1SUcPT7da75eUPnmpK/img.jpg?width=1280&amp;amp;height=720&amp;amp;face=0_0_1280_720,https://scrap.kakaocdn.net/dn/lDvjp/dJMb9fZrgMh/rfwsnhVRCZYvsTGbNTJ9JK/img.jpg?width=1280&amp;amp;height=720&amp;amp;face=0_0_1280_720,https://scrap.kakaocdn.net/dn/GdSxe/dJMb9c9tSeW/EKE1Q88DRUkxm0dldu06R0/img.jpg?width=1280&amp;amp;height=720&amp;amp;face=0_0_1280_720&quot; data-video-width=&quot;860&quot; data-video-height=&quot;484&quot; data-video-origin-width=&quot;860&quot; data-video-origin-height=&quot;484&quot; data-ke-mobilestyle=&quot;widthContent&quot; data-video-title=&quot;[STM32#34] 블루필보드로 로봇하드웨어개발기사 공개문제에 있는 i2c가 아닌 1602lcd를 작동시키는 방&quot; data-original-url=&quot;&quot;&gt;&lt;iframe src=&quot;https://www.youtube.com/embed/X9i3F1bRd_M&quot; width=&quot;860&quot; height=&quot;484&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;[STM32#34]&amp;nbsp;블루필보드로&amp;nbsp;로봇하드웨어개발기사&amp;nbsp;공개문제에&amp;nbsp;있는&amp;nbsp;i2c가&amp;nbsp;아닌&amp;nbsp;1602lcd를&amp;nbsp;작동시키는&amp;nbsp;방법을&amp;nbsp;데이터시트로&amp;nbsp;알아보기!(녹칸다&amp;nbsp;내맘대로&amp;nbsp;STM32) &lt;br /&gt;&lt;br /&gt;심심한녹칸다의&amp;nbsp;내맘대로&amp;nbsp;STM32시리즈이다! &lt;br /&gt;&lt;br /&gt;STM32시리즈의&amp;nbsp;모든&amp;nbsp;자료는&amp;nbsp;구글&amp;nbsp;슬라이드에&amp;nbsp;작성하고&amp;nbsp;모두에게&amp;nbsp;공유되어있음! &lt;br /&gt;&lt;a href=&quot;https://docs.google.com/presentation/d/1myA5iYbjuKsLWLqtRLKAiRfwUwvqB1d1RGjiMIIgp3I/edit?slide=id.g3bd7e320f89_10_229#slide=id.g3bd7e320f89_10_229&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://docs.google.com/presentation/d/1myA5iYbjuKsLWLqtRLKAiRfwUwvqB1d1RGjiMIIgp3I/edit?slide=id.g3bd7e320f89_10_229#slide=id.g3bd7e320f89_10_229&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;로봇하드웨어개발기사에&amp;nbsp;있는&amp;nbsp;일부&amp;nbsp;내용을&amp;nbsp;STM32보드로&amp;nbsp;한번&amp;nbsp;접근해보는&amp;nbsp;것입니다! &lt;br /&gt;&lt;br /&gt;1.블루필보드에&amp;nbsp;1602LCD를&amp;nbsp;회로도에&amp;nbsp;맞게&amp;nbsp;연결한다음&amp;nbsp;데이터시트를&amp;nbsp;해석해서&amp;nbsp;첫번째&amp;nbsp;줄에는&amp;nbsp;&amp;ldquo;NOCKANDA&amp;rdquo;라고&amp;nbsp;출력하고&amp;nbsp;두번째&amp;nbsp;줄에는&amp;nbsp;&amp;ldquo;SUBSCRIBE!&amp;rdquo;라고&amp;nbsp;출력해보도록&amp;nbsp;한다!&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;01.PNG&quot; data-origin-width=&quot;1214&quot; data-origin-height=&quot;646&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bfkRtb/dJMcafMjlXU/AutjSUXadIlBD9KSjApwOk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bfkRtb/dJMcafMjlXU/AutjSUXadIlBD9KSjApwOk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bfkRtb/dJMcafMjlXU/AutjSUXadIlBD9KSjApwOk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbfkRtb%2FdJMcafMjlXU%2FAutjSUXadIlBD9KSjApwOk%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;1214&quot; height=&quot;646&quot; data-filename=&quot;01.PNG&quot; data-origin-width=&quot;1214&quot; data-origin-height=&quot;646&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;pre id=&quot;code_1770796071418&quot; class=&quot;cpp&quot; data-ke-language=&quot;cpp&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;/* USER CODE BEGIN 0 */
void lcd_write4(uint8_t n)
{
  HAL_GPIO_WritePin(GPIOB, GPIO_PIN_4, (n &amp;gt;&amp;gt; 0) &amp;amp; 1);
  HAL_GPIO_WritePin(GPIOB, GPIO_PIN_5, (n &amp;gt;&amp;gt; 1) &amp;amp; 1);
  HAL_GPIO_WritePin(GPIOB, GPIO_PIN_6, (n &amp;gt;&amp;gt; 2) &amp;amp; 1);
  HAL_GPIO_WritePin(GPIOB, GPIO_PIN_7, (n &amp;gt;&amp;gt; 3) &amp;amp; 1);
  HAL_GPIO_WritePin(GPIOC, GPIO_PIN_15, GPIO_PIN_SET);
  HAL_Delay(1);
  HAL_GPIO_WritePin(GPIOC, GPIO_PIN_15, GPIO_PIN_RESET);
  HAL_Delay(1);
}
void lcd_write8(uint8_t data, uint8_t rs)
{
  HAL_GPIO_WritePin(GPIOC, GPIO_PIN_13, rs);
  lcd_write4(data &amp;gt;&amp;gt; 4);   // 상위 4비트
  lcd_write4(data &amp;amp; 0x0F); // 하위 4비트
}
void lcd_cmd(uint8_t cmd)
{
  lcd_write8(cmd, 0);
}
void lcd_data(uint8_t data)
{
  lcd_write8(data, 1);
}
void lcd_puts(char *s)
{
  while(*s)
  	lcd_data(*s++);
}
/* USER CODE END 0 */

/* USER CODE BEGIN 2 */
 //STM32가 부팅된 후 15ms이상 기다려줘야한다!
 HAL_Delay(15);
 //그다음 0b0011을 전송한다
 lcd_write4(0b0011);
 HAL_Delay(5); //4.1ms이상 대기
 lcd_write4(0b0011);
 HAL_Delay(1); //100us(0.1ms)이상 대기
 lcd_write4(0b0011);
 //HAL_Delay(1);
 lcd_write4(0b0010);
 lcd_cmd(0b00101000);  // 4bit, 2line
 lcd_cmd(0b00001000);  // Display OFF
 lcd_cmd(0b00000001);  // Clear
 //HAL_Delay(5);
 lcd_cmd(0b00000110);  // Entry mode
 lcd_cmd(0b00001100);  // Display ON
 lcd_cmd(0x80);
 lcd_puts(&quot;NOCKANDA&quot;);
 lcd_cmd(0xC0);
 lcd_puts(&quot;SUBSCRIBE!&quot;);
 /* USER CODE END 2 */&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;br /&gt;2.첫번째줄에&amp;nbsp;왼쪽부터&amp;nbsp;2번째칸에서&amp;nbsp;시작해서&amp;nbsp;NOCKANDA라고&amp;nbsp;출력하고&amp;nbsp;두번째줄의&amp;nbsp;3번째&amp;nbsp;칸부터&amp;nbsp;시작해서&amp;nbsp;SUBSCRIBE!를&amp;nbsp;출력하시오!&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;02.PNG&quot; data-origin-width=&quot;1003&quot; data-origin-height=&quot;489&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/qSN8T/dJMcafyL1eD/882QwycTwjAgnbkQw3xLK1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/qSN8T/dJMcafyL1eD/882QwycTwjAgnbkQw3xLK1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/qSN8T/dJMcafyL1eD/882QwycTwjAgnbkQw3xLK1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FqSN8T%2FdJMcafyL1eD%2F882QwycTwjAgnbkQw3xLK1%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;1003&quot; height=&quot;489&quot; data-filename=&quot;02.PNG&quot; data-origin-width=&quot;1003&quot; data-origin-height=&quot;489&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;pre id=&quot;code_1770796083141&quot; class=&quot;cpp&quot; data-ke-language=&quot;cpp&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;/* USER CODE BEGIN 0 */
void lcd_write4(uint8_t n)
{
  HAL_GPIO_WritePin(GPIOB, GPIO_PIN_4, (n &amp;gt;&amp;gt; 0) &amp;amp; 1);
  HAL_GPIO_WritePin(GPIOB, GPIO_PIN_5, (n &amp;gt;&amp;gt; 1) &amp;amp; 1);
  HAL_GPIO_WritePin(GPIOB, GPIO_PIN_6, (n &amp;gt;&amp;gt; 2) &amp;amp; 1);
  HAL_GPIO_WritePin(GPIOB, GPIO_PIN_7, (n &amp;gt;&amp;gt; 3) &amp;amp; 1);
  HAL_GPIO_WritePin(GPIOC, GPIO_PIN_15, GPIO_PIN_SET);
  HAL_Delay(1);
  HAL_GPIO_WritePin(GPIOC, GPIO_PIN_15, GPIO_PIN_RESET);
  HAL_Delay(1);
}
void lcd_write8(uint8_t data, uint8_t rs)
{
  HAL_GPIO_WritePin(GPIOC, GPIO_PIN_13, rs);
  lcd_write4(data &amp;gt;&amp;gt; 4);   // 상위 4비트
  lcd_write4(data &amp;amp; 0x0F); // 하위 4비트
}
void lcd_cmd(uint8_t cmd)
{
  lcd_write8(cmd, 0);
}
void lcd_data(uint8_t data)
{
  lcd_write8(data, 1);
}
void lcd_puts(char *s)
{
  while(*s)
  	lcd_data(*s++);
}


void set_cursor(uint8_t x, uint8_t y){
	uint8_t cursor = 0b10000000;
	if(y != 0){
		cursor = cursor | 0b01000000;
	}
	cursor = cursor + x;
	lcd_cmd(cursor);
}
/* USER CODE END 0 */
/* USER CODE BEGIN 2 */
 //STM32가 부팅된 후 15ms이상 기다려줘야한다!
 HAL_Delay(15);
 //그다음 0b0011을 전송한다
 lcd_write4(0b0011);
 HAL_Delay(5); //4.1ms이상 대기
 lcd_write4(0b0011);
 HAL_Delay(1); //100us(0.1ms)이상 대기
 lcd_write4(0b0011);
 //HAL_Delay(1);
 lcd_write4(0b0010);
 lcd_cmd(0b00101000);  // 4bit, 2line
 lcd_cmd(0b00001000);  // Display OFF
 lcd_cmd(0b00000001);  // Clear
 //HAL_Delay(5);
 lcd_cmd(0b00000110);  // Entry mode
 lcd_cmd(0b00001100);  // Display ON
 set_cursor(2,0);
 lcd_puts(&quot;NOCKANDA&quot;);
 set_cursor(3,1);
 lcd_puts(&quot;SUBSCRIBE!&quot;);
 /* USER CODE END 2 */&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;br /&gt;3.로봇하드웨어개발기사에서&amp;nbsp;공개되어있는&amp;nbsp;부분만&amp;nbsp;STM32보드로&amp;nbsp;간단하게&amp;nbsp;구현해보시오!(조이스틱x축PA0,&amp;nbsp;y축PA1,&amp;nbsp;서보모터PB11)&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;03.PNG&quot; data-origin-width=&quot;1313&quot; data-origin-height=&quot;596&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/3mle7/dJMcai3fYYf/ZGT58Gc7q4kPuBy6pOokFK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/3mle7/dJMcai3fYYf/ZGT58Gc7q4kPuBy6pOokFK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/3mle7/dJMcai3fYYf/ZGT58Gc7q4kPuBy6pOokFK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2F3mle7%2FdJMcai3fYYf%2FZGT58Gc7q4kPuBy6pOokFK%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;1313&quot; height=&quot;596&quot; data-filename=&quot;03.PNG&quot; data-origin-width=&quot;1313&quot; data-origin-height=&quot;596&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;pre id=&quot;code_1770796099251&quot; class=&quot;cpp&quot; data-ke-language=&quot;cpp&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;/* USER CODE BEGIN 0 */
void lcd_write4(uint8_t n)
{
  HAL_GPIO_WritePin(GPIOB, GPIO_PIN_4, (n &amp;gt;&amp;gt; 0) &amp;amp; 1);
  HAL_GPIO_WritePin(GPIOB, GPIO_PIN_5, (n &amp;gt;&amp;gt; 1) &amp;amp; 1);
  HAL_GPIO_WritePin(GPIOB, GPIO_PIN_6, (n &amp;gt;&amp;gt; 2) &amp;amp; 1);
  HAL_GPIO_WritePin(GPIOB, GPIO_PIN_7, (n &amp;gt;&amp;gt; 3) &amp;amp; 1);
  HAL_GPIO_WritePin(GPIOC, GPIO_PIN_15, GPIO_PIN_SET);
  HAL_Delay(1);
  HAL_GPIO_WritePin(GPIOC, GPIO_PIN_15, GPIO_PIN_RESET);
  HAL_Delay(1);
}
void lcd_write8(uint8_t data, uint8_t rs)
{
  HAL_GPIO_WritePin(GPIOC, GPIO_PIN_13, rs);
  lcd_write4(data &amp;gt;&amp;gt; 4);   // 상위 4비트
  lcd_write4(data &amp;amp; 0x0F); // 하위 4비트
}
void lcd_cmd(uint8_t cmd)
{
  lcd_write8(cmd, 0);
}
void lcd_data(uint8_t data)
{
  lcd_write8(data, 1);
}
void lcd_puts(char *s)
{
  while(*s)
  	lcd_data(*s++);
}


void set_cursor(uint8_t x, uint8_t y){
	uint8_t cursor = 0b10000000;
	if(y != 0){
		cursor = cursor | 0b01000000;
	}
	cursor = cursor + x;
	lcd_cmd(cursor);
}
void set_servo(uint8_t degree){
	//degree는 0~180도 범위이고 CCR4는 600부터 2400의 범위이다!
	TIM2-&amp;gt;CCR4 = (uint32_t)(600+(2400-600)*degree/180.0);
}
uint16_t map(uint16_t analog){
	return 180*analog/4095.0;
}
/* USER CODE END 0 */
/* USER CODE BEGIN 2 */
 HAL_TIM_PWM_Start(&amp;amp;htim2,TIM_CHANNEL_4);
 //STM32가 부팅된 후 15ms이상 기다려줘야한다!
 HAL_Delay(15);
 //그다음 0b0011을 전송한다
 lcd_write4(0b0011);
 HAL_Delay(5); //4.1ms이상 대기
 lcd_write4(0b0011);
 HAL_Delay(1); //100us(0.1ms)이상 대기
 lcd_write4(0b0011);
 //HAL_Delay(1);
 lcd_write4(0b0010);
 lcd_cmd(0b00101000);  // 4bit, 2line
 lcd_cmd(0b00001000);  // Display OFF
 lcd_cmd(0b00000001);  // Clear
 //HAL_Delay(5);
 lcd_cmd(0b00000110);  // Entry mode
 lcd_cmd(0b00001100);  // Display ON
 set_cursor(0,0);
 lcd_puts(&quot;ROBOT ARM       &quot;);
 set_cursor(0,1);
 lcd_puts(&quot;NUMBER:001      &quot;);
 HAL_Delay(5000);
 uint16_t adc_value0 = 0;
 uint16_t adc_value1 = 0;
 uint8_t line1[20];
 uint8_t line2[20];
 /* USER CODE END 2 */

while (1)
 {
	  //M1:AAAA  M2:BBBB
	  //M3:CCCC
	  //PA0 ADC1 RANK1
	  HAL_ADC_Start(&amp;amp;hadc1);
	  HAL_ADC_PollForConversion(&amp;amp;hadc1, 100);
	  adc_value0 = HAL_ADC_GetValue(&amp;amp;hadc1);
	  //PA1 ADC1 RANK2
	  HAL_ADC_Start(&amp;amp;hadc1);
	  HAL_ADC_PollForConversion(&amp;amp;hadc1, 100);
	  adc_value1 = HAL_ADC_GetValue(&amp;amp;hadc1);
	  sprintf(line1,&quot;M1:%4d  M2:%4d&quot;,adc_value0,adc_value1);
	  sprintf(line2,&quot;M3:%13d&quot;,HAL_GetTick());
	  set_cursor(0,0);
	  lcd_puts(line1);
	  set_cursor(0,1);
	  lcd_puts(line2);
	  //서보모터제어
	  set_servo(map(adc_value1));
	  HAL_Delay(100);
   /* USER CODE END WHILE */
   /* USER CODE BEGIN 3 */
 }&lt;/code&gt;&lt;/pre&gt;</description>
      <category>프로그래밍/STM32</category>
      <author>덕력킹</author>
      <guid isPermaLink="true">https://bota.tistory.com/2476</guid>
      <comments>https://bota.tistory.com/2476#entry2476comment</comments>
      <pubDate>Wed, 11 Feb 2026 16:49:33 +0900</pubDate>
    </item>
    <item>
      <title>[STM32#33] 블루필보드로 3D프린터개발산업기사 실기 공개문제에 있는 메뉴트리 구현과 스탭모터(nema17 &amp;amp; a4988) 제어 구현해보기!(녹칸다 내맘대로 STM32)</title>
      <link>https://bota.tistory.com/2475</link>
      <description>&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;stm32.png&quot; data-origin-width=&quot;1920&quot; data-origin-height=&quot;1080&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/dsiSHI/dJMcagEraVE/qpk9elZvRUxE8kKhKxrOwk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/dsiSHI/dJMcagEraVE/qpk9elZvRUxE8kKhKxrOwk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/dsiSHI/dJMcagEraVE/qpk9elZvRUxE8kKhKxrOwk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FdsiSHI%2FdJMcagEraVE%2Fqpk9elZvRUxE8kKhKxrOwk%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;1920&quot; height=&quot;1080&quot; data-filename=&quot;stm32.png&quot; data-origin-width=&quot;1920&quot; data-origin-height=&quot;1080&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/live/g8DphoILqS0&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://youtube.com/live/g8DphoILqS0&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/watch?v=g8DphoILqS0&quot; data-video-thumbnail=&quot;https://scrap.kakaocdn.net/dn/MnV3T/dJMb9iaMV4R/wM4F6JPPIOWeig8cRQKznK/img.jpg?width=1280&amp;amp;height=720&amp;amp;face=0_0_1280_720,https://scrap.kakaocdn.net/dn/bN0dWo/dJMb9g46Wty/4AajMgI5EJ7qO233Zl6Iq1/img.jpg?width=1280&amp;amp;height=720&amp;amp;face=0_0_1280_720,https://scrap.kakaocdn.net/dn/DEcHp/dJMb9cBDUv2/tHH8J5oND5hYXXHGGKWl90/img.jpg?width=1280&amp;amp;height=720&amp;amp;face=0_0_1280_720&quot; data-video-width=&quot;860&quot; data-video-height=&quot;484&quot; data-video-origin-width=&quot;860&quot; data-video-origin-height=&quot;484&quot; data-ke-mobilestyle=&quot;widthContent&quot; data-video-title=&quot;[STM32#33] 블루필보드로 3D프린터개발산업기사 실기 공개문제에 있는 메뉴트리 구현과 스탭모터(ne&quot; data-original-url=&quot;&quot;&gt;&lt;iframe src=&quot;https://www.youtube.com/embed/g8DphoILqS0&quot; width=&quot;860&quot; height=&quot;484&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;[STM32#33]&amp;nbsp;블루필보드로&amp;nbsp;3D프린터개발산업기사&amp;nbsp;실기&amp;nbsp;공개문제에&amp;nbsp;있는&amp;nbsp;메뉴트리&amp;nbsp;구현과&amp;nbsp;스탭모터(nema17&amp;nbsp;&amp;amp;&amp;nbsp;a4988)&amp;nbsp;제어&amp;nbsp;구현해보기!(녹칸다&amp;nbsp;내맘대로&amp;nbsp;STM32) &lt;br /&gt;&lt;br /&gt;심심한녹칸다의&amp;nbsp;내맘대로&amp;nbsp;STM32시리즈이다! &lt;br /&gt;&lt;br /&gt;STM32시리즈의&amp;nbsp;모든&amp;nbsp;자료는&amp;nbsp;구글&amp;nbsp;슬라이드에&amp;nbsp;작성하고&amp;nbsp;모두에게&amp;nbsp;공유되어있음! &lt;br /&gt;&lt;a href=&quot;https://docs.google.com/presentation/d/1myA5iYbjuKsLWLqtRLKAiRfwUwvqB1d1RGjiMIIgp3I/edit?slide=id.g3bd6ca3685c_3_55#slide=id.g3bd6ca3685c_3_55&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://docs.google.com/presentation/d/1myA5iYbjuKsLWLqtRLKAiRfwUwvqB1d1RGjiMIIgp3I/edit?slide=id.g3bd6ca3685c_3_55#slide=id.g3bd6ca3685c_3_55&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;3D프린터개발산업기사에&amp;nbsp;있는&amp;nbsp;일부&amp;nbsp;내용을&amp;nbsp;STM32보드로&amp;nbsp;한번&amp;nbsp;접근해보는&amp;nbsp;것입니다! &lt;br /&gt;실제&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;1.PB5,PB6,PB7핀을&amp;nbsp;활용해서&amp;nbsp;로터리엔코더를&amp;nbsp;연결하고&amp;nbsp;선형적인&amp;nbsp;링크드&amp;nbsp;리스트를&amp;nbsp;구성해서&amp;nbsp;로터리&amp;nbsp;엔코더를&amp;nbsp;돌렸을때&amp;nbsp;항목이&amp;nbsp;바뀌는&amp;nbsp;결과를&amp;nbsp;PC의&amp;nbsp;putty&amp;nbsp;화면에&amp;nbsp;하시오!&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;01.PNG&quot; data-origin-width=&quot;824&quot; data-origin-height=&quot;537&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/ZuyhE/dJMcagEraYc/uzekjKhl3WnIuMHjb7ZMzk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/ZuyhE/dJMcagEraYc/uzekjKhl3WnIuMHjb7ZMzk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/ZuyhE/dJMcagEraYc/uzekjKhl3WnIuMHjb7ZMzk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FZuyhE%2FdJMcagEraYc%2FuzekjKhl3WnIuMHjb7ZMzk%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;824&quot; height=&quot;537&quot; data-filename=&quot;01.PNG&quot; data-origin-width=&quot;824&quot; data-origin-height=&quot;537&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;pre id=&quot;code_1770649449558&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 */
 uint8_t buff[50];
 uint8_t old_A = 0;
 typedef struct Node {
    struct Node *parent;
    struct Node *child;
    int value;
 }Node;
 Node n1; //최상위
 Node n2;
 Node n3;
 Node n4; //최하위
 //n1의 자식은 n2이고 부모는 없다!
 n1.value = 1;
 n1.child = &amp;amp;n2;
 n1.parent = NULL;
 //n2의 자식은 n3이고 부모는 n1이다!
 n2.value = 2;
 n2.child = &amp;amp;n3;
 n2.parent = &amp;amp;n1;
 //n3의 자식은 n4이고 부모는 n2이다!
 n3.value = 3;
 n3.child = &amp;amp;n4;
 n3.parent = &amp;amp;n2;
 //n4의 자식은 없고 부모는 n3이다!
 n4.value = 4;
 n4.child = NULL;
 n4.parent = &amp;amp;n3;
 //초기 관심노드는 n1이다!
 Node *CWD = &amp;amp;n1;
 int num = 0;
 /* USER CODE END 2 */

while (1)
 {
	  //녹칸다가 풀업방식으로 연결해놓음
	  uint8_t sw = HAL_GPIO_ReadPin(rot_sw_GPIO_Port,rot_sw_Pin);
	  if(sw == 0){
		  //현재 CWD가 참조하는 원본의 num값이 몇이냐?
		  sprintf(buff,&quot;num = %d\n&quot;,CWD-&amp;gt;value);
		  CDC_Transmit_FS(buff, strlen(buff));
		  HAL_Delay(200);
	  }
	  //PA11의 상승엣지가 발생했을때
	  uint8_t now_A = HAL_GPIO_ReadPin(rot_clk_GPIO_Port,rot_clk_Pin);
	  if(old_A == 0 &amp;amp;&amp;amp; now_A == 1){
		  //PA12의 값을 측정해서 LOW면 시계, HIGH면 반시계
		  uint8_t now_B = HAL_GPIO_ReadPin(rot_dt_GPIO_Port,rot_dt_Pin);
		  if(now_B){
			 //반시계
			  //최하위 -&amp;gt; 최상위 방향으로 이동
			  //만약 부모노드가 없다면 이동하지 않는다!
			  if(CWD-&amp;gt;parent){
				  CWD = CWD-&amp;gt;parent;
			  }else{
				  CDC_Transmit_FS(&quot;THIS NODE IS ROOT!\n&quot;, 19);
			  }
			  sprintf(buff,&quot;num = %d\n&quot;,CWD-&amp;gt;value);
			  CDC_Transmit_FS(buff, strlen(buff));

		  }else{
			 //시계
			  //최상위 -&amp;gt; 최하위 방향이동
			  //만약 자식노드가 없다면 이동하지 않는다!
			  if(CWD-&amp;gt;child){
				  CWD = CWD-&amp;gt;child;
			  }else{
				  CDC_Transmit_FS(&quot;THIS NODE IS LEAF!\n&quot;, 19);
			  }
			  sprintf(buff,&quot;num = %d\n&quot;,CWD-&amp;gt;value);
			  CDC_Transmit_FS(buff, strlen(buff));
		  }
	  }
	  old_A = now_A;
	  HAL_Delay(1);
   /* USER CODE END WHILE */
   /* USER CODE BEGIN 3 */
 }&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;br /&gt;2.공개시험&amp;nbsp;문제에&amp;nbsp;나오는&amp;nbsp;메뉴트리를&amp;nbsp;그대로&amp;nbsp;구성하되&amp;nbsp;결과를&amp;nbsp;PC&amp;nbsp;화면에서&amp;nbsp;출력하시오!&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;02.PNG&quot; data-origin-width=&quot;801&quot; data-origin-height=&quot;547&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/mglvX/dJMcahJ60Zb/B8Eryldp34KTv8jszxtV10/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/mglvX/dJMcahJ60Zb/B8Eryldp34KTv8jszxtV10/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/mglvX/dJMcahJ60Zb/B8Eryldp34KTv8jszxtV10/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FmglvX%2FdJMcahJ60Zb%2FB8Eryldp34KTv8jszxtV10%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;801&quot; height=&quot;547&quot; data-filename=&quot;02.PNG&quot; data-origin-width=&quot;801&quot; data-origin-height=&quot;547&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;pre id=&quot;code_1770649475043&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 */
 uint8_t buff[50];
 uint8_t old_A = 0;
 typedef struct Node {
    struct Node *parent;
    struct Node *child;
    struct Node *next;
    struct Node *prev;
    uint8_t Text[20];
    uint8_t is_return; //true면 리턴노드
 }Node;
 Node root;
 Node menu1;
 Node menu2;
 Node menu2_1;
 Node menu2_2;
 strcpy(menu1.Text, &quot;EXIT            &quot;);
 strcpy(menu2.Text, &quot;MOTOR TEST      &quot;);
 strcpy(menu2_1.Text, &quot;ANGLE:+000.0    &quot;);
 strcpy(menu2_2.Text, &quot;RETURN          &quot;);
 root.is_return = 0;
 menu1.is_return = 1;
 menu2.is_return = 0;
 menu2_1.is_return = 0;
 menu2_2.is_return = 1;
 root.parent = NULL;
 root.child = &amp;amp;menu1;
 root.next = NULL;
 root.prev = NULL;

 menu1.parent = &amp;amp;root;
 menu1.child = NULL;
 menu1.next = &amp;amp;menu2;
 menu1.prev = &amp;amp;menu2;
 menu2.parent = &amp;amp;root;
 menu2.child = &amp;amp;menu2_1;
 menu2.next = &amp;amp;menu1;
 menu2.prev = &amp;amp;menu1;
 menu2_1.parent = &amp;amp;menu2;
 menu2_1.child = NULL;
 menu2_1.next = &amp;amp;menu2_2;
 menu2_1.prev = NULL;
 menu2_2.parent = &amp;amp;menu2;
 menu2_2.child = NULL;
 menu2_2.next = NULL;
 menu2_2.prev = &amp;amp;menu2_1;
 Node *CWD = &amp;amp;root;
 //초기화면은 root의 화면이 출력된다!
 CDC_Transmit_FS(&quot;X:    Y:    A000\n3D PRINTER READY\n&quot;, 34);
 /* USER CODE END 2 */


while (1)
 {
	  //녹칸다가 풀업방식으로 연결해놓음
	  uint8_t sw = HAL_GPIO_ReadPin(rot_sw_GPIO_Port,rot_sw_Pin);
	  if(sw == 0){
		  //현재노드가 root노드이면 root의 하위메뉴로 진입한다!
		  if(CWD == &amp;amp;root){
			  CWD = CWD-&amp;gt;child;
			  //LCD에 나와야할 내용은 child와 그다음 삼촌이다!
			  //&amp;gt;CWD-&amp;gt;Text;
			  // CWD-&amp;gt;next-&amp;gt;Text;
			  CDC_Transmit_FS(&quot;&amp;gt;&quot;, 1);
			  HAL_Delay(10);
			  CDC_Transmit_FS(CWD-&amp;gt;Text, strlen(CWD-&amp;gt;Text));
			  HAL_Delay(10);
			  CDC_Transmit_FS(&quot;\n &quot;, 2);
			  HAL_Delay(10);
			  CDC_Transmit_FS(CWD-&amp;gt;next-&amp;gt;Text, strlen(CWD-&amp;gt;next-&amp;gt;Text));
			  HAL_Delay(10);
			  CDC_Transmit_FS(&quot;\n&quot;, 1);
		  }else{
			  //만약에 현재 노드가 리턴노드면 상위메뉴로 이동한다
			  if(CWD-&amp;gt;is_return){
				  if(CWD-&amp;gt;parent){
					  CWD = CWD-&amp;gt;parent;
					  //상위메뉴로 올라갔는데, 그 메뉴가 root인 경우

					  if(CWD == &amp;amp;root){
						  //root 고유한 화면 출력
						  CDC_Transmit_FS(&quot;X:    Y:    A000\n3D PRINTER READY\n&quot;, 34);
					  }else{
						  CDC_Transmit_FS(&quot;&amp;gt;&quot;, 1);
						  HAL_Delay(10);
						  CDC_Transmit_FS(CWD-&amp;gt;Text, strlen(CWD-&amp;gt;Text));
						  HAL_Delay(10);
						  CDC_Transmit_FS(&quot;\n &quot;, 2);
						  HAL_Delay(10);
						  CDC_Transmit_FS(CWD-&amp;gt;next-&amp;gt;Text, strlen(CWD-&amp;gt;next-&amp;gt;Text));
						  HAL_Delay(10);
						  CDC_Transmit_FS(&quot;\n&quot;, 1);
					  }
				  }
			  }else{
				  //루트도 아니고 리턴노드도 아니라면 하위메뉴로 진입한다!
				  if(CWD-&amp;gt;child){
					  CWD = CWD-&amp;gt;child;
					  CDC_Transmit_FS(&quot;&amp;gt;&quot;, 1);
					  HAL_Delay(10);
					  CDC_Transmit_FS(CWD-&amp;gt;Text, strlen(CWD-&amp;gt;Text));
					  HAL_Delay(10);
					  CDC_Transmit_FS(&quot;\n &quot;, 2);
					  HAL_Delay(10);

					  CDC_Transmit_FS(CWD-&amp;gt;next-&amp;gt;Text, strlen(CWD-&amp;gt;next-&amp;gt;Text));
					  HAL_Delay(10);
					  CDC_Transmit_FS(&quot;\n&quot;, 1);
				  }else{
					  //리프노드인 경우
				  }
			  }
		  }
		  HAL_Delay(200);
	  }
	  //PA11의 상승엣지가 발생했을때
	  uint8_t now_A = HAL_GPIO_ReadPin(rot_clk_GPIO_Port,rot_clk_Pin);
	  if(old_A == 0 &amp;amp;&amp;amp; now_A == 1){
		  //PA12의 값을 측정해서 LOW면 시계, HIGH면 반시계
		  uint8_t now_B = HAL_GPIO_ReadPin(rot_dt_GPIO_Port,rot_dt_Pin);
		  if(now_B){
			 //반시계
			  if(CWD != &amp;amp;root &amp;amp;&amp;amp; CWD-&amp;gt;prev){
				 CWD = CWD-&amp;gt;prev;
				 //*CWD-&amp;gt;text
				 // CWD-&amp;gt;next-&amp;gt;text
				 CDC_Transmit_FS(&quot;&amp;gt;&quot;, 1);
				  HAL_Delay(10);
				  CDC_Transmit_FS(CWD-&amp;gt;Text, strlen(CWD-&amp;gt;Text));
				  HAL_Delay(10);
				  CDC_Transmit_FS(&quot;\n &quot;, 2);
				  HAL_Delay(10);
				  CDC_Transmit_FS(CWD-&amp;gt;next-&amp;gt;Text, strlen(CWD-&amp;gt;next-&amp;gt;Text));

				  HAL_Delay(10);
				  CDC_Transmit_FS(&quot;\n&quot;, 1);
			 }
		  }else{
			 //시계
			 //만약 next로 갈게 있다면 next로 이동한다!
			 if(CWD != &amp;amp;root &amp;amp;&amp;amp; CWD-&amp;gt;next){
				 CWD = CWD-&amp;gt;next;
				 // CWD-&amp;gt;prev-&amp;gt;text
				 //*CWD-&amp;gt;text
				 CDC_Transmit_FS(&quot; &quot;, 1);
				  HAL_Delay(10);
				  CDC_Transmit_FS(CWD-&amp;gt;prev-&amp;gt;Text, strlen(CWD-&amp;gt;prev-&amp;gt;Text));
				  HAL_Delay(10);
				  CDC_Transmit_FS(&quot;\n&amp;gt;&quot;, 2);
				  HAL_Delay(10);
				  CDC_Transmit_FS(CWD-&amp;gt;Text, strlen(CWD-&amp;gt;Text));
				  HAL_Delay(10);
				  CDC_Transmit_FS(&quot;\n&quot;, 1);
			 }
		  }
	  }
	  old_A = now_A;
	  HAL_Delay(1);
   /* USER CODE END WHILE */
   /* USER CODE BEGIN 3 */
 }&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;br /&gt;3.예제&amp;nbsp;2의&amp;nbsp;결과를&amp;nbsp;1602LCD&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-filename=&quot;03.PNG&quot; data-origin-width=&quot;824&quot; data-origin-height=&quot;551&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bgxoNf/dJMcaaqFt3l/LSnjidKKBIKeVDso0K8uq1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bgxoNf/dJMcaaqFt3l/LSnjidKKBIKeVDso0K8uq1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bgxoNf/dJMcaaqFt3l/LSnjidKKBIKeVDso0K8uq1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbgxoNf%2FdJMcaaqFt3l%2FLSnjidKKBIKeVDso0K8uq1%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;824&quot; height=&quot;551&quot; data-filename=&quot;03.PNG&quot; data-origin-width=&quot;824&quot; data-origin-height=&quot;551&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;pre id=&quot;code_1770649513713&quot; class=&quot;cpp&quot; data-ke-language=&quot;cpp&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;#define delay_ms HAL_Delay
#define SYS_CLOCK    72
#define SYSTICK_LOAD 72000-1
uint32_t millis_cnt = 0;
uint32_t millis() {
 return millis_cnt;
}
uint32_t micros() {
 return (millis_cnt &amp;amp; 0x3FFFFF) * 1000 + (SYSTICK_LOAD - SysTick-&amp;gt;VAL) / SYS_CLOCK;
}
void delay_us(uint32_t us) {  // 64MHz 보정
 if (us &amp;gt; 1) {
   uint32_t count = us * 7 - 6;
   while (count--);
 } else {
   uint32_t count = 2;
   while (count--);
 }
}
#define ADDRESS   0x27&amp;lt;&amp;lt;1
#define RS1_EN1   0x05
#define RS1_EN0   0x01
#define RS0_EN1   0x04
#define RS0_EN0   0x00
#define BackLight 0x08
// RS-Q0 / RW-Q1 / EN-Q2 / BackLight-Q3 / D4-Q4 / D5-Q5 / D6-Q6 / D7-Q7
void LCD_DATA(uint8_t data) {
 uint8_t temp=(data &amp;amp; 0xF0)|RS1_EN1|BackLight;
 while(HAL_I2C_Master_Transmit(&amp;amp;hi2c1, ADDRESS, &amp;amp;temp, 1, 1000)!=HAL_OK);
 temp=(data &amp;amp; 0xF0)|RS1_EN0|BackLight;
 while(HAL_I2C_Master_Transmit(&amp;amp;hi2c1, ADDRESS, &amp;amp;temp, 1, 1000)!=HAL_OK);
 delay_us(4);
 temp=((data &amp;lt;&amp;lt; 4) &amp;amp; 0xF0)|RS1_EN1|BackLight;
 while(HAL_I2C_Master_Transmit(&amp;amp;hi2c1, ADDRESS, &amp;amp;temp, 1, 1000)!=HAL_OK);
 temp = ((data &amp;lt;&amp;lt; 4) &amp;amp; 0xF0)|RS1_EN0|BackLight;
 while(HAL_I2C_Master_Transmit(&amp;amp;hi2c1, ADDRESS, &amp;amp;temp, 1, 1000)!=HAL_OK);
 delay_us(50);
}
void LCD_CMD(uint8_t cmd) {
 uint8_t temp=(cmd &amp;amp; 0xF0)|RS0_EN1|BackLight;
 while(HAL_I2C_Master_Transmit(&amp;amp;hi2c1, ADDRESS, &amp;amp;temp, 1, 1000)!=HAL_OK);
 temp=(cmd &amp;amp; 0xF0)|RS0_EN0|BackLight;
 while(HAL_I2C_Master_Transmit(&amp;amp;hi2c1, ADDRESS, &amp;amp;temp, 1, 1000)!=HAL_OK);
 delay_us(4);
 temp=((cmd &amp;lt;&amp;lt; 4) &amp;amp; 0xF0)|RS0_EN1|BackLight;
 while(HAL_I2C_Master_Transmit(&amp;amp;hi2c1, ADDRESS, &amp;amp;temp, 1, 1000)!=HAL_OK);
 temp=((cmd &amp;lt;&amp;lt; 4) &amp;amp; 0xF0)|RS0_EN0|BackLight;
 while(HAL_I2C_Master_Transmit(&amp;amp;hi2c1, ADDRESS, &amp;amp;temp, 1, 1000)!=HAL_OK);
 delay_us(50);
}
void LCD_CMD_4bit(uint8_t cmd) {
 uint8_t temp=((cmd &amp;lt;&amp;lt; 4) &amp;amp; 0xF0)|RS0_EN1|BackLight;
 while(HAL_I2C_Master_Transmit(&amp;amp;hi2c1, ADDRESS, &amp;amp;temp, 1, 1000)!=HAL_OK);
 temp=((cmd &amp;lt;&amp;lt; 4) &amp;amp; 0xF0)|RS0_EN0|BackLight;
 while(HAL_I2C_Master_Transmit(&amp;amp;hi2c1, ADDRESS, &amp;amp;temp, 1, 1000)!=HAL_OK);
 delay_us(50);
}
void LCD_INIT(void) {
 delay_ms(100);
 LCD_CMD_4bit(0x03); delay_ms(5);
 LCD_CMD_4bit(0x03); delay_us(100);
 LCD_CMD_4bit(0x03); delay_us(100);
 LCD_CMD_4bit(0x02); delay_us(100);
 LCD_CMD(0x28);  // 4 bits, 2 line, 5x8 font
 LCD_CMD(0x08);  // display off, cursor off, blink off
 LCD_CMD(0x01);  // clear display
 delay_ms(3);
 LCD_CMD(0x06);  // cursor movint direction
 LCD_CMD(0x0C);  // display on, cursor off, blink off
}
void LCD_XY(char x, char y) {
 if      (y == 0) LCD_CMD(0x80 + x);
 else if (y == 1) LCD_CMD(0xC0 + x);
 else if (y == 2) LCD_CMD(0x94 + x);
 else if (y == 3) LCD_CMD(0xD4 + x);
}
void LCD_CLEAR(void) {
 LCD_CMD(0x01);
 delay_ms(2);
}
void LCD_PUTS(char *str) {
 while (*str) LCD_DATA(*str++);
}
/* USER CODE BEGIN 2 */
 LCD_INIT(); //1회호출(메인루프 시작전)
 uint8_t buff[50];
 uint8_t old_A = 0;
 typedef struct Node {
    struct Node *parent;
    struct Node *child;
    struct Node *next;
    struct Node *prev;
    uint8_t Text[20];
    uint8_t is_return; //true면 리턴노드
 }Node;
 Node root;
 Node menu1;
 Node menu2;
 Node menu2_1;
 Node menu2_2;
 strcpy(menu1.Text, &quot;EXIT            &quot;);
 strcpy(menu2.Text, &quot;MOTOR TEST      &quot;);
 strcpy(menu2_1.Text, &quot;ANGLE:+000.0    &quot;);
 strcpy(menu2_2.Text, &quot;RETURN          &quot;);
 root.is_return = 0;
 menu1.is_return = 1;
 menu2.is_return = 0;
 menu2_1.is_return = 0;
 menu2_2.is_return = 1;
 root.parent = NULL;
 root.child = &amp;amp;menu1;
 root.next = NULL;
 root.prev = NULL;

 menu1.parent = &amp;amp;root;
 menu1.child = NULL;
 menu1.next = &amp;amp;menu2;
 menu1.prev = &amp;amp;menu2;
 menu2.parent = &amp;amp;root;
 menu2.child = &amp;amp;menu2_1;
 menu2.next = &amp;amp;menu1;
 menu2.prev = &amp;amp;menu1;
 menu2_1.parent = &amp;amp;menu2;
 menu2_1.child = NULL;
 menu2_1.next = &amp;amp;menu2_2;
 menu2_1.prev = NULL;
 menu2_2.parent = &amp;amp;menu2;
 menu2_2.child = NULL;
 menu2_2.next = NULL;
 menu2_2.prev = &amp;amp;menu2_1;
 Node *CWD = &amp;amp;root;
 //초기화면은 root의 화면이 출력된다!
 LCD_XY(0, 0) ; LCD_PUTS(&quot;X:    Y:    A000&quot;);
 LCD_XY(0, 1) ; LCD_PUTS(&quot;3D PRINTER READY&quot;);
 /* USER CODE END 2 */


while (1)
 {
	  //녹칸다가 풀업방식으로 연결해놓음
	  uint8_t sw = HAL_GPIO_ReadPin(rot_sw_GPIO_Port,rot_sw_Pin);
	  if(sw == 0){
		  //현재노드가 root노드이면 root의 하위메뉴로 진입한다!
		  if(CWD == &amp;amp;root){
			  CWD = CWD-&amp;gt;child;
			  //LCD에 나와야할 내용은 child와 그다음 삼촌이다!
			  //&amp;gt;CWD-&amp;gt;Text;
			  // CWD-&amp;gt;next-&amp;gt;Text;
			  LCD_XY(0, 0) ; LCD_PUTS(&quot;&amp;gt;&quot;);
			  LCD_XY(1, 0) ; LCD_PUTS(CWD-&amp;gt;Text);
			  LCD_XY(0, 1) ; LCD_PUTS(&quot; &quot;);
			  LCD_XY(1, 1) ; LCD_PUTS(CWD-&amp;gt;next-&amp;gt;Text);
		  }else{
			  //만약에 현재 노드가 리턴노드면 상위메뉴로 이동한다
			  if(CWD-&amp;gt;is_return){
				  if(CWD-&amp;gt;parent){
					  CWD = CWD-&amp;gt;parent;
					  //상위메뉴로 올라갔는데, 그 메뉴가 root인 경우
					  if(CWD == &amp;amp;root){
						  //root 고유한 화면 출력
						  LCD_XY(0, 0) ; LCD_PUTS(&quot;X:    Y:    A000&quot;);
						  LCD_XY(0, 1) ; LCD_PUTS(&quot;3D PRINTER READY&quot;);
					  }else{
						  LCD_XY(0, 0) ; LCD_PUTS(&quot;&amp;gt;&quot;);
						  LCD_XY(1, 0) ; LCD_PUTS(CWD-&amp;gt;Text);
						  LCD_XY(0, 1) ; LCD_PUTS(&quot; &quot;);
						  LCD_XY(1, 1) ; LCD_PUTS(CWD-&amp;gt;next-&amp;gt;Text);
					  }
				  }
			  }else{
				  //루트도 아니고 리턴노드도 아니라면 하위메뉴로 진입한다!
				  if(CWD-&amp;gt;child){
					  CWD = CWD-&amp;gt;child;
					  LCD_XY(0, 0) ; LCD_PUTS(&quot;&amp;gt;&quot;);
					  LCD_XY(1, 0) ; LCD_PUTS(CWD-&amp;gt;Text);
					  LCD_XY(0, 1) ; LCD_PUTS(&quot; &quot;);
					  LCD_XY(1, 1) ; LCD_PUTS(CWD-&amp;gt;next-&amp;gt;Text);
				  }else{
					  //리프노드인 경우
				  }
			  }
		  }
		  HAL_Delay(200);
	  }
	  //PA11의 상승엣지가 발생했을때
	  uint8_t now_A = HAL_GPIO_ReadPin(rot_clk_GPIO_Port,rot_clk_Pin);
	  if(old_A == 0 &amp;amp;&amp;amp; now_A == 1){
		  //PA12의 값을 측정해서 LOW면 시계, HIGH면 반시계
		  uint8_t now_B = HAL_GPIO_ReadPin(rot_dt_GPIO_Port,rot_dt_Pin);
		  if(now_B){
			 //반시계
			  if(CWD != &amp;amp;root &amp;amp;&amp;amp; CWD-&amp;gt;prev){
				 CWD = CWD-&amp;gt;prev;
				 LCD_XY(0, 0) ; LCD_PUTS(&quot;&amp;gt;&quot;);
				 LCD_XY(1, 0) ; LCD_PUTS(CWD-&amp;gt;Text);
				 LCD_XY(0, 1) ; LCD_PUTS(&quot; &quot;);
				 LCD_XY(1, 1) ; LCD_PUTS(CWD-&amp;gt;next-&amp;gt;Text);
			 }

		  }else{
			 //시계
			 //만약 next로 갈게 있다면 next로 이동한다!
			 if(CWD != &amp;amp;root &amp;amp;&amp;amp; CWD-&amp;gt;next){
				 CWD = CWD-&amp;gt;next;
				 LCD_XY(0, 0) ; LCD_PUTS(&quot; &quot;);
				 LCD_XY(1, 0) ; LCD_PUTS(CWD-&amp;gt;prev-&amp;gt;Text);
				 LCD_XY(0, 1) ; LCD_PUTS(&quot;&amp;gt;&quot;);
				 LCD_XY(1, 1) ; LCD_PUTS(CWD-&amp;gt;Text);
			 }
		  }
	  }
	  old_A = now_A;
	  HAL_Delay(1);
   /* USER CODE END WHILE */
   /* USER CODE BEGIN 3 */
 }&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;br /&gt;4.PB3핀에&amp;nbsp;A4988의&amp;nbsp;STEP핀을&amp;nbsp;연결하고&amp;nbsp;PB4에&amp;nbsp;DIR핀을&amp;nbsp;연결해서&amp;nbsp;NEMA17스탭모터를&amp;nbsp;테스트&amp;nbsp;하는&amp;nbsp;코드를&amp;nbsp;먼저&amp;nbsp;만드시오!&amp;nbsp;로터리엔코더&amp;nbsp;스위치를&amp;nbsp;누르면&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 alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;04.PNG&quot; data-origin-width=&quot;774&quot; data-origin-height=&quot;540&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/tGqh0/dJMcahJ60Zi/uLDf5p1xJxHyfLAFYoD5a1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/tGqh0/dJMcahJ60Zi/uLDf5p1xJxHyfLAFYoD5a1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/tGqh0/dJMcahJ60Zi/uLDf5p1xJxHyfLAFYoD5a1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FtGqh0%2FdJMcahJ60Zi%2FuLDf5p1xJxHyfLAFYoD5a1%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;774&quot; height=&quot;540&quot; data-filename=&quot;04.PNG&quot; data-origin-width=&quot;774&quot; data-origin-height=&quot;540&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;pre id=&quot;code_1770649560581&quot; class=&quot;cpp&quot; data-ke-language=&quot;cpp&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;#define delay_ms HAL_Delay
#define SYS_CLOCK    72
#define SYSTICK_LOAD 72000-1
uint32_t millis_cnt = 0;
uint32_t millis() {
 return millis_cnt;
}
uint32_t micros() {
 return (millis_cnt &amp;amp; 0x3FFFFF) * 1000 + (SYSTICK_LOAD - SysTick-&amp;gt;VAL) / SYS_CLOCK;
}
void delay_us(uint32_t us) {  // 64MHz 보정
 if (us &amp;gt; 1) {
   uint32_t count = us * 7 - 6;
   while (count--);
 } else {
   uint32_t count = 2;
   while (count--);
 }
}
#define ADDRESS   0x27&amp;lt;&amp;lt;1
#define RS1_EN1   0x05
#define RS1_EN0   0x01
#define RS0_EN1   0x04
#define RS0_EN0   0x00
#define BackLight 0x08
// RS-Q0 / RW-Q1 / EN-Q2 / BackLight-Q3 / D4-Q4 / D5-Q5 / D6-Q6 / D7-Q7
void LCD_DATA(uint8_t data) {
 uint8_t temp=(data &amp;amp; 0xF0)|RS1_EN1|BackLight;
 while(HAL_I2C_Master_Transmit(&amp;amp;hi2c1, ADDRESS, &amp;amp;temp, 1, 1000)!=HAL_OK);
 temp=(data &amp;amp; 0xF0)|RS1_EN0|BackLight;
 while(HAL_I2C_Master_Transmit(&amp;amp;hi2c1, ADDRESS, &amp;amp;temp, 1, 1000)!=HAL_OK);
 delay_us(4);
 temp=((data &amp;lt;&amp;lt; 4) &amp;amp; 0xF0)|RS1_EN1|BackLight;
 while(HAL_I2C_Master_Transmit(&amp;amp;hi2c1, ADDRESS, &amp;amp;temp, 1, 1000)!=HAL_OK);
 temp = ((data &amp;lt;&amp;lt; 4) &amp;amp; 0xF0)|RS1_EN0|BackLight;
 while(HAL_I2C_Master_Transmit(&amp;amp;hi2c1, ADDRESS, &amp;amp;temp, 1, 1000)!=HAL_OK);
 delay_us(50);
}
void LCD_CMD(uint8_t cmd) {
 uint8_t temp=(cmd &amp;amp; 0xF0)|RS0_EN1|BackLight;
 while(HAL_I2C_Master_Transmit(&amp;amp;hi2c1, ADDRESS, &amp;amp;temp, 1, 1000)!=HAL_OK);
 temp=(cmd &amp;amp; 0xF0)|RS0_EN0|BackLight;
 while(HAL_I2C_Master_Transmit(&amp;amp;hi2c1, ADDRESS, &amp;amp;temp, 1, 1000)!=HAL_OK);
 delay_us(4);
 temp=((cmd &amp;lt;&amp;lt; 4) &amp;amp; 0xF0)|RS0_EN1|BackLight;
 while(HAL_I2C_Master_Transmit(&amp;amp;hi2c1, ADDRESS, &amp;amp;temp, 1, 1000)!=HAL_OK);
 temp=((cmd &amp;lt;&amp;lt; 4) &amp;amp; 0xF0)|RS0_EN0|BackLight;
 while(HAL_I2C_Master_Transmit(&amp;amp;hi2c1, ADDRESS, &amp;amp;temp, 1, 1000)!=HAL_OK);
 delay_us(50);
}
void LCD_CMD_4bit(uint8_t cmd) {
 uint8_t temp=((cmd &amp;lt;&amp;lt; 4) &amp;amp; 0xF0)|RS0_EN1|BackLight;
 while(HAL_I2C_Master_Transmit(&amp;amp;hi2c1, ADDRESS, &amp;amp;temp, 1, 1000)!=HAL_OK);
 temp=((cmd &amp;lt;&amp;lt; 4) &amp;amp; 0xF0)|RS0_EN0|BackLight;
 while(HAL_I2C_Master_Transmit(&amp;amp;hi2c1, ADDRESS, &amp;amp;temp, 1, 1000)!=HAL_OK);
 delay_us(50);
}
void LCD_INIT(void) {
 delay_ms(100);
 LCD_CMD_4bit(0x03); delay_ms(5);
 LCD_CMD_4bit(0x03); delay_us(100);
 LCD_CMD_4bit(0x03); delay_us(100);
 LCD_CMD_4bit(0x02); delay_us(100);
 LCD_CMD(0x28);  // 4 bits, 2 line, 5x8 font
 LCD_CMD(0x08);  // display off, cursor off, blink off
 LCD_CMD(0x01);  // clear display
 delay_ms(3);
 LCD_CMD(0x06);  // cursor movint direction
 LCD_CMD(0x0C);  // display on, cursor off, blink off
}
void LCD_XY(char x, char y) {
 if      (y == 0) LCD_CMD(0x80 + x);
 else if (y == 1) LCD_CMD(0xC0 + x);
 else if (y == 2) LCD_CMD(0x94 + x);
 else if (y == 3) LCD_CMD(0xD4 + x);
}
void LCD_CLEAR(void) {
 LCD_CMD(0x01);
 delay_ms(2);
}
void LCD_PUTS(char *str) {
 while (*str) LCD_DATA(*str++);
}
/* USER CODE BEGIN 0 */
volatile int32_t set_deg = 0;
int32_t now_deg = 0;
void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim)
{
	if(set_deg*2 &amp;gt; now_deg){
		//시계방향으로 회전해서 목표지점에 도달한다!
		HAL_GPIO_WritePin(DIR_GPIO_Port, DIR_Pin, 0); //정회전
		HAL_GPIO_TogglePin(STEP_GPIO_Port, STEP_Pin);
		now_deg++;
	}else if(set_deg*2 &amp;lt; now_deg){
		//반시계방향으로 회전해서 목표지점에 도달한다!
		HAL_GPIO_WritePin(DIR_GPIO_Port, DIR_Pin, 1); //역회전
		HAL_GPIO_TogglePin(STEP_GPIO_Port, STEP_Pin);
		now_deg--;
	}
}
/* USER CODE END 0 */
/* USER CODE BEGIN 2 */
 HAL_TIM_Base_Start_IT(&amp;amp;htim3);
 HAL_GPIO_WritePin(DIR_GPIO_Port, DIR_Pin, 0); //회전방향
 LCD_INIT(); //1회호출(메인루프 시작전)
 uint8_t buff[50];
 uint8_t old_A = 0;
 typedef struct Node {
    struct Node *parent;
    struct Node *child;
    struct Node *next;
    struct Node *prev;
    uint8_t Text[20];
    uint8_t is_return; //true면 리턴노드
 }Node;
 Node root;
 Node menu1;
 Node menu2;
 Node menu2_1;
 Node menu2_2;
 strcpy(menu1.Text, &quot;EXIT            &quot;);
 strcpy(menu2.Text, &quot;MOTOR TEST      &quot;);
 strcpy(menu2_1.Text, &quot;ANGLE:+000.0    &quot;);
 strcpy(menu2_2.Text, &quot;RETURN          &quot;);
 root.is_return = 0;
 menu1.is_return = 1;
 menu2.is_return = 0;
 menu2_1.is_return = 0;
 menu2_2.is_return = 1;
 root.parent = NULL;
 root.child = &amp;amp;menu1;
 root.next = NULL;
 root.prev = NULL;
 menu1.parent = &amp;amp;root;
 menu1.child = NULL;
 menu1.next = &amp;amp;menu2;
 menu1.prev = &amp;amp;menu2;
 menu2.parent = &amp;amp;root;
 menu2.child = &amp;amp;menu2_1;
 menu2.next = &amp;amp;menu1;
 menu2.prev = &amp;amp;menu1;
 menu2_1.parent = &amp;amp;menu2;
 menu2_1.child = NULL;
 menu2_1.next = &amp;amp;menu2_2;
 menu2_1.prev = NULL;
 menu2_2.parent = &amp;amp;menu2;
 menu2_2.child = NULL;
 menu2_2.next = NULL;
 menu2_2.prev = &amp;amp;menu2_1;
 Node *CWD = &amp;amp;root;
 //초기화면은 root의 화면이 출력된다!
 LCD_XY(0, 0) ; LCD_PUTS(&quot;X:    Y:    A000&quot;);
 LCD_XY(0, 1) ; LCD_PUTS(&quot;3D PRINTER READY&quot;);
 float target_deg = 0;
 int32_t tar_deg = 0;
 /* USER CODE END 2 */
while (1)
 {
	  //녹칸다가 풀업방식으로 연결해놓음
	  uint8_t sw = HAL_GPIO_ReadPin(rot_sw_GPIO_Port,rot_sw_Pin);
	  if(sw == 0){
		  //현재노드가 root노드이면 root의 하위메뉴로 진입한다!
		  if(CWD == &amp;amp;root){
			  CWD = CWD-&amp;gt;child;
			  //LCD에 나와야할 내용은 child와 그다음 삼촌이다!
			  //&amp;gt;CWD-&amp;gt;Text;
			  // CWD-&amp;gt;next-&amp;gt;Text;
			  LCD_XY(0, 0) ; LCD_PUTS(&quot;&amp;gt;&quot;);
			  LCD_XY(1, 0) ; LCD_PUTS(CWD-&amp;gt;Text);
			  LCD_XY(0, 1) ; LCD_PUTS(&quot; &quot;);
			  LCD_XY(1, 1) ; LCD_PUTS(CWD-&amp;gt;next-&amp;gt;Text);
		  }else{
			  //만약에 현재 노드가 리턴노드면 상위메뉴로 이동한다
			  if(CWD-&amp;gt;is_return){
				  if(CWD-&amp;gt;parent){
					  CWD = CWD-&amp;gt;parent;
					  //상위메뉴로 올라갔는데, 그 메뉴가 root인 경우
					  if(CWD == &amp;amp;root){
						  //root 고유한 화면 출력
						  LCD_XY(0, 0) ; LCD_PUTS(&quot;X:    Y:    A000&quot;);
						  LCD_XY(0, 1) ; LCD_PUTS(&quot;3D PRINTER READY&quot;);

					  }else{
						  LCD_XY(0, 0) ; LCD_PUTS(&quot;&amp;gt;&quot;);
						  LCD_XY(1, 0) ; LCD_PUTS(CWD-&amp;gt;Text);
						  LCD_XY(0, 1) ; LCD_PUTS(&quot; &quot;);
						  LCD_XY(1, 1) ; LCD_PUTS(CWD-&amp;gt;next-&amp;gt;Text);
					  }
				  }
			  }else{
				  //루트도 아니고 리턴노드도 아니라면 하위메뉴로 진입한다!
				  if(CWD-&amp;gt;child){
					  CWD = CWD-&amp;gt;child;
					  LCD_XY(0, 0) ; LCD_PUTS(&quot;&amp;gt;&quot;);
					  LCD_XY(1, 0) ; LCD_PUTS(CWD-&amp;gt;Text);
					  LCD_XY(0, 1) ; LCD_PUTS(&quot; &quot;);
					  LCD_XY(1, 1) ; LCD_PUTS(CWD-&amp;gt;next-&amp;gt;Text);
				  }else{
					  //리프노드인 경우
					  if(CWD == &amp;amp;menu2_1){
						  //한번 누르면 설정 한번더 누르면 확인
						  HAL_Delay(200);
						  while(1){
							  uint8_t now_A = HAL_GPIO_ReadPin(rot_clk_GPIO_Port,rot_clk_Pin);
							  if(old_A == 0 &amp;amp;&amp;amp; now_A == 1){
								  //PA12의 값을 측정해서 LOW면 시계, HIGH면 반시계
								  uint8_t now_B = HAL_GPIO_ReadPin(rot_dt_GPIO_Port,rot_dt_Pin);

								  if(now_B){
									 //반시계
									  target_deg -= 1.8;
									  tar_deg--;
									  LCD_XY(0, 0) ; LCD_PUTS(&quot;&amp;gt;&quot;);
									  sprintf(CWD-&amp;gt;Text,&quot;ANGLE:%.1f       &quot;,target_deg);
									  LCD_XY(1, 0) ; LCD_PUTS(CWD-&amp;gt;Text);
								  }else{
									 //시계
									  target_deg += 1.8;
									  tar_deg++;
									  LCD_XY(0, 0) ; LCD_PUTS(&quot;&amp;gt;&quot;);
									  sprintf(CWD-&amp;gt;Text,&quot;ANGLE:%.1f       &quot;,target_deg);
									  LCD_XY(1, 0) ; LCD_PUTS(CWD-&amp;gt;Text);
								  }
							  }
							  old_A = now_A;
							  HAL_Delay(1);
							  //버튼을 한번 누르면 무한루프
							  //한번더 누르면 종료
							  if(HAL_GPIO_ReadPin(rot_sw_GPIO_Port,rot_sw_Pin) == 0){
								  //녹칸다가 설정한 값으로 스탭모터를 회전시키기!
								  set_deg = tar_deg;
								  HAL_Delay(200);
								  break;
							  }
						  }
					  }

				  }
			  }
		  }
		  HAL_Delay(200);
	  }
	  //PA11의 상승엣지가 발생했을때
	  uint8_t now_A = HAL_GPIO_ReadPin(rot_clk_GPIO_Port,rot_clk_Pin);
	  if(old_A == 0 &amp;amp;&amp;amp; now_A == 1){
		  //PA12의 값을 측정해서 LOW면 시계, HIGH면 반시계
		  uint8_t now_B = HAL_GPIO_ReadPin(rot_dt_GPIO_Port,rot_dt_Pin);
		  if(now_B){
			 //반시계
			  if(CWD != &amp;amp;root &amp;amp;&amp;amp; CWD-&amp;gt;prev){
				 CWD = CWD-&amp;gt;prev;
				 LCD_XY(0, 0) ; LCD_PUTS(&quot;&amp;gt;&quot;);
				 LCD_XY(1, 0) ; LCD_PUTS(CWD-&amp;gt;Text);
				 LCD_XY(0, 1) ; LCD_PUTS(&quot; &quot;);
				 LCD_XY(1, 1) ; LCD_PUTS(CWD-&amp;gt;next-&amp;gt;Text);
			 }
		  }else{
			 //시계
			 //만약 next로 갈게 있다면 next로 이동한다!
			 if(CWD != &amp;amp;root &amp;amp;&amp;amp; CWD-&amp;gt;next){
				 CWD = CWD-&amp;gt;next;
				 LCD_XY(0, 0) ; LCD_PUTS(&quot; &quot;);
				 LCD_XY(1, 0) ; LCD_PUTS(CWD-&amp;gt;prev-&amp;gt;Text);
				 LCD_XY(0, 1) ; LCD_PUTS(&quot;&amp;gt;&quot;);
				 LCD_XY(1, 1) ; LCD_PUTS(CWD-&amp;gt;Text);

			 }
		  }
	  }
	  old_A = now_A;
	  HAL_Delay(1);
   /* USER CODE END WHILE */
   /* USER CODE BEGIN 3 */
 }&lt;/code&gt;&lt;/pre&gt;</description>
      <category>프로그래밍/STM32</category>
      <author>덕력킹</author>
      <guid isPermaLink="true">https://bota.tistory.com/2475</guid>
      <comments>https://bota.tistory.com/2475#entry2475comment</comments>
      <pubDate>Tue, 10 Feb 2026 00:07:53 +0900</pubDate>
    </item>
    <item>
      <title>[STM32#32] 블루필보드로 전자산업기사, 임베디드기능사 국가자격증 실기시험 공개문제에 있는 일부 문제를 해결해보기!(녹칸다 내맘대로 STM32)</title>
      <link>https://bota.tistory.com/2474</link>
      <description>&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;stm32.png&quot; data-origin-width=&quot;1920&quot; data-origin-height=&quot;1080&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/3MioV/dJMcahJ4VU7/IyrwYRdQwkxZcBYPrQeVuK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/3MioV/dJMcahJ4VU7/IyrwYRdQwkxZcBYPrQeVuK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/3MioV/dJMcahJ4VU7/IyrwYRdQwkxZcBYPrQeVuK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2F3MioV%2FdJMcahJ4VU7%2FIyrwYRdQwkxZcBYPrQeVuK%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;1920&quot; height=&quot;1080&quot; data-filename=&quot;stm32.png&quot; data-origin-width=&quot;1920&quot; data-origin-height=&quot;1080&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/live/Pl1SAaUqfII&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://youtube.com/live/Pl1SAaUqfII&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/watch?v=Pl1SAaUqfII&quot; data-video-thumbnail=&quot;https://scrap.kakaocdn.net/dn/zCtCl/dJMb9eTKYlh/oXJK4YHcuDo7rJAHMYwAE1/img.jpg?width=1280&amp;amp;height=720&amp;amp;face=0_0_1280_720,https://scrap.kakaocdn.net/dn/cYvrVc/dJMb9gxgHX4/bpP2SZ0GaVbKlge38mc9g1/img.jpg?width=1280&amp;amp;height=720&amp;amp;face=0_0_1280_720,https://scrap.kakaocdn.net/dn/gKloj/dJMb9cBDsCu/14yCZ28klIO11q9aMz8xu0/img.jpg?width=1280&amp;amp;height=720&amp;amp;face=0_0_1280_720&quot; data-video-width=&quot;860&quot; data-video-height=&quot;484&quot; data-video-origin-width=&quot;860&quot; data-video-origin-height=&quot;484&quot; data-ke-mobilestyle=&quot;widthContent&quot; data-video-title=&quot;[STM32#32] 블루필보드로 전자산업기사, 임베디드기능사 국가자격증 실기시험 공개문제에 있는 일&quot; data-original-url=&quot;&quot;&gt;&lt;iframe src=&quot;https://www.youtube.com/embed/Pl1SAaUqfII&quot; width=&quot;860&quot; height=&quot;484&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;[STM32#32]&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) &lt;br /&gt;&lt;br /&gt;심심한녹칸다의&amp;nbsp;내맘대로&amp;nbsp;STM32시리즈이다! &lt;br /&gt;&lt;br /&gt;STM32시리즈의&amp;nbsp;모든&amp;nbsp;자료는&amp;nbsp;구글&amp;nbsp;슬라이드에&amp;nbsp;작성하고&amp;nbsp;모두에게&amp;nbsp;공유되어있음! &lt;br /&gt;&lt;a href=&quot;https://docs.google.com/presentation/d/1myA5iYbjuKsLWLqtRLKAiRfwUwvqB1d1RGjiMIIgp3I/edit?slide=id.g3bcab2a4904_2_225#slide=id.g3bcab2a4904_2_225&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://docs.google.com/presentation/d/1myA5iYbjuKsLWLqtRLKAiRfwUwvqB1d1RGjiMIIgp3I/edit?slide=id.g3bcab2a4904_2_225#slide=id.g3bcab2a4904_2_225&lt;/a&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;STM32로&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;1.STM32의&amp;nbsp;PB9에&amp;nbsp;주파수발생기를&amp;nbsp;연결하고&amp;nbsp;PB8에&amp;nbsp;LED를&amp;nbsp;연결해서&amp;nbsp;주파수&amp;nbsp;발생기에서&amp;nbsp;엣지를&amp;nbsp;검출할때&amp;nbsp;마다&amp;nbsp;PB8의&amp;nbsp;LED가&amp;nbsp;토글되도록&amp;nbsp;하시오!&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;01.PNG&quot; data-origin-width=&quot;1267&quot; data-origin-height=&quot;575&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/crDKeI/dJMcachGt7W/xEuUzlo8NcObYwg0Dkx7f0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/crDKeI/dJMcachGt7W/xEuUzlo8NcObYwg0Dkx7f0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/crDKeI/dJMcachGt7W/xEuUzlo8NcObYwg0Dkx7f0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FcrDKeI%2FdJMcachGt7W%2FxEuUzlo8NcObYwg0Dkx7f0%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;1267&quot; height=&quot;575&quot; data-filename=&quot;01.PNG&quot; data-origin-width=&quot;1267&quot; data-origin-height=&quot;575&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;pre id=&quot;code_1770197758845&quot; class=&quot;cpp&quot; data-ke-language=&quot;cpp&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;/* USER CODE BEGIN 0 */
void HAL_GPIO_EXTI_Callback(uint16_t GPIO_Pin)
{
  if(GPIO_Pin == GPIO_PIN_9)
  {
      HAL_GPIO_TogglePin(GPIOB, GPIO_PIN_8);
  }
}
/* USER CODE END 0 */&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;br /&gt;2.주파수&amp;nbsp;발생기에서&amp;nbsp;나오는&amp;nbsp;신호를&amp;nbsp;검출해서&amp;nbsp;1씩&amp;nbsp;증가하는&amp;nbsp;카운터를&amp;nbsp;구성한다음&amp;nbsp;단위시간으로&amp;nbsp;나눠서&amp;nbsp;USB&amp;nbsp;CDC로&amp;nbsp;출력하시오!&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;02.PNG&quot; data-origin-width=&quot;1085&quot; data-origin-height=&quot;529&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cPiNFl/dJMcagRVxSR/Sa0xWlqk9MHcMrSZlywVek/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cPiNFl/dJMcagRVxSR/Sa0xWlqk9MHcMrSZlywVek/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cPiNFl/dJMcagRVxSR/Sa0xWlqk9MHcMrSZlywVek/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FcPiNFl%2FdJMcagRVxSR%2FSa0xWlqk9MHcMrSZlywVek%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;1085&quot; height=&quot;529&quot; data-filename=&quot;02.PNG&quot; data-origin-width=&quot;1085&quot; data-origin-height=&quot;529&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;pre id=&quot;code_1770197767650&quot; class=&quot;cpp&quot; data-ke-language=&quot;cpp&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;/* USER CODE BEGIN 0 */
volatile uint16_t cnt = 0;
void HAL_GPIO_EXTI_Callback(uint16_t GPIO_Pin)
{
  if(GPIO_Pin == GPIO_PIN_9)
  {
	   //10ms초마다 1씩 증가
	   cnt++;
  }
}
/* USER CODE END 0 */
/* USER CODE BEGIN 2 */
 uint8_t buff[100];
 /* USER CODE END 2 */
while (1)
 {
	  //1초 간격으로 cnt값을 USB CDC로 출력하고 cnt를 0으로 초기화한다!
	  sprintf(buff,&quot;now_cnt = %d\n&quot;,cnt);
	  CDC_Transmit_FS(buff, strlen(buff));
	  cnt = 0;
	  HAL_Delay(1000);
   /* USER CODE END WHILE */
   /* USER CODE BEGIN 3 */
 }&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;br /&gt;3.예제2에서&amp;nbsp;측정한&amp;nbsp;주파수값을&amp;nbsp;1602LCD(PB6,PB7)에&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-filename=&quot;03.PNG&quot; data-origin-width=&quot;832&quot; data-origin-height=&quot;649&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/Syolx/dJMcachGt8j/K9Xjakjwr9X0HnxAQQ1ixK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/Syolx/dJMcachGt8j/K9Xjakjwr9X0HnxAQQ1ixK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/Syolx/dJMcachGt8j/K9Xjakjwr9X0HnxAQQ1ixK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FSyolx%2FdJMcachGt8j%2FK9Xjakjwr9X0HnxAQQ1ixK%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;832&quot; height=&quot;649&quot; data-filename=&quot;03.PNG&quot; data-origin-width=&quot;832&quot; data-origin-height=&quot;649&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;pre id=&quot;code_1770197790248&quot; class=&quot;cpp&quot; data-ke-language=&quot;cpp&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;#define delay_ms HAL_Delay
#define SYS_CLOCK    72
#define SYSTICK_LOAD 72000-1
uint32_t millis_cnt = 0;
uint32_t millis() {
 return millis_cnt;
}
uint32_t micros() {
 return (millis_cnt &amp;amp; 0x3FFFFF) * 1000 + (SYSTICK_LOAD - SysTick-&amp;gt;VAL) / SYS_CLOCK;
}
void delay_us(uint32_t us) {  // 64MHz 보정
 if (us &amp;gt; 1) {
   uint32_t count = us * 7 - 6;
   while (count--);
 } else {
   uint32_t count = 2;
   while (count--);
 }
}
#define ADDRESS   0x27&amp;lt;&amp;lt;1
#define RS1_EN1   0x05
#define RS1_EN0   0x01
#define RS0_EN1   0x04
#define RS0_EN0   0x00
#define BackLight 0x08
// RS-Q0 / RW-Q1 / EN-Q2 / BackLight-Q3 / D4-Q4 / D5-Q5 / D6-Q6 / D7-Q7
void LCD_DATA(uint8_t data) {
 uint8_t temp=(data &amp;amp; 0xF0)|RS1_EN1|BackLight;
 while(HAL_I2C_Master_Transmit(&amp;amp;hi2c1, ADDRESS, &amp;amp;temp, 1, 1000)!=HAL_OK);
 temp=(data &amp;amp; 0xF0)|RS1_EN0|BackLight;
 while(HAL_I2C_Master_Transmit(&amp;amp;hi2c1, ADDRESS, &amp;amp;temp, 1, 1000)!=HAL_OK);
 delay_us(4);
 temp=((data &amp;lt;&amp;lt; 4) &amp;amp; 0xF0)|RS1_EN1|BackLight;
 while(HAL_I2C_Master_Transmit(&amp;amp;hi2c1, ADDRESS, &amp;amp;temp, 1, 1000)!=HAL_OK);
 temp = ((data &amp;lt;&amp;lt; 4) &amp;amp; 0xF0)|RS1_EN0|BackLight;
 while(HAL_I2C_Master_Transmit(&amp;amp;hi2c1, ADDRESS, &amp;amp;temp, 1, 1000)!=HAL_OK);
 delay_us(50);
}
void LCD_CMD(uint8_t cmd) {
 uint8_t temp=(cmd &amp;amp; 0xF0)|RS0_EN1|BackLight;
 while(HAL_I2C_Master_Transmit(&amp;amp;hi2c1, ADDRESS, &amp;amp;temp, 1, 1000)!=HAL_OK);
 temp=(cmd &amp;amp; 0xF0)|RS0_EN0|BackLight;
 while(HAL_I2C_Master_Transmit(&amp;amp;hi2c1, ADDRESS, &amp;amp;temp, 1, 1000)!=HAL_OK);
 delay_us(4);
 temp=((cmd &amp;lt;&amp;lt; 4) &amp;amp; 0xF0)|RS0_EN1|BackLight;
 while(HAL_I2C_Master_Transmit(&amp;amp;hi2c1, ADDRESS, &amp;amp;temp, 1, 1000)!=HAL_OK);
 temp=((cmd &amp;lt;&amp;lt; 4) &amp;amp; 0xF0)|RS0_EN0|BackLight;
 while(HAL_I2C_Master_Transmit(&amp;amp;hi2c1, ADDRESS, &amp;amp;temp, 1, 1000)!=HAL_OK);
 delay_us(50);
}
void LCD_CMD_4bit(uint8_t cmd) {
 uint8_t temp=((cmd &amp;lt;&amp;lt; 4) &amp;amp; 0xF0)|RS0_EN1|BackLight;
 while(HAL_I2C_Master_Transmit(&amp;amp;hi2c1, ADDRESS, &amp;amp;temp, 1, 1000)!=HAL_OK);
 temp=((cmd &amp;lt;&amp;lt; 4) &amp;amp; 0xF0)|RS0_EN0|BackLight;
 while(HAL_I2C_Master_Transmit(&amp;amp;hi2c1, ADDRESS, &amp;amp;temp, 1, 1000)!=HAL_OK);
 delay_us(50);
}
void LCD_INIT(void) {
 delay_ms(100);
 LCD_CMD_4bit(0x03); delay_ms(5);
 LCD_CMD_4bit(0x03); delay_us(100);
 LCD_CMD_4bit(0x03); delay_us(100);
 LCD_CMD_4bit(0x02); delay_us(100);
 LCD_CMD(0x28);  // 4 bits, 2 line, 5x8 font
 LCD_CMD(0x08);  // display off, cursor off, blink off
 LCD_CMD(0x01);  // clear display
 delay_ms(3);
 LCD_CMD(0x06);  // cursor movint direction
 LCD_CMD(0x0C);  // display on, cursor off, blink off
}
void LCD_XY(char x, char y) {
 if      (y == 0) LCD_CMD(0x80 + x);
 else if (y == 1) LCD_CMD(0xC0 + x);
 else if (y == 2) LCD_CMD(0x94 + x);
 else if (y == 3) LCD_CMD(0xD4 + x);
}
void LCD_CLEAR(void) {
 LCD_CMD(0x01);
 delay_ms(2);
}
void LCD_PUTS(char *str) {
 while (*str) LCD_DATA(*str++);
}
/* USER CODE BEGIN 0 */
volatile uint16_t cnt = 0;
void HAL_GPIO_EXTI_Callback(uint16_t GPIO_Pin)
{
  if(GPIO_Pin == GPIO_PIN_9)
  {
	   //10ms초마다 1씩 증가
	   cnt++;
  }
}
/* USER CODE END 0 */
/* USER CODE BEGIN 2 */
 uint8_t line1[20];
 uint8_t line2[20];
 LCD_INIT(); //1회호출(메인루프 시작전)
 LCD_XY(0, 0) ; LCD_PUTS(&quot;[Pulse Mode]    &quot;); //첫번째줄
 /* USER CODE END 2 */
while (1)
 {
	  //1초간격으로 1602LCD에 출력한다!
	  sprintf(line2,&quot;Freq: %3dHz     &quot;,cnt);
	  LCD_XY(0, 1) ; LCD_PUTS(line2); //두번째줄
	  cnt = 0;
	  HAL_Delay(1000);
   /* USER CODE END WHILE */
   /* USER CODE BEGIN 3 */
 }&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;br /&gt;4.전자산업기사&amp;nbsp;공개문제&amp;nbsp;2번에서&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-filename=&quot;04.PNG&quot; data-origin-width=&quot;831&quot; data-origin-height=&quot;642&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/baWB2B/dJMcachGt8o/8PC85cMxaSPukEz6BZFKh1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/baWB2B/dJMcachGt8o/8PC85cMxaSPukEz6BZFKh1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/baWB2B/dJMcachGt8o/8PC85cMxaSPukEz6BZFKh1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbaWB2B%2FdJMcachGt8o%2F8PC85cMxaSPukEz6BZFKh1%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;831&quot; height=&quot;642&quot; data-filename=&quot;04.PNG&quot; data-origin-width=&quot;831&quot; data-origin-height=&quot;642&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;pre id=&quot;code_1770197825227&quot; class=&quot;cpp&quot; data-ke-language=&quot;cpp&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;//(LCD코드는 생략)
/* USER CODE BEGIN 0 */
volatile uint16_t h = 11; //시
volatile uint16_t m = 59; //분
volatile uint16_t s = 50; //초
volatile uint16_t ms = 0; //밀리초
void HAL_GPIO_EXTI_Callback(uint16_t GPIO_Pin)
{
  if(GPIO_Pin == GPIO_PIN_9)
  {
	   //10ms초마다 1씩 증가
	   ms++;
	   if(ms &amp;gt;= 100){
		   ms = 0;
		   s++;
	   }
	   if(s &amp;gt;= 60){
		   s = 0;
		   m++;
	   }
	   if(m &amp;gt;= 60){
		   m = 0;
		   h++;
	   }
	   if(h &amp;gt;= 24){
		   h = 0;
	   }
  }
}

/* USER CODE END 0 */

/* USER CODE BEGIN 2 */
 uint8_t line1[20];
 uint8_t line2[20];
 LCD_INIT(); //1회호출(메인루프 시작전)
 LCD_XY(0, 0) ; LCD_PUTS(&quot;[ DigitalClock ]&quot;); //첫번째줄
 /* USER CODE END 2 */

while (1)
 {
	  //1초간격으로 1602LCD에 출력한다!
	  sprintf(line2,&quot;Freq: %3dHz     &quot;,cnt);
	  LCD_XY(0, 1) ; LCD_PUTS(line2); //두번째줄
	  cnt = 0;
	  HAL_Delay(1000);
   /* USER CODE END WHILE */
   /* USER CODE BEGIN 3 */
 }
while (1)
 {
	  //1초간격으로 1602LCD에 출력한다!
	  sprintf(line2,&quot;[%s]%02d:%02d:%02d:%02d &quot;,(h&amp;gt;=12)?&quot;PM&quot;:&quot;AM&quot;,h,m,s,ms);
	  LCD_XY(0, 1) ; LCD_PUTS(line2); //두번째줄
	  HAL_Delay(10);
   /* USER CODE END WHILE */
   /* USER CODE BEGIN 3 */
 }&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;br /&gt;5.임베디드기능사에서&amp;nbsp;나오는&amp;nbsp;문제를&amp;nbsp;P6~P9까지를&amp;nbsp;PB6~PB9까지&amp;nbsp;연결&amp;nbsp;P10을&amp;nbsp;PB4,&amp;nbsp;P11을&amp;nbsp;PB5에&amp;nbsp;연결해서&amp;nbsp;FND에&amp;nbsp;숫자&amp;nbsp;두자리(15)를&amp;nbsp;출력하시오!&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;05.PNG&quot; data-origin-width=&quot;1206&quot; data-origin-height=&quot;632&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bBBCkk/dJMcachGt8s/anAzaHUikLzr3QTGkBQ9Bk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bBBCkk/dJMcachGt8s/anAzaHUikLzr3QTGkBQ9Bk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bBBCkk/dJMcachGt8s/anAzaHUikLzr3QTGkBQ9Bk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbBBCkk%2FdJMcachGt8s%2FanAzaHUikLzr3QTGkBQ9Bk%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;1206&quot; height=&quot;632&quot; data-filename=&quot;05.PNG&quot; data-origin-width=&quot;1206&quot; data-origin-height=&quot;632&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;pre id=&quot;code_1770197835674&quot; class=&quot;cpp&quot; data-ke-language=&quot;cpp&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;/* USER CODE BEGIN 0 */
void set_fnd(uint8_t num){
	HAL_GPIO_WritePin(GPIOB, GPIO_PIN_6, num&amp;amp;0b0001); //하위
	HAL_GPIO_WritePin(GPIOB, GPIO_PIN_7, (num&amp;gt;&amp;gt;1)&amp;amp;0b0001);
	HAL_GPIO_WritePin(GPIOB, GPIO_PIN_8, (num&amp;gt;&amp;gt;2)&amp;amp;0b0001);
	HAL_GPIO_WritePin(GPIOB, GPIO_PIN_9, (num&amp;gt;&amp;gt;3)&amp;amp;0b0001); //상위
}
uint8_t fnd_num = 15;
uint8_t fnd_sw = 0;
void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim)
{
	if(fnd_sw == 0){
		//십의자리
		set_fnd(fnd_num/10);
		HAL_GPIO_WritePin(GPIOB, GPIO_PIN_4, 1);
		HAL_GPIO_WritePin(GPIOB, GPIO_PIN_5, 0);
		fnd_sw = 1;
	}else if(fnd_sw == 1){
		//일의자리
		set_fnd(fnd_num%10);
		HAL_GPIO_WritePin(GPIOB, GPIO_PIN_4, 0);
		HAL_GPIO_WritePin(GPIOB, GPIO_PIN_5, 1);
		fnd_sw = 0;
	}
}
/* USER CODE END 0 */
/* USER CODE BEGIN 2 */
 HAL_TIM_Base_Start_IT(&amp;amp;htim3);
/* USER CODE END 2 */&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;br /&gt;6.예제5에서&amp;nbsp;PB12,PB13에&amp;nbsp;버튼을&amp;nbsp;1개씩&amp;nbsp;추가하고&amp;nbsp;PB12버튼을&amp;nbsp;누르면&amp;nbsp;FND에&amp;nbsp;1씩&amp;nbsp;업카운트되고&amp;nbsp;PB13을&amp;nbsp;누르면&amp;nbsp;다운카운트되는데&amp;nbsp;표시되는&amp;nbsp;숫자의&amp;nbsp;범위가&amp;nbsp;00~99까지&amp;nbsp;되도록&amp;nbsp;하시오!&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;06.PNG&quot; data-origin-width=&quot;1321&quot; data-origin-height=&quot;589&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bPKa4O/dJMcahXBdPU/Jmoo3eeikm6t0yv93MarLK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bPKa4O/dJMcahXBdPU/Jmoo3eeikm6t0yv93MarLK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bPKa4O/dJMcahXBdPU/Jmoo3eeikm6t0yv93MarLK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbPKa4O%2FdJMcahXBdPU%2FJmoo3eeikm6t0yv93MarLK%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;1321&quot; height=&quot;589&quot; data-filename=&quot;06.PNG&quot; data-origin-width=&quot;1321&quot; data-origin-height=&quot;589&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;pre id=&quot;code_1770197845202&quot; class=&quot;cpp&quot; data-ke-language=&quot;cpp&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;/* USER CODE BEGIN 0 */
void set_fnd(uint8_t num){
	HAL_GPIO_WritePin(GPIOB, GPIO_PIN_6, num&amp;amp;0b0001); //하위
	HAL_GPIO_WritePin(GPIOB, GPIO_PIN_7, (num&amp;gt;&amp;gt;1)&amp;amp;0b0001);
	HAL_GPIO_WritePin(GPIOB, GPIO_PIN_8, (num&amp;gt;&amp;gt;2)&amp;amp;0b0001);
	HAL_GPIO_WritePin(GPIOB, GPIO_PIN_9, (num&amp;gt;&amp;gt;3)&amp;amp;0b0001); //상위
}
uint8_t fnd_num = 15;
uint8_t fnd_sw = 0;
void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim)
{
	if(fnd_sw == 0){
		//십의자리
		set_fnd(fnd_num/10);
		HAL_GPIO_WritePin(GPIOB, GPIO_PIN_4, 1);
		HAL_GPIO_WritePin(GPIOB, GPIO_PIN_5, 0);
		fnd_sw = 1;
	}else if(fnd_sw == 1){
		//일의자리
		set_fnd(fnd_num%10);
		HAL_GPIO_WritePin(GPIOB, GPIO_PIN_4, 0);
		HAL_GPIO_WritePin(GPIOB, GPIO_PIN_5, 1);
		fnd_sw = 0;
	}
}
/* USER CODE END 0 */



/* USER CODE BEGIN 2 */
 HAL_TIM_Base_Start_IT(&amp;amp;htim3);
 for(int i = 0;i&amp;lt;2;i++){
	  fnd_control = 1;
	  fnd_num = 88;
	  HAL_Delay(1000);
	  fnd_control = 0;
	  HAL_Delay(1000);
 }
 fnd_control = 1;
 fnd_num = 0;
 /* USER CODE END 2 */

while (1)
 {
	  if(HAL_GPIO_ReadPin(GPIOB, GPIO_PIN_12) == 0){
		  if(fnd_num != 99){
			  fnd_num++;
		  }
		  HAL_Delay(200);
	  }
	  if(HAL_GPIO_ReadPin(GPIOB, GPIO_PIN_13) == 0){
		  if(fnd_num != 0){
			  fnd_num--;
		  }
		  HAL_Delay(200);
	  }
   /* USER CODE END WHILE */
   /* USER CODE BEGIN 3 */
 }&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;br /&gt;7.예제6에서&amp;nbsp;PB12를&amp;nbsp;누르면&amp;nbsp;0에서&amp;nbsp;99까지&amp;nbsp;0.5초간격으로&amp;nbsp;업카운트되고&amp;nbsp;PB13을&amp;nbsp;누르면&amp;nbsp;99에서&amp;nbsp;0까지&amp;nbsp;1씩&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-filename=&quot;07.PNG&quot; data-origin-width=&quot;1327&quot; data-origin-height=&quot;578&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bozZ2W/dJMcajnv6n7/W6WbzeEjPuxYR64deKkaf1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bozZ2W/dJMcajnv6n7/W6WbzeEjPuxYR64deKkaf1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bozZ2W/dJMcajnv6n7/W6WbzeEjPuxYR64deKkaf1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbozZ2W%2FdJMcajnv6n7%2FW6WbzeEjPuxYR64deKkaf1%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;1327&quot; height=&quot;578&quot; data-filename=&quot;07.PNG&quot; data-origin-width=&quot;1327&quot; data-origin-height=&quot;578&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;pre id=&quot;code_1770197858454&quot; class=&quot;cpp&quot; data-ke-language=&quot;cpp&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;/* USER CODE BEGIN 0 */
void set_fnd(uint8_t num){
	HAL_GPIO_WritePin(GPIOB, GPIO_PIN_6, num&amp;amp;0b0001); //하위
	HAL_GPIO_WritePin(GPIOB, GPIO_PIN_7, (num&amp;gt;&amp;gt;1)&amp;amp;0b0001);
	HAL_GPIO_WritePin(GPIOB, GPIO_PIN_8, (num&amp;gt;&amp;gt;2)&amp;amp;0b0001);
	HAL_GPIO_WritePin(GPIOB, GPIO_PIN_9, (num&amp;gt;&amp;gt;3)&amp;amp;0b0001); //상위
}
uint8_t fnd_num = 15;
uint8_t fnd_sw = 0;
void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim)
{
	if(fnd_sw == 0){
		//십의자리
		set_fnd(fnd_num/10);
		HAL_GPIO_WritePin(GPIOB, GPIO_PIN_4, 1);
		HAL_GPIO_WritePin(GPIOB, GPIO_PIN_5, 0);
		fnd_sw = 1;
	}else if(fnd_sw == 1){
		//일의자리
		set_fnd(fnd_num%10);
		HAL_GPIO_WritePin(GPIOB, GPIO_PIN_4, 0);
		HAL_GPIO_WritePin(GPIOB, GPIO_PIN_5, 1);
		fnd_sw = 0;
	}
}
/* USER CODE END 0 */



/* USER CODE BEGIN 2 */
 HAL_TIM_Base_Start_IT(&amp;amp;htim3);
 for(int i = 0;i&amp;lt;2;i++){
	  fnd_control = 1;
	  fnd_num = 88;
	  HAL_Delay(1000);
	  fnd_control = 0;
	  HAL_Delay(1000);
 }
 fnd_control = 1;
 fnd_num = 0;
 uint32_t t = 0;
 //task_num이 0이면 아무것도 안함, 1이면 task1, 2면 task2
 uint8_t task_num = 0;
 /* USER CODE END 2 */
while (1)
 {
	  if(task_num == 1){
		  if(HAL_GetTick() - t &amp;gt;= 500){
			  t = HAL_GetTick();
			  //0부터 상승
			  if(fnd_num == 99){
				  fnd_num = 0;
			  }else{
				  fnd_num++;
			  }
		  }

	  }else if(task_num == 2){
		  if(HAL_GetTick() - t &amp;gt;= 500){
			  t = HAL_GetTick();
			  //99부터 하강
			  if(fnd_num == 0){
				  fnd_num = 99;
			  }else{
				  fnd_num--;
			  }
		  }
	  }
	  if(HAL_GPIO_ReadPin(GPIOB, GPIO_PIN_12) == 0){
		  //task1 작동
		  task_num = 1;
		  fnd_num = 0;
		  HAL_Delay(200);
	  }
	  if(HAL_GPIO_ReadPin(GPIOB, GPIO_PIN_13) == 0){
		  //task2 작동
		  task_num = 2;
		  fnd_num = 99;
		  HAL_Delay(200);
	  }
   /* USER CODE END WHILE */
   /* USER CODE BEGIN 3 */
 }&lt;/code&gt;&lt;/pre&gt;</description>
      <category>프로그래밍/STM32</category>
      <author>덕력킹</author>
      <guid isPermaLink="true">https://bota.tistory.com/2474</guid>
      <comments>https://bota.tistory.com/2474#entry2474comment</comments>
      <pubDate>Wed, 4 Feb 2026 18:40:00 +0900</pubDate>
    </item>
    <item>
      <title>[STM32#31] F103C8T6 blue pill board(블루필보드)를 cubeIDE와 ST-LINK를 이용해서 업로드하는 방법 알아보기!(녹칸다 내맘대로 STM32)</title>
      <link>https://bota.tistory.com/2473</link>
      <description>&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;stm32.png&quot; data-origin-width=&quot;1920&quot; data-origin-height=&quot;1080&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/ck2sgh/dJMcadU8jsr/WWlmzKKMhEtdYgGRIGxEu1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/ck2sgh/dJMcadU8jsr/WWlmzKKMhEtdYgGRIGxEu1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/ck2sgh/dJMcadU8jsr/WWlmzKKMhEtdYgGRIGxEu1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fck2sgh%2FdJMcadU8jsr%2FWWlmzKKMhEtdYgGRIGxEu1%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;1920&quot; height=&quot;1080&quot; data-filename=&quot;stm32.png&quot; data-origin-width=&quot;1920&quot; data-origin-height=&quot;1080&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/live/SpbPhleFvAc&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://youtube.com/live/SpbPhleFvAc&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/watch?v=SpbPhleFvAc&quot; data-video-thumbnail=&quot;https://scrap.kakaocdn.net/dn/pSlYO/dJMb9kl7YEk/KeE9M05zsfpu3eIrpz9XVk/img.jpg?width=1280&amp;amp;height=720&amp;amp;face=0_0_1280_720,https://scrap.kakaocdn.net/dn/cU0eGx/dJMb9gxgvYa/kRZBa4OwHIEikrhFT8y1d1/img.jpg?width=1280&amp;amp;height=720&amp;amp;face=0_0_1280_720,https://scrap.kakaocdn.net/dn/cs1CM4/dJMb9bvXslh/lj6fWSsKveQwiPpRMBSfa0/img.jpg?width=1280&amp;amp;height=720&amp;amp;face=0_0_1280_720&quot; data-video-width=&quot;860&quot; data-video-height=&quot;484&quot; data-video-origin-width=&quot;860&quot; data-video-origin-height=&quot;484&quot; data-ke-mobilestyle=&quot;widthContent&quot; data-video-title=&quot;[STM32#31] F103C8T6 blue pill board(블루필보드)를 cubeIDE와 ST-LINK를 이용해서 업로드하는 방법 알아보기!(&quot; data-original-url=&quot;&quot;&gt;&lt;iframe src=&quot;https://www.youtube.com/embed/SpbPhleFvAc&quot; width=&quot;860&quot; height=&quot;484&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;[STM32#31]&amp;nbsp;F103C8T6&amp;nbsp;blue&amp;nbsp;pill&amp;nbsp;board(블루필보드)를&amp;nbsp;cubeIDE와&amp;nbsp;ST-LINK를&amp;nbsp;이용해서&amp;nbsp;업로드하는&amp;nbsp;방법&amp;nbsp;알아보기!(녹칸다&amp;nbsp;내맘대로&amp;nbsp;STM32) &lt;br /&gt;&lt;br /&gt;심심한녹칸다의&amp;nbsp;내맘대로&amp;nbsp;STM32시리즈이다! &lt;br /&gt;&lt;br /&gt;STM32시리즈의&amp;nbsp;모든&amp;nbsp;자료는&amp;nbsp;구글&amp;nbsp;슬라이드에&amp;nbsp;작성하고&amp;nbsp;모두에게&amp;nbsp;공유되어있음! &lt;br /&gt;&lt;a href=&quot;https://docs.google.com/presentation/d/1myA5iYbjuKsLWLqtRLKAiRfwUwvqB1d1RGjiMIIgp3I/edit?slide=id.g3bc8a5e1652_2_99#slide=id.g3bc8a5e1652_2_99&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://docs.google.com/presentation/d/1myA5iYbjuKsLWLqtRLKAiRfwUwvqB1d1RGjiMIIgp3I/edit?slide=id.g3bc8a5e1652_2_99#slide=id.g3bc8a5e1652_2_99&lt;/a&gt;&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;1.블루필보드에&amp;nbsp;내장되어있는&amp;nbsp;PC13번핀을&amp;nbsp;1초&amp;nbsp;간격으로&amp;nbsp;토글하시오!&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;01.PNG&quot; data-origin-width=&quot;514&quot; data-origin-height=&quot;346&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/b9QwID/dJMcagxAg0m/3jBeCUv71o7CgKqXBEfJIK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/b9QwID/dJMcagxAg0m/3jBeCUv71o7CgKqXBEfJIK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/b9QwID/dJMcagxAg0m/3jBeCUv71o7CgKqXBEfJIK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fb9QwID%2FdJMcagxAg0m%2F3jBeCUv71o7CgKqXBEfJIK%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;514&quot; height=&quot;346&quot; data-filename=&quot;01.PNG&quot; data-origin-width=&quot;514&quot; data-origin-height=&quot;346&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;pre id=&quot;code_1770040614142&quot; class=&quot;cpp&quot; data-ke-language=&quot;cpp&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;while (1)
 {
	  HAL_GPIO_TogglePin(GPIOC, GPIO_PIN_13);
	  HAL_Delay(1000);
   /* USER CODE END WHILE */
   /* USER CODE BEGIN 3 */
 }&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;br /&gt;2.블루필보드가&amp;nbsp;1초간격으로&amp;nbsp;&amp;ldquo;NOCKANDA!!\n&amp;rdquo;라는&amp;nbsp;문자열을&amp;nbsp;USB&amp;nbsp;CDC를&amp;nbsp;이용해서&amp;nbsp;시리얼&amp;nbsp;출력한뒤&amp;nbsp;PC에서&amp;nbsp;putty로&amp;nbsp;확인하시오!&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;02.PNG&quot; data-origin-width=&quot;351&quot; data-origin-height=&quot;246&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/Q8E7x/dJMcagxAg1d/WnimeNtIFSx4fpbfIjwww0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/Q8E7x/dJMcagxAg1d/WnimeNtIFSx4fpbfIjwww0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/Q8E7x/dJMcagxAg1d/WnimeNtIFSx4fpbfIjwww0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FQ8E7x%2FdJMcagxAg1d%2FWnimeNtIFSx4fpbfIjwww0%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;351&quot; height=&quot;246&quot; data-filename=&quot;02.PNG&quot; data-origin-width=&quot;351&quot; data-origin-height=&quot;246&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;pre id=&quot;code_1770040621866&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 */
 char msg[] = &quot;NOCKANDA!!\n&quot;;
 /* USER CODE END 2 */
 /* Infinite loop */
 /* USER CODE BEGIN WHILE */
 while (1)
 {
	  CDC_Transmit_FS(msg, strlen(msg));
	  HAL_Delay(1000);
   /* USER CODE END WHILE */
   /* USER CODE BEGIN 3 */
 }&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;br /&gt;3.PB8,&amp;nbsp;PB9핀에&amp;nbsp;LED를&amp;nbsp;1개씩&amp;nbsp;연결하고&amp;nbsp;1초&amp;nbsp;간격으로&amp;nbsp;서로&amp;nbsp;번갈아가면서&amp;nbsp;LED가&amp;nbsp;점멸되도록&amp;nbsp;하시오!&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;03.PNG&quot; data-origin-width=&quot;503&quot; data-origin-height=&quot;397&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/EMC0H/dJMcagRUJJD/oSBGFhkkTzvBU0oooKv2M1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/EMC0H/dJMcagRUJJD/oSBGFhkkTzvBU0oooKv2M1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/EMC0H/dJMcagRUJJD/oSBGFhkkTzvBU0oooKv2M1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FEMC0H%2FdJMcagRUJJD%2FoSBGFhkkTzvBU0oooKv2M1%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;503&quot; height=&quot;397&quot; data-filename=&quot;03.PNG&quot; data-origin-width=&quot;503&quot; data-origin-height=&quot;397&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;pre id=&quot;code_1770040630092&quot; class=&quot;cpp&quot; data-ke-language=&quot;cpp&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;while (1)
 {
	  //PB8 ON PB9 OFF
	  HAL_GPIO_WritePin(GPIOB, GPIO_PIN_8, 1);
	  HAL_GPIO_WritePin(GPIOB, GPIO_PIN_9, 0);
	  HAL_Delay(1000);
	  //PB8 OFF PB9 ON
	  HAL_GPIO_WritePin(GPIOB, GPIO_PIN_8, 0);
	  HAL_GPIO_WritePin(GPIOB, GPIO_PIN_9, 1);
	  HAL_Delay(1000);
   /* USER CODE END WHILE */
   /* USER CODE BEGIN 3 */
 }&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;br /&gt;4.PB6,PB7에&amp;nbsp;버튼(택트스위치)을&amp;nbsp;1개씩&amp;nbsp;연결하고&amp;nbsp;버튼을&amp;nbsp;누르면&amp;nbsp;PB6은&amp;nbsp;PB8&amp;nbsp;LED가&amp;nbsp;토글되고,&amp;nbsp;PB7은&amp;nbsp;PB9&amp;nbsp;LED가&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-filename=&quot;04.PNG&quot; data-origin-width=&quot;478&quot; data-origin-height=&quot;380&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/taCdq/dJMcabQAtTy/xvMdKiiZkk1v9WX31RUry0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/taCdq/dJMcabQAtTy/xvMdKiiZkk1v9WX31RUry0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/taCdq/dJMcabQAtTy/xvMdKiiZkk1v9WX31RUry0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FtaCdq%2FdJMcabQAtTy%2FxvMdKiiZkk1v9WX31RUry0%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;478&quot; height=&quot;380&quot; data-filename=&quot;04.PNG&quot; data-origin-width=&quot;478&quot; data-origin-height=&quot;380&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;pre id=&quot;code_1770040639393&quot; class=&quot;cpp&quot; data-ke-language=&quot;cpp&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;while (1)
 {
	  //PB6을 누르면 PB8이 토글된다
	  if(HAL_GPIO_ReadPin(GPIOB, GPIO_PIN_6) == 0){
		  HAL_GPIO_TogglePin(GPIOB, GPIO_PIN_8);
		  HAL_Delay(200); //너무 빠르게 눌려지는 것 방지!
	  }
	  //PB7을 누르면 PB9가 토글된다
	  if(HAL_GPIO_ReadPin(GPIOB, GPIO_PIN_7) == 0){
		  HAL_GPIO_TogglePin(GPIOB, GPIO_PIN_9);
		  HAL_Delay(200); //너무 빠르게 눌려지는 것 방지!
	  }
   /* USER CODE END WHILE */
   /* USER CODE BEGIN 3 */
 }&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;br /&gt;5.PB6&amp;nbsp;버튼을&amp;nbsp;누르면&amp;nbsp;PC시리얼화면에&amp;nbsp;&amp;ldquo;NOCKANDA!!\n&amp;rdquo;라고&amp;nbsp;출력되고&amp;nbsp;PB7을&amp;nbsp;누르면&amp;nbsp;&amp;ldquo;SUBSCRIBE!!\n&amp;rdquo;라고&amp;nbsp;출력되도록&amp;nbsp;하시오!&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;05.PNG&quot; data-origin-width=&quot;548&quot; data-origin-height=&quot;396&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cdLSGf/dJMcagEov7t/qZtRb8nv8EXBKijOq0KKjk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cdLSGf/dJMcagEov7t/qZtRb8nv8EXBKijOq0KKjk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cdLSGf/dJMcagEov7t/qZtRb8nv8EXBKijOq0KKjk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FcdLSGf%2FdJMcagEov7t%2FqZtRb8nv8EXBKijOq0KKjk%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;548&quot; height=&quot;396&quot; data-filename=&quot;05.PNG&quot; data-origin-width=&quot;548&quot; data-origin-height=&quot;396&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;pre id=&quot;code_1770040647666&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 */
 uint8_t msg1[] = &quot;NOCKANDA!!\n&quot;;
 uint8_t msg2[] = &quot;SUBSCRIBE!!\n&quot;;
 /* USER CODE END 2 */
 /* Infinite loop */
 /* USER CODE BEGIN WHILE */
 while (1)
 {
	  //PB6을 누르면 PB8이 토글된다
	  if(HAL_GPIO_ReadPin(GPIOB, GPIO_PIN_6) == 0){
		  CDC_Transmit_FS(msg1, strlen(msg1));
		  HAL_Delay(200); //너무 빠르게 눌려지는 것 방지!
	  }
	  //PB7을 누르면 PB9가 토글된다
	  if(HAL_GPIO_ReadPin(GPIOB, GPIO_PIN_7) == 0){
		  CDC_Transmit_FS(msg2, strlen(msg2));
		  HAL_Delay(200); //너무 빠르게 눌려지는 것 방지!
	  }
   /* USER CODE END WHILE */
   /* USER CODE BEGIN 3 */
 }&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;br /&gt;6.PA0에 가변저항을 연결해서 가변저항값을 PC의 시리얼 화면에 100밀리초 간격으로 출력하시오!&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;06.PNG&quot; data-origin-width=&quot;480&quot; data-origin-height=&quot;434&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/H59EZ/dJMcabC4xzw/JjBopyBOnXImILUHHusoqK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/H59EZ/dJMcabC4xzw/JjBopyBOnXImILUHHusoqK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/H59EZ/dJMcabC4xzw/JjBopyBOnXImILUHHusoqK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FH59EZ%2FdJMcabC4xzw%2FJjBopyBOnXImILUHHusoqK%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;480&quot; height=&quot;434&quot; data-filename=&quot;06.PNG&quot; data-origin-width=&quot;480&quot; data-origin-height=&quot;434&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;pre id=&quot;code_1770040655698&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 */
 HAL_ADC_Start(&amp;amp;hadc1); //딱 한번만 호출
 uint16_t adc_value0 = 0;
 char buff[50];
 /* USER CODE END 2 */
 /* Infinite loop */
 /* USER CODE BEGIN WHILE */
 while (1)
 {
	  //측정할때마다 호출
	  if(HAL_ADC_PollForConversion(&amp;amp;hadc1, 10) == HAL_OK)
	  {
		  // 값 처리
		  adc_value0 = HAL_ADC_GetValue(&amp;amp;hadc1); //0~4095
		  sprintf(buff,&quot;A0 = %d\n&quot;,adc_value0);
		  CDC_Transmit_FS(buff, strlen(buff));
	  }
	  HAL_Delay(100);
   /* USER CODE END WHILE */
   /* USER CODE BEGIN 3 */
 }&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;br /&gt;7.PA0에 연결된 가변저항을 돌리면 서보모터(PB5)의 각도가 0~180도 사이로 바뀌도록 하시오!&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;07.PNG&quot; data-origin-width=&quot;546&quot; data-origin-height=&quot;387&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/clkGyJ/dJMcabXmh03/S5SsQ8fULzaNvWRLvhTT7k/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/clkGyJ/dJMcabXmh03/S5SsQ8fULzaNvWRLvhTT7k/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/clkGyJ/dJMcabXmh03/S5SsQ8fULzaNvWRLvhTT7k/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FclkGyJ%2FdJMcabXmh03%2FS5SsQ8fULzaNvWRLvhTT7k%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;546&quot; height=&quot;387&quot; data-filename=&quot;07.PNG&quot; data-origin-width=&quot;546&quot; data-origin-height=&quot;387&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;pre id=&quot;code_1770040669430&quot; class=&quot;cpp&quot; data-ke-language=&quot;cpp&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;/* USER CODE BEGIN 0 */
void set_servo(uint8_t degree){
	//degree는 0~180도 범위이고 CCR4는 600부터 2400의 범위이다!
	TIM3-&amp;gt;CCR2 = (uint32_t)(600+(2400-600)*degree/180.0);
}
//0~4095범위의 값을 0~180사이로 변환!
uint16_t map(uint16_t analog){
	return 180*analog/4095.0;
}
/* USER CODE END 0 */
/* USER CODE BEGIN 2 */
 HAL_TIM_PWM_Start(&amp;amp;htim3,TIM_CHANNEL_2); //PB5
 HAL_ADC_Start(&amp;amp;hadc1); //딱 한번만 호출
 uint16_t adc_value0 = 0;
 /* USER CODE END 2 */
 /* Infinite loop */
 /* USER CODE BEGIN WHILE */
 while (1)
 {
	  if(HAL_ADC_PollForConversion(&amp;amp;hadc1, 10) == HAL_OK)
	  {
		  // 값 처리
		  adc_value0 = HAL_ADC_GetValue(&amp;amp;hadc1); //0~4095
		  //0~4095를 0~180도 범위로 조정해야한다!
		  set_servo(map(adc_value0));
	  }
	  HAL_Delay(10);
   /* USER CODE END WHILE */
   /* USER CODE BEGIN 3 */
 }&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;br /&gt;8.I2C통신으로 작동되는 1602LCD를 블루필보드에 연결해서 첫번째 줄에는 타이머카운터값을 출력하고 두번째 줄에는 PA0에 연결된 가변저항값을 출력하시오!&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;08.PNG&quot; data-origin-width=&quot;618&quot; data-origin-height=&quot;338&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bRWdOJ/dJMcabXmh06/lQe6mkw9vLdsba0GLZAZW1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bRWdOJ/dJMcabXmh06/lQe6mkw9vLdsba0GLZAZW1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bRWdOJ/dJMcabXmh06/lQe6mkw9vLdsba0GLZAZW1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbRWdOJ%2FdJMcabXmh06%2FlQe6mkw9vLdsba0GLZAZW1%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;618&quot; height=&quot;338&quot; data-filename=&quot;08.PNG&quot; data-origin-width=&quot;618&quot; data-origin-height=&quot;338&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;pre id=&quot;code_1770040686321&quot; class=&quot;cpp&quot; data-ke-language=&quot;cpp&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;#define delay_ms HAL_Delay
#define SYS_CLOCK    72
#define SYSTICK_LOAD 72000-1
uint32_t millis_cnt = 0;
uint32_t millis() {
 return millis_cnt;
}
uint32_t micros() {
 return (millis_cnt &amp;amp; 0x3FFFFF) * 1000 + (SYSTICK_LOAD - SysTick-&amp;gt;VAL) / SYS_CLOCK;
}
void delay_us(uint32_t us) {  // 64MHz 보정
 if (us &amp;gt; 1) {
   uint32_t count = us * 7 - 6;
   while (count--);
 } else {
   uint32_t count = 2;
   while (count--);
 }
}
#define ADDRESS   0x27&amp;lt;&amp;lt;1
#define RS1_EN1   0x05
#define RS1_EN0   0x01
#define RS0_EN1   0x04
#define RS0_EN0   0x00
#define BackLight 0x08
// RS-Q0 / RW-Q1 / EN-Q2 / BackLight-Q3 / D4-Q4 / D5-Q5 / D6-Q6 / D7-Q7
void LCD_DATA(uint8_t data) {
 uint8_t temp=(data &amp;amp; 0xF0)|RS1_EN1|BackLight;
 while(HAL_I2C_Master_Transmit(&amp;amp;hi2c1, ADDRESS, &amp;amp;temp, 1, 1000)!=HAL_OK);
 temp=(data &amp;amp; 0xF0)|RS1_EN0|BackLight;
 while(HAL_I2C_Master_Transmit(&amp;amp;hi2c1, ADDRESS, &amp;amp;temp, 1, 1000)!=HAL_OK);
 delay_us(4);
 temp=((data &amp;lt;&amp;lt; 4) &amp;amp; 0xF0)|RS1_EN1|BackLight;
 while(HAL_I2C_Master_Transmit(&amp;amp;hi2c1, ADDRESS, &amp;amp;temp, 1, 1000)!=HAL_OK);
 temp = ((data &amp;lt;&amp;lt; 4) &amp;amp; 0xF0)|RS1_EN0|BackLight;
 while(HAL_I2C_Master_Transmit(&amp;amp;hi2c1, ADDRESS, &amp;amp;temp, 1, 1000)!=HAL_OK);
 delay_us(50);
}
void LCD_CMD(uint8_t cmd) {
 uint8_t temp=(cmd &amp;amp; 0xF0)|RS0_EN1|BackLight;
 while(HAL_I2C_Master_Transmit(&amp;amp;hi2c1, ADDRESS, &amp;amp;temp, 1, 1000)!=HAL_OK);
 temp=(cmd &amp;amp; 0xF0)|RS0_EN0|BackLight;
 while(HAL_I2C_Master_Transmit(&amp;amp;hi2c1, ADDRESS, &amp;amp;temp, 1, 1000)!=HAL_OK);
 delay_us(4);
 temp=((cmd &amp;lt;&amp;lt; 4) &amp;amp; 0xF0)|RS0_EN1|BackLight;
 while(HAL_I2C_Master_Transmit(&amp;amp;hi2c1, ADDRESS, &amp;amp;temp, 1, 1000)!=HAL_OK);
 temp=((cmd &amp;lt;&amp;lt; 4) &amp;amp; 0xF0)|RS0_EN0|BackLight;
 while(HAL_I2C_Master_Transmit(&amp;amp;hi2c1, ADDRESS, &amp;amp;temp, 1, 1000)!=HAL_OK);
 delay_us(50);
}
void LCD_CMD_4bit(uint8_t cmd) {
 uint8_t temp=((cmd &amp;lt;&amp;lt; 4) &amp;amp; 0xF0)|RS0_EN1|BackLight;
 while(HAL_I2C_Master_Transmit(&amp;amp;hi2c1, ADDRESS, &amp;amp;temp, 1, 1000)!=HAL_OK);
 temp=((cmd &amp;lt;&amp;lt; 4) &amp;amp; 0xF0)|RS0_EN0|BackLight;
 while(HAL_I2C_Master_Transmit(&amp;amp;hi2c1, ADDRESS, &amp;amp;temp, 1, 1000)!=HAL_OK);
 delay_us(50);
}
void LCD_INIT(void) {
 delay_ms(100);
 LCD_CMD_4bit(0x03); delay_ms(5);
 LCD_CMD_4bit(0x03); delay_us(100);
 LCD_CMD_4bit(0x03); delay_us(100);
 LCD_CMD_4bit(0x02); delay_us(100);
 LCD_CMD(0x28);  // 4 bits, 2 line, 5x8 font
 LCD_CMD(0x08);  // display off, cursor off, blink off
 LCD_CMD(0x01);  // clear display
 delay_ms(3);
 LCD_CMD(0x06);  // cursor movint direction
 LCD_CMD(0x0C);  // display on, cursor off, blink off
}
void LCD_XY(char x, char y) {
 if      (y == 0) LCD_CMD(0x80 + x);
 else if (y == 1) LCD_CMD(0xC0 + x);
 else if (y == 2) LCD_CMD(0x94 + x);
 else if (y == 3) LCD_CMD(0xD4 + x);
}
void LCD_CLEAR(void) {
 LCD_CMD(0x01);
 delay_ms(2);
}
void LCD_PUTS(char *str) {
 while (*str) LCD_DATA(*str++);
}
/* USER CODE BEGIN 2 */
 LCD_INIT(); //1회호출(메인루프 시작전)
 HAL_ADC_Start(&amp;amp;hadc1); //딱 한번만 호출
 uint16_t adc_value0 = 0;
 uint8_t line1[20];
 uint8_t line2[20];
 /* USER CODE END 2 */
 /* Infinite loop */
 /* USER CODE BEGIN WHILE */
 while (1)
 {
	  if(HAL_ADC_PollForConversion(&amp;amp;hadc1, 10) == HAL_OK)
	  {
		  // 값 처리
		  adc_value0 = HAL_ADC_GetValue(&amp;amp;hadc1);
		  sprintf(line1,&quot;CNT = %10d&quot;,HAL_GetTick());
		  sprintf(line2,&quot;PA0 = %10d&quot;,adc_value0);
		  LCD_XY(0, 0) ; LCD_PUTS(line1);
		  LCD_XY(0, 1) ; LCD_PUTS(line2);
	  }
	  HAL_Delay(100);
   /* USER CODE END WHILE */
   /* USER CODE BEGIN 3 */
 }&lt;/code&gt;&lt;/pre&gt;</description>
      <category>프로그래밍/STM32</category>
      <author>덕력킹</author>
      <guid isPermaLink="true">https://bota.tistory.com/2473</guid>
      <comments>https://bota.tistory.com/2473#entry2473comment</comments>
      <pubDate>Mon, 2 Feb 2026 23:00:06 +0900</pubDate>
    </item>
    <item>
      <title>[STM32#30] CAN통신으로 각종 센서값을 전송하고 자동차에서 사용하는 OBD2 프로토콜을 간단하게 모방해보기!(녹칸다 내맘대로 STM32)</title>
      <link>https://bota.tistory.com/2472</link>
      <description>&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;stm32.png&quot; data-origin-width=&quot;1920&quot; data-origin-height=&quot;1080&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cN9jfn/dJMcabXjYXo/eKWjL9CkjRn4wonf20ZTX1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cN9jfn/dJMcabXjYXo/eKWjL9CkjRn4wonf20ZTX1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cN9jfn/dJMcabXjYXo/eKWjL9CkjRn4wonf20ZTX1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FcN9jfn%2FdJMcabXjYXo%2FeKWjL9CkjRn4wonf20ZTX1%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;1920&quot; height=&quot;1080&quot; data-filename=&quot;stm32.png&quot; data-origin-width=&quot;1920&quot; data-origin-height=&quot;1080&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/live/zxJ_ntNADKc&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://youtube.com/live/zxJ_ntNADKc&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/watch?v=zxJ_ntNADKc&quot; data-video-thumbnail=&quot;https://scrap.kakaocdn.net/dn/bDRR3H/dJMb9dHiGnB/cMfdTdMTyLmuOYTNtA9Klk/img.jpg?width=1280&amp;amp;height=720&amp;amp;face=0_0_1280_720,https://scrap.kakaocdn.net/dn/dvaX5D/dJMb82eHF4J/VI5xU638gfACKkB1BJEn2K/img.jpg?width=1280&amp;amp;height=720&amp;amp;face=0_0_1280_720,https://scrap.kakaocdn.net/dn/bjkI9f/dJMb82MxF93/v5DFajsqU95JxQajWLlsH0/img.jpg?width=1280&amp;amp;height=720&amp;amp;face=0_0_1280_720&quot; data-video-width=&quot;860&quot; data-video-height=&quot;484&quot; data-video-origin-width=&quot;860&quot; data-video-origin-height=&quot;484&quot; data-ke-mobilestyle=&quot;widthContent&quot; data-video-title=&quot;[STM32#30] CAN통신으로 각종 센서값을 전송하고 자동차에서 사용하는 OBD2 프로토콜을 간단하게 모&quot; data-original-url=&quot;&quot;&gt;&lt;iframe src=&quot;https://www.youtube.com/embed/zxJ_ntNADKc&quot; width=&quot;860&quot; height=&quot;484&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;[STM32#30]&amp;nbsp;CAN통신으로&amp;nbsp;각종&amp;nbsp;센서값을&amp;nbsp;전송하고&amp;nbsp;자동차에서&amp;nbsp;사용하는&amp;nbsp;OBD2&amp;nbsp;프로토콜을&amp;nbsp;간단하게&amp;nbsp;모방해보기!(녹칸다&amp;nbsp;내맘대로&amp;nbsp;STM32) &lt;br /&gt;&lt;br /&gt;심심한녹칸다의&amp;nbsp;내맘대로&amp;nbsp;STM32시리즈이다! &lt;br /&gt;&lt;br /&gt;STM32시리즈의&amp;nbsp;모든&amp;nbsp;자료는&amp;nbsp;구글&amp;nbsp;슬라이드에&amp;nbsp;작성하고&amp;nbsp;모두에게&amp;nbsp;공유되어있음! &lt;br /&gt;&lt;a href=&quot;https://docs.google.com/presentation/d/1myA5iYbjuKsLWLqtRLKAiRfwUwvqB1d1RGjiMIIgp3I/edit?slide=id.g3be1268f534_1_233#slide=id.g3be1268f534_1_233&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://docs.google.com/presentation/d/1myA5iYbjuKsLWLqtRLKAiRfwUwvqB1d1RGjiMIIgp3I/edit?slide=id.g3be1268f534_1_233#slide=id.g3be1268f534_1_233&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;이번편까지&amp;nbsp;해서&amp;nbsp;CAN통신은&amp;nbsp;마무리! &lt;br /&gt;&lt;br /&gt;1.녹칸다의&amp;nbsp;STM32쉴드에&amp;nbsp;PA0에&amp;nbsp;붙어있는&amp;nbsp;가변저항값을&amp;nbsp;측정해서&amp;nbsp;CAN통신으로&amp;nbsp;PC로&amp;nbsp;전송하기!&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;01.PNG&quot; data-origin-width=&quot;1003&quot; data-origin-height=&quot;652&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/ctN39F/dJMcac9Iuml/xyToeBK3LOzR0Irdp4Mhx1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/ctN39F/dJMcac9Iuml/xyToeBK3LOzR0Irdp4Mhx1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/ctN39F/dJMcac9Iuml/xyToeBK3LOzR0Irdp4Mhx1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FctN39F%2FdJMcac9Iuml%2FxyToeBK3LOzR0Irdp4Mhx1%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;1003&quot; height=&quot;652&quot; data-filename=&quot;01.PNG&quot; data-origin-width=&quot;1003&quot; data-origin-height=&quot;652&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;pre id=&quot;code_1769583766985&quot; class=&quot;cpp&quot; data-ke-language=&quot;cpp&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;/* USER CODE BEGIN 0 */
CAN_FilterTypeDef sFilterConfig;
CAN_TxHeaderTypeDef TxMessage;
CAN_RxHeaderTypeDef RxMessage;
uint8_t               TxData[8];
uint8_t               RxData[8];
uint32_t              TxMailbox;
//main에서 1회 호출
void Can_Set(){
	sFilterConfig.FilterBank= 0;
	sFilterConfig.FilterMode= CAN_FILTERMODE_IDMASK;
	sFilterConfig.FilterScale= CAN_FILTERSCALE_32BIT;
	sFilterConfig.FilterIdHigh= 0x0000;
	sFilterConfig.FilterIdLow= 0x0000;
	sFilterConfig.FilterMaskIdHigh= 0x0000;
	sFilterConfig.FilterMaskIdLow= 0x0000;
	sFilterConfig.FilterFIFOAssignment= CAN_RX_FIFO0;
	sFilterConfig.FilterActivation= ENABLE;
	sFilterConfig.SlaveStartFilterBank = 14;
	HAL_CAN_ConfigFilter(&amp;amp;hcan, &amp;amp;sFilterConfig);
	HAL_CAN_ActivateNotification(&amp;amp;hcan, CAN_IT_RX_FIFO0_MSG_PENDING);
	HAL_CAN_Start(&amp;amp;hcan);
}
/* USER CODE END 0 */
/* USER CODE BEGIN 2 */
 HAL_ADC_Start(&amp;amp;hadc1); //딱 한번만 호출
 Can_Set();
 uint16_t adc_value0 = 0;
 /* USER CODE END 2 */

while (1)
 {
	  //측정할때마다 호출
	  if(HAL_ADC_PollForConversion(&amp;amp;hadc1, 10) == HAL_OK)
	  {
		  // 값 처리
		  adc_value0 = HAL_ADC_GetValue(&amp;amp;hadc1); //0~4095
		  //CAN데이터로 송신!
		  TxMessage.DLC = 1; //데이터길이
		  TxMessage.ExtId = 0;
		  TxMessage.IDE = CAN_ID_STD;
		  TxMessage.RTR = CAN_RTR_DATA;
		  TxMessage.StdId = 0x600;
		  TxMessage.TransmitGlobalTime = DISABLE;
		  //0~4095범위의 ADC값을 0~255범위로 축소
		  TxData[0] = (uint8_t)(adc_value0/4095.0*255);
		  HAL_CAN_AddTxMessage(&amp;amp;hcan, &amp;amp;TxMessage, TxData, &amp;amp;TxMailbox);
	  }
	  HAL_Delay(100);
   /* USER CODE END WHILE */
   /* USER CODE BEGIN 3 */
 }&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;br /&gt;2.예제1에서&amp;nbsp;0~4095의&amp;nbsp;숫자를&amp;nbsp;각&amp;nbsp;자리로&amp;nbsp;나눠서&amp;nbsp;4byte로&amp;nbsp;전송하기!&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;02.PNG&quot; data-origin-width=&quot;968&quot; data-origin-height=&quot;637&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/Ll034/dJMcaajODyg/khM78KgHBO26iJ9DYkc92K/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/Ll034/dJMcaajODyg/khM78KgHBO26iJ9DYkc92K/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/Ll034/dJMcaajODyg/khM78KgHBO26iJ9DYkc92K/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FLl034%2FdJMcaajODyg%2FkhM78KgHBO26iJ9DYkc92K%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;968&quot; height=&quot;637&quot; data-filename=&quot;02.PNG&quot; data-origin-width=&quot;968&quot; data-origin-height=&quot;637&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;pre id=&quot;code_1769583779222&quot; class=&quot;cpp&quot; data-ke-language=&quot;cpp&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;/* USER CODE BEGIN 0 */
CAN_FilterTypeDef sFilterConfig;
CAN_TxHeaderTypeDef TxMessage;
CAN_RxHeaderTypeDef RxMessage;
uint8_t               TxData[8];
uint8_t               RxData[8];
uint32_t              TxMailbox;
//main에서 1회 호출
void Can_Set(){
	sFilterConfig.FilterBank= 0;
	sFilterConfig.FilterMode= CAN_FILTERMODE_IDMASK;
	sFilterConfig.FilterScale= CAN_FILTERSCALE_32BIT;
	sFilterConfig.FilterIdHigh= 0x0000;
	sFilterConfig.FilterIdLow= 0x0000;
	sFilterConfig.FilterMaskIdHigh= 0x0000;
	sFilterConfig.FilterMaskIdLow= 0x0000;
	sFilterConfig.FilterFIFOAssignment= CAN_RX_FIFO0;
	sFilterConfig.FilterActivation= ENABLE;
	sFilterConfig.SlaveStartFilterBank = 14;
	HAL_CAN_ConfigFilter(&amp;amp;hcan, &amp;amp;sFilterConfig);
	HAL_CAN_ActivateNotification(&amp;amp;hcan, CAN_IT_RX_FIFO0_MSG_PENDING);
	HAL_CAN_Start(&amp;amp;hcan);
}
/* USER CODE END 0 */
/* USER CODE BEGIN 2 */
 HAL_ADC_Start(&amp;amp;hadc1); //딱 한번만 호출
 Can_Set();
 uint16_t adc_value0 = 0;
 /* USER CODE END 2 */

while (1)
 {
	  //측정할때마다 호출
	  if(HAL_ADC_PollForConversion(&amp;amp;hadc1, 10) == HAL_OK)
	  {
		  // 값 처리
		  adc_value0 = HAL_ADC_GetValue(&amp;amp;hadc1); //0~4095
		  //CAN데이터로 송신!
		  TxMessage.DLC = 4; //데이터길이
		  TxMessage.ExtId = 0;
		  TxMessage.IDE = CAN_ID_STD;
		  TxMessage.RTR = CAN_RTR_DATA;
		  TxMessage.StdId = 0x600;
		  TxMessage.TransmitGlobalTime = DISABLE;
		  TxData[0] = adc_value0/1000; //천의자리
		  TxData[1] = (adc_value0/100)%10; //백의자리
		  TxData[2] = (adc_value0/10)%10; //십의자리
		  TxData[3] = adc_value0%10; //일의자리
		  HAL_CAN_AddTxMessage(&amp;amp;hcan, &amp;amp;TxMessage, TxData, &amp;amp;TxMailbox);
	  }
	  HAL_Delay(100);
   /* USER CODE END WHILE */
   /* USER CODE BEGIN 3 */
 }&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;br /&gt;3.온습도센서(DHT-11)의&amp;nbsp;측정값을&amp;nbsp;CAN통신으로&amp;nbsp;PC로&amp;nbsp;전송하기!&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;03.PNG&quot; data-origin-width=&quot;898&quot; data-origin-height=&quot;659&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cvjrRn/dJMcaajODyp/owgHkpyZQQ6KtV2KWYdBXK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cvjrRn/dJMcaajODyp/owgHkpyZQQ6KtV2KWYdBXK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cvjrRn/dJMcaajODyp/owgHkpyZQQ6KtV2KWYdBXK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FcvjrRn%2FdJMcaajODyp%2FowgHkpyZQQ6KtV2KWYdBXK%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;659&quot; data-filename=&quot;03.PNG&quot; data-origin-width=&quot;898&quot; data-origin-height=&quot;659&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;pre id=&quot;code_1769583833191&quot; class=&quot;cpp&quot; data-ke-language=&quot;cpp&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;/* USER CODE BEGIN 0 *//* USER CODE BEGIN 2 */
 Can_Set();
 char str[100];
 /* USER CODE END 2 */
 /* Infinite loop */
 /* USER CODE BEGIN WHILE */
 while (1)
 {
	  uint8_t error_no = DHT_read();
	  if(error_no == 0){  // 정상일 때 처리
		  float temp = 0;
		  float humi = 0;
		  temp = DHT.temp_i;
		  if (DHT.temp_d &amp;amp; 0x80) {
			  temp = -1 - temp;
		  }
		  temp += (DHT.temp_d &amp;amp; 0x0f) * 0.1;
		  humi = DHT.rh_i + DHT.rh_d * 0.1;
		  sprintf(str, &quot;T:%.1f'C H:%.1f%c\n&quot;, temp,humi,'%');
		  HAL_UART_Transmit(&amp;amp;huart2,str,strlen(str),100);
		  TxMessage.DLC = 4; //데이터길이
		  TxMessage.ExtId = 0;
		  TxMessage.IDE = CAN_ID_STD;
		  TxMessage.RTR = CAN_RTR_DATA;
		  TxMessage.StdId = 0x600;
		  TxMessage.TransmitGlobalTime = DISABLE;
		  TxData[0] = (uint8_t)temp; //온도의 정수부
		  TxData[1] = ((uint8_t)(temp*10))%10; //온도의 실수부
		  TxData[2] = (uint8_t)humi; //습도의 정부수
		  TxData[3] = ((uint8_t)(humi*10))%10; //습도의 실수부
		  HAL_CAN_AddTxMessage(&amp;amp;hcan, &amp;amp;TxMessage, TxData, &amp;amp;TxMailbox);
	  }
	  HAL_Delay(2000);
 }


#define delay_ms HAL_Delay
#define SYS_CLOCK    64
#define SYSTICK_LOAD 63999
uint32_t millis_cnt = 0;
uint32_t millis() {
return millis_cnt;
}
uint32_t micros() {
return (millis_cnt &amp;amp; 0x3FFFFF) * 1000 + (SYSTICK_LOAD - SysTick-&amp;gt;VAL) / SYS_CLOCK;
}
void delay_us(uint32_t us) {  // 64MHz 보정
if (us &amp;gt; 1) {
  uint32_t count = us * 7 - 6;
  while (count--);
} else {
  uint32_t count = 2;
  while (count--);
}
}

union {
 uint32_t data;
 struct {
   uint8_t temp_d;
   uint8_t temp_i;
   uint8_t rh_d;
   uint8_t rh_i;
 };
} DHT;
uint8_t DHT_read () {
 uint8_t i, check_sum;
 uint32_t start;
 check_sum = 0;
 DHT.data = 0;
 GPIOC-&amp;gt;CRL = (GPIOC-&amp;gt;CRL&amp;amp;0xFFFFFF0F)|(7&amp;lt;&amp;lt;(1*4));  // Output Open-drain (Master send LOW signal)
 delay_ms(18);
 GPIOC-&amp;gt;CRL= (GPIOC-&amp;gt;CRL&amp;amp;0xFFFFFF0F)|(4&amp;lt;&amp;lt;(1*4));  // Floating input (Master send HIGH signal &amp;amp; data receive)
 start = micros();
 while (GPIOC-&amp;gt;IDR&amp;amp;(1&amp;lt;&amp;lt;1)) {
   if (micros()-start &amp;gt; 50) return 1;  // 20~40us
 }
 start = micros();
 while (!(GPIOC-&amp;gt;IDR&amp;amp;(1&amp;lt;&amp;lt;1))) {
   if (micros()-start &amp;gt; 120) return 2;  // 80us
 }
 start = micros();
 while (GPIOC-&amp;gt;IDR&amp;amp;(1&amp;lt;&amp;lt;1)) {
   if (micros()-start &amp;gt; 120) return 3;  // 80us
 }
 for (i = 0; i &amp;lt; 32; i++) {
   while (!(GPIOC-&amp;gt;IDR&amp;amp;(1&amp;lt;&amp;lt;1))); // 50us
   start = micros();
   while (GPIOC-&amp;gt;IDR&amp;amp;(1&amp;lt;&amp;lt;1));
   if (micros()-start &amp;gt; 50) DHT.data |= (0x80000000 &amp;gt;&amp;gt; i); // &quot;0&quot;=26~28us, &quot;1&quot;=70us
 }
 for (i = 0; i &amp;lt; 8; i++) {
   while (!(GPIOC-&amp;gt;IDR&amp;amp;(1&amp;lt;&amp;lt;1))); // 50us
   start = micros();
   while (GPIOC-&amp;gt;IDR&amp;amp;(1&amp;lt;&amp;lt;1));
   if (micros()-start &amp;gt; 50) check_sum |= (0x80 &amp;gt;&amp;gt; i);
 }
 if ((DHT.rh_i + DHT.rh_d + DHT.temp_i + DHT.temp_d) == check_sum) return 0;
 else return 4;
}

CAN_FilterTypeDef sFilterConfig;
CAN_TxHeaderTypeDef TxMessage;
CAN_RxHeaderTypeDef RxMessage;
uint8_t               TxData[8];
uint8_t               RxData[8];
uint32_t              TxMailbox;
//main에서 1회 호출
void Can_Set(){
	sFilterConfig.FilterBank= 0;
	sFilterConfig.FilterMode= CAN_FILTERMODE_IDMASK;
	sFilterConfig.FilterScale= CAN_FILTERSCALE_32BIT;
	sFilterConfig.FilterIdHigh= 0x0000;
	sFilterConfig.FilterIdLow= 0x0000;
	sFilterConfig.FilterMaskIdHigh= 0x0000;
	sFilterConfig.FilterMaskIdLow= 0x0000;
	sFilterConfig.FilterFIFOAssignment= CAN_RX_FIFO0;
	sFilterConfig.FilterActivation= ENABLE;
	sFilterConfig.SlaveStartFilterBank = 14;
	HAL_CAN_ConfigFilter(&amp;amp;hcan, &amp;amp;sFilterConfig);
	HAL_CAN_ActivateNotification(&amp;amp;hcan, CAN_IT_RX_FIFO0_MSG_PENDING);
	HAL_CAN_Start(&amp;amp;hcan);
}
/* USER CODE END 0 */

/* USER CODE BEGIN 2 */
 Can_Set();
 char str[100];
 /* USER CODE END 2 */
 /* Infinite loop */
 /* USER CODE BEGIN WHILE */
 while (1)
 {
	  uint8_t error_no = DHT_read();
	  if(error_no == 0){  // 정상일 때 처리
		  float temp = 0;
		  float humi = 0;
		  temp = DHT.temp_i;
		  if (DHT.temp_d &amp;amp; 0x80) {
			  temp = -1 - temp;
		  }
		  temp += (DHT.temp_d &amp;amp; 0x0f) * 0.1;
		  humi = DHT.rh_i + DHT.rh_d * 0.1;
		  sprintf(str, &quot;T:%.1f'C H:%.1f%c\n&quot;, temp,humi,'%');
		  HAL_UART_Transmit(&amp;amp;huart2,str,strlen(str),100);
		  TxMessage.DLC = 4; //데이터길이
		  TxMessage.ExtId = 0;
		  TxMessage.IDE = CAN_ID_STD;
		  TxMessage.RTR = CAN_RTR_DATA;
		  TxMessage.StdId = 0x600;
		  TxMessage.TransmitGlobalTime = DISABLE;
		  TxData[0] = (uint8_t)temp; //온도의 정수부
		  TxData[1] = ((uint8_t)(temp*10))%10; //온도의 실수부
		  TxData[2] = (uint8_t)humi; //습도의 정부수
		  TxData[3] = ((uint8_t)(humi*10))%10; //습도의 실수부
		  HAL_CAN_AddTxMessage(&amp;amp;hcan, &amp;amp;TxMessage, TxData, &amp;amp;TxMailbox);
	  }
	  HAL_Delay(2000);
 }&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;br /&gt;4.PC프로그램에&amp;nbsp;0x7DF와&amp;nbsp;데이터&amp;nbsp;8byte를&amp;nbsp;stm32로&amp;nbsp;전송하면&amp;nbsp;STM32는&amp;nbsp;0x7E0이라는&amp;nbsp;ID와&amp;nbsp;PC가&amp;nbsp;보낸&amp;nbsp;데이터를&amp;nbsp;그대로&amp;nbsp;ECHO하도록&amp;nbsp;하시오!&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;04.PNG&quot; data-origin-width=&quot;672&quot; data-origin-height=&quot;642&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/dAuKkG/dJMcaajODyJ/nPiVV8tFivVFKHjApyrEk0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/dAuKkG/dJMcaajODyJ/nPiVV8tFivVFKHjApyrEk0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/dAuKkG/dJMcaajODyJ/nPiVV8tFivVFKHjApyrEk0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FdAuKkG%2FdJMcaajODyJ%2FnPiVV8tFivVFKHjApyrEk0%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;672&quot; height=&quot;642&quot; data-filename=&quot;04.PNG&quot; data-origin-width=&quot;672&quot; data-origin-height=&quot;642&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;pre id=&quot;code_1769583849935&quot; class=&quot;cpp&quot; data-ke-language=&quot;cpp&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;/* USER CODE BEGIN 0 */
CAN_FilterTypeDef sFilterConfig;
CAN_TxHeaderTypeDef TxMessage;
CAN_RxHeaderTypeDef RxMessage;
uint8_t               TxData[8];
uint8_t               RxData[8];
uint32_t              TxMailbox;
//main에서 1회 호출
void Can_Set(){
	sFilterConfig.FilterBank= 0;
	sFilterConfig.FilterMode= CAN_FILTERMODE_IDMASK;
	sFilterConfig.FilterScale= CAN_FILTERSCALE_32BIT;
	sFilterConfig.FilterIdHigh= 0x0000;
	sFilterConfig.FilterIdLow= 0x0000;
	sFilterConfig.FilterMaskIdHigh= 0x0000;
	sFilterConfig.FilterMaskIdLow= 0x0000;
	sFilterConfig.FilterFIFOAssignment= CAN_RX_FIFO0;
	sFilterConfig.FilterActivation= ENABLE;
	sFilterConfig.SlaveStartFilterBank = 14;
	HAL_CAN_ConfigFilter(&amp;amp;hcan, &amp;amp;sFilterConfig);
	HAL_CAN_ActivateNotification(&amp;amp;hcan, CAN_IT_RX_FIFO0_MSG_PENDING);
	HAL_CAN_Start(&amp;amp;hcan);
}


void HAL_CAN_RxFifo0MsgPendingCallback(CAN_HandleTypeDef *hcan1)
{
	HAL_CAN_GetRxMessage(hcan1, CAN_RX_FIFO0, &amp;amp;RxMessage, RxData);
	if(RxMessage.StdId == 0x7DF){
		TxMessage.DLC = 8; //데이터길이
		TxMessage.ExtId = 0;
		TxMessage.IDE = CAN_ID_STD;
		TxMessage.RTR = CAN_RTR_DATA;
		TxMessage.StdId = 0x7E0;
		TxMessage.TransmitGlobalTime = DISABLE;
		for(int i = 0;i&amp;lt;8;i++){
			TxData[i] = RxData[i];
		}
		HAL_CAN_AddTxMessage(&amp;amp;hcan, &amp;amp;TxMessage, TxData, &amp;amp;TxMailbox);
	}
}
/* USER CODE END 0 */
/* USER CODE BEGIN 2 */
 Can_Set();
 /* USER CODE END 2 */&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;br /&gt;5.PC프로그램이&amp;nbsp;현재&amp;nbsp;자동차의&amp;nbsp;속도를&amp;nbsp;물어보는&amp;nbsp;PID를&amp;nbsp;전송하면&amp;nbsp;STM32는&amp;nbsp;속도를&amp;nbsp;255(0xFF)로&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-filename=&quot;05.PNG&quot; data-origin-width=&quot;725&quot; data-origin-height=&quot;689&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bHXQ3U/dJMcaajODyN/5dswV5ZDgfz1t725xPwiF1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bHXQ3U/dJMcaajODyN/5dswV5ZDgfz1t725xPwiF1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bHXQ3U/dJMcaajODyN/5dswV5ZDgfz1t725xPwiF1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbHXQ3U%2FdJMcaajODyN%2F5dswV5ZDgfz1t725xPwiF1%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;725&quot; height=&quot;689&quot; data-filename=&quot;05.PNG&quot; data-origin-width=&quot;725&quot; data-origin-height=&quot;689&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;pre id=&quot;code_1769583860155&quot; class=&quot;cpp&quot; data-ke-language=&quot;cpp&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;/* USER CODE BEGIN 0 */
CAN_FilterTypeDef sFilterConfig;
CAN_TxHeaderTypeDef TxMessage;
CAN_RxHeaderTypeDef RxMessage;
uint8_t               TxData[8];
uint8_t               RxData[8];
uint32_t              TxMailbox;
//main에서 1회 호출
void Can_Set(){
	sFilterConfig.FilterBank= 0;
	sFilterConfig.FilterMode= CAN_FILTERMODE_IDMASK;
	sFilterConfig.FilterScale= CAN_FILTERSCALE_32BIT;
	sFilterConfig.FilterIdHigh= 0x0000;
	sFilterConfig.FilterIdLow= 0x0000;
	sFilterConfig.FilterMaskIdHigh= 0x0000;
	sFilterConfig.FilterMaskIdLow= 0x0000;
	sFilterConfig.FilterFIFOAssignment= CAN_RX_FIFO0;
	sFilterConfig.FilterActivation= ENABLE;
	sFilterConfig.SlaveStartFilterBank = 14;
	HAL_CAN_ConfigFilter(&amp;amp;hcan, &amp;amp;sFilterConfig);
	HAL_CAN_ActivateNotification(&amp;amp;hcan, CAN_IT_RX_FIFO0_MSG_PENDING);
	HAL_CAN_Start(&amp;amp;hcan);
}


void HAL_CAN_RxFifo0MsgPendingCallback(CAN_HandleTypeDef *hcan1)
{
	HAL_CAN_GetRxMessage(hcan1, CAN_RX_FIFO0, &amp;amp;RxMessage, RxData);
	if(RxMessage.StdId == 0x7DF){
		TxMessage.DLC = 8; //데이터길이
		TxMessage.ExtId = 0;
		TxMessage.IDE = CAN_ID_STD;
		TxMessage.RTR = CAN_RTR_DATA;
		TxMessage.StdId = 0x7E0;
		TxMessage.TransmitGlobalTime = DISABLE;
		uint8_t length = RxData[0];
		uint8_t service_id = RxData[1];
		uint8_t p_id = RxData[2];
		//Vehicle speed
		if(service_id == 0x01 &amp;amp;&amp;amp; p_id == 0x0D){
			TxData[0] = 3;
			TxData[1] = service_id;
			TxData[2] = p_id;
			TxData[3] = 255;
			TxData[4] = 0;
			TxData[5] = 0;
			TxData[6] = 0;
			TxData[7] = 0;
			HAL_CAN_AddTxMessage(&amp;amp;hcan, &amp;amp;TxMessage, TxData, &amp;amp;TxMailbox);
		}
		
	}
}

/* USER CODE END 0 */
/* USER CODE BEGIN 2 */
 Can_Set();
 /* USER CODE END 2 */&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;br /&gt;6.예제5에서&amp;nbsp;가변저항을&amp;nbsp;돌리면&amp;nbsp;속도가&amp;nbsp;0~255사이로&amp;nbsp;변화하도록&amp;nbsp;하시오!&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;06.PNG&quot; data-origin-width=&quot;927&quot; data-origin-height=&quot;632&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/nejo4/dJMcaa5bKzQ/KLROhiBaVSdqpShc9xueik/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/nejo4/dJMcaa5bKzQ/KLROhiBaVSdqpShc9xueik/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/nejo4/dJMcaa5bKzQ/KLROhiBaVSdqpShc9xueik/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fnejo4%2FdJMcaa5bKzQ%2FKLROhiBaVSdqpShc9xueik%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;927&quot; height=&quot;632&quot; data-filename=&quot;06.PNG&quot; data-origin-width=&quot;927&quot; data-origin-height=&quot;632&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;pre id=&quot;code_1769583873241&quot; class=&quot;cpp&quot; data-ke-language=&quot;cpp&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;/* USER CODE BEGIN 0 */
//이 변수가 인터럽트를 포함한 여기저기서 사용할 경우 이 키워드를 붙혀야한다!
volatile uint16_t adc_value0 = 0;
CAN_FilterTypeDef sFilterConfig;
CAN_TxHeaderTypeDef TxMessage;
CAN_RxHeaderTypeDef RxMessage;
uint8_t               TxData[8];
uint8_t               RxData[8];
uint32_t              TxMailbox;
//main에서 1회 호출
void Can_Set(){
	sFilterConfig.FilterBank= 0;
	sFilterConfig.FilterMode= CAN_FILTERMODE_IDMASK;
	sFilterConfig.FilterScale= CAN_FILTERSCALE_32BIT;
	sFilterConfig.FilterIdHigh= 0x0000;
	sFilterConfig.FilterIdLow= 0x0000;
	sFilterConfig.FilterMaskIdHigh= 0x0000;
	sFilterConfig.FilterMaskIdLow= 0x0000;
	sFilterConfig.FilterFIFOAssignment= CAN_RX_FIFO0;
	sFilterConfig.FilterActivation= ENABLE;
	sFilterConfig.SlaveStartFilterBank = 14;
	HAL_CAN_ConfigFilter(&amp;amp;hcan, &amp;amp;sFilterConfig);
	HAL_CAN_ActivateNotification(&amp;amp;hcan, CAN_IT_RX_FIFO0_MSG_PENDING);
	HAL_CAN_Start(&amp;amp;hcan);
}

void HAL_CAN_RxFifo0MsgPendingCallback(CAN_HandleTypeDef *hcan1)
{
	HAL_CAN_GetRxMessage(hcan1, CAN_RX_FIFO0, &amp;amp;RxMessage, RxData);
	if(RxMessage.StdId == 0x7DF){
		TxMessage.DLC = 8; //데이터길이
		TxMessage.ExtId = 0;
		TxMessage.IDE = CAN_ID_STD;
		TxMessage.RTR = CAN_RTR_DATA;
		TxMessage.StdId = 0x7E0;
		TxMessage.TransmitGlobalTime = DISABLE;
		uint8_t length = RxData[0];
		uint8_t service_id = RxData[1];
		uint8_t p_id = RxData[2];
		//Vehicle speed
		if(service_id == 0x01 &amp;amp;&amp;amp; p_id == 0x0D){
			TxData[0] = 3;
			TxData[1] = service_id;
			TxData[2] = p_id;
			TxData[3] = (uint8_t)(adc_value0/4095.0*255);
			TxData[4] = 0;
			TxData[5] = 0;
			TxData[6] = 0;
			TxData[7] = 0;
			HAL_CAN_AddTxMessage(&amp;amp;hcan, &amp;amp;TxMessage, TxData, &amp;amp;TxMailbox);
		}
	}
}
/* USER CODE END 0 */

/* USER CODE BEGIN 2 */
 Can_Set();
 HAL_ADC_Start(&amp;amp;hadc1);
 /* USER CODE END 2 */
 /* Infinite loop */
 /* USER CODE BEGIN WHILE */
 while (1)
 {
	  if(HAL_ADC_PollForConversion(&amp;amp;hadc1, 10) == HAL_OK)
	  {
		  // 값 처리
		  adc_value0 = HAL_ADC_GetValue(&amp;amp;hadc1);
	  }
	  HAL_Delay(100);
   /* USER CODE END WHILE */
   /* USER CODE BEGIN 3 */
 }&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;br /&gt;7.PC프로그램에서&amp;nbsp;자동차의&amp;nbsp;엔진RPM을&amp;nbsp;물어보는&amp;nbsp;PID를&amp;nbsp;전송하면&amp;nbsp;가변저항을&amp;nbsp;돌려서&amp;nbsp;엔진&amp;nbsp;RPM이&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-filename=&quot;07.PNG&quot; data-origin-width=&quot;979&quot; data-origin-height=&quot;649&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/dc0RNi/dJMcac2XHd4/RKz4MLG4JpKCruGkBZDqhK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/dc0RNi/dJMcac2XHd4/RKz4MLG4JpKCruGkBZDqhK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/dc0RNi/dJMcac2XHd4/RKz4MLG4JpKCruGkBZDqhK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fdc0RNi%2FdJMcac2XHd4%2FRKz4MLG4JpKCruGkBZDqhK%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;979&quot; height=&quot;649&quot; data-filename=&quot;07.PNG&quot; data-origin-width=&quot;979&quot; data-origin-height=&quot;649&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;pre id=&quot;code_1769583886450&quot; class=&quot;cpp&quot; data-ke-language=&quot;cpp&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;/* USER CODE BEGIN 0 */
//이 변수가 인터럽트를 포함한 여기저기서 사용할 경우 이 키워드를 붙혀야한다!
volatile uint16_t adc_value0 = 0;
char tx_buff[50];
CAN_FilterTypeDef sFilterConfig;
CAN_TxHeaderTypeDef TxMessage;
CAN_RxHeaderTypeDef RxMessage;
uint8_t               TxData[8];
uint8_t               RxData[8];
uint32_t              TxMailbox;
//main에서 1회 호출
void Can_Set(){
	sFilterConfig.FilterBank= 0;
	sFilterConfig.FilterMode= CAN_FILTERMODE_IDMASK;
	sFilterConfig.FilterScale= CAN_FILTERSCALE_32BIT;
	sFilterConfig.FilterIdHigh= 0x0000;
	sFilterConfig.FilterIdLow= 0x0000;
	sFilterConfig.FilterMaskIdHigh= 0x0000;
	sFilterConfig.FilterMaskIdLow= 0x0000;
	sFilterConfig.FilterFIFOAssignment= CAN_RX_FIFO0;
	sFilterConfig.FilterActivation= ENABLE;
	sFilterConfig.SlaveStartFilterBank = 14;
	HAL_CAN_ConfigFilter(&amp;amp;hcan, &amp;amp;sFilterConfig);
	HAL_CAN_ActivateNotification(&amp;amp;hcan, CAN_IT_RX_FIFO0_MSG_PENDING);
	HAL_CAN_Start(&amp;amp;hcan);
}

void HAL_CAN_RxFifo0MsgPendingCallback(CAN_HandleTypeDef *hcan1)
{
	HAL_CAN_GetRxMessage(hcan1, CAN_RX_FIFO0, &amp;amp;RxMessage, RxData);
	if(RxMessage.StdId == 0x7DF){
		TxMessage.DLC = 8; //데이터길이
		TxMessage.ExtId = 0;
		TxMessage.IDE = CAN_ID_STD;
		TxMessage.RTR = CAN_RTR_DATA;
		TxMessage.StdId = 0x7E0;
		TxMessage.TransmitGlobalTime = DISABLE;
		uint8_t length = RxData[0];
		uint8_t service_id = RxData[1];
		uint8_t p_id = RxData[2];
		//Engine speed
		if(service_id == 0x01 &amp;amp;&amp;amp; p_id == 0x0C){
			TxData[0] = 4;
			TxData[1] = service_id;
			TxData[2] = p_id;
			uint16_t rpm = (uint16_t)(adc_value0/4095.0*16383.75);
			TxData[3] = (rpm*4)/256; //A
			TxData[4] = (rpm*4)%256; //B
			TxData[5] = 0;
			TxData[6] = 0;
			TxData[7] = 0;
			HAL_CAN_AddTxMessage(&amp;amp;hcan, &amp;amp;TxMessage, TxData, &amp;amp;TxMailbox);
			sprintf(tx_buff,&quot;RPM=%d, A=%02X, B=%02X, C_RPM=%d\n&quot;,rpm,TxData[3],TxData[4],(TxData[3]*256+TxData[4])/4);
			HAL_UART_Transmit(&amp;amp;huart2,tx_buff,strlen(tx_buff),100);
		}
	}
}
/* USER CODE END 0 */


/* USER CODE BEGIN 2 */
 Can_Set();
 HAL_ADC_Start(&amp;amp;hadc1);
 /* USER CODE END 2 */
 /* Infinite loop */
 /* USER CODE BEGIN WHILE */
 while (1)
 {
	  if(HAL_ADC_PollForConversion(&amp;amp;hadc1, 10) == HAL_OK)
	  {
		  // 값 처리
		  adc_value0 = HAL_ADC_GetValue(&amp;amp;hadc1);
	  }
	  HAL_Delay(100);
   /* USER CODE END WHILE */
   /* USER CODE BEGIN 3 */
 }&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;br /&gt;8.동일한&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-filename=&quot;08.PNG&quot; data-origin-width=&quot;1043&quot; data-origin-height=&quot;658&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/zkpQV/dJMcahb9Azi/Qqm6tkdVI3LwuxfrwTQkuK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/zkpQV/dJMcahb9Azi/Qqm6tkdVI3LwuxfrwTQkuK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/zkpQV/dJMcahb9Azi/Qqm6tkdVI3LwuxfrwTQkuK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FzkpQV%2FdJMcahb9Azi%2FQqm6tkdVI3LwuxfrwTQkuK%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;1043&quot; height=&quot;658&quot; data-filename=&quot;08.PNG&quot; data-origin-width=&quot;1043&quot; data-origin-height=&quot;658&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;pre id=&quot;code_1769583901036&quot; class=&quot;cpp&quot; data-ke-language=&quot;cpp&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;/* USER CODE BEGIN 0 */
//이 변수가 인터럽트를 포함한 여기저기서 사용할 경우 이 키워드를 붙혀야한다!
volatile uint16_t adc_value0 = 0;
char tx_buff[50];
CAN_FilterTypeDef sFilterConfig;
CAN_TxHeaderTypeDef TxMessage;
CAN_RxHeaderTypeDef RxMessage;
uint8_t               TxData[8];
uint8_t               RxData[8];
uint32_t              TxMailbox;
//main에서 1회 호출
void Can_Set(){
	sFilterConfig.FilterBank= 0;
	sFilterConfig.FilterMode= CAN_FILTERMODE_IDMASK;
	sFilterConfig.FilterScale= CAN_FILTERSCALE_32BIT;
	sFilterConfig.FilterIdHigh= 0x0000;
	sFilterConfig.FilterIdLow= 0x0000;
	sFilterConfig.FilterMaskIdHigh= 0x0000;
	sFilterConfig.FilterMaskIdLow= 0x0000;
	sFilterConfig.FilterFIFOAssignment= CAN_RX_FIFO0;
	sFilterConfig.FilterActivation= ENABLE;
	sFilterConfig.SlaveStartFilterBank = 14;
	HAL_CAN_ConfigFilter(&amp;amp;hcan, &amp;amp;sFilterConfig);
	HAL_CAN_ActivateNotification(&amp;amp;hcan, CAN_IT_RX_FIFO0_MSG_PENDING);
	HAL_CAN_Start(&amp;amp;hcan);
}

void HAL_CAN_RxFifo0MsgPendingCallback(CAN_HandleTypeDef *hcan1)
{
	HAL_CAN_GetRxMessage(hcan1, CAN_RX_FIFO0, &amp;amp;RxMessage, RxData);
	if(RxMessage.StdId == 0x7DF){
		TxMessage.DLC = 8; //데이터길이
		TxMessage.ExtId = 0;
		TxMessage.IDE = CAN_ID_STD;
		TxMessage.RTR = CAN_RTR_DATA;
		TxMessage.StdId = 0x7E0;
		TxMessage.TransmitGlobalTime = DISABLE;
		uint8_t length = RxData[0];
		uint8_t service_id = RxData[1];
		uint8_t p_id = RxData[2];
		//Engine coolant temperature
		if(service_id == 0x01 &amp;amp;&amp;amp; p_id == 0x05){
			TxData[0] = 4;
			TxData[1] = service_id;
			TxData[2] = p_id;
			int16_t temp = (uint16_t)(adc_value0/4095.0*255) -40;
			TxData[3] = temp + 40;
			TxData[4] = 0;
			TxData[5] = 0;
			TxData[6] = 0;
			TxData[7] = 0;
			HAL_CAN_AddTxMessage(&amp;amp;hcan, &amp;amp;TxMessage, TxData, &amp;amp;TxMailbox);
			sprintf(tx_buff,&quot;temp=%d, A=%02X, c_temp=%d\n&quot;,temp,TxData[3],TxData[3]-40);
			HAL_UART_Transmit(&amp;amp;huart2,tx_buff,strlen(tx_buff),100);
		}
	}
}

/* USER CODE END 0 */


/* USER CODE BEGIN 2 */
 Can_Set();
 HAL_ADC_Start(&amp;amp;hadc1);
 /* USER CODE END 2 */
 /* Infinite loop */
 /* USER CODE BEGIN WHILE */
 while (1)
 {
	  if(HAL_ADC_PollForConversion(&amp;amp;hadc1, 10) == HAL_OK)
	  {
		  // 값 처리
		  adc_value0 = HAL_ADC_GetValue(&amp;amp;hadc1);
	  }
	  HAL_Delay(100);
   /* USER CODE END WHILE */
   /* USER CODE BEGIN 3 */
 }&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>프로그래밍/STM32</category>
      <author>덕력킹</author>
      <guid isPermaLink="true">https://bota.tistory.com/2472</guid>
      <comments>https://bota.tistory.com/2472#entry2472comment</comments>
      <pubDate>Wed, 28 Jan 2026 16:07:22 +0900</pubDate>
    </item>
    <item>
      <title>[STM32#29] CAN통신 모듈인 SN65HVD230을 연결해서 설정하는 방법을 알아보고 ecan-u01s을 이용해서 패킷을 확인해보기!(녹칸다 내맘대로 STM32)</title>
      <link>https://bota.tistory.com/2471</link>
      <description>&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;stm32.png&quot; data-origin-width=&quot;1920&quot; data-origin-height=&quot;1080&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/zKM4U/dJMcabCZ0ww/lnAW6RoKOkLTGPmv16f3rK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/zKM4U/dJMcabCZ0ww/lnAW6RoKOkLTGPmv16f3rK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/zKM4U/dJMcabCZ0ww/lnAW6RoKOkLTGPmv16f3rK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FzKM4U%2FdJMcabCZ0ww%2FlnAW6RoKOkLTGPmv16f3rK%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;1920&quot; height=&quot;1080&quot; data-filename=&quot;stm32.png&quot; data-origin-width=&quot;1920&quot; data-origin-height=&quot;1080&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/live/Y64tBhImAvo&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://youtube.com/live/Y64tBhImAvo&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/watch?v=Y64tBhImAvo&quot; data-video-thumbnail=&quot;https://scrap.kakaocdn.net/dn/bm0Uhr/dJMb9cBCBoH/3ERneyQfXu1NFiOspnLjLK/img.jpg?width=1280&amp;amp;height=720&amp;amp;face=0_0_1280_720,https://scrap.kakaocdn.net/dn/bidDCi/dJMb9kl7juA/ODbSFSWQNE8aFK27yxzLn0/img.jpg?width=1280&amp;amp;height=720&amp;amp;face=0_0_1280_720,https://scrap.kakaocdn.net/dn/90HZZ/dJMb9frzVJa/joUBaj9QgkBo5C8tUY2A6K/img.jpg?width=1280&amp;amp;height=720&amp;amp;face=0_0_1280_720&quot; data-video-width=&quot;860&quot; data-video-height=&quot;484&quot; data-video-origin-width=&quot;860&quot; data-video-origin-height=&quot;484&quot; data-ke-mobilestyle=&quot;widthContent&quot; data-video-title=&quot;[STM32#29] CAN통신 모듈인 SN65HVD230을 연결해서 설정하는 방법을 알아보고 ecan-u01s을 이용해서 패킷&quot; data-original-url=&quot;&quot;&gt;&lt;iframe src=&quot;https://www.youtube.com/embed/Y64tBhImAvo&quot; width=&quot;860&quot; height=&quot;484&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;[STM32#29]&amp;nbsp;CAN통신&amp;nbsp;모듈인&amp;nbsp;SN65HVD230을&amp;nbsp;연결해서&amp;nbsp;설정하는&amp;nbsp;방법을&amp;nbsp;알아보고&amp;nbsp;ecan-u01s을&amp;nbsp;이용해서&amp;nbsp;패킷을&amp;nbsp;확인해보기!(녹칸다&amp;nbsp;내맘대로&amp;nbsp;STM32) &lt;br /&gt;&lt;br /&gt;심심한녹칸다의&amp;nbsp;내맘대로&amp;nbsp;STM32시리즈이다! &lt;br /&gt;&lt;br /&gt;STM32시리즈의&amp;nbsp;모든&amp;nbsp;자료는&amp;nbsp;구글&amp;nbsp;슬라이드에&amp;nbsp;작성하고&amp;nbsp;모두에게&amp;nbsp;공유되어있음! &lt;br /&gt;&lt;a href=&quot;https://docs.google.com/presentation/d/1myA5iYbjuKsLWLqtRLKAiRfwUwvqB1d1RGjiMIIgp3I/edit?slide=id.g3bb3c8bdfec_1_0#slide=id.g3bb3c8bdfec_1_0&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://docs.google.com/presentation/d/1myA5iYbjuKsLWLqtRLKAiRfwUwvqB1d1RGjiMIIgp3I/edit?slide=id.g3bb3c8bdfec_1_0#slide=id.g3bb3c8bdfec_1_0&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;이번편은&amp;nbsp;stm32보드로&amp;nbsp;간단하게&amp;nbsp;can통신을&amp;nbsp;해보도록&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-filename=&quot;aa.PNG&quot; data-origin-width=&quot;1339&quot; data-origin-height=&quot;671&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/b1XgQh/dJMcahDcLnW/i8zICS7eGtYdwnz45qWxrK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/b1XgQh/dJMcahDcLnW/i8zICS7eGtYdwnz45qWxrK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/b1XgQh/dJMcahDcLnW/i8zICS7eGtYdwnz45qWxrK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fb1XgQh%2FdJMcahDcLnW%2Fi8zICS7eGtYdwnz45qWxrK%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;1339&quot; height=&quot;671&quot; data-filename=&quot;aa.PNG&quot; data-origin-width=&quot;1339&quot; data-origin-height=&quot;671&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;bb.PNG&quot; data-origin-width=&quot;1094&quot; data-origin-height=&quot;648&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cqa7v1/dJMcacWc8El/32I6kvu7m27KKkQOwtKLm0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cqa7v1/dJMcacWc8El/32I6kvu7m27KKkQOwtKLm0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cqa7v1/dJMcacWc8El/32I6kvu7m27KKkQOwtKLm0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fcqa7v1%2FdJMcacWc8El%2F32I6kvu7m27KKkQOwtKLm0%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;1094&quot; height=&quot;648&quot; data-filename=&quot;bb.PNG&quot; data-origin-width=&quot;1094&quot; data-origin-height=&quot;648&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;cc.PNG&quot; data-origin-width=&quot;718&quot; data-origin-height=&quot;528&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/wyjOw/dJMcacWc8Ek/lfoYKf4FlSQU3JMG3IYge0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/wyjOw/dJMcacWc8Ek/lfoYKf4FlSQU3JMG3IYge0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/wyjOw/dJMcacWc8Ek/lfoYKf4FlSQU3JMG3IYge0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FwyjOw%2FdJMcacWc8Ek%2FlfoYKf4FlSQU3JMG3IYge0%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;718&quot; height=&quot;528&quot; data-filename=&quot;cc.PNG&quot; data-origin-width=&quot;718&quot; data-origin-height=&quot;528&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;br /&gt;1.STM32가&amp;nbsp;1초간격으로&amp;nbsp;CAN통신&amp;nbsp;메시지를&amp;nbsp;PC로&amp;nbsp;전송할때,&amp;nbsp;PC에&amp;nbsp;CAN통신을&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-filename=&quot;01.PNG&quot; data-origin-width=&quot;768&quot; data-origin-height=&quot;653&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/NWfwk/dJMcadHyKfO/Jrths2FkccZmyOVSuwSp0k/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/NWfwk/dJMcadHyKfO/Jrths2FkccZmyOVSuwSp0k/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/NWfwk/dJMcadHyKfO/Jrths2FkccZmyOVSuwSp0k/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FNWfwk%2FdJMcadHyKfO%2FJrths2FkccZmyOVSuwSp0k%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;768&quot; height=&quot;653&quot; data-filename=&quot;01.PNG&quot; data-origin-width=&quot;768&quot; data-origin-height=&quot;653&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;pre id=&quot;code_1769435860314&quot; class=&quot;cpp&quot; data-ke-language=&quot;cpp&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;/* USER CODE BEGIN 0 */
//CAN통신할때 필요한 변수와 구조체
CAN_FilterTypeDef sFilterConfig;
CAN_TxHeaderTypeDef TxMessage;
CAN_RxHeaderTypeDef RxMessage;
uint8_t               TxData[8];
uint8_t               RxData[8];
uint32_t              TxMailbox;
void Can_Set(){
	sFilterConfig.FilterBank= 0;
	sFilterConfig.FilterMode= CAN_FILTERMODE_IDMASK;
	sFilterConfig.FilterScale= CAN_FILTERSCALE_32BIT;
	sFilterConfig.FilterIdHigh= 0x0000;
	sFilterConfig.FilterIdLow= 0x0000;
	sFilterConfig.FilterMaskIdHigh= 0x0000;
	sFilterConfig.FilterMaskIdLow= 0x0000;
	sFilterConfig.FilterFIFOAssignment= CAN_RX_FIFO0;
	sFilterConfig.FilterActivation= ENABLE;
	sFilterConfig.SlaveStartFilterBank = 14;
	HAL_CAN_ConfigFilter(&amp;amp;hcan, &amp;amp;sFilterConfig);
	HAL_CAN_ActivateNotification(&amp;amp;hcan, CAN_IT_RX_FIFO0_MSG_PENDING);
	HAL_CAN_Start(&amp;amp;hcan);
}
/* USER CODE END 0 */
/* USER CODE BEGIN 2 */
 //캔통신 시작~
 Can_Set();
 /* USER CODE END 2 */


while (1)
 {
	  //STM32가 1초간격으로 메시지를 전송한다!
	  //송신
	  TxMessage.DLC = 8; //데이터길이
	  TxMessage.ExtId = 0;
	  TxMessage.IDE = CAN_ID_STD;
	  TxMessage.RTR = CAN_RTR_DATA;
	  TxMessage.StdId = 0x123; //0x000 ~ 0x7FF
	  TxMessage.TransmitGlobalTime = DISABLE;
	  TxData[0] = 1;
	  TxData[1] = 2;
	  TxData[2] = 3;
	  TxData[3] = 4;
	  TxData[5] = 5;
	  TxData[6] = 6;
	  TxData[7] = 7;
	  HAL_CAN_AddTxMessage(&amp;amp;hcan, &amp;amp;TxMessage, TxData, &amp;amp;TxMailbox);
	  HAL_Delay(1000);
   /* USER CODE END WHILE */
   /* USER CODE BEGIN 3 */
 }&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;br /&gt;2.이번에는&amp;nbsp;PC쪽&amp;nbsp;프로그램에서&amp;nbsp;8개의&amp;nbsp;길이를&amp;nbsp;가지는&amp;nbsp;데이터를&amp;nbsp;송신했을때&amp;nbsp;STM32의&amp;nbsp;usart2를&amp;nbsp;이용해서&amp;nbsp;putty에&amp;nbsp;log를&amp;nbsp;출력하시오!&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;02.PNG&quot; data-origin-width=&quot;1213&quot; data-origin-height=&quot;585&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cGX5KQ/dJMcahDcLn9/3JBM0rxsl0kgfvCmkIvf7K/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cGX5KQ/dJMcahDcLn9/3JBM0rxsl0kgfvCmkIvf7K/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cGX5KQ/dJMcahDcLn9/3JBM0rxsl0kgfvCmkIvf7K/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FcGX5KQ%2FdJMcahDcLn9%2F3JBM0rxsl0kgfvCmkIvf7K%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;1213&quot; height=&quot;585&quot; data-filename=&quot;02.PNG&quot; data-origin-width=&quot;1213&quot; data-origin-height=&quot;585&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;pre id=&quot;code_1769435876753&quot; class=&quot;cpp&quot; data-ke-language=&quot;cpp&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;/* USER CODE BEGIN 0 */
//CAN통신할때 필요한 변수와 구조체
CAN_FilterTypeDef sFilterConfig;
CAN_TxHeaderTypeDef TxMessage;
CAN_RxHeaderTypeDef RxMessage;
uint8_t               TxData[8];
uint8_t               RxData[8];
uint32_t              TxMailbox;
//로그출력용 변수
uint8_t tx_buff[50];
void Can_Set(){
	sFilterConfig.FilterBank= 0;
	sFilterConfig.FilterMode= CAN_FILTERMODE_IDMASK;
	sFilterConfig.FilterScale= CAN_FILTERSCALE_32BIT;
	sFilterConfig.FilterIdHigh= 0x0000;
	sFilterConfig.FilterIdLow= 0x0000;
	sFilterConfig.FilterMaskIdHigh= 0x0000;
	sFilterConfig.FilterMaskIdLow= 0x0000;
	sFilterConfig.FilterFIFOAssignment= CAN_RX_FIFO0;
	sFilterConfig.FilterActivation= ENABLE;
	sFilterConfig.SlaveStartFilterBank = 14;
	HAL_CAN_ConfigFilter(&amp;amp;hcan, &amp;amp;sFilterConfig);
	HAL_CAN_ActivateNotification(&amp;amp;hcan, CAN_IT_RX_FIFO0_MSG_PENDING);
	HAL_CAN_Start(&amp;amp;hcan);
}

//CAN수신부
void HAL_CAN_RxFifo0MsgPendingCallback(CAN_HandleTypeDef *hcan1)
{
	HAL_CAN_GetRxMessage(hcan1, CAN_RX_FIFO0, &amp;amp;RxMessage, RxData);

	if(RxMessage.RTR == CAN_RTR_DATA &amp;amp;&amp;amp; RxMessage.IDE == CAN_ID_STD){
		sprintf(tx_buff,&quot;CAN ID = %X, Length = %d, &quot;,RxMessage.StdId,RxMessage.DLC);
		HAL_UART_Transmit(&amp;amp;huart2, tx_buff, strlen(tx_buff), 100);
		for(int i = 0;i&amp;lt;RxMessage.DLC;i++){
			sprintf(tx_buff,&quot;%d, &quot;,RxData[i]);
			HAL_UART_Transmit(&amp;amp;huart2, tx_buff, strlen(tx_buff), 100);
		}
		HAL_UART_Transmit(&amp;amp;huart2, &quot;\n&quot;, 1, 100);
	}
}
/* USER CODE END 0 */


/* USER CODE BEGIN 2 */
 //캔통신 시작~
 Can_Set();
 /* USER CODE END 2 */
while (1)
 {
	  //STM32가 1초간격으로 메시지를 전송한다!
	  //송신
	  TxMessage.DLC = 8; //데이터길이
	  TxMessage.ExtId = 0;
	  TxMessage.IDE = CAN_ID_STD;
	  TxMessage.RTR = CAN_RTR_DATA;
	  TxMessage.StdId = 0x123; //0x000 ~ 0x7FF
	  TxMessage.TransmitGlobalTime = DISABLE;
	  TxData[0] = 1;
	  TxData[1] = 2;
	  TxData[2] = 3;
	  TxData[3] = 4;
	  TxData[5] = 5;
	  TxData[6] = 6;
	  TxData[7] = 7;
	  HAL_CAN_AddTxMessage(&amp;amp;hcan, &amp;amp;TxMessage, TxData, &amp;amp;TxMailbox);
	  HAL_Delay(1000);
   /* USER CODE END WHILE */
   /* USER CODE BEGIN 3 */
 }&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;br /&gt;3.녹칸다의&amp;nbsp;STM32쉴드에보면&amp;nbsp;LED가&amp;nbsp;8개&amp;nbsp;붙어있는데,&amp;nbsp;PC에서&amp;nbsp;8byte의&amp;nbsp;CAN메시지를&amp;nbsp;송신해서&amp;nbsp;각&amp;nbsp;바이트가&amp;nbsp;0이면&amp;nbsp;LED가&amp;nbsp;OFF이고&amp;nbsp;1이면&amp;nbsp;LED가&amp;nbsp;ON되도록하시오!(일괄제어)&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;03.PNG&quot; data-origin-width=&quot;924&quot; data-origin-height=&quot;651&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/OnwJ1/dJMcahJ0zSq/JmYth92CGL0m8JWrw0emkk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/OnwJ1/dJMcahJ0zSq/JmYth92CGL0m8JWrw0emkk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/OnwJ1/dJMcahJ0zSq/JmYth92CGL0m8JWrw0emkk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FOnwJ1%2FdJMcahJ0zSq%2FJmYth92CGL0m8JWrw0emkk%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;924&quot; height=&quot;651&quot; data-filename=&quot;03.PNG&quot; data-origin-width=&quot;924&quot; data-origin-height=&quot;651&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;pre id=&quot;code_1769435892009&quot; class=&quot;cpp&quot; data-ke-language=&quot;cpp&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;/* USER CODE BEGIN 0 */
//CAN통신할때 필요한 변수와 구조체
CAN_FilterTypeDef sFilterConfig;
CAN_TxHeaderTypeDef TxMessage;
CAN_RxHeaderTypeDef RxMessage;
uint8_t               TxData[8];
uint8_t               RxData[8];
uint32_t              TxMailbox;
//로그출력용 변수
uint8_t tx_buff[50];
void Can_Set(){
	sFilterConfig.FilterBank= 0;
	sFilterConfig.FilterMode= CAN_FILTERMODE_IDMASK;
	sFilterConfig.FilterScale= CAN_FILTERSCALE_32BIT;
	sFilterConfig.FilterIdHigh= 0x0000;
	sFilterConfig.FilterIdLow= 0x0000;
	sFilterConfig.FilterMaskIdHigh= 0x0000;
	sFilterConfig.FilterMaskIdLow= 0x0000;
	sFilterConfig.FilterFIFOAssignment= CAN_RX_FIFO0;
	sFilterConfig.FilterActivation= ENABLE;
	sFilterConfig.SlaveStartFilterBank = 14;
	HAL_CAN_ConfigFilter(&amp;amp;hcan, &amp;amp;sFilterConfig);
	HAL_CAN_ActivateNotification(&amp;amp;hcan, CAN_IT_RX_FIFO0_MSG_PENDING);
	HAL_CAN_Start(&amp;amp;hcan);
}

//CAN수신부
void HAL_CAN_RxFifo0MsgPendingCallback(CAN_HandleTypeDef *hcan1)
{
	HAL_CAN_GetRxMessage(hcan1, CAN_RX_FIFO0, &amp;amp;RxMessage, RxData);
	if(RxMessage.RTR == CAN_RTR_DATA &amp;amp;&amp;amp; RxMessage.IDE == CAN_ID_STD){
		//LED 8개가 제어됨!
		if(RxData[0]){
		  //0이 아닌 모든경우(ON)
		  HAL_GPIO_WritePin(LED1_GPIO_Port, LED1_Pin, 1);
		}else{
		  //0을 수신(OFF)
		  HAL_GPIO_WritePin(LED1_GPIO_Port, LED1_Pin, 0);
		}
		if(RxData[1]){
		  HAL_GPIO_WritePin(LED2_GPIO_Port, LED2_Pin, 1);
		}else{
		  HAL_GPIO_WritePin(LED2_GPIO_Port, LED2_Pin, 0);
		}
		if(RxData[2]){
		  HAL_GPIO_WritePin(LED3_GPIO_Port, LED3_Pin, 1);
		}else{
		  HAL_GPIO_WritePin(LED3_GPIO_Port, LED3_Pin, 0);
		}
		if(RxData[3]){
		  HAL_GPIO_WritePin(LED4_GPIO_Port, LED4_Pin, 1);
		}else{
		  HAL_GPIO_WritePin(LED4_GPIO_Port, LED4_Pin, 0);
		}

		if(RxData[4]){
		  HAL_GPIO_WritePin(LED5_GPIO_Port, LED5_Pin, 1);
		}else{
		  HAL_GPIO_WritePin(LED5_GPIO_Port, LED5_Pin, 0);
		}
		if(RxData[5]){
		  HAL_GPIO_WritePin(LED6_GPIO_Port, LED6_Pin, 1);
		}else{
		  HAL_GPIO_WritePin(LED6_GPIO_Port, LED6_Pin, 0);
		}
		if(RxData[6]){
		  HAL_GPIO_WritePin(LED7_GPIO_Port, LED7_Pin, 1);
		}else{
		  HAL_GPIO_WritePin(LED7_GPIO_Port, LED7_Pin, 0);
		}
		if(RxData[7]){
		  HAL_GPIO_WritePin(LED8_GPIO_Port, LED8_Pin, 1);
		}else{
		  HAL_GPIO_WritePin(LED8_GPIO_Port, LED8_Pin, 0);
		}
	}
}

/* USER CODE END 0 */
/* USER CODE BEGIN 2 */
 //캔통신 시작~
 Can_Set();
 /* USER CODE END 2 */&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;br /&gt;4.예제3번과&amp;nbsp;유사하지만&amp;nbsp;CAN데이터를&amp;nbsp;2개만&amp;nbsp;보내서,&amp;nbsp;첫번째&amp;nbsp;바이트가&amp;nbsp;LED번호,&amp;nbsp;두번째&amp;nbsp;바이트가&amp;nbsp;0이면&amp;nbsp;OFF,&amp;nbsp;1이면&amp;nbsp;ON인&amp;nbsp;스타일로&amp;nbsp;접근하시오!(번호&amp;nbsp;8이면&amp;nbsp;전체를&amp;nbsp;ON/OFF)&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;04.PNG&quot; data-origin-width=&quot;921&quot; data-origin-height=&quot;651&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/tzDwC/dJMcafyD1qK/5iqdBFZjkPDKXjWKEsbXk0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/tzDwC/dJMcafyD1qK/5iqdBFZjkPDKXjWKEsbXk0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/tzDwC/dJMcafyD1qK/5iqdBFZjkPDKXjWKEsbXk0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FtzDwC%2FdJMcafyD1qK%2F5iqdBFZjkPDKXjWKEsbXk0%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;921&quot; height=&quot;651&quot; data-filename=&quot;04.PNG&quot; data-origin-width=&quot;921&quot; data-origin-height=&quot;651&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;pre id=&quot;code_1769435905254&quot; class=&quot;cpp&quot; data-ke-language=&quot;cpp&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;/* USER CODE BEGIN 0 */
//CAN통신할때 필요한 변수와 구조체
CAN_FilterTypeDef sFilterConfig;
CAN_TxHeaderTypeDef TxMessage;
CAN_RxHeaderTypeDef RxMessage;
uint8_t               TxData[8];
uint8_t               RxData[8];
uint32_t              TxMailbox;
//로그출력용 변수
uint8_t tx_buff[50];
void Can_Set(){
	sFilterConfig.FilterBank= 0;
	sFilterConfig.FilterMode= CAN_FILTERMODE_IDMASK;
	sFilterConfig.FilterScale= CAN_FILTERSCALE_32BIT;
	sFilterConfig.FilterIdHigh= 0x0000;
	sFilterConfig.FilterIdLow= 0x0000;
	sFilterConfig.FilterMaskIdHigh= 0x0000;
	sFilterConfig.FilterMaskIdLow= 0x0000;
	sFilterConfig.FilterFIFOAssignment= CAN_RX_FIFO0;
	sFilterConfig.FilterActivation= ENABLE;
	sFilterConfig.SlaveStartFilterBank = 14;
	HAL_CAN_ConfigFilter(&amp;amp;hcan, &amp;amp;sFilterConfig);
	HAL_CAN_ActivateNotification(&amp;amp;hcan, CAN_IT_RX_FIFO0_MSG_PENDING);
	HAL_CAN_Start(&amp;amp;hcan);
}

//CAN수신부
void HAL_CAN_RxFifo0MsgPendingCallback(CAN_HandleTypeDef *hcan1)
{
	HAL_CAN_GetRxMessage(hcan1, CAN_RX_FIFO0, &amp;amp;RxMessage, RxData);
	if(RxMessage.RTR == CAN_RTR_DATA &amp;amp;&amp;amp; RxMessage.IDE == CAN_ID_STD){
		//LED 8개가 제어됨!
		if(RxMessage.DLC == 2){
			//RxData[0] LED 번호
			//RxData[1] LED 작동명령
			if(RxData[0] == 0){
			  HAL_GPIO_WritePin(LED1_GPIO_Port, LED1_Pin, RxData[1]);
			}else if(RxData[0] == 1){
			  HAL_GPIO_WritePin(LED2_GPIO_Port, LED2_Pin, RxData[1]);
			}else if(RxData[0] == 2){
			  HAL_GPIO_WritePin(LED3_GPIO_Port, LED3_Pin, RxData[1]);
			}else if(RxData[0] == 3){
			  HAL_GPIO_WritePin(LED4_GPIO_Port, LED4_Pin, RxData[1]);
			}else if(RxData[0] == 4){
			  HAL_GPIO_WritePin(LED5_GPIO_Port, LED5_Pin, RxData[1]);
			}else if(RxData[0] == 5){
			  HAL_GPIO_WritePin(LED6_GPIO_Port, LED6_Pin, RxData[1]);
			}else if(RxData[0] == 6){
			  HAL_GPIO_WritePin(LED7_GPIO_Port, LED7_Pin, RxData[1]);
			}else if(RxData[0] == 7){
			  HAL_GPIO_WritePin(LED8_GPIO_Port, LED8_Pin, RxData[1]);


			}else if(RxData[0] == 8){
			  //전체 일괄제어
			  HAL_GPIO_WritePin(LED1_GPIO_Port, LED1_Pin, RxData[1]);
			  HAL_GPIO_WritePin(LED2_GPIO_Port, LED2_Pin, RxData[1]);
			  HAL_GPIO_WritePin(LED3_GPIO_Port, LED3_Pin, RxData[1]);
			  HAL_GPIO_WritePin(LED4_GPIO_Port, LED4_Pin, RxData[1]);
			  HAL_GPIO_WritePin(LED5_GPIO_Port, LED5_Pin, RxData[1]);
			  HAL_GPIO_WritePin(LED6_GPIO_Port, LED6_Pin, RxData[1]);
			  HAL_GPIO_WritePin(LED7_GPIO_Port, LED7_Pin, RxData[1]);
			  HAL_GPIO_WritePin(LED8_GPIO_Port, LED8_Pin, RxData[1]);
			}
		}
	}
}

/* USER CODE END 0 */
/* USER CODE BEGIN 2 */
 //캔통신 시작~
 Can_Set();
 /* USER CODE END 2 */&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;br /&gt;5.녹칸다의 STM32쉴드에 PB11에 서보모터(SG90)을 연결하고 CAN통신 메시지를 1바이트 범위로 0~180의 값을 전송해서 서보모터의 각도를 제어하시오!&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;05.PNG&quot; data-origin-width=&quot;986&quot; data-origin-height=&quot;646&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/JTGkc/dJMcadU47lz/wrVsxejo1lY06Re41HV7kK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/JTGkc/dJMcadU47lz/wrVsxejo1lY06Re41HV7kK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/JTGkc/dJMcadU47lz/wrVsxejo1lY06Re41HV7kK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FJTGkc%2FdJMcadU47lz%2FwrVsxejo1lY06Re41HV7kK%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;986&quot; height=&quot;646&quot; data-filename=&quot;05.PNG&quot; data-origin-width=&quot;986&quot; data-origin-height=&quot;646&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;pre id=&quot;code_1769435915708&quot; class=&quot;cpp&quot; data-ke-language=&quot;cpp&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;/* USER CODE BEGIN 0 */
//CAN통신할때 필요한 변수와 구조체
CAN_FilterTypeDef sFilterConfig;
CAN_TxHeaderTypeDef TxMessage;
CAN_RxHeaderTypeDef RxMessage;
uint8_t               TxData[8];
uint8_t               RxData[8];
uint32_t              TxMailbox;
//로그출력용 변수
uint8_t tx_buff[50];
void set_servo(uint8_t degree){
	TIM2-&amp;gt;CCR4 = (uint32_t)(600+(2400-600)*degree/180.0);
}
void Can_Set(){
	sFilterConfig.FilterBank= 0;
	sFilterConfig.FilterMode= CAN_FILTERMODE_IDMASK;
	sFilterConfig.FilterScale= CAN_FILTERSCALE_32BIT;
	sFilterConfig.FilterIdHigh= 0x0000;
	sFilterConfig.FilterIdLow= 0x0000;
	sFilterConfig.FilterMaskIdHigh= 0x0000;
	sFilterConfig.FilterMaskIdLow= 0x0000;
	sFilterConfig.FilterFIFOAssignment= CAN_RX_FIFO0;
	sFilterConfig.FilterActivation= ENABLE;
	sFilterConfig.SlaveStartFilterBank = 14;
	HAL_CAN_ConfigFilter(&amp;amp;hcan, &amp;amp;sFilterConfig);
	HAL_CAN_ActivateNotification(&amp;amp;hcan, CAN_IT_RX_FIFO0_MSG_PENDING);
	HAL_CAN_Start(&amp;amp;hcan);
}

//CAN수신부
void HAL_CAN_RxFifo0MsgPendingCallback(CAN_HandleTypeDef *hcan1)
{
	HAL_CAN_GetRxMessage(hcan1, CAN_RX_FIFO0, &amp;amp;RxMessage, RxData);
	if(RxMessage.RTR == CAN_RTR_DATA &amp;amp;&amp;amp; RxMessage.IDE == CAN_ID_STD){
		//LED 8개가 제어됨!
		if(RxMessage.DLC == 1){
			//RxData[0] 서보모터의각도 0~180
			if(RxData[0] &amp;gt; 180) RxData[0] = 180;
			set_servo(RxData[0]);
		}
	}
}
/* USER CODE END 0 */

//캔통신 시작~
 Can_Set();
 HAL_TIM_PWM_Start(&amp;amp;htim2,TIM_CHANNEL_4);
 /* USER CODE END 2 */&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;br /&gt;6.이번에는&amp;nbsp;STM32에&amp;nbsp;붙어있는&amp;nbsp;버튼&amp;nbsp;8개가&amp;nbsp;있는데,&amp;nbsp;8바이트의&amp;nbsp;정보로&amp;nbsp;각버튼이&amp;nbsp;눌려지면&amp;nbsp;1,&amp;nbsp;안눌려지면&amp;nbsp;0의&amp;nbsp;값을&amp;nbsp;CAN메시지로&amp;nbsp;송신하시오!&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;06.PNG&quot; data-origin-width=&quot;926&quot; data-origin-height=&quot;614&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bhmgQa/dJMcadU47lE/R2SUcU3eoy2rFjKiArIU1k/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bhmgQa/dJMcadU47lE/R2SUcU3eoy2rFjKiArIU1k/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bhmgQa/dJMcadU47lE/R2SUcU3eoy2rFjKiArIU1k/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbhmgQa%2FdJMcadU47lE%2FR2SUcU3eoy2rFjKiArIU1k%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;926&quot; height=&quot;614&quot; data-filename=&quot;06.PNG&quot; data-origin-width=&quot;926&quot; data-origin-height=&quot;614&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;pre id=&quot;code_1769435929171&quot; class=&quot;cpp&quot; data-ke-language=&quot;cpp&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;/* USER CODE BEGIN 0 */
//CAN통신할때 필요한 변수와 구조체
CAN_FilterTypeDef sFilterConfig;
CAN_TxHeaderTypeDef TxMessage;
CAN_RxHeaderTypeDef RxMessage;
uint8_t               TxData[8];
uint8_t               RxData[8];
uint32_t              TxMailbox;
//로그출력용 변수
uint8_t tx_buff[50];
void Can_Set(){
	sFilterConfig.FilterBank= 0;
	sFilterConfig.FilterMode= CAN_FILTERMODE_IDMASK;
	sFilterConfig.FilterScale= CAN_FILTERSCALE_32BIT;
	sFilterConfig.FilterIdHigh= 0x0000;
	sFilterConfig.FilterIdLow= 0x0000;
	sFilterConfig.FilterMaskIdHigh= 0x0000;
	sFilterConfig.FilterMaskIdLow= 0x0000;
	sFilterConfig.FilterFIFOAssignment= CAN_RX_FIFO0;
	sFilterConfig.FilterActivation= ENABLE;
	sFilterConfig.SlaveStartFilterBank = 14;
	HAL_CAN_ConfigFilter(&amp;amp;hcan, &amp;amp;sFilterConfig);
	HAL_CAN_ActivateNotification(&amp;amp;hcan, CAN_IT_RX_FIFO0_MSG_PENDING);
	HAL_CAN_Start(&amp;amp;hcan);
}
//CAN수신부
void HAL_CAN_RxFifo0MsgPendingCallback(CAN_HandleTypeDef *hcan1)
{
	HAL_CAN_GetRxMessage(hcan1, CAN_RX_FIFO0, &amp;amp;RxMessage, RxData);
}
/* USER CODE END 0 */

/* USER CODE BEGIN 2 */
 //캔통신 시작~
 Can_Set();
 /* USER CODE END 2 */
while (1)
 {
	  //0.1초간격으로 8byte array에 버튼의 눌려짐 상태를 넣어서 송신한다!
	  TxMessage.DLC = 8; //데이터길이
	  TxMessage.ExtId = 0;
	  TxMessage.IDE = CAN_ID_STD;
	  TxMessage.RTR = CAN_RTR_DATA;
	  TxMessage.StdId = 0x123; //0x000 ~ 0x7FF
	  TxMessage.TransmitGlobalTime = DISABLE;
	  TxData[0] = !HAL_GPIO_ReadPin(BTN1_GPIO_Port, BTN1_Pin);
	  TxData[1] = !HAL_GPIO_ReadPin(BTN2_GPIO_Port, BTN2_Pin);
	  TxData[2] = !HAL_GPIO_ReadPin(BTN3_GPIO_Port, BTN3_Pin);
	  TxData[3] = !HAL_GPIO_ReadPin(BTN4_GPIO_Port, BTN4_Pin);
	  TxData[4] = !HAL_GPIO_ReadPin(BTN5_GPIO_Port, BTN5_Pin);
	  TxData[5] = !HAL_GPIO_ReadPin(BTN6_GPIO_Port, BTN6_Pin);
	  TxData[6] = !HAL_GPIO_ReadPin(BTN7_GPIO_Port, BTN7_Pin);
	  TxData[7] = !HAL_GPIO_ReadPin(BTN8_GPIO_Port, BTN8_Pin);
	  HAL_CAN_AddTxMessage(&amp;amp;hcan, &amp;amp;TxMessage, TxData, &amp;amp;TxMailbox);
	  HAL_Delay(100);
   /* USER CODE END WHILE */
   /* USER CODE BEGIN 3 */
 }&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;br /&gt;7.버튼1~버튼8까지있을때&amp;nbsp;버튼1을&amp;nbsp;최하위bit로&amp;nbsp;생각하고&amp;nbsp;8bit로&amp;nbsp;계산해서&amp;nbsp;can메시지를&amp;nbsp;1바이트&amp;nbsp;전송하시오!&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;07.PNG&quot; data-origin-width=&quot;978&quot; data-origin-height=&quot;614&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cqX9mS/dJMcadU47l6/3EhyqKEEHwX3d04kDdh2a0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cqX9mS/dJMcadU47l6/3EhyqKEEHwX3d04kDdh2a0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cqX9mS/dJMcadU47l6/3EhyqKEEHwX3d04kDdh2a0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FcqX9mS%2FdJMcadU47l6%2F3EhyqKEEHwX3d04kDdh2a0%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;978&quot; height=&quot;614&quot; data-filename=&quot;07.PNG&quot; data-origin-width=&quot;978&quot; data-origin-height=&quot;614&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;pre id=&quot;code_1769435946871&quot; class=&quot;cpp&quot; data-ke-language=&quot;cpp&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;/* USER CODE BEGIN 0 */
//CAN통신할때 필요한 변수와 구조체
CAN_FilterTypeDef sFilterConfig;
CAN_TxHeaderTypeDef TxMessage;
CAN_RxHeaderTypeDef RxMessage;
uint8_t               TxData[8];
uint8_t               RxData[8];
uint32_t              TxMailbox;
//로그출력용 변수
uint8_t tx_buff[50];
void Can_Set(){
	sFilterConfig.FilterBank= 0;
	sFilterConfig.FilterMode= CAN_FILTERMODE_IDMASK;
	sFilterConfig.FilterScale= CAN_FILTERSCALE_32BIT;
	sFilterConfig.FilterIdHigh= 0x0000;
	sFilterConfig.FilterIdLow= 0x0000;
	sFilterConfig.FilterMaskIdHigh= 0x0000;
	sFilterConfig.FilterMaskIdLow= 0x0000;
	sFilterConfig.FilterFIFOAssignment= CAN_RX_FIFO0;
	sFilterConfig.FilterActivation= ENABLE;
	sFilterConfig.SlaveStartFilterBank = 14;
	HAL_CAN_ConfigFilter(&amp;amp;hcan, &amp;amp;sFilterConfig);
	HAL_CAN_ActivateNotification(&amp;amp;hcan, CAN_IT_RX_FIFO0_MSG_PENDING);
	HAL_CAN_Start(&amp;amp;hcan);
}
//CAN수신부
void HAL_CAN_RxFifo0MsgPendingCallback(CAN_HandleTypeDef *hcan1)
{
	HAL_CAN_GetRxMessage(hcan1, CAN_RX_FIFO0, &amp;amp;RxMessage, RxData);
}
/* USER CODE END 0 */

/* USER CODE BEGIN 2 */
 //캔통신 시작~
 Can_Set();
 GPIO_TypeDef * myport[] = {BTN1_GPIO_Port,BTN2_GPIO_Port,BTN3_GPIO_Port,BTN4_GPIO_Port,BTN5_GPIO_Port,BTN6_GPIO_Port,BTN7_GPIO_Port,BTN8_GPIO_Port};
 uint16_t mypin[] = {BTN1_Pin,BTN2_Pin,BTN3_Pin,BTN4_Pin,BTN5_Pin,BTN6_Pin,BTN7_Pin,BTN8_Pin};
 /* USER CODE END 2 */
 /* Infinite loop */
 /* USER CODE BEGIN WHILE */
 while (1)
 {
	  //0.1초간격으로 1byte 버튼의 눌려짐 상태를 bit연산으로 송신한다!
	  TxMessage.DLC = 1; //데이터길이
	  TxMessage.ExtId = 0;
	  TxMessage.IDE = CAN_ID_STD;
	  TxMessage.RTR = CAN_RTR_DATA;
	  TxMessage.StdId = 0x123; //0x000 ~ 0x7FF
	  TxMessage.TransmitGlobalTime = DISABLE;
	  TxData[0] = 0;
	  for(int i = 0;i&amp;lt;8;i++){
		  TxData[0] |= (!HAL_GPIO_ReadPin(myport[i], mypin[i]) &amp;lt;&amp;lt; i);
	  }
	  HAL_CAN_AddTxMessage(&amp;amp;hcan, &amp;amp;TxMessage, TxData, &amp;amp;TxMailbox);
	  HAL_Delay(100);
   /* USER CODE END WHILE */
   /* USER CODE BEGIN 3 */
 }&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;br /&gt;8.버튼1을&amp;nbsp;누르면&amp;nbsp;0~255범위에서&amp;nbsp;숫자가&amp;nbsp;1씩&amp;nbsp;업카운트된다!&amp;nbsp;버튼2를&amp;nbsp;누르면&amp;nbsp;1씩&amp;nbsp;다운카운트된다!&amp;nbsp;그리고&amp;nbsp;버튼3을&amp;nbsp;누르면&amp;nbsp;0으로&amp;nbsp;초기화된다!&amp;nbsp;이&amp;nbsp;카운터값을&amp;nbsp;버튼이&amp;nbsp;눌려지는&amp;nbsp;타이밍에&amp;nbsp;can통신으로&amp;nbsp;1바이트&amp;nbsp;전송하시오!&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;08.PNG&quot; data-origin-width=&quot;1000&quot; data-origin-height=&quot;631&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/b63RLB/dJMcaac2iVB/cshss3tOG4YkkAtWtbKXSk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/b63RLB/dJMcaac2iVB/cshss3tOG4YkkAtWtbKXSk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/b63RLB/dJMcaac2iVB/cshss3tOG4YkkAtWtbKXSk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fb63RLB%2FdJMcaac2iVB%2Fcshss3tOG4YkkAtWtbKXSk%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;1000&quot; height=&quot;631&quot; data-filename=&quot;08.PNG&quot; data-origin-width=&quot;1000&quot; data-origin-height=&quot;631&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;pre id=&quot;code_1769435959681&quot; class=&quot;cpp&quot; data-ke-language=&quot;cpp&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;/* USER CODE BEGIN 0 */
//CAN통신할때 필요한 변수와 구조체
CAN_FilterTypeDef sFilterConfig;
CAN_TxHeaderTypeDef TxMessage;
CAN_RxHeaderTypeDef RxMessage;
uint8_t               TxData[8];
uint8_t               RxData[8];
uint32_t              TxMailbox;
//로그출력용 변수
uint8_t tx_buff[50];
void Can_Set(){
	sFilterConfig.FilterBank= 0;
	sFilterConfig.FilterMode= CAN_FILTERMODE_IDMASK;
	sFilterConfig.FilterScale= CAN_FILTERSCALE_32BIT;
	sFilterConfig.FilterIdHigh= 0x0000;
	sFilterConfig.FilterIdLow= 0x0000;
	sFilterConfig.FilterMaskIdHigh= 0x0000;
	sFilterConfig.FilterMaskIdLow= 0x0000;
	sFilterConfig.FilterFIFOAssignment= CAN_RX_FIFO0;
	sFilterConfig.FilterActivation= ENABLE;
	sFilterConfig.SlaveStartFilterBank = 14;
	HAL_CAN_ConfigFilter(&amp;amp;hcan, &amp;amp;sFilterConfig);
	HAL_CAN_ActivateNotification(&amp;amp;hcan, CAN_IT_RX_FIFO0_MSG_PENDING);
	HAL_CAN_Start(&amp;amp;hcan);
}
//CAN수신부
void HAL_CAN_RxFifo0MsgPendingCallback(CAN_HandleTypeDef *hcan1)
{
	HAL_CAN_GetRxMessage(hcan1, CAN_RX_FIFO0, &amp;amp;RxMessage, RxData);
}

int cnt = 0;
void send_can_msg(){
	TxMessage.DLC = 1; //데이터길이
   TxMessage.ExtId = 0;
   TxMessage.IDE = CAN_ID_STD;
   TxMessage.RTR = CAN_RTR_DATA;
   TxMessage.StdId = 0x123; //0x000 ~ 0x7FF
   TxMessage.TransmitGlobalTime = DISABLE;
   TxData[0] = cnt;
   HAL_CAN_AddTxMessage(&amp;amp;hcan, &amp;amp;TxMessage, TxData, &amp;amp;TxMailbox);
}
/* USER CODE END 0 */
/* USER CODE BEGIN 2 */
 //캔통신 시작~
 Can_Set();
 /* USER CODE END 2 */
 while (1)
 {
	  if(HAL_GPIO_ReadPin(BTN1_GPIO_Port, BTN1_Pin) == 0){
		  cnt++;
		  if(cnt &amp;gt; 255) cnt = 255;
		  send_can_msg();
		  HAL_Delay(200);
	  }
	  if(HAL_GPIO_ReadPin(BTN2_GPIO_Port, BTN2_Pin) == 0){
		  cnt--;
		  if(cnt &amp;lt; 0) cnt = 0;
		  send_can_msg();
		  HAL_Delay(200);
	  }
	  if(HAL_GPIO_ReadPin(BTN3_GPIO_Port, BTN3_Pin) == 0){
		  cnt = 0;
		  send_can_msg();
		  HAL_Delay(200);
	  }
 }&lt;/code&gt;&lt;/pre&gt;</description>
      <category>프로그래밍/STM32</category>
      <author>덕력킹</author>
      <guid isPermaLink="true">https://bota.tistory.com/2471</guid>
      <comments>https://bota.tistory.com/2471#entry2471comment</comments>
      <pubDate>Mon, 26 Jan 2026 23:02:19 +0900</pubDate>
    </item>
    <item>
      <title>[STM32#28] stm32를 modbus rtu 슬레이브(slave)로 C# winform을 마스터(master)로 설정해서 제어하는 방법(4)!(녹칸다 내맘대로 STM32)</title>
      <link>https://bota.tistory.com/2470</link>
      <description>&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;stm32.png&quot; data-origin-width=&quot;1920&quot; data-origin-height=&quot;1080&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bTpV3f/dJMb996eA8d/5pcn62miPZli3HZDpM7lm0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bTpV3f/dJMb996eA8d/5pcn62miPZli3HZDpM7lm0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bTpV3f/dJMb996eA8d/5pcn62miPZli3HZDpM7lm0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbTpV3f%2FdJMb996eA8d%2F5pcn62miPZli3HZDpM7lm0%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;1920&quot; height=&quot;1080&quot; data-filename=&quot;stm32.png&quot; data-origin-width=&quot;1920&quot; data-origin-height=&quot;1080&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/live/YIJnO-q8EEM&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://youtube.com/live/YIJnO-q8EEM&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/watch?v=YIJnO-q8EEM&quot; data-video-thumbnail=&quot;https://scrap.kakaocdn.net/dn/iDdoJ/dJMb86nRyan/nqW9oC0x2FezjEa0IhJ9wK/img.jpg?width=1280&amp;amp;height=720&amp;amp;face=0_0_1280_720,https://scrap.kakaocdn.net/dn/brhryd/dJMb87NQkZ3/MMVRvywWo2o5cKWE8GO91K/img.jpg?width=1280&amp;amp;height=720&amp;amp;face=0_0_1280_720,https://scrap.kakaocdn.net/dn/bk7F8c/dJMb81GRaYC/l7m0bKKdQenK1gxMILSxfk/img.jpg?width=1280&amp;amp;height=720&amp;amp;face=0_0_1280_720&quot; data-video-width=&quot;860&quot; data-video-height=&quot;484&quot; data-video-origin-width=&quot;860&quot; data-video-origin-height=&quot;484&quot; data-ke-mobilestyle=&quot;widthContent&quot; data-video-title=&quot;[STM32#28] stm32를 modbus rtu 슬레이브(slave)로 C# winform을 마스터(master)로 설정해서 제어하는 방법(4)!(&quot; data-original-url=&quot;&quot;&gt;&lt;iframe src=&quot;https://www.youtube.com/embed/YIJnO-q8EEM&quot; width=&quot;860&quot; height=&quot;484&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;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;[STM32#28]&amp;nbsp;stm32를&amp;nbsp;modbus&amp;nbsp;rtu&amp;nbsp;슬레이브(slave)로&amp;nbsp;C#&amp;nbsp;winform을&amp;nbsp;마스터(master)로&amp;nbsp;설정해서&amp;nbsp;제어하는&amp;nbsp;방법(4)!(녹칸다&amp;nbsp;내맘대로&amp;nbsp;STM32) &lt;br /&gt;&lt;br /&gt;심심한녹칸다의&amp;nbsp;내맘대로&amp;nbsp;STM32시리즈이다! &lt;br /&gt;&lt;br /&gt;STM32시리즈의&amp;nbsp;모든&amp;nbsp;자료는&amp;nbsp;구글&amp;nbsp;슬라이드에&amp;nbsp;작성하고&amp;nbsp;모두에게&amp;nbsp;공유되어있음! &lt;br /&gt;&lt;a href=&quot;https://docs.google.com/presentation/d/1myA5iYbjuKsLWLqtRLKAiRfwUwvqB1d1RGjiMIIgp3I/edit?slide=id.g3bace9f0d28_4_189#slide=id.g3bace9f0d28_4_189&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://docs.google.com/presentation/d/1myA5iYbjuKsLWLqtRLKAiRfwUwvqB1d1RGjiMIIgp3I/edit?slide=id.g3bace9f0d28_4_189#slide=id.g3bace9f0d28_4_189&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;read&amp;nbsp;input&amp;nbsp;register부터&amp;nbsp;이어서&amp;nbsp;해보기! &lt;br /&gt;&lt;br /&gt;1.녹칸다의&amp;nbsp;STM32시리즈&amp;nbsp;27-4번예제에서&amp;nbsp;가변저항,&amp;nbsp;CDS,&amp;nbsp;NTC서미스터의&amp;nbsp;값을&amp;nbsp;레지스터에&amp;nbsp;기록하고&amp;nbsp;C#윈폼&amp;nbsp;화면에&amp;nbsp;modbus&amp;nbsp;rtu로&amp;nbsp;읽어와서&amp;nbsp;출력하시오!&amp;nbsp;[참고] &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;-가변저항(12bit),&amp;nbsp;CDS(12bit),&amp;nbsp;ntc서미스터(온도/소수점이있겠지?)&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;01.PNG&quot; data-origin-width=&quot;961&quot; data-origin-height=&quot;576&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/PkwAF/dJMcagYzhAP/VeKmJKOPzvTM6jkGTKnKo0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/PkwAF/dJMcagYzhAP/VeKmJKOPzvTM6jkGTKnKo0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/PkwAF/dJMcagYzhAP/VeKmJKOPzvTM6jkGTKnKo0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FPkwAF%2FdJMcagYzhAP%2FVeKmJKOPzvTM6jkGTKnKo0%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;961&quot; height=&quot;576&quot; data-filename=&quot;01.PNG&quot; data-origin-width=&quot;961&quot; data-origin-height=&quot;576&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;pre id=&quot;code_1768990553354&quot; class=&quot;cpp&quot; data-ke-language=&quot;cpp&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;/* USER CODE BEGIN 0 */
uint16_t cal_crc(uint8_t *data, uint8_t len)
{
  uint16_t crc = 0xFFFF;
  for(uint8_t i = 0; i &amp;lt; len; i++)
  {
      crc ^= data[i];   // LSB부터 XOR
      for(uint8_t j = 0; j &amp;lt; 8; j++)
      {
          if(crc &amp;amp; 0x0001)
          {
              crc &amp;gt;&amp;gt;= 1;
              crc ^= 0xA001;   // Modbus polynomial
          }
          else
          {
              crc &amp;gt;&amp;gt;= 1;
          }
      }
  }
  return crc;
}
#define R1 10000
#define c1 1.009249522e-03
#define c2 2.378405444e-04
#define c3 2.019202697e-07
/* USER CODE END 0 */

/* USER CODE BEGIN 2 */
 uint8_t slave_id = 0x01;
 uint8_t tx_buff[100];
 uint8_t req[50];
 uint8_t res[50];
 //modbus rtu에서 읽기전용 레지스터
 uint16_t r_reg[6] = {0};
 uint32_t t = 0;
 float logR2, R2, T, Tc, Tf;
 uint16_t adc_value0 = 0;
 uint16_t adc_value1 = 0;
 uint16_t adc_value2 = 0;
 /* USER CODE END 2 */

while (1)
 {
	  //100밀리초 간격으로 adc값을 읽어서 레지스터(uint16_t로 된 배열)에 대입한다
	  if(HAL_GetTick() - t &amp;gt;= 100){
		  t = HAL_GetTick();
		  //PA0 ADC1 RANK1
		  HAL_ADC_Start(&amp;amp;hadc1);
		  HAL_ADC_PollForConversion(&amp;amp;hadc1, 100);
		  adc_value0 = HAL_ADC_GetValue(&amp;amp;hadc1); //가변저항
		  //PA1 ADC1 RANK2
		  HAL_ADC_Start(&amp;amp;hadc1);
		  HAL_ADC_PollForConversion(&amp;amp;hadc1, 100);
		  adc_value1 = HAL_ADC_GetValue(&amp;amp;hadc1); //CDS
		  //PA4 ADC1 RANK3
		  HAL_ADC_Start(&amp;amp;hadc1);
		  HAL_ADC_PollForConversion(&amp;amp;hadc1, 100);
		  adc_value2 = HAL_ADC_GetValue(&amp;amp;hadc1); //NTC서미스터
		  //온도계산
		  R2 = R1 * (4095.0 / adc_value2 - 1.0);
		  logR2 = log(R2);
		  T = (1.0 / (c1 + c2*logR2 + c3*logR2*logR2*logR2));
		  Tc = T - 273.15; //온도값
		  //modbus레지스터에 대입
		  r_reg[0] = adc_value0;
		  r_reg[1] = adc_value1;
		  r_reg[2] = (uint16_t)(Tc*100);
	  }
	  //read input register에 대응하는 부분
	  if(HAL_UART_Receive(&amp;amp;huart1, req, 8, 500) == HAL_OK){
		//응답예시데이터
		uint8_t id = req[0];
		//내 id에게 req가 왔을때만 res를 전송한다!
		if(id == slave_id){
			uint8_t fc = req[1];
			if(fc == 0x04){
				//read input register
				uint16_t start_addr = (req[2] &amp;lt;&amp;lt; 8) | req[3];
				uint16_t count = (req[4] &amp;lt;&amp;lt; 8) | req[5];
				uint16_t crc16 = (req[7] &amp;lt;&amp;lt; 8) | req[6];
				//STM32가 CRC16을 계산함!
				uint16_t my_crc16 = cal_crc(req,6);
				if(crc16 == my_crc16){
					sprintf(tx_buff,&quot;id=%02X, fc=%02X, addr=%04X, data=%04X, crc=%04X\n&quot;,id,fc,start_addr,count,crc16);
					HAL_UART_Transmit(&amp;amp;huart2, tx_buff, strlen(tx_buff), 100);
					//마스터가 요구한 워드에 갯수만큼 응답한다!
					//0~2번까지는 자리가 고정이다!
					res[0] = id;
					res[1] = fc;
					res[2] = count * 2; //count는 무조건 1인상태!
					//count == 2
					//반복문
					for(int i = 0;i &amp;lt; count * 2;i++){
					 //i의 값을 2로 나눠서 나머지가 없으면 짝수다!
						  if(i%2 == 0){
							  //짝수
							  res[3+i] = r_reg[start_addr+(i/2)] &amp;gt;&amp;gt; 8; //상위8bit
						  }else{
							  //홀수
							  res[3+i] = r_reg[start_addr+(i/2)] &amp;amp; 0xFF; //하위8bit
						  }
					  }
						//count가 2이라면~ [0,1,2,3,4,5,6] [7,8]
					  //CRC16의 위치는 3+count*2, 4+count*2
					  //CRC16이전의 데이터로 체크섬을 계산한다!
					  uint16_t res_crc16 = cal_crc(res,3+count*2);
					  res[3+count*2] = (res_crc16 &amp;amp; 0xFF);
					  res[4+count*2] = (res_crc16 &amp;gt;&amp;gt; 8);
					  //3+count*2에다가 체크섬 갯수 2개를 더한개 최종보낼 데이터의 길이
					  HAL_UART_Transmit(&amp;amp;huart1, res, 5+count*2, 100);
					  HAL_UART_Transmit(&amp;amp;huart2, &quot;RES DATA = &quot;, 11, 100);
					  for(int i = 0;i&amp;lt;5+count*2;i++){
						  sprintf(tx_buff,&quot;%02X, &quot;,res[i]);
						  HAL_UART_Transmit(&amp;amp;huart2, tx_buff, strlen(tx_buff), 100);
					  }
					  HAL_UART_Transmit(&amp;amp;huart2, &quot;\n&quot;, 1, 100);
				  }else{
					  HAL_UART_Transmit(&amp;amp;huart2, &quot;CRC16 ERROR!\n&quot;, 13, 100);
				  }
			  }
		  }
	  }
	  /*
   /* USER CODE END WHILE */
   /* USER CODE BEGIN 3 */
 }&lt;/code&gt;&lt;/pre&gt;
&lt;pre id=&quot;code_1768990567033&quot; class=&quot;cpp&quot; data-ke-language=&quot;cpp&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;ModbusSerialMaster msm;

        public Form1()
        {
            InitializeComponent();
        }

        private void button1_Click(object sender, EventArgs e)
        {
            //접속버튼 클릭
            serialPort1.PortName = textBox1.Text;
            serialPort1.BaudRate = 9600;
            serialPort1.Open();

            if (serialPort1.IsOpen)
            {
                msm = ModbusSerialMaster.CreateRtu(serialPort1);

                MessageBox.Show(&quot;접속완료&quot;);
            }
            else
            {
                MessageBox.Show(&quot;접속실패&quot;);
            }
        }


        private void button2_Click(object sender, EventArgs e)
        {
            timer1.Start();
        }

        private void timer1_Tick(object sender, EventArgs e)
        {
            //타이머인터럽트가 0.1초마다 뭐하면되는냐?
            //0번지부터 2개를 읽는다!
            ushort[] data = msm.ReadInputRegisters(1, 0, 3);
            textBox4.Text = data[0].ToString(); //가변저항
            textBox2.Text = data[1].ToString(); //CDS
            textBox3.Text = (data[2]/100.0f).ToString(); //온도
        }&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;br /&gt;2.이번에는&amp;nbsp;프로토콜&amp;nbsp;자료를&amp;nbsp;참고해서&amp;nbsp;write&amp;nbsp;multiple&amp;nbsp;coil명령으로&amp;nbsp;STM32쉴드에&amp;nbsp;붙어있는&amp;nbsp;8개의&amp;nbsp;LED를&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-filename=&quot;02.PNG&quot; data-origin-width=&quot;801&quot; data-origin-height=&quot;587&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/dnO3nX/dJMcagRPirD/aKjkkkOKzaylKAbCE86bsk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/dnO3nX/dJMcagRPirD/aKjkkkOKzaylKAbCE86bsk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/dnO3nX/dJMcagRPirD/aKjkkkOKzaylKAbCE86bsk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FdnO3nX%2FdJMcagRPirD%2FaKjkkkOKzaylKAbCE86bsk%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;801&quot; height=&quot;587&quot; data-filename=&quot;02.PNG&quot; data-origin-width=&quot;801&quot; data-origin-height=&quot;587&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;pre id=&quot;code_1768990584530&quot; class=&quot;cpp&quot; data-ke-language=&quot;cpp&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;/* USER CODE BEGIN 0 */
uint16_t cal_crc(uint8_t *data, uint8_t len)
{
  uint16_t crc = 0xFFFF;
  for(uint8_t i = 0; i &amp;lt; len; i++)
  {
      crc ^= data[i];   // LSB부터 XOR
      for(uint8_t j = 0; j &amp;lt; 8; j++)
      {
          if(crc &amp;amp; 0x0001)
          {
              crc &amp;gt;&amp;gt;= 1;
              crc ^= 0xA001;   // Modbus polynomial
          }
          else
          {
              crc &amp;gt;&amp;gt;= 1;
          }
      }
  }
  return crc;
}
/* USER CODE END 0 */

/* USER CODE BEGIN 2 */
 uint8_t slave_id = 0x01;
 uint8_t tx_buff[100];
 uint8_t recv; //1개씩 읽는 변수
 uint8_t pos = 0;
 uint8_t req[50];
 uint8_t res[50];
 //modbus rtu의 write coil
 uint8_t mycoil[8] = {0};
 GPIO_TypeDef *mygroup[] = {GPIOB,GPIOB,GPIOB,GPIOB,GPIOB,GPIOB,GPIOC,GPIOB};
 uint16_t mypin[] = {GPIO_PIN_3,GPIO_PIN_13,GPIO_PIN_5,GPIO_PIN_14,GPIO_PIN_4,GPIO_PIN_15,GPIO_PIN_4,GPIO_PIN_7};
 /* USER CODE END 2 */

while (1)
 {
	  for(int i = 0;i&amp;lt;8;i++){
		  HAL_GPIO_WritePin(mygroup[i], mypin[i], mycoil[i]);
	  }
	  //write multiple coil은 길이가 확정되어있지 않다!
	  if(HAL_UART_Receive(&amp;amp;huart1, &amp;amp;recv, 1, 500) == HAL_OK){
		  pos = 0;
		  req[pos++] = recv;
		  while(HAL_UART_Receive(&amp;amp;huart1, &amp;amp;recv, 1, 100) == HAL_OK){
			  req[pos++] = recv;
		  }
		  uint8_t id = req[0];
		  uint8_t fc = req[1];
		  uint16_t addr = (req[2] &amp;lt;&amp;lt; 8) | req[3];
		  uint16_t qty = (req[4] &amp;lt;&amp;lt; 8) | req[5];
		  uint8_t cnt = req[6];
		  //CRC16의 위치
		  //req 7+cnt개
		  uint16_t crc1 = cal_crc(req,7+cnt);
		  uint16_t crc2 = (req[7+cnt+1] &amp;lt;&amp;lt; 8) |  req[7+cnt];
		  if(crc1 == crc2){
			  //데이터 해석
			  for(int i = 0;i &amp;lt; qty;i++){
				  uint8_t state = (req[7+(i/8)] &amp;gt;&amp;gt; (i%8)) &amp;amp; 0x01;
				  mycoil[i] = state;
				  sprintf(tx_buff,&quot;%d = %d\n&quot;,i,state);
				  HAL_UART_Transmit(&amp;amp;huart2, tx_buff, strlen(tx_buff), 100);
			  }
			  //응답
			  res[0] = req[0];
			  res[1] = req[1];
			  res[2] = req[2];
			  res[3] = req[3];
			  res[4] = req[4];
			  res[5] = req[5];
			  uint16_t crc3 = cal_crc(res,6);
			  res[6] = crc3 &amp;amp; 0x00FF; //crc3의 하위 8bit
			  res[7] = crc3 &amp;gt;&amp;gt; 8; //crc3의 상위 8bit
			  HAL_UART_Transmit(&amp;amp;huart1, res, 8, 100);
		  }
		  /*
		  //흐름이 끊어짐(지금 STM32가 읽은 데이터 갯수는 pos byte)
		  for(int i = 0;i&amp;lt;pos;i++){
			  sprintf(tx_buff,&quot;%02X, &quot;,req[i]);
			  HAL_UART_Transmit(&amp;amp;huart2, tx_buff, strlen(tx_buff), 100);
		  }
		  */
	  }
	  /*
   /* USER CODE END WHILE */
   /* USER CODE BEGIN 3 */
 }&lt;/code&gt;&lt;/pre&gt;
&lt;pre id=&quot;code_1768990596951&quot; class=&quot;cpp&quot; data-ke-language=&quot;cpp&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;ModbusSerialMaster msm;

        public Form1()
        {
            InitializeComponent();
        }

        private void button1_Click(object sender, EventArgs e)
        {
            //접속버튼 클릭
            serialPort1.PortName = textBox1.Text;
            serialPort1.BaudRate = 9600;
            serialPort1.Open();

            if (serialPort1.IsOpen)
            {
                msm = ModbusSerialMaster.CreateRtu(serialPort1);

                MessageBox.Show(&quot;접속완료&quot;);
            }
            else
            {
                MessageBox.Show(&quot;접속실패&quot;);
            }
        }


        private void button2_Click(object sender, EventArgs e)
        {
            timer1.Start();
        }

        private void timer1_Tick(object sender, EventArgs e)
        {
            //타이머인터럽트가 0.1초마다 뭐하면되는냐?
            //0번지부터 2개를 읽는다!
            ushort[] data = msm.ReadInputRegisters(1, 0, 3);
            textBox4.Text = data[0].ToString(); //가변저항
            textBox2.Text = data[1].ToString(); //CDS
            textBox3.Text = (data[2]/100.0f).ToString(); //온도
        }&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;br /&gt;3.이번에는&amp;nbsp;write&amp;nbsp;multiple&amp;nbsp;register명령을&amp;nbsp;stm32에&amp;nbsp;전송해서&amp;nbsp;putty에&amp;nbsp;stm32가&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-filename=&quot;03.PNG&quot; data-origin-width=&quot;865&quot; data-origin-height=&quot;507&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/6yEYj/dJMcagK4ezx/FS2kJHZEPGnKRK7lgoeD81/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/6yEYj/dJMcagK4ezx/FS2kJHZEPGnKRK7lgoeD81/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/6yEYj/dJMcagK4ezx/FS2kJHZEPGnKRK7lgoeD81/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2F6yEYj%2FdJMcagK4ezx%2FFS2kJHZEPGnKRK7lgoeD81%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;865&quot; height=&quot;507&quot; data-filename=&quot;03.PNG&quot; data-origin-width=&quot;865&quot; data-origin-height=&quot;507&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;pre id=&quot;code_1768990612070&quot; class=&quot;cpp&quot; data-ke-language=&quot;cpp&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;/* USER CODE BEGIN 0 */
uint16_t cal_crc(uint8_t *data, uint8_t len)
{
  uint16_t crc = 0xFFFF;
  for(uint8_t i = 0; i &amp;lt; len; i++)
  {
      crc ^= data[i];   // LSB부터 XOR
      for(uint8_t j = 0; j &amp;lt; 8; j++)
      {
          if(crc &amp;amp; 0x0001)
          {
              crc &amp;gt;&amp;gt;= 1;
              crc ^= 0xA001;   // Modbus polynomial
          }
          else
          {
              crc &amp;gt;&amp;gt;= 1;
          }
      }
  }
  return crc;
}
/* USER CODE END 0 */

/* USER CODE BEGIN 2 */
 uint8_t slave_id = 0x01;
 uint8_t tx_buff[100];
 uint8_t recv; //1개씩 읽는 변수
 uint8_t pos = 0;
 uint8_t req[50];
 uint8_t res[50];
 //modbus rtu의 write register
 uint16_t w_reg[10];
 /* USER CODE END 2 */

while (1)
 {
	  //write multiple coil은 길이가 확정되어있지 않다!
	  if(HAL_UART_Receive(&amp;amp;huart1, &amp;amp;recv, 1, 500) == HAL_OK){
		  pos = 0;
		  req[pos++] = recv;
		  while(HAL_UART_Receive(&amp;amp;huart1, &amp;amp;recv, 1, 100) == HAL_OK){
			  req[pos++] = recv;
		  }
		  uint8_t id = req[0];
		  uint8_t fc = req[1];
		  uint16_t addr = (req[2] &amp;lt;&amp;lt; 8) | req[3];
		  uint16_t qty = (req[4] &amp;lt;&amp;lt; 8) | req[5];
		  uint8_t cnt = req[6];
		  for(int i =0;i&amp;lt;cnt;i++){
			  if(i%2 == 0){
				  w_reg[i/2] =  (req[7+i]&amp;lt;&amp;lt;8);
			  }else{
				  w_reg[i/2] = w_reg[i/2] | req[7+i];
			  }
		  }
		  //출력테스트
		  for(int i = 0;i&amp;lt;qty;i++){
			  sprintf(tx_buff,&quot;%d = %d\n&quot;,i,w_reg[i]);
			  HAL_UART_Transmit(&amp;amp;huart2, tx_buff, strlen(tx_buff), 100);
		  }

		  //응답
		  res[0] = req[0];
		  res[1] = req[1];
		  res[2] = req[2];
		  res[3] = req[3];
		  res[4] = req[4];
		  res[5] = req[5];
		  uint16_t crc3 = cal_crc(res,6);
		  res[6] = crc3 &amp;amp; 0x00FF; //crc3의 하위 8bit
		  res[7] = crc3 &amp;gt;&amp;gt; 8; //crc3의 상위 8bit
		  HAL_UART_Transmit(&amp;amp;huart1, res, 8, 100);
	  }
	  /*
   /* USER CODE END WHILE */
   /* USER CODE BEGIN 3 */
 }&lt;/code&gt;&lt;/pre&gt;
&lt;pre id=&quot;code_1768990625549&quot; class=&quot;cpp&quot; data-ke-language=&quot;cpp&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;ModbusSerialMaster msm;

        public Form1()
        {
            InitializeComponent();
        }

        private void button1_Click(object sender, EventArgs e)
        {
            //접속버튼 클릭
            serialPort1.PortName = textBox1.Text;
            serialPort1.BaudRate = 9600;
            serialPort1.Open();

            if (serialPort1.IsOpen)
            {
                msm = ModbusSerialMaster.CreateRtu(serialPort1);

                MessageBox.Show(&quot;접속완료&quot;);
            }
            else
            {
                MessageBox.Show(&quot;접속실패&quot;);
            }
        }


      private void button2_Click(object sender, EventArgs e)
        {
            ushort[] data = new ushort[6];
            data[0] = (ushort)numericUpDown1.Value;
            data[1] = (ushort)numericUpDown2.Value;
            data[2] = (ushort)numericUpDown3.Value;
            data[3] = (ushort)numericUpDown4.Value;
            data[4] = (ushort)numericUpDown5.Value;
            data[5] = (ushort)numericUpDown6.Value;
            try
            {
                msm.WriteMultipleRegisters(1, 0, data);
            }
            catch
            {

            }
            
        }&lt;/code&gt;&lt;/pre&gt;</description>
      <category>프로그래밍/STM32</category>
      <author>덕력킹</author>
      <guid isPermaLink="true">https://bota.tistory.com/2470</guid>
      <comments>https://bota.tistory.com/2470#entry2470comment</comments>
      <pubDate>Wed, 21 Jan 2026 19:18:08 +0900</pubDate>
    </item>
    <item>
      <title>[STM32#27] stm32를 modbus rtu 슬레이브(slave)로 C# winform을 마스터(master)로 설정해서 제어하는 방법(3)!(녹칸다 내맘대로 STM32)</title>
      <link>https://bota.tistory.com/2469</link>
      <description>&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;stm32.png&quot; data-origin-width=&quot;1920&quot; data-origin-height=&quot;1080&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/Q5zZM/dJMcad1Nx44/LgVxczyQws8REyBfbG0qa1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/Q5zZM/dJMcad1Nx44/LgVxczyQws8REyBfbG0qa1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/Q5zZM/dJMcad1Nx44/LgVxczyQws8REyBfbG0qa1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FQ5zZM%2FdJMcad1Nx44%2FLgVxczyQws8REyBfbG0qa1%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;1920&quot; height=&quot;1080&quot; data-filename=&quot;stm32.png&quot; data-origin-width=&quot;1920&quot; data-origin-height=&quot;1080&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/live/5ZRg9t2ga8o&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://youtube.com/live/5ZRg9t2ga8o&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/watch?v=5ZRg9t2ga8o&quot; data-video-thumbnail=&quot;https://scrap.kakaocdn.net/dn/bBi3ij/dJMb9frzibP/kcT982wIp91aAAhNxXyQaK/img.jpg?width=1280&amp;amp;height=720&amp;amp;face=0_0_1280_720,https://scrap.kakaocdn.net/dn/yR3UT/dJMb9iaK0h9/KcmWVvBwyWGOJXUkwVFx7k/img.jpg?width=1280&amp;amp;height=720&amp;amp;face=0_0_1280_720,https://scrap.kakaocdn.net/dn/PZOSa/dJMb9lk00Wl/3MkneQCEOQOm7mON5mYnS0/img.jpg?width=1280&amp;amp;height=720&amp;amp;face=0_0_1280_720&quot; data-video-width=&quot;860&quot; data-video-height=&quot;484&quot; data-video-origin-width=&quot;860&quot; data-video-origin-height=&quot;484&quot; data-ke-mobilestyle=&quot;widthContent&quot; data-video-title=&quot;[STM32#27] stm32를 modbus rtu 슬레이브(slave)로 C# winform을 마스터(master)로 설정해서 제어하는 방법(3)!(&quot; data-original-url=&quot;&quot;&gt;&lt;iframe src=&quot;https://www.youtube.com/embed/5ZRg9t2ga8o&quot; width=&quot;860&quot; height=&quot;484&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;[STM32#27]&amp;nbsp;stm32를&amp;nbsp;modbus&amp;nbsp;rtu&amp;nbsp;슬레이브(slave)로&amp;nbsp;C#&amp;nbsp;winform을&amp;nbsp;마스터(master)로&amp;nbsp;설정해서&amp;nbsp;제어하는&amp;nbsp;방법(3)!(녹칸다&amp;nbsp;내맘대로&amp;nbsp;STM32) &lt;br /&gt;&lt;br /&gt;심심한녹칸다의&amp;nbsp;내맘대로&amp;nbsp;STM32시리즈이다! &lt;br /&gt;&lt;br /&gt;STM32시리즈의&amp;nbsp;모든&amp;nbsp;자료는&amp;nbsp;구글&amp;nbsp;슬라이드에&amp;nbsp;작성하고&amp;nbsp;모두에게&amp;nbsp;공유되어있음! &lt;br /&gt;&lt;a href=&quot;https://docs.google.com/presentation/d/1myA5iYbjuKsLWLqtRLKAiRfwUwvqB1d1RGjiMIIgp3I/edit?slide=id.g3b7a28c0ef6_1_0#slide=id.g3b7a28c0ef6_1_0&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://docs.google.com/presentation/d/1myA5iYbjuKsLWLqtRLKAiRfwUwvqB1d1RGjiMIIgp3I/edit?slide=id.g3b7a28c0ef6_1_0#slide=id.g3b7a28c0ef6_1_0&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;read&amp;nbsp;holding&amp;nbsp;register부터&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;1.녹칸다의&amp;nbsp;STM32&amp;nbsp;26편-6번예제에서&amp;nbsp;C#으로&amp;nbsp;만든&amp;nbsp;modbus&amp;nbsp;rtu마스터가&amp;nbsp;1개의&amp;nbsp;word를&amp;nbsp;read&amp;nbsp;holding&amp;nbsp;register하도록&amp;nbsp;해놓았는데,&amp;nbsp;2개이상도&amp;nbsp;가능하도록&amp;nbsp;수정하시오!&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;01.PNG&quot; data-origin-width=&quot;888&quot; data-origin-height=&quot;548&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bGJdGn/dJMcabpqOsv/pRtJ0KppwU4yEqzWG53pa0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bGJdGn/dJMcabpqOsv/pRtJ0KppwU4yEqzWG53pa0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bGJdGn/dJMcabpqOsv/pRtJ0KppwU4yEqzWG53pa0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbGJdGn%2FdJMcabpqOsv%2FpRtJ0KppwU4yEqzWG53pa0%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;888&quot; height=&quot;548&quot; data-filename=&quot;01.PNG&quot; data-origin-width=&quot;888&quot; data-origin-height=&quot;548&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;pre id=&quot;code_1768831276771&quot; class=&quot;cpp&quot; data-ke-language=&quot;cpp&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;/* USER CODE BEGIN 0 */
uint16_t cal_crc(uint8_t *data, uint8_t len)
{
   uint16_t crc = 0xFFFF;
   for(uint8_t i = 0; i &amp;lt; len; i++)
   {
       crc ^= data[i];   // LSB부터 XOR
       for(uint8_t j = 0; j &amp;lt; 8; j++)
       {
           if(crc &amp;amp; 0x0001)
           {
               crc &amp;gt;&amp;gt;= 1;
               crc ^= 0xA001;   // Modbus polynomial
           }
           else
           {
               crc &amp;gt;&amp;gt;= 1;
           }
       }
   }
   return crc;
}
/* USER CODE END 0 */
/* USER CODE BEGIN 2 */
 uint8_t slave_id = 0x01;
 uint8_t tx_buff[100];
 uint8_t req[8];
 uint8_t res[50];
 uint16_t w_reg[6] = {0}; //6word 정도의 레지스터가 있다고 가정함
 /* USER CODE END 2 */





while (1)
 {
	  //usart1은 RS485통신, usart2는 PC와 통신
	  //usart1으로 수신해서 usart2로 결과를 송신한다!
	  if(HAL_UART_Receive(&amp;amp;huart1, req, 8, 500) == HAL_OK){
		  //응답예시데이터
		  uint8_t id = req[0];
		  //내 id에게 req가 왔을때만 res를 전송한다!
		  if(id == slave_id){
			  uint8_t fc = req[1];
			  if(fc == 0x06){
				  uint16_t reg_addr = (req[2] &amp;lt;&amp;lt; 8) | req[3];
				  uint16_t reg_data = (req[4] &amp;lt;&amp;lt; 8) | req[5];
				  uint16_t crc16 = (req[7] &amp;lt;&amp;lt; 8) | req[6];
				  //STM32가 CRC16을 계산함!
				  uint16_t my_crc16 = cal_crc(req,6);
				  if(crc16 == my_crc16){
					  sprintf(tx_buff,&quot;id=%02X, fc=%02X, addr=%04X, data=%04X, crc=%04X\n&quot;,id,fc,reg_addr,reg_data,crc16);
					  HAL_UART_Transmit(&amp;amp;huart2, tx_buff, strlen(tx_buff), 100);
					  w_reg[reg_addr] = reg_data;
					  //레지스터가 6개 있으니까 6개의 값을 출력한다!
					  sprintf(tx_buff,&quot;w_reg=%d, %d, %d, %d, %d, %d\n&quot;,w_reg[0],w_reg[1],w_reg[2],w_reg[3],w_reg[4],w_reg[5]);
					  HAL_UART_Transmit(&amp;amp;huart2, tx_buff, strlen(tx_buff), 100);
					  //응답은 req를 그대로 응답하면 된다!
					  HAL_UART_Transmit(&amp;amp;huart1, req, 8, 100);
				  }else{
					  HAL_UART_Transmit(&amp;amp;huart2, &quot;CRC16 ERROR!\n&quot;, 13, 100);
				  }

			  }else if(fc == 0x03){
				  //read holding register
				  uint16_t start_addr = (req[2] &amp;lt;&amp;lt; 8) | req[3];
				  uint16_t count = (req[4] &amp;lt;&amp;lt; 8) | req[5];
				  uint16_t crc16 = (req[7] &amp;lt;&amp;lt; 8) | req[6];
				  //STM32가 CRC16을 계산함!
				  uint16_t my_crc16 = cal_crc(req,6);
				  if(crc16 == my_crc16){
					  sprintf(tx_buff,&quot;id=%02X, fc=%02X, addr=%04X, data=%04X, crc=%04X\n&quot;,id,fc,start_addr,count,crc16);
					  HAL_UART_Transmit(&amp;amp;huart2, tx_buff, strlen(tx_buff), 100);
					  //마스터가 요구한 워드에 갯수만큼 응답한다!
					  //0~2번까지는 자리가 고정이다!
					  res[0] = id;
					  res[1] = fc;
					  res[2] = count * 2; //count는 무조건 1인상태!
					  //count == 2
					  //반복문
					  for(int i = 0;i &amp;lt; count * 2;i++){
						  //i의 값을 2로 나눠서 나머지가 없으면 짝수다!
						  if(i%2 == 0){
							  //짝수
							  res[3+i] = w_reg[start_addr+(i/2)] &amp;gt;&amp;gt; 8; //상위8bit
						  }else{
							  //홀수
							  res[3+i] = w_reg[start_addr+(i/2)] &amp;amp; 0xFF; //하위8bit
						  }
					  }

					  //count가 2이라면~ [0,1,2,3,4,5,6] [7,8]
					  //CRC16의 위치는 3+count*2, 4+count*2
					  //CRC16이전의 데이터로 체크섬을 계산한다!
					  uint16_t res_crc16 = cal_crc(res,3+count*2);
					  res[3+count*2] = (res_crc16 &amp;amp; 0xFF);
					  res[4+count*2] = (res_crc16 &amp;gt;&amp;gt; 8);
					  //3+count*2에다가 체크섬 갯수 2개를 더한개 최종보낼 데이터의 길이
					  HAL_UART_Transmit(&amp;amp;huart1, res, 5+count*2, 100);
					  HAL_UART_Transmit(&amp;amp;huart2, &quot;RES DATA = &quot;, 11, 100);
					  for(int i = 0;i&amp;lt;5+count*2;i++){
						  sprintf(tx_buff,&quot;%02X, &quot;,res[i]);
						  HAL_UART_Transmit(&amp;amp;huart2, tx_buff, strlen(tx_buff), 100);
					  }
					  HAL_UART_Transmit(&amp;amp;huart2, &quot;\n&quot;, 1, 100);
				  }else{
					  HAL_UART_Transmit(&amp;amp;huart2, &quot;CRC16 ERROR!\n&quot;, 13, 100);
				  }
			  }
		  }
	  }&lt;/code&gt;&lt;/pre&gt;
&lt;pre id=&quot;code_1768831416474&quot; class=&quot;cpp&quot; data-ke-language=&quot;cpp&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;using Modbus.Device; //네임스페이스를 추가!

//nmodbus4 객체선언(modbus rtu전용)
        ModbusSerialMaster msm;

private void button1_Click(object sender, EventArgs e)
        {
            //접속버튼 클릭
            serialPort1.BaudRate = 9600;
            serialPort1.PortName = textBox1.Text;

            serialPort1.Open();

            if (serialPort1.IsOpen)
            {
                //접속이 완료된 serialport 객체를 라이브러리에게 넘긴다!
                msm = ModbusSerialMaster.CreateRtu(serialPort1);
                MessageBox.Show(&quot;연결완료!&quot;);
            }
        }

        private void button2_Click(object sender, EventArgs e)
        {
            ushort addr = ushort.Parse(textBox2.Text);
            ushort value = ushort.Parse(textBox3.Text);
            msm.WriteSingleRegister(1, addr, value);
        }


        private void button3_Click(object sender, EventArgs e)
        {
            ushort addr = ushort.Parse(textBox4.Text);
            ushort cnt = ushort.Parse(textBox5.Text);
            ushort[] data = msm.ReadHoldingRegisters(1, addr, cnt);

            richTextBox1.Text += &quot;응답데이터=\n&quot;;
            for(int i = 0; i &amp;lt; data.Length; i++)
            {
                richTextBox1.Text += data[i] + &quot;\n&quot;;
            }
        }&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;br /&gt;2.(지금부터&amp;nbsp;새로운예제로&amp;nbsp;구현하기)&amp;nbsp;read&amp;nbsp;holding&amp;nbsp;register를&amp;nbsp;참고해서&amp;nbsp;read&amp;nbsp;input&amp;nbsp;register를&amp;nbsp;구현한다음&amp;nbsp;stm32의&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-filename=&quot;02.PNG&quot; data-origin-width=&quot;1156&quot; data-origin-height=&quot;460&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/ofy3d/dJMcafSUQyL/KjlY8AmtjkPUOBuK8x2Uw0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/ofy3d/dJMcafSUQyL/KjlY8AmtjkPUOBuK8x2Uw0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/ofy3d/dJMcafSUQyL/KjlY8AmtjkPUOBuK8x2Uw0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fofy3d%2FdJMcafSUQyL%2FKjlY8AmtjkPUOBuK8x2Uw0%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;1156&quot; height=&quot;460&quot; data-filename=&quot;02.PNG&quot; data-origin-width=&quot;1156&quot; data-origin-height=&quot;460&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;pre id=&quot;code_1768831298416&quot; class=&quot;cpp&quot; data-ke-language=&quot;cpp&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;/* USER CODE BEGIN 0 */
uint16_t cal_crc(uint8_t *data, uint8_t len)
{
   uint16_t crc = 0xFFFF;
   for(uint8_t i = 0; i &amp;lt; len; i++)
   {
       crc ^= data[i];   // LSB부터 XOR
       for(uint8_t j = 0; j &amp;lt; 8; j++)
       {
           if(crc &amp;amp; 0x0001)
           {
               crc &amp;gt;&amp;gt;= 1;
               crc ^= 0xA001;   // Modbus polynomial
           }
           else
           {
               crc &amp;gt;&amp;gt;= 1;
           }
       }
   }
   return crc;
}
/* USER CODE END 0 */
/* USER CODE BEGIN 2 */
 uint8_t slave_id = 0x01;
 uint8_t tx_buff[100];
 uint8_t req[8];
 uint8_t res[50];
 //
 uint16_t r_reg[6] = {111,222,333,444,555,666}; //dummy data

 /* USER CODE END 2 */





while (1)
 {
	  //usart1은 RS485통신, usart2는 PC와 통신
	 	  //usart1으로 수신해서 usart2로 결과를 송신한다!
	 	  if(HAL_UART_Receive(&amp;amp;huart1, req, 8, 500) == HAL_OK){
	 		  //응답예시데이터
	 		  uint8_t id = req[0];
	 		  //내 id에게 req가 왔을때만 res를 전송한다!
	 		  if(id == slave_id){
	 			  uint8_t fc = req[1];
	 			  if(fc == 0x04){
					  //read input register
					  uint16_t start_addr = (req[2] &amp;lt;&amp;lt; 8) | req[3];
					  uint16_t count = (req[4] &amp;lt;&amp;lt; 8) | req[5];
					  uint16_t crc16 = (req[7] &amp;lt;&amp;lt; 8) | req[6];
					  //STM32가 CRC16을 계산함!
					  uint16_t my_crc16 = cal_crc(req,6);
					  if(crc16 == my_crc16){
						  sprintf(tx_buff,&quot;id=%02X, fc=%02X, addr=%04X, data=%04X, crc=%04X\n&quot;,id,fc,start_addr,count,crc16);
						  HAL_UART_Transmit(&amp;amp;huart2, tx_buff, strlen(tx_buff), 100);
						  //마스터가 요구한 워드에 갯수만큼 응답한다!
						  //0~2번까지는 자리가 고정이다!
						  res[0] = id;
						  res[1] = fc;
						  res[2] = count * 2; //count는 무조건 1인상태!
						  //count == 2
						  //반복문
						  for(int i = 0;i &amp;lt; count * 2;i++){
							  //i의 값을 2로 나눠서 나머지가 없으면 짝수다!
							  if(i%2 == 0){
								  //짝수
								  res[3+i] = r_reg[start_addr+(i/2)] &amp;gt;&amp;gt; 8; //상위8bit
							  }else{
								  //홀수
								  res[3+i] = r_reg[start_addr+(i/2)] &amp;amp; 0xFF; //하위8bit
							  }
						  }
						  //count가 2이라면~ [0,1,2,3,4,5,6] [7,8]
						  //CRC16의 위치는 3+count*2, 4+count*2
						  //CRC16이전의 데이터로 체크섬을 계산한다!
						  uint16_t res_crc16 = cal_crc(res,3+count*2);
						  res[3+count*2] = (res_crc16 &amp;amp; 0xFF);
						  res[4+count*2] = (res_crc16 &amp;gt;&amp;gt; 8);
						  //3+count*2에다가 체크섬 갯수 2개를 더한개 최종보낼 데이터의 길이
						  HAL_UART_Transmit(&amp;amp;huart1, res, 5+count*2, 100);
						  HAL_UART_Transmit(&amp;amp;huart2, &quot;RES DATA = &quot;, 11, 100);
						  for(int i = 0;i&amp;lt;5+count*2;i++){
							  sprintf(tx_buff,&quot;%02X, &quot;,res[i]);
							  HAL_UART_Transmit(&amp;amp;huart2, tx_buff, strlen(tx_buff), 100);
						  }
						  HAL_UART_Transmit(&amp;amp;huart2, &quot;\n&quot;, 1, 100);
					  }else{
						  HAL_UART_Transmit(&amp;amp;huart2, &quot;CRC16 ERROR!\n&quot;, 13, 100);
					  }
				  }
			  }
		  }
   /* USER CODE END WHILE */
   /* USER CODE BEGIN 3 */
 }&lt;/code&gt;&lt;/pre&gt;
&lt;pre id=&quot;code_1768831395812&quot; class=&quot;cpp&quot; data-ke-language=&quot;cpp&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;using Modbus.Device;

ModbusSerialMaster msm;

        public Form1()
        {
            InitializeComponent();
        }

        private void button1_Click(object sender, EventArgs e)
        {
            //접속버튼 클릭
            serialPort1.PortName = textBox1.Text;
            serialPort1.BaudRate = 9600;
            serialPort1.Open();

            if (serialPort1.IsOpen)
            {
                msm = ModbusSerialMaster.CreateRtu(serialPort1);

                MessageBox.Show(&quot;접속완료&quot;);
            }
            else
            {
                MessageBox.Show(&quot;접속실패&quot;);
            }
        }


        private void button2_Click(object sender, EventArgs e)
        {
            ushort addr = ushort.Parse(textBox2.Text);
            ushort cnt = ushort.Parse(textBox3.Text);

            ushort[] data = msm.ReadInputRegisters(1, addr, cnt);

            richTextBox1.Text = &quot;수신데이터=\n&quot;;
            for(int i = 0; i &amp;lt; data.Length; i++)
            {
                richTextBox1.Text += data[i] + &quot;\n&quot;;
            }
        }&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;br /&gt;3.예제2에서&amp;nbsp;만든&amp;nbsp;수신구문은&amp;nbsp;마스터가&amp;nbsp;보낸&amp;nbsp;request를&amp;nbsp;8개가&amp;nbsp;다&amp;nbsp;올때까지&amp;nbsp;기다리는&amp;nbsp;형식이라서&amp;nbsp;blocking이&amp;nbsp;너무&amp;nbsp;심하게&amp;nbsp;걸린다!&amp;nbsp;RTOS를&amp;nbsp;적용하고&amp;nbsp;PB1에&amp;nbsp;연결된&amp;nbsp;버튼을&amp;nbsp;누르면&amp;nbsp;1씩&amp;nbsp;다운카운트되고,&amp;nbsp;PA8에&amp;nbsp;연결된&amp;nbsp;버튼을&amp;nbsp;누르면&amp;nbsp;1씩&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;하시오! &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;-task1&amp;nbsp;:&amp;nbsp;마스터에서&amp;nbsp;modbus&amp;nbsp;rtu명령이&amp;nbsp;오면&amp;nbsp;응답한다 &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;-task2&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-filename=&quot;03.PNG&quot; data-origin-width=&quot;795&quot; data-origin-height=&quot;546&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/5jpiL/dJMcafSUQyR/7BbuVYSpBgjSaQkfCo7ub0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/5jpiL/dJMcafSUQyR/7BbuVYSpBgjSaQkfCo7ub0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/5jpiL/dJMcafSUQyR/7BbuVYSpBgjSaQkfCo7ub0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2F5jpiL%2FdJMcafSUQyR%2F7BbuVYSpBgjSaQkfCo7ub0%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;795&quot; height=&quot;546&quot; data-filename=&quot;03.PNG&quot; data-origin-width=&quot;795&quot; data-origin-height=&quot;546&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;pre id=&quot;code_1768831324621&quot; class=&quot;cpp&quot; data-ke-language=&quot;cpp&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;/* USER CODE BEGIN 0 */
uint16_t cal_crc(uint8_t *data, uint8_t len)
{
  uint16_t crc = 0xFFFF;
  for(uint8_t i = 0; i &amp;lt; len; i++)
  {
      crc ^= data[i];   // LSB부터 XOR
      for(uint8_t j = 0; j &amp;lt; 8; j++)
      {
          if(crc &amp;amp; 0x0001)
          {
              crc &amp;gt;&amp;gt;= 1;
              crc ^= 0xA001;   // Modbus polynomial
          }
          else
          {
              crc &amp;gt;&amp;gt;= 1;
          }
      }
  }
  return crc;
}
//task1과 task2가 동시에 참조하는 메모리
 volatile uint16_t r_reg[6] = {0};
/* USER CODE END 0 */

void StartDefaultTask(void *argument)
{
 /* USER CODE BEGIN 5 */
 uint8_t slave_id = 0x01;
 uint8_t tx_buff[100];
 uint8_t req[50];
 uint8_t res[50];
 /* Infinite loop */
 for(;;)
 {
		  if(HAL_UART_Receive(&amp;amp;huart1, req, 8, 500) == HAL_OK){
			  //응답예시데이터
			  uint8_t id = req[0];
			  //내 id에게 req가 왔을때만 res를 전송한다!
			  if(id == slave_id){
				  uint8_t fc = req[1];
				  if(fc == 0x04){
					  //read input register
					  uint16_t start_addr = (req[2] &amp;lt;&amp;lt; 8) | req[3];
					  uint16_t count = (req[4] &amp;lt;&amp;lt; 8) | req[5];
					  uint16_t crc16 = (req[7] &amp;lt;&amp;lt; 8) | req[6];
					  //STM32가 CRC16을 계산함!
					  uint16_t my_crc16 = cal_crc(req,6);
					  if(crc16 == my_crc16){
						  sprintf(tx_buff,&quot;id=%02X, fc=%02X, addr=%04X, data=%04X, crc=%04X\n&quot;,id,fc,start_addr,count,crc16);
						  HAL_UART_Transmit(&amp;amp;huart2, tx_buff, strlen(tx_buff), 100);
						  //마스터가 요구한 워드에 갯수만큼 응답한다!
						  //0~2번까지는 자리가 고정이다!
						  res[0] = id;
						  res[1] = fc;
						  res[2] = count * 2; //count는 무조건 1인상태!

						  //count == 2
						  //반복문
						  for(int i = 0;i &amp;lt; count * 2;i++){
							  //i의 값을 2로 나눠서 나머지가 없으면 짝수다!
							  if(i%2 == 0){
								  //짝수
								  res[3+i] = r_reg[start_addr+(i/2)] &amp;gt;&amp;gt; 8; //상위8bit
							  }else{
								  //홀수
								  res[3+i] = r_reg[start_addr+(i/2)] &amp;amp; 0xFF; //하위8bit
							  }
						  }
						//count가 2이라면~ [0,1,2,3,4,5,6] [7,8]
					  //CRC16의 위치는 3+count*2, 4+count*2
					  //CRC16이전의 데이터로 체크섬을 계산한다!
					  uint16_t res_crc16 = cal_crc(res,3+count*2);
					  res[3+count*2] = (res_crc16 &amp;amp; 0xFF);
					  res[4+count*2] = (res_crc16 &amp;gt;&amp;gt; 8);
					  //3+count*2에다가 체크섬 갯수 2개를 더한개 최종보낼 데이터의 길이
					  HAL_UART_Transmit(&amp;amp;huart1, res, 5+count*2, 100);
					  HAL_UART_Transmit(&amp;amp;huart2, &quot;RES DATA = &quot;, 11, 100);
					  for(int i = 0;i&amp;lt;5+count*2;i++){
						  sprintf(tx_buff,&quot;%02X, &quot;,res[i]);
						  HAL_UART_Transmit(&amp;amp;huart2, tx_buff, strlen(tx_buff), 100);
					  }
					  HAL_UART_Transmit(&amp;amp;huart2, &quot;\n&quot;, 1, 100);
				  }else{
					  HAL_UART_Transmit(&amp;amp;huart2, &quot;CRC16 ERROR!\n&quot;, 13, 100);
				  }
			  }
		  }
	  }
   osDelay(1);
 }
 /* USER CODE END 5 */
}
void StartTask02(void *argument)
{
 /* USER CODE BEGIN StartTask02 */
 /* Infinite loop */
 for(;;)
 {
	  if(HAL_GPIO_ReadPin(GPIOB, GPIO_PIN_1) == 0){
		  r_reg[0]--;
		  osDelay(200);
	  }
	  if(HAL_GPIO_ReadPin(GPIOA, GPIO_PIN_8) == 0){
		  r_reg[0]++;
		  osDelay(200);
	  }
   osDelay(1); //반드시 있어야함
 }
 /* USER CODE END StartTask02 */
}&lt;/code&gt;&lt;/pre&gt;
&lt;pre id=&quot;code_1768831434796&quot; class=&quot;cpp&quot; data-ke-language=&quot;cpp&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;ModbusSerialMaster msm;

        public Form1()
        {
            InitializeComponent();
        }

        private void button1_Click(object sender, EventArgs e)
        {
            //접속버튼 클릭
            serialPort1.PortName = textBox1.Text;
            serialPort1.BaudRate = 9600;
            serialPort1.Open();

            if (serialPort1.IsOpen)
            {
                msm = ModbusSerialMaster.CreateRtu(serialPort1);

                MessageBox.Show(&quot;접속완료&quot;);
            }
            else
            {
                MessageBox.Show(&quot;접속실패&quot;);
            }
        }


        private void button2_Click(object sender, EventArgs e)
        {
            timer1.Start();
        }

        private void timer1_Tick(object sender, EventArgs e)
        {
            //타이머인터럽트가 0.1초마다 뭐하면되는냐?
            ushort[] data = msm.ReadInputRegisters(1, 0, 1);
            textBox4.Text = ((short)data[0]).ToString();
        }&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;br /&gt;4.녹칸다의 STM32쉴드에 붙어있는 가변저항의 값을 읽기전용 레지스터 1번지에 저장을해서 마스터 화면에 출력하시오!&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;-task1&amp;nbsp;:&amp;nbsp;마스터에서&amp;nbsp;modbus&amp;nbsp;rtu명령이&amp;nbsp;오면&amp;nbsp;응답한다 &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;-task2&amp;nbsp;:&amp;nbsp;버튼을&amp;nbsp;누르면&amp;nbsp;업/다운&amp;nbsp;카운트한다 &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;-task3&amp;nbsp;:&amp;nbsp;ADC값&amp;nbsp;측정하기~&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;04.PNG&quot; data-origin-width=&quot;896&quot; data-origin-height=&quot;445&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cUUbDx/dJMcafSUQy0/uLp4jmGfwI2mrutmMbunkk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cUUbDx/dJMcafSUQy0/uLp4jmGfwI2mrutmMbunkk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cUUbDx/dJMcafSUQy0/uLp4jmGfwI2mrutmMbunkk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FcUUbDx%2FdJMcafSUQy0%2FuLp4jmGfwI2mrutmMbunkk%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;896&quot; height=&quot;445&quot; data-filename=&quot;04.PNG&quot; data-origin-width=&quot;896&quot; data-origin-height=&quot;445&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;pre id=&quot;code_1768831351073&quot; class=&quot;cpp&quot; data-ke-language=&quot;cpp&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;/* USER CODE BEGIN 0 */
uint16_t cal_crc(uint8_t *data, uint8_t len)
{
  uint16_t crc = 0xFFFF;
  for(uint8_t i = 0; i &amp;lt; len; i++)
  {
      crc ^= data[i];   // LSB부터 XOR
      for(uint8_t j = 0; j &amp;lt; 8; j++)
      {
          if(crc &amp;amp; 0x0001)
          {
              crc &amp;gt;&amp;gt;= 1;
              crc ^= 0xA001;   // Modbus polynomial
          }
          else
          {
              crc &amp;gt;&amp;gt;= 1;
          }
      }
  }
  return crc;
}
//task1과 task2가 동시에 참조하는 메모리
 volatile uint16_t r_reg[6] = {0};
/* USER CODE END 0 */

void StartDefaultTask(void *argument)
{
 /* USER CODE BEGIN 5 */
 uint8_t slave_id = 0x01;
 uint8_t tx_buff[100];
 uint8_t req[50];
 uint8_t res[50];
 /* Infinite loop */
 for(;;)
 {
		  if(HAL_UART_Receive(&amp;amp;huart1, req, 8, 500) == HAL_OK){
			  //응답예시데이터
			  uint8_t id = req[0];
			  //내 id에게 req가 왔을때만 res를 전송한다!
			  if(id == slave_id){
				  uint8_t fc = req[1];
				  if(fc == 0x04){
					  //read input register
					  uint16_t start_addr = (req[2] &amp;lt;&amp;lt; 8) | req[3];
					  uint16_t count = (req[4] &amp;lt;&amp;lt; 8) | req[5];
					  uint16_t crc16 = (req[7] &amp;lt;&amp;lt; 8) | req[6];
					  //STM32가 CRC16을 계산함!
					  uint16_t my_crc16 = cal_crc(req,6);
					  if(crc16 == my_crc16){
						  sprintf(tx_buff,&quot;id=%02X, fc=%02X, addr=%04X, data=%04X, crc=%04X\n&quot;,id,fc,start_addr,count,crc16);
						  HAL_UART_Transmit(&amp;amp;huart2, tx_buff, strlen(tx_buff), 100);
						  //마스터가 요구한 워드에 갯수만큼 응답한다!
						  //0~2번까지는 자리가 고정이다!
						  res[0] = id;
						  res[1] = fc;
						  res[2] = count * 2; //count는 무조건 1인상태!

						  //count == 2
						  //반복문
						  for(int i = 0;i &amp;lt; count * 2;i++){
							  //i의 값을 2로 나눠서 나머지가 없으면 짝수다!
							  if(i%2 == 0){
								  //짝수
								  res[3+i] = r_reg[start_addr+(i/2)] &amp;gt;&amp;gt; 8; //상위8bit
							  }else{
								  //홀수
								  res[3+i] = r_reg[start_addr+(i/2)] &amp;amp; 0xFF; //하위8bit
							  }
						  }
						//count가 2이라면~ [0,1,2,3,4,5,6] [7,8]
					  //CRC16의 위치는 3+count*2, 4+count*2
					  //CRC16이전의 데이터로 체크섬을 계산한다!
					  uint16_t res_crc16 = cal_crc(res,3+count*2);
					  res[3+count*2] = (res_crc16 &amp;amp; 0xFF);
					  res[4+count*2] = (res_crc16 &amp;gt;&amp;gt; 8);
					  //3+count*2에다가 체크섬 갯수 2개를 더한개 최종보낼 데이터의 길이
					  HAL_UART_Transmit(&amp;amp;huart1, res, 5+count*2, 100);
					  HAL_UART_Transmit(&amp;amp;huart2, &quot;RES DATA = &quot;, 11, 100);
					  for(int i = 0;i&amp;lt;5+count*2;i++){
						  sprintf(tx_buff,&quot;%02X, &quot;,res[i]);
						  HAL_UART_Transmit(&amp;amp;huart2, tx_buff, strlen(tx_buff), 100);
					  }
					  HAL_UART_Transmit(&amp;amp;huart2, &quot;\n&quot;, 1, 100);
				  }else{
					  HAL_UART_Transmit(&amp;amp;huart2, &quot;CRC16 ERROR!\n&quot;, 13, 100);
				  }
			  }
		  }
	  }
   osDelay(1);
 }
 /* USER CODE END 5 */
}
void StartTask02(void *argument)
{
 /* USER CODE BEGIN StartTask02 */
 /* Infinite loop */
 for(;;)
 {
	  if(HAL_GPIO_ReadPin(GPIOB, GPIO_PIN_1) == 0){
		  r_reg[0]--;
		  osDelay(200);
	  }
	  if(HAL_GPIO_ReadPin(GPIOA, GPIO_PIN_8) == 0){
		  r_reg[0]++;
		  osDelay(200);
	  }
   osDelay(1); //반드시 있어야함
 }
 /* USER CODE END StartTask02 */
}
void StartTask03(void *argument)
{
 /* USER CODE BEGIN StartTask03 */
  HAL_ADC_Start(&amp;amp;hadc1); //딱 한번만 호출
 /* Infinite loop */
 for(;;)
 {
	  if(HAL_ADC_PollForConversion(&amp;amp;hadc1, 10) == HAL_OK)
	  {
		  r_reg[1] = HAL_ADC_GetValue(&amp;amp;hadc1); //0~4095
	  }
	  osDelay(100);
 }
 /* USER CODE END StartTask03 */
}&lt;/code&gt;&lt;/pre&gt;
&lt;pre id=&quot;code_1768831455961&quot; class=&quot;cpp&quot; data-ke-language=&quot;cpp&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;ModbusSerialMaster msm;

        public Form1()
        {
            InitializeComponent();
        }

        private void button1_Click(object sender, EventArgs e)
        {
            //접속버튼 클릭
            serialPort1.PortName = textBox1.Text;
            serialPort1.BaudRate = 9600;
            serialPort1.Open();

            if (serialPort1.IsOpen)
            {
                msm = ModbusSerialMaster.CreateRtu(serialPort1);

                MessageBox.Show(&quot;접속완료&quot;);
            }
            else
            {
                MessageBox.Show(&quot;접속실패&quot;);
            }
        }


        private void button2_Click(object sender, EventArgs e)
        {
            timer1.Start();
        }

        private void timer1_Tick(object sender, EventArgs e)
        {
            //타이머인터럽트가 0.1초마다 뭐하면되는냐?
            //0번지부터 2개를 읽는다!
            ushort[] data = msm.ReadInputRegisters(1, 0, 2);
            textBox4.Text = ((short)data[0]).ToString();
            textBox2.Text = ((short)data[1]).ToString();
        }&lt;/code&gt;&lt;/pre&gt;</description>
      <category>프로그래밍/STM32</category>
      <author>덕력킹</author>
      <guid isPermaLink="true">https://bota.tistory.com/2469</guid>
      <comments>https://bota.tistory.com/2469#entry2469comment</comments>
      <pubDate>Mon, 19 Jan 2026 23:05:46 +0900</pubDate>
    </item>
    <item>
      <title>[STM32#26] stm32를 modbus rtu 슬레이브(slave)로 C# winform을 마스터(master)로 설정해서 제어하는 방법(2)!(녹칸다 내맘대로 STM32)</title>
      <link>https://bota.tistory.com/2468</link>
      <description>&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;stm32.png&quot; data-origin-width=&quot;1920&quot; data-origin-height=&quot;1080&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/u4D1O/dJMcacBNPL5/x5vSgLc6xnFzCkKBJNmUpK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/u4D1O/dJMcacBNPL5/x5vSgLc6xnFzCkKBJNmUpK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/u4D1O/dJMcacBNPL5/x5vSgLc6xnFzCkKBJNmUpK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fu4D1O%2FdJMcacBNPL5%2Fx5vSgLc6xnFzCkKBJNmUpK%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;1920&quot; height=&quot;1080&quot; data-filename=&quot;stm32.png&quot; data-origin-width=&quot;1920&quot; data-origin-height=&quot;1080&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/live/0GP7utrIFTw&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://youtube.com/live/0GP7utrIFTw&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/watch?v=0GP7utrIFTw&quot; data-video-thumbnail=&quot;https://scrap.kakaocdn.net/dn/YTYln/hyZRhTXahZ/Sq7CpLOdsRX35fzuKPGSe1/img.jpg?width=1280&amp;amp;height=720&amp;amp;face=0_0_1280_720,https://scrap.kakaocdn.net/dn/co0npT/hyZRbA2KqN/1hy1Hswfsc53fWdbE6CDak/img.jpg?width=1280&amp;amp;height=720&amp;amp;face=0_0_1280_720,https://scrap.kakaocdn.net/dn/bh3T6s/hyZRrbb1mv/dRModsAlvvVcx3ikX0QCy0/img.jpg?width=1280&amp;amp;height=720&amp;amp;face=0_0_1280_720&quot; data-video-width=&quot;860&quot; data-video-height=&quot;484&quot; data-video-origin-width=&quot;860&quot; data-video-origin-height=&quot;484&quot; data-ke-mobilestyle=&quot;widthContent&quot; data-video-title=&quot;[STM32#26] stm32를 modbus rtu 슬레이브(slave)로 C# winform을 마스터(master)로 설정해서 제어하는 방법(2)!(&quot; data-original-url=&quot;&quot;&gt;&lt;iframe src=&quot;https://www.youtube.com/embed/0GP7utrIFTw&quot; width=&quot;860&quot; height=&quot;484&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;[STM32#26]&amp;nbsp;stm32를&amp;nbsp;modbus&amp;nbsp;rtu&amp;nbsp;슬레이브(slave)로&amp;nbsp;C#&amp;nbsp;winform을&amp;nbsp;마스터(master)로&amp;nbsp;설정해서&amp;nbsp;제어하는&amp;nbsp;방법(2)!(녹칸다&amp;nbsp;내맘대로&amp;nbsp;STM32) &lt;br /&gt;&lt;br /&gt;심심한녹칸다의&amp;nbsp;내맘대로&amp;nbsp;STM32시리즈이다! &lt;br /&gt;&lt;br /&gt;STM32시리즈의&amp;nbsp;모든&amp;nbsp;자료는&amp;nbsp;구글&amp;nbsp;슬라이드에&amp;nbsp;작성하고&amp;nbsp;모두에게&amp;nbsp;공유되어있음! &lt;br /&gt;&lt;a href=&quot;https://docs.google.com/presentation/d/1myA5iYbjuKsLWLqtRLKAiRfwUwvqB1d1RGjiMIIgp3I/edit?slide=id.g3b2751bc412_11_154#slide=id.g3b2751bc412_11_154&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://docs.google.com/presentation/d/1myA5iYbjuKsLWLqtRLKAiRfwUwvqB1d1RGjiMIIgp3I/edit?slide=id.g3b2751bc412_11_154#slide=id.g3b2751bc412_11_154&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;마스터인&amp;nbsp;C#윈폼에서는&amp;nbsp;nmodbus4&amp;nbsp;라이브러리를&amp;nbsp;적용해보도록&amp;nbsp;하자! &lt;br /&gt;&lt;br /&gt;1.예제25편-2에서&amp;nbsp;만든&amp;nbsp;예제를&amp;nbsp;마스터쪽에&amp;nbsp;nmodbus4라이브러리를&amp;nbsp;적용해서&amp;nbsp;stm32가&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-filename=&quot;01.PNG&quot; data-origin-width=&quot;1369&quot; data-origin-height=&quot;602&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bYnP6M/dJMcagKYuec/KAOuQ38JAZ3whn3kV7AuUk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bYnP6M/dJMcagKYuec/KAOuQ38JAZ3whn3kV7AuUk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bYnP6M/dJMcagKYuec/KAOuQ38JAZ3whn3kV7AuUk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbYnP6M%2FdJMcagKYuec%2FKAOuQ38JAZ3whn3kV7AuUk%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;1369&quot; height=&quot;602&quot; data-filename=&quot;01.PNG&quot; data-origin-width=&quot;1369&quot; data-origin-height=&quot;602&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;pre id=&quot;code_1767770427283&quot; class=&quot;cpp&quot; data-ke-language=&quot;cpp&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;/* USER CODE BEGIN 0 */
uint16_t cal_crc(uint8_t *data, uint8_t len)
{
   uint16_t crc = 0xFFFF;
   for(uint8_t i = 0; i &amp;lt; len; i++)
   {
       crc ^= data[i];   // LSB부터 XOR
       for(uint8_t j = 0; j &amp;lt; 8; j++)
       {
           if(crc &amp;amp; 0x0001)
           {
               crc &amp;gt;&amp;gt;= 1;
               crc ^= 0xA001;   // Modbus polynomial
           }
           else
           {
               crc &amp;gt;&amp;gt;= 1;
           }
       }
   }
   return crc;
}
/* USER CODE END 0 */
/* USER CODE BEGIN 2 */
 //녹칸다의 STM32쉴드의 8개의 LED를 배열로 뭉쳐놓은것!
 GPIO_TypeDef *mygroup[] = {GPIOB,GPIOB,GPIOB,GPIOB,GPIOB,GPIOB,GPIOC,GPIOB};
 uint16_t mypin[] = {GPIO_PIN_3,GPIO_PIN_13,GPIO_PIN_5,GPIO_PIN_14,GPIO_PIN_4,GPIO_PIN_15,GPIO_PIN_4,GPIO_PIN_7};
 uint8_t slave_id = 0x01;
 uint8_t tx_buff[100];
 uint8_t req[8];
 /* USER CODE END 2 */

while (1)
 {
	  //usart1은 RS485통신, usart2는 PC와 통신
	  //usart1으로 수신해서 usart2로 결과를 송신한다!
	  if(HAL_UART_Receive(&amp;amp;huart1, req, 8, 500) == HAL_OK){
		  //응답예시데이터
		  uint8_t id = req[0];
		  //내 id에게 req가 왔을때만 res를 전송한다!
		  if(id == slave_id){
			  uint8_t fc = req[1];
			  uint16_t coil_addr = (req[2] &amp;lt;&amp;lt; 8) | req[3];
			  uint16_t coil_data = (req[4] &amp;lt;&amp;lt; 8) | req[5];
			  uint16_t crc16 = (req[7] &amp;lt;&amp;lt; 8) | req[6];
			  //STM32가 CRC16을 계산함!
			  uint16_t my_crc16 = cal_crc(req,6);
			  if(crc16 == my_crc16){
				  sprintf(tx_buff,&quot;id=%02X, fc=%02X, addr=%04X, data=%04X, crc=%04X\n&quot;,id,fc,coil_addr,coil_data,crc16);
				  HAL_UART_Transmit(&amp;amp;huart2, tx_buff, strlen(tx_buff), 100);
				  //write single coil명령어 수행
				  if(coil_data == 0xFF00){
					  //ON
					  HAL_GPIO_WritePin(mygroup[coil_addr], mypin[coil_addr], 1);
				  }else{
					  //OFF
					  HAL_GPIO_WritePin(mygroup[coil_addr], mypin[coil_addr], 0);
				  }
				  //응답전송! 그런데 FC=0x05는 req와 res가 같다!
				  HAL_UART_Transmit(&amp;amp;huart1, req, 8, 100);
			  }else{
				  HAL_UART_Transmit(&amp;amp;huart2, &quot;CRC16 ERROR!\n&quot;, 13, 100);
			  }
		  }
	  }
 }&lt;/code&gt;&lt;/pre&gt;
&lt;pre id=&quot;code_1767770546587&quot; class=&quot;csharp&quot; data-ke-language=&quot;csharp&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;using Modbus.Device; //네임스페이스를 추가!

//nmodbus4 객체선언(modbus rtu전용)
        ModbusSerialMaster msm;

private void button1_Click(object sender, EventArgs e)
        {
            //접속버튼 클릭
            serialPort1.BaudRate = 9600;
            serialPort1.PortName = textBox1.Text;

            serialPort1.Open();

            if (serialPort1.IsOpen)
            {
                //접속이 완료된 serialport 객체를 라이브러리에게 넘긴다!
                msm = ModbusSerialMaster.CreateRtu(serialPort1);
                MessageBox.Show(&quot;연결완료!&quot;);
            }
        }

        private void button2_Click(object sender, EventArgs e)
        {
            //coil 0번을 ON한다!
            msm.WriteSingleCoil(1, 0, true);
        }

        private void button3_Click(object sender, EventArgs e)
        {
            msm.WriteSingleCoil(1, 0, false);
        }

        private void button4_Click(object sender, EventArgs e)
        {
            msm.WriteSingleCoil(1, 1, true);
        }
        private void button5_Click(object sender, EventArgs e)
        {
            msm.WriteSingleCoil(1, 1, false);
        }

        private void button6_Click(object sender, EventArgs e)
        {
            msm.WriteSingleCoil(1, 2, true);
        }

        private void button7_Click(object sender, EventArgs e)
        {
            msm.WriteSingleCoil(1, 2, false);
        }

        private void button8_Click(object sender, EventArgs e)
        {
            msm.WriteSingleCoil(1, 3, true);
        }

        private void button9_Click(object sender, EventArgs e)
        {
            msm.WriteSingleCoil(1, 3, false);
        }

        

        private void button10_Click(object sender, EventArgs e)
        {
            msm.WriteSingleCoil(1, 4, true);
        }

        private void button11_Click(object sender, EventArgs e)
        {
            msm.WriteSingleCoil(1, 4, false);
        }
        private void button12_Click(object sender, EventArgs e)
        {
            msm.WriteSingleCoil(1, 5, true);
        }

        private void button13_Click(object sender, EventArgs e)
        {
            msm.WriteSingleCoil(1, 5, false);
        }

        private void button14_Click(object sender, EventArgs e)
        {
            msm.WriteSingleCoil(1, 6, true);
        }

        private void button15_Click(object sender, EventArgs e)
        {
            msm.WriteSingleCoil(1, 6, false);
        }
        private void button16_Click(object sender, EventArgs e)
        {
            msm.WriteSingleCoil(1, 7, true);
        }
        private void button17_Click(object sender, EventArgs e)
        {
            msm.WriteSingleCoil(1, 7, false);
        }&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;br /&gt;2.예제1에&amp;nbsp;더해서&amp;nbsp;마스터쪽에서&amp;nbsp;readcoil을&amp;nbsp;실행했을때&amp;nbsp;STM32의&amp;nbsp;8개의&amp;nbsp;LED의&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-filename=&quot;02.PNG&quot; data-origin-width=&quot;943&quot; data-origin-height=&quot;608&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/Q5vH9/dJMb9958X4J/9070CXdAMdAXzKmB4UKJI1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/Q5vH9/dJMb9958X4J/9070CXdAMdAXzKmB4UKJI1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/Q5vH9/dJMb9958X4J/9070CXdAMdAXzKmB4UKJI1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FQ5vH9%2FdJMb9958X4J%2F9070CXdAMdAXzKmB4UKJI1%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;943&quot; height=&quot;608&quot; data-filename=&quot;02.PNG&quot; data-origin-width=&quot;943&quot; data-origin-height=&quot;608&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;pre id=&quot;code_1767770453324&quot; class=&quot;cpp&quot; data-ke-language=&quot;cpp&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;/* USER CODE BEGIN 0 */
uint16_t cal_crc(uint8_t *data, uint8_t len)
{
   uint16_t crc = 0xFFFF;
   for(uint8_t i = 0; i &amp;lt; len; i++)
   {
       crc ^= data[i];   // LSB부터 XOR
       for(uint8_t j = 0; j &amp;lt; 8; j++)
       {
           if(crc &amp;amp; 0x0001)
           {
               crc &amp;gt;&amp;gt;= 1;
               crc ^= 0xA001;   // Modbus polynomial
           }
           else
           {
               crc &amp;gt;&amp;gt;= 1;
           }
       }
   }
   return crc;
}
/* USER CODE END 0 */
/* USER CODE BEGIN 2 */
 //녹칸다의 STM32쉴드의 8개의 LED를 배열로 뭉쳐놓은것!
 GPIO_TypeDef *mygroup[] = {GPIOB,GPIOB,GPIOB,GPIOB,GPIOB,GPIOB,GPIOC,GPIOB};
 uint16_t mypin[] = {GPIO_PIN_3,GPIO_PIN_13,GPIO_PIN_5,GPIO_PIN_14,GPIO_PIN_4,GPIO_PIN_15,GPIO_PIN_4,GPIO_PIN_7};
 uint8_t slave_id = 0x01;
 uint8_t tx_buff[100];
 uint8_t req[8];
 uint8_t res[6]; //read coils 전용
 uint8_t write_coil[1];
 /* USER CODE END 2 */


while (1)
 {
	  //usart1은 RS485통신, usart2는 PC와 통신
	  //usart1으로 수신해서 usart2로 결과를 송신한다!
	  if(HAL_UART_Receive(&amp;amp;huart1, req, 8, 500) == HAL_OK){
		  //응답예시데이터
		  uint8_t id = req[0];
		  //내 id에게 req가 왔을때만 res를 전송한다!
		  if(id == slave_id){
			  uint8_t fc = req[1];
			  if(fc == 0x01){
				  //read coils
				  uint16_t start_addr = (req[2] &amp;lt;&amp;lt; 8) | req[3];
				  uint16_t count = (req[4] &amp;lt;&amp;lt; 8) | req[5];
				  uint16_t crc16 = (req[7] &amp;lt;&amp;lt; 8) | req[6];
				  //STM32가 CRC16을 계산함!
				  uint16_t my_crc16 = cal_crc(req,6);
				  if(crc16 == my_crc16){
					  //read coil 응답데이터 만들기
					  //write_coil[0]여기에 순서에 맞게 bit 상태를 넣으면 됨!
					  write_coil[0] = 0;
					  for(int i = 0; i &amp;lt; count; i++)
					  {
					      if(mygroup[i]-&amp;gt;ODR &amp;amp; mypin[i])
					          write_coil[0] |= (1 &amp;lt;&amp;lt; i);
					  }
					  sprintf(tx_buff,&quot;id=%02X, fc=%02X, start_addr=%04X, cnt=%04X, crc=%04X, data=%d\n&quot;,id,fc,start_addr,count,crc16,write_coil[0]);
					  HAL_UART_Transmit(&amp;amp;huart2, tx_buff, strlen(tx_buff), 100);
					  res[0] = id;
					  res[1] = fc;
					  res[2] = 1; //응답데이터는 1byte이다!
					  res[3] = write_coil[0];
					  uint16_t res_crc = cal_crc(res,4);

					  res[4] = res_crc &amp;amp; 0xFF; //res_crc의 하위8bit
					  res[5] = res_crc &amp;gt;&amp;gt; 8; //res_crc의 상위8bit
					  HAL_UART_Transmit(&amp;amp;huart1, res, 6, 100);
				  }else{
					  HAL_UART_Transmit(&amp;amp;huart2, &quot;CRC16 ERROR!\n&quot;, 13, 100);
				  }
			  }else if(fc == 0x05){
				  //write single coil
				  uint16_t coil_addr = (req[2] &amp;lt;&amp;lt; 8) | req[3];
				  uint16_t coil_data = (req[4] &amp;lt;&amp;lt; 8) | req[5];
				  uint16_t crc16 = (req[7] &amp;lt;&amp;lt; 8) | req[6];
				  //STM32가 CRC16을 계산함!
				  uint16_t my_crc16 = cal_crc(req,6);
				  if(crc16 == my_crc16){
					  sprintf(tx_buff,&quot;id=%02X, fc=%02X, addr=%04X, data=%04X, crc=%04X\n&quot;,id,fc,coil_addr,coil_data,crc16);
					  HAL_UART_Transmit(&amp;amp;huart2, tx_buff, strlen(tx_buff), 100);
					  //write single coil명령어 수행
					  if(coil_data == 0xFF00){
						  //ON
						  HAL_GPIO_WritePin(mygroup[coil_addr], mypin[coil_addr], 1);
					  }else{
						  //OFF
						  HAL_GPIO_WritePin(mygroup[coil_addr], mypin[coil_addr], 0);
					  }
					  //응답전송! 그런데 FC=0x05는 req와 res가 같다!
					  HAL_UART_Transmit(&amp;amp;huart1, req, 8, 100);
				  }else{
					  HAL_UART_Transmit(&amp;amp;huart2, &quot;CRC16 ERROR!\n&quot;, 13, 100);
				  }
			  }
		  }
	  }
   /* USER CODE END WHILE */
   /* USER CODE BEGIN 3 */
 }&lt;/code&gt;&lt;/pre&gt;
&lt;pre id=&quot;code_1767770570550&quot; class=&quot;csharp&quot; data-ke-language=&quot;csharp&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;using Modbus.Device; //네임스페이스를 추가!

//nmodbus4 객체선언(modbus rtu전용)
        ModbusSerialMaster msm;

private void button1_Click(object sender, EventArgs e)
        {
            //접속버튼 클릭
            serialPort1.BaudRate = 9600;
            serialPort1.PortName = textBox1.Text;

            serialPort1.Open();

            if (serialPort1.IsOpen)
            {
                //접속이 완료된 serialport 객체를 라이브러리에게 넘긴다!
                msm = ModbusSerialMaster.CreateRtu(serialPort1);
                MessageBox.Show(&quot;연결완료!&quot;);
            }
        }

        private void button2_Click(object sender, EventArgs e)
        {
            //coil 0번을 ON한다!
            msm.WriteSingleCoil(1, 0, true);
        }

        private void button3_Click(object sender, EventArgs e)
        {
            msm.WriteSingleCoil(1, 0, false);
        }

        private void button4_Click(object sender, EventArgs e)
        {
            msm.WriteSingleCoil(1, 1, true);
        }
        private void button5_Click(object sender, EventArgs e)
        {
            msm.WriteSingleCoil(1, 1, false);
        }

        private void button6_Click(object sender, EventArgs e)
        {
            msm.WriteSingleCoil(1, 2, true);
        }

        private void button7_Click(object sender, EventArgs e)
        {
            msm.WriteSingleCoil(1, 2, false);
        }

        private void button8_Click(object sender, EventArgs e)
        {
            msm.WriteSingleCoil(1, 3, true);
        }

        private void button9_Click(object sender, EventArgs e)
        {
            msm.WriteSingleCoil(1, 3, false);
        }
        private void button10_Click(object sender, EventArgs e)
        {
            msm.WriteSingleCoil(1, 4, true);
        }

        private void button11_Click(object sender, EventArgs e)
        {
            msm.WriteSingleCoil(1, 4, false);
        }
        private void button12_Click(object sender, EventArgs e)
        {
            msm.WriteSingleCoil(1, 5, true);
        }
        private void button13_Click(object sender, EventArgs e)
        {
            msm.WriteSingleCoil(1, 5, false);
        }

        private void button14_Click(object sender, EventArgs e)
        {
            msm.WriteSingleCoil(1, 6, true);
        }

        private void button15_Click(object sender, EventArgs e)
        {
            msm.WriteSingleCoil(1, 6, false);
        }
        private void button16_Click(object sender, EventArgs e)
        {
            msm.WriteSingleCoil(1, 7, true);
        }
        private void button17_Click(object sender, EventArgs e)
        {
            msm.WriteSingleCoil(1, 7, false);
        }
        private void button18_Click(object sender, EventArgs e)
        {
            //라이브러리가 stm32에게 0번지부터 8개의 쓰기코일값을 요구한다!
            bool[] data = msm.ReadCoils(1, 0, 8);

            string text = &quot;&quot;;
            for(int i = 0; i &amp;lt; 8; i++)
            {
                text += data[i].ToString() + &quot;, &quot;;
            }
            richTextBox1.Text += text + &quot;\n&quot;;
        }&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;br /&gt;3.예제2번에서&amp;nbsp;마스터쪽에&amp;nbsp;STM32쪽&amp;nbsp;LED가&amp;nbsp;켜져있으면&amp;nbsp;ON버튼의&amp;nbsp;배경색을&amp;nbsp;녹색으로&amp;nbsp;하고,&amp;nbsp;OFF상태면&amp;nbsp;OFF버튼의&amp;nbsp;배경색을&amp;nbsp;빨간색으로&amp;nbsp;하시오!&amp;nbsp;여기서&amp;nbsp;C#의&amp;nbsp;timer를&amp;nbsp;하나&amp;nbsp;추가해서&amp;nbsp;100밀리초&amp;nbsp;간격으로&amp;nbsp;read&amp;nbsp;coils&amp;nbsp;명령을&amp;nbsp;수행하도록하시오!&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;03.PNG&quot; data-origin-width=&quot;947&quot; data-origin-height=&quot;606&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bktZpI/dJMcahb1UyM/uF4OBSPyJpkWTzMNBKexqK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bktZpI/dJMcahb1UyM/uF4OBSPyJpkWTzMNBKexqK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bktZpI/dJMcahb1UyM/uF4OBSPyJpkWTzMNBKexqK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbktZpI%2FdJMcahb1UyM%2FuF4OBSPyJpkWTzMNBKexqK%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;947&quot; height=&quot;606&quot; data-filename=&quot;03.PNG&quot; data-origin-width=&quot;947&quot; data-origin-height=&quot;606&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;pre id=&quot;code_1767770471328&quot; class=&quot;cpp&quot; data-ke-language=&quot;cpp&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;/* USER CODE BEGIN 0 */
uint16_t cal_crc(uint8_t *data, uint8_t len)
{
   uint16_t crc = 0xFFFF;
   for(uint8_t i = 0; i &amp;lt; len; i++)
   {
       crc ^= data[i];   // LSB부터 XOR
       for(uint8_t j = 0; j &amp;lt; 8; j++)
       {
           if(crc &amp;amp; 0x0001)
           {
               crc &amp;gt;&amp;gt;= 1;
               crc ^= 0xA001;   // Modbus polynomial
           }
           else
           {
               crc &amp;gt;&amp;gt;= 1;
           }
       }
   }
   return crc;
}
/* USER CODE END 0 */
/* USER CODE BEGIN 2 */
 //녹칸다의 STM32쉴드의 8개의 LED를 배열로 뭉쳐놓은것!
 GPIO_TypeDef *mygroup[] = {GPIOB,GPIOB,GPIOB,GPIOB,GPIOB,GPIOB,GPIOC,GPIOB};
 uint16_t mypin[] = {GPIO_PIN_3,GPIO_PIN_13,GPIO_PIN_5,GPIO_PIN_14,GPIO_PIN_4,GPIO_PIN_15,GPIO_PIN_4,GPIO_PIN_7};
 uint8_t slave_id = 0x01;
 uint8_t tx_buff[100];
 uint8_t req[8];
 uint8_t res[6]; //read coils 전용
 uint8_t write_coil[1];
 /* USER CODE END 2 */


while (1)
 {
	  //usart1은 RS485통신, usart2는 PC와 통신
	  //usart1으로 수신해서 usart2로 결과를 송신한다!
	  if(HAL_UART_Receive(&amp;amp;huart1, req, 8, 500) == HAL_OK){
		  //응답예시데이터
		  uint8_t id = req[0];
		  //내 id에게 req가 왔을때만 res를 전송한다!
		  if(id == slave_id){
			  uint8_t fc = req[1];
			  if(fc == 0x01){
				  //read coils
				  uint16_t start_addr = (req[2] &amp;lt;&amp;lt; 8) | req[3];
				  uint16_t count = (req[4] &amp;lt;&amp;lt; 8) | req[5];
				  uint16_t crc16 = (req[7] &amp;lt;&amp;lt; 8) | req[6];
				  //STM32가 CRC16을 계산함!
				  uint16_t my_crc16 = cal_crc(req,6);
				  if(crc16 == my_crc16){
					  //read coil 응답데이터 만들기
					  //write_coil[0]여기에 순서에 맞게 bit 상태를 넣으면 됨!
					  write_coil[0] = 0;
					  for(int i = 0; i &amp;lt; count; i++)
					  {
					      if(mygroup[i]-&amp;gt;ODR &amp;amp; mypin[i])
					          write_coil[0] |= (1 &amp;lt;&amp;lt; i);
					  }
					  sprintf(tx_buff,&quot;id=%02X, fc=%02X, start_addr=%04X, cnt=%04X, crc=%04X, data=%d\n&quot;,id,fc,start_addr,count,crc16,write_coil[0]);
					  HAL_UART_Transmit(&amp;amp;huart2, tx_buff, strlen(tx_buff), 100);
					  res[0] = id;
					  res[1] = fc;
					  res[2] = 1; //응답데이터는 1byte이다!
					  res[3] = write_coil[0];
					  uint16_t res_crc = cal_crc(res,4);

					  res[4] = res_crc &amp;amp; 0xFF; //res_crc의 하위8bit
					  res[5] = res_crc &amp;gt;&amp;gt; 8; //res_crc의 상위8bit
					  HAL_UART_Transmit(&amp;amp;huart1, res, 6, 100);
				  }else{
					  HAL_UART_Transmit(&amp;amp;huart2, &quot;CRC16 ERROR!\n&quot;, 13, 100);
				  }
			  }else if(fc == 0x05){
				  //write single coil
				  uint16_t coil_addr = (req[2] &amp;lt;&amp;lt; 8) | req[3];
				  uint16_t coil_data = (req[4] &amp;lt;&amp;lt; 8) | req[5];
				  uint16_t crc16 = (req[7] &amp;lt;&amp;lt; 8) | req[6];
				  //STM32가 CRC16을 계산함!
				  uint16_t my_crc16 = cal_crc(req,6);
				  if(crc16 == my_crc16){
					  sprintf(tx_buff,&quot;id=%02X, fc=%02X, addr=%04X, data=%04X, crc=%04X\n&quot;,id,fc,coil_addr,coil_data,crc16);
					  HAL_UART_Transmit(&amp;amp;huart2, tx_buff, strlen(tx_buff), 100);
					  //write single coil명령어 수행
					  if(coil_data == 0xFF00){
						  //ON
						  HAL_GPIO_WritePin(mygroup[coil_addr], mypin[coil_addr], 1);
					  }else{
						  //OFF
						  HAL_GPIO_WritePin(mygroup[coil_addr], mypin[coil_addr], 0);
					  }
					  //응답전송! 그런데 FC=0x05는 req와 res가 같다!
					  HAL_UART_Transmit(&amp;amp;huart1, req, 8, 100);
				  }else{
					  HAL_UART_Transmit(&amp;amp;huart2, &quot;CRC16 ERROR!\n&quot;, 13, 100);
				  }
			  }
		  }
	  }
   /* USER CODE END WHILE */
   /* USER CODE BEGIN 3 */
 }&lt;/code&gt;&lt;/pre&gt;
&lt;pre id=&quot;code_1767770605252&quot; class=&quot;csharp&quot; data-ke-language=&quot;csharp&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;using Modbus.Device; //네임스페이스를 추가!

//nmodbus4 객체선언(modbus rtu전용)
        ModbusSerialMaster msm;

private void button1_Click(object sender, EventArgs e)
        {
            //접속버튼 클릭
            serialPort1.BaudRate = 9600;
            serialPort1.PortName = textBox1.Text;

            serialPort1.Open();

            if (serialPort1.IsOpen)
            {
                //접속이 완료된 serialport 객체를 라이브러리에게 넘긴다!
                msm = ModbusSerialMaster.CreateRtu(serialPort1);
                MessageBox.Show(&quot;연결완료!&quot;);
            }
        }

        private void button2_Click(object sender, EventArgs e)
        {
            //coil 0번을 ON한다!
            msm.WriteSingleCoil(1, 0, true);
        }

        private void button3_Click(object sender, EventArgs e)
        {
            msm.WriteSingleCoil(1, 0, false);
        }

        private void button4_Click(object sender, EventArgs e)
        {
            msm.WriteSingleCoil(1, 1, true);
        }
        private void button5_Click(object sender, EventArgs e)
        {
            msm.WriteSingleCoil(1, 1, false);
        }

        private void button6_Click(object sender, EventArgs e)
        {
            msm.WriteSingleCoil(1, 2, true);
        }

        private void button7_Click(object sender, EventArgs e)
        {
            msm.WriteSingleCoil(1, 2, false);
        }

        private void button8_Click(object sender, EventArgs e)
        {
            msm.WriteSingleCoil(1, 3, true);
        }

        private void button9_Click(object sender, EventArgs e)
        {
            msm.WriteSingleCoil(1, 3, false);
        }
        private void button10_Click(object sender, EventArgs e)
        {
            msm.WriteSingleCoil(1, 4, true);
        }

        private void button11_Click(object sender, EventArgs e)
        {
            msm.WriteSingleCoil(1, 4, false);
        }
        private void button12_Click(object sender, EventArgs e)
        {
            msm.WriteSingleCoil(1, 5, true);
        }
        private void button13_Click(object sender, EventArgs e)
        {
            msm.WriteSingleCoil(1, 5, false);
        }

        private void button14_Click(object sender, EventArgs e)
        {
            msm.WriteSingleCoil(1, 6, true);
        }

        private void button15_Click(object sender, EventArgs e)
        {
            msm.WriteSingleCoil(1, 6, false);
        }
        private void button16_Click(object sender, EventArgs e)
        {
            msm.WriteSingleCoil(1, 7, true);
        }
        private void button17_Click(object sender, EventArgs e)
        {
            msm.WriteSingleCoil(1, 7, false);
        }
        private void button18_Click(object sender, EventArgs e)
        {
            timer1.Start();
        }


        private void timer1_Tick(object sender, EventArgs e)
        {
            //0.1초마다 이부분이 실행되는데 뭐할래?
            //라이브러리가 stm32에게 0번지부터 8개의 쓰기코일값을 요구한다!
            bool[] data = msm.ReadCoils(1, 0, 8);

            if (data[0])
            {
                button2.BackColor = Color.Green;
                button3.BackColor = SystemColors.Control;
            }
            else
            {
                button2.BackColor = SystemColors.Control;
                button3.BackColor = Color.Red;
            }
            if (data[1])
            {
                button4.BackColor = Color.Green;
                button5.BackColor = SystemColors.Control;
            }
            else
            {
                button4.BackColor = SystemColors.Control;
                button5.BackColor = Color.Red;
            }
            if (data[2])
            {
                button6.BackColor = Color.Green;
                button7.BackColor = SystemColors.Control;
            }
            else
            {
                button6.BackColor = SystemColors.Control;
                button7.BackColor = Color.Red;
            }

            if (data[3])
            {
                button8.BackColor = Color.Green;
                button9.BackColor = SystemColors.Control;
            }
            else
            {
                button8.BackColor = SystemColors.Control;
                button9.BackColor = Color.Red;
            }
            if (data[4])
            {
                button10.BackColor = Color.Green;
                button11.BackColor = SystemColors.Control;
            }
            else
            {
                button10.BackColor = SystemColors.Control;
                button11.BackColor = Color.Red;
            }
            if (data[5])
            {
                button12.BackColor = Color.Green;
                button13.BackColor = SystemColors.Control;
            }
            else
            {
                button12.BackColor = SystemColors.Control;
                button13.BackColor = Color.Red;
            }

            if (data[6])
            {
                button14.BackColor = Color.Green;
                button15.BackColor = SystemColors.Control;
            }
            else
            {
                button14.BackColor = SystemColors.Control;
                button15.BackColor = Color.Red;
            }
            if (data[7])
            {
                button16.BackColor = Color.Green;
                button17.BackColor = SystemColors.Control;
            }
            else
            {
                button16.BackColor = SystemColors.Control;
                button17.BackColor = Color.Red;
            }
        }&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;br /&gt;4.이번예제는&amp;nbsp;지금까지&amp;nbsp;했던&amp;nbsp;coil내용을&amp;nbsp;다&amp;nbsp;제거하고&amp;nbsp;write&amp;nbsp;single&amp;nbsp;register에&amp;nbsp;대해서&amp;nbsp;예제를&amp;nbsp;만들어보도록&amp;nbsp;한다!&amp;nbsp;마스터쪽에서&amp;nbsp;설정한&amp;nbsp;값을&amp;nbsp;stm32가&amp;nbsp;받아서&amp;nbsp;putty에&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-filename=&quot;04.PNG&quot; data-origin-width=&quot;1137&quot; data-origin-height=&quot;524&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/b9ombm/dJMcahb1UyS/loDz8Al9aScSwPKNa28GD1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/b9ombm/dJMcahb1UyS/loDz8Al9aScSwPKNa28GD1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/b9ombm/dJMcahb1UyS/loDz8Al9aScSwPKNa28GD1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fb9ombm%2FdJMcahb1UyS%2FloDz8Al9aScSwPKNa28GD1%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;1137&quot; height=&quot;524&quot; data-filename=&quot;04.PNG&quot; data-origin-width=&quot;1137&quot; data-origin-height=&quot;524&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;pre id=&quot;code_1767770491305&quot; class=&quot;cpp&quot; data-ke-language=&quot;cpp&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;/* USER CODE BEGIN 0 */
uint16_t cal_crc(uint8_t *data, uint8_t len)
{
   uint16_t crc = 0xFFFF;
   for(uint8_t i = 0; i &amp;lt; len; i++)
   {
       crc ^= data[i];   // LSB부터 XOR
       for(uint8_t j = 0; j &amp;lt; 8; j++)
       {
           if(crc &amp;amp; 0x0001)
           {
               crc &amp;gt;&amp;gt;= 1;
               crc ^= 0xA001;   // Modbus polynomial
           }
           else
           {
               crc &amp;gt;&amp;gt;= 1;
           }
       }
   }
   return crc;
}
/* USER CODE END 0 */
/* USER CODE BEGIN 2 */
 uint8_t slave_id = 0x01;
 uint8_t tx_buff[100];
 uint8_t req[8];
 uint16_t w_reg[6] = {0}; //6word 정도의 레지스터가 있다고 가정함
 /* USER CODE END 2 */



while (1)
 {
	  //usart1은 RS485통신, usart2는 PC와 통신
	  //usart1으로 수신해서 usart2로 결과를 송신한다!
	  if(HAL_UART_Receive(&amp;amp;huart1, req, 8, 500) == HAL_OK){
		  //응답예시데이터
		  uint8_t id = req[0];
		  //내 id에게 req가 왔을때만 res를 전송한다!
		  if(id == slave_id){
			  uint8_t fc = req[1];
			  //fc가 0x06이 올 예정!
			  uint16_t reg_addr = (req[2] &amp;lt;&amp;lt; 8) | req[3];
			  uint16_t reg_data = (req[4] &amp;lt;&amp;lt; 8) | req[5];
			  uint16_t crc16 = (req[7] &amp;lt;&amp;lt; 8) | req[6];
			  //STM32가 CRC16을 계산함!
			  uint16_t my_crc16 = cal_crc(req,6);
			  if(crc16 == my_crc16){
				  sprintf(tx_buff,&quot;id=%02X, fc=%02X, addr=%04X, data=%04X, crc=%04X\n&quot;,id,fc,reg_addr,reg_data,crc16);
				  HAL_UART_Transmit(&amp;amp;huart2, tx_buff, strlen(tx_buff), 100);
				  w_reg[reg_addr] = reg_data;
				  //레지스터가 6개 있으니까 6개의 값을 출력한다!
				  sprintf(tx_buff,&quot;w_reg=%d, %d, %d, %d, %d, %d\n&quot;,w_reg[0],w_reg[1],w_reg[2],w_reg[3],w_reg[4],w_reg[5]);
				  HAL_UART_Transmit(&amp;amp;huart2, tx_buff, strlen(tx_buff), 100);
				  //응답은 req를 그대로 응답하면 된다!
				  HAL_UART_Transmit(&amp;amp;huart1, req, 8, 100);
			  }else{
				  HAL_UART_Transmit(&amp;amp;huart2, &quot;CRC16 ERROR!\n&quot;, 13, 100);
			  }
		  }
	  }
   /* USER CODE END WHILE */
   /* USER CODE BEGIN 3 */
 }&lt;/code&gt;&lt;/pre&gt;
&lt;pre id=&quot;code_1767770654302&quot; class=&quot;csharp&quot; data-ke-language=&quot;csharp&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;using Modbus.Device; //네임스페이스를 추가!

//nmodbus4 객체선언(modbus rtu전용)
        ModbusSerialMaster msm;

private void button1_Click(object sender, EventArgs e)
        {
            //접속버튼 클릭
            serialPort1.BaudRate = 9600;
            serialPort1.PortName = textBox1.Text;

            serialPort1.Open();

            if (serialPort1.IsOpen)
            {
                //접속이 완료된 serialport 객체를 라이브러리에게 넘긴다!
                msm = ModbusSerialMaster.CreateRtu(serialPort1);
                MessageBox.Show(&quot;연결완료!&quot;);
            }
        }

        private void button2_Click(object sender, EventArgs e)
        {
            ushort addr = ushort.Parse(textBox2.Text);
            ushort value = ushort.Parse(textBox3.Text);
            msm.WriteSingleRegister(1, addr, value);
        }&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;br /&gt;5.마스터쪽에서 STM32의 쓰기레지스터 0번지에 값을 쓰면 녹칸다의 STM32쉴드에 붙어있는 FND모듈에 그 값이 출력되도록 하시오!&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;05.PNG&quot; data-origin-width=&quot;982&quot; data-origin-height=&quot;588&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bxD0cy/dJMcac2PEBQ/jWSJNboBKZ2se6L9wEu6Hk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bxD0cy/dJMcac2PEBQ/jWSJNboBKZ2se6L9wEu6Hk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bxD0cy/dJMcac2PEBQ/jWSJNboBKZ2se6L9wEu6Hk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbxD0cy%2FdJMcac2PEBQ%2FjWSJNboBKZ2se6L9wEu6Hk%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;982&quot; height=&quot;588&quot; data-filename=&quot;05.PNG&quot; data-origin-width=&quot;982&quot; data-origin-height=&quot;588&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;pre id=&quot;code_1767770505771&quot; class=&quot;cpp&quot; data-ke-language=&quot;cpp&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;/* USER CODE BEGIN 0 */
uint16_t cal_crc(uint8_t *data, uint8_t len)
{
   uint16_t crc = 0xFFFF;
   for(uint8_t i = 0; i &amp;lt; len; i++)
   {
       crc ^= data[i];   // LSB부터 XOR
       for(uint8_t j = 0; j &amp;lt; 8; j++)
       {
           if(crc &amp;amp; 0x0001)
           {
               crc &amp;gt;&amp;gt;= 1;
               crc ^= 0xA001;   // Modbus polynomial
           }
           else
           {
               crc &amp;gt;&amp;gt;= 1;
           }
       }
   }
   return crc;
}
//여기 추가해야하는 코드는 FND모듈에추가해야하는 코드 그대로 복붙하기!
/* USER CODE END 0 */
/* USER CODE BEGIN 2 */
 uint8_t slave_id = 0x01;
 uint8_t tx_buff[100];
 uint8_t req[8];
 uint16_t w_reg[6] = {0}; //6word 정도의 레지스터가 있다고 가정함
 tm1637Init();
 tm1637SetBrightness(4);
 tm1637DisplayDecimalTrim(0, 0);
 /* USER CODE END 2 */




while (1)
 {
	  //usart1은 RS485통신, usart2는 PC와 통신
	  //usart1으로 수신해서 usart2로 결과를 송신한다!
	  if(HAL_UART_Receive(&amp;amp;huart1, req, 8, 500) == HAL_OK){
		  //응답예시데이터
		  uint8_t id = req[0];
		  //내 id에게 req가 왔을때만 res를 전송한다!
		  if(id == slave_id){
			  uint8_t fc = req[1];
			  //fc가 0x06이 올 예정!
			  uint16_t reg_addr = (req[2] &amp;lt;&amp;lt; 8) | req[3];
			  uint16_t reg_data = (req[4] &amp;lt;&amp;lt; 8) | req[5];
			  uint16_t crc16 = (req[7] &amp;lt;&amp;lt; 8) | req[6];
			  //STM32가 CRC16을 계산함!
			  uint16_t my_crc16 = cal_crc(req,6);
			  if(crc16 == my_crc16){
				  sprintf(tx_buff,&quot;id=%02X, fc=%02X, addr=%04X, data=%04X, crc=%04X\n&quot;,id,fc,reg_addr,reg_data,crc16);
				  HAL_UART_Transmit(&amp;amp;huart2, tx_buff, strlen(tx_buff), 100);
				  w_reg[reg_addr] = reg_data;
				  if(reg_addr == 0)
					  tm1637DisplayDecimalTrim(w_reg[0], 0);
				  //레지스터가 6개 있으니까 6개의 값을 출력한다!
				  sprintf(tx_buff,&quot;w_reg=%d, %d, %d, %d, %d, %d\n&quot;,w_reg[0],w_reg[1],w_reg[2],w_reg[3],w_reg[4],w_reg[5]);
				  HAL_UART_Transmit(&amp;amp;huart2, tx_buff, strlen(tx_buff), 100);
				  //응답은 req를 그대로 응답하면 된다!
				  HAL_UART_Transmit(&amp;amp;huart1, req, 8, 100);
			  }else{
				  HAL_UART_Transmit(&amp;amp;huart2, &quot;CRC16 ERROR!\n&quot;, 13, 100);
			  }
		  }
	  }
   /* USER CODE END WHILE */
   /* USER CODE BEGIN 3 */
 }&lt;/code&gt;&lt;/pre&gt;
&lt;pre id=&quot;code_1767770663955&quot; class=&quot;csharp&quot; data-ke-language=&quot;csharp&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;using Modbus.Device; //네임스페이스를 추가!

//nmodbus4 객체선언(modbus rtu전용)
        ModbusSerialMaster msm;

private void button1_Click(object sender, EventArgs e)
        {
            //접속버튼 클릭
            serialPort1.BaudRate = 9600;
            serialPort1.PortName = textBox1.Text;

            serialPort1.Open();

            if (serialPort1.IsOpen)
            {
                //접속이 완료된 serialport 객체를 라이브러리에게 넘긴다!
                msm = ModbusSerialMaster.CreateRtu(serialPort1);
                MessageBox.Show(&quot;연결완료!&quot;);
            }
        }

        private void button2_Click(object sender, EventArgs e)
        {
            ushort addr = ushort.Parse(textBox2.Text);
            ushort value = ushort.Parse(textBox3.Text);
            msm.WriteSingleRegister(1, addr, value);
        }&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;br /&gt;6.이번에는&amp;nbsp;예제4에&amp;nbsp;더해서&amp;nbsp;쓰기&amp;nbsp;레지스터에서&amp;nbsp;값을&amp;nbsp;읽는&amp;nbsp;명령인&amp;nbsp;read&amp;nbsp;holding&amp;nbsp;register를&amp;nbsp;구현해서&amp;nbsp;C#화면에&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;시간관계상)&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;06.PNG&quot; data-origin-width=&quot;1256&quot; data-origin-height=&quot;567&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/dF9CqB/dJMcabQpZ7t/lqrsoGmCkSrBpo2t5FsZK1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/dF9CqB/dJMcabQpZ7t/lqrsoGmCkSrBpo2t5FsZK1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/dF9CqB/dJMcabQpZ7t/lqrsoGmCkSrBpo2t5FsZK1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FdF9CqB%2FdJMcabQpZ7t%2FlqrsoGmCkSrBpo2t5FsZK1%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;1256&quot; height=&quot;567&quot; data-filename=&quot;06.PNG&quot; data-origin-width=&quot;1256&quot; data-origin-height=&quot;567&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;pre id=&quot;code_1767770520482&quot; class=&quot;cpp&quot; data-ke-language=&quot;cpp&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;/* USER CODE BEGIN 0 */
uint16_t cal_crc(uint8_t *data, uint8_t len)
{
   uint16_t crc = 0xFFFF;
   for(uint8_t i = 0; i &amp;lt; len; i++)
   {
       crc ^= data[i];   // LSB부터 XOR
       for(uint8_t j = 0; j &amp;lt; 8; j++)
       {
           if(crc &amp;amp; 0x0001)
           {
               crc &amp;gt;&amp;gt;= 1;
               crc ^= 0xA001;   // Modbus polynomial
           }
           else
           {
               crc &amp;gt;&amp;gt;= 1;
           }
       }
   }
   return crc;
}
/* USER CODE END 0 */
/* USER CODE BEGIN 2 */
 uint8_t slave_id = 0x01;
 uint8_t tx_buff[100];
 uint8_t req[8];
 uint8_t res[17];
 uint16_t w_reg[6] = {0}; //6word 정도의 레지스터가 있다고 가정함
 /* USER CODE END 2 */





while (1)
 {
	  //usart1은 RS485통신, usart2는 PC와 통신
	  //usart1으로 수신해서 usart2로 결과를 송신한다!
	  if(HAL_UART_Receive(&amp;amp;huart1, req, 8, 500) == HAL_OK){
		  //응답예시데이터
		  uint8_t id = req[0];
		  //내 id에게 req가 왔을때만 res를 전송한다!
		  if(id == slave_id){
			  uint8_t fc = req[1];
			  if(fc == 0x06){
				  uint16_t reg_addr = (req[2] &amp;lt;&amp;lt; 8) | req[3];
				  uint16_t reg_data = (req[4] &amp;lt;&amp;lt; 8) | req[5];
				  uint16_t crc16 = (req[7] &amp;lt;&amp;lt; 8) | req[6];
				  //STM32가 CRC16을 계산함!
				  uint16_t my_crc16 = cal_crc(req,6);
				  if(crc16 == my_crc16){
					  sprintf(tx_buff,&quot;id=%02X, fc=%02X, addr=%04X, data=%04X, crc=%04X\n&quot;,id,fc,reg_addr,reg_data,crc16);
					  HAL_UART_Transmit(&amp;amp;huart2, tx_buff, strlen(tx_buff), 100);
					  w_reg[reg_addr] = reg_data;
					  //레지스터가 6개 있으니까 6개의 값을 출력한다!
					  sprintf(tx_buff,&quot;w_reg=%d, %d, %d, %d, %d, %d\n&quot;,w_reg[0],w_reg[1],w_reg[2],w_reg[3],w_reg[4],w_reg[5]);
					  HAL_UART_Transmit(&amp;amp;huart2, tx_buff, strlen(tx_buff), 100);
					  //응답은 req를 그대로 응답하면 된다!
					  HAL_UART_Transmit(&amp;amp;huart1, req, 8, 100);
				  }else{
					  HAL_UART_Transmit(&amp;amp;huart2, &quot;CRC16 ERROR!\n&quot;, 13, 100);
				  }

			  }else if(fc == 0x03){
				  //read holding register
				  uint16_t start_addr = (req[2] &amp;lt;&amp;lt; 8) | req[3];
				  uint16_t count = (req[4] &amp;lt;&amp;lt; 8) | req[5];
				  uint16_t crc16 = (req[7] &amp;lt;&amp;lt; 8) | req[6];
				  //STM32가 CRC16을 계산함!
				  uint16_t my_crc16 = cal_crc(req,6);
				  if(crc16 == my_crc16){
					  sprintf(tx_buff,&quot;id=%02X, fc=%02X, addr=%04X, data=%04X, crc=%04X\n&quot;,id,fc,start_addr,count,crc16);
					  HAL_UART_Transmit(&amp;amp;huart2, tx_buff, strlen(tx_buff), 100);
					  //마스터가 요구한 워드에 갯수만큼 응답한다!
					  res[0] = id;
					  res[1] = fc;
					  res[2] = count * 2;
					  res[3] = (w_reg[start_addr] &amp;gt;&amp;gt; 8);
					  res[4] = (w_reg[start_addr] &amp;amp; 0xFF);
					  uint16_t res_crc16 = cal_crc(res,5);
					  res[5] = (res_crc16 &amp;amp; 0xFF);
					  res[6] = (res_crc16 &amp;gt;&amp;gt; 8);
					  HAL_UART_Transmit(&amp;amp;huart1, res, 7, 100);
				  }else{
					  HAL_UART_Transmit(&amp;amp;huart2, &quot;CRC16 ERROR!\n&quot;, 13, 100);
				  }
			  }
		  }
	  }
   /* USER CODE END WHILE */
   /* USER CODE BEGIN 3 */
 }&lt;/code&gt;&lt;/pre&gt;
&lt;pre id=&quot;code_1767770674012&quot; class=&quot;csharp&quot; data-ke-language=&quot;csharp&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;using Modbus.Device; //네임스페이스를 추가!

//nmodbus4 객체선언(modbus rtu전용)
        ModbusSerialMaster msm;

private void button1_Click(object sender, EventArgs e)
        {
            //접속버튼 클릭
            serialPort1.BaudRate = 9600;
            serialPort1.PortName = textBox1.Text;

            serialPort1.Open();

            if (serialPort1.IsOpen)
            {
                //접속이 완료된 serialport 객체를 라이브러리에게 넘긴다!
                msm = ModbusSerialMaster.CreateRtu(serialPort1);
                MessageBox.Show(&quot;연결완료!&quot;);
            }
        }

        private void button2_Click(object sender, EventArgs e)
        {
            ushort addr = ushort.Parse(textBox2.Text);
            ushort value = ushort.Parse(textBox3.Text);
            msm.WriteSingleRegister(1, addr, value);
        }

        private void button3_Click(object sender, EventArgs e)
        {
            ushort addr = ushort.Parse(textBox4.Text);
            ushort[] data = msm.ReadHoldingRegisters(1, addr, 1);

            richTextBox1.Text += &quot;응답데이터=&quot; + data[0].ToString() + &quot;\n&quot;;
        }&lt;/code&gt;&lt;/pre&gt;</description>
      <category>프로그래밍/STM32</category>
      <author>덕력킹</author>
      <guid isPermaLink="true">https://bota.tistory.com/2468</guid>
      <comments>https://bota.tistory.com/2468#entry2468comment</comments>
      <pubDate>Wed, 7 Jan 2026 16:26:36 +0900</pubDate>
    </item>
    <item>
      <title>[STM32#25] stm32를 modbus rtu 슬레이브(slave)로 C# winform을 마스터(master)로 설정해서 제어하는 방법(1)!(녹칸다 내맘대로 STM32)</title>
      <link>https://bota.tistory.com/2467</link>
      <description>&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;stm32.png&quot; data-origin-width=&quot;1920&quot; data-origin-height=&quot;1080&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cxd2OE/dJMcaaDX3hP/Xk6LMoczjydNhDvQBHVZC1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cxd2OE/dJMcaaDX3hP/Xk6LMoczjydNhDvQBHVZC1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cxd2OE/dJMcaaDX3hP/Xk6LMoczjydNhDvQBHVZC1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fcxd2OE%2FdJMcaaDX3hP%2FXk6LMoczjydNhDvQBHVZC1%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;1920&quot; height=&quot;1080&quot; data-filename=&quot;stm32.png&quot; data-origin-width=&quot;1920&quot; data-origin-height=&quot;1080&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/live/xWxbcANp3ac&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://youtube.com/live/xWxbcANp3ac&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/watch?v=xWxbcANp3ac&quot; data-video-thumbnail=&quot;https://scrap.kakaocdn.net/dn/B2oHP/dJMb9aKxNNx/fK8Thq1OzXw89eVYlJ5OA1/img.jpg?width=1280&amp;amp;height=720&amp;amp;face=0_0_1280_720,https://scrap.kakaocdn.net/dn/rITfA/dJMb83SbvQo/hpBpE6R95hKErSq7gUKCl1/img.jpg?width=1280&amp;amp;height=720&amp;amp;face=0_0_1280_720,https://scrap.kakaocdn.net/dn/blUcD2/dJMb88FXyD2/2RVm3qF96EdWvKBqLeiei0/img.jpg?width=1280&amp;amp;height=720&amp;amp;face=0_0_1280_720&quot; data-video-width=&quot;860&quot; data-video-height=&quot;484&quot; data-video-origin-width=&quot;860&quot; data-video-origin-height=&quot;484&quot; data-ke-mobilestyle=&quot;widthContent&quot; data-video-title=&quot;[STM32#25] stm32를 modbus rtu 슬레이브(slave)로 C# winform을 마스터(master)로 설정해서 제어하는 방법(1)!(&quot; data-original-url=&quot;&quot;&gt;&lt;iframe src=&quot;https://www.youtube.com/embed/xWxbcANp3ac&quot; width=&quot;860&quot; height=&quot;484&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;[STM32#25]&amp;nbsp;stm32를&amp;nbsp;modbus&amp;nbsp;rtu&amp;nbsp;슬레이브(slave)로&amp;nbsp;C#&amp;nbsp;winform을&amp;nbsp;마스터(master)로&amp;nbsp;설정해서&amp;nbsp;제어하는&amp;nbsp;방법(1)!(녹칸다&amp;nbsp;내맘대로&amp;nbsp;STM32) &lt;br /&gt;&lt;br /&gt;심심한녹칸다의&amp;nbsp;내맘대로&amp;nbsp;STM32시리즈이다! &lt;br /&gt;&lt;br /&gt;STM32시리즈의&amp;nbsp;모든&amp;nbsp;자료는&amp;nbsp;구글&amp;nbsp;슬라이드에&amp;nbsp;작성하고&amp;nbsp;모두에게&amp;nbsp;공유되어있음! &lt;br /&gt;&lt;a href=&quot;https://docs.google.com/presentation/d/1myA5iYbjuKsLWLqtRLKAiRfwUwvqB1d1RGjiMIIgp3I/edit?slide=id.g3b25d818391_8_0#slide=id.g3b25d818391_8_0&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://docs.google.com/presentation/d/1myA5iYbjuKsLWLqtRLKAiRfwUwvqB1d1RGjiMIIgp3I/edit?slide=id.g3b25d818391_8_0#slide=id.g3b25d818391_8_0&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;이제&amp;nbsp;stm32가&amp;nbsp;마스터가&amp;nbsp;아니라&amp;nbsp;슬레이브가&amp;nbsp;되는&amp;nbsp;것입니다~~! &lt;br /&gt;&lt;br /&gt;1.C#윈폼에서&amp;nbsp;버튼을&amp;nbsp;2개&amp;nbsp;생성하고&amp;nbsp;ON버튼을&amp;nbsp;누르면&amp;nbsp;STM32의&amp;nbsp;PB3의&amp;nbsp;LED가&amp;nbsp;켜지고,&amp;nbsp;OFF버튼을&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-filename=&quot;01.PNG&quot; data-origin-width=&quot;745&quot; data-origin-height=&quot;530&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/dkwjY3/dJMcacaIvA1/yRcMr9myuSCcpKGAtKvNO1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/dkwjY3/dJMcacaIvA1/yRcMr9myuSCcpKGAtKvNO1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/dkwjY3/dJMcacaIvA1/yRcMr9myuSCcpKGAtKvNO1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FdkwjY3%2FdJMcacaIvA1%2FyRcMr9myuSCcpKGAtKvNO1%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;530&quot; data-filename=&quot;01.PNG&quot; data-origin-width=&quot;745&quot; data-origin-height=&quot;530&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;pre id=&quot;code_1767622464230&quot; class=&quot;cpp&quot; data-ke-language=&quot;cpp&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;/* USER CODE BEGIN 0 */
uint16_t cal_crc(uint8_t *data, uint8_t len)
{
   uint16_t crc = 0xFFFF;
   for(uint8_t i = 0; i &amp;lt; len; i++)
   {
       crc ^= data[i];   // LSB부터 XOR
       for(uint8_t j = 0; j &amp;lt; 8; j++)
       {
           if(crc &amp;amp; 0x0001)
           {
               crc &amp;gt;&amp;gt;= 1;
               crc ^= 0xA001;   // Modbus polynomial
           }
           else
           {
               crc &amp;gt;&amp;gt;= 1;
           }
       }
   }
   return crc;
}
/* USER CODE END 0 */
/* USER CODE BEGIN 2 */
 //녹칸다의 STM32쉴드의 8개의 LED를 배열로 뭉쳐놓은것!
 GPIO_TypeDef *mygroup[] = {GPIOB,GPIOB,GPIOB,GPIOB,GPIOB,GPIOB,GPIOC,GPIOB};
 uint16_t mypin[] = {GPIO_PIN_3,GPIO_PIN_13,GPIO_PIN_5,GPIO_PIN_14,GPIO_PIN_4,GPIO_PIN_15,GPIO_PIN_4,GPIO_PIN_7};
 uint8_t slave_id = 0x01;
 uint8_t tx_buff[100];
 uint8_t req[8];
 /* USER CODE END 2 */

while (1)
 {
	  //usart1은 RS485통신, usart2는 PC와 통신
	  //usart1으로 수신해서 usart2로 결과를 송신한다!
	  if(HAL_UART_Receive(&amp;amp;huart1, req, 8, 100) == HAL_OK){
		  //응답예시데이터
		  uint8_t id = req[0];
		  //내 id에게 req가 왔을때만 res를 전송한다!
		  if(id == slave_id){
			  uint8_t fc = req[1];
			  uint16_t coil_addr = (req[2] &amp;lt;&amp;lt; 8) | req[3];
			  uint16_t coil_data = (req[4] &amp;lt;&amp;lt; 8) | req[5];
			  uint16_t crc16 = (req[7] &amp;lt;&amp;lt; 8) | req[6];
			  //STM32가 CRC16을 계산함!
			  uint16_t my_crc16 = cal_crc(req,6);
			  if(crc16 == my_crc16){
				  sprintf(tx_buff,&quot;id=%02X, fc=%02X, addr=%04X, data=%04X, crc=%04X\n&quot;,id,fc,coil_addr,coil_data,crc16);
				  HAL_UART_Transmit(&amp;amp;huart2, tx_buff, strlen(tx_buff), 100);
				  //write single coil명령어 수행
				  if(coil_data == 0xFF00){
					  //ON
					  HAL_GPIO_WritePin(mygroup[coil_addr], mypin[coil_addr], 1);
				  }else{
					  //OFF
					  HAL_GPIO_WritePin(mygroup[coil_addr], mypin[coil_addr], 0);
				  }
				  //응답전송! 그런데 FC=0x05는 req와 res가 같다!
				  HAL_UART_Transmit(&amp;amp;huart1, req, 8, 100);
			  }else{
				  HAL_UART_Transmit(&amp;amp;huart2, &quot;CRC16 ERROR!\n&quot;, 13, 100);
			  }
		  }
	  }
 }&lt;/code&gt;&lt;/pre&gt;
&lt;pre id=&quot;code_1767622491920&quot; class=&quot;csharp&quot; data-ke-language=&quot;csharp&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;private void button1_Click(object sender, EventArgs e)
        {
            //접속버튼 클릭
            serialPort1.BaudRate = 9600;
            serialPort1.PortName = textBox1.Text;

            serialPort1.Open();

            if (serialPort1.IsOpen)
            {
                MessageBox.Show(&quot;연결완료!&quot;);
            }
        }

        private void button2_Click(object sender, EventArgs e)
        {
            if (serialPort1.IsOpen)
            {
                byte[] req = { 0x01, 0x05, 0x00, 0x00, 0xFF, 0x00, 0x8C, 0x3A };
                serialPort1.Write(req, 0, 8);
            }
        }

        private void button3_Click(object sender, EventArgs e)
        {
            if (serialPort1.IsOpen)
            {
                byte[] req = { 0x01, 0x05, 0x00, 0x00, 0x00, 0x00, 0xCD, 0xCA };
                serialPort1.Write(req, 0, 8);
            }
        }

private void serialPort1_DataReceived(object sender, System.IO.Ports.SerialDataReceivedEventArgs e)
        {
            //슬레이브로부터 8개의 데이터가 응답으로 올 예정이다!
            byte[] res = new byte[8];
            int pos = 0;
            for (int i = 0; i &amp;lt; 8; i++)
            {
                res[pos++] = (byte)serialPort1.ReadByte();
            }
            
            richTextBox1.Text += &quot;[응답] &quot;;
            for(int i = 0; i &amp;lt; 8; i++)
            {
                richTextBox1.Text += res[i].ToString(&quot;X&quot;) + &quot;, &quot;;
            }
            richTextBox1.Text += &quot;\n&quot;;
        }&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;br /&gt;2.예제1번에서&amp;nbsp;PB3번&amp;nbsp;LED만&amp;nbsp;제어했던것을&amp;nbsp;녹칸다의&amp;nbsp;STM32쉴드에&amp;nbsp;붙어있는&amp;nbsp;8개의&amp;nbsp;LED를&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-filename=&quot;02.PNG&quot; data-origin-width=&quot;822&quot; data-origin-height=&quot;551&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cHJDcq/dJMcachtTIO/bBKZ3Pt0KLt2MHNWHzP03k/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cHJDcq/dJMcachtTIO/bBKZ3Pt0KLt2MHNWHzP03k/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cHJDcq/dJMcachtTIO/bBKZ3Pt0KLt2MHNWHzP03k/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FcHJDcq%2FdJMcachtTIO%2FbBKZ3Pt0KLt2MHNWHzP03k%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;551&quot; data-filename=&quot;02.PNG&quot; data-origin-width=&quot;822&quot; data-origin-height=&quot;551&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;pre id=&quot;code_1767622475788&quot; class=&quot;cpp&quot; data-ke-language=&quot;cpp&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;/* USER CODE BEGIN 0 */
uint16_t cal_crc(uint8_t *data, uint8_t len)
{
   uint16_t crc = 0xFFFF;
   for(uint8_t i = 0; i &amp;lt; len; i++)
   {
       crc ^= data[i];   // LSB부터 XOR
       for(uint8_t j = 0; j &amp;lt; 8; j++)
       {
           if(crc &amp;amp; 0x0001)
           {
               crc &amp;gt;&amp;gt;= 1;
               crc ^= 0xA001;   // Modbus polynomial
           }
           else
           {
               crc &amp;gt;&amp;gt;= 1;
           }
       }
   }
   return crc;
}
/* USER CODE END 0 */
/* USER CODE BEGIN 2 */
 //녹칸다의 STM32쉴드의 8개의 LED를 배열로 뭉쳐놓은것!
 GPIO_TypeDef *mygroup[] = {GPIOB,GPIOB,GPIOB,GPIOB,GPIOB,GPIOB,GPIOC,GPIOB};
 uint16_t mypin[] = {GPIO_PIN_3,GPIO_PIN_13,GPIO_PIN_5,GPIO_PIN_14,GPIO_PIN_4,GPIO_PIN_15,GPIO_PIN_4,GPIO_PIN_7};
 uint8_t slave_id = 0x01;
 uint8_t tx_buff[100];
 uint8_t req[8];
 /* USER CODE END 2 */

while (1)
 {
	  //usart1은 RS485통신, usart2는 PC와 통신
	  //usart1으로 수신해서 usart2로 결과를 송신한다!
	  if(HAL_UART_Receive(&amp;amp;huart1, req, 8, 100) == HAL_OK){
		  //응답예시데이터
		  uint8_t id = req[0];
		  //내 id에게 req가 왔을때만 res를 전송한다!
		  if(id == slave_id){
			  uint8_t fc = req[1];
			  uint16_t coil_addr = (req[2] &amp;lt;&amp;lt; 8) | req[3];
			  uint16_t coil_data = (req[4] &amp;lt;&amp;lt; 8) | req[5];
			  uint16_t crc16 = (req[7] &amp;lt;&amp;lt; 8) | req[6];
			  //STM32가 CRC16을 계산함!
			  uint16_t my_crc16 = cal_crc(req,6);
			  if(crc16 == my_crc16){
				  sprintf(tx_buff,&quot;id=%02X, fc=%02X, addr=%04X, data=%04X, crc=%04X\n&quot;,id,fc,coil_addr,coil_data,crc16);
				  HAL_UART_Transmit(&amp;amp;huart2, tx_buff, strlen(tx_buff), 100);
				  //write single coil명령어 수행
				  if(coil_data == 0xFF00){
					  //ON
					  HAL_GPIO_WritePin(mygroup[coil_addr], mypin[coil_addr], 1);
				  }else{
					  //OFF
					  HAL_GPIO_WritePin(mygroup[coil_addr], mypin[coil_addr], 0);
				  }
				  //응답전송! 그런데 FC=0x05는 req와 res가 같다!
				  HAL_UART_Transmit(&amp;amp;huart1, req, 8, 100);
			  }else{
				  HAL_UART_Transmit(&amp;amp;huart2, &quot;CRC16 ERROR!\n&quot;, 13, 100);
			  }
		  }
	  }
 }&lt;/code&gt;&lt;/pre&gt;
&lt;pre id=&quot;code_1767622508000&quot; class=&quot;csharp&quot; data-ke-language=&quot;csharp&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;private void button1_Click(object sender, EventArgs e)
        {
            //접속버튼 클릭
            serialPort1.BaudRate = 9600;
            serialPort1.PortName = textBox1.Text;

            serialPort1.Open();

            if (serialPort1.IsOpen)
            {
                MessageBox.Show(&quot;연결완료!&quot;);
            }
        }

        private void button2_Click(object sender, EventArgs e)
        {
            if (serialPort1.IsOpen) write_single_coil(0, true);
        }

        private void button3_Click(object sender, EventArgs e)
        {
            if (serialPort1.IsOpen) write_single_coil(0, false);
        }

        private void serialPort1_DataReceived(object sender, System.IO.Ports.SerialDataReceivedEventArgs e)
        {
            //슬레이브로부터 8개의 데이터가 응답으로 올 예정이다!
            byte[] res = new byte[8];
            int pos = 0;
            for (int i = 0; i &amp;lt; 8; i++)
            {
                res[pos++] = (byte)serialPort1.ReadByte();
            }
            

            richTextBox1.Text += &quot;[응답] &quot;;
            for(int i = 0; i &amp;lt; 8; i++)
            {
                richTextBox1.Text += res[i].ToString(&quot;X&quot;) + &quot;, &quot;;
            }
            richTextBox1.Text += &quot;\n&quot;;
        }
        UInt16 cal_crc(byte[] data, int len)
        {
            UInt16 crc = 0xFFFF;
            for (int pos = 0; pos &amp;lt; len; pos++)
            {
                crc ^= data[pos];

                for (int i = 0; i &amp;lt; 8; i++)
                {
                    if ((crc &amp;amp; 0x0001) != 0)
                    {
                        crc &amp;gt;&amp;gt;= 1;
                        crc ^= 0xA001;
                    }
                    else
                    {
                        crc &amp;gt;&amp;gt;= 1;
                    }
                }
            }
            return crc;
        }
        void write_single_coil(UInt16 coil_num, bool state)
        {
            byte[] req = { 0x01, 0x05, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00 };
            if (state == false)
            {
                req[4] = 0x00;
            }

            req[2] = (byte)(coil_num &amp;gt;&amp;gt; 8);
            req[3] = (byte)(coil_num &amp;amp; 0xFF);
            UInt16 crc = cal_crc(req, 6);
            req[6] = (byte)(crc &amp;amp; 0xFF);
            req[7] = (byte)(crc &amp;gt;&amp;gt; 8);
            serialPort1.Write(req, 0, 8);
        }
        private void button4_Click(object sender, EventArgs e)
        {
            if (serialPort1.IsOpen) write_single_coil(1, true);
        }

        private void button5_Click(object sender, EventArgs e)
        {
            if (serialPort1.IsOpen) write_single_coil(1, false);
        }

        private void button6_Click(object sender, EventArgs e)
        {
            if (serialPort1.IsOpen) write_single_coil(2, true);
        }

        private void button7_Click(object sender, EventArgs e)
        {
            if (serialPort1.IsOpen) write_single_coil(2, false);
        }

        private void button8_Click(object sender, EventArgs e)
        {
            if (serialPort1.IsOpen) write_single_coil(3, true);
        }

        private void button9_Click(object sender, EventArgs e)
        {
            if (serialPort1.IsOpen) write_single_coil(3, false);
        }

         private void button10_Click(object sender, EventArgs e)
        {
            if (serialPort1.IsOpen) write_single_coil(4, true);
        }

        private void button11_Click(object sender, EventArgs e)
        {
            if (serialPort1.IsOpen) write_single_coil(4, false);
        }

        private void button12_Click(object sender, EventArgs e)
        {
            if (serialPort1.IsOpen) write_single_coil(5, true);
        }

        private void button13_Click(object sender, EventArgs e)
        {
            if (serialPort1.IsOpen) write_single_coil(5, false);
        }

        private void button14_Click(object sender, EventArgs e)
        {
            if (serialPort1.IsOpen) write_single_coil(6, true);
        }
        private void button15_Click(object sender, EventArgs e)
        {
            if (serialPort1.IsOpen) write_single_coil(6, false);
        }
        private void button16_Click(object sender, EventArgs e)
        {
            if (serialPort1.IsOpen) write_single_coil(7, true);
        }
        private void button17_Click(object sender, EventArgs e)
        {
            if (serialPort1.IsOpen) write_single_coil(7, false);
        }&lt;/code&gt;&lt;/pre&gt;</description>
      <category>프로그래밍/STM32</category>
      <author>덕력킹</author>
      <guid isPermaLink="true">https://bota.tistory.com/2467</guid>
      <comments>https://bota.tistory.com/2467#entry2467comment</comments>
      <pubDate>Mon, 5 Jan 2026 23:16:30 +0900</pubDate>
    </item>
    <item>
      <title>[STM32#24] RS485 to TTL모듈을 이용해서 modbus rtu로 4채널릴레이(relay)와 온습도센서(XY-MD02) 제어해보기 계속!(녹칸다 내맘대로 STM32)</title>
      <link>https://bota.tistory.com/2466</link>
      <description>&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;stm32.png&quot; data-origin-width=&quot;1920&quot; data-origin-height=&quot;1080&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/nqdu8/dJMcafytth6/K4M02p7UZYbNVn5yJuztXK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/nqdu8/dJMcafytth6/K4M02p7UZYbNVn5yJuztXK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/nqdu8/dJMcafytth6/K4M02p7UZYbNVn5yJuztXK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fnqdu8%2FdJMcafytth6%2FK4M02p7UZYbNVn5yJuztXK%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;1920&quot; height=&quot;1080&quot; data-filename=&quot;stm32.png&quot; data-origin-width=&quot;1920&quot; data-origin-height=&quot;1080&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/live/AaawBcSBXX0&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://youtube.com/live/AaawBcSBXX0&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/watch?v=AaawBcSBXX0&quot; data-video-thumbnail=&quot;https://scrap.kakaocdn.net/dn/ctnEGw/hyZQCS0NCi/kT1srylsaYlKFB33POrkN1/img.jpg?width=1280&amp;amp;height=720&amp;amp;face=0_0_1280_720,https://scrap.kakaocdn.net/dn/8Wyzd/hyZPMBfho0/zfLguwedgFfNgIvOwuWUx1/img.jpg?width=1280&amp;amp;height=720&amp;amp;face=0_0_1280_720,https://scrap.kakaocdn.net/dn/bxie3f/hyZQAniRwt/0wEmVyGyk53xfnQG0GrGO0/img.jpg?width=1280&amp;amp;height=720&amp;amp;face=0_0_1280_720&quot; data-video-width=&quot;860&quot; data-video-height=&quot;484&quot; data-video-origin-width=&quot;860&quot; data-video-origin-height=&quot;484&quot; data-ke-mobilestyle=&quot;widthContent&quot; data-video-title=&quot;[STM32#24] RS485 to TTL모듈을 이용해서 modbus rtu로 4채널릴레이(relay)와 온습도센서(XY-MD02) 제어해보기 &quot; data-original-url=&quot;&quot;&gt;&lt;iframe src=&quot;https://www.youtube.com/embed/AaawBcSBXX0&quot; width=&quot;860&quot; height=&quot;484&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;[STM32#24]&amp;nbsp;RS485&amp;nbsp;to&amp;nbsp;TTL모듈을&amp;nbsp;이용해서&amp;nbsp;modbus&amp;nbsp;rtu로&amp;nbsp;4채널릴레이(relay)와&amp;nbsp;온습도센서(XY-MD02)&amp;nbsp;제어해보기&amp;nbsp;계속!(녹칸다&amp;nbsp;내맘대로&amp;nbsp;STM32) &lt;br /&gt;&lt;br /&gt;심심한녹칸다의&amp;nbsp;내맘대로&amp;nbsp;STM32시리즈이다! &lt;br /&gt;&lt;br /&gt;STM32시리즈의&amp;nbsp;모든&amp;nbsp;자료는&amp;nbsp;구글&amp;nbsp;슬라이드에&amp;nbsp;작성하고&amp;nbsp;모두에게&amp;nbsp;공유되어있음! &lt;br /&gt;&lt;a href=&quot;https://docs.google.com/presentation/d/1myA5iYbjuKsLWLqtRLKAiRfwUwvqB1d1RGjiMIIgp3I/edit?slide=id.g3b3e89c7231_3_141#slide=id.g3b3e89c7231_3_141&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://docs.google.com/presentation/d/1myA5iYbjuKsLWLqtRLKAiRfwUwvqB1d1RGjiMIIgp3I/edit?slide=id.g3b3e89c7231_3_141#slide=id.g3b3e89c7231_3_141&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;4채널릴레이는&amp;nbsp;어느정도&amp;nbsp;했고&amp;nbsp;이번에는&amp;nbsp;온습도센서를&amp;nbsp;처리해보도록&amp;nbsp;하겠습니다! &lt;br /&gt;&lt;br /&gt;1.녹칸다가 23편에서 만든 예제2번을 그대로 적용한다음, modbus 4채널릴레이의 매뉴얼에 보면 릴레이의 on/off상태를 읽어오는 명령이 있는데, 이 명령을 이용해서 슬레이브쪽 릴레이의 작동상태를 마스터에서 알수있도록 하시오!(usart2출력)&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;01.PNG&quot; data-origin-width=&quot;963&quot; data-origin-height=&quot;614&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bR0hQT/dJMb99SzhrZ/gpgWXyFPLk55mzstO3Yn51/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bR0hQT/dJMb99SzhrZ/gpgWXyFPLk55mzstO3Yn51/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bR0hQT/dJMb99SzhrZ/gpgWXyFPLk55mzstO3Yn51/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbR0hQT%2FdJMb99SzhrZ%2FgpgWXyFPLk55mzstO3Yn51%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;963&quot; height=&quot;614&quot; data-filename=&quot;01.PNG&quot; data-origin-width=&quot;963&quot; data-origin-height=&quot;614&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;pre id=&quot;code_1767167860216&quot; class=&quot;cpp&quot; data-ke-language=&quot;cpp&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;/* USER CODE BEGIN 0 */
uint8_t nockanda_req[][8] = {
		{0x01,0x05,0x00,0x00,0xFF,0x00,0x8C,0x3A},
		{0x01,0x05,0x00,0x00,0x00,0x00,0xCD,0xCA},
		{0x01,0x05,0x00,0x01,0xFF,0x00,0xDD,0xFA},
		{0x01,0x05,0x00,0x01,0x00,0x00,0x9C,0x0A},
		{0x01,0x05,0x00,0x02,0xFF,0x00,0x2D,0xFA},
		{0x01,0x05,0x00,0x02,0x00,0x00,0x6C,0x0A},
		{0x01,0x05,0x00,0x03,0xFF,0x00,0x7C,0x3A},
		{0x01,0x05,0x00,0x03,0x00,0x00,0x3D,0xCA}
};
uint8_t res[8];
uint8_t tx_buff[100];
//btn_num은 0부터 7까지 눌려진 버튼의 번호이다!
void control_relay(int btn_num){
  HAL_UART_Transmit(&amp;amp;huart1, nockanda_req[btn_num], sizeof(nockanda_req[btn_num]), 100);
  if(HAL_UART_Receive(&amp;amp;huart1, res, 8, 100) == HAL_OK){
  }
  HAL_Delay(200);
}
/* USER CODE END 0 */

/* USER CODE BEGIN 2 */
 uint32_t nockanda_t = 0;
 /* USER CODE END 2 */
 /* Infinite loop */
 /* USER CODE BEGIN WHILE */
 while (1)
 {
	  //100밀리초 간격으로 4채널릴레이에게 릴레이 상태를 물어본다!
	  if(HAL_GetTick() - nockanda_t &amp;gt;= 100){
		  nockanda_t = HAL_GetTick();
		  uint8_t req[] = {0x01,0x01,0x00,0x00,0x00,0x08,0x3D,0xCC};
		  HAL_UART_Transmit(&amp;amp;huart1, req, sizeof(req), 100);
		  //릴레이로부터 응답을 수신함!
		  //HAL_Delay(100);
		  if(HAL_UART_Receive(&amp;amp;huart1, res, 6, 100) == HAL_OK){
			//res[3]에 coil의 상태가 들어있다!
			uint8_t coils[4];
			for(int i = 0;i&amp;lt;4;i++){
				coils[i] = (res[3] &amp;gt;&amp;gt; i) &amp;amp; 0b00000001;
				sprintf(tx_buff,&quot;COIL%d = %s,&quot;,i,coils[i] ? &quot;ON&quot; : &quot;OFF&quot;);
				HAL_UART_Transmit(&amp;amp;huart2, tx_buff, strlen(tx_buff), 100);
			}
		   HAL_UART_Transmit(&amp;amp;huart2, &quot;\n&quot;, 1, 100);
		  }
	  }
	  if(HAL_GPIO_ReadPin(GPIOB, GPIO_PIN_1) == 0) control_relay(0);
	  if(HAL_GPIO_ReadPin(GPIOA, GPIO_PIN_8) == 0) control_relay(2);
	  if(HAL_GPIO_ReadPin(GPIOB, GPIO_PIN_2) == 0) control_relay(4);
	  if(HAL_GPIO_ReadPin(GPIOB, GPIO_PIN_6) == 0) control_relay(6);
	  if(HAL_GPIO_ReadPin(GPIOC, GPIO_PIN_5) == 0) control_relay(1);
	  if(HAL_GPIO_ReadPin(GPIOC, GPIO_PIN_7) == 0) control_relay(3);
	  if(HAL_GPIO_ReadPin(GPIOA, GPIO_PIN_11) == 0) control_relay(5);
	  if(HAL_GPIO_ReadPin(GPIOA, GPIO_PIN_12) == 0) control_relay(7);
   /* USER CODE END WHILE */
   /* USER CODE BEGIN 3 */
 }&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;br /&gt;2.예제1번에서&amp;nbsp;녹칸다가&amp;nbsp;버튼을&amp;nbsp;무지하게&amp;nbsp;빠르게&amp;nbsp;누르게되면&amp;nbsp;read&amp;nbsp;coils쪽&amp;nbsp;코드가&amp;nbsp;HAL_Delay에&amp;nbsp;의해서&amp;nbsp;멈추게&amp;nbsp;된다!&amp;nbsp;이&amp;nbsp;부분을&amp;nbsp;freeRTOS를&amp;nbsp;이용해서&amp;nbsp;간단하게&amp;nbsp;극복해보시오! &lt;br /&gt;task1:녹칸다가&amp;nbsp;8개의&amp;nbsp;버튼중에&amp;nbsp;어떤&amp;nbsp;버튼을&amp;nbsp;눌렀는지를&amp;nbsp;대기열에&amp;nbsp;넣음! &lt;br /&gt;task2:100밀리초&amp;nbsp;간격으로&amp;nbsp;read&amp;nbsp;coils명령을&amp;nbsp;대기열에&amp;nbsp;넣음! &lt;br /&gt;task3:대기열에&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-filename=&quot;02.PNG&quot; data-origin-width=&quot;1056&quot; data-origin-height=&quot;616&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cmE9SM/dJMcahXnXWE/fKL6Y1TC4ifyLK55iHCzTK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cmE9SM/dJMcahXnXWE/fKL6Y1TC4ifyLK55iHCzTK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cmE9SM/dJMcahXnXWE/fKL6Y1TC4ifyLK55iHCzTK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FcmE9SM%2FdJMcahXnXWE%2FfKL6Y1TC4ifyLK55iHCzTK%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;1056&quot; height=&quot;616&quot; data-filename=&quot;02.PNG&quot; data-origin-width=&quot;1056&quot; data-origin-height=&quot;616&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;pre id=&quot;code_1767167880488&quot; class=&quot;cpp&quot; data-ke-language=&quot;cpp&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;/* USER CODE BEGIN 0 */
uint8_t nockanda_req[][8] = {
		{0x01,0x05,0x00,0x00,0xFF,0x00,0x8C,0x3A},
		{0x01,0x05,0x00,0x00,0x00,0x00,0xCD,0xCA},
		{0x01,0x05,0x00,0x01,0xFF,0x00,0xDD,0xFA},
		{0x01,0x05,0x00,0x01,0x00,0x00,0x9C,0x0A},
		{0x01,0x05,0x00,0x02,0xFF,0x00,0x2D,0xFA},
		{0x01,0x05,0x00,0x02,0x00,0x00,0x6C,0x0A},
		{0x01,0x05,0x00,0x03,0xFF,0x00,0x7C,0x3A},
		{0x01,0x05,0x00,0x03,0x00,0x00,0x3D,0xCA}
};
uint8_t res[8];
uint8_t tx_buff[100];
//btn_num은 0부터 7까지 눌려진 버튼의 번호이다!
void control_relay(int btn_num){
  HAL_UART_Transmit(&amp;amp;huart1, nockanda_req[btn_num], sizeof(nockanda_req[btn_num]), 100);
  if(HAL_UART_Receive(&amp;amp;huart1, res, 8, 100) == HAL_OK){
  }
}
typedef struct {
   uint8_t fc; //fc가 0x05면 write single coil, 0x01이면 read coils
   uint8_t btn_num;
} Msg_t;
//메시지 큐(전역)
osMessageQueueId_t dataQueue;
/* USER CODE END 0 */
/* USER CODE BEGIN 2 */
 //메시지큐(메인)
 dataQueue = osMessageQueueNew(
                   8,              // queue length
                   sizeof(Msg_t),  // item size
                   NULL);
 /* USER CODE END 2 */

void StartDefaultTask(void *argument)
{
 /* USER CODE BEGIN 5 */
	//8개의 버튼중에 어떤 버튼이 눌려졌는지를 대기열에 넣는다!
	Msg_t msg;
	msg.fc  = 0x05;
 /* Infinite loop */
 for(;;)
 {
	  if(HAL_GPIO_ReadPin(GPIOB, GPIO_PIN_1) == 0){
		  //큐에다가 버튼 0번이 눌려졌다고 넣어준다
		  msg.btn_num = 0;
		  osMessageQueuePut(dataQueue, &amp;amp;msg, 0, 0);
		  osDelay(200);
	  }
	  if(HAL_GPIO_ReadPin(GPIOA, GPIO_PIN_8) == 0){
		  msg.btn_num = 2;
		  osMessageQueuePut(dataQueue, &amp;amp;msg, 0, 0);
		  osDelay(200);
	  }
	  if(HAL_GPIO_ReadPin(GPIOB, GPIO_PIN_2) == 0){
		  msg.btn_num = 4;
		  osMessageQueuePut(dataQueue, &amp;amp;msg, 0, 0);
		  osDelay(200);
	  }
	  if(HAL_GPIO_ReadPin(GPIOB, GPIO_PIN_6) == 0){
		  msg.btn_num = 6;
		  osMessageQueuePut(dataQueue, &amp;amp;msg, 0, 0);
		  osDelay(200);
	  }
	  if(HAL_GPIO_ReadPin(GPIOC, GPIO_PIN_5) == 0) {
		  msg.btn_num = 1;
		  osMessageQueuePut(dataQueue, &amp;amp;msg, 0, 0);
		  osDelay(200);
	  }

	  if(HAL_GPIO_ReadPin(GPIOC, GPIO_PIN_7) == 0){
		  msg.btn_num = 3;
		  osMessageQueuePut(dataQueue, &amp;amp;msg, 0, 0);
		  osDelay(200);
	  }
	  if(HAL_GPIO_ReadPin(GPIOA, GPIO_PIN_11) == 0){
		  msg.btn_num = 5;
		  osMessageQueuePut(dataQueue, &amp;amp;msg, 0, 0);
		  osDelay(200);
	  }
	  if(HAL_GPIO_ReadPin(GPIOA, GPIO_PIN_12) == 0){
		  msg.btn_num = 7;
		  osMessageQueuePut(dataQueue, &amp;amp;msg, 0, 0);
		  osDelay(200);
	  }
	  osDelay(1); //이녀석 필수!
 }
 /* USER CODE END 5 */
/* USER CODE END Header_StartTask02 */
void StartTask02(void *argument)
{
 /* USER CODE BEGIN StartTask02 */
	//100밀리초 간격으로 read coils에 대한 명령을 대기열에 넣는다!
	Msg_t msg;
	msg.fc = 0x01;
 /* Infinite loop */
 for(;;)
 {
	  osMessageQueuePut(dataQueue, &amp;amp;msg, 0, 0);
     osDelay(100);
 }

/* USER CODE END Header_StartTask03 */
void StartTask03(void *argument)
{
 /* USER CODE BEGIN StartTask03 */
	//대기열에 뭔가 기다리는게 있으면 순서대로 뺴서 처리한다!
	Msg_t msg;
 /* Infinite loop */
 for(;;)
 {
	  osMessageQueueGet(dataQueue, &amp;amp;msg, NULL, osWaitForever);
	  if(msg.fc == 0x01){
		  uint8_t req[] = {0x01,0x01,0x00,0x00,0x00,0x08,0x3D,0xCC};
		  HAL_UART_Transmit(&amp;amp;huart1, req, sizeof(req), 100);
		  //릴레이로부터 응답을 수신함!
		  //HAL_Delay(100);
		  if(HAL_UART_Receive(&amp;amp;huart1, res, 6, 100) == HAL_OK){
			//res[3]에 coil의 상태가 들어있다!
			uint8_t coils[4];
			for(int i = 0;i&amp;lt;4;i++){
				coils[i] = (res[3] &amp;gt;&amp;gt; i) &amp;amp; 0b00000001;
				sprintf(tx_buff,&quot;COIL%d = %s,&quot;,i,coils[i] ? &quot;ON&quot; : &quot;OFF&quot;);
				HAL_UART_Transmit(&amp;amp;huart2, tx_buff, strlen(tx_buff), 100);
			}
		   HAL_UART_Transmit(&amp;amp;huart2, &quot;\n&quot;, 1, 100);
		  }
	  }else if(msg.fc == 0x05){
		  //task1으로부터 온 메시지
		  control_relay(msg.btn_num);
	  }
 }
 /* USER CODE END StartTask03 */
}&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;br /&gt;3.modbus&amp;nbsp;rtu&amp;nbsp;온습도센서를&amp;nbsp;연결해서&amp;nbsp;온도를&amp;nbsp;측정해서&amp;nbsp;putty화면에&amp;nbsp;출력하시오!&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;03.PNG&quot; data-origin-width=&quot;1018&quot; data-origin-height=&quot;573&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/yDGXh/dJMcahXnXWI/E6FrjhAVHxheMuOxyQAPTK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/yDGXh/dJMcahXnXWI/E6FrjhAVHxheMuOxyQAPTK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/yDGXh/dJMcahXnXWI/E6FrjhAVHxheMuOxyQAPTK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FyDGXh%2FdJMcahXnXWI%2FE6FrjhAVHxheMuOxyQAPTK%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;1018&quot; height=&quot;573&quot; data-filename=&quot;03.PNG&quot; data-origin-width=&quot;1018&quot; data-origin-height=&quot;573&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;pre id=&quot;code_1767167899366&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 */
 uint8_t res[8];
 uint8_t tx_buff[100];
 /* USER CODE END 2 */


while (1)
 {
	  uint8_t req[] = {0x01,0x04,0x00,0x01,0x00,0x01,0x60,0x0A};
	  HAL_UART_Transmit(&amp;amp;huart1, req, sizeof(req), 100);
	  if(HAL_UART_Receive(&amp;amp;huart1, res, 7, 100) == HAL_OK){
	 		//USART2로 출력!
	 		HAL_UART_Transmit(&amp;amp;huart2, &quot;res = &quot;, 6, 100);
	 		for(int i = 0;i&amp;lt;7;i++){
	 		  sprintf(tx_buff,&quot;%02X, &quot;,res[i]);
	 		  HAL_UART_Transmit(&amp;amp;huart2, tx_buff, strlen(tx_buff), 100);
	 	  }
	 	  HAL_UART_Transmit(&amp;amp;huart2, &quot;\n&quot;, 1, 100);
	 	  //온도계산 res[3] res[4]
	 	  int16_t temp = (res[3] &amp;lt;&amp;lt; 8) | res[4];
	 	  sprintf(tx_buff,&quot;temp = %.1f\n&quot;,temp/10.0);
	 	 HAL_UART_Transmit(&amp;amp;huart2, tx_buff, strlen(tx_buff), 100);
	   }
	  HAL_Delay(1000);
   /* USER CODE END WHILE */
   /* USER CODE BEGIN 3 */
 }&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;br /&gt;4.modbus&amp;nbsp;rtu&amp;nbsp;온습도센서를&amp;nbsp;연결해서&amp;nbsp;습도를&amp;nbsp;측정해서&amp;nbsp;putty화면에&amp;nbsp;출력하시오!&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;04.PNG&quot; data-origin-width=&quot;992&quot; data-origin-height=&quot;471&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cQyviE/dJMcafFfFUx/Z3CKsWEO69mCl82N8PNga1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cQyviE/dJMcafFfFUx/Z3CKsWEO69mCl82N8PNga1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cQyviE/dJMcafFfFUx/Z3CKsWEO69mCl82N8PNga1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FcQyviE%2FdJMcafFfFUx%2FZ3CKsWEO69mCl82N8PNga1%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;992&quot; height=&quot;471&quot; data-filename=&quot;04.PNG&quot; data-origin-width=&quot;992&quot; data-origin-height=&quot;471&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;pre id=&quot;code_1767167908673&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 */
 uint8_t res[8];
 uint8_t tx_buff[100];
 /* USER CODE END 2 */


while (1)
 {
	  uint8_t req[] = {0x01,0x04,0x00,0x02,0x00,0x01,0x90,0x0A};
	  HAL_UART_Transmit(&amp;amp;huart1, req, sizeof(req), 100);
	  if(HAL_UART_Receive(&amp;amp;huart1, res, 7, 100) == HAL_OK){
	 		//USART2로 출력!
	 		HAL_UART_Transmit(&amp;amp;huart2, &quot;res = &quot;, 6, 100);
	 		for(int i = 0;i&amp;lt;7;i++){
	 		  sprintf(tx_buff,&quot;%02X, &quot;,res[i]);
	 		  HAL_UART_Transmit(&amp;amp;huart2, tx_buff, strlen(tx_buff), 100);
	 	  }
	 	  HAL_UART_Transmit(&amp;amp;huart2, &quot;\n&quot;, 1, 100);
	 	  //습도계산 res[3] res[4]
	 	  uint16_t humi = (res[3] &amp;lt;&amp;lt; 8) | res[4];
	 	  sprintf(tx_buff,&quot;humi = %.1f\n&quot;,humi/10.0);
	 	 HAL_UART_Transmit(&amp;amp;huart2, tx_buff, strlen(tx_buff), 100);
	   }
	  HAL_Delay(1000);
   /* USER CODE END WHILE */
   /* USER CODE BEGIN 3 */
 }&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;br /&gt;5.온도와&amp;nbsp;습도를&amp;nbsp;동시에&amp;nbsp;측정해서&amp;nbsp;putty화면에&amp;nbsp;출력하시오!&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;05.PNG&quot; data-origin-width=&quot;989&quot; data-origin-height=&quot;498&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/l35aI/dJMcahXnXWQ/QGqXRy7n1OSItAgNRJuJY1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/l35aI/dJMcahXnXWQ/QGqXRy7n1OSItAgNRJuJY1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/l35aI/dJMcahXnXWQ/QGqXRy7n1OSItAgNRJuJY1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fl35aI%2FdJMcahXnXWQ%2FQGqXRy7n1OSItAgNRJuJY1%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;989&quot; height=&quot;498&quot; data-filename=&quot;05.PNG&quot; data-origin-width=&quot;989&quot; data-origin-height=&quot;498&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;pre id=&quot;code_1767167917907&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 */
 uint8_t res[8];
 uint8_t tx_buff[100];
 /* USER CODE END 2 */

while (1)
 {
	  uint8_t req[] = {0x01,0x04,0x00,0x01,0x00,0x02,0x20,0x0B};
	  HAL_UART_Transmit(&amp;amp;huart1, req, sizeof(req), 100);
	  if(HAL_UART_Receive(&amp;amp;huart1, res, 9, 100) == HAL_OK){
	 		//USART2로 출력!
	 		HAL_UART_Transmit(&amp;amp;huart2, &quot;res = &quot;, 6, 100);
	 		for(int i = 0;i&amp;lt;9;i++){
	 		  sprintf(tx_buff,&quot;%02X, &quot;,res[i]);
	 		  HAL_UART_Transmit(&amp;amp;huart2, tx_buff, strlen(tx_buff), 100);
	 	  }
	 	  HAL_UART_Transmit(&amp;amp;huart2, &quot;\n&quot;, 1, 100);
	 	  //온도 res[3] + res[4]
	 	  //습도 res[5] + res[6]
	 	  int16_t temp = (res[3] &amp;lt;&amp;lt; 8) | res[4];
	 	  uint16_t humi = (res[5] &amp;lt;&amp;lt; 8) | res[6];
	 	  sprintf(tx_buff,&quot;temp = %.1f, humi = %.1f\n&quot;,temp/10.0,humi/10.0);
	 	 HAL_UART_Transmit(&amp;amp;huart2, tx_buff, strlen(tx_buff), 100);
	   }
	  HAL_Delay(1000);
   /* USER CODE END WHILE */
   /* USER CODE BEGIN 3 */
 }&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;br /&gt;6.측정한 온도와 습도를 1602LCD에 출력하시오!&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;06.PNG&quot; data-origin-width=&quot;939&quot; data-origin-height=&quot;629&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cV7zCL/dJMcahXnXWT/mUB1euw54uozv1THXWEiz0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cV7zCL/dJMcahXnXWT/mUB1euw54uozv1THXWEiz0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cV7zCL/dJMcahXnXWT/mUB1euw54uozv1THXWEiz0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FcV7zCL%2FdJMcahXnXWT%2FmUB1euw54uozv1THXWEiz0%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;939&quot; height=&quot;629&quot; data-filename=&quot;06.PNG&quot; data-origin-width=&quot;939&quot; data-origin-height=&quot;629&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;pre id=&quot;code_1767167933200&quot; class=&quot;cpp&quot; data-ke-language=&quot;cpp&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;//BEGIN0에 i2c 1602LCD관련코드 링크타고가서 추가하기!

/* USER CODE BEGIN 2 */
 uint8_t res[9];
 uint8_t tx_buff[100];
 uint8_t line1[20];
 uint8_t line2[20];
 LCD_INIT(); //1회호출(메인루프 시작전)
 /* USER CODE END 2 */

while (1)
 {
	  uint8_t req[] = {0x01,0x04,0x00,0x01,0x00,0x02,0x20,0x0B};
	  HAL_UART_Transmit(&amp;amp;huart1, req, sizeof(req), 100);
	  if(HAL_UART_Receive(&amp;amp;huart1, res, 9, 100) == HAL_OK){
	 		//USART2로 출력!
	 		HAL_UART_Transmit(&amp;amp;huart2, &quot;res = &quot;, 6, 100);
	 		for(int i = 0;i&amp;lt;9;i++){
	 		  sprintf(tx_buff,&quot;%02X, &quot;,res[i]);
	 		  HAL_UART_Transmit(&amp;amp;huart2, tx_buff, strlen(tx_buff), 100);
	 	  }
	 	  HAL_UART_Transmit(&amp;amp;huart2, &quot;\n&quot;, 1, 100);
	 	  //온도 res[3] + res[4]
	 	  //습도 res[5] + res[6]
	 	  int16_t temp = (res[3] &amp;lt;&amp;lt; 8) | res[4];
	 	  uint16_t humi = (res[5] &amp;lt;&amp;lt; 8) | res[6];
	 	  sprintf(tx_buff,&quot;temp = %.1f, humi = %.1f\n&quot;,temp/10.0,humi/10.0);
	 	  HAL_UART_Transmit(&amp;amp;huart2, tx_buff, strlen(tx_buff), 100);
	 	  //1602LCD에 출력하기
	 	  LCD_CLEAR();
	 	  sprintf(line1,&quot;TEMP = %.1f'C&quot;,temp/10.0);
	 	  sprintf(line2,&quot;HUMI = %.1f%c&quot;,humi/10.0,'%');
	 	  LCD_XY(0, 0) ; LCD_PUTS(line1);
	 	  LCD_XY(0, 1) ; LCD_PUTS(line2);
	   }
	  HAL_Delay(1000);
 }&lt;/code&gt;&lt;/pre&gt;</description>
      <category>프로그래밍/STM32</category>
      <author>덕력킹</author>
      <guid isPermaLink="true">https://bota.tistory.com/2466</guid>
      <comments>https://bota.tistory.com/2466#entry2466comment</comments>
      <pubDate>Wed, 31 Dec 2025 17:01:16 +0900</pubDate>
    </item>
    <item>
      <title>[STM32#23] RS485 to TTL모듈을 이용해서 modbus rtu로 4채널릴레이(relay)와 온습도센서(XY-MD02) 제어하는 방법!(녹칸다 내맘대로 STM32)</title>
      <link>https://bota.tistory.com/2465</link>
      <description>&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;stm32.png&quot; data-origin-width=&quot;1920&quot; data-origin-height=&quot;1080&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/COrx9/dJMcahJPpN9/epEFgsHIpUk7T0bsKCsEDK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/COrx9/dJMcahJPpN9/epEFgsHIpUk7T0bsKCsEDK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/COrx9/dJMcahJPpN9/epEFgsHIpUk7T0bsKCsEDK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FCOrx9%2FdJMcahJPpN9%2FepEFgsHIpUk7T0bsKCsEDK%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;1920&quot; height=&quot;1080&quot; data-filename=&quot;stm32.png&quot; data-origin-width=&quot;1920&quot; data-origin-height=&quot;1080&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/live/oMZoDk0ourA&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://youtube.com/live/oMZoDk0ourA&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/watch?v=oMZoDk0ourA&quot; data-video-thumbnail=&quot;https://scrap.kakaocdn.net/dn/bPQz49/hyZQJiutrC/pmwM60029Dav8TCuhhBFIk/img.jpg?width=1280&amp;amp;height=720&amp;amp;face=0_0_1280_720,https://scrap.kakaocdn.net/dn/bxULpN/hyZQwx4EMf/PQzkHXnTW8ReJRNPSgvpZK/img.jpg?width=1280&amp;amp;height=720&amp;amp;face=0_0_1280_720,https://scrap.kakaocdn.net/dn/bORDNr/hyZQKhoFJP/riUwdFmmqzrDz0UEpvkbmk/img.jpg?width=1280&amp;amp;height=720&amp;amp;face=0_0_1280_720&quot; data-video-width=&quot;860&quot; data-video-height=&quot;484&quot; data-video-origin-width=&quot;860&quot; data-video-origin-height=&quot;484&quot; data-ke-mobilestyle=&quot;widthContent&quot; data-video-title=&quot;[STM32#23] RS485 to TTL모듈을 이용해서 modbus rtu로 4채널릴레이(relay)와 온습도센서(XY-MD02) 제어하는 방&quot; data-original-url=&quot;&quot;&gt;&lt;iframe src=&quot;https://www.youtube.com/embed/oMZoDk0ourA&quot; width=&quot;860&quot; height=&quot;484&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;[STM32#23]&amp;nbsp;RS485&amp;nbsp;to&amp;nbsp;TTL모듈을&amp;nbsp;이용해서&amp;nbsp;modbus&amp;nbsp;rtu로&amp;nbsp;4채널릴레이(relay)와&amp;nbsp;온습도센서(XY-MD02)&amp;nbsp;제어하는&amp;nbsp;방법!(녹칸다&amp;nbsp;내맘대로&amp;nbsp;STM32) &lt;br /&gt;&lt;br /&gt;심심한녹칸다의&amp;nbsp;내맘대로&amp;nbsp;STM32시리즈이다! &lt;br /&gt;&lt;br /&gt;STM32시리즈의&amp;nbsp;모든&amp;nbsp;자료는&amp;nbsp;구글&amp;nbsp;슬라이드에&amp;nbsp;작성하고&amp;nbsp;모두에게&amp;nbsp;공유되어있음! &lt;br /&gt;&lt;a href=&quot;https://docs.google.com/presentation/d/1myA5iYbjuKsLWLqtRLKAiRfwUwvqB1d1RGjiMIIgp3I/edit?slide=id.g3ab12818c94_4_1#slide=id.g3ab12818c94_4_1&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://docs.google.com/presentation/d/1myA5iYbjuKsLWLqtRLKAiRfwUwvqB1d1RGjiMIIgp3I/edit?slide=id.g3ab12818c94_4_1#slide=id.g3ab12818c94_4_1&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;산업용&amp;nbsp;통신인&amp;nbsp;modbus&amp;nbsp;rtu를&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;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;01.PNG&quot; data-origin-width=&quot;977&quot; data-origin-height=&quot;552&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bmvwcC/dJMcaiWeg2O/7ewIwa5ztWlm2Yow8y0XZK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bmvwcC/dJMcaiWeg2O/7ewIwa5ztWlm2Yow8y0XZK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bmvwcC/dJMcaiWeg2O/7ewIwa5ztWlm2Yow8y0XZK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbmvwcC%2FdJMcaiWeg2O%2F7ewIwa5ztWlm2Yow8y0XZK%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;977&quot; height=&quot;552&quot; data-filename=&quot;01.PNG&quot; data-origin-width=&quot;977&quot; data-origin-height=&quot;552&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;br /&gt;1.STM32가&amp;nbsp;RS485릴레이의&amp;nbsp;채널0을&amp;nbsp;1초간격으로&amp;nbsp;on/off하도록&amp;nbsp;하시오!&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;1.PNG&quot; data-origin-width=&quot;832&quot; data-origin-height=&quot;531&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/q2aup/dJMcajnhf67/419IfvGkLhDsnWgTe5KZEK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/q2aup/dJMcajnhf67/419IfvGkLhDsnWgTe5KZEK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/q2aup/dJMcajnhf67/419IfvGkLhDsnWgTe5KZEK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fq2aup%2FdJMcajnhf67%2F419IfvGkLhDsnWgTe5KZEK%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;832&quot; height=&quot;531&quot; data-filename=&quot;1.PNG&quot; data-origin-width=&quot;832&quot; data-origin-height=&quot;531&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;pre id=&quot;code_1767017986268&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 */
 uint8_t on_req[] = {0x01,0x05,0x00,0x00,0xFF,0x00,0x8C,0x3A};
 uint8_t off_req[] = {0x01,0x05,0x00,0x00,0x00,0x00,0xCD,0xCA};
 uint8_t res[8];
 uint8_t tx_buff[100];
 /* USER CODE END 2 */
 /* Infinite loop */
 /* USER CODE BEGIN WHILE */
 while (1)
 {
	  //채널0 ON명령어 전송!(01 05 00 00 FF 00 8C 3A)
	  HAL_UART_Transmit(&amp;amp;huart1, on_req, sizeof(on_req), 100);
	  HAL_UART_Transmit(&amp;amp;huart2, &quot;on_req sent!\n&quot;, 13, 100);
	  //릴레이로부터 응답을 수신함!
	  //HAL_Delay(100);
	  if(HAL_UART_Receive(&amp;amp;huart1, res, 8, 100) == HAL_OK){
		  //USART2로 출력!
		  HAL_UART_Transmit(&amp;amp;huart2, &quot;res = &quot;, 6, 100);
		  for(int i = 0;i&amp;lt;8;i++){
			  sprintf(tx_buff,&quot;%02X, &quot;,res[i]);
			  HAL_UART_Transmit(&amp;amp;huart2, tx_buff, strlen(tx_buff), 100);
		  }
		  HAL_UART_Transmit(&amp;amp;huart2, &quot;\n&quot;, 1, 100);
	  }
	  HAL_Delay(1000);

	  //채널0 OFF명령어 전송!(01 05 00 00 00 00 CD CA)
	  HAL_UART_Transmit(&amp;amp;huart1, off_req, sizeof(off_req), 100);
	  HAL_UART_Transmit(&amp;amp;huart2, &quot;off_req sent!\n&quot;, 14, 100);
	  //HAL_Delay(100);
	  //릴레이로부터 응답을 수신함!
	  if(HAL_UART_Receive(&amp;amp;huart1, res, 8, 100) == HAL_OK){
		  //USART2로 출력!
		  HAL_UART_Transmit(&amp;amp;huart2, &quot;res = &quot;, 6, 100);
		  for(int i = 0;i&amp;lt;8;i++){
			  sprintf(tx_buff,&quot;%02X, &quot;,res[i]);
			  HAL_UART_Transmit(&amp;amp;huart2, tx_buff, strlen(tx_buff), 100);
		  }
		  HAL_UART_Transmit(&amp;amp;huart2, &quot;\n&quot;, 1, 100);
	  }
	  HAL_Delay(1000);
   /* USER CODE END WHILE */
   /* USER CODE BEGIN 3 */
 }&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;br /&gt;2.녹칸다의&amp;nbsp;STM32쉴드에&amp;nbsp;붙어있는&amp;nbsp;버튼&amp;nbsp;8개를&amp;nbsp;이용해서&amp;nbsp;4채널&amp;nbsp;릴레이를&amp;nbsp;모두&amp;nbsp;on/off할수있는&amp;nbsp;기능을&amp;nbsp;구현하시오!&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;2.PNG&quot; data-origin-width=&quot;830&quot; data-origin-height=&quot;502&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cMEm6O/dJMcab3T8tY/Fn89EcwKjtMvI4xw4A9pG0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cMEm6O/dJMcab3T8tY/Fn89EcwKjtMvI4xw4A9pG0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cMEm6O/dJMcab3T8tY/Fn89EcwKjtMvI4xw4A9pG0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FcMEm6O%2FdJMcab3T8tY%2FFn89EcwKjtMvI4xw4A9pG0%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;830&quot; height=&quot;502&quot; data-filename=&quot;2.PNG&quot; data-origin-width=&quot;830&quot; data-origin-height=&quot;502&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;pre id=&quot;code_1767018000743&quot; class=&quot;cpp&quot; data-ke-language=&quot;cpp&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;/* USER CODE BEGIN 0 */
uint8_t nockanda_req[][8] = {
		{0x01,0x05,0x00,0x00,0xFF,0x00,0x8C,0x3A},
		{0x01,0x05,0x00,0x00,0x00,0x00,0xCD,0xCA},
		{0x01,0x05,0x00,0x01,0xFF,0x00,0xDD,0xFA},
		{0x01,0x05,0x00,0x01,0x00,0x00,0x9C,0x0A},
		{0x01,0x05,0x00,0x02,0xFF,0x00,0x2D,0xFA},
		{0x01,0x05,0x00,0x02,0x00,0x00,0x6C,0x0A},
		{0x01,0x05,0x00,0x03,0xFF,0x00,0x7C,0x3A},
		{0x01,0x05,0x00,0x03,0x00,0x00,0x3D,0xCA}
};
uint8_t res[8];
uint8_t tx_buff[100];
//btn_num은 0부터 7까지 눌려진 버튼의 번호이다!
void control_relay(int btn_num){
	//채널0 ON명령어 전송!(01 05 00 00 FF 00 8C 3A)
   HAL_UART_Transmit(&amp;amp;huart1, nockanda_req[btn_num], sizeof(nockanda_req[btn_num]), 100);
   HAL_UART_Transmit(&amp;amp;huart2, &quot;on_req sent!\n&quot;, 13, 100);
   //릴레이로부터 응답을 수신함!
   //HAL_Delay(100);
   if(HAL_UART_Receive(&amp;amp;huart1, res, 8, 100) == HAL_OK){
	    //USART2로 출력!
	    HAL_UART_Transmit(&amp;amp;huart2, &quot;res = &quot;, 6, 100);
	    for(int i = 0;i&amp;lt;8;i++){
	  	  sprintf(tx_buff,&quot;%02X, &quot;,res[i]);
		  HAL_UART_Transmit(&amp;amp;huart2, tx_buff, strlen(tx_buff), 100);
	  }
	  HAL_UART_Transmit(&amp;amp;huart2, &quot;\n&quot;, 1, 100);
   }
   HAL_Delay(200);
}
/* USER CODE END 0 */

while (1)
 {
	  if(HAL_GPIO_ReadPin(GPIOB, GPIO_PIN_1) == 0) control_relay(0);
	  if(HAL_GPIO_ReadPin(GPIOA, GPIO_PIN_8) == 0) control_relay(2);
	  if(HAL_GPIO_ReadPin(GPIOB, GPIO_PIN_2) == 0) control_relay(4);
	  if(HAL_GPIO_ReadPin(GPIOB, GPIO_PIN_6) == 0) control_relay(6);
	  if(HAL_GPIO_ReadPin(GPIOC, GPIO_PIN_5) == 0) control_relay(1);
	  if(HAL_GPIO_ReadPin(GPIOC, GPIO_PIN_7) == 0) control_relay(3);
	  if(HAL_GPIO_ReadPin(GPIOA, GPIO_PIN_11) == 0) control_relay(5);
	  if(HAL_GPIO_ReadPin(GPIOA, GPIO_PIN_12) == 0) control_relay(7);
   /* USER CODE END WHILE */
   /* USER CODE BEGIN 3 */
 }&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;br /&gt;3.예제2에서&amp;nbsp;릴레이를&amp;nbsp;제어하는&amp;nbsp;8개의&amp;nbsp;커맨드가&amp;nbsp;있는데,&amp;nbsp;각&amp;nbsp;커맨드의&amp;nbsp;CRC16을&amp;nbsp;계산하는&amp;nbsp;함수를&amp;nbsp;이용해서&amp;nbsp;CRC16만&amp;nbsp;계산해서&amp;nbsp;출력하시오!&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;3.PNG&quot; data-origin-width=&quot;507&quot; data-origin-height=&quot;376&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/VUOQl/dJMcaiPrYwV/Zk7GMkLWShPd5NGGVp6ty1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/VUOQl/dJMcaiPrYwV/Zk7GMkLWShPd5NGGVp6ty1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/VUOQl/dJMcaiPrYwV/Zk7GMkLWShPd5NGGVp6ty1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FVUOQl%2FdJMcaiPrYwV%2FZk7GMkLWShPd5NGGVp6ty1%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;507&quot; height=&quot;376&quot; data-filename=&quot;3.PNG&quot; data-origin-width=&quot;507&quot; data-origin-height=&quot;376&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;pre id=&quot;code_1767018014258&quot; class=&quot;cpp&quot; data-ke-language=&quot;cpp&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;/* USER CODE BEGIN 0 */
uint8_t nockanda_req[][8] = {
		{0x01,0x05,0x00,0x00,0xFF,0x00,0x8C,0x3A}, //0
		{0x01,0x05,0x00,0x00,0x00,0x00,0xCD,0xCA}, //1
		{0x01,0x05,0x00,0x01,0xFF,0x00,0xDD,0xFA}, //2
		{0x01,0x05,0x00,0x01,0x00,0x00,0x9C,0x0A}, //3
		{0x01,0x05,0x00,0x02,0xFF,0x00,0x2D,0xFA}, //4
		{0x01,0x05,0x00,0x02,0x00,0x00,0x6C,0x0A}, //5
		{0x01,0x05,0x00,0x03,0xFF,0x00,0x7C,0x3A}, //6
		{0x01,0x05,0x00,0x03,0x00,0x00,0x3D,0xCA} //7
};
uint8_t res[8];
uint8_t tx_buff[100];
//함수의 프로토타입 선언
void control_relay(int btn_num);
uint16_t cal_crc(uint8_t *data, uint8_t len);
//btn_num은 0부터 7까지 눌려진 버튼의 번호이다!
void control_relay(int btn_num){
	uint16_t crc16 = cal_crc(nockanda_req[btn_num],6);
	sprintf(tx_buff,&quot;btn_num= %d, crc16= %04x\n&quot;,btn_num,crc16);
	HAL_UART_Transmit(&amp;amp;huart2, tx_buff, strlen(tx_buff), 100);
   HAL_Delay(200);
}


uint16_t cal_crc(uint8_t *data, uint8_t len)
{
   uint16_t crc = 0xFFFF;
   for(uint8_t i = 0; i &amp;lt; len; i++)
   {
       crc ^= data[i];   // LSB부터 XOR
       for(uint8_t j = 0; j &amp;lt; 8; j++)
       {
           if(crc &amp;amp; 0x0001)
           {
               crc &amp;gt;&amp;gt;= 1;
               crc ^= 0xA001;   // Modbus polynomial
           }
           else
           {
               crc &amp;gt;&amp;gt;= 1;
           }
       }
   }
   return crc;
}
while (1)
 {
	  if(HAL_GPIO_ReadPin(GPIOB, GPIO_PIN_1) == 0) control_relay(0);
	  if(HAL_GPIO_ReadPin(GPIOA, GPIO_PIN_8) == 0) control_relay(2);
	  if(HAL_GPIO_ReadPin(GPIOB, GPIO_PIN_2) == 0) control_relay(4);
	  if(HAL_GPIO_ReadPin(GPIOB, GPIO_PIN_6) == 0) control_relay(6);
	  if(HAL_GPIO_ReadPin(GPIOC, GPIO_PIN_5) == 0) control_relay(1);
	  if(HAL_GPIO_ReadPin(GPIOC, GPIO_PIN_7) == 0) control_relay(3);
	  if(HAL_GPIO_ReadPin(GPIOA, GPIO_PIN_11) == 0) control_relay(5);
	  if(HAL_GPIO_ReadPin(GPIOA, GPIO_PIN_12) == 0) control_relay(7);
   /* USER CODE END WHILE */
   /* USER CODE BEGIN 3 */
 }&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;br /&gt;4.modbus&amp;nbsp;rtu명령어에서&amp;nbsp;CRC16자리를&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-filename=&quot;4.PNG&quot; data-origin-width=&quot;666&quot; data-origin-height=&quot;557&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/p6BJL/dJMcafZw5PC/KQtuKt6t1WFeoqpozS1tG1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/p6BJL/dJMcafZw5PC/KQtuKt6t1WFeoqpozS1tG1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/p6BJL/dJMcafZw5PC/KQtuKt6t1WFeoqpozS1tG1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fp6BJL%2FdJMcafZw5PC%2FKQtuKt6t1WFeoqpozS1tG1%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;666&quot; height=&quot;557&quot; data-filename=&quot;4.PNG&quot; data-origin-width=&quot;666&quot; data-origin-height=&quot;557&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;pre id=&quot;code_1767018026701&quot; class=&quot;cpp&quot; data-ke-language=&quot;cpp&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;/* USER CODE BEGIN 0 */
uint8_t nockanda_req[][8] = {
		{0x01,0x05,0x00,0x00,0xFF,0x00,0x00,0x00}, //0
		{0x01,0x05,0x00,0x00,0x00,0x00,0x00,0x00}, //1
		{0x01,0x05,0x00,0x01,0xFF,0x00,0x00,0x00}, //2
		{0x01,0x05,0x00,0x01,0x00,0x00,0x00,0x00}, //3
		{0x01,0x05,0x00,0x02,0xFF,0x00,0x00,0x00}, //4
		{0x01,0x05,0x00,0x02,0x00,0x00,0x00,0x00}, //5
		{0x01,0x05,0x00,0x03,0xFF,0x00,0x00,0x00}, //6
		{0x01,0x05,0x00,0x03,0x00,0x00,0x00,0x00} //7
};
uint8_t res[8];
uint8_t tx_buff[100];
//함수의 프로토타입 선언
void control_relay(int btn_num);
uint16_t cal_crc(uint8_t *data, uint8_t len);
//btn_num은 0부터 7까지 눌려진 버튼의 번호이다!
void control_relay(int btn_num){
	uint16_t crc16 = cal_crc(nockanda_req[btn_num],6);
	nockanda_req[btn_num][6] = crc16 &amp;amp; 0x00FF; //CRC_L
	nockanda_req[btn_num][7] = crc16 &amp;gt;&amp;gt; 8; //CRC_H
	HAL_UART_Transmit(&amp;amp;huart1, nockanda_req[btn_num], sizeof(nockanda_req[btn_num]), 100);
  HAL_UART_Transmit(&amp;amp;huart2, &quot;on_req sent!\n&quot;, 13, 100);
  //릴레이로부터 응답을 수신함!
  //HAL_Delay(100);
  if(HAL_UART_Receive(&amp;amp;huart1, res, 8, 100) == HAL_OK){
		//USART2로 출력!
		HAL_UART_Transmit(&amp;amp;huart2, &quot;res = &quot;, 6, 100);
		for(int i = 0;i&amp;lt;8;i++){
		  sprintf(tx_buff,&quot;%02X, &quot;,res[i]);
		  HAL_UART_Transmit(&amp;amp;huart2, tx_buff, strlen(tx_buff), 100);
	  }
	  HAL_UART_Transmit(&amp;amp;huart2, &quot;\n&quot;, 1, 100);
  }
   HAL_Delay(200);
}

uint16_t cal_crc(uint8_t *data, uint8_t len)
{
   uint16_t crc = 0xFFFF;
   for(uint8_t i = 0; i &amp;lt; len; i++)
   {
       crc ^= data[i];   // LSB부터 XOR
       for(uint8_t j = 0; j &amp;lt; 8; j++)
       {
           if(crc &amp;amp; 0x0001)
           {
               crc &amp;gt;&amp;gt;= 1;
               crc ^= 0xA001;   // Modbus polynomial
           }
           else
           {
               crc &amp;gt;&amp;gt;= 1;
           }
       }
   }
   return crc;
}
while (1)
 {
	  if(HAL_GPIO_ReadPin(GPIOB, GPIO_PIN_1) == 0) control_relay(0);
	  if(HAL_GPIO_ReadPin(GPIOA, GPIO_PIN_8) == 0) control_relay(2);
	  if(HAL_GPIO_ReadPin(GPIOB, GPIO_PIN_2) == 0) control_relay(4);
	  if(HAL_GPIO_ReadPin(GPIOB, GPIO_PIN_6) == 0) control_relay(6);
	  if(HAL_GPIO_ReadPin(GPIOC, GPIO_PIN_5) == 0) control_relay(1);
	  if(HAL_GPIO_ReadPin(GPIOC, GPIO_PIN_7) == 0) control_relay(3);
	  if(HAL_GPIO_ReadPin(GPIOA, GPIO_PIN_11) == 0) control_relay(5);
	  if(HAL_GPIO_ReadPin(GPIOA, GPIO_PIN_12) == 0) control_relay(7);
   /* USER CODE END WHILE */
   /* USER CODE BEGIN 3 */
 }&lt;/code&gt;&lt;/pre&gt;</description>
      <category>프로그래밍/STM32</category>
      <author>덕력킹</author>
      <guid isPermaLink="true">https://bota.tistory.com/2465</guid>
      <comments>https://bota.tistory.com/2465#entry2465comment</comments>
      <pubDate>Mon, 29 Dec 2025 23:21:44 +0900</pubDate>
    </item>
    <item>
      <title>[STM32#22] freeRTOS를 적용해서 녹칸다의 STM32쉴드에 붙어있는 여러가지 부분에 응용해보기!(녹칸다 내맘대로 STM32)</title>
      <link>https://bota.tistory.com/2464</link>
      <description>&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;stm32.png&quot; data-origin-width=&quot;1920&quot; data-origin-height=&quot;1080&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/btLCz8/dJMcaf6gUPK/vL6SRKOty8xT3wZwkI8gnK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/btLCz8/dJMcaf6gUPK/vL6SRKOty8xT3wZwkI8gnK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/btLCz8/dJMcaf6gUPK/vL6SRKOty8xT3wZwkI8gnK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbtLCz8%2FdJMcaf6gUPK%2FvL6SRKOty8xT3wZwkI8gnK%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;1920&quot; height=&quot;1080&quot; data-filename=&quot;stm32.png&quot; data-origin-width=&quot;1920&quot; data-origin-height=&quot;1080&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/live/snS0bWdWQZw&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://youtube.com/live/snS0bWdWQZw&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/watch?v=snS0bWdWQZw&quot; data-video-thumbnail=&quot;https://scrap.kakaocdn.net/dn/bASYII/hyZPGfXeq8/5kz0Xjn52BN01U9EgEEDOk/img.jpg?width=1280&amp;amp;height=720&amp;amp;face=0_0_1280_720,https://scrap.kakaocdn.net/dn/6iicR/hyZQAeQDsH/ViAxHzVaumcOUxT6OSd6K0/img.jpg?width=1280&amp;amp;height=720&amp;amp;face=0_0_1280_720&quot; data-video-width=&quot;860&quot; data-video-height=&quot;484&quot; data-video-origin-width=&quot;860&quot; data-video-origin-height=&quot;484&quot; data-ke-mobilestyle=&quot;widthContent&quot; data-video-title=&quot;[STM32#22] freeRTOS를 적용해서 녹칸다의 STM32쉴드에 붙어있는 여러가지 부분에 응용해보기!(녹칸다 &quot; data-original-url=&quot;&quot;&gt;&lt;iframe src=&quot;https://www.youtube.com/embed/snS0bWdWQZw&quot; width=&quot;860&quot; height=&quot;484&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;[STM32#22]&amp;nbsp;freeRTOS를&amp;nbsp;적용해서&amp;nbsp;녹칸다의&amp;nbsp;STM32쉴드에&amp;nbsp;붙어있는&amp;nbsp;여러가지&amp;nbsp;부분에&amp;nbsp;응용해보기!(녹칸다&amp;nbsp;내맘대로&amp;nbsp;STM32) &lt;br /&gt;&lt;br /&gt;심심한녹칸다의&amp;nbsp;내맘대로&amp;nbsp;STM32시리즈이다! &lt;br /&gt;&lt;br /&gt;STM32시리즈의&amp;nbsp;모든&amp;nbsp;자료는&amp;nbsp;구글&amp;nbsp;슬라이드에&amp;nbsp;작성하고&amp;nbsp;모두에게&amp;nbsp;공유되어있음! &lt;br /&gt;&lt;a href=&quot;https://docs.google.com/presentation/d/1myA5iYbjuKsLWLqtRLKAiRfwUwvqB1d1RGjiMIIgp3I/edit?slide=id.g3b2ee18b41b_9_216#slide=id.g3b2ee18b41b_9_216&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://docs.google.com/presentation/d/1myA5iYbjuKsLWLqtRLKAiRfwUwvqB1d1RGjiMIIgp3I/edit?slide=id.g3b2ee18b41b_9_216#slide=id.g3b2ee18b41b_9_216&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;아주&amp;nbsp;약간만&amp;nbsp;응용하고&amp;nbsp;넘어가버리기! &lt;br /&gt;&lt;br /&gt;1.로터리엔코더와&amp;nbsp;부저를&amp;nbsp;조합해서&amp;nbsp;아래와&amp;nbsp;같이&amp;nbsp;2개의&amp;nbsp;task를&amp;nbsp;rtos로&amp;nbsp;작동시키시오! &lt;br /&gt;task1:로터리엔코더를&amp;nbsp;돌리면&amp;nbsp;LED8개가&amp;nbsp;시계방향&amp;nbsp;혹은&amp;nbsp;반시계방향으로&amp;nbsp;회전한다!&amp;nbsp; &lt;br /&gt;task2:버튼5개를&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-filename=&quot;01.PNG&quot; data-origin-width=&quot;1298&quot; data-origin-height=&quot;583&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/V6Ric/dJMcafrFpr8/KCJJJrjeSNNJSIDh5Jqed1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/V6Ric/dJMcafrFpr8/KCJJJrjeSNNJSIDh5Jqed1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/V6Ric/dJMcafrFpr8/KCJJJrjeSNNJSIDh5Jqed1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FV6Ric%2FdJMcafrFpr8%2FKCJJJrjeSNNJSIDh5Jqed1%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;1298&quot; height=&quot;583&quot; data-filename=&quot;01.PNG&quot; data-origin-width=&quot;1298&quot; data-origin-height=&quot;583&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;pre id=&quot;code_1766558292345&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 */
GPIO_TypeDef *mygroup[] = {GPIOB,GPIOB,GPIOB,GPIOB,GPIOB,GPIOB,GPIOC,GPIOB};
uint16_t mypin[] = {GPIO_PIN_3,GPIO_PIN_13,GPIO_PIN_5,GPIO_PIN_14,GPIO_PIN_4,GPIO_PIN_15,GPIO_PIN_4,GPIO_PIN_7};
void set_led(int num){
	//LED의 상태 업데이트 현재 켜져야하는 LED는 CNT번째꺼
	  for(int i = 0;i&amp;lt;8;i++){
		  if(i == num){
			  HAL_GPIO_WritePin(mygroup[i],mypin[i],GPIO_PIN_SET);
		  }else{
			  HAL_GPIO_WritePin(mygroup[i],mypin[i],GPIO_PIN_RESET);
		  }
	  }
}
static void Tone(uint32_t Frequency)
{
  TIM3-&amp;gt;ARR = (1000000UL / Frequency) - 1; //주파수
  TIM3-&amp;gt;CCR3 = (TIM3-&amp;gt;ARR &amp;gt;&amp;gt; 1); //듀티비 50%
}
#define NOTE_C6  1047 //도
#define NOTE_D6  1175 //레
#define NOTE_E6  1319 //미
#define NOTE_F6  1397 //파
#define NOTE_G6  1568 //솔
#define NOTE_A6  1760 //라
#define NOTE_B6  1976 //시
#define NOTE_C7  2093 //도
/* USER CODE END 4 */

void StartDefaultTask(void *argument)
{
 /* USER CODE BEGIN 5 */
 uint8_t old_A = 0;
 int cnt = 0;
 //시작하자마자 일단 12시방향의 LED는 1개 켜고 출발한다!
 HAL_GPIO_WritePin(mygroup[0],mypin[0],GPIO_PIN_SET);
 /* Infinite loop */
 for(;;)
 {
	  //녹칸다가 풀업방식으로 연결해놓음
	  uint8_t sw = HAL_GPIO_ReadPin(GPIOC,GPIO_PIN_7);
	  if(sw == 0){
		  HAL_UART_Transmit(&amp;amp;huart2, &quot;SW\n&quot;, 3, 100);
		  HAL_Delay(200);
	  }
	  //PA11의 상승엣지가 발생했을때
	  uint8_t now_A = HAL_GPIO_ReadPin(GPIOA,GPIO_PIN_11);
	  if(old_A == 0 &amp;amp;&amp;amp; now_A == 1){
		  //PA12의 값을 측정해서 LOW면 시계, HIGH면 반시계
		  uint8_t now_B = HAL_GPIO_ReadPin(GPIOA,GPIO_PIN_12);
		  if(now_B){
			 //반시계
			  cnt--;
			  if(cnt &amp;lt; 0) cnt = 7;
			  set_led(cnt);
		  }else{
			 //시계
			  cnt++;
			  if(cnt &amp;gt; 7) cnt = 0;
			  set_led(cnt);
		  }
	  }
	  old_A = now_A;
     osDelay(1); //1밀리초 지연~
 }
 /* USER CODE END 5 */
}

void StartTask02(void *argument)
{
 /* USER CODE BEGIN StartTask02 */
 HAL_TIM_PWM_Start(&amp;amp;htim3,TIM_CHANNEL_3);
 HAL_GPIO_WritePin(GPIOC, GPIO_PIN_2, 0);
 /* Infinite loop */
 for(;;)
 {
	  if(HAL_GPIO_ReadPin(GPIOB,GPIO_PIN_1) == 0){
		  HAL_GPIO_WritePin(GPIOC, GPIO_PIN_2, 1);
		  Tone(NOTE_C6);
	  }else if(HAL_GPIO_ReadPin(GPIOA,GPIO_PIN_8) == 0){
		  HAL_GPIO_WritePin(GPIOC, GPIO_PIN_2, 1);
		  Tone(NOTE_D6);
	  }else if(HAL_GPIO_ReadPin(GPIOB,GPIO_PIN_2) == 0){
		  HAL_GPIO_WritePin(GPIOC, GPIO_PIN_2, 1);
		  Tone(NOTE_E6);
	  }else if(HAL_GPIO_ReadPin(GPIOB,GPIO_PIN_6) == 0){
		  HAL_GPIO_WritePin(GPIOC, GPIO_PIN_2, 1);
		  Tone(NOTE_F6);
	  }else if(HAL_GPIO_ReadPin(GPIOC,GPIO_PIN_5) == 0){
		  HAL_GPIO_WritePin(GPIOC, GPIO_PIN_2, 1);
		  Tone(NOTE_G6);
	  }else{
		  //소리를 끈다
		  HAL_GPIO_WritePin(GPIOC, GPIO_PIN_2, 0);
	  }
 }
 /* USER CODE END StartTask02 */
}&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;br /&gt;2.로터리엔코더+TM1637와&amp;nbsp;가변저항을&amp;nbsp;조합해서&amp;nbsp;아래와&amp;nbsp;같이&amp;nbsp;2개의&amp;nbsp;task를&amp;nbsp;rtos로&amp;nbsp;작동시키시오! &lt;br /&gt;task1:로터리엔코더를&amp;nbsp;시계방향으로&amp;nbsp;돌리면&amp;nbsp;1씩&amp;nbsp;증가하고&amp;nbsp;반시계방향으로&amp;nbsp;돌리면&amp;nbsp;1씩&amp;nbsp;감소하는&amp;nbsp;카운터값이&amp;nbsp;있는데,&amp;nbsp;그&amp;nbsp;값을&amp;nbsp;FND모듈인&amp;nbsp;TM1637에&amp;nbsp;출력하시오! &lt;br /&gt;task2:PA0에&amp;nbsp;연결된&amp;nbsp;가변저항값을&amp;nbsp;ADC로&amp;nbsp;읽어들여서&amp;nbsp;USART2로&amp;nbsp;시리얼&amp;nbsp;출력하시오!&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;02.PNG&quot; data-origin-width=&quot;1046&quot; data-origin-height=&quot;545&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/d4e86S/dJMcafrFpse/yZ4XberpuLwnIlAfGk0RA1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/d4e86S/dJMcafrFpse/yZ4XberpuLwnIlAfGk0RA1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/d4e86S/dJMcafrFpse/yZ4XberpuLwnIlAfGk0RA1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fd4e86S%2FdJMcafrFpse%2FyZ4XberpuLwnIlAfGk0RA1%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;1046&quot; height=&quot;545&quot; data-filename=&quot;02.PNG&quot; data-origin-width=&quot;1046&quot; data-origin-height=&quot;545&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;pre id=&quot;code_1766558346152&quot; class=&quot;cpp&quot; data-ke-language=&quot;cpp&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;/* USER CODE BEGIN 0 */
//주고받는 데이터 (사용자 정의)
typedef struct {
   uint16_t id;
   int16_t value;
} Msg_t;
//메시지 큐(전역)
osMessageQueueId_t dataQueue;
/* USER CODE END 0 */


/* USER CODE BEGIN 2 */
 //메시지큐(메인)
 dataQueue = osMessageQueueNew(
                   8,              // queue length
                   sizeof(Msg_t),  // item size
                   NULL);
 /* USER CODE END 2 */


void DWT_Delay_Init(void)
{
   CoreDebug-&amp;gt;DEMCR |= CoreDebug_DEMCR_TRCENA_Msk;
   DWT-&amp;gt;CYCCNT = 0;
   DWT-&amp;gt;CTRL |= DWT_CTRL_CYCCNTENA_Msk;
}
void delay_us(uint32_t us)
{
   uint32_t cycles = (SystemCoreClock / 1000000) * us;
   uint32_t start = DWT-&amp;gt;CYCCNT;
   while ((DWT-&amp;gt;CYCCNT - start) &amp;lt; cycles);
}
// TM1637 7세그먼트 숫자 코드 매핑
const char segmentMap[] = {
  0x3f, 0x06, 0x5b, 0x4f,
  0x66, 0x6d, 0x7d, 0x07,
  0x7f, 0x6f, 0x77, 0x7c,
  0x39, 0x5e, 0x79, 0x71,
  0x00
};
// GPIOB 클럭 활성화 매크로
#define PORTB_CLK_ENABLE() (RCC-&amp;gt;APB2ENR |= RCC_APB2ENR_IOPBEN)
// PB8, PB9 핀 사용 (GPIOB)
// PB8 = CLK, PB9 = DIO
// CLK와 DIO 핀 제어 함수
static inline void _tm1637ClkHigh(void) { GPIOB-&amp;gt;BSRR = (1 &amp;lt;&amp;lt; 8); } // CLK HIGH
static inline void _tm1637ClkLow(void)  { GPIOB-&amp;gt;BRR = (1 &amp;lt;&amp;lt; 8); }  // CLK LOW
static inline void _tm1637DioHigh(void) { GPIOB-&amp;gt;BSRR = (1 &amp;lt;&amp;lt; 9); } // DIO HIGH
static inline void _tm1637DioLow(void)  { GPIOB-&amp;gt;BRR = (1 &amp;lt;&amp;lt; 9); }  // DIO LOW
// 마이크로초 단위 딜레이
void _tm1637DelayUsec(unsigned int i)
{
	delay_us(i); // 사용자 정의 delay_us 함수 사용
}

// TM1637 초기화 함수 (GPIO 출력 설정)
void tm1637Init(void)
{
  PORTB_CLK_ENABLE(); // GPIOB 클럭 활성화
  // GPIOB CRH 초기화 (PB8, PB9 출력 2MHz Push-Pull)
  GPIOB-&amp;gt;CRH &amp;amp;= ~((0xF &amp;lt;&amp;lt; 0) | (0xF &amp;lt;&amp;lt; 4)); // 해당 비트 클리어
  GPIOB-&amp;gt;CRH |= (0x2 &amp;lt;&amp;lt; 0); // PB8: MODE=10(출력 2MHz), CNF=00(Push-Pull)
  GPIOB-&amp;gt;CRH |= (0x2 &amp;lt;&amp;lt; 4); // PB9: MODE=10(출력 2MHz), CNF=00(Push-Pull)
  tm1637SetBrightness(8); // 밝기 최대
}
// TM1637 시작 신호
void _tm1637Start(void)
{
  _tm1637ClkHigh();
  _tm1637DioHigh();
  _tm1637DelayUsec(20);
  _tm1637DioLow(); // START 조건: DIO LOW
}
// TM1637 종료 신호
void _tm1637Stop(void)
{
  _tm1637ClkLow();
  _tm1637DelayUsec(20);
  _tm1637DioLow();
  _tm1637DelayUsec(20);
  _tm1637ClkHigh();
  _tm1637DelayUsec(20);
  _tm1637DioHigh(); // STOP 조건: DIO HIGH
}

// TM1637 ACK 무시 (결과 확인용)
void _tm1637ReadResult(void)
{
  _tm1637ClkLow();
  _tm1637DelayUsec(50);
  // DIO 상태 확인, ACK 처리 (여기서는 실제 확인 없이 무시)
  _tm1637ClkHigh();
  _tm1637DelayUsec(20);
  _tm1637ClkLow();
}
// TM1637 1바이트 전송
void _tm1637WriteByte(unsigned char b)
{
  for (int i = 0; i &amp;lt; 8; ++i) {
      _tm1637ClkLow();
      if (b &amp;amp; 0x01) {
          _tm1637DioHigh();
      } else {
          _tm1637DioLow();
      }
      _tm1637DelayUsec(30);
      b &amp;gt;&amp;gt;= 1; // 다음 비트로 이동
      _tm1637ClkHigh();
      _tm1637DelayUsec(30);
  }
}
// 밝기 설정 (0~8, 0 = 꺼짐)
void tm1637SetBrightness(char brightness)
{
  _tm1637Start();
  _tm1637WriteByte(0x87 + brightness); // 밝기 명령어
  _tm1637ReadResult();
  _tm1637Stop();
}

// 4자리 10진수 표시 (displaySeparator=1이면 3번째 자리 점 켬)
void tm1637DisplayDecimal(int v, int displaySeparator)
{
  unsigned char digitArr[4];
  int isNegative = 0;
  if (v &amp;lt; 0) {
      isNegative = 1;
      v = -v;
  }
  // 숫자를 segmentMap으로 변환
  for (int i = 0; i &amp;lt; 4; ++i) {
      digitArr[i] = segmentMap[v % 10];
      if (i == 2 &amp;amp;&amp;amp; displaySeparator) {
          digitArr[i] |= 1 &amp;lt;&amp;lt; 7; // 점(DP) 켬
      }
      v /= 10;
  }
  // 음수 표시
  if (isNegative) {
      digitArr[3] = 0x40; // '-' 표시
  }
  // TM1637에 데이터 전송
  _tm1637Start();
  _tm1637WriteByte(0x40); // 자동 주소 증가 모드
  _tm1637ReadResult();
  _tm1637Stop();
  _tm1637Start();
  _tm1637WriteByte(0xc0); // 시작 주소 0
  _tm1637ReadResult();
  for (int i = 0; i &amp;lt; 4; ++i) {
      _tm1637WriteByte(digitArr[3 - i]); // 3-&amp;gt;0 순서로 전송
      _tm1637ReadResult();
  }
  _tm1637Stop();
}

// 4자리 10진수 표시 (앞자리 0 제거, displaySeparator=1이면 점 켬)
void tm1637DisplayDecimalTrim(int v, int displaySeparator)
{
  unsigned char digitArr[4];
  int isNegative = 0;
  if (v &amp;lt; 0) {
      isNegative = 1;
      v = -v;
  }
  // 숫자를 segmentMap으로 변환
  for (int i = 0; i &amp;lt; 4; ++i) {
      digitArr[i] = segmentMap[v % 10];
      if (i == 2 &amp;amp;&amp;amp; displaySeparator) {
          digitArr[i] |= 1 &amp;lt;&amp;lt; 7; // 점(DP) 켬
      }
      v /= 10;
  }
  // 앞자리 0 제거 (공백 처리)
  int leadingZero = 1;
  for (int i = 3; i &amp;gt;= 0; --i) {
      if (digitArr[i] != segmentMap[0] || i == 0) {
          leadingZero = 0;
      }
      if (leadingZero &amp;amp;&amp;amp; digitArr[i] == segmentMap[0]) {
          digitArr[i] = 0x00; // 공백
      }
  }
  // 음수 표시
  if (isNegative) {
      digitArr[3] = 0x40; // '-'
  }

  // TM1637에 데이터 전송
  _tm1637Start();
  _tm1637WriteByte(0x40); // 자동 주소 증가 모드
  _tm1637ReadResult();
  _tm1637Stop();
  _tm1637Start();
  _tm1637WriteByte(0xC0); // 시작 주소 0
  _tm1637ReadResult();
  for (int i = 0; i &amp;lt; 4; ++i) {
      _tm1637WriteByte(digitArr[3 - i]); // 3-&amp;gt;0 순서로 전송
      _tm1637ReadResult();
  }
  _tm1637Stop();
}
void tm1637SetRawSegment(uint8_t position, uint8_t segData)
{
  // 주소 범위 보호
  if (position &amp;gt; 3) return;
  _tm1637Start();
  _tm1637WriteByte(0x40);      // 데이터 입력 모드
  _tm1637ReadResult();
  _tm1637Stop();
  _tm1637Start();
  _tm1637WriteByte(0xC0 + position);   // 자리 선택
  _tm1637ReadResult();
  _tm1637WriteByte(segData);           // 세그먼트 데이터 전송
  _tm1637ReadResult();
  _tm1637Stop();
}
/* USER CODE END 4 */&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;br /&gt;3.예제2에서&amp;nbsp;task1의&amp;nbsp;기능을&amp;nbsp;다음과&amp;nbsp;같이&amp;nbsp;수정하시오!(앗&amp;nbsp;usart2에&amp;nbsp;출력하는걸로&amp;nbsp;충돌발생) &lt;br /&gt;task1:로터리엔코더를&amp;nbsp;시계방향으로&amp;nbsp;돌리면&amp;nbsp;1씩&amp;nbsp;증가하고&amp;nbsp;반시계방향으로&amp;nbsp;돌리면&amp;nbsp;1씩&amp;nbsp;감소하는&amp;nbsp;카운터값이&amp;nbsp;있는데,&amp;nbsp;그&amp;nbsp;값을&amp;nbsp;task3에&amp;nbsp;메시지큐로&amp;nbsp;전송한다! &lt;br /&gt;task2:PA0에&amp;nbsp;연결된&amp;nbsp;가변저항값을&amp;nbsp;ADC로&amp;nbsp;읽어들여서&amp;nbsp;task3에&amp;nbsp;메시지큐로&amp;nbsp;전송한다! &lt;br /&gt;task3:task1과&amp;nbsp;task2에서&amp;nbsp;받은&amp;nbsp;메시지를&amp;nbsp;usart2로&amp;nbsp;출력한다!&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;03.PNG&quot; data-origin-width=&quot;990&quot; data-origin-height=&quot;524&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/smPOu/dJMcai2WCjA/K1HkOPeRS11KwIPO4zkUj0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/smPOu/dJMcai2WCjA/K1HkOPeRS11KwIPO4zkUj0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/smPOu/dJMcai2WCjA/K1HkOPeRS11KwIPO4zkUj0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FsmPOu%2FdJMcai2WCjA%2FK1HkOPeRS11KwIPO4zkUj0%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;990&quot; height=&quot;524&quot; data-filename=&quot;03.PNG&quot; data-origin-width=&quot;990&quot; data-origin-height=&quot;524&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;pre id=&quot;code_1766558387461&quot; class=&quot;cpp&quot; data-ke-language=&quot;cpp&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;/* USER CODE BEGIN 0 */
//주고받는 데이터 (사용자 정의)
typedef struct {
   uint16_t id;
   int16_t value;
} Msg_t;
//메시지 큐(전역)
osMessageQueueId_t dataQueue;
/* USER CODE END 0 */


/* USER CODE BEGIN 2 */
 //메시지큐(메인)
 dataQueue = osMessageQueueNew(
                   8,              // queue length
                   sizeof(Msg_t),  // item size
                   NULL);
 /* USER CODE END 2 */


void DWT_Delay_Init(void)
{
   CoreDebug-&amp;gt;DEMCR |= CoreDebug_DEMCR_TRCENA_Msk;
   DWT-&amp;gt;CYCCNT = 0;
   DWT-&amp;gt;CTRL |= DWT_CTRL_CYCCNTENA_Msk;
}
void delay_us(uint32_t us)
{
   uint32_t cycles = (SystemCoreClock / 1000000) * us;
   uint32_t start = DWT-&amp;gt;CYCCNT;
   while ((DWT-&amp;gt;CYCCNT - start) &amp;lt; cycles);
}
// TM1637 7세그먼트 숫자 코드 매핑
const char segmentMap[] = {
  0x3f, 0x06, 0x5b, 0x4f,
  0x66, 0x6d, 0x7d, 0x07,
  0x7f, 0x6f, 0x77, 0x7c,
  0x39, 0x5e, 0x79, 0x71,
  0x00
};
// GPIOB 클럭 활성화 매크로
#define PORTB_CLK_ENABLE() (RCC-&amp;gt;APB2ENR |= RCC_APB2ENR_IOPBEN)
// PB8, PB9 핀 사용 (GPIOB)
// PB8 = CLK, PB9 = DIO
// CLK와 DIO 핀 제어 함수
static inline void _tm1637ClkHigh(void) { GPIOB-&amp;gt;BSRR = (1 &amp;lt;&amp;lt; 8); } // CLK HIGH
static inline void _tm1637ClkLow(void)  { GPIOB-&amp;gt;BRR = (1 &amp;lt;&amp;lt; 8); }  // CLK LOW
static inline void _tm1637DioHigh(void) { GPIOB-&amp;gt;BSRR = (1 &amp;lt;&amp;lt; 9); } // DIO HIGH
static inline void _tm1637DioLow(void)  { GPIOB-&amp;gt;BRR = (1 &amp;lt;&amp;lt; 9); }  // DIO LOW
// 마이크로초 단위 딜레이
void _tm1637DelayUsec(unsigned int i)
{
	delay_us(i); // 사용자 정의 delay_us 함수 사용
}

// TM1637 초기화 함수 (GPIO 출력 설정)
void tm1637Init(void)
{
  PORTB_CLK_ENABLE(); // GPIOB 클럭 활성화
  // GPIOB CRH 초기화 (PB8, PB9 출력 2MHz Push-Pull)
  GPIOB-&amp;gt;CRH &amp;amp;= ~((0xF &amp;lt;&amp;lt; 0) | (0xF &amp;lt;&amp;lt; 4)); // 해당 비트 클리어
  GPIOB-&amp;gt;CRH |= (0x2 &amp;lt;&amp;lt; 0); // PB8: MODE=10(출력 2MHz), CNF=00(Push-Pull)
  GPIOB-&amp;gt;CRH |= (0x2 &amp;lt;&amp;lt; 4); // PB9: MODE=10(출력 2MHz), CNF=00(Push-Pull)
  tm1637SetBrightness(8); // 밝기 최대
}
// TM1637 시작 신호
void _tm1637Start(void)
{
  _tm1637ClkHigh();
  _tm1637DioHigh();
  _tm1637DelayUsec(20);
  _tm1637DioLow(); // START 조건: DIO LOW
}
// TM1637 종료 신호
void _tm1637Stop(void)
{
  _tm1637ClkLow();
  _tm1637DelayUsec(20);
  _tm1637DioLow();
  _tm1637DelayUsec(20);
  _tm1637ClkHigh();
  _tm1637DelayUsec(20);
  _tm1637DioHigh(); // STOP 조건: DIO HIGH
}

// TM1637 ACK 무시 (결과 확인용)
void _tm1637ReadResult(void)
{
  _tm1637ClkLow();
  _tm1637DelayUsec(50);
  // DIO 상태 확인, ACK 처리 (여기서는 실제 확인 없이 무시)
  _tm1637ClkHigh();
  _tm1637DelayUsec(20);
  _tm1637ClkLow();
}
// TM1637 1바이트 전송
void _tm1637WriteByte(unsigned char b)
{
  for (int i = 0; i &amp;lt; 8; ++i) {
      _tm1637ClkLow();
      if (b &amp;amp; 0x01) {
          _tm1637DioHigh();
      } else {
          _tm1637DioLow();
      }
      _tm1637DelayUsec(30);
      b &amp;gt;&amp;gt;= 1; // 다음 비트로 이동
      _tm1637ClkHigh();
      _tm1637DelayUsec(30);
  }
}
// 밝기 설정 (0~8, 0 = 꺼짐)
void tm1637SetBrightness(char brightness)
{
  _tm1637Start();
  _tm1637WriteByte(0x87 + brightness); // 밝기 명령어
  _tm1637ReadResult();
  _tm1637Stop();
}

// 4자리 10진수 표시 (displaySeparator=1이면 3번째 자리 점 켬)
void tm1637DisplayDecimal(int v, int displaySeparator)
{
  unsigned char digitArr[4];
  int isNegative = 0;
  if (v &amp;lt; 0) {
      isNegative = 1;
      v = -v;
  }
  // 숫자를 segmentMap으로 변환
  for (int i = 0; i &amp;lt; 4; ++i) {
      digitArr[i] = segmentMap[v % 10];
      if (i == 2 &amp;amp;&amp;amp; displaySeparator) {
          digitArr[i] |= 1 &amp;lt;&amp;lt; 7; // 점(DP) 켬
      }
      v /= 10;
  }
  // 음수 표시
  if (isNegative) {
      digitArr[3] = 0x40; // '-' 표시
  }
  // TM1637에 데이터 전송
  _tm1637Start();
  _tm1637WriteByte(0x40); // 자동 주소 증가 모드
  _tm1637ReadResult();
  _tm1637Stop();
  _tm1637Start();
  _tm1637WriteByte(0xc0); // 시작 주소 0
  _tm1637ReadResult();
  for (int i = 0; i &amp;lt; 4; ++i) {
      _tm1637WriteByte(digitArr[3 - i]); // 3-&amp;gt;0 순서로 전송
      _tm1637ReadResult();
  }
  _tm1637Stop();
}

// 4자리 10진수 표시 (앞자리 0 제거, displaySeparator=1이면 점 켬)
void tm1637DisplayDecimalTrim(int v, int displaySeparator)
{
  unsigned char digitArr[4];
  int isNegative = 0;
  if (v &amp;lt; 0) {
      isNegative = 1;
      v = -v;
  }
  // 숫자를 segmentMap으로 변환
  for (int i = 0; i &amp;lt; 4; ++i) {
      digitArr[i] = segmentMap[v % 10];
      if (i == 2 &amp;amp;&amp;amp; displaySeparator) {
          digitArr[i] |= 1 &amp;lt;&amp;lt; 7; // 점(DP) 켬
      }
      v /= 10;
  }
  // 앞자리 0 제거 (공백 처리)
  int leadingZero = 1;
  for (int i = 3; i &amp;gt;= 0; --i) {
      if (digitArr[i] != segmentMap[0] || i == 0) {
          leadingZero = 0;
      }
      if (leadingZero &amp;amp;&amp;amp; digitArr[i] == segmentMap[0]) {
          digitArr[i] = 0x00; // 공백
      }
  }
  // 음수 표시
  if (isNegative) {
      digitArr[3] = 0x40; // '-'
  }

  // TM1637에 데이터 전송
  _tm1637Start();
  _tm1637WriteByte(0x40); // 자동 주소 증가 모드
  _tm1637ReadResult();
  _tm1637Stop();
  _tm1637Start();
  _tm1637WriteByte(0xC0); // 시작 주소 0
  _tm1637ReadResult();
  for (int i = 0; i &amp;lt; 4; ++i) {
      _tm1637WriteByte(digitArr[3 - i]); // 3-&amp;gt;0 순서로 전송
      _tm1637ReadResult();
  }
  _tm1637Stop();
}
void tm1637SetRawSegment(uint8_t position, uint8_t segData)
{
  // 주소 범위 보호
  if (position &amp;gt; 3) return;
  _tm1637Start();
  _tm1637WriteByte(0x40);      // 데이터 입력 모드
  _tm1637ReadResult();
  _tm1637Stop();
  _tm1637Start();
  _tm1637WriteByte(0xC0 + position);   // 자리 선택
  _tm1637ReadResult();
  _tm1637WriteByte(segData);           // 세그먼트 데이터 전송
  _tm1637ReadResult();
  _tm1637Stop();
}
/* USER CODE END 4 */




void StartDefaultTask(void *argument)
{
 /* USER CODE BEGIN 5 */
 DWT_Delay_Init();
 tm1637Init();
 int cnt = 0;
 //초기값 출력하기~
 tm1637DisplayDecimalTrim(cnt,0);
 uint8_t old_rot_A = 0;
 Msg_t msg;
 msg.id = 1;
 /* Infinite loop */
 for(;;)
 {
	  if(HAL_GPIO_ReadPin(GPIOC, GPIO_PIN_7) == 0){
		  cnt = 0;
		  tm1637DisplayDecimalTrim(cnt,0);
		  //cnt값을 메시지큐에 넣는다!
		  msg.value = cnt;
		  osMessageQueuePut(dataQueue, &amp;amp;msg, 0, 0); //송신
	  }
	  uint8_t now_rot_A = HAL_GPIO_ReadPin(GPIOA, GPIO_PIN_11);
	  if(now_rot_A == 1 &amp;amp;&amp;amp; old_rot_A == 0){
		  uint8_t now_rot_B = HAL_GPIO_ReadPin(GPIOA, GPIO_PIN_12);
		  if(now_rot_B){
			  //CCW
			  cnt--;
		  }else{
			  //CW
			  cnt++;
		  }
		  tm1637DisplayDecimalTrim(cnt,0);
		  msg.value = cnt;
		  osMessageQueuePut(dataQueue, &amp;amp;msg, 0, 0); //송신
	  }
	  old_rot_A = now_rot_A;
	  osDelay(1);
 }
 /* USER CODE END 5 */
}

void StartTask02(void *argument)
{
 /* USER CODE BEGIN StartTask02 */
 HAL_ADC_Start(&amp;amp;hadc1); //딱 한번만 호출
 uint16_t adc_value0 = 0;
 Msg_t msg;
 msg.id  = 2;
 /* Infinite loop */
 for(;;)
 {
	  //측정할때마다 호출
	  if(HAL_ADC_PollForConversion(&amp;amp;hadc1, 10) == HAL_OK)
	  {
		  // 값 처리
		  adc_value0 = HAL_ADC_GetValue(&amp;amp;hadc1); //0~4095
		  msg.value = adc_value0;
		  osMessageQueuePut(dataQueue, &amp;amp;msg, 0, 0); //송신
	  }
	  osDelay(100);
 }
 /* USER CODE END StartTask02 */
}
void StartTask03(void *argument)
{
 /* USER CODE BEGIN StartTask03 */
 Msg_t msg;
 char buff[50];
 /* Infinite loop */
 for(;;)
 {
	  osMessageQueueGet(dataQueue, &amp;amp;msg, NULL, osWaitForever);
	  sprintf(buff,&quot;id = %d, value= %d\n&quot;,msg.id,msg.value);
	  HAL_UART_Transmit(&amp;amp;huart2,buff,strlen(buff),100);
 }
 /* USER CODE END StartTask03 */
}&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;br /&gt;4.온습도센서와&amp;nbsp;가변저항과&amp;nbsp;1602LCD의&amp;nbsp;조합으로&amp;nbsp;아래와&amp;nbsp;같이&amp;nbsp;3개의&amp;nbsp;task를&amp;nbsp;구성하시오! &lt;br /&gt;task1:0.1초간격으로&amp;nbsp;1씩&amp;nbsp;증가하는&amp;nbsp;카운터값을&amp;nbsp;task3에&amp;nbsp;메시지큐로&amp;nbsp;전송한다! &lt;br /&gt;task2:PA0에&amp;nbsp;연결된&amp;nbsp;가변저항값을&amp;nbsp;ADC로&amp;nbsp;읽어들여서&amp;nbsp;task3에&amp;nbsp;메시지큐로&amp;nbsp;전송한다! &lt;br /&gt;task3:task1과&amp;nbsp;task2에서&amp;nbsp;받은&amp;nbsp;메시지를&amp;nbsp;1602LCD에&amp;nbsp;출력하는데,&amp;nbsp;task1의&amp;nbsp;값은&amp;nbsp;첫번째&amp;nbsp;line에&amp;nbsp;출력하고&amp;nbsp;가변저항값은&amp;nbsp;두번째&amp;nbsp;line에&amp;nbsp;출력하시오!&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;04.PNG&quot; data-origin-width=&quot;977&quot; data-origin-height=&quot;451&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/8FuSt/dJMcai2WCjJ/SXwgTMagZQeDt2fiodwMN0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/8FuSt/dJMcai2WCjJ/SXwgTMagZQeDt2fiodwMN0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/8FuSt/dJMcai2WCjJ/SXwgTMagZQeDt2fiodwMN0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2F8FuSt%2FdJMcai2WCjJ%2FSXwgTMagZQeDt2fiodwMN0%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;977&quot; height=&quot;451&quot; data-filename=&quot;04.PNG&quot; data-origin-width=&quot;977&quot; data-origin-height=&quot;451&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;pre id=&quot;code_1766558417880&quot; class=&quot;cpp&quot; data-ke-language=&quot;cpp&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;/* USER CODE BEGIN 0 */
//주고받는 데이터 (사용자 정의)
typedef struct {
   uint16_t id;
   int16_t value;
} Msg_t;
//메시지 큐(전역)
osMessageQueueId_t dataQueue;
/* USER CODE END 0 */
/* USER CODE BEGIN 2 */
 //메시지큐(메인)
 dataQueue = osMessageQueueNew(
                   8,              // queue length
                   sizeof(Msg_t),  // item size
                   NULL);
 /* USER CODE END 2 */
/* USER CODE BEGIN 4 */
void DWT_Delay_Init(void)
{
   CoreDebug-&amp;gt;DEMCR |= CoreDebug_DEMCR_TRCENA_Msk;
   DWT-&amp;gt;CYCCNT = 0;
   DWT-&amp;gt;CTRL |= DWT_CTRL_CYCCNTENA_Msk;
}
void delay_us(uint32_t us)
{
   uint32_t cycles = (SystemCoreClock / 1000000) * us;
   uint32_t start = DWT-&amp;gt;CYCCNT;
   while ((DWT-&amp;gt;CYCCNT - start) &amp;lt; cycles);
}
#define delay_ms osDelay
#define ADDRESS   0x27&amp;lt;&amp;lt;1
#define RS1_EN1   0x05
#define RS1_EN0   0x01
#define RS0_EN1   0x04
#define RS0_EN0   0x00
#define BackLight 0x08

// RS-Q0 / RW-Q1 / EN-Q2 / BackLight-Q3 / D4-Q4 / D5-Q5 / D6-Q6 / D7-Q7
void LCD_DATA(uint8_t data) {
uint8_t temp=(data &amp;amp; 0xF0)|RS1_EN1|BackLight;
while(HAL_I2C_Master_Transmit(&amp;amp;hi2c1, ADDRESS, &amp;amp;temp, 1, 1000)!=HAL_OK);
temp=(data &amp;amp; 0xF0)|RS1_EN0|BackLight;
while(HAL_I2C_Master_Transmit(&amp;amp;hi2c1, ADDRESS, &amp;amp;temp, 1, 1000)!=HAL_OK);
delay_us(4);
temp=((data &amp;lt;&amp;lt; 4) &amp;amp; 0xF0)|RS1_EN1|BackLight;
while(HAL_I2C_Master_Transmit(&amp;amp;hi2c1, ADDRESS, &amp;amp;temp, 1, 1000)!=HAL_OK);
temp = ((data &amp;lt;&amp;lt; 4) &amp;amp; 0xF0)|RS1_EN0|BackLight;
while(HAL_I2C_Master_Transmit(&amp;amp;hi2c1, ADDRESS, &amp;amp;temp, 1, 1000)!=HAL_OK);
delay_us(50);
}
void LCD_CMD(uint8_t cmd) {
uint8_t temp=(cmd &amp;amp; 0xF0)|RS0_EN1|BackLight;
while(HAL_I2C_Master_Transmit(&amp;amp;hi2c1, ADDRESS, &amp;amp;temp, 1, 1000)!=HAL_OK);
temp=(cmd &amp;amp; 0xF0)|RS0_EN0|BackLight;
while(HAL_I2C_Master_Transmit(&amp;amp;hi2c1, ADDRESS, &amp;amp;temp, 1, 1000)!=HAL_OK);
delay_us(4);
temp=((cmd &amp;lt;&amp;lt; 4) &amp;amp; 0xF0)|RS0_EN1|BackLight;
while(HAL_I2C_Master_Transmit(&amp;amp;hi2c1, ADDRESS, &amp;amp;temp, 1, 1000)!=HAL_OK);
temp=((cmd &amp;lt;&amp;lt; 4) &amp;amp; 0xF0)|RS0_EN0|BackLight;
while(HAL_I2C_Master_Transmit(&amp;amp;hi2c1, ADDRESS, &amp;amp;temp, 1, 1000)!=HAL_OK);
delay_us(50);
}
void LCD_CMD_4bit(uint8_t cmd) {
uint8_t temp=((cmd &amp;lt;&amp;lt; 4) &amp;amp; 0xF0)|RS0_EN1|BackLight;
while(HAL_I2C_Master_Transmit(&amp;amp;hi2c1, ADDRESS, &amp;amp;temp, 1, 1000)!=HAL_OK);
temp=((cmd &amp;lt;&amp;lt; 4) &amp;amp; 0xF0)|RS0_EN0|BackLight;
while(HAL_I2C_Master_Transmit(&amp;amp;hi2c1, ADDRESS, &amp;amp;temp, 1, 1000)!=HAL_OK);
delay_us(50);
}

void LCD_INIT(void) {
delay_ms(100);
LCD_CMD_4bit(0x03); delay_ms(5);
LCD_CMD_4bit(0x03); delay_us(100);
LCD_CMD_4bit(0x03); delay_us(100);
LCD_CMD_4bit(0x02); delay_us(100);
LCD_CMD(0x28);  // 4 bits, 2 line, 5x8 font
LCD_CMD(0x08);  // display off, cursor off, blink off
LCD_CMD(0x01);  // clear display
delay_ms(3);
LCD_CMD(0x06);  // cursor movint direction
LCD_CMD(0x0C);  // display on, cursor off, blink off
}
void LCD_XY(char x, char y) {
if      (y == 0) LCD_CMD(0x80 + x);
else if (y == 1) LCD_CMD(0xC0 + x);
else if (y == 2) LCD_CMD(0x94 + x);
else if (y == 3) LCD_CMD(0xD4 + x);
}
void LCD_CLEAR(void) {
LCD_CMD(0x01);
delay_ms(2);
}
void LCD_PUTS(char *str) {
while (*str) LCD_DATA(*str++);
}
/* USER CODE END 4 */




void StartDefaultTask(void *argument)
{
 /* USER CODE BEGIN 5 */
	uint16_t cnt = 0;
	Msg_t msg;
	msg.id  = 1;
 /* Infinite loop */
 for(;;)
 {
	  cnt++;
	  msg.value = cnt;
	  osMessageQueuePut(dataQueue, &amp;amp;msg, 0, 0); //송신
	  osDelay(1000);
 }
}
void StartTask02(void *argument)
{
 HAL_ADC_Start(&amp;amp;hadc1); //딱 한번만 호출
 uint16_t adc_value0 = 0;
 Msg_t msg;
 msg.id  = 2;
 /* Infinite loop */
 for(;;)
 {
	  //측정할때마다 호출
	  if(HAL_ADC_PollForConversion(&amp;amp;hadc1, 10) == HAL_OK)
	  {
		  // 값 처리
		  adc_value0 = HAL_ADC_GetValue(&amp;amp;hadc1); //0~4095
		  msg.value = adc_value0;
		  osMessageQueuePut(dataQueue, &amp;amp;msg, 0, 0); //송신
	  }
	  osDelay(100);
 }
}

void StartTask03(void *argument)
{
 /* USER CODE BEGIN StartTask03 */
 Msg_t msg;
 char buff[50];
 DWT_Delay_Init(); //한번 호출하기~
 LCD_INIT(); //1회호출(메인루프 시작전)
 /* Infinite loop */
 for(;;)
 {
	  osMessageQueueGet(dataQueue, &amp;amp;msg, NULL, osWaitForever);
	  if(msg.id == 1){
		  sprintf(buff,&quot;cnt = %10d&quot;,msg.value);
		  LCD_XY(0, 0) ; LCD_PUTS(buff);
	  }else if(msg.id == 2){
		  sprintf(buff,&quot;PA0 value=%6d&quot;,msg.value);
		  LCD_XY(0, 1) ; LCD_PUTS(buff);
	  }
 }
 /* USER CODE END StartTask03 */
}&lt;/code&gt;&lt;/pre&gt;</description>
      <category>프로그래밍/STM32</category>
      <author>덕력킹</author>
      <guid isPermaLink="true">https://bota.tistory.com/2464</guid>
      <comments>https://bota.tistory.com/2464#entry2464comment</comments>
      <pubDate>Wed, 24 Dec 2025 15:42:12 +0900</pubDate>
    </item>
    <item>
      <title>[STM32#21] freeRTOS를 적용하는 방법과 메시지큐(osMessageQueueId_t)를 이용해서 데이터를 주고받는 방법 간단하게 알아보기!(녹칸다 내맘대로 STM32)</title>
      <link>https://bota.tistory.com/2463</link>
      <description>&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;stm32.png&quot; data-origin-width=&quot;1920&quot; data-origin-height=&quot;1080&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/qIBcX/dJMcaaYbIUk/s6tgaBQVKwkQ8xXrROio3k/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/qIBcX/dJMcaaYbIUk/s6tgaBQVKwkQ8xXrROio3k/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/qIBcX/dJMcaaYbIUk/s6tgaBQVKwkQ8xXrROio3k/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FqIBcX%2FdJMcaaYbIUk%2Fs6tgaBQVKwkQ8xXrROio3k%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;1920&quot; height=&quot;1080&quot; data-filename=&quot;stm32.png&quot; data-origin-width=&quot;1920&quot; data-origin-height=&quot;1080&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/live/vSkSt9_30jQ&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://youtube.com/live/vSkSt9_30jQ&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/watch?v=vSkSt9_30jQ&quot; data-video-thumbnail=&quot;https://scrap.kakaocdn.net/dn/bpHOwa/hyZPZGLlQl/V1ipu78YQms65VuPTtHFW0/img.jpg?width=1280&amp;amp;height=720&amp;amp;face=0_0_1280_720,https://scrap.kakaocdn.net/dn/cqHBIM/hyZPY8VRL5/8wOhWrZDDUVDCYQPRY1cYk/img.jpg?width=1280&amp;amp;height=720&amp;amp;face=0_0_1280_720,https://scrap.kakaocdn.net/dn/bU8XrP/hyZPPjsVB3/aoDH3BTtzPWGpLaUXOSvUK/img.jpg?width=1280&amp;amp;height=720&amp;amp;face=0_0_1280_720&quot; data-video-width=&quot;860&quot; data-video-height=&quot;484&quot; data-video-origin-width=&quot;860&quot; data-video-origin-height=&quot;484&quot; data-ke-mobilestyle=&quot;widthContent&quot; data-video-title=&quot;[STM32#21] freeRTOS를 적용하는 방법과 메시지큐(osMessageQueueId_t)를 이용해서 데이터를 주고받는 방법 &quot; data-original-url=&quot;&quot;&gt;&lt;iframe src=&quot;https://www.youtube.com/embed/vSkSt9_30jQ&quot; width=&quot;860&quot; height=&quot;484&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;[STM32#21]&amp;nbsp;freeRTOS를&amp;nbsp;적용하는&amp;nbsp;방법과&amp;nbsp;메시지큐(osMessageQueueId_t)를&amp;nbsp;이용해서&amp;nbsp;데이터를&amp;nbsp;주고받는&amp;nbsp;방법&amp;nbsp;간단하게&amp;nbsp;알아보기!(녹칸다&amp;nbsp;내맘대로&amp;nbsp;STM32) &lt;br /&gt;&lt;br /&gt;심심한녹칸다의&amp;nbsp;내맘대로&amp;nbsp;STM32시리즈이다! &lt;br /&gt;&lt;br /&gt;STM32시리즈의&amp;nbsp;모든&amp;nbsp;자료는&amp;nbsp;구글&amp;nbsp;슬라이드에&amp;nbsp;작성하고&amp;nbsp;모두에게&amp;nbsp;공유되어있음! &lt;br /&gt;&lt;a href=&quot;https://docs.google.com/presentation/d/1myA5iYbjuKsLWLqtRLKAiRfwUwvqB1d1RGjiMIIgp3I/edit?slide=id.g3b24791482c_1_0#slide=id.g3b24791482c_1_0&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://docs.google.com/presentation/d/1myA5iYbjuKsLWLqtRLKAiRfwUwvqB1d1RGjiMIIgp3I/edit?slide=id.g3b24791482c_1_0#slide=id.g3b24791482c_1_0&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;STM32에서&amp;nbsp;freeRTOS를&amp;nbsp;사용하는&amp;nbsp;방법을&amp;nbsp;아주&amp;nbsp;간단히만&amp;nbsp;알아보겠습니다! &lt;br /&gt;&lt;br /&gt;1.main&amp;nbsp;루프에서&amp;nbsp;HAL_getTick을&amp;nbsp;이용해서&amp;nbsp;2개의&amp;nbsp;task를&amp;nbsp;구현하는&amp;nbsp;방법에&amp;nbsp;대해서&amp;nbsp;보이시오! &lt;br /&gt;-task1&amp;nbsp;:&amp;nbsp;PB3을&amp;nbsp;1000밀리초&amp;nbsp;간격으로&amp;nbsp;깜빡인다! &lt;br /&gt;-task2&amp;nbsp;:&amp;nbsp;PB13을&amp;nbsp;1500밀리초&amp;nbsp;간격으로&amp;nbsp;깜빡인다!&lt;/p&gt;
&lt;pre id=&quot;code_1766412264080&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 */
 uint32_t t1 = 0;
 uint32_t t2 = 0;
 /* USER CODE END 2 */
 /* Infinite loop */
 /* USER CODE BEGIN WHILE */
 while (1)
 {
	  //-task1 : PB3을 1000밀리초 간격으로 깜빡인다!
	  if(HAL_GetTick() - t1 &amp;gt;= 1000){
		  t1 = HAL_GetTick();
		  HAL_GPIO_TogglePin(GPIOB, GPIO_PIN_3);
	  }
	  //-task2 : PB13을 1500밀리초 간격으로 깜빡인다!
	  if(HAL_GetTick() - t2 &amp;gt;= 1500){
		  t2 = HAL_GetTick();
		  HAL_GPIO_TogglePin(GPIOB, GPIO_PIN_13);
	  }
   /* USER CODE END WHILE */
   /* USER CODE BEGIN 3 */
 }&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;br /&gt;2.task1을&amp;nbsp;TIM1에&amp;nbsp;task2를&amp;nbsp;TIM2에&amp;nbsp;적용해서&amp;nbsp;LED를&amp;nbsp;깜빡이시오!&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;ioc2.PNG&quot; data-origin-width=&quot;1161&quot; data-origin-height=&quot;494&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/be7nkb/dJMcad1CDwL/YqVp89Tc5kFsskp3ZWAeDK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/be7nkb/dJMcad1CDwL/YqVp89Tc5kFsskp3ZWAeDK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/be7nkb/dJMcad1CDwL/YqVp89Tc5kFsskp3ZWAeDK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fbe7nkb%2FdJMcad1CDwL%2FYqVp89Tc5kFsskp3ZWAeDK%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;1161&quot; height=&quot;494&quot; data-filename=&quot;ioc2.PNG&quot; data-origin-width=&quot;1161&quot; data-origin-height=&quot;494&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;pre id=&quot;code_1766412274540&quot; class=&quot;cpp&quot; data-ke-language=&quot;cpp&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;/* USER CODE BEGIN 0 */
void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim)
{
   //TIM2일수도있고 TIM3일수도있고~
	if (htim-&amp;gt;Instance == TIM2)
	{
		// TASK1
		HAL_GPIO_TogglePin(GPIOB, GPIO_PIN_3);
	}
	else if (htim-&amp;gt;Instance == TIM3)
	{
		// TASK2
		HAL_GPIO_TogglePin(GPIOB, GPIO_PIN_13);
	}
}
/* USER CODE END 0 */

/* USER CODE BEGIN 2 */
 HAL_TIM_Base_Start_IT(&amp;amp;htim2);
 HAL_TIM_Base_Start_IT(&amp;amp;htim3);
 /* USER CODE END 2 */
 /* Infinite loop */
 /* USER CODE BEGIN WHILE */
 while (1)
 {
	  //메인루트에서는 할일 없음!
   /* USER CODE END WHILE */
   /* USER CODE BEGIN 3 */
 }&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;br /&gt;3.cubeide에서&amp;nbsp;tim1을&amp;nbsp;클락소스로&amp;nbsp;지정하고&amp;nbsp;rtos로&amp;nbsp;task2개를&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-filename=&quot;ioc3.PNG&quot; data-origin-width=&quot;1176&quot; data-origin-height=&quot;535&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bpKGz2/dJMb99LJOWC/1mLf2Z2Jn8r3or1kuGIvhk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bpKGz2/dJMb99LJOWC/1mLf2Z2Jn8r3or1kuGIvhk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bpKGz2/dJMb99LJOWC/1mLf2Z2Jn8r3or1kuGIvhk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbpKGz2%2FdJMb99LJOWC%2F1mLf2Z2Jn8r3or1kuGIvhk%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;1176&quot; height=&quot;535&quot; data-filename=&quot;ioc3.PNG&quot; data-origin-width=&quot;1176&quot; data-origin-height=&quot;535&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;pre id=&quot;code_1766412288040&quot; class=&quot;cpp&quot; data-ke-language=&quot;cpp&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;void StartDefaultTask(void *argument)
{
 /* USER CODE BEGIN 5 */
 /* Infinite loop */
 for(;;)
 {
	  //task1
	  HAL_GPIO_TogglePin(GPIOB, GPIO_PIN_3);
	  osDelay(1000);
 }
 /* USER CODE END 5 */
}

void StartTask02(void *argument)
{
 /* USER CODE BEGIN StartTask02 */
 /* Infinite loop */
 for(;;)
 {
	  //task2
	  HAL_GPIO_TogglePin(GPIOB, GPIO_PIN_13);
	  osDelay(1500);
 }
 /* USER CODE END StartTask02 */
}&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;br /&gt;4.아래와&amp;nbsp;같이&amp;nbsp;task를&amp;nbsp;구성해서&amp;nbsp;예제를&amp;nbsp;구현하시오! &lt;br /&gt;-task1&amp;nbsp;:&amp;nbsp;1000밀리초&amp;nbsp;간격으로&amp;nbsp;task1의&amp;nbsp;내부변수값을&amp;nbsp;usart2에&amp;nbsp;출력한다! &lt;br /&gt;-task2&amp;nbsp;:&amp;nbsp;1000밀리초&amp;nbsp;간격으로&amp;nbsp;task2의&amp;nbsp;내부변수값을&amp;nbsp;usart2에&amp;nbsp;출력한다!&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;04.PNG&quot; data-origin-width=&quot;276&quot; data-origin-height=&quot;203&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/VOVHS/dJMcafFcldV/Z9KkzZg33RWkqgNSiVMyZk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/VOVHS/dJMcafFcldV/Z9KkzZg33RWkqgNSiVMyZk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/VOVHS/dJMcafFcldV/Z9KkzZg33RWkqgNSiVMyZk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FVOVHS%2FdJMcafFcldV%2FZ9KkzZg33RWkqgNSiVMyZk%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;203&quot; data-filename=&quot;04.PNG&quot; data-origin-width=&quot;276&quot; data-origin-height=&quot;203&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;pre id=&quot;code_1766412298271&quot; class=&quot;cpp&quot; data-ke-language=&quot;cpp&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;void StartDefaultTask(void *argument)
{
 /* USER CODE BEGIN 5 */
 /* Infinite loop */
 int num = 1234;
 char buff[20];
 for(;;)
 {
	  //task1
	  sprintf(buff,&quot;TASK1=%d\n&quot;,num);
	  HAL_UART_Transmit(&amp;amp;huart2,buff,strlen(buff),100);
	  osDelay(1000);
 }
 /* USER CODE END 5 */
}
void StartTask02(void *argument)
{
 /* USER CODE BEGIN StartTask02 */
 /* Infinite loop */
 int num = 5678;
 char buff[20];
 for(;;)
 {
	  //task2
	  sprintf(buff,&quot;TASK2=%d\n&quot;,num);
	  HAL_UART_Transmit(&amp;amp;huart2,buff,strlen(buff),100);
	  osDelay(1000);
 }
 /* USER CODE END StartTask02 */
}&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;br /&gt;5.예제&amp;nbsp;4에서&amp;nbsp;아래와&amp;nbsp;같이&amp;nbsp;task를&amp;nbsp;구성하고&amp;nbsp;메시지큐를&amp;nbsp;활용해서&amp;nbsp;충돌이&amp;nbsp;나는것을&amp;nbsp;방지하시오! &lt;br /&gt;-task1&amp;nbsp;:&amp;nbsp;1000밀리초&amp;nbsp;간격으로&amp;nbsp;내부에&amp;nbsp;있는&amp;nbsp;변수값을&amp;nbsp;메시지큐에&amp;nbsp;넣는다!(생산자) &lt;br /&gt;-task2&amp;nbsp;:&amp;nbsp;1000밀리초&amp;nbsp;간격으로&amp;nbsp;내부에&amp;nbsp;있는&amp;nbsp;변수값을&amp;nbsp;메시지큐에&amp;nbsp;넣는다!(생산자) &lt;br /&gt;-task3&amp;nbsp;:&amp;nbsp;메시지큐에&amp;nbsp;있는&amp;nbsp;내용을&amp;nbsp;usart2에&amp;nbsp;출력한다!(소비자)&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;05.PNG&quot; data-origin-width=&quot;286&quot; data-origin-height=&quot;213&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/br8t1c/dJMcahXkgE0/KBM7wLLKXoquHozmioIT9k/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/br8t1c/dJMcahXkgE0/KBM7wLLKXoquHozmioIT9k/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/br8t1c/dJMcahXkgE0/KBM7wLLKXoquHozmioIT9k/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fbr8t1c%2FdJMcahXkgE0%2FKBM7wLLKXoquHozmioIT9k%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;286&quot; height=&quot;213&quot; data-filename=&quot;05.PNG&quot; data-origin-width=&quot;286&quot; data-origin-height=&quot;213&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;pre id=&quot;code_1766412314913&quot; class=&quot;cpp&quot; data-ke-language=&quot;cpp&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;/* USER CODE BEGIN 0 */
//주고받는 데이터 (사용자 정의)
typedef struct {
   uint16_t id;
   int value;
} Msg_t;
//메시지 큐(전역)
osMessageQueueId_t dataQueue;
/* USER CODE END 0 */
/* USER CODE BEGIN 2 */
 //메시지큐(메인)
 dataQueue = osMessageQueueNew(
                   8,              // queue length
                   sizeof(Msg_t),  // item size
                   NULL);
 /* USER CODE END 2 */

void StartDefaultTask(void *argument)
{
 /* USER CODE BEGIN 5 */
 /* Infinite loop */
 int num = 1234;
 Msg_t msg;
 msg.id  = 1;
 for(;;)
 {
	  //task1(공급자)
	  msg.value = num;
	  osMessageQueuePut(dataQueue, &amp;amp;msg, 0, 0); //non-blocking
	  osDelay(1000);
 }

void StartTask02(void *argument)
{
 /* USER CODE BEGIN StartTask02 */
 /* Infinite loop */
 int num = 5678;
 Msg_t msg;
 msg.id  = 2;
 for(;;)
 {
	  //task2(공급자)
	  msg.value = num;
	  osMessageQueuePut(dataQueue, &amp;amp;msg, 0, 0); //non-blocking
	  osDelay(1000);
 }
void StartTask03(void *argument)
{
 /* USER CODE BEGIN StartTask03 */
 /* Infinite loop */
 Msg_t msg;
 char buff[30];
 for(;;)
 {
	  //소비자
	  //dataQueue에 공급자가 넣은 데이터가 없으면 무한대기
	  osMessageQueueGet(dataQueue, &amp;amp;msg, NULL, osWaitForever); //blocking
	  sprintf(buff,&quot;id=%d, value=%d\n&quot;,msg.id,msg.value);
	  HAL_UART_Transmit(&amp;amp;huart2,buff,strlen(buff),100);
 }
 /* USER CODE END StartTask03 */
}&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;br /&gt;6.예제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;수&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-filename=&quot;06.PNG&quot; data-origin-width=&quot;287&quot; data-origin-height=&quot;241&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/ljBzP/dJMcaiu6DF3/PwwKchfznfQB34VkxWjJr1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/ljBzP/dJMcaiu6DF3/PwwKchfznfQB34VkxWjJr1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/ljBzP/dJMcaiu6DF3/PwwKchfznfQB34VkxWjJr1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FljBzP%2FdJMcaiu6DF3%2FPwwKchfznfQB34VkxWjJr1%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;241&quot; data-filename=&quot;06.PNG&quot; data-origin-width=&quot;287&quot; data-origin-height=&quot;241&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;pre id=&quot;code_1766412325857&quot; class=&quot;cpp&quot; data-ke-language=&quot;cpp&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;/* USER CODE BEGIN 0 */
//주고받는 데이터 (사용자 정의)
typedef struct {
   uint16_t id;
   int value;
} Msg_t;
//메시지 큐(전역)
osMessageQueueId_t dataQueue;
/* USER CODE END 0 */
/* USER CODE BEGIN 2 */
 //메시지큐(메인)
 dataQueue = osMessageQueueNew(
                   8,              // queue length
                   sizeof(Msg_t),  // item size
                   NULL);
 /* USER CODE END 2 */

void StartDefaultTask(void *argument)
{
 /* USER CODE BEGIN 5 */
 /* Infinite loop */
 int num = 1234;
 Msg_t msg;
 msg.id  = 1;
 for(;;)
 {
	  //task1(공급자)
	  msg.value = num;
	  if(osMessageQueuePut(dataQueue, &amp;amp;msg, 0, 0) == osOK){
		  //큐에 빈공간이 있어서 성공적으로 넣었다!
	  }else{
		  //큐에 빈공간이 없어서 실패했다!
	  }

	  osDelay(1000);
 }

void StartTask02(void *argument)
{
 /* USER CODE BEGIN StartTask02 */
 /* Infinite loop */
 int num = 5678;
 Msg_t msg;
 msg.id  = 2;
 for(;;)
 {
	  //task2(공급자)
	  msg.value = num;
	  if(osMessageQueuePut(dataQueue, &amp;amp;msg, 0, 0) == osOK){
		  //큐에 빈공간이 있어서 성공적으로 넣었다!
	  }else{
		  //큐에 빈공간이 없어서 실패했다!
	  }

	  osDelay(1000);
 }
void StartTask03(void *argument)
{
 /* USER CODE BEGIN StartTask03 */
 /* Infinite loop */
 Msg_t msg;
 char buff[30];
 for(;;)
 {
	  //소비자
	  //dataQueue에 공급자가 넣은 데이터가 없으면 무한대기
	  osMessageQueueGet(dataQueue, &amp;amp;msg, NULL, osWaitForever); //blocking
	  sprintf(buff,&quot;id=%d, value=%d\n&quot;,msg.id,msg.value);
	  HAL_UART_Transmit(&amp;amp;huart2,buff,strlen(buff),100);
 }
 /* USER CODE END StartTask03 */
}&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;br /&gt;7.아래와&amp;nbsp;같이&amp;nbsp;task를&amp;nbsp;구현해서&amp;nbsp;usart2로&amp;nbsp;출력하시오! &lt;br /&gt;-task1&amp;nbsp;:&amp;nbsp;1000밀리초&amp;nbsp;간격으로&amp;nbsp;num1의&amp;nbsp;값은&amp;nbsp;1씩&amp;nbsp;증가하고&amp;nbsp;num2의&amp;nbsp;값은&amp;nbsp;1씩&amp;nbsp;감소시켜서&amp;nbsp;큐에&amp;nbsp;넣는다! &lt;br /&gt;-task2&amp;nbsp;:&amp;nbsp;1000밀리초&amp;nbsp;간격으로&amp;nbsp;num1의&amp;nbsp;값은&amp;nbsp;1씩&amp;nbsp;증가하고&amp;nbsp;num2의&amp;nbsp;값은&amp;nbsp;1씩&amp;nbsp;감소시켜서&amp;nbsp;큐에&amp;nbsp;넣는다! &lt;br /&gt;-task3&amp;nbsp;:&amp;nbsp;메시지큐에&amp;nbsp;있는&amp;nbsp;내용을&amp;nbsp;usart2에&amp;nbsp;출력한다!(소비자)&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;07.PNG&quot; data-origin-width=&quot;862&quot; data-origin-height=&quot;336&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/3RyhD/dJMcaaqlJDf/jgkjdfyQ0yiYZVRCjhZU31/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/3RyhD/dJMcaaqlJDf/jgkjdfyQ0yiYZVRCjhZU31/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/3RyhD/dJMcaaqlJDf/jgkjdfyQ0yiYZVRCjhZU31/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2F3RyhD%2FdJMcaaqlJDf%2FjgkjdfyQ0yiYZVRCjhZU31%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;862&quot; height=&quot;336&quot; data-filename=&quot;07.PNG&quot; data-origin-width=&quot;862&quot; data-origin-height=&quot;336&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;pre id=&quot;code_1766412338118&quot; class=&quot;cpp&quot; data-ke-language=&quot;cpp&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;/* USER CODE BEGIN 0 */
//주고받는 데이터 (사용자 정의)
typedef struct {
   uint16_t id;
   int value1;
   int value2;
} Msg_t;
//메시지 큐(전역)
osMessageQueueId_t dataQueue;
/* USER CODE END 0 */
/* USER CODE BEGIN 2 */
 //메시지큐(메인)
 dataQueue = osMessageQueueNew(
                   8,              // queue length
                   sizeof(Msg_t),  // item size
                   NULL);
 /* USER CODE END 2 */

void StartDefaultTask(void *argument)
{
 /* USER CODE BEGIN 5 */
 /* Infinite loop */
 Msg_t msg = {1,0,0};
 for(;;)
 {
	  //task1(공급자)
	  msg.value1++;
	  msg.value2--;
	  if(osMessageQueuePut(dataQueue, &amp;amp;msg, 0, 0) == osOK){
		  //큐에 빈공간이 있어서 성공적으로 넣었다!
	  }else{
		  //큐에 빈공간이 없어서 실패했다!
	  }
	  osDelay(1000);
 }
 /* USER CODE END 5 */
}
void StartTask02(void *argument)
{
 /* USER CODE BEGIN StartTask02 */
 /* Infinite loop */
 Msg_t msg = {2,0,0};
 for(;;)
 {
	  //task2(공급자)
	  msg.value1++;
	  msg.value2--;
	  if(osMessageQueuePut(dataQueue, &amp;amp;msg, 0, 0) == osOK){
		  //큐에 빈공간이 있어서 성공적으로 넣었다!
	  }else{
		  //큐에 빈공간이 없어서 실패했다!
	  }
	  osDelay(1000);
 }
 /* USER CODE END StartTask02 */
}

void StartTask03(void *argument)
{
 /* USER CODE BEGIN StartTask03 */
 /* Infinite loop */
 Msg_t msg;
 char buff[30];
 for(;;)
 {
	  //소비자
	  //dataQueue에 공급자가 넣은 데이터가 없으면 무한대기
	  osMessageQueueGet(dataQueue, &amp;amp;msg, NULL, osWaitForever); //blocking
	  sprintf(buff,&quot;id=%d, value1=%d, value2=%d\n&quot;,msg.id,msg.value1,msg.value2);
	  HAL_UART_Transmit(&amp;amp;huart2,buff,strlen(buff),100);
 }
 /* USER CODE END StartTask03 */
}&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;br /&gt;8.아래와&amp;nbsp;같이&amp;nbsp;task를&amp;nbsp;구현하시오! &lt;br /&gt;-task1&amp;nbsp;:&amp;nbsp;100밀리초&amp;nbsp;간격으로&amp;nbsp;LED&amp;nbsp;8개가&amp;nbsp;링모양으로&amp;nbsp;순차적으로&amp;nbsp;켜진다! &lt;br /&gt;-task2&amp;nbsp;:&amp;nbsp;1초&amp;nbsp;간격으로&amp;nbsp;1씩&amp;nbsp;증가하는&amp;nbsp;카운터값을&amp;nbsp;usart2로&amp;nbsp;전송하시오!&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;08.PNG&quot; data-origin-width=&quot;727&quot; data-origin-height=&quot;412&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/qXKpY/dJMcajgtkoA/AY9RLGFCBo9tnfRhkGbRLK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/qXKpY/dJMcajgtkoA/AY9RLGFCBo9tnfRhkGbRLK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/qXKpY/dJMcajgtkoA/AY9RLGFCBo9tnfRhkGbRLK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FqXKpY%2FdJMcajgtkoA%2FAY9RLGFCBo9tnfRhkGbRLK%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;727&quot; height=&quot;412&quot; data-filename=&quot;08.PNG&quot; data-origin-width=&quot;727&quot; data-origin-height=&quot;412&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;pre id=&quot;code_1766412350125&quot; class=&quot;cpp&quot; data-ke-language=&quot;cpp&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;/* USER CODE BEGIN 0 */
GPIO_TypeDef *mygpio[] = {GPIOB,GPIOB,GPIOB,GPIOB,GPIOB,GPIOB,GPIOC,GPIOB};
uint16_t mypin[] = {GPIO_PIN_3,GPIO_PIN_13,GPIO_PIN_5,GPIO_PIN_14,GPIO_PIN_4,GPIO_PIN_15,GPIO_PIN_4,GPIO_PIN_7};
/* USER CODE END 0 */
void StartDefaultTask(void *argument)
{
 /* USER CODE BEGIN 5 */
 /* Infinite loop */
 int led_num = 0;
 for(;;)
 {
	  //task1
	  //100밀리초 간격으로 LED를 빙글빙글돌린다
	  for(int i = 0;i&amp;lt;8;i++){
		  //led_num와 i가 같은 녀석만 켜고 나머지는 끈다!
		  if(led_num == i){
			  HAL_GPIO_WritePin(mygpio[i], mypin[i], 1);
		  }else{
			  HAL_GPIO_WritePin(mygpio[i], mypin[i], 0);
		  }
	  }
	  led_num++;
	  if(led_num == 8) led_num = 0;
	  osDelay(100);
 }


void StartTask02(void *argument)
{
 /* USER CODE BEGIN StartTask02 */
 /* Infinite loop */
 int num = 0;
 char buff[30];
 for(;;)
 {
	  sprintf(buff,&quot;num = %d\n&quot;,num);
	  HAL_UART_Transmit(&amp;amp;huart2,buff,strlen(buff),100);
	  num++;
	  osDelay(1000);
 }
 /* USER CODE END StartTask02 */
}&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>프로그래밍/STM32</category>
      <author>덕력킹</author>
      <guid isPermaLink="true">https://bota.tistory.com/2463</guid>
      <comments>https://bota.tistory.com/2463#entry2463comment</comments>
      <pubDate>Mon, 22 Dec 2025 23:08:17 +0900</pubDate>
    </item>
    <item>
      <title>[STM32#20] usart1에 esp01을 연결해서 wifi에 연결하고 mqtt프로토콜을 이용해서 데이터를 전송하는 방법 알아보기!(녹칸다 내맘대로 STM32)</title>
      <link>https://bota.tistory.com/2462</link>
      <description>&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;stm32_2.png&quot; data-origin-width=&quot;1920&quot; data-origin-height=&quot;1080&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/RYzDG/dJMcagc0BXq/uKvm4cUK3QaKWAg0Dogi81/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/RYzDG/dJMcagc0BXq/uKvm4cUK3QaKWAg0Dogi81/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/RYzDG/dJMcagc0BXq/uKvm4cUK3QaKWAg0Dogi81/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FRYzDG%2FdJMcagc0BXq%2FuKvm4cUK3QaKWAg0Dogi81%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;1920&quot; height=&quot;1080&quot; data-filename=&quot;stm32_2.png&quot; data-origin-width=&quot;1920&quot; data-origin-height=&quot;1080&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/live/vxvtke2AAUc&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://youtube.com/live/vxvtke2AAUc&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/watch?v=vxvtke2AAUc&quot; data-video-thumbnail=&quot;https://scrap.kakaocdn.net/dn/pjbOQ/hyZPwrtdUU/UXdDBGuLelDicwwidyCoj0/img.jpg?width=1280&amp;amp;height=720&amp;amp;face=0_0_1280_720,https://scrap.kakaocdn.net/dn/eBWdC/hyZPz9zEso/ecSi68QAOjKK4fLKZlt3pK/img.jpg?width=1280&amp;amp;height=720&amp;amp;face=0_0_1280_720,https://scrap.kakaocdn.net/dn/dptRxk/hyZPzIwp3o/2IEVz2sWX0NKyIyiZ1Ptg1/img.jpg?width=1280&amp;amp;height=720&amp;amp;face=0_0_1280_720&quot; data-video-width=&quot;860&quot; data-video-height=&quot;484&quot; data-video-origin-width=&quot;860&quot; data-video-origin-height=&quot;484&quot; data-ke-mobilestyle=&quot;widthContent&quot; data-video-title=&quot;[STM32#20] usart1에 esp01을 연결해서 wifi에 연결하고 mqtt프로토콜을 이용해서 C#이나 스마트폰에 데이&quot; data-original-url=&quot;&quot;&gt;&lt;iframe src=&quot;https://www.youtube.com/embed/vxvtke2AAUc&quot; width=&quot;860&quot; height=&quot;484&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;[STM32#20]&amp;nbsp;usart1에&amp;nbsp;esp01을&amp;nbsp;연결해서&amp;nbsp;wifi에&amp;nbsp;연결하고&amp;nbsp;mqtt프로토콜을&amp;nbsp;이용해서&amp;nbsp;데이터를&amp;nbsp;전송하는&amp;nbsp;방법&amp;nbsp;알아보기!(녹칸다&amp;nbsp;내맘대로&amp;nbsp;STM32) &lt;br /&gt;&lt;br /&gt;심심한녹칸다의&amp;nbsp;내맘대로&amp;nbsp;STM32시리즈이다! &lt;br /&gt;&lt;br /&gt;STM32시리즈의&amp;nbsp;모든&amp;nbsp;자료는&amp;nbsp;구글&amp;nbsp;슬라이드에&amp;nbsp;작성하고&amp;nbsp;모두에게&amp;nbsp;공유되어있음! &lt;br /&gt;&lt;a href=&quot;https://docs.google.com/presentation/d/1myA5iYbjuKsLWLqtRLKAiRfwUwvqB1d1RGjiMIIgp3I/edit?slide=id.g3a6f1f77138_2_233#slide=id.g3a6f1f77138_2_233&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://docs.google.com/presentation/d/1myA5iYbjuKsLWLqtRLKAiRfwUwvqB1d1RGjiMIIgp3I/edit?slide=id.g3a6f1f77138_2_233#slide=id.g3a6f1f77138_2_233&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;STM32에서&amp;nbsp;sscanf와&amp;nbsp;ring&amp;nbsp;buffer를&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-filename=&quot;회로도.PNG&quot; data-origin-width=&quot;1348&quot; data-origin-height=&quot;629&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/sn0tg/dJMcacIrEuP/3gofXtHra0FjWtSzSA5dw1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/sn0tg/dJMcacIrEuP/3gofXtHra0FjWtSzSA5dw1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/sn0tg/dJMcacIrEuP/3gofXtHra0FjWtSzSA5dw1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fsn0tg%2FdJMcacIrEuP%2F3gofXtHra0FjWtSzSA5dw1%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;1348&quot; height=&quot;629&quot; data-filename=&quot;회로도.PNG&quot; data-origin-width=&quot;1348&quot; data-origin-height=&quot;629&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;at커맨드.PNG&quot; data-origin-width=&quot;1383&quot; data-origin-height=&quot;673&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/chPmeD/dJMcad1AJzD/rkuFtCwfDm86UdFtaoCgYK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/chPmeD/dJMcad1AJzD/rkuFtCwfDm86UdFtaoCgYK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/chPmeD/dJMcad1AJzD/rkuFtCwfDm86UdFtaoCgYK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FchPmeD%2FdJMcad1AJzD%2FrkuFtCwfDm86UdFtaoCgYK%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;1383&quot; height=&quot;673&quot; data-filename=&quot;at커맨드.PNG&quot; data-origin-width=&quot;1383&quot; data-origin-height=&quot;673&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;프레임1.PNG&quot; data-origin-width=&quot;1335&quot; data-origin-height=&quot;569&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/KuQmd/dJMcadgdTCb/Ncrk4vhp5UBkxrlbnV4jk0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/KuQmd/dJMcadgdTCb/Ncrk4vhp5UBkxrlbnV4jk0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/KuQmd/dJMcadgdTCb/Ncrk4vhp5UBkxrlbnV4jk0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FKuQmd%2FdJMcadgdTCb%2FNcrk4vhp5UBkxrlbnV4jk0%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;1335&quot; height=&quot;569&quot; data-filename=&quot;프레임1.PNG&quot; data-origin-width=&quot;1335&quot; data-origin-height=&quot;569&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;프레임2.PNG&quot; data-origin-width=&quot;1307&quot; data-origin-height=&quot;561&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/9pc1W/dJMcadgdTCa/3kiAzUKlUuLwMkEGVy5VPk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/9pc1W/dJMcadgdTCa/3kiAzUKlUuLwMkEGVy5VPk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/9pc1W/dJMcadgdTCa/3kiAzUKlUuLwMkEGVy5VPk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2F9pc1W%2FdJMcadgdTCa%2F3kiAzUKlUuLwMkEGVy5VPk%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;1307&quot; height=&quot;561&quot; data-filename=&quot;프레임2.PNG&quot; data-origin-width=&quot;1307&quot; data-origin-height=&quot;561&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;&lt;br /&gt;1.STM32에서&amp;nbsp;ESP01에&amp;nbsp;AT커맨드를&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-filename=&quot;ioc.PNG&quot; data-origin-width=&quot;1259&quot; data-origin-height=&quot;681&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bfKjVC/dJMcaaqjI8x/Ks8LHZ6SR2anDJZElpgPk0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bfKjVC/dJMcaaqjI8x/Ks8LHZ6SR2anDJZElpgPk0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bfKjVC/dJMcaaqjI8x/Ks8LHZ6SR2anDJZElpgPk0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbfKjVC%2FdJMcaaqjI8x%2FKs8LHZ6SR2anDJZElpgPk0%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;1259&quot; height=&quot;681&quot; data-filename=&quot;ioc.PNG&quot; data-origin-width=&quot;1259&quot; data-origin-height=&quot;681&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;pre id=&quot;code_1765957826127&quot; class=&quot;cpp&quot; data-ke-language=&quot;cpp&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;/* USER CODE BEGIN 0 */
char cmd1[] = &quot;AT\r\n&quot;;
char cmd2[] = &quot;ATE0\r\n&quot;;
char mode_set[] = &quot;AT+CWMODE=1\r\n&quot;;
char ap_con[] = &quot;AT+CWJAP=\&quot;popcorn\&quot;,\&quot;11213144\&quot;\r\n&quot;;
char ap_discon[] = &quot;AT+CWQAP\r\n&quot;;
char tcp_con[] = &quot;AT+CIPSTART=\&quot;TCP\&quot;,\&quot;broker.emqx.io\&quot;,1883\r\n&quot;;
char data;
#define b_size 256
uint8_t ring_buffer[b_size];
int head = 0;
int tail = 0;
void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart)
{
	ring_buffer[head++] = data;
	if(head == b_size) head = 0;
	HAL_UART_Receive_IT(&amp;amp;huart1, &amp;amp;data, 1); //인터럽트 재시작~
}
void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim)
{
   //usart1에서 수신한 ring buffer안에 내용을 usart2에 출력한다!
	if(head != tail){
		char data = ring_buffer[tail];
		HAL_UART_Transmit(&amp;amp;huart2, &amp;amp;data, 1, 100);
		tail++;
		if (tail == b_size) tail = 0;
	}
}

/* USER CODE BEGIN 2 */
 HAL_UART_Receive_IT(&amp;amp;huart1, &amp;amp;data, 1); //수신인터럽트
 HAL_TIM_Base_Start_IT(&amp;amp;htim2); //타이머인터럽트
 char u2_data;
 /* USER CODE END 2 */
 /* Infinite loop */
 /* USER CODE BEGIN WHILE */
 while (1)
 {
	  //usart2로 녹칸다가 문자 '1'을 전송하면 AT커맨드를 전송한다!
	  if(HAL_UART_Receive(&amp;amp;huart2, &amp;amp;u2_data, 1, 100) == HAL_OK){
		  if(u2_data == '1'){
			  //생존확인
			  HAL_UART_Transmit(&amp;amp;huart1, cmd1, strlen(cmd1), 100);
		  }else if(u2_data == '2'){
			  //echo off
			  HAL_UART_Transmit(&amp;amp;huart1, cmd2, strlen(cmd2), 100);
		  }else if(u2_data == '3'){
			  //스테이션 모드로 변경
			  HAL_UART_Transmit(&amp;amp;huart1, mode_set, strlen(mode_set), 100);
		  }else if(u2_data == '4'){
			  //인터넷공유기에 접쏙!
			  HAL_UART_Transmit(&amp;amp;huart1, ap_con, strlen(ap_con), 100);
		  }else if(u2_data == '5'){
			  //인터넷공유기 접속 해제!
			  HAL_UART_Transmit(&amp;amp;huart1, ap_discon, strlen(ap_discon), 100);
		  }else if(u2_data == '6'){
			  //브로커와 TCP 연결하기
			  //MQTT브로커와 TCP연결한다음, MQTT연결 명령어를 시간내 전송안하면
			  //서버가 자동으로 연결을 끊어버린다!
			  HAL_UART_Transmit(&amp;amp;huart1, tcp_con, strlen(tcp_con), 100);
		  }
	  }
   /* USER CODE END WHILE */
   /* USER CODE BEGIN 3 */
 }&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;br /&gt;2.MQTT브로커랑&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-filename=&quot;01.PNG&quot; data-origin-width=&quot;1021&quot; data-origin-height=&quot;662&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bNNebg/dJMcahXihEw/Cne8kCoW6mTENpw6tl5zMk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bNNebg/dJMcahXihEw/Cne8kCoW6mTENpw6tl5zMk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bNNebg/dJMcahXihEw/Cne8kCoW6mTENpw6tl5zMk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbNNebg%2FdJMcahXihEw%2FCne8kCoW6mTENpw6tl5zMk%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;1021&quot; height=&quot;662&quot; data-filename=&quot;01.PNG&quot; data-origin-width=&quot;1021&quot; data-origin-height=&quot;662&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;pre id=&quot;code_1765957845844&quot; class=&quot;cpp&quot; data-ke-language=&quot;cpp&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;/* USER CODE BEGIN 0 */
char cmd1[] = &quot;AT\r\n&quot;;
char cmd2[] = &quot;ATE0\r\n&quot;;
char mode_set[] = &quot;AT+CWMODE=1\r\n&quot;;
char ap_con[] = &quot;AT+CWJAP=\&quot;popcorn\&quot;,\&quot;11213144\&quot;\r\n&quot;;
char ap_discon[] = &quot;AT+CWQAP\r\n&quot;;
char tcp_con[] = &quot;AT+CIPSTART=\&quot;TCP\&quot;,\&quot;broker.emqx.io\&quot;,1883\r\n&quot;;
char data;
#define b_size 256
uint8_t ring_buffer[b_size];
int head = 0;
int tail = 0;
void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart)
{
	ring_buffer[head++] = data;
	if(head == b_size) head = 0;
	HAL_UART_Receive_IT(&amp;amp;huart1, &amp;amp;data, 1); //인터럽트 재시작~
}
void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim)
{
   //usart1에서 수신한 ring buffer안에 내용을 usart2에 출력한다!
	if(head != tail){
		char data = ring_buffer[tail];
		HAL_UART_Transmit(&amp;amp;huart2, &amp;amp;data, 1, 100);
		tail++;
		if (tail == b_size) tail = 0;
	}
}
/* USER CODE END 0 */

/* USER CODE BEGIN 2 */
 HAL_UART_Receive_IT(&amp;amp;huart1, &amp;amp;data, 1); //수신인터럽트
 HAL_TIM_Base_Start_IT(&amp;amp;htim2); //타이머인터럽트
 char u2_data;
 uint8_t msg[256];
 //연결 해제
 HAL_UART_Transmit(&amp;amp;huart1,ap_discon,strlen(ap_discon),100);
 HAL_UART_Transmit(&amp;amp;huart2,&quot;AP DIS CON\r\n&quot;,12,100);
 HAL_Delay(2000); //2초정도 기다리면 되겠지?
 //연결
 HAL_UART_Transmit(&amp;amp;huart1,ap_con,strlen(ap_con),100);
 HAL_UART_Transmit(&amp;amp;huart2,&quot;AP CONNECTING\r\n&quot;,15,100);
 HAL_Delay(10000);
 //브로커 접속
 HAL_UART_Transmit(&amp;amp;huart1,tcp_con,strlen(tcp_con),100);
 HAL_UART_Transmit(&amp;amp;huart2,&quot;BROKER CONNECTING\r\n&quot;,19,100);
 HAL_Delay(5000);
 //MQTT 연결
 uint8_t num1 = (HAL_GetTick()/1000) %10;
 uint8_t num2 = (HAL_GetTick()/100) %10;
 uint8_t num3 = (HAL_GetTick()/10) %10;
 uint8_t num4 = HAL_GetTick() %10;
 uint8_t MQTT_CONNECT[] = {0x10,0x14,0x00,0x04,'M','Q','T','T',0x04,0x02,0x00,0x3C,0x00,0x08,'N','O','C','K','0'+num1,'0'+num2,'0'+num3,'0'+num4};
 sprintf(msg, &quot;AT+CIPSEND=%d\r\n&quot;, sizeof(MQTT_CONNECT));
 HAL_UART_Transmit(&amp;amp;huart1,msg,strlen(msg),100);
 HAL_Delay(1000);
 HAL_UART_Transmit(&amp;amp;huart1,MQTT_CONNECT,sizeof(MQTT_CONNECT),100);
 HAL_UART_Transmit(&amp;amp;huart2,&quot;MQTT SET\r\n&quot;,10,100);
 /* USER CODE END 2 */
 /* Infinite loop */
 /* USER CODE BEGIN WHILE */
 while (1)
 {
	  uint8_t MQTT_PUBLISH[] = {0x30,0x00,0x00,0x08,'N','O','C','K','A','N','D','A',0x00,0x00};
	  uint8_t MQTT_MSG[50];
	  sprintf(MQTT_MSG,&quot;STM32 HAL_GetTick()=%d&quot;,HAL_GetTick());
	  MQTT_PUBLISH[13] = strlen(MQTT_MSG);
	  MQTT_PUBLISH[1] = (sizeof(MQTT_PUBLISH)-2) +strlen(MQTT_MSG);
	  sprintf(msg, &quot;AT+CIPSEND=%d\r\n&quot;, sizeof(MQTT_PUBLISH)+strlen(MQTT_MSG));
	  HAL_UART_Transmit(&amp;amp;huart1,msg,strlen(msg),100);
	  HAL_Delay(500);
	  HAL_UART_Transmit(&amp;amp;huart1,MQTT_PUBLISH,sizeof(MQTT_PUBLISH),100);
	  HAL_UART_Transmit(&amp;amp;huart1,MQTT_MSG,strlen(MQTT_MSG),100);
	  HAL_UART_Transmit(&amp;amp;huart2,&quot;publish\r\n&quot;,9,100);
	  HAL_Delay(500);
   /* USER CODE END WHILE */
   /* USER CODE BEGIN 3 */
 }&lt;/code&gt;&lt;/pre&gt;
&lt;pre id=&quot;code_1765957950095&quot; class=&quot;csharp&quot; data-ke-language=&quot;csharp&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;using uPLibrary.Networking.M2Mqtt;
using uPLibrary.Networking.M2Mqtt.Messages;

//전역으로 클래스선언
        MqttClient client;
        string clientId;

        public Form1()
        {
            InitializeComponent();
        }

        private void Form1_Load(object sender, EventArgs e)
        {
            //메인폼이 로드되어서 사용자 눈에 딱 보였다!
            //MQTT 브로커와 연결하는 부분
            string BrokerAddress = &quot;broker.emqx.io&quot;;
            client = new MqttClient(BrokerAddress);

            // register a callback-function (we have to implement, see below) which is called by the library when a message was received
            client.MqttMsgPublishReceived += client_MqttMsgPublishReceived;

            // use a unique id as client id, each time we start the application
            clientId = Guid.NewGuid().ToString();
            client.Connect(clientId);

            richTextBox1.Text += &quot;접속완료\n&quot;;


            //접속이 완료된 위치
            //Subscribe Topic 추가
            string[] mytopic = { &quot;NOCKANDA&quot; };
            byte[] qos = { 0 };
            client.Subscribe(mytopic, qos);

            richTextBox1.Text += &quot;구독완료\n&quot;;
        }
        //MQTT이벤트 핸들러
        void client_MqttMsgPublishReceived(object sender, MqttMsgPublishEventArgs e)
        {
            string ReceivedMessage = Encoding.UTF8.GetString(e.Message, 2, e.Message.Length - 2);
            //DO SOMETHING..!

            richTextBox1.Text += &quot;[수신] &quot; + ReceivedMessage + &quot;\n&quot;;

        }

        private void Form1_FormClosed(object sender, FormClosedEventArgs e)
        {
            //사용자가 프로그램을 껐다!
            //MQTT 연결 종료
            client.Disconnect();
        }&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;br /&gt;3.녹칸다의&amp;nbsp;STM32쉴드에&amp;nbsp;PA0에&amp;nbsp;붙어있는&amp;nbsp;가변저항값을&amp;nbsp;12bit로&amp;nbsp;측정해서&amp;nbsp;MQTT로&amp;nbsp;C#윈폼에&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-filename=&quot;03.PNG&quot; data-origin-width=&quot;966&quot; data-origin-height=&quot;642&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/lC2ct/dJMcagjLdwL/4YDFBP9m2IG0t5UZlZzpQ0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/lC2ct/dJMcagjLdwL/4YDFBP9m2IG0t5UZlZzpQ0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/lC2ct/dJMcagjLdwL/4YDFBP9m2IG0t5UZlZzpQ0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FlC2ct%2FdJMcagjLdwL%2F4YDFBP9m2IG0t5UZlZzpQ0%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;642&quot; data-filename=&quot;03.PNG&quot; data-origin-width=&quot;966&quot; data-origin-height=&quot;642&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;pre id=&quot;code_1765957862329&quot; class=&quot;cpp&quot; data-ke-language=&quot;cpp&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;/* USER CODE BEGIN 0 */
char cmd1[] = &quot;AT\r\n&quot;;
char cmd2[] = &quot;ATE0\r\n&quot;;
char mode_set[] = &quot;AT+CWMODE=1\r\n&quot;;
char ap_con[] = &quot;AT+CWJAP=\&quot;popcorn\&quot;,\&quot;11213144\&quot;\r\n&quot;;
char ap_discon[] = &quot;AT+CWQAP\r\n&quot;;
char tcp_con[] = &quot;AT+CIPSTART=\&quot;TCP\&quot;,\&quot;broker.emqx.io\&quot;,1883\r\n&quot;;
char data;
#define b_size 256
uint8_t ring_buffer[b_size];
int head = 0;
int tail = 0;
void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart)
{
	ring_buffer[head++] = data;
	if(head == b_size) head = 0;
	HAL_UART_Receive_IT(&amp;amp;huart1, &amp;amp;data, 1); //인터럽트 재시작~
}
void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim)
{
   //usart1에서 수신한 ring buffer안에 내용을 usart2에 출력한다!
	if(head != tail){
		char data = ring_buffer[tail];
		HAL_UART_Transmit(&amp;amp;huart2, &amp;amp;data, 1, 100);
		tail++;
		if (tail == b_size) tail = 0;
	}
}
/* USER CODE END 0 */

/* USER CODE BEGIN 2 */
 HAL_UART_Receive_IT(&amp;amp;huart1, &amp;amp;data, 1); //수신인터럽트
 HAL_TIM_Base_Start_IT(&amp;amp;htim2); //타이머인터럽트
HAL_ADC_Start(&amp;amp;hadc1); //딱 한번만 호출
 uint16_t adc_value0 = 0;

 char u2_data;
 uint8_t msg[256];
 //연결 해제
 HAL_UART_Transmit(&amp;amp;huart1,ap_discon,strlen(ap_discon),100);
 HAL_UART_Transmit(&amp;amp;huart2,&quot;AP DIS CON\r\n&quot;,12,100);
 HAL_Delay(2000); //2초정도 기다리면 되겠지?
 //연결
 HAL_UART_Transmit(&amp;amp;huart1,ap_con,strlen(ap_con),100);
 HAL_UART_Transmit(&amp;amp;huart2,&quot;AP CONNECTING\r\n&quot;,15,100);
 HAL_Delay(10000);
 //브로커 접속
 HAL_UART_Transmit(&amp;amp;huart1,tcp_con,strlen(tcp_con),100);
 HAL_UART_Transmit(&amp;amp;huart2,&quot;BROKER CONNECTING\r\n&quot;,19,100);
 HAL_Delay(5000);
 //MQTT 연결
 uint8_t num1 = (HAL_GetTick()/1000) %10;
 uint8_t num2 = (HAL_GetTick()/100) %10;
 uint8_t num3 = (HAL_GetTick()/10) %10;
 uint8_t num4 = HAL_GetTick() %10;
 uint8_t MQTT_CONNECT[] = {0x10,0x14,0x00,0x04,'M','Q','T','T',0x04,0x02,0x00,0x3C,0x00,0x08,'N','O','C','K','0'+num1,'0'+num2,'0'+num3,'0'+num4};
 sprintf(msg, &quot;AT+CIPSEND=%d\r\n&quot;, sizeof(MQTT_CONNECT));
 HAL_UART_Transmit(&amp;amp;huart1,msg,strlen(msg),100);
 HAL_Delay(1000);
 HAL_UART_Transmit(&amp;amp;huart1,MQTT_CONNECT,sizeof(MQTT_CONNECT),100);
 HAL_UART_Transmit(&amp;amp;huart2,&quot;MQTT SET\r\n&quot;,10,100);
 /* USER CODE END 2 */
 /* Infinite loop */
 /* USER CODE BEGIN WHILE */
 while (1)
 {
	  if(HAL_ADC_PollForConversion(&amp;amp;hadc1, 10) == HAL_OK)
	  {
		  adc_value0 = HAL_ADC_GetValue(&amp;amp;hadc1);
	  }
	  uint8_t MQTT_PUBLISH[] = {0x30,0x00,0x00,0x08,'N','O','C','K','A','N','D','A',0x00,0x00};
	  uint8_t MQTT_MSG[50];
	  sprintf(MQTT_MSG,&quot;%d,%d&quot;,msg_num,adc_value0);
	  msg_num++;
	  MQTT_PUBLISH[13] = strlen(MQTT_MSG);
	  MQTT_PUBLISH[1] = (sizeof(MQTT_PUBLISH)-2) +strlen(MQTT_MSG);
	  sprintf(msg, &quot;AT+CIPSEND=%d\r\n&quot;, sizeof(MQTT_PUBLISH)+strlen(MQTT_MSG));
	  HAL_UART_Transmit(&amp;amp;huart1,msg,strlen(msg),100);
	  HAL_Delay(500);
	  HAL_UART_Transmit(&amp;amp;huart1,MQTT_PUBLISH,sizeof(MQTT_PUBLISH),100);
	  HAL_UART_Transmit(&amp;amp;huart1,MQTT_MSG,strlen(MQTT_MSG),100);
	  HAL_UART_Transmit(&amp;amp;huart2,&quot;publish\r\n&quot;,9,100);
	  HAL_Delay(500);
   /* USER CODE END WHILE */
   /* USER CODE BEGIN 3 */
 }&lt;/code&gt;&lt;/pre&gt;
&lt;pre id=&quot;code_1765957965927&quot; class=&quot;csharp&quot; data-ke-language=&quot;csharp&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;using uPLibrary.Networking.M2Mqtt;
using uPLibrary.Networking.M2Mqtt.Messages;

//전역으로 클래스선언
        MqttClient client;
        string clientId;

        public Form1()
        {
            InitializeComponent();
        }

        private void Form1_Load(object sender, EventArgs e)
        {
            //메인폼이 로드되어서 사용자 눈에 딱 보였다!
            //MQTT 브로커와 연결하는 부분
            string BrokerAddress = &quot;broker.emqx.io&quot;;
            client = new MqttClient(BrokerAddress);

            // register a callback-function (we have to implement, see below) which is called by the library when a message was received
            client.MqttMsgPublishReceived += client_MqttMsgPublishReceived;

            // use a unique id as client id, each time we start the application
            clientId = Guid.NewGuid().ToString();
            client.Connect(clientId);

            richTextBox1.Text += &quot;접속완료\n&quot;;


            //접속이 완료된 위치
            //Subscribe Topic 추가
            string[] mytopic = { &quot;NOCKANDA&quot; };
            byte[] qos = { 0 };
            client.Subscribe(mytopic, qos);

            richTextBox1.Text += &quot;구독완료\n&quot;;
        }
        //MQTT이벤트 핸들러
        void client_MqttMsgPublishReceived(object sender, MqttMsgPublishEventArgs e)
        {
            string ReceivedMessage = Encoding.UTF8.GetString(e.Message, 2, e.Message.Length - 2);
            //DO SOMETHING..!

            richTextBox1.Text += &quot;[수신] &quot; + ReceivedMessage + &quot;\n&quot;;

            string[] data = ReceivedMessage.Split(',');
            if(data.Length == 2)
            {
                textBox1.Text = data[0];
                textBox2.Text = data[1];
            }
        }

        private void Form1_FormClosed(object sender, FormClosedEventArgs e)
        {
            //사용자가 프로그램을 껐다!
            //MQTT 연결 종료
            client.Disconnect();
        }&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;br /&gt;4.STM32쉴드에&amp;nbsp;붙어있는&amp;nbsp;온습도센서인&amp;nbsp;DHT-11의&amp;nbsp;값을&amp;nbsp;측정해서&amp;nbsp;MQTT로&amp;nbsp;C#윈폼에&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-filename=&quot;04.PNG&quot; data-origin-width=&quot;788&quot; data-origin-height=&quot;661&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/loin7/dJMcaf6eokf/QiW3It9AC8PxB6t6TOXEi0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/loin7/dJMcaf6eokf/QiW3It9AC8PxB6t6TOXEi0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/loin7/dJMcaf6eokf/QiW3It9AC8PxB6t6TOXEi0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Floin7%2FdJMcaf6eokf%2FQiW3It9AC8PxB6t6TOXEi0%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;788&quot; height=&quot;661&quot; data-filename=&quot;04.PNG&quot; data-origin-width=&quot;788&quot; data-origin-height=&quot;661&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;pre id=&quot;code_1765957889325&quot; class=&quot;cpp&quot; data-ke-language=&quot;cpp&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;/* USER CODE BEGIN 0 */
char cmd1[] = &quot;AT\r\n&quot;;
char cmd2[] = &quot;ATE0\r\n&quot;;
char mode_set[] = &quot;AT+CWMODE=1\r\n&quot;;
char ap_con[] = &quot;AT+CWJAP=\&quot;popcorn\&quot;,\&quot;11213144\&quot;\r\n&quot;;
char ap_discon[] = &quot;AT+CWQAP\r\n&quot;;
char tcp_con[] = &quot;AT+CIPSTART=\&quot;TCP\&quot;,\&quot;broker.emqx.io\&quot;,1883\r\n&quot;;
char data;
#define b_size 256
uint8_t ring_buffer[b_size];
int head = 0;
int tail = 0;
void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart)
{
	ring_buffer[head++] = data;
	if(head == b_size) head = 0;
	HAL_UART_Receive_IT(&amp;amp;huart1, &amp;amp;data, 1); //인터럽트 재시작~
}
void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim)
{
   //usart1에서 수신한 ring buffer안에 내용을 usart2에 출력한다!
	if(head != tail){
		char data = ring_buffer[tail];
		HAL_UART_Transmit(&amp;amp;huart2, &amp;amp;data, 1, 100);
		tail++;
		if (tail == b_size) tail = 0;
	}
}

#define delay_ms HAL_Delay
#define SYS_CLOCK    64
#define SYSTICK_LOAD 63999
uint32_t millis_cnt = 0;
uint32_t millis() {
return millis_cnt;
}
uint32_t micros() {
return (millis_cnt &amp;amp; 0x3FFFFF) * 1000 + (SYSTICK_LOAD - SysTick-&amp;gt;VAL) / SYS_CLOCK;
}
void delay_us(uint32_t us) {  // 64MHz 보정
if (us &amp;gt; 1) {
 uint32_t count = us * 7 - 6;
 while (count--);
} else {
 uint32_t count = 2;
 while (count--);
}
}
union {
uint32_t data;
struct {
  uint8_t temp_d;
  uint8_t temp_i;
  uint8_t rh_d;
  uint8_t rh_i;
};
} DHT;

uint8_t DHT_read () {
uint8_t i, check_sum;
uint32_t start;
check_sum = 0;
DHT.data = 0;
GPIOC-&amp;gt;CRL = (GPIOC-&amp;gt;CRL&amp;amp;0xFFFFFF0F)|(7&amp;lt;&amp;lt;(1*4));  // Output Open-drain (Master send LOW signal)
delay_ms(18);
GPIOC-&amp;gt;CRL= (GPIOC-&amp;gt;CRL&amp;amp;0xFFFFFF0F)|(4&amp;lt;&amp;lt;(1*4));  // Floating input (Master send HIGH signal &amp;amp; data receive)
start = micros();
while (GPIOC-&amp;gt;IDR&amp;amp;(1&amp;lt;&amp;lt;1)) {
  if (micros()-start &amp;gt; 50) return 1;  // 20~40us
}
start = micros();
while (!(GPIOC-&amp;gt;IDR&amp;amp;(1&amp;lt;&amp;lt;1))) {
  if (micros()-start &amp;gt; 120) return 2;  // 80us
}
start = micros();
while (GPIOC-&amp;gt;IDR&amp;amp;(1&amp;lt;&amp;lt;1)) {
  if (micros()-start &amp;gt; 120) return 3;  // 80us
}
for (i = 0; i &amp;lt; 32; i++) {
  while (!(GPIOC-&amp;gt;IDR&amp;amp;(1&amp;lt;&amp;lt;1))); // 50us
  start = micros();
  while (GPIOC-&amp;gt;IDR&amp;amp;(1&amp;lt;&amp;lt;1));
  if (micros()-start &amp;gt; 50) DHT.data |= (0x80000000 &amp;gt;&amp;gt; i); // &quot;0&quot;=26~28us, &quot;1&quot;=70us
}
for (i = 0; i &amp;lt; 8; i++) {
  while (!(GPIOC-&amp;gt;IDR&amp;amp;(1&amp;lt;&amp;lt;1))); // 50us
  start = micros();
  while (GPIOC-&amp;gt;IDR&amp;amp;(1&amp;lt;&amp;lt;1));
  if (micros()-start &amp;gt; 50) check_sum |= (0x80 &amp;gt;&amp;gt; i);
}
if ((DHT.rh_i + DHT.rh_d + DHT.temp_i + DHT.temp_d) == check_sum) return 0;
else return 4;
}
/* USER CODE END 0 */

/* USER CODE BEGIN 2 */
 HAL_UART_Receive_IT(&amp;amp;huart1, &amp;amp;data, 1); //수신인터럽트
 HAL_TIM_Base_Start_IT(&amp;amp;htim2); //타이머인터럽트
 HAL_ADC_Start(&amp;amp;hadc1); //딱 한번만 호출
 uint16_t adc_value0 = 0;
 char u2_data;
 uint8_t msg[256];
 //연결 해제
 HAL_UART_Transmit(&amp;amp;huart1,ap_discon,strlen(ap_discon),100);
 HAL_UART_Transmit(&amp;amp;huart2,&quot;AP DIS CON\r\n&quot;,12,100);
 HAL_Delay(2000); //2초정도 기다리면 되겠지?
 //연결
 HAL_UART_Transmit(&amp;amp;huart1,ap_con,strlen(ap_con),100);
 HAL_UART_Transmit(&amp;amp;huart2,&quot;AP CONNECTING\r\n&quot;,15,100);
 HAL_Delay(10000);
 //브로커 접속
 HAL_UART_Transmit(&amp;amp;huart1,tcp_con,strlen(tcp_con),100);
 HAL_UART_Transmit(&amp;amp;huart2,&quot;BROKER CONNECTING\r\n&quot;,19,100);
 HAL_Delay(5000);

 //MQTT 연결
 uint8_t num1 = (HAL_GetTick()/1000) %10;
 uint8_t num2 = (HAL_GetTick()/100) %10;
 uint8_t num3 = (HAL_GetTick()/10) %10;
 uint8_t num4 = HAL_GetTick() %10;
 uint8_t MQTT_CONNECT[] = {0x10,0x14,0x00,0x04,'M','Q','T','T',0x04,0x02,0x00,0x3C,0x00,0x08,'N','O','C','K','0'+num1,'0'+num2,'0'+num3,'0'+num4};
 sprintf(msg, &quot;AT+CIPSEND=%d\r\n&quot;, sizeof(MQTT_CONNECT));
 HAL_UART_Transmit(&amp;amp;huart1,msg,strlen(msg),100);
 HAL_Delay(1000);
 HAL_UART_Transmit(&amp;amp;huart1,MQTT_CONNECT,sizeof(MQTT_CONNECT),100);
 HAL_UART_Transmit(&amp;amp;huart2,&quot;MQTT SET\r\n&quot;,10,100);
 int msg_num = 0;
 /* USER CODE END 2 */
 /* Infinite loop */
 /* USER CODE BEGIN WHILE */
 while (1)
 {
	  uint8_t error_no = DHT_read();
	  if(error_no == 0){  // 정상일 때 처리
		  float temp = 0;
		  float humi = 0;
		  temp = DHT.temp_i;
		  if (DHT.temp_d &amp;amp; 0x80) {
			  temp = -1 - temp;
		  }
		  temp += (DHT.temp_d &amp;amp; 0x0f) * 0.1;
		  humi = DHT.rh_i + DHT.rh_d * 0.1;

		  uint8_t MQTT_PUBLISH[] = {0x30,0x00,0x00,0x08,'N','O','C','K','A','N','D','A',0x00,0x00};
		  uint8_t MQTT_MSG[50];
		  sprintf(MQTT_MSG,&quot;%d,%.2f,%.2f&quot;,msg_num,temp,humi);
		  msg_num++;
		  MQTT_PUBLISH[13] = strlen(MQTT_MSG);
		  MQTT_PUBLISH[1] = (sizeof(MQTT_PUBLISH)-2) +strlen(MQTT_MSG);
		  sprintf(msg, &quot;AT+CIPSEND=%d\r\n&quot;, sizeof(MQTT_PUBLISH)+strlen(MQTT_MSG));
		  HAL_UART_Transmit(&amp;amp;huart1,msg,strlen(msg),100);
		  HAL_Delay(500);
		  HAL_UART_Transmit(&amp;amp;huart1,MQTT_PUBLISH,sizeof(MQTT_PUBLISH),100);
		  HAL_UART_Transmit(&amp;amp;huart1,MQTT_MSG,strlen(MQTT_MSG),100);
		  HAL_UART_Transmit(&amp;amp;huart2,&quot;publish\r\n&quot;,9,100);
	  } else {
		  //측정실패
	  }
	  HAL_Delay(1500);
   /* USER CODE END WHILE */
   /* USER CODE BEGIN 3 */
 }&lt;/code&gt;&lt;/pre&gt;
&lt;pre id=&quot;code_1765957983425&quot; class=&quot;csharp&quot; data-ke-language=&quot;csharp&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;using uPLibrary.Networking.M2Mqtt;
using uPLibrary.Networking.M2Mqtt.Messages;

//전역으로 클래스선언
        MqttClient client;
        string clientId;

        public Form1()
        {
            InitializeComponent();
        }

        private void Form1_Load(object sender, EventArgs e)
        {
            //메인폼이 로드되어서 사용자 눈에 딱 보였다!
            //MQTT 브로커와 연결하는 부분
            string BrokerAddress = &quot;broker.emqx.io&quot;;
            client = new MqttClient(BrokerAddress);

            // register a callback-function (we have to implement, see below) which is called by the library when a message was received
            client.MqttMsgPublishReceived += client_MqttMsgPublishReceived;

            // use a unique id as client id, each time we start the application
            clientId = Guid.NewGuid().ToString();
            client.Connect(clientId);

            richTextBox1.Text += &quot;접속완료\n&quot;;


            //접속이 완료된 위치
            //Subscribe Topic 추가
            string[] mytopic = { &quot;NOCKANDA&quot; };
            byte[] qos = { 0 };
            client.Subscribe(mytopic, qos);

            richTextBox1.Text += &quot;구독완료\n&quot;;
        }
        //MQTT이벤트 핸들러
        void client_MqttMsgPublishReceived(object sender, MqttMsgPublishEventArgs e)
        {
            string ReceivedMessage = Encoding.UTF8.GetString(e.Message, 2, e.Message.Length - 2);
            //DO SOMETHING..!

            richTextBox1.Text += &quot;[수신] &quot; + ReceivedMessage + &quot;\n&quot;;
            string[] data = ReceivedMessage.Split(',');
            if(data.Length == 3)
            {
                textBox1.Text = data[0];
                textBox2.Text = data[1];
                textBox3.Text = data[2];
            }

        }

        private void Form1_FormClosed(object sender, FormClosedEventArgs e)
        {
            //사용자가 프로그램을 껐다!
            //MQTT 연결 종료
            client.Disconnect();
        }&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;br /&gt;5.예제4에서&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-filename=&quot;05.PNG&quot; data-origin-width=&quot;878&quot; data-origin-height=&quot;620&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bJnOYN/dJMcahXihFc/0jFCHj0J9dwLMhNHMyRC50/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bJnOYN/dJMcahXihFc/0jFCHj0J9dwLMhNHMyRC50/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bJnOYN/dJMcahXihFc/0jFCHj0J9dwLMhNHMyRC50/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbJnOYN%2FdJMcahXihFc%2F0jFCHj0J9dwLMhNHMyRC50%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;878&quot; height=&quot;620&quot; data-filename=&quot;05.PNG&quot; data-origin-width=&quot;878&quot; data-origin-height=&quot;620&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;5-1.PNG&quot; data-origin-width=&quot;896&quot; data-origin-height=&quot;666&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/qR2cF/dJMcahXihFi/A74xfhDZLaMeAkJzz3dNzk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/qR2cF/dJMcahXihFi/A74xfhDZLaMeAkJzz3dNzk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/qR2cF/dJMcahXihFi/A74xfhDZLaMeAkJzz3dNzk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FqR2cF%2FdJMcahXihFi%2FA74xfhDZLaMeAkJzz3dNzk%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;896&quot; height=&quot;666&quot; data-filename=&quot;5-1.PNG&quot; data-origin-width=&quot;896&quot; data-origin-height=&quot;666&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;pre id=&quot;code_1765957920238&quot; class=&quot;cpp&quot; data-ke-language=&quot;cpp&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;/* USER CODE BEGIN 0 */
char cmd1[] = &quot;AT\r\n&quot;;
char cmd2[] = &quot;ATE0\r\n&quot;;
char mode_set[] = &quot;AT+CWMODE=1\r\n&quot;;
char ap_con[] = &quot;AT+CWJAP=\&quot;popcorn\&quot;,\&quot;11213144\&quot;\r\n&quot;;
char ap_discon[] = &quot;AT+CWQAP\r\n&quot;;
char tcp_con[] = &quot;AT+CIPSTART=\&quot;TCP\&quot;,\&quot;broker.emqx.io\&quot;,1883\r\n&quot;;
char data;
#define b_size 256
uint8_t ring_buffer[b_size];
int head = 0;
int tail = 0;
void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart)
{
	ring_buffer[head++] = data;
	if(head == b_size) head = 0;
	HAL_UART_Receive_IT(&amp;amp;huart1, &amp;amp;data, 1); //인터럽트 재시작~
}
void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim)
{
   //usart1에서 수신한 ring buffer안에 내용을 usart2에 출력한다!
	if(head != tail){
		char data = ring_buffer[tail];
		HAL_UART_Transmit(&amp;amp;huart2, &amp;amp;data, 1, 100);
		tail++;
		if (tail == b_size) tail = 0;
	}
}

#define delay_ms HAL_Delay
#define SYS_CLOCK    64
#define SYSTICK_LOAD 63999
uint32_t millis_cnt = 0;
uint32_t millis() {
return millis_cnt;
}
uint32_t micros() {
return (millis_cnt &amp;amp; 0x3FFFFF) * 1000 + (SYSTICK_LOAD - SysTick-&amp;gt;VAL) / SYS_CLOCK;
}
void delay_us(uint32_t us) {  // 64MHz 보정
if (us &amp;gt; 1) {
 uint32_t count = us * 7 - 6;
 while (count--);
} else {
 uint32_t count = 2;
 while (count--);
}
}
union {
uint32_t data;
struct {
  uint8_t temp_d;
  uint8_t temp_i;
  uint8_t rh_d;
  uint8_t rh_i;
};
} DHT;

uint8_t DHT_read () {
uint8_t i, check_sum;
uint32_t start;
check_sum = 0;
DHT.data = 0;
GPIOC-&amp;gt;CRL = (GPIOC-&amp;gt;CRL&amp;amp;0xFFFFFF0F)|(7&amp;lt;&amp;lt;(1*4));  // Output Open-drain (Master send LOW signal)
delay_ms(18);
GPIOC-&amp;gt;CRL= (GPIOC-&amp;gt;CRL&amp;amp;0xFFFFFF0F)|(4&amp;lt;&amp;lt;(1*4));  // Floating input (Master send HIGH signal &amp;amp; data receive)
start = micros();
while (GPIOC-&amp;gt;IDR&amp;amp;(1&amp;lt;&amp;lt;1)) {
  if (micros()-start &amp;gt; 50) return 1;  // 20~40us
}
start = micros();
while (!(GPIOC-&amp;gt;IDR&amp;amp;(1&amp;lt;&amp;lt;1))) {
  if (micros()-start &amp;gt; 120) return 2;  // 80us
}
start = micros();
while (GPIOC-&amp;gt;IDR&amp;amp;(1&amp;lt;&amp;lt;1)) {
  if (micros()-start &amp;gt; 120) return 3;  // 80us
}
for (i = 0; i &amp;lt; 32; i++) {
  while (!(GPIOC-&amp;gt;IDR&amp;amp;(1&amp;lt;&amp;lt;1))); // 50us
  start = micros();
  while (GPIOC-&amp;gt;IDR&amp;amp;(1&amp;lt;&amp;lt;1));
  if (micros()-start &amp;gt; 50) DHT.data |= (0x80000000 &amp;gt;&amp;gt; i); // &quot;0&quot;=26~28us, &quot;1&quot;=70us
}
for (i = 0; i &amp;lt; 8; i++) {
  while (!(GPIOC-&amp;gt;IDR&amp;amp;(1&amp;lt;&amp;lt;1))); // 50us
  start = micros();
  while (GPIOC-&amp;gt;IDR&amp;amp;(1&amp;lt;&amp;lt;1));
  if (micros()-start &amp;gt; 50) check_sum |= (0x80 &amp;gt;&amp;gt; i);
}
if ((DHT.rh_i + DHT.rh_d + DHT.temp_i + DHT.temp_d) == check_sum) return 0;
else return 4;
}
/* USER CODE END 0 */

/* USER CODE BEGIN 2 */
 HAL_UART_Receive_IT(&amp;amp;huart1, &amp;amp;data, 1); //수신인터럽트
 HAL_TIM_Base_Start_IT(&amp;amp;htim2); //타이머인터럽트
 HAL_ADC_Start(&amp;amp;hadc1); //딱 한번만 호출
 uint16_t adc_value0 = 0;
 char u2_data;
 uint8_t msg[256];
 //연결 해제
 HAL_UART_Transmit(&amp;amp;huart1,ap_discon,strlen(ap_discon),100);
 HAL_UART_Transmit(&amp;amp;huart2,&quot;AP DIS CON\r\n&quot;,12,100);
 HAL_Delay(2000); //2초정도 기다리면 되겠지?
 //연결
 HAL_UART_Transmit(&amp;amp;huart1,ap_con,strlen(ap_con),100);
 HAL_UART_Transmit(&amp;amp;huart2,&quot;AP CONNECTING\r\n&quot;,15,100);
 HAL_Delay(10000);
 //브로커 접속
 HAL_UART_Transmit(&amp;amp;huart1,tcp_con,strlen(tcp_con),100);
 HAL_UART_Transmit(&amp;amp;huart2,&quot;BROKER CONNECTING\r\n&quot;,19,100);
 HAL_Delay(5000);

 //MQTT 연결
 uint8_t num1 = (HAL_GetTick()/1000) %10;
 uint8_t num2 = (HAL_GetTick()/100) %10;
 uint8_t num3 = (HAL_GetTick()/10) %10;
 uint8_t num4 = HAL_GetTick() %10;
 uint8_t MQTT_CONNECT[] = {0x10,0x14,0x00,0x04,'M','Q','T','T',0x04,0x02,0x00,0x3C,0x00,0x08,'N','O','C','K','0'+num1,'0'+num2,'0'+num3,'0'+num4};
 sprintf(msg, &quot;AT+CIPSEND=%d\r\n&quot;, sizeof(MQTT_CONNECT));
 HAL_UART_Transmit(&amp;amp;huart1,msg,strlen(msg),100);
 HAL_Delay(1000);
 HAL_UART_Transmit(&amp;amp;huart1,MQTT_CONNECT,sizeof(MQTT_CONNECT),100);
 HAL_UART_Transmit(&amp;amp;huart2,&quot;MQTT SET\r\n&quot;,10,100);
 int msg_num = 0;
 /* USER CODE END 2 */
 /* Infinite loop */
 /* USER CODE BEGIN WHILE */
 while (1)
 {
	  uint8_t error_no = DHT_read();
	  if(error_no == 0){  // 정상일 때 처리
		  float temp = 0;
		  float humi = 0;
		  temp = DHT.temp_i;
		  if (DHT.temp_d &amp;amp; 0x80) {
			  temp = -1 - temp;
		  }
		  temp += (DHT.temp_d &amp;amp; 0x0f) * 0.1;
		  humi = DHT.rh_i + DHT.rh_d * 0.1;

		  uint8_t MQTT_PUBLISH[] = {0x30,0x00,0x00,0x08,'N','O','C','K','A','N','D','A',0x00,0x00};
		  uint8_t MQTT_MSG[50];
		  sprintf(MQTT_MSG,&quot;%d,%.2f,%.2f&quot;,msg_num,temp,humi);
		  msg_num++;
		  MQTT_PUBLISH[13] = strlen(MQTT_MSG);
		  MQTT_PUBLISH[1] = (sizeof(MQTT_PUBLISH)-2) +strlen(MQTT_MSG);
		  sprintf(msg, &quot;AT+CIPSEND=%d\r\n&quot;, sizeof(MQTT_PUBLISH)+strlen(MQTT_MSG));
		  HAL_UART_Transmit(&amp;amp;huart1,msg,strlen(msg),100);
		  HAL_Delay(500);
		  HAL_UART_Transmit(&amp;amp;huart1,MQTT_PUBLISH,sizeof(MQTT_PUBLISH),100);
		  HAL_UART_Transmit(&amp;amp;huart1,MQTT_MSG,strlen(MQTT_MSG),100);
		  HAL_UART_Transmit(&amp;amp;huart2,&quot;publish\r\n&quot;,9,100);
	  } else {
		  //측정실패
	  }
	  HAL_Delay(1500);
   /* USER CODE END WHILE */
   /* USER CODE BEGIN 3 */
 }&lt;/code&gt;&lt;/pre&gt;
&lt;pre id=&quot;code_1765957999978&quot; class=&quot;csharp&quot; data-ke-language=&quot;csharp&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;using uPLibrary.Networking.M2Mqtt;
using uPLibrary.Networking.M2Mqtt.Messages;

//전역으로 클래스선언
        MqttClient client;
        string clientId;

        public Form1()
        {
            InitializeComponent();
        }

        private void Form1_Load(object sender, EventArgs e)
        {
            //메인폼이 로드되어서 사용자 눈에 딱 보였다!
            //MQTT 브로커와 연결하는 부분
            string BrokerAddress = &quot;broker.emqx.io&quot;;
            client = new MqttClient(BrokerAddress);

            // register a callback-function (we have to implement, see below) which is called by the library when a message was received
            client.MqttMsgPublishReceived += client_MqttMsgPublishReceived;

            // use a unique id as client id, each time we start the application
            clientId = Guid.NewGuid().ToString();
            client.Connect(clientId);

            richTextBox1.Text += &quot;접속완료\n&quot;;


            //접속이 완료된 위치
            //Subscribe Topic 추가
            string[] mytopic = { &quot;NOCKANDA&quot; };
            byte[] qos = { 0 };
            client.Subscribe(mytopic, qos);

            richTextBox1.Text += &quot;구독완료\n&quot;;
        }
        //MQTT이벤트 핸들러
        void client_MqttMsgPublishReceived(object sender, MqttMsgPublishEventArgs e)
        {
            string ReceivedMessage = Encoding.UTF8.GetString(e.Message, 2, e.Message.Length - 2);
            //DO SOMETHING..!

            string[] data = ReceivedMessage.Split(',');
            if(data.Length == 3)
            {
                textBox1.Text = data[0];
                textBox2.Text = data[1]; //온도
                textBox3.Text = data[2]; //습도
                float temp = float.Parse(data[1]);
                float humi = float.Parse(data[2]);
                aGauge1.Value = temp;
                aGauge2.Value = humi;
            }
        }

        private void Form1_FormClosed(object sender, FormClosedEventArgs e)
        {
            //사용자가 프로그램을 껐다!
            //MQTT 연결 종료
            client.Disconnect();
        }&lt;/code&gt;&lt;/pre&gt;</description>
      <category>프로그래밍/STM32</category>
      <author>덕력킹</author>
      <guid isPermaLink="true">https://bota.tistory.com/2462</guid>
      <comments>https://bota.tistory.com/2462#entry2462comment</comments>
      <pubDate>Wed, 17 Dec 2025 16:55:21 +0900</pubDate>
    </item>
    <item>
      <title>[STM32#19] STM32에서 형식이 있는 데이터를 sscanf로 수신하는 방법과 ring buffer 활용방법 알아보기!(녹칸다 내맘대로 STM32)</title>
      <link>https://bota.tistory.com/2461</link>
      <description>&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;stm32.png&quot; data-origin-width=&quot;1920&quot; data-origin-height=&quot;1080&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bk5zaP/dJMcaiIBkeb/7dxiQtLwNe4dh5B5BNdNHK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bk5zaP/dJMcaiIBkeb/7dxiQtLwNe4dh5B5BNdNHK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bk5zaP/dJMcaiIBkeb/7dxiQtLwNe4dh5B5BNdNHK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fbk5zaP%2FdJMcaiIBkeb%2F7dxiQtLwNe4dh5B5BNdNHK%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;1920&quot; height=&quot;1080&quot; data-filename=&quot;stm32.png&quot; data-origin-width=&quot;1920&quot; data-origin-height=&quot;1080&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/live/sM4WSj0hdWk&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://youtube.com/live/sM4WSj0hdWk&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/watch?v=sM4WSj0hdWk&quot; data-video-thumbnail=&quot;https://scrap.kakaocdn.net/dn/buK1aU/hyZPtgASpQ/kxq7cQ30LyQa5uKKzbidWK/img.jpg?width=1280&amp;amp;height=720&amp;amp;face=0_0_1280_720,https://scrap.kakaocdn.net/dn/ble4X6/hyZPvS07rR/BcfsVvlJgmTEktbFSS6jI1/img.jpg?width=1280&amp;amp;height=720&amp;amp;face=0_0_1280_720,https://scrap.kakaocdn.net/dn/fEsJE/hyZPtt8Xyi/SHHk5sqNuSROwki4hKP27K/img.jpg?width=1280&amp;amp;height=720&amp;amp;face=0_0_1280_720&quot; data-video-width=&quot;860&quot; data-video-height=&quot;484&quot; data-video-origin-width=&quot;860&quot; data-video-origin-height=&quot;484&quot; data-ke-mobilestyle=&quot;widthContent&quot; data-video-title=&quot;[STM32#19] STM32에서 형식이 있는 데이터를 sscanf로 수신하는 방법과 ring buffer 활용방법 알아보기!(녹&quot; data-original-url=&quot;&quot;&gt;&lt;iframe src=&quot;https://www.youtube.com/embed/sM4WSj0hdWk&quot; width=&quot;860&quot; height=&quot;484&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;[STM32#19]&amp;nbsp;STM32에서&amp;nbsp;형식이&amp;nbsp;있는&amp;nbsp;데이터를&amp;nbsp;sscanf로&amp;nbsp;수신하는&amp;nbsp;방법과&amp;nbsp;ring&amp;nbsp;buffer&amp;nbsp;활용방법&amp;nbsp;알아보기!(녹칸다&amp;nbsp;내맘대로&amp;nbsp;STM32) &lt;br /&gt;&lt;br /&gt;심심한녹칸다의&amp;nbsp;내맘대로&amp;nbsp;STM32시리즈이다! &lt;br /&gt;&lt;br /&gt;STM32시리즈의&amp;nbsp;모든&amp;nbsp;자료는&amp;nbsp;구글&amp;nbsp;슬라이드에&amp;nbsp;작성하고&amp;nbsp;모두에게&amp;nbsp;공유되어있음! &lt;br /&gt;&lt;a href=&quot;https://docs.google.com/presentation/d/1myA5iYbjuKsLWLqtRLKAiRfwUwvqB1d1RGjiMIIgp3I/edit?slide=id.g3b065dcc8fb_1_0#slide=id.g3b065dcc8fb_1_0&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://docs.google.com/presentation/d/1myA5iYbjuKsLWLqtRLKAiRfwUwvqB1d1RGjiMIIgp3I/edit?slide=id.g3b065dcc8fb_1_0#slide=id.g3b065dcc8fb_1_0&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;STM32에서&amp;nbsp;sscanf와&amp;nbsp;ring&amp;nbsp;buffer를&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;1.C#에서&amp;nbsp;아래와&amp;nbsp;같은&amp;nbsp;데이터를&amp;nbsp;전송할때&amp;nbsp;STM32가&amp;nbsp;해석해서&amp;nbsp;응답을&amp;nbsp;보낼&amp;nbsp;수&amp;nbsp;있도록&amp;nbsp;sscanf로&amp;nbsp;기능&amp;nbsp;구현을&amp;nbsp;하시오! &lt;br /&gt;(데이터)&amp;nbsp;&amp;ldquo;num1=1234\n&amp;rdquo;&amp;nbsp;일때&amp;nbsp;STM32는&amp;nbsp;1234를&amp;nbsp;추출한다! &lt;br /&gt;(응답)&amp;nbsp;&amp;ldquo;num1&amp;nbsp;is&amp;nbsp;1234!!\n&amp;rdquo;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;01.PNG&quot; data-origin-width=&quot;467&quot; data-origin-height=&quot;497&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cHXk58/dJMb99ZelYf/4niyso1U5njvxemNZo88M0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cHXk58/dJMb99ZelYf/4niyso1U5njvxemNZo88M0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cHXk58/dJMb99ZelYf/4niyso1U5njvxemNZo88M0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FcHXk58%2FdJMb99ZelYf%2F4niyso1U5njvxemNZo88M0%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;467&quot; height=&quot;497&quot; data-filename=&quot;01.PNG&quot; data-origin-width=&quot;467&quot; data-origin-height=&quot;497&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;pre id=&quot;code_1765807977683&quot; class=&quot;cpp&quot; data-ke-language=&quot;cpp&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;/* USER CODE BEGIN 0 */
char rx_buff[100];
char tx_buff[100];
int rx_pos = 0;
char data;
int num1 = 0;
void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart)
{
	//데이터 처리(종료문자가 \n인 상황)
	rx_buff[rx_pos++] = data;
	if(data == '\n'){
		//STM32가 echo
		rx_buff[rx_pos] = '\0';
		//rx_buff에 있는 데이터 형식 num1=1234
		if(sscanf(rx_buff,&quot;num1=%d&quot;,&amp;amp;num1) == 1){
			//성공
			sprintf(tx_buff,&quot;num1 is %d!!\n&quot;,num1);
			HAL_UART_Transmit(&amp;amp;huart2, tx_buff, strlen(tx_buff), 100);
		}else{
			//실패
			HAL_UART_Transmit(&amp;amp;huart2, &quot;error!\n&quot;, 7, 100);
		}
		rx_pos = 0;
	}
	//수신인터럽트 다시 시작
	HAL_UART_Receive_IT(&amp;amp;huart2, &amp;amp;data, 1);
}&lt;/code&gt;&lt;/pre&gt;
&lt;pre id=&quot;code_1765808140549&quot; class=&quot;csharp&quot; data-ke-language=&quot;csharp&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;private void button1_Click(object sender, EventArgs e)
        {
            serialPort1.PortName = textBox1.Text;
            serialPort1.BaudRate = 115200; //usart2

            serialPort1.Open(); //개방!

            if (serialPort1.IsOpen)
            {
                serialPort1.ReadExisting();
                MessageBox.Show(&quot;연결완료!&quot;);
            }
        }

        private void serialPort1_DataReceived(object sender, System.IO.Ports.SerialDataReceivedEventArgs e)
        {
            string data = serialPort1.ReadLine();
            richTextBox1.Text += &quot;[수신]=&quot; + data + &quot;\n&quot;;
        }

        private void button2_Click(object sender, EventArgs e)
        {
            //포트가 열려있고, 입력창이 빈칸이 아닐때~
            if (serialPort1.IsOpen &amp;amp;&amp;amp; textBox2.Text != &quot;&quot;)
            {
                serialPort1.WriteLine(textBox2.Text);
            }
        }&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;br /&gt;2.이번에는&amp;nbsp;아래와같은&amp;nbsp;커맨드&amp;nbsp;형식일때&amp;nbsp;여러개의&amp;nbsp;명령어를&amp;nbsp;인식가능하도록&amp;nbsp;하시오! &lt;br /&gt;(데이터1)&amp;nbsp;&amp;ldquo;select&amp;nbsp;value&amp;nbsp;=&amp;nbsp;10&amp;rdquo; &lt;br /&gt;(데이터2)&amp;nbsp;&amp;ldquo;update&amp;nbsp;value&amp;nbsp;=&amp;nbsp;10&amp;rdquo; &lt;br /&gt;(데이터3)&amp;nbsp;&amp;ldquo;delete&amp;nbsp;value&amp;nbsp;=&amp;nbsp;10&amp;rdquo; &lt;br /&gt;(응답)&amp;nbsp;&amp;ldquo;cmd&amp;nbsp;is&amp;nbsp;select,&amp;nbsp;value&amp;nbsp;is&amp;nbsp;10&amp;rdquo;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;02.PNG&quot; data-origin-width=&quot;455&quot; data-origin-height=&quot;504&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/dLzIl6/dJMcafd5fMC/mHNWqNDkfRk6eP6VnfBXXk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/dLzIl6/dJMcafd5fMC/mHNWqNDkfRk6eP6VnfBXXk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/dLzIl6/dJMcafd5fMC/mHNWqNDkfRk6eP6VnfBXXk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FdLzIl6%2FdJMcafd5fMC%2FmHNWqNDkfRk6eP6VnfBXXk%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;455&quot; height=&quot;504&quot; data-filename=&quot;02.PNG&quot; data-origin-width=&quot;455&quot; data-origin-height=&quot;504&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;pre id=&quot;code_1765807987462&quot; class=&quot;cpp&quot; data-ke-language=&quot;cpp&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;/* USER CODE BEGIN 0 */
char rx_buff[100];
char tx_buff[100];
int rx_pos = 0;
char data;
int num1 = 0;
void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart)
{
	//데이터 처리(종료문자가 \n인 상황)
	rx_buff[rx_pos++] = data;
	if(data == '\n'){
		//STM32가 echo
		rx_buff[rx_pos] = '\0';
		//rx_buff에 있는 데이터 형식 &amp;ldquo;select value = 10&amp;rdquo;
		if(sscanf(rx_buff,&quot;select value = %d&quot;,&amp;amp;num1) == 1){
			//성공
			sprintf(tx_buff,&quot;cmd is select, value is %d\n&quot;,num1);
			HAL_UART_Transmit(&amp;amp;huart2, tx_buff, strlen(tx_buff), 100);
		}else if(sscanf(rx_buff,&quot;update value = %d&quot;,&amp;amp;num1) == 1){
			//성공
			sprintf(tx_buff,&quot;cmd is update, value is %d\n&quot;,num1);
			HAL_UART_Transmit(&amp;amp;huart2, tx_buff, strlen(tx_buff), 100);
		}else if(sscanf(rx_buff,&quot;delete value = %d&quot;,&amp;amp;num1) == 1){
			//성공
			sprintf(tx_buff,&quot;cmd is delete, value is %d\n&quot;,num1);
			HAL_UART_Transmit(&amp;amp;huart2, tx_buff, strlen(tx_buff), 100);
		}else{
			//실패
			HAL_UART_Transmit(&amp;amp;huart2, &quot;error!\n&quot;, 7, 100);
		}
		rx_pos = 0;
	}
	//수신인터럽트 다시 시작
	HAL_UART_Receive_IT(&amp;amp;huart2, &amp;amp;data, 1);
}&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;(C#코드는 예제1과 같음)&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;br /&gt;3.예제2에서&amp;nbsp;녹칸다가&amp;nbsp;제기한&amp;nbsp;원인을&amp;nbsp;해결하는&amp;nbsp;방법에서&amp;nbsp;약간&amp;nbsp;다른&amp;nbsp;방법을&amp;nbsp;제시해보시오!(여러개의&amp;nbsp;조건문을&amp;nbsp;1개로&amp;nbsp;압축하기)&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;03.PNG&quot; data-origin-width=&quot;459&quot; data-origin-height=&quot;493&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/szXoX/dJMcahbTmiI/trKQlgewtgSZ5NXoFLGFyk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/szXoX/dJMcahbTmiI/trKQlgewtgSZ5NXoFLGFyk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/szXoX/dJMcahbTmiI/trKQlgewtgSZ5NXoFLGFyk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FszXoX%2FdJMcahbTmiI%2FtrKQlgewtgSZ5NXoFLGFyk%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;459&quot; height=&quot;493&quot; data-filename=&quot;03.PNG&quot; data-origin-width=&quot;459&quot; data-origin-height=&quot;493&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;pre id=&quot;code_1765807998044&quot; class=&quot;cpp&quot; data-ke-language=&quot;cpp&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;/* USER CODE BEGIN 0 */
char rx_buff[100];
char tx_buff[100];
int rx_pos = 0;
char data;
int num1 = 0;
char cmd[20];
void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart)
{
	//데이터 처리(종료문자가 \n인 상황)
	rx_buff[rx_pos++] = data;
	if(data == '\n'){
		//STM32가 echo
		rx_buff[rx_pos] = '\0';
		//rx_buff에 있는 데이터 형식 &amp;ldquo;select value = 10&amp;rdquo;
		if(sscanf(rx_buff,&quot;%s value = %d&quot;,cmd,&amp;amp;num1) == 2){
			//성공
			sprintf(tx_buff,&quot;cmd is %s, value is %d\n&quot;,cmd,num1);
			HAL_UART_Transmit(&amp;amp;huart2, tx_buff, strlen(tx_buff), 100);
		}else{
			//실패
			HAL_UART_Transmit(&amp;amp;huart2, &quot;error!\n&quot;, 7, 100);
		}
		rx_pos = 0;
	}
	//수신인터럽트 다시 시작
	HAL_UART_Receive_IT(&amp;amp;huart2, &amp;amp;data, 1);
}&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;(C#코드는 예제1과 같음)&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;br /&gt;4.녹칸다가&amp;nbsp;아래와&amp;nbsp;같은&amp;nbsp;명령어를&amp;nbsp;입력하면&amp;nbsp;STM32의&amp;nbsp;PB3&amp;nbsp;LED가&amp;nbsp;제어된다! &lt;br /&gt;(LED&amp;nbsp;OFF)&amp;nbsp;&amp;ldquo;LED=0&amp;rdquo;&amp;nbsp;&amp;nbsp;(LED&amp;nbsp;ON)&amp;nbsp;&amp;ldquo;LED=1&amp;rdquo;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;04.PNG&quot; data-origin-width=&quot;542&quot; data-origin-height=&quot;367&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/c9LVK2/dJMcahXhBPa/uEUSxk9CTegcItCDXG2ImK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/c9LVK2/dJMcahXhBPa/uEUSxk9CTegcItCDXG2ImK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/c9LVK2/dJMcahXhBPa/uEUSxk9CTegcItCDXG2ImK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fc9LVK2%2FdJMcahXhBPa%2FuEUSxk9CTegcItCDXG2ImK%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;542&quot; height=&quot;367&quot; data-filename=&quot;04.PNG&quot; data-origin-width=&quot;542&quot; data-origin-height=&quot;367&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;pre id=&quot;code_1765808007772&quot; class=&quot;cpp&quot; data-ke-language=&quot;cpp&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;/* USER CODE BEGIN 0 */
char rx_buff[100];
char tx_buff[100];
int rx_pos = 0;
char data;
int state = 0;
char cmd[20];
void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart)
{
	//데이터 처리(종료문자가 \n인 상황)
	rx_buff[rx_pos++] = data;
	if(data == '\n'){
		//STM32가 echo
		rx_buff[rx_pos] = '\0';
		//rx_buff에 있는 데이터 형식 &quot;LED=0&quot;
		if(sscanf(rx_buff,&quot;LED=%d&quot;,&amp;amp;state) == 1){
			//성공
			if(state == 0){
				HAL_GPIO_WritePin(GPIOB, GPIO_PIN_3, state);
				HAL_UART_Transmit(&amp;amp;huart2, &quot;LED IS OFF!\n&quot;, 12, 100);
			}else if(state == 1){
				HAL_GPIO_WritePin(GPIOB, GPIO_PIN_3, state);
				HAL_UART_Transmit(&amp;amp;huart2, &quot;LED IS ON!\n&quot;, 11, 100);
			}
		}else{
			//실패
			HAL_UART_Transmit(&amp;amp;huart2, &quot;error!\n&quot;, 7, 100);
		}
		rx_pos = 0;
	}
	//수신인터럽트 다시 시작
	HAL_UART_Receive_IT(&amp;amp;huart2, &amp;amp;data, 1);
}&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;(C#코드는 예제1과 같음)&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;br /&gt;5.이번에는&amp;nbsp;예제4와&amp;nbsp;동일한&amp;nbsp;구성을&amp;nbsp;가지면서&amp;nbsp;STM32쉴드에&amp;nbsp;붙어있는&amp;nbsp;LED&amp;nbsp;8개를&amp;nbsp;개별적으로&amp;nbsp;제어할&amp;nbsp;수&amp;nbsp;있는&amp;nbsp;명령어&amp;nbsp;체계를&amp;nbsp;구성하시오! &lt;br /&gt;&amp;ldquo;LED@=%&amp;rdquo;&amp;nbsp;&amp;nbsp;:&amp;nbsp;LED번호는&amp;nbsp;@,&amp;nbsp;ON/OFF여부는&amp;nbsp;%&amp;nbsp;&amp;nbsp;(예시)&amp;nbsp;&amp;ldquo;LED2=1&amp;rdquo;&amp;nbsp;:&amp;nbsp;LED2번을&amp;nbsp;ON해라!&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;05.PNG&quot; data-origin-width=&quot;604&quot; data-origin-height=&quot;411&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/LNse3/dJMcagcZX15/a82QkjjQsvWWyg3Qfi8TX1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/LNse3/dJMcagcZX15/a82QkjjQsvWWyg3Qfi8TX1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/LNse3/dJMcagcZX15/a82QkjjQsvWWyg3Qfi8TX1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FLNse3%2FdJMcagcZX15%2Fa82QkjjQsvWWyg3Qfi8TX1%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;411&quot; data-filename=&quot;05.PNG&quot; data-origin-width=&quot;604&quot; data-origin-height=&quot;411&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;pre id=&quot;code_1765808025315&quot; class=&quot;cpp&quot; data-ke-language=&quot;cpp&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;/* USER CODE BEGIN 0 */
char rx_buff[100];
char tx_buff[100];
int rx_pos = 0;
char data;
int led_num = 0;
int state = 0;
char cmd[20];
void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart)
{
	//데이터 처리(종료문자가 \n인 상황)
	rx_buff[rx_pos++] = data;
	if(data == '\n'){
		//STM32가 echo
		rx_buff[rx_pos] = '\0';
		//rx_buff에 있는 데이터 형식 &quot;LED@=%&quot;
		if(sscanf(rx_buff,&quot;LED%d=%d&quot;,&amp;amp;led_num,&amp;amp;state) == 2){
			//성공
			if(led_num == 1){
				if(state == 0){
					HAL_GPIO_WritePin(GPIOB, GPIO_PIN_3, state);
					HAL_UART_Transmit(&amp;amp;huart2, &quot;LED1 IS OFF!\n&quot;, 13, 100);
				}else if(state == 1){
					HAL_GPIO_WritePin(GPIOB, GPIO_PIN_3, state);
					HAL_UART_Transmit(&amp;amp;huart2, &quot;LED1 IS ON!\n&quot;, 12, 100);
				}
			}else if(led_num == 2){
				if(state == 0){
					HAL_GPIO_WritePin(GPIOB, GPIO_PIN_13, state);
					HAL_UART_Transmit(&amp;amp;huart2, &quot;LED2 IS OFF!\n&quot;, 13, 100);
				}else if(state == 1){
					HAL_GPIO_WritePin(GPIOB, GPIO_PIN_13, state);
					HAL_UART_Transmit(&amp;amp;huart2, &quot;LED2 IS ON!\n&quot;, 12, 100);
				}

			}else if(led_num == 3){
				if(state == 0){
					HAL_GPIO_WritePin(GPIOB, GPIO_PIN_5, state);
					HAL_UART_Transmit(&amp;amp;huart2, &quot;LED3 IS OFF!\n&quot;, 13, 100);
				}else if(state == 1){
					HAL_GPIO_WritePin(GPIOB, GPIO_PIN_5, state);
					HAL_UART_Transmit(&amp;amp;huart2, &quot;LED3 IS ON!\n&quot;, 12, 100);
				}
			}else if(led_num == 4){
				if(state == 0){
					HAL_GPIO_WritePin(GPIOB, GPIO_PIN_14, state);
					HAL_UART_Transmit(&amp;amp;huart2, &quot;LED4 IS OFF!\n&quot;, 13, 100);
				}else if(state == 1){
					HAL_GPIO_WritePin(GPIOB, GPIO_PIN_14, state);
					HAL_UART_Transmit(&amp;amp;huart2, &quot;LED4 IS ON!\n&quot;, 12, 100);
				}
			}else if(led_num == 5){
				if(state == 0){
					HAL_GPIO_WritePin(GPIOB, GPIO_PIN_4, state);
					HAL_UART_Transmit(&amp;amp;huart2, &quot;LED5 IS OFF!\n&quot;, 13, 100);
				}else if(state == 1){
					HAL_GPIO_WritePin(GPIOB, GPIO_PIN_4, state);
					HAL_UART_Transmit(&amp;amp;huart2, &quot;LED5 IS ON!\n&quot;, 12, 100);
				}
			}else if(led_num == 6){
				if(state == 0){
					HAL_GPIO_WritePin(GPIOB, GPIO_PIN_15, state);
					HAL_UART_Transmit(&amp;amp;huart2, &quot;LED6 IS OFF!\n&quot;, 13, 100);
				}else if(state == 1){
					HAL_GPIO_WritePin(GPIOB, GPIO_PIN_15, state);
					HAL_UART_Transmit(&amp;amp;huart2, &quot;LED6 IS ON!\n&quot;, 12, 100);
				}

			}else if(led_num == 7){
				if(state == 0){
					HAL_GPIO_WritePin(GPIOC, GPIO_PIN_4, state);
					HAL_UART_Transmit(&amp;amp;huart2, &quot;LED7 IS OFF!\n&quot;, 13, 100);
				}else if(state == 1){
					HAL_GPIO_WritePin(GPIOC, GPIO_PIN_4, state);
					HAL_UART_Transmit(&amp;amp;huart2, &quot;LED7 IS ON!\n&quot;, 12, 100);
				}
			}else if(led_num == 8){
				if(state == 0){
					HAL_GPIO_WritePin(GPIOB, GPIO_PIN_7, state);
					HAL_UART_Transmit(&amp;amp;huart2, &quot;LED8 IS OFF!\n&quot;, 13, 100);
				}else if(state == 1){
					HAL_GPIO_WritePin(GPIOB, GPIO_PIN_7, state);
					HAL_UART_Transmit(&amp;amp;huart2, &quot;LED8 IS ON!\n&quot;, 12, 100);
				}
			}
		}else{
			//실패
			HAL_UART_Transmit(&amp;amp;huart2, &quot;error!\n&quot;, 7, 100);
		}
		rx_pos = 0;
	}
	//수신인터럽트 다시 시작
	HAL_UART_Receive_IT(&amp;amp;huart2, &amp;amp;data, 1);
}&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;(C#코드는 예제1과 같음)&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;br /&gt;6.예제5번에서&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-filename=&quot;06.PNG&quot; data-origin-width=&quot;648&quot; data-origin-height=&quot;351&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/9NN5C/dJMcabpcTAY/AeOjsZdDjZtSOp6zjPBEIk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/9NN5C/dJMcabpcTAY/AeOjsZdDjZtSOp6zjPBEIk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/9NN5C/dJMcabpcTAY/AeOjsZdDjZtSOp6zjPBEIk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2F9NN5C%2FdJMcabpcTAY%2FAeOjsZdDjZtSOp6zjPBEIk%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;648&quot; height=&quot;351&quot; data-filename=&quot;06.PNG&quot; data-origin-width=&quot;648&quot; data-origin-height=&quot;351&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;pre id=&quot;code_1765808038822&quot; class=&quot;cpp&quot; data-ke-language=&quot;cpp&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;/* USER CODE BEGIN 0 */
char rx_buff[100];
char tx_buff[100];
int rx_pos = 0;
char data;
int led_num = 0;
int state = 0;
char cmd[20];
GPIO_TypeDef *mygpio[] = {GPIOB,GPIOB,GPIOB,GPIOB,GPIOB,GPIOB,GPIOC,GPIOB};
uint16_t mypin[] = {GPIO_PIN_3,GPIO_PIN_13,GPIO_PIN_5,GPIO_PIN_14,GPIO_PIN_4,GPIO_PIN_15,GPIO_PIN_4,GPIO_PIN_7};
void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart)
{
	//데이터 처리(종료문자가 \n인 상황)
	rx_buff[rx_pos++] = data;
	if(data == '\n'){
		//STM32가 echo
		rx_buff[rx_pos] = '\0';
		//rx_buff에 있는 데이터 형식 &quot;LED@=%&quot;
		if(sscanf(rx_buff,&quot;LED%d=%d&quot;,&amp;amp;led_num,&amp;amp;state) == 2){
			//성공
			if(led_num &amp;gt;=0 &amp;amp;&amp;amp; led_num&amp;lt;=8 &amp;amp;&amp;amp; (state == 0 || state == 1)){
				HAL_GPIO_WritePin(mygpio[led_num-1], mypin[led_num-1], state);
				sprintf(tx_buff,&quot;LED%d IS %s\n&quot;,led_num,state == 0 ? &quot;OFF&quot; : &quot;ON&quot;);
				HAL_UART_Transmit(&amp;amp;huart2, tx_buff, strlen(tx_buff), 100);
			}else{
				HAL_UART_Transmit(&amp;amp;huart2, &quot;error-2!\n&quot;, 9, 100);
			}
		}else{
			//실패
			HAL_UART_Transmit(&amp;amp;huart2, &quot;error-1!\n&quot;, 9, 100);
		}
		rx_pos = 0;
	}
	//수신인터럽트 다시 시작
	HAL_UART_Receive_IT(&amp;amp;huart2, &amp;amp;data, 1);
}&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;(C#코드는 예제1과 같음)&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;p data-ke-size=&quot;size16&quot;&gt;&lt;br /&gt;7.예제6번에서&amp;nbsp;동작하는&amp;nbsp;방식을&amp;nbsp;JSON명령어를&amp;nbsp;인식하도록&amp;nbsp;하시오! &lt;br /&gt;{&quot;led_num&quot;:1,&quot;state&quot;:0}&amp;nbsp;:&amp;nbsp;LED1&amp;nbsp;OFF &lt;br /&gt;{&quot;led_num&quot;:3,&quot;state&quot;:1}&amp;nbsp;:&amp;nbsp;LED3&amp;nbsp;ON&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;07.PNG&quot; data-origin-width=&quot;580&quot; data-origin-height=&quot;289&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bjZS9y/dJMcag48nEo/VFZL79ATfYm2bb7kTq6Rm0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bjZS9y/dJMcag48nEo/VFZL79ATfYm2bb7kTq6Rm0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bjZS9y/dJMcag48nEo/VFZL79ATfYm2bb7kTq6Rm0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbjZS9y%2FdJMcag48nEo%2FVFZL79ATfYm2bb7kTq6Rm0%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;580&quot; height=&quot;289&quot; data-filename=&quot;07.PNG&quot; data-origin-width=&quot;580&quot; data-origin-height=&quot;289&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;pre id=&quot;code_1765808048168&quot; class=&quot;cpp&quot; data-ke-language=&quot;cpp&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;/* USER CODE BEGIN 0 */
char rx_buff[100];
char tx_buff[100];
int rx_pos = 0;
char data;
int led_num = 0;
int state = 0;
char cmd[20];
GPIO_TypeDef *mygpio[] = {GPIOB,GPIOB,GPIOB,GPIOB,GPIOB,GPIOB,GPIOC,GPIOB};
uint16_t mypin[] = {GPIO_PIN_3,GPIO_PIN_13,GPIO_PIN_5,GPIO_PIN_14,GPIO_PIN_4,GPIO_PIN_15,GPIO_PIN_4,GPIO_PIN_7};
void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart)
{
	//데이터 처리(종료문자가 \n인 상황)
	rx_buff[rx_pos++] = data;
	if(data == '\n'){
		//STM32가 echo
		rx_buff[rx_pos] = '\0';
		//rx_buff에 있는 데이터 형식 &quot;{&quot;led_num&quot;:1,&quot;state&quot;:0}&quot;
		if(sscanf(rx_buff,&quot;{\&quot;led_num\&quot;:%d,\&quot;state\&quot;:%d}&quot;,&amp;amp;led_num,&amp;amp;state) == 2){
			//성공
			if(led_num &amp;gt;=0 &amp;amp;&amp;amp; led_num&amp;lt;=8 &amp;amp;&amp;amp; (state == 0 || state == 1)){
				HAL_GPIO_WritePin(mygpio[led_num-1], mypin[led_num-1], state);
				sprintf(tx_buff,&quot;LED%d IS %s\n&quot;,led_num,state == 0 ? &quot;OFF&quot; : &quot;ON&quot;);
				HAL_UART_Transmit(&amp;amp;huart2, tx_buff, strlen(tx_buff), 100);
			}else{
				HAL_UART_Transmit(&amp;amp;huart2, &quot;error-2!\n&quot;, 9, 100);
			}
		}else{
			//실패
			HAL_UART_Transmit(&amp;amp;huart2, &quot;error-1!\n&quot;, 9, 100);
		}
		rx_pos = 0;
	}
	HAL_UART_Receive_IT(&amp;amp;huart2, &amp;amp;data, 1);//수신인터럽트 다시 시작
}&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;(C#코드는 예제1과 같음)&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;br /&gt;8.데이터&amp;nbsp;형식이&amp;nbsp;JSON이&amp;nbsp;되었으니,&amp;nbsp;C#에서도&amp;nbsp;JSON데이터를&amp;nbsp;생성할&amp;nbsp;수&amp;nbsp;있게&amp;nbsp;되었다!&amp;nbsp;C#에&amp;nbsp;JSON라이브러리를&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-filename=&quot;08.PNG&quot; data-origin-width=&quot;496&quot; data-origin-height=&quot;269&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/qAI0y/dJMcag48nEW/QGrw24kvJ9GOxcJVaAifF1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/qAI0y/dJMcag48nEW/QGrw24kvJ9GOxcJVaAifF1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/qAI0y/dJMcag48nEW/QGrw24kvJ9GOxcJVaAifF1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FqAI0y%2FdJMcag48nEW%2FQGrw24kvJ9GOxcJVaAifF1%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;496&quot; height=&quot;269&quot; data-filename=&quot;08.PNG&quot; data-origin-width=&quot;496&quot; data-origin-height=&quot;269&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;pre id=&quot;code_1765808072161&quot; class=&quot;cpp&quot; data-ke-language=&quot;cpp&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;/* USER CODE BEGIN 0 */
char rx_buff[100];
char tx_buff[100];
int rx_pos = 0;
char data;
int led_num = 0;
int state = 0;
char cmd[20];
GPIO_TypeDef *mygpio[] = {GPIOB,GPIOB,GPIOB,GPIOB,GPIOB,GPIOB,GPIOC,GPIOB};
uint16_t mypin[] = {GPIO_PIN_3,GPIO_PIN_13,GPIO_PIN_5,GPIO_PIN_14,GPIO_PIN_4,GPIO_PIN_15,GPIO_PIN_4,GPIO_PIN_7};
void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart)
{
	//데이터 처리(종료문자가 \n인 상황)
	rx_buff[rx_pos++] = data;
	if(data == '\n'){
		//STM32가 echo
		rx_buff[rx_pos] = '\0';
		//rx_buff에 있는 데이터 형식 &quot;{&quot;led_num&quot;:1,&quot;state&quot;:0}&quot;
		if(sscanf(rx_buff,&quot;{\&quot;led_num\&quot;:%d,\&quot;state\&quot;:%d}&quot;,&amp;amp;led_num,&amp;amp;state) == 2){
			//성공
			if(led_num &amp;gt;=0 &amp;amp;&amp;amp; led_num&amp;lt;=8 &amp;amp;&amp;amp; (state == 0 || state == 1)){
				HAL_GPIO_WritePin(mygpio[led_num-1], mypin[led_num-1], state);
				sprintf(tx_buff,&quot;LED%d IS %s\n&quot;,led_num,state == 0 ? &quot;OFF&quot; : &quot;ON&quot;);
				HAL_UART_Transmit(&amp;amp;huart2, tx_buff, strlen(tx_buff), 100);
			}else{
				HAL_UART_Transmit(&amp;amp;huart2, &quot;error-2!\n&quot;, 9, 100);
			}
		}else{
			//실패
			HAL_UART_Transmit(&amp;amp;huart2, &quot;error-1!\n&quot;, 9, 100);
		}
		rx_pos = 0;
	}
	HAL_UART_Receive_IT(&amp;amp;huart2, &amp;amp;data, 1);//수신인터럽트 다시 시작
}&lt;/code&gt;&lt;/pre&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;pre id=&quot;code_1765808210235&quot; class=&quot;csharp&quot; data-ke-language=&quot;csharp&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;using Newtonsoft.Json;
////////////////////////////////////
//C#의 전역위치
        class Nockanda
        {
            public int led_num;
            public int state;
        }

        Nockanda data = new Nockanda();
/////////////////////////////////////
private void button1_Click(object sender, EventArgs e)
        {
            serialPort1.PortName = textBox1.Text;
            serialPort1.BaudRate = 115200; //usart2

            serialPort1.Open(); //개방!

            if (serialPort1.IsOpen)
            {
                serialPort1.ReadExisting();
                MessageBox.Show(&quot;연결완료!&quot;);
            }
        }

        private void serialPort1_DataReceived(object sender, System.IO.Ports.SerialDataReceivedEventArgs e)
        {
            string data = serialPort1.ReadLine();
            richTextBox1.Text += &quot;[수신]=&quot; + data + &quot;\n&quot;;
        }
        void send_data(int led_num, int state)
        {
            if (serialPort1.IsOpen)
            {
                data.led_num = led_num;
                data.state = state;
                string output = JsonConvert.SerializeObject(data);
                serialPort1.WriteLine(output);
            }
        }

        private void button2_Click(object sender, EventArgs e)
        {
            send_data(1, 1);
        }

        private void button3_Click(object sender, EventArgs e)
        {
            send_data(1, 0);
        }

        private void button4_Click(object sender, EventArgs e)
        {
            send_data(2, 1);
        }

        private void button5_Click(object sender, EventArgs e)
        {
            send_data(2, 0);
        }


        private void button6_Click(object sender, EventArgs e)
        {
            send_data(3, 1);
        }

        private void button7_Click(object sender, EventArgs e)
        {
            send_data(3, 0);
        }

        private void button8_Click(object sender, EventArgs e)
        {
            send_data(4, 1);
        }

        private void button9_Click(object sender, EventArgs e)
        {
            send_data(4, 0);
        }

        private void button10_Click(object sender, EventArgs e)
        {
            send_data(5, 1);
        }

        private void button11_Click(object sender, EventArgs e)
        {
            send_data(5, 0);
        }

        private void button12_Click(object sender, EventArgs e)
        {
            send_data(6, 1);
        }

        private void button13_Click(object sender, EventArgs e)
        {
            send_data(6, 0);
        }

        private void button14_Click(object sender, EventArgs e)
        {
            send_data(7, 1);
        }

        private void button15_Click(object sender, EventArgs e)
        {
            send_data(7, 0);
        }

        private void button16_Click(object sender, EventArgs e)
        {
            send_data(8, 1);
        }

        private void button17_Click(object sender, EventArgs e)
        {
            send_data(8, 0);
        }&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;br /&gt;9.STM32의&amp;nbsp;수신인터럽트에서&amp;nbsp;1개의&amp;nbsp;문자를&amp;nbsp;받으면&amp;nbsp;즉시&amp;nbsp;응답하도록&amp;nbsp;해서&amp;nbsp;putty에서&amp;nbsp;데이터를&amp;nbsp;전송하시오!&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;09.PNG&quot; data-origin-width=&quot;792&quot; data-origin-height=&quot;178&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/T6BxH/dJMcabCKvGW/OmGE2ZpYhbVuO2QasQrIKk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/T6BxH/dJMcabCKvGW/OmGE2ZpYhbVuO2QasQrIKk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/T6BxH/dJMcabCKvGW/OmGE2ZpYhbVuO2QasQrIKk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FT6BxH%2FdJMcabCKvGW%2FOmGE2ZpYhbVuO2QasQrIKk%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;792&quot; height=&quot;178&quot; data-filename=&quot;09.PNG&quot; data-origin-width=&quot;792&quot; data-origin-height=&quot;178&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;pre id=&quot;code_1765808085722&quot; class=&quot;cpp&quot; data-ke-language=&quot;cpp&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;/* USER CODE BEGIN 0 */
#define b_size 256
uint8_t ring_buffer[b_size];
int head = 0;
int tail = 0;
char data;
char tx_buff[256];
int tx_pos = 0;
void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart)
{
	//수신인터럽트로 받은 데이터를 ring_buffer에 대입한다
	//버퍼에 집어넣는 쪽
	ring_buffer[head++] = data;
	if(head == b_size) head = 0;
	//bad case
	//HAL_UART_Transmit(&amp;amp;huart2, &amp;amp;data, 1, 100);
	//수신인터럽트 다시 시작
	HAL_UART_Receive_IT(&amp;amp;huart2, &amp;amp;data, 1);
}


/* USER CODE BEGIN 2 */
 HAL_UART_Receive_IT(&amp;amp;huart2, &amp;amp;data, 1); //수신인터럽트 시작
 /* USER CODE END 2 */
 /* Infinite loop */
 /* USER CODE BEGIN WHILE */
 while (1)
 {
	  //버퍼에서 읽는 쪽
		if(head != tail){
			tx_buff[tx_pos++] = ring_buffer[tail];
			if(ring_buffer[tail] == '\n'){
				//녹칸다가 보낸 데이터의 끝지점이구나!
				tx_buff[tx_pos] = '\0';
				tx_pos = 0;
				HAL_UART_Transmit(&amp;amp;huart2, tx_buff, strlen(tx_buff), 100);
			}
			tail++;
			if (tail == b_size) tail = 0;
		}
   /* USER CODE END WHILE */
   /* USER CODE BEGIN 3 */
 }&lt;/code&gt;&lt;/pre&gt;</description>
      <category>프로그래밍/STM32</category>
      <author>덕력킹</author>
      <guid isPermaLink="true">https://bota.tistory.com/2461</guid>
      <comments>https://bota.tistory.com/2461#entry2461comment</comments>
      <pubDate>Mon, 15 Dec 2025 23:19:47 +0900</pubDate>
    </item>
    <item>
      <title>[STM32#18] HAL_UART_Receive_IT, HAL_UART_RxCpltCallback수신 인터럽트를 이용해서 각종 모터 제어해보기!(녹칸다 내맘대로 STM32)</title>
      <link>https://bota.tistory.com/2460</link>
      <description>&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;stm32.png&quot; data-origin-width=&quot;1920&quot; data-origin-height=&quot;1080&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/Ne4bH/dJMcafE7wgN/Sm1S3kQQEbF01qJTJrSS31/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/Ne4bH/dJMcafE7wgN/Sm1S3kQQEbF01qJTJrSS31/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/Ne4bH/dJMcafE7wgN/Sm1S3kQQEbF01qJTJrSS31/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FNe4bH%2FdJMcafE7wgN%2FSm1S3kQQEbF01qJTJrSS31%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;1920&quot; height=&quot;1080&quot; data-filename=&quot;stm32.png&quot; data-origin-width=&quot;1920&quot; data-origin-height=&quot;1080&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/live/NtAF5P2SCoM&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://youtube.com/live/NtAF5P2SCoM&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/watch?v=NtAF5P2SCoM&quot; data-video-thumbnail=&quot;https://scrap.kakaocdn.net/dn/h86M4/hyZOIel9uk/GesNyUnfKviWHhWEKHJWRk/img.jpg?width=1280&amp;amp;height=720&amp;amp;face=0_0_1280_720,https://scrap.kakaocdn.net/dn/wnmU4/hyZPfbYBMk/FJyOxl2OKwVhrxN1e8EjVK/img.jpg?width=1280&amp;amp;height=720&amp;amp;face=0_0_1280_720&quot; data-video-width=&quot;860&quot; data-video-height=&quot;484&quot; data-video-origin-width=&quot;860&quot; data-video-origin-height=&quot;484&quot; data-ke-mobilestyle=&quot;widthContent&quot; data-video-title=&quot;[STM32#18] HAL_UART_Receive_IT, HAL_UART_RxCpltCallback수신 인터럽트를 이용해서 각종 모터 제어해보기!(녹칸&quot; data-original-url=&quot;&quot;&gt;&lt;iframe src=&quot;https://www.youtube.com/embed/NtAF5P2SCoM&quot; width=&quot;860&quot; height=&quot;484&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;[STM32#18]&amp;nbsp;HAL_UART_Receive_IT,&amp;nbsp;HAL_UART_RxCpltCallback수신&amp;nbsp;인터럽트를&amp;nbsp;이용해서&amp;nbsp;각종&amp;nbsp;모터&amp;nbsp;제어해보기!(녹칸다&amp;nbsp;내맘대로&amp;nbsp;STM32) &lt;br /&gt;&lt;br /&gt;심심한녹칸다의&amp;nbsp;내맘대로&amp;nbsp;STM32시리즈이다! &lt;br /&gt;&lt;br /&gt;STM32시리즈의&amp;nbsp;모든&amp;nbsp;자료는&amp;nbsp;구글&amp;nbsp;슬라이드에&amp;nbsp;작성하고&amp;nbsp;모두에게&amp;nbsp;공유되어있음! &lt;br /&gt;&lt;a href=&quot;https://docs.google.com/presentation/d/1myA5iYbjuKsLWLqtRLKAiRfwUwvqB1d1RGjiMIIgp3I/edit?slide=id.g3ae770b99e6_1_256#slide=id.g3ae770b99e6_1_256&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://docs.google.com/presentation/d/1myA5iYbjuKsLWLqtRLKAiRfwUwvqB1d1RGjiMIIgp3I/edit?slide=id.g3ae770b99e6_1_256#slide=id.g3ae770b99e6_1_256&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;녹칸다의&amp;nbsp;STM32쉴드에&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;수신인터럽트 ioc 설정&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;ioc설정.PNG&quot; data-origin-width=&quot;717&quot; data-origin-height=&quot;616&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/q8Be3/dJMcadHgfSD/uhGBieNOEtQNOnowVkjox0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/q8Be3/dJMcadHgfSD/uhGBieNOEtQNOnowVkjox0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/q8Be3/dJMcadHgfSD/uhGBieNOEtQNOnowVkjox0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fq8Be3%2FdJMcadHgfSD%2FuhGBieNOEtQNOnowVkjox0%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;717&quot; height=&quot;616&quot; data-filename=&quot;ioc설정.PNG&quot; data-origin-width=&quot;717&quot; data-origin-height=&quot;616&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;br /&gt;1.STM32의&amp;nbsp;usart2수신부분을&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-filename=&quot;01.PNG&quot; data-origin-width=&quot;1364&quot; data-origin-height=&quot;553&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bTXqWF/dJMcaajvsVf/lN7xGBjJOuYsEG6kqv47V0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bTXqWF/dJMcaajvsVf/lN7xGBjJOuYsEG6kqv47V0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bTXqWF/dJMcaajvsVf/lN7xGBjJOuYsEG6kqv47V0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbTXqWF%2FdJMcaajvsVf%2FlN7xGBjJOuYsEG6kqv47V0%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;1364&quot; height=&quot;553&quot; data-filename=&quot;01.PNG&quot; data-origin-width=&quot;1364&quot; data-origin-height=&quot;553&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;pre id=&quot;code_1765351959598&quot; class=&quot;cpp&quot; data-ke-language=&quot;cpp&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;/* USER CODE BEGIN 0 */
char recv;
char buff[100]; //수신메모리
int pos = 0;
/* USER CODE END 0 */

/* USER CODE BEGIN 2 */
 HAL_UART_Receive_IT(&amp;amp;huart2, &amp;amp;recv, 1); //수신인터럽트 시작
 char buff2[100];
 /* USER CODE END 2 */
/* USER CODE BEGIN WHILE */
 while (1)
 {
	  //1초간격으로 stm32의 타이머카운터값을 전송한다!
	  sprintf(buff2,&quot;now getTick = %d\n&quot;,HAL_GetTick());
	  HAL_UART_Transmit(&amp;amp;huart2, buff2, strlen(buff2), 100);
	  HAL_Delay(1000);
   /* USER CODE END WHILE */
   /* USER CODE BEGIN 3 */
 }


/* USER CODE BEGIN 4 */
//usart2 수신인터럽트
void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart)
{
	//recv에 1개 읽은 문자가 들어있는 상황이다!
	buff[pos] = recv;
	pos++;
	if(recv == '\r'){
		buff[pos] = '\n';
		pos++;
		buff[pos] = '\0';
		//echo
		HAL_UART_Transmit(&amp;amp;huart2, buff, strlen(buff), 100);
		pos = 0;
	}
   //수신인터럽트 다시 시작
	HAL_UART_Receive_IT(&amp;amp;huart2, &amp;amp;recv, 1);
}
/* USER CODE END 4 */&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;br /&gt;2.C#윈폼에서&amp;nbsp;STM32와&amp;nbsp;시리얼통신으로&amp;nbsp;연결되고&amp;nbsp;버튼1을&amp;nbsp;누르면&amp;nbsp;0도,&amp;nbsp;버튼2를&amp;nbsp;누르면&amp;nbsp;90도,&amp;nbsp;버튼3을&amp;nbsp;누르면&amp;nbsp;180도로&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-filename=&quot;02.PNG&quot; data-origin-width=&quot;1061&quot; data-origin-height=&quot;557&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/drSkCG/dJMcaaw2TJF/04UaQmpOYkAlgZBwp1cUR1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/drSkCG/dJMcaaw2TJF/04UaQmpOYkAlgZBwp1cUR1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/drSkCG/dJMcaaw2TJF/04UaQmpOYkAlgZBwp1cUR1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FdrSkCG%2FdJMcaaw2TJF%2F04UaQmpOYkAlgZBwp1cUR1%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;1061&quot; height=&quot;557&quot; data-filename=&quot;02.PNG&quot; data-origin-width=&quot;1061&quot; data-origin-height=&quot;557&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;pre id=&quot;code_1765351971451&quot; class=&quot;cpp&quot; data-ke-language=&quot;cpp&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;/* USER CODE BEGIN 0 */
char recv;
char buff[100]; //수신메모리
int pos = 0;
void set_servo(uint8_t degree){
	//degree는 0~180도 범위이고 CCR4는 600부터 2400의 범위이다!
	TIM2-&amp;gt;CCR4 = (uint32_t)(600+(2400-600)*degree/180.0);
}
/* USER CODE END 0 */


/* USER CODE BEGIN 2 */
 HAL_UART_Receive_IT(&amp;amp;huart2, &amp;amp;recv, 1); //수신인터럽트 시작
 HAL_TIM_PWM_Start(&amp;amp;htim2,TIM_CHANNEL_4); //PWM시작~
 char buff2[100];
 /* USER CODE END 2 */

while (1)
 {
   /* USER CODE END WHILE */
   /* USER CODE BEGIN 3 */
 }



/* USER CODE BEGIN 4 */
//usart2 수신인터럽트
void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart)
{
	//recv에 1개 읽은 문자가 들어있는 상황이다!
	buff[pos] = recv;
	pos++;
	if(recv == '\n'){
		buff[pos] = '\0';
		//C#에서 보낸 데이터 한덩어리가 여기서 처리된다!
		//&quot;0&quot; ~ &quot;180&quot;
		int degree = atoi(buff);
		set_servo(degree);
		pos = 0;
	}
   //수신인터럽트 다시 시작
	HAL_UART_Receive_IT(&amp;amp;huart2, &amp;amp;recv, 1);
}&lt;/code&gt;&lt;/pre&gt;
&lt;pre id=&quot;code_1765352267490&quot; class=&quot;csharp&quot; data-ke-language=&quot;csharp&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;private void button1_Click(object sender, EventArgs e)
        {
            serialPort1.PortName = textBox1.Text;
            serialPort1.BaudRate = 115200;
            serialPort1.Open();
            if (serialPort1.IsOpen)
            {
                serialPort1.ReadExisting();
                MessageBox.Show(&quot;접속완료!&quot;);
            }
        }

        private void button2_Click(object sender, EventArgs e)
        {
            if (serialPort1.IsOpen)
            {
                serialPort1.WriteLine(&quot;0&quot;);
            }
        }

private void button3_Click(object sender, EventArgs e)
        {
            if (serialPort1.IsOpen)
            {
                serialPort1.WriteLine(&quot;90&quot;);
            }
        }

        private void button4_Click(object sender, EventArgs e)
        {
            if (serialPort1.IsOpen)
            {
                serialPort1.WriteLine(&quot;180&quot;);
            }
        }&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;br /&gt;3.이번에는 컨트롤중에 numericupdown이라는 녀석을 이용해서 사용자가 입력한 숫자값을 버튼을 누르면 STM32에 전송해서 각도를 제어하시오!(STM32코드는 예제2와 동일함)&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;03.PNG&quot; data-origin-width=&quot;993&quot; data-origin-height=&quot;596&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/GW8vT/dJMcahbRuIi/fAQ8iWbdd9ry2tMpTtOzDK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/GW8vT/dJMcahbRuIi/fAQ8iWbdd9ry2tMpTtOzDK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/GW8vT/dJMcahbRuIi/fAQ8iWbdd9ry2tMpTtOzDK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FGW8vT%2FdJMcahbRuIi%2FfAQ8iWbdd9ry2tMpTtOzDK%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;596&quot; data-filename=&quot;03.PNG&quot; data-origin-width=&quot;993&quot; data-origin-height=&quot;596&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;pre id=&quot;code_1765351984205&quot; class=&quot;cpp&quot; data-ke-language=&quot;cpp&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;/* USER CODE BEGIN 0 */
char recv;
char buff[100]; //수신메모리
int pos = 0;
void set_servo(uint8_t degree){
	//degree는 0~180도 범위이고 CCR4는 600부터 2400의 범위이다!
	TIM2-&amp;gt;CCR4 = (uint32_t)(600+(2400-600)*degree/180.0);
}
/* USER CODE END 0 */


/* USER CODE BEGIN 2 */
 HAL_UART_Receive_IT(&amp;amp;huart2, &amp;amp;recv, 1); //수신인터럽트 시작
 HAL_TIM_PWM_Start(&amp;amp;htim2,TIM_CHANNEL_4); //PWM시작~
 char buff2[100];
 /* USER CODE END 2 */

while (1)
 {
   /* USER CODE END WHILE */
   /* USER CODE BEGIN 3 */
 }



/* USER CODE BEGIN 4 */
//usart2 수신인터럽트
void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart)
{
	//recv에 1개 읽은 문자가 들어있는 상황이다!
	buff[pos] = recv;
	pos++;
	if(recv == '\n'){
		buff[pos] = '\0';
		//C#에서 보낸 데이터 한덩어리가 여기서 처리된다!
		//&quot;0&quot; ~ &quot;180&quot;
		int degree = atoi(buff);
		set_servo(degree);
		pos = 0;
	}
   //수신인터럽트 다시 시작
	HAL_UART_Receive_IT(&amp;amp;huart2, &amp;amp;recv, 1);
}&lt;/code&gt;&lt;/pre&gt;
&lt;pre id=&quot;code_1765352277045&quot; class=&quot;csharp&quot; data-ke-language=&quot;csharp&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;private void button1_Click(object sender, EventArgs e)
        {
            serialPort1.PortName = textBox1.Text;
            serialPort1.BaudRate = 115200;
            serialPort1.Open();
            if (serialPort1.IsOpen)
            {
                serialPort1.ReadExisting();
                MessageBox.Show(&quot;접속완료!&quot;);
            }
        }

        private void button5_Click(object sender, EventArgs e)
        {
            //전송버튼 클릭이벤트!
            if (serialPort1.IsOpen)
            {
                serialPort1.WriteLine(numericUpDown1.Value.ToString());
            }
        }&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;br /&gt;4.이번에는&amp;nbsp;컨트롤중에&amp;nbsp;hcrollbar라는&amp;nbsp;녀석을&amp;nbsp;이용해서&amp;nbsp;컨트롤을&amp;nbsp;드래그해서&amp;nbsp;서보모터의&amp;nbsp;각도를&amp;nbsp;회전시키시오!(STM32코드는&amp;nbsp;예제2와&amp;nbsp;동일함)&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;04.PNG&quot; data-origin-width=&quot;1033&quot; data-origin-height=&quot;594&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/mREyR/dJMcacuRDbL/TNcZB7KzkedHm2Cn1gdOaK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/mREyR/dJMcacuRDbL/TNcZB7KzkedHm2Cn1gdOaK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/mREyR/dJMcacuRDbL/TNcZB7KzkedHm2Cn1gdOaK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FmREyR%2FdJMcacuRDbL%2FTNcZB7KzkedHm2Cn1gdOaK%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;1033&quot; height=&quot;594&quot; data-filename=&quot;04.PNG&quot; data-origin-width=&quot;1033&quot; data-origin-height=&quot;594&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;pre id=&quot;code_1765351998126&quot; class=&quot;cpp&quot; data-ke-language=&quot;cpp&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;/* USER CODE BEGIN 0 */
char recv;
char buff[100]; //수신메모리
int pos = 0;
void set_servo(uint8_t degree){
	//degree는 0~180도 범위이고 CCR4는 600부터 2400의 범위이다!
	TIM2-&amp;gt;CCR4 = (uint32_t)(600+(2400-600)*degree/180.0);
}
/* USER CODE END 0 */


/* USER CODE BEGIN 2 */
 HAL_UART_Receive_IT(&amp;amp;huart2, &amp;amp;recv, 1); //수신인터럽트 시작
 HAL_TIM_PWM_Start(&amp;amp;htim2,TIM_CHANNEL_4); //PWM시작~
 char buff2[100];
 /* USER CODE END 2 */

while (1)
 {
   /* USER CODE END WHILE */
   /* USER CODE BEGIN 3 */
 }



/* USER CODE BEGIN 4 */
//usart2 수신인터럽트
void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart)
{
	//recv에 1개 읽은 문자가 들어있는 상황이다!
	buff[pos] = recv;
	pos++;
	if(recv == '\n'){
		buff[pos] = '\0';
		//C#에서 보낸 데이터 한덩어리가 여기서 처리된다!
		//&quot;0&quot; ~ &quot;180&quot;
		int degree = atoi(buff);
		set_servo(degree);
		pos = 0;
	}
   //수신인터럽트 다시 시작
	HAL_UART_Receive_IT(&amp;amp;huart2, &amp;amp;recv, 1);
}&lt;/code&gt;&lt;/pre&gt;
&lt;pre id=&quot;code_1765352285256&quot; class=&quot;csharp&quot; data-ke-language=&quot;csharp&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;private void button1_Click(object sender, EventArgs e)
        {
            serialPort1.PortName = textBox1.Text;
            serialPort1.BaudRate = 115200;
            serialPort1.Open();
            if (serialPort1.IsOpen)
            {
                serialPort1.ReadExisting();
                MessageBox.Show(&quot;접속완료!&quot;);
            }
        }

        private void hScrollBar1_Scroll(object sender, ScrollEventArgs e)
        {
            label2.Text = hScrollBar1.Value.ToString();
            if (serialPort1.IsOpen)
            {
                serialPort1.WriteLine(hScrollBar1.Value.ToString());
            }
        }&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;br /&gt;5.예제4에서&amp;nbsp;STM32보드가&amp;nbsp;100밀리초&amp;nbsp;간격으로&amp;nbsp;현재&amp;nbsp;서보모터의&amp;nbsp;설정&amp;nbsp;각도를&amp;nbsp;전송하고&amp;nbsp;C#은&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-filename=&quot;05.PNG&quot; data-origin-width=&quot;1070&quot; data-origin-height=&quot;595&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/oOd5b/dJMcagKNlSx/KqcmvkCioxS23wKBKBsex0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/oOd5b/dJMcagKNlSx/KqcmvkCioxS23wKBKBsex0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/oOd5b/dJMcagKNlSx/KqcmvkCioxS23wKBKBsex0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FoOd5b%2FdJMcagKNlSx%2FKqcmvkCioxS23wKBKBsex0%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;1070&quot; height=&quot;595&quot; data-filename=&quot;05.PNG&quot; data-origin-width=&quot;1070&quot; data-origin-height=&quot;595&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;pre id=&quot;code_1765352009249&quot; class=&quot;cpp&quot; data-ke-language=&quot;cpp&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;/* USER CODE BEGIN 0 */
char recv;
char buff[100]; //수신메모리
int pos = 0;
int degree = 0; //현재 서보모터의 각도값
void set_servo(uint8_t degree){
	//degree는 0~180도 범위이고 CCR4는 600부터 2400의 범위이다!
	TIM2-&amp;gt;CCR4 = (uint32_t)(600+(2400-600)*degree/180.0);
}
/* USER CODE END 0 */



/* USER CODE BEGIN 2 */
 HAL_UART_Receive_IT(&amp;amp;huart2, &amp;amp;recv, 1); //수신인터럽트 시작
 HAL_TIM_PWM_Start(&amp;amp;htim2,TIM_CHANNEL_4); //PWM시작~
 char buff2[100];
 /* USER CODE END 2 */

/* USER CODE BEGIN WHILE */
 while (1)
 {
	  //0.1초간격으로 degree값을 C#으로 전송한다!(종료문자 \n)
	  sprintf(buff2,&quot;%d\n&quot;,degree);
	  HAL_UART_Transmit(&amp;amp;huart2, buff2, strlen(buff2), 100);
	  HAL_Delay(100);
   /* USER CODE END WHILE */
   /* USER CODE BEGIN 3 */
 }
/* USER CODE BEGIN 4 */
//usart2 수신인터럽트
void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart)
{
	//recv에 1개 읽은 문자가 들어있는 상황이다!
	buff[pos] = recv;
	pos++;
	if(recv == '\n'){
		buff[pos] = '\0';
		//C#에서 보낸 데이터 한덩어리가 여기서 처리된다!
		//&quot;0&quot; ~ &quot;180&quot;
		int degree = atoi(buff);
		set_servo(degree);
		pos = 0;
	}
   //수신인터럽트 다시 시작
	HAL_UART_Receive_IT(&amp;amp;huart2, &amp;amp;recv, 1);
}&lt;/code&gt;&lt;/pre&gt;
&lt;pre id=&quot;code_1765352294249&quot; class=&quot;csharp&quot; data-ke-language=&quot;csharp&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;private void button1_Click(object sender, EventArgs e)
        {
            serialPort1.PortName = textBox1.Text;
            serialPort1.BaudRate = 115200;
            serialPort1.Open();
            if (serialPort1.IsOpen)
            {
                serialPort1.ReadExisting();
                MessageBox.Show(&quot;접속완료!&quot;);
            }
        }

       private void hScrollBar1_Scroll(object sender, ScrollEventArgs e)
        {
            label2.Text = hScrollBar1.Value.ToString();
            if (serialPort1.IsOpen)
            {
                serialPort1.WriteLine(hScrollBar1.Value.ToString());
            }
        }

        private void serialPort1_DataReceived(object sender, System.IO.Ports.SerialDataReceivedEventArgs e)
        {
            string data = serialPort1.ReadLine();
            textBox2.Text = data;
        }&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;br /&gt;6.이번에는&amp;nbsp;STM32의&amp;nbsp;부저를&amp;nbsp;활용하는데,&amp;nbsp;C#에서&amp;nbsp;부저에&amp;nbsp;발생해야하는&amp;nbsp;주파수값을&amp;nbsp;직접적으로&amp;nbsp;전송하고&amp;nbsp;0을&amp;nbsp;전송하면&amp;nbsp;OFF하는걸로&amp;nbsp;하시오!&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;06.PNG&quot; data-origin-width=&quot;1068&quot; data-origin-height=&quot;581&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/rsBNU/dJMcag46qQe/kii3H7uL6yfi5TS6EH8jkk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/rsBNU/dJMcag46qQe/kii3H7uL6yfi5TS6EH8jkk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/rsBNU/dJMcag46qQe/kii3H7uL6yfi5TS6EH8jkk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FrsBNU%2FdJMcag46qQe%2Fkii3H7uL6yfi5TS6EH8jkk%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;1068&quot; height=&quot;581&quot; data-filename=&quot;06.PNG&quot; data-origin-width=&quot;1068&quot; data-origin-height=&quot;581&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;pre id=&quot;code_1765352019890&quot; class=&quot;cpp&quot; data-ke-language=&quot;cpp&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;/* USER CODE BEGIN 0 */
char recv;
char buff[100]; //수신메모리
int pos = 0;
static void Tone(uint32_t Frequency)
{
  TIM3-&amp;gt;ARR = (1000000UL / Frequency) - 1; //주파수
  TIM3-&amp;gt;CCR3 = (TIM3-&amp;gt;ARR &amp;gt;&amp;gt; 1); //듀티비 50%
}
/* USER CODE END 0 */




/* USER CODE BEGIN 2 */
 HAL_UART_Receive_IT(&amp;amp;huart2, &amp;amp;recv, 1); //수신인터럽트 시작
 HAL_TIM_PWM_Start(&amp;amp;htim3,TIM_CHANNEL_3);
 char buff2[100];
 /* USER CODE END 2 */


/* USER CODE BEGIN WHILE */
 while (1)
 {
   /* USER CODE END WHILE */
   /* USER CODE BEGIN 3 */
 }
 /* USER CODE END 3 */

/* USER CODE BEGIN 4 */
//usart2 수신인터럽트
void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart)
{
	//recv에 1개 읽은 문자가 들어있는 상황이다!
	buff[pos] = recv;
	pos++;
	if(recv == '\n'){
		buff[pos] = '\0';
		//C#에서 보낸 데이터 한덩어리가 여기서 처리된다!
		//0이면 OFF이고 0이 아니면 재생한다
		int pitch = atoi(buff);
		if(pitch == 0){
			HAL_GPIO_WritePin(GPIOC, GPIO_PIN_2, 0);
		}else{
			HAL_GPIO_WritePin(GPIOC, GPIO_PIN_2, 1);
			Tone(pitch);
		}
		pos = 0;
	}
   //수신인터럽트 다시 시작
	HAL_UART_Receive_IT(&amp;amp;huart2, &amp;amp;recv, 1);
}&lt;/code&gt;&lt;/pre&gt;
&lt;pre id=&quot;code_1765352308724&quot; class=&quot;csharp&quot; data-ke-language=&quot;csharp&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;private void button1_Click(object sender, EventArgs e)
        {
            serialPort1.PortName = textBox1.Text;
            serialPort1.BaudRate = 115200;
            serialPort1.Open();
            if (serialPort1.IsOpen)
            {
                serialPort1.ReadExisting();
                MessageBox.Show(&quot;접속완료!&quot;);
            }
        }

        private void button2_MouseDown(object sender, MouseEventArgs e)
        {
            //도6
            if (serialPort1.IsOpen) serialPort1.WriteLine(&quot;1047&quot;);
        }

        private void button2_MouseUp(object sender, MouseEventArgs e)
        {
            //도6
            if (serialPort1.IsOpen) serialPort1.WriteLine(&quot;0&quot;);
        }

        private void button3_MouseDown(object sender, MouseEventArgs e)
        {
            //레6
            if (serialPort1.IsOpen) serialPort1.WriteLine(&quot;1175&quot;);
        }
        private void button3_MouseUp(object sender, MouseEventArgs e)
        {
            //레6
            if (serialPort1.IsOpen) serialPort1.WriteLine(&quot;0&quot;);
        }

        private void button4_MouseDown(object sender, MouseEventArgs e)
        {
            //미6
            if (serialPort1.IsOpen) serialPort1.WriteLine(&quot;1319&quot;);
        }

        private void button4_MouseUp(object sender, MouseEventArgs e)
        {
            //미6
            if (serialPort1.IsOpen) serialPort1.WriteLine(&quot;0&quot;);
        }

        private void button5_MouseDown(object sender, MouseEventArgs e)
        {
            //파6
            if (serialPort1.IsOpen) serialPort1.WriteLine(&quot;1397&quot;);
        }

        private void button5_MouseUp(object sender, MouseEventArgs e)
        {
            //파6
            if (serialPort1.IsOpen) serialPort1.WriteLine(&quot;0&quot;);
        }


        private void button6_MouseDown(object sender, MouseEventArgs e)
        {
            //솔6
            if (serialPort1.IsOpen) serialPort1.WriteLine(&quot;1568&quot;);
        }

        private void button6_MouseUp(object sender, MouseEventArgs e)
        {
            //솔6
            if (serialPort1.IsOpen) serialPort1.WriteLine(&quot;0&quot;);
        }

        private void button7_MouseDown(object sender, MouseEventArgs e)
        {
            //라6
            if (serialPort1.IsOpen) serialPort1.WriteLine(&quot;1760&quot;);
        }

        private void button7_MouseUp(object sender, MouseEventArgs e)
        {
            //라6
            if (serialPort1.IsOpen) serialPort1.WriteLine(&quot;0&quot;);
        }

        private void button8_MouseDown(object sender, MouseEventArgs e)
        {
            //시6
            if (serialPort1.IsOpen) serialPort1.WriteLine(&quot;1976&quot;);
        }


        private void button8_MouseUp(object sender, MouseEventArgs e)
        {
            //시6
            if (serialPort1.IsOpen) serialPort1.WriteLine(&quot;0&quot;);
        }

        private void button9_MouseDown(object sender, MouseEventArgs e)
        {
            //도7
            if (serialPort1.IsOpen) serialPort1.WriteLine(&quot;2093&quot;);
        }

        private void button9_MouseUp(object sender, MouseEventArgs e)
        {
            //도7
            if (serialPort1.IsOpen) serialPort1.WriteLine(&quot;0&quot;);
        }&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;br /&gt;&lt;s&gt;7.h스크롤바를&amp;nbsp;이용해서&amp;nbsp;0~2500정도의&amp;nbsp;범위에서&amp;nbsp;값을&amp;nbsp;STM32에&amp;nbsp;전송해서&amp;nbsp;해당되는&amp;nbsp;진동의&amp;nbsp;음을&amp;nbsp;재생하도록&amp;nbsp;하시오!&lt;/s&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;8.스탭모터(28byj-48)의&amp;nbsp;위치제어값을&amp;nbsp;C#윈폼에서&amp;nbsp;전송해서&amp;nbsp;C#에서&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-filename=&quot;07.PNG&quot; data-origin-width=&quot;1054&quot; data-origin-height=&quot;571&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bOI22M/dJMcadgbkm0/KVrd5lQAZondEes7CfX8T0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bOI22M/dJMcadgbkm0/KVrd5lQAZondEes7CfX8T0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bOI22M/dJMcadgbkm0/KVrd5lQAZondEes7CfX8T0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbOI22M%2FdJMcadgbkm0%2FKVrd5lQAZondEes7CfX8T0%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;1054&quot; height=&quot;571&quot; data-filename=&quot;07.PNG&quot; data-origin-width=&quot;1054&quot; data-origin-height=&quot;571&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;pre id=&quot;code_1765352042976&quot; class=&quot;cpp&quot; data-ke-language=&quot;cpp&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;/* USER CODE BEGIN 0 */
char recv;
char buff[100]; //수신메모리
int pos = 0;
uint8_t seq[][4]={
		{0,0,0,1}, //1
		{0,0,1,1}, //2
		{0,0,1,0}, //3
		{0,1,1,0}, //4
		{0,1,0,0}, //5
		{1,1,0,0}, //6
		{1,0,0,0}, //7
		{1,0,0,1}  //8
};
GPIO_TypeDef *mygroup[] = {GPIOC,GPIOC,GPIOC,GPIOD};
uint16_t mypin[] = {GPIO_PIN_10,GPIO_PIN_11,GPIO_PIN_12,GPIO_PIN_2};
int now_pos = 0; //스탭모터가 알고있는 자기의 현재 위치
int target_pos = 0; //녹칸다가 설정한 목표위치
int seq_num = 0;
void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim)
{
  //타이머 인터럽트 콜백함수
	if(now_pos &amp;lt; target_pos){
		//시계방향으로 회전해야하는 상황
		for(int z = 0; z&amp;lt;4;z++){
		  HAL_GPIO_WritePin(mygroup[z],mypin[z],seq[seq_num][z]);
		}
		seq_num++;
		if(seq_num &amp;gt;= 8) seq_num = 0;
		now_pos++; //시퀀스 1회당 현재위치 1 증가
	}else if(now_pos &amp;gt; target_pos){
		//반시계방향으로 회전해야 하는 상황
		for(int z = 0; z&amp;lt;4;z++){
		  HAL_GPIO_WritePin(mygroup[z],mypin[z],seq[seq_num][z]);
		}
		seq_num--;
		if(seq_num &amp;lt; 0) seq_num = 7;
		now_pos--; //시퀀스 1회당 현재위치 1 감소
	}
}
/* USER CODE END 0 */


/* USER CODE BEGIN 2 */
 HAL_UART_Receive_IT(&amp;amp;huart2, &amp;amp;recv, 1); //수신인터럽트 시작
 HAL_TIM_Base_Start_IT(&amp;amp;htim2); //타이머인터럽트 시작
 char buff2[100];
 /* USER CODE END 2 */
/* USER CODE BEGIN WHILE */
 while (1)
 {
	  //now_pos
	  sprintf(buff2,&quot;%d\n&quot;,now_pos);
	  HAL_UART_Transmit(&amp;amp;huart2, buff2, strlen(buff2), 100);
	  HAL_Delay(100);
   /* USER CODE END WHILE */
   /* USER CODE BEGIN 3 */
 }
USER CODE BEGIN 3 */
 }
 /* USER CODE END 3 */
/* USER CODE BEGIN 4 */
//usart2 수신인터럽트
void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart)
{
	//recv에 1개 읽은 문자가 들어있는 상황이다!
	buff[pos] = recv;
	pos++;
	if(recv == '\n'){
		buff[pos] = '\0';
		//C#에서 보낸 데이터 한덩어리가 여기서 처리된다!
		target_pos = atoi(buff);
		pos = 0;
	}
   //수신인터럽트 다시 시작
	HAL_UART_Receive_IT(&amp;amp;huart2, &amp;amp;recv, 1);
}
/* USER CODE END 4 */&lt;/code&gt;&lt;/pre&gt;
&lt;pre id=&quot;code_1765352322509&quot; class=&quot;csharp&quot; data-ke-language=&quot;csharp&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;private void button1_Click(object sender, EventArgs e)
        {
            serialPort1.PortName = textBox1.Text;
            serialPort1.BaudRate = 115200;
            serialPort1.Open();
            if (serialPort1.IsOpen)
            {
                serialPort1.ReadExisting();
                MessageBox.Show(&quot;접속완료!&quot;);
            }
        }
private void button2_Click(object sender, EventArgs e)
        {
            if (serialPort1.IsOpen)
            {
                serialPort1.WriteLine(&quot;0&quot;);
            }
        }

private void button3_Click(object sender, EventArgs e)
        {
            if (serialPort1.IsOpen)
            {
                serialPort1.WriteLine(&quot;1024&quot;);
            }
        }
private void button4_Click(object sender, EventArgs e)
        {
            if (serialPort1.IsOpen)
            {
                serialPort1.WriteLine(&quot;-1024&quot;);
            }
        }&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;br /&gt;9.numericupdown을&amp;nbsp;이용해서&amp;nbsp;-4096*3&amp;nbsp;~&amp;nbsp;+4096*3의&amp;nbsp;범위에서&amp;nbsp;스탭모터의&amp;nbsp;위치를&amp;nbsp;결정할&amp;nbsp;수&amp;nbsp;있고,&amp;nbsp;현재&amp;nbsp;위치값을&amp;nbsp;STM32가&amp;nbsp;100밀리초&amp;nbsp;간격으로&amp;nbsp;C#에게&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-filename=&quot;08.PNG&quot; data-origin-width=&quot;853&quot; data-origin-height=&quot;475&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bMez9A/dJMcajnadho/4YnYzMzZkaYAZgIuam8q7k/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bMez9A/dJMcajnadho/4YnYzMzZkaYAZgIuam8q7k/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bMez9A/dJMcajnadho/4YnYzMzZkaYAZgIuam8q7k/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbMez9A%2FdJMcajnadho%2F4YnYzMzZkaYAZgIuam8q7k%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;853&quot; height=&quot;475&quot; data-filename=&quot;08.PNG&quot; data-origin-width=&quot;853&quot; data-origin-height=&quot;475&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;pre id=&quot;code_1765352233972&quot; class=&quot;cpp&quot; data-ke-language=&quot;cpp&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;/* USER CODE BEGIN 0 */
char recv;
char buff[100]; //수신메모리
int pos = 0;
uint8_t seq[][4]={
		{0,0,0,1}, //1
		{0,0,1,1}, //2
		{0,0,1,0}, //3
		{0,1,1,0}, //4
		{0,1,0,0}, //5
		{1,1,0,0}, //6
		{1,0,0,0}, //7
		{1,0,0,1}  //8
};
GPIO_TypeDef *mygroup[] = {GPIOC,GPIOC,GPIOC,GPIOD};
uint16_t mypin[] = {GPIO_PIN_10,GPIO_PIN_11,GPIO_PIN_12,GPIO_PIN_2};
int now_pos = 0; //스탭모터가 알고있는 자기의 현재 위치
int target_pos = 0; //녹칸다가 설정한 목표위치
int seq_num = 0;
void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim)
{
  //타이머 인터럽트 콜백함수
	if(now_pos &amp;lt; target_pos){
		//시계방향으로 회전해야하는 상황
		for(int z = 0; z&amp;lt;4;z++){
		  HAL_GPIO_WritePin(mygroup[z],mypin[z],seq[seq_num][z]);
		}
		seq_num++;
		if(seq_num &amp;gt;= 8) seq_num = 0;
		now_pos++; //시퀀스 1회당 현재위치 1 증가
	}else if(now_pos &amp;gt; target_pos){
		//반시계방향으로 회전해야 하는 상황
		for(int z = 0; z&amp;lt;4;z++){
		  HAL_GPIO_WritePin(mygroup[z],mypin[z],seq[seq_num][z]);
		}
		seq_num--;
		if(seq_num &amp;lt; 0) seq_num = 7;
		now_pos--; //시퀀스 1회당 현재위치 1 감소
	}
}
/* USER CODE END 0 */


/* USER CODE BEGIN 2 */
 HAL_UART_Receive_IT(&amp;amp;huart2, &amp;amp;recv, 1); //수신인터럽트 시작
 HAL_TIM_Base_Start_IT(&amp;amp;htim2); //타이머인터럽트 시작
 char buff2[100];
 /* USER CODE END 2 */
/* USER CODE BEGIN WHILE */
 while (1)
 {
	  //now_pos
	  sprintf(buff2,&quot;%d\n&quot;,now_pos);
	  HAL_UART_Transmit(&amp;amp;huart2, buff2, strlen(buff2), 100);
	  HAL_Delay(100);
   /* USER CODE END WHILE */
   /* USER CODE BEGIN 3 */
 }
USER CODE BEGIN 3 */
 }
 /* USER CODE END 3 */
/* USER CODE BEGIN 4 */
//usart2 수신인터럽트
void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart)
{
	//recv에 1개 읽은 문자가 들어있는 상황이다!
	buff[pos] = recv;
	pos++;
	if(recv == '\n'){
		buff[pos] = '\0';
		//C#에서 보낸 데이터 한덩어리가 여기서 처리된다!
		target_pos = atoi(buff);
		pos = 0;
	}
   //수신인터럽트 다시 시작
	HAL_UART_Receive_IT(&amp;amp;huart2, &amp;amp;recv, 1);
}
/* USER CODE END 4 */&lt;/code&gt;&lt;/pre&gt;
&lt;pre id=&quot;code_1765352337924&quot; class=&quot;csharp&quot; data-ke-language=&quot;csharp&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;private void button1_Click(object sender, EventArgs e)
        {
            serialPort1.PortName = textBox1.Text;
            serialPort1.BaudRate = 115200;
            serialPort1.Open();
            if (serialPort1.IsOpen)
            {
                serialPort1.ReadExisting();
                MessageBox.Show(&quot;접속완료!&quot;);
            }
        }
private void button2_Click(object sender, EventArgs e)
        {
            if (serialPort1.IsOpen)
            {
                serialPort1.WriteLine(numericUpDown1.Value.ToString());
            }
        }

        private void serialPort1_DataReceived(object sender, System.IO.Ports.SerialDataReceivedEventArgs e)
        {
            string data = serialPort1.ReadLine();
            textBox2.Text = data;
        }&lt;/code&gt;&lt;/pre&gt;</description>
      <category>프로그래밍/STM32</category>
      <author>덕력킹</author>
      <guid isPermaLink="true">https://bota.tistory.com/2460</guid>
      <comments>https://bota.tistory.com/2460#entry2460comment</comments>
      <pubDate>Wed, 10 Dec 2025 16:42:33 +0900</pubDate>
    </item>
    <item>
      <title>[STM32#17] STM32쉴드에 붙어있는 각종 센서값을 C# winform에게 전송하고 UI에 출력하는 방법 알아보기!(녹칸다 내맘대로 STM32)</title>
      <link>https://bota.tistory.com/2459</link>
      <description>&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;stm32.png&quot; data-origin-width=&quot;1920&quot; data-origin-height=&quot;1080&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cqWEjj/dJMcachjmVD/k16eVNXUGMrL5hEXX31171/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cqWEjj/dJMcachjmVD/k16eVNXUGMrL5hEXX31171/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cqWEjj/dJMcachjmVD/k16eVNXUGMrL5hEXX31171/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FcqWEjj%2FdJMcachjmVD%2Fk16eVNXUGMrL5hEXX31171%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;1920&quot; height=&quot;1080&quot; data-filename=&quot;stm32.png&quot; data-origin-width=&quot;1920&quot; data-origin-height=&quot;1080&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/live/1HmpkgreFAA&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://youtube.com/live/1HmpkgreFAA&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/watch?v=1HmpkgreFAA&quot; data-video-thumbnail=&quot;https://scrap.kakaocdn.net/dn/bhzJSw/hyZPd5HJIb/c0V95leG0awEUYAprvvFR0/img.jpg?width=1280&amp;amp;height=720&amp;amp;face=0_0_1280_720,https://scrap.kakaocdn.net/dn/eZC7W/hyZPlbAJ8Y/dXLFeuH7UABQ5ZuGKjJZUK/img.jpg?width=1280&amp;amp;height=720&amp;amp;face=0_0_1280_720,https://scrap.kakaocdn.net/dn/VQazS/hyZOFV0Xdu/CJFPLWywkpK4oH6m58lKe1/img.jpg?width=1280&amp;amp;height=720&amp;amp;face=0_0_1280_720&quot; data-video-width=&quot;860&quot; data-video-height=&quot;484&quot; data-video-origin-width=&quot;860&quot; data-video-origin-height=&quot;484&quot; data-ke-mobilestyle=&quot;widthContent&quot; data-video-title=&quot;[STM32#17] STM32쉴드에 붙어있는 각종 센서값을 C# winform에게 전송하고 UI에 출력하는 방법 알아보기!&quot; data-original-url=&quot;&quot;&gt;&lt;iframe src=&quot;https://www.youtube.com/embed/1HmpkgreFAA&quot; width=&quot;860&quot; height=&quot;484&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;[STM32#17]&amp;nbsp;STM32쉴드에&amp;nbsp;붙어있는&amp;nbsp;각종&amp;nbsp;센서값을&amp;nbsp;C#&amp;nbsp;winform에게&amp;nbsp;전송하고&amp;nbsp;UI에&amp;nbsp;출력하는&amp;nbsp;방법&amp;nbsp;알아보기!(녹칸다&amp;nbsp;내맘대로&amp;nbsp;STM32) &lt;br /&gt;&lt;br /&gt;심심한녹칸다의&amp;nbsp;내맘대로&amp;nbsp;STM32시리즈이다! &lt;br /&gt;&lt;br /&gt;STM32시리즈의&amp;nbsp;모든&amp;nbsp;자료는&amp;nbsp;구글&amp;nbsp;슬라이드에&amp;nbsp;작성하고&amp;nbsp;모두에게&amp;nbsp;공유되어있음! &lt;br /&gt;&lt;a href=&quot;https://docs.google.com/presentation/d/1myA5iYbjuKsLWLqtRLKAiRfwUwvqB1d1RGjiMIIgp3I/edit?slide=id.g3ae38c5a1b6_3_0#slide=id.g3ae38c5a1b6_3_0&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://docs.google.com/presentation/d/1myA5iYbjuKsLWLqtRLKAiRfwUwvqB1d1RGjiMIIgp3I/edit?slide=id.g3ae38c5a1b6_3_0#slide=id.g3ae38c5a1b6_3_0&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;녹칸다의&amp;nbsp;STM32쉴드에&amp;nbsp;붙어있는&amp;nbsp;센서값을&amp;nbsp;C#윈폼으로&amp;nbsp;전송해보도록&amp;nbsp;하겠습니다~! &lt;br /&gt;&lt;br /&gt;1.바로직전&amp;nbsp;슬라이드를&amp;nbsp;참고해서,&amp;nbsp;A0,A1,A4에&amp;nbsp;연결된&amp;nbsp;아날로그&amp;nbsp;3종세트의&amp;nbsp;값을&amp;nbsp;ADC1을&amp;nbsp;이용해서&amp;nbsp;동시에&amp;nbsp;측정하고,&amp;nbsp;그&amp;nbsp;값을&amp;nbsp;C#윈폼&amp;nbsp;화면에&amp;nbsp;richtextbox1에&amp;nbsp;출력하시오!(보내는&amp;nbsp;데이터는&amp;nbsp;CSV&amp;nbsp;형식으로&amp;nbsp;전송하시오)&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;01.PNG&quot; data-origin-width=&quot;849&quot; data-origin-height=&quot;483&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cODZyL/dJMcab3Mobp/v1WQGQKqfkwsPn7WYIeoK0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cODZyL/dJMcab3Mobp/v1WQGQKqfkwsPn7WYIeoK0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cODZyL/dJMcab3Mobp/v1WQGQKqfkwsPn7WYIeoK0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FcODZyL%2FdJMcab3Mobp%2Fv1WQGQKqfkwsPn7WYIeoK0%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;849&quot; height=&quot;483&quot; data-filename=&quot;01.PNG&quot; data-origin-width=&quot;849&quot; data-origin-height=&quot;483&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;pre id=&quot;code_1765202772773&quot; class=&quot;cpp&quot; data-ke-language=&quot;cpp&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;/* USER CODE BEGIN 0 */
#define R1 10000
#define c1 1.009249522e-03
#define c2 2.378405444e-04
#define c3 2.019202697e-07
/* USER CODE END 0 */
//중략
/* USER CODE BEGIN 2 */
 uint16_t adc_value0 = 0;
 uint16_t adc_value1 = 0;
 uint16_t adc_value2 = 0;
 char buff[50];
 float logR2, R2, T, Tc, Tf;
 /* USER CODE END 2 */
 /* Infinite loop */
 /* USER CODE BEGIN WHILE */
 while (1)
 {
	  //PA0 ADC1 RANK1
	  HAL_ADC_Start(&amp;amp;hadc1);
	  HAL_ADC_PollForConversion(&amp;amp;hadc1, 100);
	  adc_value0 = HAL_ADC_GetValue(&amp;amp;hadc1);
	  //PA1 ADC1 RANK2
	  HAL_ADC_Start(&amp;amp;hadc1);
	  HAL_ADC_PollForConversion(&amp;amp;hadc1, 100);
	  adc_value1 = HAL_ADC_GetValue(&amp;amp;hadc1);
	  //PA4 ADC1 RANK3
	  HAL_ADC_Start(&amp;amp;hadc1);
	  HAL_ADC_PollForConversion(&amp;amp;hadc1, 100);
	  adc_value2 = HAL_ADC_GetValue(&amp;amp;hadc1);
	  //온도계산
	  R2 = R1 * (4095.0 / adc_value2 - 1.0);
	  logR2 = log(R2);
	  T = (1.0 / (c1 + c2*logR2 + c3*logR2*logR2*logR2));
	  Tc = T - 273.15;
	  sprintf(buff,&quot;%d,%d,%.2f\n&quot;,adc_value0,adc_value1,Tc);
	  HAL_UART_Transmit(&amp;amp;huart2, buff, strlen(buff), 100);
	  HAL_Delay(100);

   /* USER CODE END WHILE */
   /* USER CODE BEGIN 3 */
 }&lt;/code&gt;&lt;/pre&gt;
&lt;pre id=&quot;code_1765202888516&quot; class=&quot;csharp&quot; data-ke-language=&quot;csharp&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;private void button1_Click(object sender, EventArgs e)
        {
            //접속버튼 클릭
            serialPort1.PortName = textBox1.Text;
            serialPort1.BaudRate = 115200;
            serialPort1.Open();
            if (serialPort1.IsOpen)
            {
                //수신버퍼 클리어
                serialPort1.ReadExisting();
                MessageBox.Show(&quot;접속완료!&quot;);
            }
        }

        private void serialPort1_DataReceived(object sender, System.IO.Ports.SerialDataReceivedEventArgs e)
        {
            //STM32가 데이터를 전송했다!
            string data = serialPort1.ReadLine();
            richTextBox1.Text += data + &quot;\n&quot;;
            //data안에 들어있는 값은 CSV형식이다!
            string[] analog_value = data.Split(',');
            //짤려진 조각의 갯수는 반드시 3개여야한다!
            if(analog_value.Length == 3)
            {
                textBox2.Text = analog_value[0];
                textBox3.Text = analog_value[1];
                textBox4.Text = analog_value[2];
            }
        }&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;br /&gt;2.예제1번에서&amp;nbsp;STM32가&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-filename=&quot;02.PNG&quot; data-origin-width=&quot;722&quot; data-origin-height=&quot;515&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/ccgees/dJMcafkN892/64oLUx9kijtPvXgruh0090/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/ccgees/dJMcafkN892/64oLUx9kijtPvXgruh0090/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/ccgees/dJMcafkN892/64oLUx9kijtPvXgruh0090/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fccgees%2FdJMcafkN892%2F64oLUx9kijtPvXgruh0090%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;722&quot; height=&quot;515&quot; data-filename=&quot;02.PNG&quot; data-origin-width=&quot;722&quot; data-origin-height=&quot;515&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;pre id=&quot;code_1765202790360&quot; class=&quot;cpp&quot; data-ke-language=&quot;cpp&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;/* USER CODE BEGIN 0 */
#define R1 10000
#define c1 1.009249522e-03
#define c2 2.378405444e-04
#define c3 2.019202697e-07
/* USER CODE END 0 */
//중략
/* USER CODE BEGIN 2 */
 uint16_t adc_value0 = 0;
 uint16_t adc_value1 = 0;
 uint16_t adc_value2 = 0;
 char buff[50];
 float logR2, R2, T, Tc, Tf;
 struct{
	  uint16_t sen1; //2
	  uint16_t sen2; //2
	  float sen3; //4
 }dataset;

 /* USER CODE END 2 */

 /* Infinite loop */
 /* USER CODE BEGIN WHILE */
 while (1)
 {
	  //PA0 ADC1 RANK1
	  HAL_ADC_Start(&amp;amp;hadc1);
	  HAL_ADC_PollForConversion(&amp;amp;hadc1, 100);
	  adc_value0 = HAL_ADC_GetValue(&amp;amp;hadc1);
	  //PA1 ADC1 RANK2
	  HAL_ADC_Start(&amp;amp;hadc1);
	  HAL_ADC_PollForConversion(&amp;amp;hadc1, 100);
	  adc_value1 = HAL_ADC_GetValue(&amp;amp;hadc1);
	  //PA4 ADC1 RANK3
	  HAL_ADC_Start(&amp;amp;hadc1);
	  HAL_ADC_PollForConversion(&amp;amp;hadc1, 100);
	  adc_value2 = HAL_ADC_GetValue(&amp;amp;hadc1);
	  //온도계산
	  R2 = R1 * (4095.0 / adc_value2 - 1.0);
	  logR2 = log(R2);
	  T = (1.0 / (c1 + c2*logR2 + c3*logR2*logR2*logR2));
	  Tc = T - 273.15;
	  dataset.sen1 = adc_value0;
	  dataset.sen2 = adc_value1;
	  dataset.sen3 = Tc;
	  //내가 변환하고자하는 변수의 주소를 (uint8_t*)으로 명시적 형변환을 하면
	  //어떤 변수가 uint8_t array로 변환되는 효과를 가져올 수 있다!
	  HAL_UART_Transmit(&amp;amp;huart2, (uint8_t*)(&amp;amp;dataset), sizeof(dataset), 100);
	  HAL_Delay(100);


   /* USER CODE END WHILE */
   /* USER CODE BEGIN 3 */
 }&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_1765202901855&quot; class=&quot;csharp&quot; data-ke-language=&quot;csharp&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;private void button1_Click(object sender, EventArgs e)
        {
            //접속버튼 클릭
            serialPort1.PortName = textBox1.Text;
            serialPort1.BaudRate = 115200;
            serialPort1.Open();
            if (serialPort1.IsOpen)
            {
                //수신버퍼 클리어
                serialPort1.ReadExisting();
                MessageBox.Show(&quot;접속완료!&quot;);
            }
        }


        private void serialPort1_DataReceived(object sender, System.IO.Ports.SerialDataReceivedEventArgs e)
        {
            //STM32가 데이터를 전송했다!
            //C#에서 STM32가 보낸 데이터를 무조건 8개를 받아야한다!
            byte[] recv = new byte[8]; //uint8_t
            int cnt = 0;
            while (true)
            {
                recv[cnt] = (byte)serialPort1.ReadByte();
                cnt++;
                if (cnt == 8) break;
            }
            //rawdata 출력
            richTextBox1.Text += &quot;수신 = &quot;;
            string text = &quot;&quot;;
            for(int i = 0; i &amp;lt; 8; i++)
            {
                text += recv[i] + &quot;, &quot;;
            }
            richTextBox1.Text += text + &quot;\n&quot;;
            //데이터해석
            UInt16 sen1 = BitConverter.ToUInt16(recv, 0);
            UInt16 sen2 = BitConverter.ToUInt16(recv, 2);
            float sen3 = BitConverter.ToSingle(recv, 4);
            textBox2.Text = sen1.ToString();
            textBox3.Text = sen2.ToString();
            textBox4.Text = sen3.ToString();
        }&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;br /&gt;3.예제1번에서&amp;nbsp;STM32가&amp;nbsp;key-value형식을&amp;nbsp;가지는&amp;nbsp;json형식으로&amp;nbsp;데이터를&amp;nbsp;전송한다음&amp;nbsp;C#에서&amp;nbsp;json파서를&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-filename=&quot;03.PNG&quot; data-origin-width=&quot;781&quot; data-origin-height=&quot;468&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/blaJgr/dJMcafkN9aO/tmSzeLZsl44Nt5oym5wUk0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/blaJgr/dJMcafkN9aO/tmSzeLZsl44Nt5oym5wUk0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/blaJgr/dJMcafkN9aO/tmSzeLZsl44Nt5oym5wUk0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FblaJgr%2FdJMcafkN9aO%2FtmSzeLZsl44Nt5oym5wUk0%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;468&quot; data-filename=&quot;03.PNG&quot; data-origin-width=&quot;781&quot; data-origin-height=&quot;468&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;pre id=&quot;code_1765202803920&quot; class=&quot;cpp&quot; data-ke-language=&quot;cpp&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;/* USER CODE BEGIN 0 */
#define R1 10000
#define c1 1.009249522e-03
#define c2 2.378405444e-04
#define c3 2.019202697e-07
/* USER CODE END 0 */
//중략
/* USER CODE BEGIN 2 */
 uint16_t adc_value0 = 0;
 uint16_t adc_value1 = 0;
 uint16_t adc_value2 = 0;
 char buff[50];
 float logR2, R2, T, Tc, Tf;


 /* USER CODE END 2 */
 /* Infinite loop */
 /* USER CODE BEGIN WHILE */
 while (1)
 {
	  //PA0 ADC1 RANK1
	  HAL_ADC_Start(&amp;amp;hadc1);
	  HAL_ADC_PollForConversion(&amp;amp;hadc1, 100);
	  adc_value0 = HAL_ADC_GetValue(&amp;amp;hadc1);
	  //PA1 ADC1 RANK2
	  HAL_ADC_Start(&amp;amp;hadc1);
	  HAL_ADC_PollForConversion(&amp;amp;hadc1, 100);
	  adc_value1 = HAL_ADC_GetValue(&amp;amp;hadc1);
	  //PA4 ADC1 RANK3
	  HAL_ADC_Start(&amp;amp;hadc1);
	  HAL_ADC_PollForConversion(&amp;amp;hadc1, 100);
	  adc_value2 = HAL_ADC_GetValue(&amp;amp;hadc1);
	  //온도계산
	  R2 = R1 * (4095.0 / adc_value2 - 1.0);
	  logR2 = log(R2);
	  T = (1.0 / (c1 + c2*logR2 + c3*logR2*logR2*logR2));
	  Tc = T - 273.15;
	  sprintf(buff,&quot;{\&quot;sen1\&quot;:%d,\&quot;sen2\&quot;:%d,\&quot;sen3\&quot;:%.2f}\n&quot;,adc_value0,adc_value1,Tc);
	  HAL_UART_Transmit(&amp;amp;huart2, buff, strlen(buff), 100);
	  HAL_Delay(100);



   /* USER CODE END WHILE */
   /* USER CODE BEGIN 3 */
 }&lt;/code&gt;&lt;/pre&gt;
&lt;pre id=&quot;code_1765202914147&quot; class=&quot;csharp&quot; data-ke-language=&quot;csharp&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;using Newtonsoft.Json.Linq; //네임스페이스 추가

private void button1_Click(object sender, EventArgs e)
        {
            //접속버튼 클릭
            serialPort1.PortName = textBox1.Text;
            serialPort1.BaudRate = 115200;
            serialPort1.Open();
            if (serialPort1.IsOpen)
            {
                //수신버퍼 클리어
                serialPort1.ReadExisting();
                MessageBox.Show(&quot;접속완료!&quot;);
            }
        }


private void serialPort1_DataReceived(object sender, System.IO.Ports.SerialDataReceivedEventArgs e)
        {
            //STM32가 데이터를 전송했다!
            string data = serialPort1.ReadLine();
            richTextBox1.Text += data + &quot;\n&quot;;
            //데이터를 해석하려면 json parser가 필요하다!
            try
            {
                JObject myjson = JObject.Parse(data);
                //key값이 sen1인 value값이 뭐냐?
                textBox2.Text = myjson[&quot;sen1&quot;].ToString();
                textBox3.Text = myjson[&quot;sen2&quot;].ToString();
                textBox4.Text = myjson[&quot;sen3&quot;].ToString();
            }
            catch { }
            
        }&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;br /&gt;4.예제3에서&amp;nbsp;했던&amp;nbsp;결과에서&amp;nbsp;C#윈폼의&amp;nbsp;chart를&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-filename=&quot;04.PNG&quot; data-origin-width=&quot;845&quot; data-origin-height=&quot;481&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/QZnlv/dJMcaacI9Ff/nhRUXCPCEL8DOrCksym5Dk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/QZnlv/dJMcaacI9Ff/nhRUXCPCEL8DOrCksym5Dk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/QZnlv/dJMcaacI9Ff/nhRUXCPCEL8DOrCksym5Dk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FQZnlv%2FdJMcaacI9Ff%2FnhRUXCPCEL8DOrCksym5Dk%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;845&quot; height=&quot;481&quot; data-filename=&quot;04.PNG&quot; data-origin-width=&quot;845&quot; data-origin-height=&quot;481&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;pre id=&quot;code_1765202816017&quot; class=&quot;cpp&quot; data-ke-language=&quot;cpp&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;/* USER CODE BEGIN 0 */
#define R1 10000
#define c1 1.009249522e-03
#define c2 2.378405444e-04
#define c3 2.019202697e-07
/* USER CODE END 0 */
//중략
/* USER CODE BEGIN 2 */
 uint16_t adc_value0 = 0;
 uint16_t adc_value1 = 0;
 uint16_t adc_value2 = 0;
 char buff[50];
 float logR2, R2, T, Tc, Tf;


 /* USER CODE END 2 */

 /* Infinite loop */
 /* USER CODE BEGIN WHILE */
 while (1)
 {
	  //PA0 ADC1 RANK1
	  HAL_ADC_Start(&amp;amp;hadc1);
	  HAL_ADC_PollForConversion(&amp;amp;hadc1, 100);
	  adc_value0 = HAL_ADC_GetValue(&amp;amp;hadc1);
	  //PA1 ADC1 RANK2
	  HAL_ADC_Start(&amp;amp;hadc1);
	  HAL_ADC_PollForConversion(&amp;amp;hadc1, 100);
	  adc_value1 = HAL_ADC_GetValue(&amp;amp;hadc1);
	  //PA4 ADC1 RANK3
	  HAL_ADC_Start(&amp;amp;hadc1);
	  HAL_ADC_PollForConversion(&amp;amp;hadc1, 100);
	  adc_value2 = HAL_ADC_GetValue(&amp;amp;hadc1);
	  //온도계산
	  R2 = R1 * (4095.0 / adc_value2 - 1.0);
	  logR2 = log(R2);
	  T = (1.0 / (c1 + c2*logR2 + c3*logR2*logR2*logR2));
	  Tc = T - 273.15;
	  sprintf(buff,&quot;{\&quot;sen1\&quot;:%d,\&quot;sen2\&quot;:%d,\&quot;sen3\&quot;:%.2f}\n&quot;,adc_value0,adc_value1,Tc);
	  HAL_UART_Transmit(&amp;amp;huart2, buff, strlen(buff), 100);
	  HAL_Delay(100);



   /* USER CODE END WHILE */
   /* USER CODE BEGIN 3 */
 }&lt;/code&gt;&lt;/pre&gt;
&lt;pre id=&quot;code_1765202925480&quot; class=&quot;csharp&quot; data-ke-language=&quot;csharp&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;using Newtonsoft.Json.Linq; //네임스페이스 추가

private void button1_Click(object sender, EventArgs e)
        {
            //접속버튼 클릭
            serialPort1.PortName = textBox1.Text;
            serialPort1.BaudRate = 115200;
            serialPort1.Open();
            if (serialPort1.IsOpen)
            {
                //수신버퍼 클리어
                serialPort1.ReadExisting();
                MessageBox.Show(&quot;접속완료!&quot;);
            }
        }


private void serialPort1_DataReceived(object sender, System.IO.Ports.SerialDataReceivedEventArgs e)
        {
            //STM32가 데이터를 전송했다!
            string data = serialPort1.ReadLine();
            //데이터를 해석하려면 json parser가 필요하다!
            try
            {
                JObject myjson = JObject.Parse(data);
                //key값이 sen1인 value값이 뭐냐?
                textBox2.Text = myjson[&quot;sen1&quot;].ToString();
                textBox3.Text = myjson[&quot;sen2&quot;].ToString();
                textBox4.Text = myjson[&quot;sen3&quot;].ToString();

                UInt16 sen1 = UInt16.Parse(myjson[&quot;sen1&quot;].ToString());
                UInt16 sen2 = UInt16.Parse(myjson[&quot;sen2&quot;].ToString());
                float sen3 = Single.Parse(myjson[&quot;sen3&quot;].ToString());

                chart1.Series[0].Points.AddY(sen1);
                chart1.Series[1].Points.AddY(sen2);
                chart1.Series[2].Points.AddY(sen3);
            }
            catch { }
            
        }&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;br /&gt;5.예제4에서&amp;nbsp;그래프는&amp;nbsp;계속&amp;nbsp;데이터가&amp;nbsp;누적되는&amp;nbsp;방식이라서&amp;nbsp;결국&amp;nbsp;화면상에&amp;nbsp;보여지는&amp;nbsp;그래프가&amp;nbsp;너무&amp;nbsp;촘촘해진다!&amp;nbsp;x축을&amp;nbsp;기준으로&amp;nbsp;50개의&amp;nbsp;데이터만&amp;nbsp;유지하고&amp;nbsp;큐와&amp;nbsp;동일하게&amp;nbsp;제일&amp;nbsp;처음&amp;nbsp;들어온&amp;nbsp;데이터는&amp;nbsp;51개가&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-filename=&quot;05.PNG&quot; data-origin-width=&quot;870&quot; data-origin-height=&quot;488&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/V1Iya/dJMcaioh6rc/4VvE5iG6DozNOWmp1BpgGK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/V1Iya/dJMcaioh6rc/4VvE5iG6DozNOWmp1BpgGK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/V1Iya/dJMcaioh6rc/4VvE5iG6DozNOWmp1BpgGK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FV1Iya%2FdJMcaioh6rc%2F4VvE5iG6DozNOWmp1BpgGK%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;870&quot; height=&quot;488&quot; data-filename=&quot;05.PNG&quot; data-origin-width=&quot;870&quot; data-origin-height=&quot;488&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;pre id=&quot;code_1765202828894&quot; class=&quot;cpp&quot; data-ke-language=&quot;cpp&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;/* USER CODE BEGIN 0 */
#define R1 10000
#define c1 1.009249522e-03
#define c2 2.378405444e-04
#define c3 2.019202697e-07
/* USER CODE END 0 */
//중략
/* USER CODE BEGIN 2 */
 uint16_t adc_value0 = 0;
 uint16_t adc_value1 = 0;
 uint16_t adc_value2 = 0;
 char buff[50];
 float logR2, R2, T, Tc, Tf;


 /* USER CODE END 2 */

 /* Infinite loop */
 /* USER CODE BEGIN WHILE */
 while (1)
 {
	  //PA0 ADC1 RANK1
	  HAL_ADC_Start(&amp;amp;hadc1);
	  HAL_ADC_PollForConversion(&amp;amp;hadc1, 100);
	  adc_value0 = HAL_ADC_GetValue(&amp;amp;hadc1);
	  //PA1 ADC1 RANK2
	  HAL_ADC_Start(&amp;amp;hadc1);
	  HAL_ADC_PollForConversion(&amp;amp;hadc1, 100);
	  adc_value1 = HAL_ADC_GetValue(&amp;amp;hadc1);
	  //PA4 ADC1 RANK3
	  HAL_ADC_Start(&amp;amp;hadc1);
	  HAL_ADC_PollForConversion(&amp;amp;hadc1, 100);
	  adc_value2 = HAL_ADC_GetValue(&amp;amp;hadc1);
	  //온도계산
	  R2 = R1 * (4095.0 / adc_value2 - 1.0);
	  logR2 = log(R2);
	  T = (1.0 / (c1 + c2*logR2 + c3*logR2*logR2*logR2));
	  Tc = T - 273.15;
	  sprintf(buff,&quot;{\&quot;sen1\&quot;:%d,\&quot;sen2\&quot;:%d,\&quot;sen3\&quot;:%.2f}\n&quot;,adc_value0,adc_value1,Tc);
	  HAL_UART_Transmit(&amp;amp;huart2, buff, strlen(buff), 100);
	  HAL_Delay(100);



   /* USER CODE END WHILE */
   /* USER CODE BEGIN 3 */
 }&lt;/code&gt;&lt;/pre&gt;
&lt;pre id=&quot;code_1765202937862&quot; class=&quot;csharp&quot; data-ke-language=&quot;csharp&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;using Newtonsoft.Json.Linq; //네임스페이스 추가

private void button1_Click(object sender, EventArgs e)
        {
            //접속버튼 클릭
            serialPort1.PortName = textBox1.Text;
            serialPort1.BaudRate = 115200;
            serialPort1.Open();
            if (serialPort1.IsOpen)
            {
                //수신버퍼 클리어
                serialPort1.ReadExisting();
                MessageBox.Show(&quot;접속완료!&quot;);
            }
        }


private void serialPort1_DataReceived(object sender, System.IO.Ports.SerialDataReceivedEventArgs e)
        {
            //STM32가 데이터를 전송했다!
            string data = serialPort1.ReadLine();
            //데이터를 해석하려면 json parser가 필요하다!
            try
            {
                JObject myjson = JObject.Parse(data);
                //key값이 sen1인 value값이 뭐냐?
                textBox2.Text = myjson[&quot;sen1&quot;].ToString();
                textBox3.Text = myjson[&quot;sen2&quot;].ToString();
                textBox4.Text = myjson[&quot;sen3&quot;].ToString();

                UInt16 sen1 = UInt16.Parse(myjson[&quot;sen1&quot;].ToString());
                UInt16 sen2 = UInt16.Parse(myjson[&quot;sen2&quot;].ToString());
                float sen3 = Single.Parse(myjson[&quot;sen3&quot;].ToString());

                //지금 데이터 갯수가 50개보다 많다면 1개 뺀다
                if(chart1.Series[0].Points.Count &amp;gt; 50)
                {
                    chart1.Series[0].Points.RemoveAt(0);
                    chart1.Series[0].Points.AddY(sen1);
                    chart1.Series[1].Points.AddY(sen2);
                    chart1.Series[2].Points.AddY(sen3);
                }
                else
                {
                    chart1.Series[0].Points.AddY(sen1);
                    chart1.Series[1].Points.AddY(sen2);
                    chart1.Series[2].Points.AddY(sen3);
                }
            }
            catch { }
        }&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;br /&gt;6.I2C통신으로&amp;nbsp;측정된&amp;nbsp;온습도센서인&amp;nbsp;AHT-10의&amp;nbsp;값을&amp;nbsp;C#윈폼&amp;nbsp;화면에&amp;nbsp;출력하시오!(기본&amp;nbsp;데이터&amp;nbsp;형식은&amp;nbsp;JSON형식으로&amp;nbsp;하도록&amp;nbsp;함)&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;06.PNG&quot; data-origin-width=&quot;858&quot; data-origin-height=&quot;441&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/ID70M/dJMb995Yg1I/7hIsihSzSZs3hNAA8fX3zK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/ID70M/dJMb995Yg1I/7hIsihSzSZs3hNAA8fX3zK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/ID70M/dJMb995Yg1I/7hIsihSzSZs3hNAA8fX3zK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FID70M%2FdJMb995Yg1I%2F7hIsihSzSZs3hNAA8fX3zK%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;858&quot; height=&quot;441&quot; data-filename=&quot;06.PNG&quot; data-origin-width=&quot;858&quot; data-origin-height=&quot;441&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;pre id=&quot;code_1765202840715&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 */
 uint8_t AHT10_TmpHum_Cmd[3] = {0xAC, 0x33, 0x00};
 uint8_t AHT10_RX_Data[6];
 uint32_t AHT10_ADC_Raw;
 float AHT10_Temperature;
 float AHT10_Humidity;
 char str[100];
 /* USER CODE END 2 */

/* USER CODE BEGIN WHILE */
 while (1)
 {
	  //요청
	  HAL_I2C_Master_Transmit(&amp;amp;hi2c1, (0x38 &amp;lt;&amp;lt; 1), AHT10_TmpHum_Cmd, 3, 10);
	  //수신대기
	  uint8_t recv[1];
	  while(1){
		  HAL_I2C_Master_Receive(&amp;amp;hi2c1, (0x38 &amp;lt;&amp;lt; 1), recv, 6, 10);
		  if(~recv[0] &amp;amp; 0x80){
			  break;
		  }
	  }
	  //데이터 수신
	  HAL_I2C_Master_Receive(&amp;amp;hi2c1, (0x38 &amp;lt;&amp;lt; 1), AHT10_RX_Data, 6, 10);
	  //수신데이터 출력
	  AHT10_ADC_Raw = (((uint32_t)AHT10_RX_Data[3] &amp;amp; 15) &amp;lt;&amp;lt; 16) | ((uint32_t)AHT10_RX_Data[4] &amp;lt;&amp;lt; 8) | AHT10_RX_Data[5];
	  AHT10_Temperature = (float)(AHT10_ADC_Raw * 200.00 / 1048576.00) - 50.00;
	  /* Convert to Relative Humidity in % */
	  AHT10_ADC_Raw = ((uint32_t)AHT10_RX_Data[1] &amp;lt;&amp;lt; 12) | ((uint32_t)AHT10_RX_Data[2] &amp;lt;&amp;lt; 4) | (AHT10_RX_Data[3] &amp;gt;&amp;gt; 4);
	  AHT10_Humidity = (float)(AHT10_ADC_Raw*100.00/1048576.00);
	  sprintf(str,&quot;{\&quot;temp\&quot;:%.2f,\&quot;humi\&quot;:%.2f}\n&quot;,AHT10_Temperature,AHT10_Humidity);
	  HAL_UART_Transmit(&amp;amp;huart2,str,strlen(str),100);
	  HAL_Delay(1000);
   /* USER CODE END WHILE */
   /* USER CODE BEGIN 3 */
 }&lt;/code&gt;&lt;/pre&gt;
&lt;pre id=&quot;code_1765202949465&quot; class=&quot;csharp&quot; data-ke-language=&quot;csharp&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;using Newtonsoft.Json.Linq; //네임스페이스 추가

private void button1_Click(object sender, EventArgs e)
        {
            //접속버튼 클릭
            serialPort1.PortName = textBox1.Text;
            serialPort1.BaudRate = 115200;
            serialPort1.Open();
            if (serialPort1.IsOpen)
            {
                //수신버퍼 클리어
                serialPort1.ReadExisting();
                MessageBox.Show(&quot;접속완료!&quot;);
            }
        }


private void serialPort1_DataReceived(object sender, System.IO.Ports.SerialDataReceivedEventArgs e)
        {
            //STM32가 데이터를 전송했다!
            string data = serialPort1.ReadLine();
            richTextBox1.Text += data + &quot;\n&quot;;
            //데이터 해석
            try
            {
                JObject myjson = JObject.Parse(data);
                textBox2.Text = myjson[&quot;temp&quot;].ToString();
                textBox3.Text = myjson[&quot;humi&quot;].ToString();
            }
            catch { }
        }&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;br /&gt;7.예제6에서&amp;nbsp;측정된&amp;nbsp;온도와&amp;nbsp;습도값을&amp;nbsp;listview를&amp;nbsp;이용해서&amp;nbsp;table형식으로&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-filename=&quot;07.PNG&quot; data-origin-width=&quot;903&quot; data-origin-height=&quot;447&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/rfpci/dJMcad1xFEO/T5Znyf13fnZSB3kl84QbCk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/rfpci/dJMcad1xFEO/T5Znyf13fnZSB3kl84QbCk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/rfpci/dJMcad1xFEO/T5Znyf13fnZSB3kl84QbCk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Frfpci%2FdJMcad1xFEO%2FT5Znyf13fnZSB3kl84QbCk%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;903&quot; height=&quot;447&quot; data-filename=&quot;07.PNG&quot; data-origin-width=&quot;903&quot; data-origin-height=&quot;447&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;pre id=&quot;code_1765202852699&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 */
 uint8_t AHT10_TmpHum_Cmd[3] = {0xAC, 0x33, 0x00};
 uint8_t AHT10_RX_Data[6];
 uint32_t AHT10_ADC_Raw;
 float AHT10_Temperature;
 float AHT10_Humidity;
 char str[100];
 /* USER CODE END 2 */

/* USER CODE BEGIN WHILE */
 while (1)
 {
	  //요청
	  HAL_I2C_Master_Transmit(&amp;amp;hi2c1, (0x38 &amp;lt;&amp;lt; 1), AHT10_TmpHum_Cmd, 3, 10);
	  //수신대기
	  uint8_t recv[1];
	  while(1){
		  HAL_I2C_Master_Receive(&amp;amp;hi2c1, (0x38 &amp;lt;&amp;lt; 1), recv, 6, 10);
		  if(~recv[0] &amp;amp; 0x80){
			  break;
		  }
	  }
	  //데이터 수신
	  HAL_I2C_Master_Receive(&amp;amp;hi2c1, (0x38 &amp;lt;&amp;lt; 1), AHT10_RX_Data, 6, 10);
	  //수신데이터 출력
	  AHT10_ADC_Raw = (((uint32_t)AHT10_RX_Data[3] &amp;amp; 15) &amp;lt;&amp;lt; 16) | ((uint32_t)AHT10_RX_Data[4] &amp;lt;&amp;lt; 8) | AHT10_RX_Data[5];
	  AHT10_Temperature = (float)(AHT10_ADC_Raw * 200.00 / 1048576.00) - 50.00;
	  /* Convert to Relative Humidity in % */
	  AHT10_ADC_Raw = ((uint32_t)AHT10_RX_Data[1] &amp;lt;&amp;lt; 12) | ((uint32_t)AHT10_RX_Data[2] &amp;lt;&amp;lt; 4) | (AHT10_RX_Data[3] &amp;gt;&amp;gt; 4);
	  AHT10_Humidity = (float)(AHT10_ADC_Raw*100.00/1048576.00);
	  sprintf(str,&quot;{\&quot;temp\&quot;:%.2f,\&quot;humi\&quot;:%.2f}\n&quot;,AHT10_Temperature,AHT10_Humidity);
	  HAL_UART_Transmit(&amp;amp;huart2,str,strlen(str),100);
	  HAL_Delay(1000);
   /* USER CODE END WHILE */
   /* USER CODE BEGIN 3 */
 }&lt;/code&gt;&lt;/pre&gt;
&lt;pre id=&quot;code_1765202962455&quot; class=&quot;csharp&quot; data-ke-language=&quot;csharp&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;using Newtonsoft.Json.Linq; //네임스페이스 추가

//전역변수자리
 int cnt = 1;

private void button1_Click(object sender, EventArgs e)
        {
            //접속버튼 클릭
            serialPort1.PortName = textBox1.Text;
            serialPort1.BaudRate = 115200;
            serialPort1.Open();
            if (serialPort1.IsOpen)
            {
                //수신버퍼 클리어
                serialPort1.ReadExisting();
                MessageBox.Show(&quot;접속완료!&quot;);
            }
        }


private void serialPort1_DataReceived(object sender, System.IO.Ports.SerialDataReceivedEventArgs e)
        {
            //STM32가 데이터를 전송했다!
            string data = serialPort1.ReadLine();
            //데이터 해석
            try
            {
                JObject myjson = JObject.Parse(data);
                textBox2.Text = myjson[&quot;temp&quot;].ToString();
                textBox3.Text = myjson[&quot;humi&quot;].ToString();

                //데이터 삽입
                ListViewItem lvi = new ListViewItem();
                lvi.Text = cnt.ToString();
                lvi.SubItems.Add(myjson[&quot;temp&quot;].ToString());
                lvi.SubItems.Add(myjson[&quot;humi&quot;].ToString());
                lvi.SubItems.Add(DateTime.Now.ToString());
                listView1.Items.Add(lvi);
                cnt++;
            }
            catch { }
        }&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;br /&gt;8.예제3에서&amp;nbsp;아날로그값&amp;nbsp;3종과&amp;nbsp;예제6에서&amp;nbsp;온습도값&amp;nbsp;2종을&amp;nbsp;모두&amp;nbsp;C#에&amp;nbsp;전송해서&amp;nbsp;listview에&amp;nbsp;현재&amp;nbsp;시간을&amp;nbsp;포함해서&amp;nbsp;출력하시오!(1초간격)&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;08.PNG&quot; data-origin-width=&quot;706&quot; data-origin-height=&quot;456&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cpdnui/dJMcad1xFES/5tlxLswlfCbITAs9o0Iih0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cpdnui/dJMcad1xFES/5tlxLswlfCbITAs9o0Iih0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cpdnui/dJMcad1xFES/5tlxLswlfCbITAs9o0Iih0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fcpdnui%2FdJMcad1xFES%2F5tlxLswlfCbITAs9o0Iih0%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;706&quot; height=&quot;456&quot; data-filename=&quot;08.PNG&quot; data-origin-width=&quot;706&quot; data-origin-height=&quot;456&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;pre id=&quot;code_1765202867850&quot; class=&quot;cpp&quot; data-ke-language=&quot;cpp&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;/* USER CODE BEGIN 0 */
#define R1 10000
#define c1 1.009249522e-03
#define c2 2.378405444e-04
#define c3 2.019202697e-07
/* USER CODE END 0 */

/* USER CODE BEGIN 2 */
 uint16_t adc_value0 = 0;
 uint16_t adc_value1 = 0;
 uint16_t adc_value2 = 0;
 float logR2, R2, T, Tc, Tf;
 uint8_t AHT10_TmpHum_Cmd[3] = {0xAC, 0x33, 0x00};
 uint8_t AHT10_RX_Data[6];
 uint32_t AHT10_ADC_Raw;
 float AHT10_Temperature;
 float AHT10_Humidity;
 char str[100];
 /* USER CODE END 2 */


/* USER CODE BEGIN WHILE */
 while (1)
 {
	  //PA0 ADC1 RANK1
	  HAL_ADC_Start(&amp;amp;hadc1);
	  HAL_ADC_PollForConversion(&amp;amp;hadc1, 100);
	  adc_value0 = HAL_ADC_GetValue(&amp;amp;hadc1);
	  //PA1 ADC1 RANK2
	  HAL_ADC_Start(&amp;amp;hadc1);
	  HAL_ADC_PollForConversion(&amp;amp;hadc1, 100);
	  adc_value1 = HAL_ADC_GetValue(&amp;amp;hadc1);
	  //PA4 ADC1 RANK3
	  HAL_ADC_Start(&amp;amp;hadc1);
	  HAL_ADC_PollForConversion(&amp;amp;hadc1, 100);
	  adc_value2 = HAL_ADC_GetValue(&amp;amp;hadc1);
	  //온도계산
	  R2 = R1 * (4095.0 / adc_value2 - 1.0);
	  logR2 = log(R2);
	  T = (1.0 / (c1 + c2*logR2 + c3*logR2*logR2*logR2));
	  Tc = T - 273.15;

	  //요청
	  HAL_I2C_Master_Transmit(&amp;amp;hi2c1, (0x38 &amp;lt;&amp;lt; 1), AHT10_TmpHum_Cmd, 3, 10);
	  //수신대기
	  uint8_t recv[1];
	  while(1){
		  HAL_I2C_Master_Receive(&amp;amp;hi2c1, (0x38 &amp;lt;&amp;lt; 1), recv, 6, 10);
		  if(~recv[0] &amp;amp; 0x80){
			  break;
		  }
	  }
	  //데이터 수신
	  HAL_I2C_Master_Receive(&amp;amp;hi2c1, (0x38 &amp;lt;&amp;lt; 1), AHT10_RX_Data, 6, 10);
	  //수신데이터 출력
	  AHT10_ADC_Raw = (((uint32_t)AHT10_RX_Data[3] &amp;amp; 15) &amp;lt;&amp;lt; 16) | ((uint32_t)AHT10_RX_Data[4] &amp;lt;&amp;lt; 8) | AHT10_RX_Data[5];
	  AHT10_Temperature = (float)(AHT10_ADC_Raw * 200.00 / 1048576.00) - 50.00;
	  /* Convert to Relative Humidity in % */
	  AHT10_ADC_Raw = ((uint32_t)AHT10_RX_Data[1] &amp;lt;&amp;lt; 12) | ((uint32_t)AHT10_RX_Data[2] &amp;lt;&amp;lt; 4) | (AHT10_RX_Data[3] &amp;gt;&amp;gt; 4);
	  AHT10_Humidity = (float)(AHT10_ADC_Raw*100.00/1048576.00);
	  sprintf(str,&quot;{\&quot;sen1\&quot;:%d,\&quot;sen2\&quot;:%d,\&quot;sen3\&quot;:%.2f,\&quot;temp\&quot;:%.2f,\&quot;humi\&quot;:%.2f}\n&quot;,adc_value0,adc_value1,Tc,AHT10_Temperature,AHT10_Humidity);
	  HAL_UART_Transmit(&amp;amp;huart2,str,strlen(str),100);
	  HAL_Delay(1000);
   /* USER CODE END WHILE */
   /* USER CODE BEGIN 3 */
 }&lt;/code&gt;&lt;/pre&gt;
&lt;pre id=&quot;code_1765202976352&quot; class=&quot;csharp&quot; data-ke-language=&quot;csharp&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;using Newtonsoft.Json.Linq; //네임스페이스 추가

//전역변수자리
 int cnt = 1;

private void button1_Click(object sender, EventArgs e)
        {
            //접속버튼 클릭
            serialPort1.PortName = textBox1.Text;
            serialPort1.BaudRate = 115200;
            serialPort1.Open();
            if (serialPort1.IsOpen)
            {
                //수신버퍼 클리어
                serialPort1.ReadExisting();
                MessageBox.Show(&quot;접속완료!&quot;);
            }
        }


private void serialPort1_DataReceived(object sender, System.IO.Ports.SerialDataReceivedEventArgs e)
        {
            //STM32가 데이터를 전송했다!
            string data = serialPort1.ReadLine();
            //데이터 해석
            try
            {
                JObject myjson = JObject.Parse(data);
                textBox2.Text = myjson[&quot;temp&quot;].ToString();
                textBox3.Text = myjson[&quot;humi&quot;].ToString();
                textBox4.Text = myjson[&quot;sen1&quot;].ToString();
                textBox5.Text = myjson[&quot;sen2&quot;].ToString();
                textBox6.Text = myjson[&quot;sen3&quot;].ToString();

                //데이터 삽입
                ListViewItem lvi = new ListViewItem();
                lvi.Text = cnt.ToString();
                lvi.SubItems.Add(myjson[&quot;temp&quot;].ToString());
                lvi.SubItems.Add(myjson[&quot;humi&quot;].ToString());
                lvi.SubItems.Add(myjson[&quot;sen1&quot;].ToString());
                lvi.SubItems.Add(myjson[&quot;sen2&quot;].ToString());
                lvi.SubItems.Add(myjson[&quot;sen3&quot;].ToString());
                lvi.SubItems.Add(DateTime.Now.ToString());
                listView1.Items.Add(lvi);
                cnt++;
            }
            catch { }
        }&lt;/code&gt;&lt;/pre&gt;</description>
      <category>프로그래밍/STM32</category>
      <author>덕력킹</author>
      <guid isPermaLink="true">https://bota.tistory.com/2459</guid>
      <comments>https://bota.tistory.com/2459#entry2459comment</comments>
      <pubDate>Mon, 8 Dec 2025 23:11:57 +0900</pubDate>
    </item>
    <item>
      <title>[STM32#16] C# winform을 이용해서 STM32f103rb nucleo보드와 usart2로 serial통신하는 방법 계속알아보기!(녹칸다 내맘대로 STM32)</title>
      <link>https://bota.tistory.com/2458</link>
      <description>&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;stm32.png&quot; data-origin-width=&quot;1920&quot; data-origin-height=&quot;1080&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cPrZnS/dJMcad1vOhh/oe3DsQ5Ejq8ny1oSkkD9b0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cPrZnS/dJMcad1vOhh/oe3DsQ5Ejq8ny1oSkkD9b0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cPrZnS/dJMcad1vOhh/oe3DsQ5Ejq8ny1oSkkD9b0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FcPrZnS%2FdJMcad1vOhh%2Foe3DsQ5Ejq8ny1oSkkD9b0%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;1920&quot; height=&quot;1080&quot; data-filename=&quot;stm32.png&quot; data-origin-width=&quot;1920&quot; data-origin-height=&quot;1080&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/live/oTKsk64gdPY&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://youtube.com/live/oTKsk64gdPY&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/watch?v=oTKsk64gdPY&quot; data-video-thumbnail=&quot;https://scrap.kakaocdn.net/dn/2rbh9/hyZOQb1uzw/ezfUxpluoNc9Qf7LMLjqn0/img.jpg?width=1280&amp;amp;height=720&amp;amp;face=0_0_1280_720,https://scrap.kakaocdn.net/dn/dcSEqE/hyZO2Ke44Q/02wGz9QkswkPVfkmTRuyf1/img.jpg?width=1280&amp;amp;height=720&amp;amp;face=0_0_1280_720,https://scrap.kakaocdn.net/dn/blN1G2/hyZNJE2YKu/pcNHDTlwekrhopyNk8PRIK/img.jpg?width=1280&amp;amp;height=720&amp;amp;face=0_0_1280_720&quot; data-video-width=&quot;860&quot; data-video-height=&quot;484&quot; data-video-origin-width=&quot;860&quot; data-video-origin-height=&quot;484&quot; data-ke-mobilestyle=&quot;widthContent&quot; data-video-title=&quot;[STM32#16] C# winform을 이용해서 STM32f103rb nucleo보드와 usart2로 serial통신하는 방법 계속알아보기!(녹칸&quot; data-original-url=&quot;&quot;&gt;&lt;iframe src=&quot;https://www.youtube.com/embed/oTKsk64gdPY&quot; width=&quot;860&quot; height=&quot;484&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;[STM32#16]&amp;nbsp;C#&amp;nbsp;winform을&amp;nbsp;이용해서&amp;nbsp;STM32f103rb&amp;nbsp;nucleo보드와&amp;nbsp;usart2로&amp;nbsp;serial통신하는&amp;nbsp;방법&amp;nbsp;계속알아보기!(녹칸다&amp;nbsp;내맘대로&amp;nbsp;STM32) &lt;br /&gt;&lt;br /&gt;심심한녹칸다의&amp;nbsp;내맘대로&amp;nbsp;STM32시리즈이다! &lt;br /&gt;&lt;br /&gt;STM32시리즈의&amp;nbsp;모든&amp;nbsp;자료는&amp;nbsp;구글&amp;nbsp;슬라이드에&amp;nbsp;작성하고&amp;nbsp;모두에게&amp;nbsp;공유되어있음! &lt;br /&gt;&lt;a href=&quot;https://docs.google.com/presentation/d/1myA5iYbjuKsLWLqtRLKAiRfwUwvqB1d1RGjiMIIgp3I/edit?slide=id.g39a36328931_2_238#slide=id.g39a36328931_2_238&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://docs.google.com/presentation/d/1myA5iYbjuKsLWLqtRLKAiRfwUwvqB1d1RGjiMIIgp3I/edit?slide=id.g39a36328931_2_238#slide=id.g39a36328931_2_238&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;이제&amp;nbsp;&amp;nbsp;C#윈폼으로&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;1.STM32에서&amp;nbsp;부호가없는&amp;nbsp;32bit정수&amp;nbsp;타입의&amp;nbsp;값&amp;nbsp;2개를&amp;nbsp;1초&amp;nbsp;간격으로&amp;nbsp;C#으로&amp;nbsp;전송한다!&amp;nbsp;이때&amp;nbsp;데이터&amp;nbsp;형식은&amp;nbsp;CSV&amp;nbsp;형식이다!&amp;nbsp;C#에서&amp;nbsp;수신한&amp;nbsp;데이터를&amp;nbsp;분리해서&amp;nbsp;출력하시오! &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;-(결과예시)&amp;nbsp;num1은&amp;nbsp;12345이고,&amp;nbsp;num2는&amp;nbsp;56789이고,&amp;nbsp;num1+num2는&amp;nbsp;???입니다!&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;01.PNG&quot; data-origin-width=&quot;552&quot; data-origin-height=&quot;362&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/p2nnq/dJMcaaqeFOO/xAh3R1VYCqPcCEX7FbsSMk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/p2nnq/dJMcaaqeFOO/xAh3R1VYCqPcCEX7FbsSMk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/p2nnq/dJMcaaqeFOO/xAh3R1VYCqPcCEX7FbsSMk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fp2nnq%2FdJMcaaqeFOO%2FxAh3R1VYCqPcCEX7FbsSMk%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;552&quot; height=&quot;362&quot; data-filename=&quot;01.PNG&quot; data-origin-width=&quot;552&quot; data-origin-height=&quot;362&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;pre id=&quot;code_1764747929959&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 */
 uint32_t num1 = 12345;
 uint32_t num2 = 67890;
 char buff[100];
 /* USER CODE END 2 */
 /* Infinite loop */
 /* USER CODE BEGIN WHILE */
 while (1)
 {
	  //num1, num2를 csv형식으로 buff에 대입한다
	  sprintf(buff,&quot;%d,%d\n&quot;,num1,num2);
	  //buff안에 있는 값을 널문자(\0)까지의 길이를 반환해서 전송한다
	  HAL_UART_Transmit(&amp;amp;huart2,buff,strlen(buff),100);
	  HAL_Delay(1000);
   /* USER CODE END WHILE */
   /* USER CODE BEGIN 3 */
 }&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_1764748038693&quot; class=&quot;csharp&quot; data-ke-language=&quot;csharp&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;private void button1_Click(object sender, EventArgs e)
        {
            //접속하기 버튼 클릭했다 뭐할래?
            serialPort1.PortName = textBox1.Text;
            serialPort1.BaudRate = 115200;

            //serialport1의 open메서드를 콜한다!
            serialPort1.Open();

            if (serialPort1.IsOpen)
            {
                //버퍼의 직전데이터가 밀려서 들어온다!
                serialPort1.ReadExisting();
                MessageBox.Show(&quot;접속완료!&quot;);
            }
        }
        private void serialPort1_DataReceived(object sender, System.IO.Ports.SerialDataReceivedEventArgs e)
        {
            //stm32가 데이터를 보냈는데 뭐할래?
            //stm32는 반드시 문자열로 전송하고 종료문자 \n붙힌다!
            string data = serialPort1.ReadLine();
            //STM32가 보낸 데이터는 CSV형식이다!
            string[] csv_data = data.Split(',');
            //STM32가 보낸 데이터는 2개이기 때문에 배열의 갯수는 2여야한다!
            if(csv_data.Length == 2)
            {
                //csv_data[0] : num1
                //csv_data[1] : num2
                UInt32 num1 = UInt32.Parse(csv_data[0]);
                UInt32 num2 = UInt32.Parse(csv_data[1]);
                UInt32 sum = num1 + num2;

                //richTextBox1.Text += &quot;num1=&quot; + num1 + &quot;, num2=&quot; + num2 + &quot;, sum=&quot; + sum + &quot;\n&quot;;
                richTextBox1.Text += $&quot;num1={num1}, num2={num2}, sum={sum}\n&quot;;
            }
        }&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;br /&gt;2.예제1번과&amp;nbsp;동일한&amp;nbsp;구성인데,&amp;nbsp;STM32가&amp;nbsp;JSON형식으로&amp;nbsp;데이터를&amp;nbsp;전송할때&amp;nbsp;C#윈폼에서&amp;nbsp;동일하게&amp;nbsp;parse해서&amp;nbsp;richtextbox1에&amp;nbsp;적절하게&amp;nbsp;출력하시오!&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;02.PNG&quot; data-origin-width=&quot;563&quot; data-origin-height=&quot;366&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bwa8H7/dJMcaiPijlF/Cu5FmAjA938sUtRFVx9wx1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bwa8H7/dJMcaiPijlF/Cu5FmAjA938sUtRFVx9wx1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bwa8H7/dJMcaiPijlF/Cu5FmAjA938sUtRFVx9wx1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fbwa8H7%2FdJMcaiPijlF%2FCu5FmAjA938sUtRFVx9wx1%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;366&quot; data-filename=&quot;02.PNG&quot; data-origin-width=&quot;563&quot; data-origin-height=&quot;366&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;pre id=&quot;code_1764747942895&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 */
 uint32_t num1 = 12345;
 uint32_t num2 = 67890;
 char buff[100];
 /* USER CODE END 2 */
 /* Infinite loop */
 /* USER CODE BEGIN WHILE */
 while (1)
 {
	  //num1, num2를 csv형식으로 buff에 대입한다
	  sprintf(buff,&quot;{\&quot;num1\&quot;:%d, \&quot;num2\&quot;:%d}\n&quot;,num1,num2);
	  //buff안에 있는 값을 널문자(\0)까지의 길이를 반환해서 전송한다
	  HAL_UART_Transmit(&amp;amp;huart2,buff,strlen(buff),100);
	  HAL_Delay(1000);
   /* USER CODE END WHILE */
   /* USER CODE BEGIN 3 */
 }&lt;/code&gt;&lt;/pre&gt;
&lt;pre id=&quot;code_1764748058831&quot; class=&quot;csharp&quot; data-ke-language=&quot;csharp&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;using Newtonsoft.Json.Linq; //네임스페이스 추가~

private void button1_Click(object sender, EventArgs e)
        {
            //접속하기 버튼 클릭했다 뭐할래?
            serialPort1.PortName = textBox1.Text;
            serialPort1.BaudRate = 115200;

            //serialport1의 open메서드를 콜한다!
            serialPort1.Open();

            if (serialPort1.IsOpen)
            {
                //버퍼의 직전데이터가 밀려서 들어온다!
                serialPort1.ReadExisting();
                MessageBox.Show(&quot;접속완료!&quot;);
            }
        }
private void serialPort1_DataReceived(object sender, System.IO.Ports.SerialDataReceivedEventArgs e)
        {
            //stm32가 데이터를 보냈는데 뭐할래?
            //stm32는 반드시 문자열로 전송하고 종료문자 \n붙힌다!
            string data = serialPort1.ReadLine();
            //data안에 JSON형식의 데이터가 있다!

            try
            {    
                JObject json_data = JObject.Parse(data);
                UInt32 num1 = UInt32.Parse(json_data[&quot;num1&quot;].ToString());// : num1
                UInt32 num2 = UInt32.Parse(json_data[&quot;num2&quot;].ToString());// : num2
                UInt32 sum = num1 + num2;

                richTextBox1.Text += $&quot;원본={data}\n&quot;;
                richTextBox1.Text += $&quot;num1={num1}, num2={num2}, sum={sum}\n&quot;;
            }
            catch
            {
                //만약 json데이터에 문제가 있다면 이쪽으로 떨어짐!
            }
        }&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;br /&gt;3.이번에는&amp;nbsp;STM32에서&amp;nbsp;2개의&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-filename=&quot;03.PNG&quot; data-origin-width=&quot;555&quot; data-origin-height=&quot;484&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cN6iu1/dJMcaaqeFPh/eHkf1KGHUptWbKLROZO87K/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cN6iu1/dJMcaaqeFPh/eHkf1KGHUptWbKLROZO87K/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cN6iu1/dJMcaaqeFPh/eHkf1KGHUptWbKLROZO87K/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FcN6iu1%2FdJMcaaqeFPh%2FeHkf1KGHUptWbKLROZO87K%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;555&quot; height=&quot;484&quot; data-filename=&quot;03.PNG&quot; data-origin-width=&quot;555&quot; data-origin-height=&quot;484&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;pre id=&quot;code_1764747956748&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 */
 union{
    uint32_t input[2]; //8byte
    uint8_t output[8]; //8byte
 }myunion;
 myunion.input[0] = 12345; //num1
 myunion.input[1] = 67890; //num2
 /* USER CODE END 2 */
 /* Infinite loop */
 /* USER CODE BEGIN WHILE */
 while (1)
 {
	  //공용체에 들어갈때는 32bit정수2개지만, 나올때는 8byte 배열이란다~
	  HAL_UART_Transmit(&amp;amp;huart2,myunion.output,sizeof(myunion.output),100);
	  HAL_Delay(1000);
   /* USER CODE END WHILE */
   /* USER CODE BEGIN 3 */
 }&lt;/code&gt;&lt;/pre&gt;
&lt;pre id=&quot;code_1764748072759&quot; class=&quot;csharp&quot; data-ke-language=&quot;csharp&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;private void button1_Click(object sender, EventArgs e)
        {
            //접속하기 버튼 클릭했다 뭐할래?
            serialPort1.PortName = textBox1.Text;
            serialPort1.BaudRate = 115200;

            //serialport1의 open메서드를 콜한다!
            serialPort1.Open();

            if (serialPort1.IsOpen)
            {
                //버퍼의 직전데이터가 밀려서 들어온다!
                serialPort1.ReadExisting();
                MessageBox.Show(&quot;접속완료!&quot;);
            }
        }
private void serialPort1_DataReceived(object sender, System.IO.Ports.SerialDataReceivedEventArgs e)
        {
            //stm32가 데이터를 보냈는데 뭐할래?
            //STM32쪽에서 8byte 배열에 날라온다!
            byte[] recv = new byte[8];
            int cnt = 0;
            while (true)
            {
                recv[cnt] = (byte)serialPort1.ReadByte();
                cnt++;
                if (cnt == 8) break;
            }

            //recv배열안에 0~3이 num1, 4~7까지 num2인상황
            UInt32 num1 = BitConverter.ToUInt32(recv, 0);
            UInt32 num2 = BitConverter.ToUInt32(recv, 4);
            UInt32 sum = num1 + num2;

            richTextBox1.Text += $&quot;[수신] = &quot;;
            for (int i = 0; i &amp;lt; 8; i++)
            {
                richTextBox1.Text += recv[i] + &quot;, &quot;;
            }
            richTextBox1.Text += &quot;\n&quot;;
            richTextBox1.Text += $&quot;num1={num1}, num2={num2}, sum={sum}\n&quot;;

        }&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;br /&gt;4.예제3과&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-filename=&quot;04.PNG&quot; data-origin-width=&quot;559&quot; data-origin-height=&quot;472&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/td7TB/dJMcaiPijlV/8W0VRT32g3Os5rvsOKZpBK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/td7TB/dJMcaiPijlV/8W0VRT32g3Os5rvsOKZpBK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/td7TB/dJMcaiPijlV/8W0VRT32g3Os5rvsOKZpBK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Ftd7TB%2FdJMcaiPijlV%2F8W0VRT32g3Os5rvsOKZpBK%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;559&quot; height=&quot;472&quot; data-filename=&quot;04.PNG&quot; data-origin-width=&quot;559&quot; data-origin-height=&quot;472&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;pre id=&quot;code_1764747969872&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 */
 struct{
	 uint32_t num1;
	 uint32_t num2;
 }mystruct;
 mystruct.num1 = 12345;
 mystruct.num2 = 67890;
 /* USER CODE END 2 */
 /* Infinite loop */
 /* USER CODE BEGIN WHILE */
 while (1)
 {
	  HAL_UART_Transmit(&amp;amp;huart2,(uint8_t*)&amp;amp;mystruct,sizeof(mystruct),100);
	  HAL_Delay(1000);
   /* USER CODE END WHILE */
   /* USER CODE BEGIN 3 */
 }&lt;/code&gt;&lt;/pre&gt;
&lt;pre id=&quot;code_1764748086836&quot; class=&quot;csharp&quot; data-ke-language=&quot;csharp&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;private void button1_Click(object sender, EventArgs e)
        {
            //접속하기 버튼 클릭했다 뭐할래?
            serialPort1.PortName = textBox1.Text;
            serialPort1.BaudRate = 115200;

            //serialport1의 open메서드를 콜한다!
            serialPort1.Open();

            if (serialPort1.IsOpen)
            {
                //버퍼의 직전데이터가 밀려서 들어온다!
                serialPort1.ReadExisting();
                MessageBox.Show(&quot;접속완료!&quot;);
            }
        }


private void serialPort1_DataReceived(object sender, System.IO.Ports.SerialDataReceivedEventArgs e)
        {
            //stm32가 데이터를 보냈는데 뭐할래?
            //STM32쪽에서 8byte 배열에 날라온다!
            byte[] recv = new byte[8];
            int cnt = 0;
            while (true)
            {
                recv[cnt] = (byte)serialPort1.ReadByte();
                cnt++;
                if (cnt == 8) break;
            }

            //recv배열안에 0~3이 num1, 4~7까지 num2인상황
            UInt32 num1 = BitConverter.ToUInt32(recv, 0);
            UInt32 num2 = BitConverter.ToUInt32(recv, 4);
            UInt32 sum = num1 + num2;

            richTextBox1.Text += $&quot;[수신] = &quot;;
            for (int i = 0; i &amp;lt; 8; i++)
            {
                richTextBox1.Text += recv[i] + &quot;, &quot;;
            }
            richTextBox1.Text += &quot;\n&quot;;
            richTextBox1.Text += $&quot;num1={num1}, num2={num2}, sum={sum}\n&quot;;

        }&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;br /&gt;5.녹칸다의 STM32쉴드에 붙어있는 로터리엔코더를 시계방향으로 돌리면 C#윈폼 화면에 값이 1씩 증가하도록하고 반시계방향으로 돌리면 1씩감소하고 스위치를 누르면 0으로 초기화 하도록 하시오!(변화되는 값은 C#의 변수값이다)&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;05.PNG&quot; data-origin-width=&quot;557&quot; data-origin-height=&quot;325&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/Ahv7T/dJMcacO7kUB/QWIAfZrtMkUdqBw9lqj6BK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/Ahv7T/dJMcacO7kUB/QWIAfZrtMkUdqBw9lqj6BK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/Ahv7T/dJMcacO7kUB/QWIAfZrtMkUdqBw9lqj6BK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FAhv7T%2FdJMcacO7kUB%2FQWIAfZrtMkUdqBw9lqj6BK%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;557&quot; height=&quot;325&quot; data-filename=&quot;05.PNG&quot; data-origin-width=&quot;557&quot; data-origin-height=&quot;325&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;pre id=&quot;code_1764747982782&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 */
 uint8_t old_A = 0;
 /* USER CODE END 2 */
 /* Infinite loop */
 /* USER CODE BEGIN WHILE */
 while (1)
 {
	  uint8_t sw = HAL_GPIO_ReadPin(GPIOC,GPIO_PIN_7);
	  if(sw == 0){
		  HAL_UART_Transmit(&amp;amp;huart2, &quot;0&quot;, 1, 100);
		  HAL_Delay(200);
	  }
	  //PA11의 상승엣지가 발생했을때
	  uint8_t now_A = HAL_GPIO_ReadPin(GPIOA,GPIO_PIN_11);
	  if(old_A == 0 &amp;amp;&amp;amp; now_A == 1){
		  //PA12의 값을 측정해서 LOW면 시계, HIGH면 반시계
		  uint8_t now_B = HAL_GPIO_ReadPin(GPIOA,GPIO_PIN_12);
		  if(now_B){
			 //반시계
			  HAL_UART_Transmit(&amp;amp;huart2, &quot;-&quot;, 1, 100);
		  }else{
			 //시계
			  HAL_UART_Transmit(&amp;amp;huart2, &quot;+&quot;, 1, 100);
		  }
	  }
	  old_A = now_A;
	  HAL_Delay(1);
   /* USER CODE END WHILE */
   /* USER CODE BEGIN 3 */
 }&lt;/code&gt;&lt;/pre&gt;
&lt;pre id=&quot;code_1764748098851&quot; class=&quot;csharp&quot; data-ke-language=&quot;csharp&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;//C#의 전역변수 위치
int cnt = 0;


private void button1_Click(object sender, EventArgs e)
        {
            //접속하기 버튼 클릭했다 뭐할래?
            serialPort1.PortName = textBox1.Text;
            serialPort1.BaudRate = 115200;

            //serialport1의 open메서드를 콜한다!
            serialPort1.Open();

            if (serialPort1.IsOpen)
            {
                //버퍼의 직전데이터가 밀려서 들어온다!
                serialPort1.ReadExisting();
                MessageBox.Show(&quot;접속완료!&quot;);
            }
        }


private void serialPort1_DataReceived(object sender, System.IO.Ports.SerialDataReceivedEventArgs e)
        {
            //stm32가 데이터를 보냈는데 뭐할래?
            //STM32에서 문자 1개가 수신된다!
            //'+' : 시계방향
            //'-' : 반시계방향
            //'0' : 초기화
            char c = (char)serialPort1.ReadChar();
            richTextBox1.Text += c + &quot;\n&quot;;

            if(c == '0')
            {
                cnt = 0;
                textBox2.Text = cnt.ToString();
            }else if (c == '+')
            {
                cnt++;
                textBox2.Text = cnt.ToString();
            }
            else if (c == '-')
            {
                cnt--;
                textBox2.Text = cnt.ToString();
            }
        }&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;br /&gt;6.예제5에서&amp;nbsp;로터리엔코더를&amp;nbsp;돌려서&amp;nbsp;바뀌는&amp;nbsp;값은&amp;nbsp;STM32메모리에&amp;nbsp;기억되고,&amp;nbsp;변화되는&amp;nbsp;값을&amp;nbsp;C#으로&amp;nbsp;전송해서&amp;nbsp;화면에&amp;nbsp;출력하시오!(카운터값이&amp;nbsp;-10~+10사이면&amp;nbsp;흰색,&amp;nbsp;+11부터는&amp;nbsp;빨간색,&amp;nbsp;-11이하면&amp;nbsp;노란색으로&amp;nbsp;바꾸시오!)&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;06.PNG&quot; data-origin-width=&quot;624&quot; data-origin-height=&quot;329&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/tiPaJ/dJMcaaw0p23/0AISLojE7XCkNsjYZzVMR1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/tiPaJ/dJMcaaw0p23/0AISLojE7XCkNsjYZzVMR1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/tiPaJ/dJMcaaw0p23/0AISLojE7XCkNsjYZzVMR1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FtiPaJ%2FdJMcaaw0p23%2F0AISLojE7XCkNsjYZzVMR1%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;624&quot; height=&quot;329&quot; data-filename=&quot;06.PNG&quot; data-origin-width=&quot;624&quot; data-origin-height=&quot;329&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;pre id=&quot;code_1764747993549&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 */
 int cnt = 0;
 uint8_t old_A = 0;
 char buff[50];
 char recv;
 /* USER CODE END 2 */
 /* Infinite loop */
 /* USER CODE BEGIN WHILE */
 while (1)
 {
	  if(HAL_UART_Receive(&amp;amp;huart2, &amp;amp;recv, 1, 1) == HAL_OK){
		  if(recv == '0'){
			  //C#에서 현재 CNT값을 1회 전송해달라는 명령!
			  sprintf(buff,&quot;%d\n&quot;,cnt);
			  HAL_UART_Transmit(&amp;amp;huart2, buff, strlen(buff), 100);
		  }
	  }
	  uint8_t sw = HAL_GPIO_ReadPin(GPIOC,GPIO_PIN_7);
	  if(sw == 0){
		  cnt = 0;
		  sprintf(buff,&quot;%d\n&quot;,cnt);
		  HAL_UART_Transmit(&amp;amp;huart2, buff, strlen(buff), 100);
		  HAL_Delay(200);
	  }
	  //PA11의 상승엣지가 발생했을때
	  uint8_t now_A = HAL_GPIO_ReadPin(GPIOA,GPIO_PIN_11);
	  if(old_A == 0 &amp;amp;&amp;amp; now_A == 1){
		  //PA12의 값을 측정해서 LOW면 시계, HIGH면 반시계
		  uint8_t now_B = HAL_GPIO_ReadPin(GPIOA,GPIO_PIN_12);
		  if(now_B){
			 //반시계
			  cnt--;
		  }else{
			 //시계
			  cnt++;
		  }
		  sprintf(buff,&quot;%d\n&quot;,cnt);
		  HAL_UART_Transmit(&amp;amp;huart2, buff, strlen(buff), 100);
	  }
	  old_A = now_A;
	  HAL_Delay(1);
   /* USER CODE END WHILE */
   /* USER CODE BEGIN 3 */
 }&lt;/code&gt;&lt;/pre&gt;
&lt;pre id=&quot;code_1764748111384&quot; class=&quot;csharp&quot; data-ke-language=&quot;csharp&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;private void button1_Click(object sender, EventArgs e)
        {
            //접속하기 버튼 클릭했다 뭐할래?
            serialPort1.PortName = textBox1.Text;
            serialPort1.BaudRate = 115200;

            //serialport1의 open메서드를 콜한다!
            serialPort1.Open();

            if (serialPort1.IsOpen)
            {
                //버퍼의 직전데이터가 밀려서 들어온다!
                serialPort1.ReadExisting();
                //C#에서 포트를 개방한 직후 STM32에게 CNT값을 물어본다!
                //STM32에게 문자 '0'을 전송하면 STM32는 응답한다!
                serialPort1.Write(&quot;0&quot;);
                MessageBox.Show(&quot;접속완료!&quot;);
            }
        }

private void serialPort1_DataReceived(object sender, System.IO.Ports.SerialDataReceivedEventArgs e)
        {
            //stm32가 데이터를 보냈는데 뭐할래?
            string data = serialPort1.ReadLine();
            textBox2.Text = data;

            int cnt = int.Parse(data);
            if(cnt &amp;gt; 10)
            {
                //빨간색
                textBox2.BackColor = Color.Red;
            }else if(cnt &amp;lt; -11)
            {
                //노란색
                textBox2.BackColor = Color.Yellow;
            }
            else
            {
                //흰색
                textBox2.BackColor = Color.White;
            }
        }&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;br /&gt;7.예제5에서&amp;nbsp;로터리엔코더의&amp;nbsp;스위치를&amp;nbsp;누르면&amp;nbsp;0으로&amp;nbsp;초기화한다라는&amp;nbsp;조건&amp;nbsp;대신에,&amp;nbsp;C#윈폼의&amp;nbsp;listbox를&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-filename=&quot;07.PNG&quot; data-origin-width=&quot;623&quot; data-origin-height=&quot;346&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/c7co0k/dJMcaiPijmf/51mT5i9icb2PKKkQUDPsJK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/c7co0k/dJMcaiPijmf/51mT5i9icb2PKKkQUDPsJK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/c7co0k/dJMcaiPijmf/51mT5i9icb2PKKkQUDPsJK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fc7co0k%2FdJMcaiPijmf%2F51mT5i9icb2PKKkQUDPsJK%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;623&quot; height=&quot;346&quot; data-filename=&quot;07.PNG&quot; data-origin-width=&quot;623&quot; data-origin-height=&quot;346&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;pre id=&quot;code_1764748005357&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 */
 uint8_t old_A = 0;
 /* USER CODE END 2 */
 /* Infinite loop */
 /* USER CODE BEGIN WHILE */
 while (1)
 {
	  uint8_t sw = HAL_GPIO_ReadPin(GPIOC,GPIO_PIN_7);
	  if(sw == 0){
		  HAL_UART_Transmit(&amp;amp;huart2, &quot;0&quot;, 1, 100);
		  HAL_Delay(200);
	  }
	  //PA11의 상승엣지가 발생했을때
	  uint8_t now_A = HAL_GPIO_ReadPin(GPIOA,GPIO_PIN_11);
	  if(old_A == 0 &amp;amp;&amp;amp; now_A == 1){
		  //PA12의 값을 측정해서 LOW면 시계, HIGH면 반시계
		  uint8_t now_B = HAL_GPIO_ReadPin(GPIOA,GPIO_PIN_12);
		  if(now_B){
			 //반시계
			  HAL_UART_Transmit(&amp;amp;huart2, &quot;-&quot;, 1, 100);
		  }else{
			 //시계
			  HAL_UART_Transmit(&amp;amp;huart2, &quot;+&quot;, 1, 100);
		  }
	  }
	  old_A = now_A;
	  HAL_Delay(1);
   /* USER CODE END WHILE */
   /* USER CODE BEGIN 3 */
 }&lt;/code&gt;&lt;/pre&gt;
&lt;pre id=&quot;code_1764748122836&quot; class=&quot;csharp&quot; data-ke-language=&quot;csharp&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;//C#의 전역변수 위치
int cnt = 0;


private void button1_Click(object sender, EventArgs e)
        {
            //접속하기 버튼 클릭했다 뭐할래?
            serialPort1.PortName = textBox1.Text;
            serialPort1.BaudRate = 115200;

            //serialport1의 open메서드를 콜한다!
            serialPort1.Open();

            if (serialPort1.IsOpen)
            {
                //버퍼의 직전데이터가 밀려서 들어온다!
                serialPort1.ReadExisting();
                MessageBox.Show(&quot;접속완료!&quot;);
            }
        }



private void serialPort1_DataReceived(object sender, System.IO.Ports.SerialDataReceivedEventArgs e)
        {
            //stm32가 데이터를 보냈는데 뭐할래?
            //STM32에서 문자 1개가 수신된다!
            //'+' : 시계방향
            //'-' : 반시계방향
            //'0' : 초기화
            char c = (char)serialPort1.ReadChar();
            richTextBox1.Text += c + &quot;\n&quot;;

            if (c == '0')
            {
                //cnt = 0;
                //textBox2.Text = cnt.ToString();
                //listbox1에 현재 cnt값을 추가함!
                listBox1.Items.Add(cnt);
            }
            else if (c == '+')
            {
                cnt++;
                textBox2.Text = cnt.ToString();
            }
            else if (c == '-')
            {
                cnt--;
                textBox2.Text = cnt.ToString();
            }

        }

        private void button2_Click(object sender, EventArgs e)
        {
            //listbox1에 있는 내용을 다 지운다!
            listBox1.Items.Clear();
        }&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;br /&gt;8.예제5에서&amp;nbsp;누겟페키지관리로가서&amp;nbsp;agauge2를&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-filename=&quot;08.PNG&quot; data-origin-width=&quot;632&quot; data-origin-height=&quot;337&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/Cgkw4/dJMcaajsZgS/3D8TOqy8IscCcZ4fiQzbX0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/Cgkw4/dJMcaajsZgS/3D8TOqy8IscCcZ4fiQzbX0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/Cgkw4/dJMcaajsZgS/3D8TOqy8IscCcZ4fiQzbX0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FCgkw4%2FdJMcaajsZgS%2F3D8TOqy8IscCcZ4fiQzbX0%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;632&quot; height=&quot;337&quot; data-filename=&quot;08.PNG&quot; data-origin-width=&quot;632&quot; data-origin-height=&quot;337&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;pre id=&quot;code_1764748015631&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 */
 uint8_t old_A = 0;
 /* USER CODE END 2 */
 /* Infinite loop */
 /* USER CODE BEGIN WHILE */
 while (1)
 {
	  uint8_t sw = HAL_GPIO_ReadPin(GPIOC,GPIO_PIN_7);
	  if(sw == 0){
		  HAL_UART_Transmit(&amp;amp;huart2, &quot;0&quot;, 1, 100);
		  HAL_Delay(200);
	  }
	  //PA11의 상승엣지가 발생했을때
	  uint8_t now_A = HAL_GPIO_ReadPin(GPIOA,GPIO_PIN_11);
	  if(old_A == 0 &amp;amp;&amp;amp; now_A == 1){
		  //PA12의 값을 측정해서 LOW면 시계, HIGH면 반시계
		  uint8_t now_B = HAL_GPIO_ReadPin(GPIOA,GPIO_PIN_12);
		  if(now_B){
			 //반시계
			  HAL_UART_Transmit(&amp;amp;huart2, &quot;-&quot;, 1, 100);
		  }else{
			 //시계
			  HAL_UART_Transmit(&amp;amp;huart2, &quot;+&quot;, 1, 100);
		  }
	  }
	  old_A = now_A;
	  HAL_Delay(1);
   /* USER CODE END WHILE */
   /* USER CODE BEGIN 3 */
 }&lt;/code&gt;&lt;/pre&gt;
&lt;pre id=&quot;code_1764748135594&quot; class=&quot;csharp&quot; data-ke-language=&quot;csharp&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;//C#의 전역변수 위치
int cnt = 0;

private void button1_Click(object sender, EventArgs e)
        {
            //접속하기 버튼 클릭했다 뭐할래?
            serialPort1.PortName = textBox1.Text;
            serialPort1.BaudRate = 115200;

            //serialport1의 open메서드를 콜한다!
            serialPort1.Open();

            if (serialPort1.IsOpen)
            {
                //버퍼의 직전데이터가 밀려서 들어온다!
                serialPort1.ReadExisting();
                MessageBox.Show(&quot;접속완료!&quot;);
            }
        }



private void serialPort1_DataReceived(object sender, System.IO.Ports.SerialDataReceivedEventArgs e)
        {
            //stm32가 데이터를 보냈는데 뭐할래?
            //STM32에서 문자 1개가 수신된다!
            //'+' : 시계방향
            //'-' : 반시계방향
            //'0' : 초기화
            char c = (char)serialPort1.ReadChar();
            richTextBox1.Text += c + &quot;\n&quot;;

            if (c == '0')
            {
                cnt = 0;
                textBox2.Text = cnt.ToString();
                aGauge1.Value = cnt;
            }
            else if (c == '+')
            {
                cnt+=5;
                if (cnt &amp;gt; 400) cnt = 400;
                textBox2.Text = cnt.ToString();
                aGauge1.Value = cnt;
            }
            else if (c == '-')
            {
                cnt-=5;
                if (cnt &amp;lt; -100) cnt = -100;
                textBox2.Text = cnt.ToString();
                aGauge1.Value = cnt;
            }

        }&lt;/code&gt;&lt;/pre&gt;</description>
      <category>프로그래밍/STM32</category>
      <author>덕력킹</author>
      <guid isPermaLink="true">https://bota.tistory.com/2458</guid>
      <comments>https://bota.tistory.com/2458#entry2458comment</comments>
      <pubDate>Wed, 3 Dec 2025 16:51:14 +0900</pubDate>
    </item>
    <item>
      <title>[STM32#15] C# winform을 이용해서 STM32f103rb nucleo보드와 usart2로 시리얼(serial)통신하는 방법 알아보기!(녹칸다 내맘대로 STM32)</title>
      <link>https://bota.tistory.com/2457</link>
      <description>&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;stm32.png&quot; data-origin-width=&quot;1920&quot; data-origin-height=&quot;1080&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bv25Yl/dJMcagYhdlf/MW6pRMy8mjRETCwruEgYu0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bv25Yl/dJMcagYhdlf/MW6pRMy8mjRETCwruEgYu0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bv25Yl/dJMcagYhdlf/MW6pRMy8mjRETCwruEgYu0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fbv25Yl%2FdJMcagYhdlf%2FMW6pRMy8mjRETCwruEgYu0%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;1920&quot; height=&quot;1080&quot; data-filename=&quot;stm32.png&quot; data-origin-width=&quot;1920&quot; data-origin-height=&quot;1080&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/live/Q39rzRj1ol8&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://youtube.com/live/Q39rzRj1ol8&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/watch?v=Q39rzRj1ol8&quot; data-video-thumbnail=&quot;https://scrap.kakaocdn.net/dn/LJXJz/hyZOwFCZSr/Eke1vQU7muYCgVzwtXsDnk/img.jpg?width=1280&amp;amp;height=720&amp;amp;face=0_0_1280_720,https://scrap.kakaocdn.net/dn/xFU6W/hyZOqyCzFK/RAD0qM6EaX9Vlq45g4gmm1/img.jpg?width=1280&amp;amp;height=720&amp;amp;face=0_0_1280_720&quot; data-video-width=&quot;860&quot; data-video-height=&quot;484&quot; data-video-origin-width=&quot;860&quot; data-video-origin-height=&quot;484&quot; data-ke-mobilestyle=&quot;widthContent&quot; data-video-title=&quot;[STM32#15] C# winform을 이용해서 STM32f103rb nucleo보드와 usart2로 시리얼(serial)통신하는 방법 알아보기!(&quot; data-original-url=&quot;&quot;&gt;&lt;iframe src=&quot;https://www.youtube.com/embed/Q39rzRj1ol8&quot; width=&quot;860&quot; height=&quot;484&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;[STM32#15]&amp;nbsp;C#&amp;nbsp;winform을&amp;nbsp;이용해서&amp;nbsp;STM32f103rb&amp;nbsp;nucleo보드와&amp;nbsp;usart2로&amp;nbsp;serial통신하는&amp;nbsp;방법&amp;nbsp;알아보기!(녹칸다&amp;nbsp;내맘대로&amp;nbsp;STM32) &lt;br /&gt;&lt;br /&gt;심심한녹칸다의&amp;nbsp;내맘대로&amp;nbsp;STM32시리즈이다! &lt;br /&gt;&lt;br /&gt;STM32시리즈의&amp;nbsp;모든&amp;nbsp;자료는&amp;nbsp;구글&amp;nbsp;슬라이드에&amp;nbsp;작성하고&amp;nbsp;모두에게&amp;nbsp;공유되어있음! &lt;br /&gt;&lt;a href=&quot;https://docs.google.com/presentation/d/1myA5iYbjuKsLWLqtRLKAiRfwUwvqB1d1RGjiMIIgp3I/edit?slide=id.g3ab9129297f_1_25#slide=id.g3ab9129297f_1_25&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://docs.google.com/presentation/d/1myA5iYbjuKsLWLqtRLKAiRfwUwvqB1d1RGjiMIIgp3I/edit?slide=id.g3ab9129297f_1_25#slide=id.g3ab9129297f_1_25&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;이번편&amp;nbsp;부터&amp;nbsp;STM32의&amp;nbsp;친구&amp;nbsp;C#윈폼이&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;span style=&quot;color: #595959;&quot;&gt;1.STM32가 1초간격으로 &amp;ldquo;I&amp;rsquo;m stm32 board!!&amp;rdquo;라는 문자열을 PC로 전송할때, C#윈폼으로 만든 프로그램화면에 받은 문자열을 그대로 출력하시오!&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;01.PNG&quot; data-origin-width=&quot;574&quot; data-origin-height=&quot;407&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/c2BdtE/dJMcafE4lga/CPrqzZUBysiuaThxtkIPq1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/c2BdtE/dJMcafE4lga/CPrqzZUBysiuaThxtkIPq1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/c2BdtE/dJMcafE4lga/CPrqzZUBysiuaThxtkIPq1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fc2BdtE%2FdJMcafE4lga%2FCPrqzZUBysiuaThxtkIPq1%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;574&quot; height=&quot;407&quot; data-filename=&quot;01.PNG&quot; data-origin-width=&quot;574&quot; data-origin-height=&quot;407&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;pre id=&quot;code_1764598314192&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 */
 char msg[] = &quot;I'm STM32 BOARD!!\n&quot;;
 /* USER CODE END 2 */
 /* Infinite loop */
 /* USER CODE BEGIN WHILE */
 while (1)
 {
	  //1초간격으로 지정된 문자열을 전송한다
	  HAL_UART_Transmit(&amp;amp;huart2,msg,strlen(msg),100);
	  HAL_Delay(1000);
   /* USER CODE END WHILE */
   /* USER CODE BEGIN 3 */
 }&lt;/code&gt;&lt;/pre&gt;
&lt;pre id=&quot;code_1764598397690&quot; class=&quot;csharp&quot; data-ke-language=&quot;csharp&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;private void button1_Click(object sender, EventArgs e)
        {
            //button1이 클릭된게 감지되었는데 너 뭐할래?
            serialPort1.PortName = textBox1.Text;
            serialPort1.BaudRate = 115200;

            serialPort1.Open(); //포트 개방!

            if (serialPort1.IsOpen)
            {
                //버퍼에 있는 데이터를 모조리 소멸시킨다
                serialPort1.ReadExisting();
                MessageBox.Show(&quot;접속완료!&quot;);
            }
        }

        private void serialPort1_DataReceived(object sender, System.IO.Ports.SerialDataReceivedEventArgs e)
        {
            //stm32에서 데이터가 수신되었다! 뭐할래?
            //stm32가 보낸 문자열중 종료문자가 LF일때 까지를 읽겠다!
            string data = serialPort1.ReadLine();
            richTextBox1.Text += data + &quot;\n&quot;;
        }&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #595959;&quot;&gt;2.STM32에서 PB1에 연결된 버튼을 누르면 BTN1 CLICK!이라고 전송하고 PA8에 연결된 버튼을 누르면 BTN2 CLICK이라고 전송해서 C#윈폼으로 만든 GUI에 출력한다!&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;02.PNG&quot; data-origin-width=&quot;963&quot; data-origin-height=&quot;443&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cjpHGk/dJMcabo72vP/kgSINLHVkDD3qRJirCBTu0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cjpHGk/dJMcabo72vP/kgSINLHVkDD3qRJirCBTu0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cjpHGk/dJMcabo72vP/kgSINLHVkDD3qRJirCBTu0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FcjpHGk%2FdJMcabo72vP%2FkgSINLHVkDD3qRJirCBTu0%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;963&quot; height=&quot;443&quot; data-filename=&quot;02.PNG&quot; data-origin-width=&quot;963&quot; data-origin-height=&quot;443&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;pre id=&quot;code_1764598324039&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 */
 char msg1[] = &quot;BTN1 CLICKED!\n&quot;;
 char msg2[] = &quot;BTN2 CLICKED!\n&quot;;
 /* USER CODE END 2 */
 /* Infinite loop */
 /* USER CODE BEGIN WHILE */
 while (1)
 {
	  //PB1을 누르면~
	  if(HAL_GPIO_ReadPin(GPIOB, GPIO_PIN_1) == 0){
		  HAL_UART_Transmit(&amp;amp;huart2,msg1,strlen(msg1),100);
		  HAL_Delay(300);
	  }
	  //PA8을 누르면~
	  if(HAL_GPIO_ReadPin(GPIOA, GPIO_PIN_8) == 0){
		  HAL_UART_Transmit(&amp;amp;huart2,msg2,strlen(msg2),100);
		  HAL_Delay(300);
	  }
   /* USER CODE END WHILE */
   /* USER CODE BEGIN 3 */
 }&lt;/code&gt;&lt;/pre&gt;
&lt;pre id=&quot;code_1764598411775&quot; class=&quot;csharp&quot; data-ke-language=&quot;csharp&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;private void button1_Click(object sender, EventArgs e)
        {
            //button1이 클릭된게 감지되었는데 너 뭐할래?
            serialPort1.PortName = textBox1.Text;
            serialPort1.BaudRate = 115200;

            serialPort1.Open(); //포트 개방!

            if (serialPort1.IsOpen)
            {
                //버퍼에 있는 데이터를 모조리 소멸시킨다
                serialPort1.ReadExisting();
                MessageBox.Show(&quot;접속완료!&quot;);
            }
        }

        private void serialPort1_DataReceived(object sender, System.IO.Ports.SerialDataReceivedEventArgs e)
        {
            //stm32에서 데이터가 수신되었다! 뭐할래?
            //stm32가 보낸 문자열중 종료문자가 LF일때 까지를 읽겠다!
            string data = serialPort1.ReadLine();
            richTextBox1.Text += data + &quot;\n&quot;;
        }&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #595959;&quot;&gt;3.예제2에서 PB1을 누르면 STM32내부에 있는 uint32_t num1 = 1234;의 값을 C#윈폼으로 바이너리로 전송하고, PA8을 누르면 int32_t num2 = -5678;의 값을 C#으로 전송해서 출력하시오!&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;03.PNG&quot; data-origin-width=&quot;1141&quot; data-origin-height=&quot;405&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/p4Xab/dJMcag43ap2/AcfdiYVZlFq5rB3fzcMl0k/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/p4Xab/dJMcag43ap2/AcfdiYVZlFq5rB3fzcMl0k/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/p4Xab/dJMcag43ap2/AcfdiYVZlFq5rB3fzcMl0k/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fp4Xab%2FdJMcag43ap2%2FAcfdiYVZlFq5rB3fzcMl0k%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;1141&quot; height=&quot;405&quot; data-filename=&quot;03.PNG&quot; data-origin-width=&quot;1141&quot; data-origin-height=&quot;405&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;pre id=&quot;code_1764598334609&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 */
 uint32_t num1 = 1234;
 int32_t num2 = -5678;
 /* USER CODE END 2 */
 /* Infinite loop */
 /* USER CODE BEGIN WHILE */
 while (1)
 {
	  //PB1을 누르면~
	  if(HAL_GPIO_ReadPin(GPIOB, GPIO_PIN_1) == 0){
		  HAL_UART_Transmit(&amp;amp;huart2,(uint8_t*)&amp;amp;num1,sizeof(num1),100);
		  HAL_Delay(300);
	  }
	  //PA8을 누르면~
	  if(HAL_GPIO_ReadPin(GPIOA, GPIO_PIN_8) == 0){
		  HAL_UART_Transmit(&amp;amp;huart2,(uint8_t*)&amp;amp;num2,sizeof(num2),100);
		  HAL_Delay(300);
	  }
   /* USER CODE END WHILE */
   /* USER CODE BEGIN 3 */
 }&lt;/code&gt;&lt;/pre&gt;
&lt;pre id=&quot;code_1764598421675&quot; class=&quot;csharp&quot; data-ke-language=&quot;csharp&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;private void button1_Click(object sender, EventArgs e)
        {
            //button1이 클릭된게 감지되었는데 너 뭐할래?
            serialPort1.PortName = textBox1.Text;
            serialPort1.BaudRate = 115200;

            serialPort1.Open(); //포트 개방!

            if (serialPort1.IsOpen)
            {
                //버퍼에 있는 데이터를 모조리 소멸시킨다
                serialPort1.ReadExisting();
                MessageBox.Show(&quot;접속완료!&quot;);
            }
        }

        private void serialPort1_DataReceived(object sender, System.IO.Ports.SerialDataReceivedEventArgs e)
        {
            //stm32에서 데이터가 수신되었다! 뭐할래?
            //4byte로 구성된 숫자가 날라오는 상황이 되었다!
            byte[] buff = new byte[4];
            //STM32가 보낸 데이터를 buff에 0번부터 시작해서
            //4개를 가져와서 대입하겠다!
            serialPort1.Read(buff, 0, 4);

            //buff안에 들어있는 값을 0부터 4개를 uint32로 해석!
            UInt32 num1 = BitConverter.ToUInt32(buff, 0);
            Int32 num2 = BitConverter.ToInt32(buff, 0);

            richTextBox1.Text = num1 + &quot;, &quot; + num2;
        }&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #595959;&quot;&gt;4.C#에서 ON버튼과 OFF버튼을 2개 생성하고, ON버튼을 누르면 PB3에 연결된 LED를 ON하고 OFF버튼은 OFF시키시오!(문자 &amp;lsquo;0&amp;rsquo;일때 OFF, 문자 &amp;lsquo;1&amp;rsquo;일때 ON)&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;04.PNG&quot; data-origin-width=&quot;476&quot; data-origin-height=&quot;269&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/2fjQo/dJMcaiPhEc2/UNkJWWvgmE7cqKr4kKiVi0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/2fjQo/dJMcaiPhEc2/UNkJWWvgmE7cqKr4kKiVi0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/2fjQo/dJMcaiPhEc2/UNkJWWvgmE7cqKr4kKiVi0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2F2fjQo%2FdJMcaiPhEc2%2FUNkJWWvgmE7cqKr4kKiVi0%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;476&quot; height=&quot;269&quot; data-filename=&quot;04.PNG&quot; data-origin-width=&quot;476&quot; data-origin-height=&quot;269&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;pre id=&quot;code_1764598342962&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 */
 char recv;
 /* USER CODE END 2 */
 /* Infinite loop */
 /* USER CODE BEGIN WHILE */
 while (1)
 {
	  if(HAL_UART_Receive(&amp;amp;huart2, &amp;amp;recv, 1, 500) == HAL_OK){
		  //C#에서 보낸 데이터 1개를 성공적으로 수신함!
		  if(recv == '0'){
			  //LED OFF
			  HAL_GPIO_WritePin(GPIOB, GPIO_PIN_3, 0);
		  }else if(recv == '1'){
			  //LED ON
			  HAL_GPIO_WritePin(GPIOB, GPIO_PIN_3, 1);
		  }
	  }
   /* USER CODE END WHILE */
   /* USER CODE BEGIN 3 */
 }&lt;/code&gt;&lt;/pre&gt;
&lt;pre id=&quot;code_1764598438926&quot; class=&quot;csharp&quot; data-ke-language=&quot;csharp&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;private void button1_Click(object sender, EventArgs e)
        {
            //button1이 클릭된게 감지되었는데 너 뭐할래?
            serialPort1.PortName = textBox1.Text;
            serialPort1.BaudRate = 115200;

            serialPort1.Open(); //포트 개방!

            if (serialPort1.IsOpen)
            {
                //버퍼에 있는 데이터를 모조리 소멸시킨다
                serialPort1.ReadExisting();
                MessageBox.Show(&quot;접속완료!&quot;);
            }
        }
private void button3_Click(object sender, EventArgs e)
        {
            //OFF버튼 문자 '0'전송
            if (serialPort1.IsOpen)
            {
                serialPort1.Write(&quot;0&quot;);
            }
            else
            {
                MessageBox.Show(&quot;접속을 해주세요!&quot;);
            }
        }

        private void button2_Click(object sender, EventArgs e)
        {
            //ON버튼 문자 '1'전송
            if (serialPort1.IsOpen)
            {
                serialPort1.Write(&quot;1&quot;);
            }
            else
            {
                MessageBox.Show(&quot;접속을 해주세요!&quot;);
            }
        }&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #595959;&quot;&gt;5.C#에서 ON버튼과 OFF버튼을 2개 생성하고, ON버튼을 누르면 PB3에 연결된 LED를 ON하고 OFF버튼은 OFF시키시오!(숫자 0일때 OFF, 숫자 1일때 ON)&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;05.PNG&quot; data-origin-width=&quot;451&quot; data-origin-height=&quot;279&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/daSdxm/dJMcab3JTQA/pk6HKIckWn6SpUC272mlC0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/daSdxm/dJMcab3JTQA/pk6HKIckWn6SpUC272mlC0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/daSdxm/dJMcab3JTQA/pk6HKIckWn6SpUC272mlC0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FdaSdxm%2FdJMcab3JTQA%2Fpk6HKIckWn6SpUC272mlC0%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;451&quot; height=&quot;279&quot; data-filename=&quot;05.PNG&quot; data-origin-width=&quot;451&quot; data-origin-height=&quot;279&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;pre id=&quot;code_1764598351302&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 */
 char recv;
 /* USER CODE END 2 */
 /* Infinite loop */
 /* USER CODE BEGIN WHILE */
 while (1)
 {
	  if(HAL_UART_Receive(&amp;amp;huart2, &amp;amp;recv, 1, 500) == HAL_OK){
		  //C#에서 보낸 데이터 1개를 성공적으로 수신함!
		  //녹칸다가 recv에 0을 보내면 LED OFF신호고 바로 적용하고
		  //1을 보내면 ON신호로 바로 적용가능하나,
		  //만약 C#에서 0,1 이외에 다른걸 보내게되면 문제가 생길수있음!
		  HAL_GPIO_WritePin(GPIOB, GPIO_PIN_3, recv);
	  }
   /* USER CODE END WHILE */
   /* USER CODE BEGIN 3 */
 }&lt;/code&gt;&lt;/pre&gt;
&lt;pre id=&quot;code_1764598456872&quot; class=&quot;csharp&quot; data-ke-language=&quot;csharp&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;private void button1_Click(object sender, EventArgs e)
        {
            //button1이 클릭된게 감지되었는데 너 뭐할래?
            serialPort1.PortName = textBox1.Text;
            serialPort1.BaudRate = 115200;

            serialPort1.Open(); //포트 개방!

            if (serialPort1.IsOpen)
            {
                //버퍼에 있는 데이터를 모조리 소멸시킨다
                serialPort1.ReadExisting();
                MessageBox.Show(&quot;접속완료!&quot;);
            }
        }

private void button3_Click(object sender, EventArgs e)
        {
            //OFF버튼 문자 '0'전송
            if (serialPort1.IsOpen)
            {
                //숫자 1개 전송하기!
                byte[] data = { 0 };
                serialPort1.Write(data, 0, 1);
            }
            else
            {
                MessageBox.Show(&quot;접속을 해주세요!&quot;);
            }
        }

        private void button2_Click(object sender, EventArgs e)
        {
            //ON버튼 문자 '1'전송
            if (serialPort1.IsOpen)
            {
                //숫자 1개 전송하기!
                byte[] data = { 1 };
                serialPort1.Write(data, 0, 1);
            }
            else
            {
                MessageBox.Show(&quot;접속을 해주세요!&quot;);
            }
        }&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #595959;&quot;&gt;6.PB3,PB13,PB5,PB14,PB4,PB15,PC4,PB7에 LED가 총 8개 연결되어있는데, C#윈폼에서 버튼을 이용해서 모든 LED를 제어할 수 있는 UI와 기능을 구현하시오!&lt;/span&gt;&lt;span style=&quot;color: #595959;&quot;&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #595959;&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;-문자0,1(LED1), 문자2,3(LED2), 문자4,5(LED3), 문자6,7(LED4), 문자8,9(LED5), 문자A,B(LED6), 문자C,D(LED7), 문자E,F(LED8)&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;06.PNG&quot; data-origin-width=&quot;760&quot; data-origin-height=&quot;467&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/dzK3l7/dJMcab3JTQD/onBmpJVn9g6CPaOKAx5Tl0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/dzK3l7/dJMcab3JTQD/onBmpJVn9g6CPaOKAx5Tl0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/dzK3l7/dJMcab3JTQD/onBmpJVn9g6CPaOKAx5Tl0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FdzK3l7%2FdJMcab3JTQD%2FonBmpJVn9g6CPaOKAx5Tl0%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;760&quot; height=&quot;467&quot; data-filename=&quot;06.PNG&quot; data-origin-width=&quot;760&quot; data-origin-height=&quot;467&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;pre id=&quot;code_1764598366640&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 */
 char recv;
 /* USER CODE END 2 */
 /* Infinite loop */
 /* USER CODE BEGIN WHILE */
 while (1)
 {
	  if(HAL_UART_Receive(&amp;amp;huart2, &amp;amp;recv, 1, 500) == HAL_OK){
		  if(recv == '0'){
			  HAL_GPIO_WritePin(GPIOB, GPIO_PIN_3, 0);
		  }else if(recv == '1'){
			  HAL_GPIO_WritePin(GPIOB, GPIO_PIN_3, 1);
		  }else if(recv == '2'){
			  HAL_GPIO_WritePin(GPIOB, GPIO_PIN_13, 0);
		  }else if(recv == '3'){
			  HAL_GPIO_WritePin(GPIOB, GPIO_PIN_13, 1);
		  }else if(recv == '4'){
			  HAL_GPIO_WritePin(GPIOB, GPIO_PIN_5, 0);
		  }else if(recv == '5'){
			  HAL_GPIO_WritePin(GPIOB, GPIO_PIN_5, 1);
		  }else if(recv == '6'){
			  HAL_GPIO_WritePin(GPIOB, GPIO_PIN_14, 0);
		  }else if(recv == '7'){
			  HAL_GPIO_WritePin(GPIOB, GPIO_PIN_14, 1);
		  }else if(recv == '8'){
			  HAL_GPIO_WritePin(GPIOB, GPIO_PIN_4, 0);
		  }else if(recv == '9'){
			  HAL_GPIO_WritePin(GPIOB, GPIO_PIN_4, 1);
		  }else if(recv == 'A'){
			  HAL_GPIO_WritePin(GPIOB, GPIO_PIN_15, 0);
		  }else if(recv == 'B'){
			  HAL_GPIO_WritePin(GPIOB, GPIO_PIN_15, 1);
		  }else if(recv == 'C'){
			  HAL_GPIO_WritePin(GPIOC, GPIO_PIN_4, 0);
		  }else if(recv == 'D'){
			  HAL_GPIO_WritePin(GPIOC, GPIO_PIN_4, 1);
		  }else if(recv == 'E'){
			  HAL_GPIO_WritePin(GPIOB, GPIO_PIN_7, 0);
		  }else if(recv == 'F'){
			  HAL_GPIO_WritePin(GPIOB, GPIO_PIN_7, 1);
		  }
	  }
   /* USER CODE END WHILE */
   /* USER CODE BEGIN 3 */
 }&lt;/code&gt;&lt;/pre&gt;
&lt;pre id=&quot;code_1764598471902&quot; class=&quot;csharp&quot; data-ke-language=&quot;csharp&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;private void button1_Click(object sender, EventArgs e)
        {
            //button1이 클릭된게 감지되었는데 너 뭐할래?
            serialPort1.PortName = textBox1.Text;
            serialPort1.BaudRate = 115200;

            serialPort1.Open(); //포트 개방!

            if (serialPort1.IsOpen)
            {
                //버퍼에 있는 데이터를 모조리 소멸시킨다
                serialPort1.ReadExisting();
                MessageBox.Show(&quot;접속완료!&quot;);
            }
        }

private void button3_Click(object sender, EventArgs e)
        {
            serialPort1.Write(&quot;0&quot;);
        }
        private void button2_Click(object sender, EventArgs e)
        {
            serialPort1.Write(&quot;1&quot;);
        }
        private void button5_Click(object sender, EventArgs e)
        {
            serialPort1.Write(&quot;2&quot;);
        }

        private void button4_Click(object sender, EventArgs e)
        {
            serialPort1.Write(&quot;3&quot;);
        }

        private void button7_Click(object sender, EventArgs e)
        {
            serialPort1.Write(&quot;4&quot;);
        }

        private void button6_Click(object sender, EventArgs e)
        {
            serialPort1.Write(&quot;5&quot;);
        }

        private void button9_Click(object sender, EventArgs e)
        {
            serialPort1.Write(&quot;6&quot;);
        }

        private void button8_Click(object sender, EventArgs e)
        {
            serialPort1.Write(&quot;7&quot;);
        }

        private void button16_Click(object sender, EventArgs e)
        {
            serialPort1.Write(&quot;8&quot;);
        }


        private void button17_Click(object sender, EventArgs e)
        {
            serialPort1.Write(&quot;9&quot;);
        }
        private void button14_Click(object sender, EventArgs e)
        {
            serialPort1.Write(&quot;A&quot;);
        }
        private void button15_Click(object sender, EventArgs e)
        {
            serialPort1.Write(&quot;B&quot;);
        }
        private void button12_Click(object sender, EventArgs e)
        {
            serialPort1.Write(&quot;C&quot;);
        }
        private void button13_Click(object sender, EventArgs e)
        {
            serialPort1.Write(&quot;D&quot;);
        }

        private void button10_Click(object sender, EventArgs e)
        {
            serialPort1.Write(&quot;E&quot;);
        }

        private void button11_Click(object sender, EventArgs e)
        {
            serialPort1.Write(&quot;F&quot;);
        }&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #595959;&quot;&gt;7.예제6번을 조금더 고급스럽게, 효율적으로 바꿔보시오! 추가로 모든 LED를 ON하고나 OFF하는 기능을 추가하시오!&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;07.PNG&quot; data-origin-width=&quot;516&quot; data-origin-height=&quot;335&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/sbFkj/dJMcabWXYV3/3CRRGaFVXXuZru6dJVIKR0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/sbFkj/dJMcabWXYV3/3CRRGaFVXXuZru6dJVIKR0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/sbFkj/dJMcabWXYV3/3CRRGaFVXXuZru6dJVIKR0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FsbFkj%2FdJMcabWXYV3%2F3CRRGaFVXXuZru6dJVIKR0%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;516&quot; height=&quot;335&quot; data-filename=&quot;07.PNG&quot; data-origin-width=&quot;516&quot; data-origin-height=&quot;335&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;pre id=&quot;code_1764598378242&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 */
 GPIO_TypeDef *mygpio[] = {GPIOB,GPIOB,GPIOB,GPIOB,GPIOB,GPIOB,GPIOC,GPIOB};
 uint16_t mypin[] = {GPIO_PIN_3,GPIO_PIN_13,GPIO_PIN_5,GPIO_PIN_14,GPIO_PIN_4,GPIO_PIN_15,GPIO_PIN_4,GPIO_PIN_7};
 char recv[2];
 /* USER CODE END 2 */
 /* Infinite loop */
 /* USER CODE BEGIN WHILE */
 while (1)
 {
	  if(HAL_UART_Receive(&amp;amp;huart2, recv, 2, 500) == HAL_OK){
		  //recv[0] : LED번호
		  int led_num = recv[0];
		  //recv[1] : 0이면 OFF, 1이면 ON
		  int state = recv[1];
		  if(led_num == 8){
			  //led_num이 8이면 모든 LED를 제어하는 것이다!
			  for(int i = 0;i&amp;lt;8;i++){
				  HAL_GPIO_WritePin(mygpio[i], mypin[i], state);
			  }
		  }else{
			  HAL_GPIO_WritePin(mygpio[led_num], mypin[led_num], state);
		  }
	  }
   /* USER CODE END WHILE */
   /* USER CODE BEGIN 3 */
 }&lt;/code&gt;&lt;/pre&gt;
&lt;pre id=&quot;code_1764598484997&quot; class=&quot;csharp&quot; data-ke-language=&quot;csharp&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;private void button1_Click(object sender, EventArgs e)
        {
            //button1이 클릭된게 감지되었는데 너 뭐할래?
            serialPort1.PortName = textBox1.Text;
            serialPort1.BaudRate = 115200;

            serialPort1.Open(); //포트 개방!

            if (serialPort1.IsOpen)
            {
                //버퍼에 있는 데이터를 모조리 소멸시킨다
                serialPort1.ReadExisting();
                MessageBox.Show(&quot;접속완료!&quot;);
            }
        }
private void button3_Click(object sender, EventArgs e)
        {
            byte[] data = { 0, 0 };
            serialPort1.Write(data, 0, 2);
        }
        private void button2_Click(object sender, EventArgs e)
        {
            byte[] data = { 0,1 };
            serialPort1.Write(data, 0, 2);
        }
        private void button5_Click(object sender, EventArgs e)
        {
            byte[] data = { 1, 0 };
            serialPort1.Write(data, 0, 2);
        }
        private void button4_Click(object sender, EventArgs e)
        {
            byte[] data = { 1, 1 };
            serialPort1.Write(data, 0, 2);
        }
        private void button7_Click(object sender, EventArgs e)
        {
            byte[] data = { 2, 0 };
            serialPort1.Write(data, 0, 2);
        }
        private void button6_Click(object sender, EventArgs e)
        {
            byte[] data = { 2, 1 };
            serialPort1.Write(data, 0, 2);
        }
        private void button9_Click(object sender, EventArgs e)
        {
            byte[] data = { 3, 0 };
            serialPort1.Write(data, 0, 2);
        }
        private void button8_Click(object sender, EventArgs e)
        {
            byte[] data = { 3, 1 };
            serialPort1.Write(data, 0, 2);
        }
        private void button16_Click(object sender, EventArgs e)
        {
            byte[] data = { 4, 0 };
            serialPort1.Write(data, 0, 2);
        }
        private void button17_Click(object sender, EventArgs e)
        {
            byte[] data = { 4, 1 };
            serialPort1.Write(data, 0, 2);
        }
        private void button14_Click(object sender, EventArgs e)
        {
            byte[] data = { 5, 0 };
            serialPort1.Write(data, 0, 2);
        }

        private void button15_Click(object sender, EventArgs e)
        {
            byte[] data = { 5, 1 };
            serialPort1.Write(data, 0, 2);
        }
        private void button12_Click(object sender, EventArgs e)
        {
            byte[] data = { 6, 0 };
            serialPort1.Write(data, 0, 2);
        }
        private void button13_Click(object sender, EventArgs e)
        {
            byte[] data = { 6, 1 };
            serialPort1.Write(data, 0, 2);
        }
        private void button10_Click(object sender, EventArgs e)
        {
            byte[] data = { 7, 0 };
            serialPort1.Write(data, 0, 2);
        }
        private void button11_Click(object sender, EventArgs e)
        {
            byte[] data = { 7, 1 };
            serialPort1.Write(data, 0, 2);
        }
        private void button18_Click(object sender, EventArgs e)
        {
            byte[] data = { 8, 1 };
            serialPort1.Write(data, 0, 2);
        }
        private void button19_Click(object sender, EventArgs e)
        {
            byte[] data = { 8, 0 };
            serialPort1.Write(data, 0, 2);
        }&lt;/code&gt;&lt;/pre&gt;</description>
      <category>프로그래밍/STM32</category>
      <author>덕력킹</author>
      <guid isPermaLink="true">https://bota.tistory.com/2457</guid>
      <comments>https://bota.tistory.com/2457#entry2457comment</comments>
      <pubDate>Mon, 1 Dec 2025 23:17:23 +0900</pubDate>
    </item>
    <item>
      <title>[STM32#14] DHT-11과 AHT-10(i2c) 온습도센서를 STM32f103rb nucleo에 연결해서 온도와 습도를 측정하는 방법 알아보기!(녹칸다 내맘대로 STM32)</title>
      <link>https://bota.tistory.com/2456</link>
      <description>&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;stm32.png&quot; data-origin-width=&quot;1920&quot; data-origin-height=&quot;1080&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/Na1nb/dJMcacuMn4p/seKFd7cU3K7sbKaSBBla31/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/Na1nb/dJMcacuMn4p/seKFd7cU3K7sbKaSBBla31/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/Na1nb/dJMcacuMn4p/seKFd7cU3K7sbKaSBBla31/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FNa1nb%2FdJMcacuMn4p%2FseKFd7cU3K7sbKaSBBla31%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;1920&quot; height=&quot;1080&quot; data-filename=&quot;stm32.png&quot; data-origin-width=&quot;1920&quot; data-origin-height=&quot;1080&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/live/DxaNkZ3ZAoU&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://youtube.com/live/DxaNkZ3ZAoU&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/watch?v=DxaNkZ3ZAoU&quot; data-video-thumbnail=&quot;https://scrap.kakaocdn.net/dn/zeyuQ/hyZOrbNCEq/ePcW7Z01f9DMewv490w6m0/img.jpg?width=1280&amp;amp;height=720&amp;amp;face=0_0_1280_720,https://scrap.kakaocdn.net/dn/ckF9Mv/hyZOprw16d/VgcbbiiXU1S1HfW4CmFdSK/img.jpg?width=1280&amp;amp;height=720&amp;amp;face=0_0_1280_720&quot; data-video-width=&quot;860&quot; data-video-height=&quot;484&quot; data-video-origin-width=&quot;860&quot; data-video-origin-height=&quot;484&quot; data-ke-mobilestyle=&quot;widthContent&quot; data-video-title=&quot;[STM32#14] DHT-11과 AHT-10(i2c) 온습도센서를 STM32f103rb nucleo에 연결해서 온도와 습도를 측정하는 방법 &quot; data-original-url=&quot;&quot;&gt;&lt;iframe src=&quot;https://www.youtube.com/embed/DxaNkZ3ZAoU&quot; width=&quot;860&quot; height=&quot;484&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;[STM32#14]&amp;nbsp;DHT-11과&amp;nbsp;AHT-10(i2c)&amp;nbsp;온습도센서를&amp;nbsp;STM32f103rb&amp;nbsp;nucleo에&amp;nbsp;연결해서&amp;nbsp;온도와&amp;nbsp;습도를&amp;nbsp;측정하는&amp;nbsp;방법&amp;nbsp;알아보기!(녹칸다&amp;nbsp;내맘대로&amp;nbsp;STM32) &lt;br /&gt;&lt;br /&gt;심심한녹칸다의&amp;nbsp;내맘대로&amp;nbsp;STM32시리즈이다! &lt;br /&gt;&lt;br /&gt;STM32시리즈의&amp;nbsp;모든&amp;nbsp;자료는&amp;nbsp;구글&amp;nbsp;슬라이드에&amp;nbsp;작성하고&amp;nbsp;모두에게&amp;nbsp;공유되어있음! &lt;br /&gt;&lt;a href=&quot;https://docs.google.com/presentation/d/1myA5iYbjuKsLWLqtRLKAiRfwUwvqB1d1RGjiMIIgp3I/edit?slide=id.g39a118d174f_1_193#slide=id.g39a118d174f_1_193&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://docs.google.com/presentation/d/1myA5iYbjuKsLWLqtRLKAiRfwUwvqB1d1RGjiMIIgp3I/edit?slide=id.g39a118d174f_1_193#slide=id.g39a118d174f_1_193&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;이번편은&amp;nbsp;온습도센서&amp;nbsp;2종세트&amp;nbsp;입니다~!&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;(DHT-11연결도)&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;회로도1.PNG&quot; data-origin-width=&quot;920&quot; data-origin-height=&quot;666&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bq4iQu/dJMcaf56LhK/dUpxKoAbkb5aRsz8kkFvM1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bq4iQu/dJMcaf56LhK/dUpxKoAbkb5aRsz8kkFvM1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bq4iQu/dJMcaf56LhK/dUpxKoAbkb5aRsz8kkFvM1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fbq4iQu%2FdJMcaf56LhK%2FdUpxKoAbkb5aRsz8kkFvM1%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;576&quot; height=&quot;417&quot; data-filename=&quot;회로도1.PNG&quot; data-origin-width=&quot;920&quot; data-origin-height=&quot;666&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;(DHT-11 코드)&lt;/p&gt;
&lt;pre id=&quot;code_1764150468054&quot; class=&quot;cpp&quot; data-ke-language=&quot;cpp&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;#define delay_ms HAL_Delay
#define SYS_CLOCK    64
#define SYSTICK_LOAD 63999
uint32_t millis_cnt = 0;
uint32_t millis() {
return millis_cnt;
}
uint32_t micros() {
return (millis_cnt &amp;amp; 0x3FFFFF) * 1000 + (SYSTICK_LOAD - SysTick-&amp;gt;VAL) / SYS_CLOCK;
}
void delay_us(uint32_t us) {  // 64MHz 보정
if (us &amp;gt; 1) {
  uint32_t count = us * 7 - 6;
  while (count--);
} else {
  uint32_t count = 2;
  while (count--);
}
}

union {
 uint32_t data;
 struct {
   uint8_t temp_d;
   uint8_t temp_i;
   uint8_t rh_d;
   uint8_t rh_i;
 };
} DHT;
uint8_t DHT_read () {
 uint8_t i, check_sum;
 uint32_t start;
 check_sum = 0;
 DHT.data = 0;
 GPIOC-&amp;gt;CRL = (GPIOC-&amp;gt;CRL&amp;amp;0xFFFFFF0F)|(7&amp;lt;&amp;lt;(1*4));  // Output Open-drain (Master send LOW signal)
 delay_ms(18);
 GPIOC-&amp;gt;CRL= (GPIOC-&amp;gt;CRL&amp;amp;0xFFFFFF0F)|(4&amp;lt;&amp;lt;(1*4));  // Floating input (Master send HIGH signal &amp;amp; data receive)
 start = micros();
 while (GPIOC-&amp;gt;IDR&amp;amp;(1&amp;lt;&amp;lt;1)) {
   if (micros()-start &amp;gt; 50) return 1;  // 20~40us
 }
 start = micros();
 while (!(GPIOC-&amp;gt;IDR&amp;amp;(1&amp;lt;&amp;lt;1))) {
   if (micros()-start &amp;gt; 120) return 2;  // 80us
 }
 start = micros();
 while (GPIOC-&amp;gt;IDR&amp;amp;(1&amp;lt;&amp;lt;1)) {
   if (micros()-start &amp;gt; 120) return 3;  // 80us
 }
 for (i = 0; i &amp;lt; 32; i++) {
   while (!(GPIOC-&amp;gt;IDR&amp;amp;(1&amp;lt;&amp;lt;1))); // 50us
   start = micros();
   while (GPIOC-&amp;gt;IDR&amp;amp;(1&amp;lt;&amp;lt;1));
   if (micros()-start &amp;gt; 50) DHT.data |= (0x80000000 &amp;gt;&amp;gt; i); // &quot;0&quot;=26~28us, &quot;1&quot;=70us
 }
 for (i = 0; i &amp;lt; 8; i++) {
   while (!(GPIOC-&amp;gt;IDR&amp;amp;(1&amp;lt;&amp;lt;1))); // 50us
   start = micros();
   while (GPIOC-&amp;gt;IDR&amp;amp;(1&amp;lt;&amp;lt;1));
   if (micros()-start &amp;gt; 50) check_sum |= (0x80 &amp;gt;&amp;gt; i);
 }
 if ((DHT.rh_i + DHT.rh_d + DHT.temp_i + DHT.temp_d) == check_sum) return 0;
 else return 4;
}&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;(AHT-10 연결도)&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;회로도2.PNG&quot; data-origin-width=&quot;955&quot; data-origin-height=&quot;676&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/7ilTp/dJMcaf56LhL/AKgMuLyQJwT4iCrE3hNlmk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/7ilTp/dJMcaf56LhL/AKgMuLyQJwT4iCrE3hNlmk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/7ilTp/dJMcaf56LhL/AKgMuLyQJwT4iCrE3hNlmk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2F7ilTp%2FdJMcaf56LhL%2FAKgMuLyQJwT4iCrE3hNlmk%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;586&quot; height=&quot;415&quot; data-filename=&quot;회로도2.PNG&quot; data-origin-width=&quot;955&quot; data-origin-height=&quot;676&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;(AHT-10 추가코드)&lt;/p&gt;
&lt;pre id=&quot;code_1764150501887&quot; class=&quot;cpp&quot; data-ke-language=&quot;cpp&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;uint8_t AHT10_TmpHum_Cmd[3] = {0xAC, 0x33, 0x00};
uint8_t AHT10_RX_Data[6];
uint32_t AHT10_ADC_Raw;
float AHT10_Temperature;
float AHT10_Humidity;
char str[100];

//요청
HAL_I2C_Master_Transmit(&amp;amp;hi2c1, (0x38 &amp;lt;&amp;lt; 1), AHT10_TmpHum_Cmd, 3, 10);
//수신대기
uint8_t recv[1];
while(1){
  HAL_I2C_Master_Receive(&amp;amp;hi2c1, (0x38 &amp;lt;&amp;lt; 1), recv, 6, 10);
  if(~recv[0] &amp;amp; 0x80){
      break;
  }
}
//데이터 수신
HAL_I2C_Master_Receive(&amp;amp;hi2c1, (0x38 &amp;lt;&amp;lt; 1), AHT10_RX_Data, 6, 10);
//수신데이터 출력
AHT10_ADC_Raw = (((uint32_t)AHT10_RX_Data[3] &amp;amp; 15) &amp;lt;&amp;lt; 16) | ((uint32_t)AHT10_RX_Data[4] &amp;lt;&amp;lt; 8) | AHT10_RX_Data[5];
AHT10_Temperature = (float)(AHT10_ADC_Raw * 200.00 / 1048576.00) - 50.00;

/* Convert to Relative Humidity in % */
AHT10_ADC_Raw = ((uint32_t)AHT10_RX_Data[1] &amp;lt;&amp;lt; 12) | ((uint32_t)AHT10_RX_Data[2] &amp;lt;&amp;lt; 4) | (AHT10_RX_Data[3] &amp;gt;&amp;gt; 4);
AHT10_Humidity = (float)(AHT10_ADC_Raw*100.00/1048576.00);

sprintf(str,&quot;%f, %f\r\n&quot;,AHT10_Temperature,AHT10_Humidity);
HAL_UART_Transmit(&amp;amp;huart2,str,strlen(str),100);&lt;/code&gt;&lt;/pre&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;h2 data-ke-size=&quot;size26&quot;&gt;(예제목차)&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;1.DHT-11의&amp;nbsp;기본예제를&amp;nbsp;이용해서&amp;nbsp;온도와&amp;nbsp;습도값을&amp;nbsp;usart2로&amp;nbsp;출력해서&amp;nbsp;putty에&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-filename=&quot;01.PNG&quot; data-origin-width=&quot;591&quot; data-origin-height=&quot;489&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/IpQxa/dJMcahJDd9B/lkRl2TBgD5jLkHBzMg4fIk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/IpQxa/dJMcahJDd9B/lkRl2TBgD5jLkHBzMg4fIk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/IpQxa/dJMcahJDd9B/lkRl2TBgD5jLkHBzMg4fIk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FIpQxa%2FdJMcahJDd9B%2FlkRl2TBgD5jLkHBzMg4fIk%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;591&quot; height=&quot;489&quot; data-filename=&quot;01.PNG&quot; data-origin-width=&quot;591&quot; data-origin-height=&quot;489&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;pre id=&quot;code_1764150524799&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 */
 char str[100];
 /* USER CODE END 2 */
 /* Infinite loop */
 /* USER CODE BEGIN WHILE */
 while (1)
 {
	  uint8_t error_no = DHT_read();
	  if(error_no == 0){  // 정상일 때 처리
		  float temp = 0;
		  float humi = 0;
		  temp = DHT.temp_i;
		  if (DHT.temp_d &amp;amp; 0x80) {
			  temp = -1 - temp;
		  }
		  temp += (DHT.temp_d &amp;amp; 0x0f) * 0.1;
		  humi = DHT.rh_i + DHT.rh_d * 0.1;
		  sprintf(str, &quot;T:%.1f'C H:%.1f%c\n&quot;, temp,humi,'%');
		  HAL_UART_Transmit(&amp;amp;huart2,str,strlen(str),100);
	  } else {
		  sprintf(str, &quot;Error=%d\n&quot;, error_no);
		  HAL_UART_Transmit(&amp;amp;huart2,str,strlen(str),100);
	  }
	  HAL_Delay(2000);
   /* USER CODE END WHILE */
   /* USER CODE BEGIN 3 */
 }&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;br /&gt;2.측정한 온도와 습도값을 I2C통신을 하는 1602LCD에 출력하시오!(I2C설정을 IOC에서 할 것)&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;02.PNG&quot; data-origin-width=&quot;605&quot; data-origin-height=&quot;364&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/baUYfs/dJMcagjDVjM/P9ipLISDifIG8ETx3PRh90/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/baUYfs/dJMcagjDVjM/P9ipLISDifIG8ETx3PRh90/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/baUYfs/dJMcagjDVjM/P9ipLISDifIG8ETx3PRh90/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbaUYfs%2FdJMcagjDVjM%2FP9ipLISDifIG8ETx3PRh90%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;605&quot; height=&quot;364&quot; data-filename=&quot;02.PNG&quot; data-origin-width=&quot;605&quot; data-origin-height=&quot;364&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;pre id=&quot;code_1764150534534&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 */
 char str[100];
 LCD_INIT(); //1회호출(메인루프 시작전)
 /* USER CODE END 2 */
 /* Infinite loop */
 /* USER CODE BEGIN WHILE */
 while (1)
 {
	  uint8_t error_no = DHT_read();
	  if(error_no == 0){  // 정상일 때 처리
		  float temp = 0;
		  float humi = 0;
		  temp = DHT.temp_i;
		  if (DHT.temp_d &amp;amp; 0x80) {
			  temp = -1 - temp;
		  }
		  temp += (DHT.temp_d &amp;amp; 0x0f) * 0.1;
		  humi = DHT.rh_i + DHT.rh_d * 0.1;
		  sprintf(str, &quot;T:%.1f'C H:%.1f%c&quot;, temp,humi,'%');
		  LCD_CLEAR();//원래 있던거 삭제!
		  LCD_XY(0, 0) ; LCD_PUTS(&quot;NOCKANDA DHT11&quot;);
		  LCD_XY(0, 1) ; LCD_PUTS(str);
	  }
	  HAL_Delay(2000);
   /* USER CODE END WHILE */
   /* USER CODE BEGIN 3 */
 }&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;br /&gt;3.측정한 온도와 습도를 FND모듈인 TM1637에 출력하는데, 소수점이하는 버리고 숫자 2개씩 해서 왼쪽 2칸은 온도, 오른쪽 2칸은 습도로 출력하시오!&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;03.PNG&quot; data-origin-width=&quot;634&quot; data-origin-height=&quot;360&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bACT6J/dJMcagjDVjR/oixLCOV5PtGH2JaQeWIV11/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bACT6J/dJMcagjDVjR/oixLCOV5PtGH2JaQeWIV11/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bACT6J/dJMcagjDVjR/oixLCOV5PtGH2JaQeWIV11/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbACT6J%2FdJMcagjDVjR%2FoixLCOV5PtGH2JaQeWIV11%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;634&quot; height=&quot;360&quot; data-filename=&quot;03.PNG&quot; data-origin-width=&quot;634&quot; data-origin-height=&quot;360&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;pre id=&quot;code_1764150543361&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 */
 char str[100];
 tm1637Init();
 /* USER CODE END 2 */
 /* Infinite loop */
 /* USER CODE BEGIN WHILE */
 while (1)
 {
	  uint8_t error_no = DHT_read();
	  if(error_no == 0){  // 정상일 때 처리
		  float temp = 0;
		  float humi = 0;
		  temp = DHT.temp_i;
		  if (DHT.temp_d &amp;amp; 0x80) {
			  temp = -1 - temp;
		  }
		  temp += (DHT.temp_d &amp;amp; 0x0f) * 0.1;
		  humi = DHT.rh_i + DHT.rh_d * 0.1;
		  int data = ((int)temp * 100) + (int)humi;
		  tm1637DisplayDecimalTrim(data,0);
	  }
	  HAL_Delay(2000);
   /* USER CODE END WHILE */
   /* USER CODE BEGIN 3 */
 }&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;br /&gt;4.STM32가&amp;nbsp;DHT11의&amp;nbsp;온습도값을&amp;nbsp;2초간격으로&amp;nbsp;측정한다!&amp;nbsp;그리고&amp;nbsp;FND모듈에&amp;nbsp;1초간격으로&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-filename=&quot;04.PNG&quot; data-origin-width=&quot;556&quot; data-origin-height=&quot;602&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cz3oBZ/dJMcabbzbuh/cziCXjXepxJ33BNmBMAnP1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cz3oBZ/dJMcabbzbuh/cziCXjXepxJ33BNmBMAnP1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cz3oBZ/dJMcabbzbuh/cziCXjXepxJ33BNmBMAnP1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fcz3oBZ%2FdJMcabbzbuh%2FcziCXjXepxJ33BNmBMAnP1%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;556&quot; height=&quot;602&quot; data-filename=&quot;04.PNG&quot; data-origin-width=&quot;556&quot; data-origin-height=&quot;602&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;pre id=&quot;code_1764150552992&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 */
 char str[100];
 tm1637Init();
 uint32_t t1 = 0; //온습도값 2초
 uint32_t t2 = 0; //FND출력 1초
 float temp = 0;
 float humi = 0;
 uint8_t sw = 0; //0이면 온도, 1이면 습도
 /* USER CODE END 2 */
 /* Infinite loop */
 /* USER CODE BEGIN WHILE */
 while (1)
 {
	  //2초간격으로 temp와 humi에 값을 입력만 한다!
	  if(HAL_GetTick() - t1 &amp;gt;= 2000){
		  t1 = HAL_GetTick();
		  uint8_t error_no = DHT_read();
		  if(error_no == 0){  // 정상일 때 처리
			  temp = DHT.temp_i;
			  if (DHT.temp_d &amp;amp; 0x80) {
				  temp = -1 - temp;
			  }
			  temp += (DHT.temp_d &amp;amp; 0x0f) * 0.1;
			  humi = DHT.rh_i + DHT.rh_d * 0.1;
		  }
	  }
	  //1초간격으로 온도와 습도를 번갈아가면서 출력한다!
	  if(HAL_GetTick() - t2 &amp;gt;= 1000){
		  t2 = HAL_GetTick();
		  if(sw == 0){
			  //온도
			  tm1637DisplayDecimalTrim((int)(temp*100),1);
			  tm1637SetRawSegment(3,0b00111001);
			  sw = 1;
		  }else if(sw == 1){
			  //습도
			  tm1637DisplayDecimalTrim((int)(humi*100),1);
			  tm1637SetRawSegment(3,0b01001001);
			  sw = 0;
		  }
	  }
   /* USER CODE END WHILE */
   /* USER CODE BEGIN 3 */
 }&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;br /&gt;5.이번에는&amp;nbsp;AHT-10온습도센서값을&amp;nbsp;usart2통신으로&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-filename=&quot;05.PNG&quot; data-origin-width=&quot;561&quot; data-origin-height=&quot;575&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cebmXU/dJMcagjDVjS/vtKBXCbZNKjIMJ2cWlA4T1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cebmXU/dJMcagjDVjS/vtKBXCbZNKjIMJ2cWlA4T1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cebmXU/dJMcagjDVjS/vtKBXCbZNKjIMJ2cWlA4T1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FcebmXU%2FdJMcagjDVjS%2FvtKBXCbZNKjIMJ2cWlA4T1%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;561&quot; height=&quot;575&quot; data-filename=&quot;05.PNG&quot; data-origin-width=&quot;561&quot; data-origin-height=&quot;575&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;pre id=&quot;code_1764150592480&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 */
 uint8_t AHT10_TmpHum_Cmd[3] = {0xAC, 0x33, 0x00};
 uint8_t AHT10_RX_Data[6];
 uint32_t AHT10_ADC_Raw;
 float AHT10_Temperature;
 float AHT10_Humidity;
 char str[100];
 /* USER CODE END 2 */
 /* Infinite loop */
 /* USER CODE BEGIN WHILE */
 while (1)
 {
	  //요청
	  HAL_I2C_Master_Transmit(&amp;amp;hi2c1, (0x38 &amp;lt;&amp;lt; 1), AHT10_TmpHum_Cmd, 3, 10);
	  //수신대기
	  uint8_t recv[1];
	  while(1){
		  HAL_I2C_Master_Receive(&amp;amp;hi2c1, (0x38 &amp;lt;&amp;lt; 1), recv, 6, 10);
		  if(~recv[0] &amp;amp; 0x80){
			  break;
		  }
	  }
	  //데이터 수신
	  HAL_I2C_Master_Receive(&amp;amp;hi2c1, (0x38 &amp;lt;&amp;lt; 1), AHT10_RX_Data, 6, 10);
	  //수신데이터 출력
	  AHT10_ADC_Raw = (((uint32_t)AHT10_RX_Data[3] &amp;amp; 15) &amp;lt;&amp;lt; 16) | ((uint32_t)AHT10_RX_Data[4] &amp;lt;&amp;lt; 8) | AHT10_RX_Data[5];
	  AHT10_Temperature = (float)(AHT10_ADC_Raw * 200.00 / 1048576.00) - 50.00;
	  /* Convert to Relative Humidity in % */
	  AHT10_ADC_Raw = ((uint32_t)AHT10_RX_Data[1] &amp;lt;&amp;lt; 12) | ((uint32_t)AHT10_RX_Data[2] &amp;lt;&amp;lt; 4) | (AHT10_RX_Data[3] &amp;gt;&amp;gt; 4);
	  AHT10_Humidity = (float)(AHT10_ADC_Raw*100.00/1048576.00);
	  sprintf(str,&quot;TEMP:%.2f'C, HUMI:%.2f%c\n&quot;,AHT10_Temperature,AHT10_Humidity,'%');
	  HAL_UART_Transmit(&amp;amp;huart2,str,strlen(str),100);
	  HAL_Delay(1000);
   /* USER CODE END WHILE */
   /* USER CODE BEGIN 3 */
 }&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;br /&gt;6.AHT-10에서&amp;nbsp;측정한&amp;nbsp;온도와&amp;nbsp;습도값을&amp;nbsp;1602LCD화면에&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-filename=&quot;06.PNG&quot; data-origin-width=&quot;569&quot; data-origin-height=&quot;376&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/zSraL/dJMcacByeYy/CuPjfIHKTEVpyltwdFQ0TK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/zSraL/dJMcacByeYy/CuPjfIHKTEVpyltwdFQ0TK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/zSraL/dJMcacByeYy/CuPjfIHKTEVpyltwdFQ0TK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FzSraL%2FdJMcacByeYy%2FCuPjfIHKTEVpyltwdFQ0TK%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;569&quot; height=&quot;376&quot; data-filename=&quot;06.PNG&quot; data-origin-width=&quot;569&quot; data-origin-height=&quot;376&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;pre id=&quot;code_1764150602027&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 */
 uint8_t AHT10_TmpHum_Cmd[3] = {0xAC, 0x33, 0x00};
 uint8_t AHT10_RX_Data[6];
 uint32_t AHT10_ADC_Raw;
 float AHT10_Temperature;
 float AHT10_Humidity;
 char str[100];
 LCD_INIT();
 /* USER CODE END 2 */
 /* Infinite loop */
 /* USER CODE BEGIN WHILE */
 while (1)
 {
	  //요청
	  HAL_I2C_Master_Transmit(&amp;amp;hi2c1, (0x38 &amp;lt;&amp;lt; 1), AHT10_TmpHum_Cmd, 3, 10);
	  //수신대기
	  uint8_t recv[1];
	  while(1){
		  HAL_I2C_Master_Receive(&amp;amp;hi2c1, (0x38 &amp;lt;&amp;lt; 1), recv, 6, 10);
		  if(~recv[0] &amp;amp; 0x80){
			  break;
		  }
	  }
	  //데이터 수신
	  HAL_I2C_Master_Receive(&amp;amp;hi2c1, (0x38 &amp;lt;&amp;lt; 1), AHT10_RX_Data, 6, 10);
	  //수신데이터 출력
	  AHT10_ADC_Raw = (((uint32_t)AHT10_RX_Data[3] &amp;amp; 15) &amp;lt;&amp;lt; 16) | ((uint32_t)AHT10_RX_Data[4] &amp;lt;&amp;lt; 8) | AHT10_RX_Data[5];
	  AHT10_Temperature = (float)(AHT10_ADC_Raw * 200.00 / 1048576.00) - 50.00;
	  /* Convert to Relative Humidity in % */
	  AHT10_ADC_Raw = ((uint32_t)AHT10_RX_Data[1] &amp;lt;&amp;lt; 12) | ((uint32_t)AHT10_RX_Data[2] &amp;lt;&amp;lt; 4) | (AHT10_RX_Data[3] &amp;gt;&amp;gt; 4);
	  AHT10_Humidity = (float)(AHT10_ADC_Raw*100.00/1048576.00);
	  sprintf(str, &quot;T:%.1f'C H:%.1f%c&quot;, AHT10_Temperature,AHT10_Humidity,'%');
	  LCD_CLEAR();//원래 있던거 삭제!
	  LCD_XY(0, 0) ; LCD_PUTS(&quot;NOCKANDA AHT-10!&quot;);
	  LCD_XY(0, 1) ; LCD_PUTS(str);
	  HAL_Delay(1000);
   /* USER CODE END WHILE */
   /* USER CODE BEGIN 3 */
 }&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;br /&gt;7.녹칸다의&amp;nbsp;STM32쉴드에서&amp;nbsp;링모양으로&amp;nbsp;배치된&amp;nbsp;LED가&amp;nbsp;8개있는데,&amp;nbsp;12시방향을&amp;nbsp;시작으로&amp;nbsp;해서&amp;nbsp;온도&amp;nbsp;3도당&amp;nbsp;LED가&amp;nbsp;1개씩&amp;nbsp;켜지도록&amp;nbsp;하시오!&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;07.PNG&quot; data-origin-width=&quot;594&quot; data-origin-height=&quot;333&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cjKjq9/dJMcagjDVjV/oxkCy6WIkUnnzRvkxI0K4k/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cjKjq9/dJMcagjDVjV/oxkCy6WIkUnnzRvkxI0K4k/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cjKjq9/dJMcagjDVjV/oxkCy6WIkUnnzRvkxI0K4k/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FcjKjq9%2FdJMcagjDVjV%2FoxkCy6WIkUnnzRvkxI0K4k%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;594&quot; height=&quot;333&quot; data-filename=&quot;07.PNG&quot; data-origin-width=&quot;594&quot; data-origin-height=&quot;333&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;pre id=&quot;code_1764150611941&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 */
 uint8_t AHT10_TmpHum_Cmd[3] = {0xAC, 0x33, 0x00};
 uint8_t AHT10_RX_Data[6];
 uint32_t AHT10_ADC_Raw;
 float AHT10_Temperature;
 float AHT10_Humidity;
 char str[100];
 LCD_INIT();
 GPIO_TypeDef *mygpio[] = {GPIOB,GPIOB,GPIOB,GPIOB,GPIOB,GPIOB,GPIOC,GPIOB};
 uint16_t mypin[] = {GPIO_PIN_3,GPIO_PIN_13,GPIO_PIN_5,GPIO_PIN_14,GPIO_PIN_4,GPIO_PIN_15,GPIO_PIN_4,GPIO_PIN_7};
 /* USER CODE END 2 */
 /* Infinite loop */
 /* USER CODE BEGIN WHILE */
 while (1)
 {
	  //요청
	  HAL_I2C_Master_Transmit(&amp;amp;hi2c1, (0x38 &amp;lt;&amp;lt; 1), AHT10_TmpHum_Cmd, 3, 10);
	  //수신대기
	  uint8_t recv[1];
	  while(1){
		  HAL_I2C_Master_Receive(&amp;amp;hi2c1, (0x38 &amp;lt;&amp;lt; 1), recv, 6, 10);
		  if(~recv[0] &amp;amp; 0x80){
			  break;
		  }
	  }
	  //데이터 수신
	  HAL_I2C_Master_Receive(&amp;amp;hi2c1, (0x38 &amp;lt;&amp;lt; 1), AHT10_RX_Data, 6, 10);
	  //수신데이터 출력
	  AHT10_ADC_Raw = (((uint32_t)AHT10_RX_Data[3] &amp;amp; 15) &amp;lt;&amp;lt; 16) | ((uint32_t)AHT10_RX_Data[4] &amp;lt;&amp;lt; 8) | AHT10_RX_Data[5];
	  AHT10_Temperature = (float)(AHT10_ADC_Raw * 200.00 / 1048576.00) - 50.00;
	  /* Convert to Relative Humidity in % */
	  AHT10_ADC_Raw = ((uint32_t)AHT10_RX_Data[1] &amp;lt;&amp;lt; 12) | ((uint32_t)AHT10_RX_Data[2] &amp;lt;&amp;lt; 4) | (AHT10_RX_Data[3] &amp;gt;&amp;gt; 4);
	  AHT10_Humidity = (float)(AHT10_ADC_Raw*100.00/1048576.00);
	  sprintf(str, &quot;T:%.1f'C H:%.1f%c&quot;, AHT10_Temperature,AHT10_Humidity,'%');
	  LCD_CLEAR();//원래 있던거 삭제!
	  LCD_XY(0, 0) ; LCD_PUTS(&quot;NOCKANDA AHT-10!&quot;);
	  LCD_XY(0, 1) ; LCD_PUTS(str);
	  int last_index =  (int)(AHT10_Temperature/3);
	  if(last_index &amp;gt; 7) last_index = 7;
	  for(int i =0;i&amp;lt;8;i++){
		  if(i &amp;lt;= last_index){
			  HAL_GPIO_WritePin(mygpio[i], mypin[i], 1);
		  }else{
			  HAL_GPIO_WritePin(mygpio[i], mypin[i], 0);
		  }
	  }
	  HAL_Delay(1000);
   /* USER CODE END WHILE */
   /* USER CODE BEGIN 3 */
 }&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;br /&gt;8.DHT-11값과&amp;nbsp;AHT-10의값을&amp;nbsp;둘다&amp;nbsp;측정해서&amp;nbsp;1602LCD에&amp;nbsp;출력하시오!&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;08.PNG&quot; data-origin-width=&quot;896&quot; data-origin-height=&quot;534&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/dnm4mG/dJMcabvRYu4/NKBJWyPlvcbOfBYWhKTTqk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/dnm4mG/dJMcabvRYu4/NKBJWyPlvcbOfBYWhKTTqk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/dnm4mG/dJMcabvRYu4/NKBJWyPlvcbOfBYWhKTTqk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fdnm4mG%2FdJMcabvRYu4%2FNKBJWyPlvcbOfBYWhKTTqk%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;548&quot; height=&quot;327&quot; data-filename=&quot;08.PNG&quot; data-origin-width=&quot;896&quot; data-origin-height=&quot;534&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;pre id=&quot;code_1764150624332&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 */
 uint8_t AHT10_TmpHum_Cmd[3] = {0xAC, 0x33, 0x00};
 uint8_t AHT10_RX_Data[6];
 uint32_t AHT10_ADC_Raw;
 float AHT10_Temperature;
 float AHT10_Humidity;
 char str[100];
 LCD_INIT();
 float temp = 0;
 float humi = 0;
 /* USER CODE END 2 */
 /* Infinite loop */
 /* USER CODE BEGIN WHILE */
 while (1)
 {
	  //요청
	  HAL_I2C_Master_Transmit(&amp;amp;hi2c1, (0x38 &amp;lt;&amp;lt; 1), AHT10_TmpHum_Cmd, 3, 10);
	  //수신대기
	  uint8_t recv[1];
	  while(1){
		  HAL_I2C_Master_Receive(&amp;amp;hi2c1, (0x38 &amp;lt;&amp;lt; 1), recv, 6, 10);
		  if(~recv[0] &amp;amp; 0x80){
			  break;
		  }
	  }
	  //데이터 수신
	  HAL_I2C_Master_Receive(&amp;amp;hi2c1, (0x38 &amp;lt;&amp;lt; 1), AHT10_RX_Data, 6, 10);


	  //수신데이터 출력
	  AHT10_ADC_Raw = (((uint32_t)AHT10_RX_Data[3] &amp;amp; 15) &amp;lt;&amp;lt; 16) | ((uint32_t)AHT10_RX_Data[4] &amp;lt;&amp;lt; 8) | AHT10_RX_Data[5];
	  AHT10_Temperature = (float)(AHT10_ADC_Raw * 200.00 / 1048576.00) - 50.00;
	  /* Convert to Relative Humidity in % */
	  AHT10_ADC_Raw = ((uint32_t)AHT10_RX_Data[1] &amp;lt;&amp;lt; 12) | ((uint32_t)AHT10_RX_Data[2] &amp;lt;&amp;lt; 4) | (AHT10_RX_Data[3] &amp;gt;&amp;gt; 4);
	  AHT10_Humidity = (float)(AHT10_ADC_Raw*100.00/1048576.00);
	  uint8_t error_no = DHT_read();
	  if(error_no == 0){  // 정상일 때 처리
		  temp = DHT.temp_i;
		  if (DHT.temp_d &amp;amp; 0x80) {
			  temp = -1 - temp;
		  }
		  temp += (DHT.temp_d &amp;amp; 0x0f) * 0.1;
		  humi = DHT.rh_i + DHT.rh_d * 0.1;
	  }
	  LCD_CLEAR();//원래 있던거 삭제!
	  sprintf(str, &quot;T:%.1f'C H:%.1f%c&quot;, temp,humi,'%');
	  LCD_XY(0, 0) ; LCD_PUTS(str);
	  sprintf(str, &quot;T:%.1f'C H:%.1f%c&quot;, AHT10_Temperature,AHT10_Humidity,'%');
	  LCD_XY(0, 1) ; LCD_PUTS(str);
	  HAL_Delay(1000);
   /* USER CODE END WHILE */
   /* USER CODE BEGIN 3 */
 }&lt;/code&gt;&lt;/pre&gt;</description>
      <category>프로그래밍/STM32</category>
      <author>덕력킹</author>
      <guid isPermaLink="true">https://bota.tistory.com/2456</guid>
      <comments>https://bota.tistory.com/2456#entry2456comment</comments>
      <pubDate>Wed, 26 Nov 2025 18:52:57 +0900</pubDate>
    </item>
    <item>
      <title>[STM32#13] FND모듈인 TM1637을 STM32f103rb nucleo에 연결해서 디스플레이에 다양한 센서값 출력하는 방법 알아보기!(녹칸다 내맘대로 STM32)</title>
      <link>https://bota.tistory.com/2455</link>
      <description>&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;maxresdefault.jpg&quot; data-origin-width=&quot;1280&quot; data-origin-height=&quot;720&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bMMPWe/dJMcahCP8Pk/KrQtIqBR9E1YUrKWRTab7K/img.jpg&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bMMPWe/dJMcahCP8Pk/KrQtIqBR9E1YUrKWRTab7K/img.jpg&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bMMPWe/dJMcahCP8Pk/KrQtIqBR9E1YUrKWRTab7K/img.jpg&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbMMPWe%2FdJMcahCP8Pk%2FKrQtIqBR9E1YUrKWRTab7K%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;1280&quot; height=&quot;720&quot; data-filename=&quot;maxresdefault.jpg&quot; data-origin-width=&quot;1280&quot; data-origin-height=&quot;720&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/live/Iz-1TaHBU88&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://youtube.com/live/Iz-1TaHBU88&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/watch?v=Iz-1TaHBU88&quot; data-video-thumbnail=&quot;https://scrap.kakaocdn.net/dn/brkRfg/hyZOGTGuy6/GvLopaqBFXITpYHXxmTxJ1/img.jpg?width=1280&amp;amp;height=720&amp;amp;face=0_0_1280_720,https://scrap.kakaocdn.net/dn/exc3kM/hyZODJqdJ6/wTIs5Ejq3PZXmOi8ByKwV1/img.jpg?width=1280&amp;amp;height=720&amp;amp;face=0_0_1280_720,https://scrap.kakaocdn.net/dn/iGnBP/hyZNJR1xHo/J29Eq0px8XtpiTBsDwNSu1/img.jpg?width=1280&amp;amp;height=720&amp;amp;face=0_0_1280_720&quot; data-video-width=&quot;860&quot; data-video-height=&quot;484&quot; data-video-origin-width=&quot;860&quot; data-video-origin-height=&quot;484&quot; data-ke-mobilestyle=&quot;widthContent&quot; data-video-title=&quot;[STM32#13] FND모듈인 TM1637을 STM32f103rb nucleo에 연결해서 디스플레이에 다양한 센서값 출력하는 방법 &quot; data-original-url=&quot;&quot;&gt;&lt;iframe src=&quot;https://www.youtube.com/embed/Iz-1TaHBU88&quot; width=&quot;860&quot; height=&quot;484&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;[STM32#13]&amp;nbsp;FND모듈인&amp;nbsp;TM1637을&amp;nbsp;STM32f103rb&amp;nbsp;nucleo에&amp;nbsp;연결해서&amp;nbsp;디스플레이에&amp;nbsp;다양한&amp;nbsp;센서값&amp;nbsp;출력하는&amp;nbsp;방법&amp;nbsp;알아보기!(녹칸다&amp;nbsp;내맘대로&amp;nbsp;STM32) &lt;br /&gt;&lt;br /&gt;심심한녹칸다의&amp;nbsp;내맘대로&amp;nbsp;STM32시리즈이다! &lt;br /&gt;&lt;br /&gt;STM32시리즈의&amp;nbsp;모든&amp;nbsp;자료는&amp;nbsp;구글&amp;nbsp;슬라이드에&amp;nbsp;작성하고&amp;nbsp;모두에게&amp;nbsp;공유되어있음! &lt;br /&gt;&lt;a href=&quot;https://docs.google.com/presentation/d/1myA5iYbjuKsLWLqtRLKAiRfwUwvqB1d1RGjiMIIgp3I/edit?slide=id.g3a8e99eac0a_1_8#slide=id.g3a8e99eac0a_1_8&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://docs.google.com/presentation/d/1myA5iYbjuKsLWLqtRLKAiRfwUwvqB1d1RGjiMIIgp3I/edit?slide=id.g3a8e99eac0a_1_8#slide=id.g3a8e99eac0a_1_8&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;이번편은&amp;nbsp;FND모듈인&amp;nbsp;TM1637입니다~!&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;회로도.PNG&quot; data-origin-width=&quot;914&quot; data-origin-height=&quot;538&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/zAenp/dJMcafZkmVl/p8CUUlTDmbPcE7QHfYSk1K/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/zAenp/dJMcafZkmVl/p8CUUlTDmbPcE7QHfYSk1K/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/zAenp/dJMcafZkmVl/p8CUUlTDmbPcE7QHfYSk1K/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FzAenp%2FdJMcafZkmVl%2Fp8CUUlTDmbPcE7QHfYSk1K%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;525&quot; height=&quot;309&quot; data-filename=&quot;회로도.PNG&quot; data-origin-width=&quot;914&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;(필수추가코드)&lt;/p&gt;
&lt;pre id=&quot;code_1763993449574&quot; class=&quot;cpp&quot; data-ke-language=&quot;cpp&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;#define delay_ms HAL_Delay
#define SYS_CLOCK    64
#define SYSTICK_LOAD 63999
uint32_t millis_cnt = 0;
uint32_t millis() {
 return millis_cnt;
}
uint32_t micros() {
 return (millis_cnt &amp;amp; 0x3FFFFF) * 1000 + (SYSTICK_LOAD - SysTick-&amp;gt;VAL) / SYS_CLOCK;
}
void delay_us(uint32_t us) {  // 64MHz 보정
 if (us &amp;gt; 1) {
   uint32_t count = us * 7 - 6;
   while (count--);
 } else {
   uint32_t count = 2;
   while (count--);
 }
}
// TM1637 7세그먼트 숫자 코드 매핑
const char segmentMap[] = {
   0x3f, 0x06, 0x5b, 0x4f,
   0x66, 0x6d, 0x7d, 0x07,
   0x7f, 0x6f, 0x77, 0x7c,
   0x39, 0x5e, 0x79, 0x71,
   0x00
};
// GPIOB 클럭 활성화 매크로
#define PORTB_CLK_ENABLE() (RCC-&amp;gt;APB2ENR |= RCC_APB2ENR_IOPBEN)
// PB8, PB9 핀 사용 (GPIOB)
// PB8 = CLK, PB9 = DIO
// CLK와 DIO 핀 제어 함수
static inline void _tm1637ClkHigh(void) { GPIOB-&amp;gt;BSRR = (1 &amp;lt;&amp;lt; 8); } // CLK HIGH
static inline void _tm1637ClkLow(void)  { GPIOB-&amp;gt;BRR = (1 &amp;lt;&amp;lt; 8); }  // CLK LOW
static inline void _tm1637DioHigh(void) { GPIOB-&amp;gt;BSRR = (1 &amp;lt;&amp;lt; 9); } // DIO HIGH
static inline void _tm1637DioLow(void)  { GPIOB-&amp;gt;BRR = (1 &amp;lt;&amp;lt; 9); }  // DIO LOW
// 마이크로초 단위 딜레이
void _tm1637DelayUsec(unsigned int i)
{
	delay_us(i); // 사용자 정의 delay_us 함수 사용
}
// TM1637 초기화 함수 (GPIO 출력 설정)
void tm1637Init(void)
{
   PORTB_CLK_ENABLE(); // GPIOB 클럭 활성화
   // GPIOB CRH 초기화 (PB8, PB9 출력 2MHz Push-Pull)
   GPIOB-&amp;gt;CRH &amp;amp;= ~((0xF &amp;lt;&amp;lt; 0) | (0xF &amp;lt;&amp;lt; 4)); // 해당 비트 클리어
   GPIOB-&amp;gt;CRH |= (0x2 &amp;lt;&amp;lt; 0); // PB8: MODE=10(출력 2MHz), CNF=00(Push-Pull)
   GPIOB-&amp;gt;CRH |= (0x2 &amp;lt;&amp;lt; 4); // PB9: MODE=10(출력 2MHz), CNF=00(Push-Pull)
   tm1637SetBrightness(8); // 밝기 최대
}

// TM1637 시작 신호
void _tm1637Start(void)
{
   _tm1637ClkHigh();
   _tm1637DioHigh();
   _tm1637DelayUsec(20);
   _tm1637DioLow(); // START 조건: DIO LOW
}
// TM1637 종료 신호
void _tm1637Stop(void)
{
   _tm1637ClkLow();
   _tm1637DelayUsec(20);
   _tm1637DioLow();
   _tm1637DelayUsec(20);
   _tm1637ClkHigh();
   _tm1637DelayUsec(20);
   _tm1637DioHigh(); // STOP 조건: DIO HIGH
}
// TM1637 ACK 무시 (결과 확인용)
void _tm1637ReadResult(void)
{
   _tm1637ClkLow();
   _tm1637DelayUsec(50);
   // DIO 상태 확인, ACK 처리 (여기서는 실제 확인 없이 무시)
   _tm1637ClkHigh();
   _tm1637DelayUsec(20);
   _tm1637ClkLow();
}

// TM1637 1바이트 전송
void _tm1637WriteByte(unsigned char b)
{
   for (int i = 0; i &amp;lt; 8; ++i) {
       _tm1637ClkLow();
       if (b &amp;amp; 0x01) {
           _tm1637DioHigh();
       } else {
           _tm1637DioLow();
       }
       _tm1637DelayUsec(30);
       b &amp;gt;&amp;gt;= 1; // 다음 비트로 이동
       _tm1637ClkHigh();
       _tm1637DelayUsec(30);
   }
}
// 밝기 설정 (0~8, 0 = 꺼짐)
void tm1637SetBrightness(char brightness)
{
   _tm1637Start();
   _tm1637WriteByte(0x87 + brightness); // 밝기 명령어
   _tm1637ReadResult();
   _tm1637Stop();
}

// 4자리 10진수 표시 (displaySeparator=1이면 3번째 자리 점 켬)
void tm1637DisplayDecimal(int v, int displaySeparator)
{
   unsigned char digitArr[4];
   int isNegative = 0;
   if (v &amp;lt; 0) {
       isNegative = 1;
       v = -v;
   }
   // 숫자를 segmentMap으로 변환
   for (int i = 0; i &amp;lt; 4; ++i) {
       digitArr[i] = segmentMap[v % 10];
       if (i == 2 &amp;amp;&amp;amp; displaySeparator) {
           digitArr[i] |= 1 &amp;lt;&amp;lt; 7; // 점(DP) 켬
       }
       v /= 10;
   }
   // 음수 표시
   if (isNegative) {
       digitArr[3] = 0x40; // '-' 표시
   }
   // TM1637에 데이터 전송
   _tm1637Start();
   _tm1637WriteByte(0x40); // 자동 주소 증가 모드
   _tm1637ReadResult();
   _tm1637Stop();
   _tm1637Start();
   _tm1637WriteByte(0xc0); // 시작 주소 0
   _tm1637ReadResult();
   for (int i = 0; i &amp;lt; 4; ++i) {
       _tm1637WriteByte(digitArr[3 - i]); // 3-&amp;gt;0 순서로 전송
       _tm1637ReadResult();
   }
   _tm1637Stop();
}

// 4자리 10진수 표시 (앞자리 0 제거, displaySeparator=1이면 점 켬)
void tm1637DisplayDecimalTrim(int v, int displaySeparator)
{
   unsigned char digitArr[4];
   int isNegative = 0;
   if (v &amp;lt; 0) {
       isNegative = 1;
       v = -v;
   }
   // 숫자를 segmentMap으로 변환
   for (int i = 0; i &amp;lt; 4; ++i) {
       digitArr[i] = segmentMap[v % 10];
       if (i == 2 &amp;amp;&amp;amp; displaySeparator) {
           digitArr[i] |= 1 &amp;lt;&amp;lt; 7; // 점(DP) 켬
       }
       v /= 10;
   }
   // 앞자리 0 제거 (공백 처리)
   int leadingZero = 1;
   for (int i = 3; i &amp;gt;= 0; --i) {
       if (digitArr[i] != segmentMap[0] || i == 0) {
           leadingZero = 0;
       }
       if (leadingZero &amp;amp;&amp;amp; digitArr[i] == segmentMap[0]) {
           digitArr[i] = 0x00; // 공백
       }
   }

   // 음수 표시
   if (isNegative) {
       digitArr[3] = 0x40; // '-'
   }
   // TM1637에 데이터 전송
   _tm1637Start();
   _tm1637WriteByte(0x40); // 자동 주소 증가 모드
   _tm1637ReadResult();
   _tm1637Stop();
   _tm1637Start();
   _tm1637WriteByte(0xC0); // 시작 주소 0
   _tm1637ReadResult();
   for (int i = 0; i &amp;lt; 4; ++i) {
       _tm1637WriteByte(digitArr[3 - i]); // 3-&amp;gt;0 순서로 전송
       _tm1637ReadResult();
   }
   _tm1637Stop();
}
void tm1637SetRawSegment(uint8_t position, uint8_t segData)
{
   // 주소 범위 보호
   if (position &amp;gt; 3) return;
   _tm1637Start();
   _tm1637WriteByte(0x40);      // 데이터 입력 모드
   _tm1637ReadResult();
   _tm1637Stop();
   _tm1637Start();
   _tm1637WriteByte(0xC0 + position);   // 자리 선택
   _tm1637ReadResult();
   _tm1637WriteByte(segData);           // 세그먼트 데이터 전송
   _tm1637ReadResult();
   _tm1637Stop();
}&lt;/code&gt;&lt;/pre&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;p data-ke-size=&quot;size16&quot;&gt;1.참고코드를&amp;nbsp;프로젝트에&amp;nbsp;반영하고&amp;nbsp;TM1637화면에&amp;nbsp;123이라고&amp;nbsp;출력하는데&amp;nbsp;2종류의&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-filename=&quot;1-1.PNG&quot; data-origin-width=&quot;432&quot; data-origin-height=&quot;229&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bO8Ytr/dJMcafLNeGT/43E4sJk1wbkMx5KkjakIK0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bO8Ytr/dJMcafLNeGT/43E4sJk1wbkMx5KkjakIK0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bO8Ytr/dJMcafLNeGT/43E4sJk1wbkMx5KkjakIK0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbO8Ytr%2FdJMcafLNeGT%2F43E4sJk1wbkMx5KkjakIK0%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;432&quot; height=&quot;229&quot; data-filename=&quot;1-1.PNG&quot; data-origin-width=&quot;432&quot; data-origin-height=&quot;229&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;pre id=&quot;code_1763993469015&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 */
 //TM1637 시작~
 tm1637Init();
 //원하는 숫자 출력
 tm1637DisplayDecimal(123, 0);  //0123
 //tm1637DisplayDecimalTrim(123, 0);  //_123
 /* USER CODE END 2 */&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;1-2.PNG&quot; data-origin-width=&quot;415&quot; data-origin-height=&quot;224&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/lNUV6/dJMcafLNeGW/QbKGmY8kFJDkHUoHkJFkVk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/lNUV6/dJMcafLNeGW/QbKGmY8kFJDkHUoHkJFkVk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/lNUV6/dJMcafLNeGW/QbKGmY8kFJDkHUoHkJFkVk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FlNUV6%2FdJMcafLNeGW%2FQbKGmY8kFJDkHUoHkJFkVk%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;415&quot; height=&quot;224&quot; data-filename=&quot;1-2.PNG&quot; data-origin-width=&quot;415&quot; data-origin-height=&quot;224&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;pre id=&quot;code_1763993479762&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 */
 //TM1637 시작~
 tm1637Init();
 //원하는 숫자 출력
 //tm1637DisplayDecimal(123, 0);  //0123
 tm1637DisplayDecimalTrim(123, 0);  //_123
 /* USER CODE END 2 */&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;br /&gt;2.TM1637에&amp;nbsp;0.1초&amp;nbsp;간격으로&amp;nbsp;1씩&amp;nbsp;업카운트를&amp;nbsp;하는데,&amp;nbsp;tm1637DisplayDecimalTrim함수를&amp;nbsp;이용해서&amp;nbsp;출력하시오!(0~9999까지만&amp;nbsp;출력하시오)&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;2.PNG&quot; data-origin-width=&quot;471&quot; data-origin-height=&quot;296&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/31Ly9/dJMcadf5I8B/nMeJaUCOLQjUWbrx85pCbK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/31Ly9/dJMcadf5I8B/nMeJaUCOLQjUWbrx85pCbK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/31Ly9/dJMcadf5I8B/nMeJaUCOLQjUWbrx85pCbK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2F31Ly9%2FdJMcadf5I8B%2FnMeJaUCOLQjUWbrx85pCbK%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;471&quot; height=&quot;296&quot; data-filename=&quot;2.PNG&quot; data-origin-width=&quot;471&quot; data-origin-height=&quot;296&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;pre id=&quot;code_1763993518888&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 */
 //TM1637 시작~
 tm1637Init();
 int cnt = 0;
 /* USER CODE END 2 */
 /* Infinite loop */
 /* USER CODE BEGIN WHILE */
 while (1)
 {
	  tm1637DisplayDecimalTrim(cnt, 0);
	  cnt++;
	  //cnt가 9999를 초과하면 다시 0으로 초기화한다!
	  if(cnt &amp;gt; 9999) cnt = 0;
	  HAL_Delay(100);
   /* USER CODE END WHILE */
   /* USER CODE BEGIN 3 */
 }&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;br /&gt;3.예제2와&amp;nbsp;동일한데,&amp;nbsp;0부터&amp;nbsp;출발해서&amp;nbsp;음의&amp;nbsp;방향으로&amp;nbsp;1씩&amp;nbsp;다운카운트를하고&amp;nbsp;(-999&amp;nbsp;~&amp;nbsp;0)&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;3.PNG&quot; data-origin-width=&quot;432&quot; data-origin-height=&quot;260&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/ZBjGk/dJMcai9xoFS/cwKCW6g7C0IfINeerdxiJ0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/ZBjGk/dJMcai9xoFS/cwKCW6g7C0IfINeerdxiJ0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/ZBjGk/dJMcai9xoFS/cwKCW6g7C0IfINeerdxiJ0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FZBjGk%2FdJMcai9xoFS%2FcwKCW6g7C0IfINeerdxiJ0%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;432&quot; height=&quot;260&quot; data-filename=&quot;3.PNG&quot; data-origin-width=&quot;432&quot; data-origin-height=&quot;260&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;pre id=&quot;code_1763993537017&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 */
 //TM1637 시작~
 tm1637Init();
 int cnt = 0;
 /* USER CODE END 2 */
 /* Infinite loop */
 /* USER CODE BEGIN WHILE */
 while (1)
 {
	  tm1637DisplayDecimalTrim(cnt, 0);
	  cnt--;
	  //cnt가 -999를 미만이 되면 0으로 초기화한다!
	  if(cnt &amp;lt; -999) cnt = 0;
	  HAL_Delay(100);
   /* USER CODE END WHILE */
   /* USER CODE BEGIN 3 */
 }&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;br /&gt;4.tm1637SetRawSegment함수를&amp;nbsp;이용해서&amp;nbsp;왼쪽부터&amp;nbsp;1번&amp;nbsp;FND는&amp;nbsp;0b0001자리만&amp;nbsp;ON하고,&amp;nbsp;2번은&amp;nbsp;0b0010만&amp;nbsp;ON하고,&amp;nbsp;3번은&amp;nbsp;0b0100만&amp;nbsp;ON하고&amp;nbsp;4번은&amp;nbsp;0b1000만&amp;nbsp;ON하도록&amp;nbsp;하시오!&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;4.PNG&quot; data-origin-width=&quot;472&quot; data-origin-height=&quot;272&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/vwzo7/dJMcai2L4G2/7PCWN4zSJ5gkjMBZIxdZhk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/vwzo7/dJMcai2L4G2/7PCWN4zSJ5gkjMBZIxdZhk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/vwzo7/dJMcai2L4G2/7PCWN4zSJ5gkjMBZIxdZhk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fvwzo7%2FdJMcai2L4G2%2F7PCWN4zSJ5gkjMBZIxdZhk%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;472&quot; height=&quot;272&quot; data-filename=&quot;4.PNG&quot; data-origin-width=&quot;472&quot; data-origin-height=&quot;272&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;pre id=&quot;code_1763993581897&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 */
 //TM1637 시작~
 tm1637Init();
 tm1637SetRawSegment(0,0b0001);
 tm1637SetRawSegment(1,0b0010);
 tm1637SetRawSegment(2,0b0100);
 tm1637SetRawSegment(3,0b1000);
 /* USER CODE END 2 */&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;br /&gt;5.이번에는&amp;nbsp;숫자패턴은&amp;nbsp;출력하지말고&amp;nbsp;4개의&amp;nbsp;FND의&amp;nbsp;소수점을&amp;nbsp;표시하는&amp;nbsp;dp만&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-filename=&quot;5.PNG&quot; data-origin-width=&quot;482&quot; data-origin-height=&quot;262&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/3o3U5/dJMcagcR3zD/z1eKkGoW1BdD6XxKaKUN7k/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/3o3U5/dJMcagcR3zD/z1eKkGoW1BdD6XxKaKUN7k/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/3o3U5/dJMcagcR3zD/z1eKkGoW1BdD6XxKaKUN7k/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2F3o3U5%2FdJMcagcR3zD%2Fz1eKkGoW1BdD6XxKaKUN7k%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;482&quot; height=&quot;262&quot; data-filename=&quot;5.PNG&quot; data-origin-width=&quot;482&quot; data-origin-height=&quot;262&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;pre id=&quot;code_1763993645159&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 */
 //TM1637 시작~
 tm1637Init();
 tm1637SetRawSegment(0,0b10000000);
 tm1637SetRawSegment(1,0b10000000);
 tm1637SetRawSegment(2,0b10000000);
 tm1637SetRawSegment(3,0b10000000);
 /* USER CODE END 2 */&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;br /&gt;6.TM1637에&amp;nbsp;붙은&amp;nbsp;FND4개의&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;pre id=&quot;code_1763993661075&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 */
 int nockanda_i = 0;
 uint8_t nockanda_array[][4] = {
	  {0b00000001, 0b00000000, 0b00000000, 0b00000000},
	  {0b00000000, 0b00000001, 0b00000000, 0b00000000},
	  {0b00000000, 0b00000000, 0b00000001, 0b00000000},
	  {0b00000000, 0b00000000, 0b00000000, 0b00000001},
	  {0b00000000, 0b00000000, 0b00000000, 0b00000010},
	  {0b00000000, 0b00000000, 0b00000000, 0b00000100},
	  {0b00000000, 0b00000000, 0b00000000, 0b00001000},
	  {0b00000000, 0b00000000, 0b00001000, 0b00000000},
	  {0b00000000, 0b00001000, 0b00000000, 0b00000000},
	  {0b00001000, 0b00000000, 0b00000000, 0b00000000},
	  {0b00010000, 0b00000000, 0b00000000, 0b00000000},
	  {0b00100000, 0b00000000, 0b00000000, 0b00000000}
 };
 //TM1637 시작~
 tm1637Init();
 /* USER CODE END 2 */
 /* Infinite loop */
 /* USER CODE BEGIN WHILE */
 while (1)
 {
	  for(int j = 0;j&amp;lt;4;j++){
		  tm1637SetRawSegment(j,nockanda_array[nockanda_i][j]);
	  }
	  nockanda_i++;
	  if(nockanda_i == 12) nockanda_i = 0;
	  HAL_Delay(100);
   /* USER CODE END WHILE */
   /* USER CODE BEGIN 3 */
 }&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;br /&gt;7.PB1버튼을&amp;nbsp;누르면&amp;nbsp;예제6이&amp;nbsp;시계방향으로&amp;nbsp;회전하고,&amp;nbsp;PA8을&amp;nbsp;누르면&amp;nbsp;반시계방향으로&amp;nbsp;회전하도록&amp;nbsp;하시오!&lt;/p&gt;
&lt;pre id=&quot;code_1763993678124&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 */
 int nockanda_i = 0;
 uint8_t nockanda_array[][4] = {
	  {0b00000001, 0b00000000, 0b00000000, 0b00000000},
	  {0b00000000, 0b00000001, 0b00000000, 0b00000000},
	  {0b00000000, 0b00000000, 0b00000001, 0b00000000},
	  {0b00000000, 0b00000000, 0b00000000, 0b00000001},
	  {0b00000000, 0b00000000, 0b00000000, 0b00000010},
	  {0b00000000, 0b00000000, 0b00000000, 0b00000100},
	  {0b00000000, 0b00000000, 0b00000000, 0b00001000},
	  {0b00000000, 0b00000000, 0b00001000, 0b00000000},
	  {0b00000000, 0b00001000, 0b00000000, 0b00000000},
	  {0b00001000, 0b00000000, 0b00000000, 0b00000000},
	  {0b00010000, 0b00000000, 0b00000000, 0b00000000},
	  {0b00100000, 0b00000000, 0b00000000, 0b00000000}
 };
 int direct = 0; //0이면 시계 1이면 반시계
 //TM1637 시작~
 tm1637Init();
 /* USER CODE END 2 */
 /* Infinite loop */
 /* USER CODE BEGIN WHILE */
 while (1)
 {
	  if(HAL_GPIO_ReadPin(GPIOB, GPIO_PIN_1) == 0){
		  direct = 0;
	  }
	  if(HAL_GPIO_ReadPin(GPIOA, GPIO_PIN_8) == 0){
		  direct = 1;
	  }
	  for(int j = 0;j&amp;lt;4;j++){
		  tm1637SetRawSegment(j,nockanda_array[nockanda_i][j]);
	  }
	  if(direct == 0){
		  nockanda_i++;
		  if(nockanda_i == 12) nockanda_i = 0;
	  }else if(direct == 1){
		  nockanda_i--;
		  if(nockanda_i == -1) nockanda_i = 11;
	  }
	  HAL_Delay(100);
   /* USER CODE END WHILE */
   /* USER CODE BEGIN 3 */
 }&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;br /&gt;8.PB1버튼을&amp;nbsp;누르면&amp;nbsp;1씩&amp;nbsp;업카운트되고,&amp;nbsp;PA8버튼을&amp;nbsp;누르면&amp;nbsp;1씩&amp;nbsp;다운카운트&amp;nbsp;되고,&amp;nbsp;PB2를&amp;nbsp;누르면&amp;nbsp;0으로&amp;nbsp;초기화하시오!&lt;/p&gt;
&lt;pre id=&quot;code_1763993688164&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 */
 //TM1637 시작~
 tm1637Init();
 int cnt = 0;
 //초기값 출력하기~
 tm1637DisplayDecimalTrim(cnt,0);
 /* USER CODE END 2 */
 /* Infinite loop */
 /* USER CODE BEGIN WHILE */
 while (1)
 {
	  if(HAL_GPIO_ReadPin(GPIOB, GPIO_PIN_1) == 0){
		  cnt++;
		  tm1637DisplayDecimalTrim(cnt,0);
		  HAL_Delay(300);//채터링방지
	  }
	  if(HAL_GPIO_ReadPin(GPIOA, GPIO_PIN_8) == 0){
		  cnt--;
		  tm1637DisplayDecimalTrim(cnt,0);
		  HAL_Delay(300);//채터링방지
	  }
	  if(HAL_GPIO_ReadPin(GPIOB, GPIO_PIN_2) == 0){
		  cnt = 0;
		  tm1637DisplayDecimalTrim(cnt,0);
		  HAL_Delay(300);//채터링방지
	  }
   /* USER CODE END WHILE */
   /* USER CODE BEGIN 3 */
 }&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;br /&gt;9.PA11과&amp;nbsp;PA12에&amp;nbsp;연결된&amp;nbsp;로터리&amp;nbsp;엔코더를&amp;nbsp;시계방향으로&amp;nbsp;돌리면&amp;nbsp;1씩&amp;nbsp;업카운트,&amp;nbsp;반시계방향으로&amp;nbsp;돌리면&amp;nbsp;1씩&amp;nbsp;다운카운트,&amp;nbsp;PC7이&amp;nbsp;로터리엔코더&amp;nbsp;스위치인데&amp;nbsp;누르면&amp;nbsp;0으로&amp;nbsp;초기화하시오!&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;9.PNG&quot; data-origin-width=&quot;536&quot; data-origin-height=&quot;306&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/c3nrl8/dJMcaiIturf/SkfVFYJ0Fa85Okd3uDqJJ1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/c3nrl8/dJMcaiIturf/SkfVFYJ0Fa85Okd3uDqJJ1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/c3nrl8/dJMcaiIturf/SkfVFYJ0Fa85Okd3uDqJJ1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fc3nrl8%2FdJMcaiIturf%2FSkfVFYJ0Fa85Okd3uDqJJ1%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;536&quot; height=&quot;306&quot; data-filename=&quot;9.PNG&quot; data-origin-width=&quot;536&quot; data-origin-height=&quot;306&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;pre id=&quot;code_1763993699969&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 */
 //TM1637 시작~
 tm1637Init();
 int cnt = 0;
 //초기값 출력하기~
 tm1637DisplayDecimalTrim(cnt,0);
 uint8_t old_rot_A = 0;
 /* USER CODE END 2 */
 /* Infinite loop */
 /* USER CODE BEGIN WHILE */
 while (1)
 {
	  if(HAL_GPIO_ReadPin(GPIOC, GPIO_PIN_7) == 0){
		  cnt = 0;
		  tm1637DisplayDecimalTrim(cnt,0);
	  }
	  uint8_t now_rot_A = HAL_GPIO_ReadPin(GPIOA, GPIO_PIN_11);
	  if(now_rot_A == 1 &amp;amp;&amp;amp; old_rot_A == 0){
		  uint8_t now_rot_B = HAL_GPIO_ReadPin(GPIOA, GPIO_PIN_12);
		  if(now_rot_B){
			  //CCW
			  cnt--;
		  }else{
			  //CW
			  cnt++;
		  }
		  tm1637DisplayDecimalTrim(cnt,0);
	  }
	  old_rot_A = now_rot_A;
	  HAL_Delay(1);
   /* USER CODE END WHILE */
   /* USER CODE BEGIN 3 */
 }&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;br /&gt;10.PA0에 연결된 12BIT 가변저항값을 TM1637에 그대로 출력하시오!&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;10.PNG&quot; data-origin-width=&quot;592&quot; data-origin-height=&quot;321&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/xUl7E/dJMcaajpOQ0/QoCJiRxDHP5VGfR9SV9rK1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/xUl7E/dJMcaajpOQ0/QoCJiRxDHP5VGfR9SV9rK1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/xUl7E/dJMcaajpOQ0/QoCJiRxDHP5VGfR9SV9rK1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FxUl7E%2FdJMcaajpOQ0%2FQoCJiRxDHP5VGfR9SV9rK1%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;592&quot; height=&quot;321&quot; data-filename=&quot;10.PNG&quot; data-origin-width=&quot;592&quot; data-origin-height=&quot;321&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;pre id=&quot;code_1763993729466&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 */
 //TM1637 시작~
 tm1637Init();
 HAL_ADC_Start(&amp;amp;hadc1); //딱 한번만 호출
 uint16_t adc_value0 = 0;
 /* Infinite loop */
 /* USER CODE BEGIN WHILE */
 while (1)
 {
	  //측정할때마다 호출
	  if(HAL_ADC_PollForConversion(&amp;amp;hadc1, 10) == HAL_OK)
	  {
		  // 값 처리
		  adc_value0 = HAL_ADC_GetValue(&amp;amp;hadc1); //0~4095
		  tm1637DisplayDecimalTrim(adc_value0,0);
	  }
	  HAL_Delay(100);
   /* USER CODE END WHILE */
   /* USER CODE BEGIN 3 */
 }&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;br /&gt;11.예제10에서&amp;nbsp;측정한&amp;nbsp;가변저항값을&amp;nbsp;전압으로&amp;nbsp;환산해서&amp;nbsp;TM1637에&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-filename=&quot;11.PNG&quot; data-origin-width=&quot;536&quot; data-origin-height=&quot;316&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cOItCi/dJMcai9xoIi/YxsZjsujZ9BQwnP8nPSkf1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cOItCi/dJMcai9xoIi/YxsZjsujZ9BQwnP8nPSkf1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cOItCi/dJMcai9xoIi/YxsZjsujZ9BQwnP8nPSkf1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FcOItCi%2FdJMcai9xoIi%2FYxsZjsujZ9BQwnP8nPSkf1%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;536&quot; height=&quot;316&quot; data-filename=&quot;11.PNG&quot; data-origin-width=&quot;536&quot; data-origin-height=&quot;316&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;pre id=&quot;code_1763993756395&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 */
 //TM1637 시작~
 tm1637Init();
 HAL_ADC_Start(&amp;amp;hadc1); //딱 한번만 호출
 uint16_t adc_value0 = 0;
 /* Infinite loop */
 /* USER CODE BEGIN WHILE */
 while (1)
 {
	  //측정할때마다 호출
	  if(HAL_ADC_PollForConversion(&amp;amp;hadc1, 10) == HAL_OK)
	  {
		  // 값 처리
		  adc_value0 = HAL_ADC_GetValue(&amp;amp;hadc1); //0~4095
		  float voltage = 3.3*adc_value0/4095;
		  voltage = voltage * 100; //FND에 출력하기 위한 용도
		  tm1637DisplayDecimalTrim((int)voltage, 1);
	  }
	  HAL_Delay(100);
   /* USER CODE END WHILE */
   /* USER CODE BEGIN 3 */
 }&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;br /&gt;12.예제6번과&amp;nbsp;예제9번을&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_1763993795512&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 */
 int nockanda_i = 0;
 uint8_t nockanda_array[][4] = {
	  {0b00000001, 0b00000000, 0b00000000, 0b00000000},
	  {0b00000000, 0b00000001, 0b00000000, 0b00000000},
	  {0b00000000, 0b00000000, 0b00000001, 0b00000000},
	  {0b00000000, 0b00000000, 0b00000000, 0b00000001},
	  {0b00000000, 0b00000000, 0b00000000, 0b00000010},
	  {0b00000000, 0b00000000, 0b00000000, 0b00000100},
	  {0b00000000, 0b00000000, 0b00000000, 0b00001000},
	  {0b00000000, 0b00000000, 0b00001000, 0b00000000},
	  {0b00000000, 0b00001000, 0b00000000, 0b00000000},
	  {0b00001000, 0b00000000, 0b00000000, 0b00000000},
	  {0b00010000, 0b00000000, 0b00000000, 0b00000000},
	  {0b00100000, 0b00000000, 0b00000000, 0b00000000}
 };
 //초기패턴출력
 for(int j = 0;j&amp;lt;4;j++){
	  tm1637SetRawSegment(j,nockanda_array[0][j]);
 }
 //TM1637 시작~
 tm1637Init();
 uint8_t old_rot_A = 0;
/* USER CODE END 2 */
 /* Infinite loop */
 /* USER CODE BEGIN WHILE */

 while (1)
 {
	  uint8_t now_rot_A = HAL_GPIO_ReadPin(GPIOA, GPIO_PIN_11);
	  if(now_rot_A == 1 &amp;amp;&amp;amp; old_rot_A == 0){
		  uint8_t now_rot_B = HAL_GPIO_ReadPin(GPIOA, GPIO_PIN_12);
		  if(now_rot_B){
			  //CCW
			  //패턴이 반시계방향으로 1씩 움직인다
			  nockanda_i--;
			  if(nockanda_i == -1) nockanda_i = 11;
		  }else{
			  //CW
			  //패턴이 시계방향으로 1씩 움직인다
			  nockanda_i++;
			  if(nockanda_i == 12) nockanda_i = 0;
		  }
		  for(int j = 0;j&amp;lt;4;j++){
			  tm1637SetRawSegment(j,nockanda_array[nockanda_i][j]);
		  }
	  }
	  old_rot_A = now_rot_A;
	  HAL_Delay(1);
   /* USER CODE END WHILE */
   /* USER CODE BEGIN 3 */
 }&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;br /&gt;13.로터리엔코더를 돌려서 0~10의 범위로 값을 결정하고, 스위치를 누르면 녹칸다쿠쿠가 밥을 짓기 시작하는데, 지정된 시간에서 1초마다 1씩 다운카운트된다! 시간이 0이되면 TM1637에 빙글빙글 돌아가는 패턴이 나오도록하시오! 밥이 다되면 부저에서 도레미파솔라시도가 LED가 빙글빙글 돌아가는 타이밍에 맞춰서 출력되도록 하시오!&amp;nbsp;&lt;/p&gt;
&lt;pre id=&quot;code_1763993820078&quot; class=&quot;cpp&quot; data-ke-language=&quot;cpp&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;static void Tone(uint32_t Frequency)
{
   TIM3-&amp;gt;ARR = (1000000UL / Frequency) - 1;
   TIM3-&amp;gt;CCR3 = (TIM3-&amp;gt;ARR &amp;gt;&amp;gt; 1);
}
static void noTone()
{
   TIM3-&amp;gt;CCR3 = 0;
}
#define NOTE_C6  1047
#define NOTE_D6  1175
#define NOTE_E6  1319
#define NOTE_F6  1397
#define NOTE_G6  1568
#define NOTE_A6  1760
#define NOTE_B6  1976
#define NOTE_C7  2093
uint8_t melody_i = 0;
uint16_t melody[] = {NOTE_C6,NOTE_D6,NOTE_E6,NOTE_F6,NOTE_G6,NOTE_A6,NOTE_B6,NOTE_C7};

/* USER CODE BEGIN 2 */
 int nockanda_i = 0;
 uint8_t nockanda_array[][4] = {
	  {0b00000001, 0b00000000, 0b00000000, 0b00000000},
	  {0b00000000, 0b00000001, 0b00000000, 0b00000000},
	  {0b00000000, 0b00000000, 0b00000001, 0b00000000},
	  {0b00000000, 0b00000000, 0b00000000, 0b00000001},
	  {0b00000000, 0b00000000, 0b00000000, 0b00000010},
	  {0b00000000, 0b00000000, 0b00000000, 0b00000100},
	  {0b00000000, 0b00000000, 0b00000000, 0b00001000},
	  {0b00000000, 0b00000000, 0b00001000, 0b00000000},
	  {0b00000000, 0b00001000, 0b00000000, 0b00000000},
	  {0b00001000, 0b00000000, 0b00000000, 0b00000000},
	  {0b00010000, 0b00000000, 0b00000000, 0b00000000},
	  {0b00100000, 0b00000000, 0b00000000, 0b00000000}
 };
 //초기패턴출력
 for(int j = 0;j&amp;lt;4;j++){
	  tm1637SetRawSegment(j,nockanda_array[0][j]);
 }
 //TM1637 시작~
 tm1637Init();
 uint8_t old_rot_A = 0;
 HAL_TIM_PWM_Start(&amp;amp;htim3,TIM_CHANNEL_3);
 uint8_t task_run = 0;
 uint8_t task_run2 = 0;
 uint32_t t = 0;

 int nockanda_cnt = 0;
 /* USER CODE END 2 */
 /* Infinite loop */
 /* USER CODE BEGIN WHILE */
 while (1)
 {
	  if(task_run2){
		  if(HAL_GetTick() - t &amp;gt;= 100){
			  t = HAL_GetTick();
			  for(int j = 0;j&amp;lt;4;j++){
				  tm1637SetRawSegment(j,nockanda_array[nockanda_i][j]);
			  }
			  nockanda_i++;
			  if(nockanda_i == 12) nockanda_i = 0;
			  //부저 재생하기
			  Tone(melody[melody_i]);
			  melody_i++;
			  if(melody_i &amp;gt; 8) melody_i = 0;
		  }
	  }
	  if(task_run){
		  //task가 시작되면 1000밀리초 간격마다 걸리는 조건문
		  if(HAL_GetTick() - t &amp;gt;= 1000){
			  t = HAL_GetTick();
			  nockanda_cnt--;
			  tm1637DisplayDecimalTrim(nockanda_cnt,0);
			  if(nockanda_cnt == 0){
				  //탈출조건
				  task_run2 = 1;//LED빙글빙글 돌리는 작업
				  melody_i = 0;
				  HAL_GPIO_WritePin(GPIOC, GPIO_PIN_2, 1); //부저ON
				  task_run = 0;
			  }
		  }
	  }

	  if(HAL_GPIO_ReadPin(GPIOC, GPIO_PIN_7) == 0){
		  //카운트가 0보다 크면서 task가 실행중이 아니라면~
		  if(nockanda_cnt &amp;gt; 0 &amp;amp;&amp;amp; task_run == 0 &amp;amp;&amp;amp; task_run2 == 0){
			  task_run = 1;
		  }
		  task_run2 = 0; //스위치 누르면 종료
		  HAL_GPIO_WritePin(GPIOC, GPIO_PIN_2, 0); //부저종료
		  HAL_Delay(300);
	  }
	  if(task_run2 == 0){
		  uint8_t now_rot_A = HAL_GPIO_ReadPin(GPIOA, GPIO_PIN_11);
		  if(now_rot_A == 1 &amp;amp;&amp;amp; old_rot_A == 0){
			  uint8_t now_rot_B = HAL_GPIO_ReadPin(GPIOA, GPIO_PIN_12);
			  if(now_rot_B){
				  //CCW
				  nockanda_cnt--;
				  if(nockanda_cnt &amp;lt; 0) nockanda_cnt = 0;
			  }else{
				  //CW
				  nockanda_cnt++;
				  if(nockanda_cnt &amp;gt; 10) nockanda_cnt = 10;
			  }
			  tm1637DisplayDecimalTrim(nockanda_cnt,0);
		  }
		  old_rot_A = now_rot_A;
		  HAL_Delay(1);
	  }
   /* USER CODE END WHILE */
   /* USER CODE BEGIN 3 */
 }&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>프로그래밍/STM32</category>
      <author>덕력킹</author>
      <guid isPermaLink="true">https://bota.tistory.com/2455</guid>
      <comments>https://bota.tistory.com/2455#entry2455comment</comments>
      <pubDate>Mon, 24 Nov 2025 23:17:01 +0900</pubDate>
    </item>
    <item>
      <title>[STM32#12] I2C버전의 1602LCD를 STM32f103rb nucleo에 연결해서 디스플레이에 다양한 센서값 출력하는 방법 알아보기!(녹칸다 내맘대로 STM32)</title>
      <link>https://bota.tistory.com/2454</link>
      <description>&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;stm32.png&quot; data-origin-width=&quot;1920&quot; data-origin-height=&quot;1080&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/wWjAu/dJMcafdVt6n/PrF3fWJvXW1iJJ8dg7mucK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/wWjAu/dJMcafdVt6n/PrF3fWJvXW1iJJ8dg7mucK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/wWjAu/dJMcafdVt6n/PrF3fWJvXW1iJJ8dg7mucK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FwWjAu%2FdJMcafdVt6n%2FPrF3fWJvXW1iJJ8dg7mucK%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;1920&quot; height=&quot;1080&quot; data-filename=&quot;stm32.png&quot; data-origin-width=&quot;1920&quot; data-origin-height=&quot;1080&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/live/64BtomW26XQ&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://youtube.com/live/64BtomW26XQ&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/watch?v=64BtomW26XQ&quot; data-video-thumbnail=&quot;https://scrap.kakaocdn.net/dn/dwqEmq/hyZNT8y3QH/KRfRoTluyZGKSZkBlheWx0/img.jpg?width=1280&amp;amp;height=720&amp;amp;face=0_0_1280_720,https://scrap.kakaocdn.net/dn/chZKqN/hyZOgA3z2a/Q2gmbfRSlcTsMquOkj35v1/img.jpg?width=1280&amp;amp;height=720&amp;amp;face=0_0_1280_720&quot; data-video-width=&quot;860&quot; data-video-height=&quot;484&quot; data-video-origin-width=&quot;860&quot; data-video-origin-height=&quot;484&quot; data-ke-mobilestyle=&quot;widthContent&quot; data-video-title=&quot;[STM32#12] I2C버전의 1602LCD를 STM32f103rb nucleo에 연결해서 디스플레이에 다양한 센서값 출력하는 방법&quot; data-original-url=&quot;&quot;&gt;&lt;iframe src=&quot;https://www.youtube.com/embed/64BtomW26XQ&quot; width=&quot;860&quot; height=&quot;484&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;[STM32#12]&amp;nbsp;I2C버전의&amp;nbsp;1602LCD를&amp;nbsp;STM32f103rb&amp;nbsp;nucleo에&amp;nbsp;연결해서&amp;nbsp;디스플레이에&amp;nbsp;다양한&amp;nbsp;센서값&amp;nbsp;출력하는&amp;nbsp;방법&amp;nbsp;알아보기!(녹칸다&amp;nbsp;내맘대로&amp;nbsp;STM32) &lt;br /&gt;&lt;br /&gt;심심한녹칸다의&amp;nbsp;내맘대로&amp;nbsp;STM32시리즈이다! &lt;br /&gt;&lt;br /&gt;STM32시리즈의&amp;nbsp;모든&amp;nbsp;자료는&amp;nbsp;구글&amp;nbsp;슬라이드에&amp;nbsp;작성하고&amp;nbsp;모두에게&amp;nbsp;공유되어있음! &lt;br /&gt;&lt;a href=&quot;https://docs.google.com/presentation/d/1myA5iYbjuKsLWLqtRLKAiRfwUwvqB1d1RGjiMIIgp3I/edit?slide=id.g399b448d9bb_1_162#slide=id.g399b448d9bb_1_162&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://docs.google.com/presentation/d/1myA5iYbjuKsLWLqtRLKAiRfwUwvqB1d1RGjiMIIgp3I/edit?slide=id.g399b448d9bb_1_162#slide=id.g399b448d9bb_1_162&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;이번편은&amp;nbsp;1602LCD입니다~!&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;(i2c 설정)&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;회로도.PNG&quot; data-origin-width=&quot;948&quot; data-origin-height=&quot;628&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/IuIEK/dJMcaaDGwBs/6OyrcOuSkRbghzOywc0hVk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/IuIEK/dJMcaaDGwBs/6OyrcOuSkRbghzOywc0hVk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/IuIEK/dJMcaaDGwBs/6OyrcOuSkRbghzOywc0hVk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FIuIEK%2FdJMcaaDGwBs%2F6OyrcOuSkRbghzOywc0hVk%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;948&quot; height=&quot;628&quot; data-filename=&quot;회로도.PNG&quot; data-origin-width=&quot;948&quot; data-origin-height=&quot;628&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;(연결도)&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;회로도2.PNG&quot; data-origin-width=&quot;1161&quot; data-origin-height=&quot;547&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/csHVJp/dJMcahv2KnF/6JhtFafFWX1wuEgMKIjUHK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/csHVJp/dJMcahv2KnF/6JhtFafFWX1wuEgMKIjUHK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/csHVJp/dJMcahv2KnF/6JhtFafFWX1wuEgMKIjUHK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FcsHVJp%2FdJMcahv2KnF%2F6JhtFafFWX1wuEgMKIjUHK%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;1161&quot; height=&quot;547&quot; data-filename=&quot;회로도2.PNG&quot; data-origin-width=&quot;1161&quot; data-origin-height=&quot;547&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;(LCD사용을 위한 기본 추가 코드)&lt;/p&gt;
&lt;pre id=&quot;code_1763548293616&quot; class=&quot;cpp&quot; data-ke-language=&quot;cpp&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;#define delay_ms HAL_Delay
#define SYS_CLOCK    64
#define SYSTICK_LOAD 63999
uint32_t millis_cnt = 0;
uint32_t millis() {
 return millis_cnt;
}
uint32_t micros() {
 return (millis_cnt &amp;amp; 0x3FFFFF) * 1000 + (SYSTICK_LOAD - SysTick-&amp;gt;VAL) / SYS_CLOCK;
}
void delay_us(uint32_t us) {  // 64MHz 보정
 if (us &amp;gt; 1) {
   uint32_t count = us * 7 - 6;
   while (count--);
 } else {
   uint32_t count = 2;
   while (count--);
 }
}
#define ADDRESS   0x27&amp;lt;&amp;lt;1
#define RS1_EN1   0x05
#define RS1_EN0   0x01
#define RS0_EN1   0x04
#define RS0_EN0   0x00
#define BackLight 0x08
// RS-Q0 / RW-Q1 / EN-Q2 / BackLight-Q3 / D4-Q4 / D5-Q5 / D6-Q6 / D7-Q7
void LCD_DATA(uint8_t data) {
 uint8_t temp=(data &amp;amp; 0xF0)|RS1_EN1|BackLight;
 while(HAL_I2C_Master_Transmit(&amp;amp;hi2c1, ADDRESS, &amp;amp;temp, 1, 1000)!=HAL_OK);
 temp=(data &amp;amp; 0xF0)|RS1_EN0|BackLight;
 while(HAL_I2C_Master_Transmit(&amp;amp;hi2c1, ADDRESS, &amp;amp;temp, 1, 1000)!=HAL_OK);
 delay_us(4);
 temp=((data &amp;lt;&amp;lt; 4) &amp;amp; 0xF0)|RS1_EN1|BackLight;
 while(HAL_I2C_Master_Transmit(&amp;amp;hi2c1, ADDRESS, &amp;amp;temp, 1, 1000)!=HAL_OK);
 temp = ((data &amp;lt;&amp;lt; 4) &amp;amp; 0xF0)|RS1_EN0|BackLight;
 while(HAL_I2C_Master_Transmit(&amp;amp;hi2c1, ADDRESS, &amp;amp;temp, 1, 1000)!=HAL_OK);
 delay_us(50);
}
void LCD_CMD(uint8_t cmd) {
 uint8_t temp=(cmd &amp;amp; 0xF0)|RS0_EN1|BackLight;
 while(HAL_I2C_Master_Transmit(&amp;amp;hi2c1, ADDRESS, &amp;amp;temp, 1, 1000)!=HAL_OK);
 temp=(cmd &amp;amp; 0xF0)|RS0_EN0|BackLight;
 while(HAL_I2C_Master_Transmit(&amp;amp;hi2c1, ADDRESS, &amp;amp;temp, 1, 1000)!=HAL_OK);
 delay_us(4);
 temp=((cmd &amp;lt;&amp;lt; 4) &amp;amp; 0xF0)|RS0_EN1|BackLight;
 while(HAL_I2C_Master_Transmit(&amp;amp;hi2c1, ADDRESS, &amp;amp;temp, 1, 1000)!=HAL_OK);
 temp=((cmd &amp;lt;&amp;lt; 4) &amp;amp; 0xF0)|RS0_EN0|BackLight;
 while(HAL_I2C_Master_Transmit(&amp;amp;hi2c1, ADDRESS, &amp;amp;temp, 1, 1000)!=HAL_OK);
 delay_us(50);
}
void LCD_CMD_4bit(uint8_t cmd) {
 uint8_t temp=((cmd &amp;lt;&amp;lt; 4) &amp;amp; 0xF0)|RS0_EN1|BackLight;
 while(HAL_I2C_Master_Transmit(&amp;amp;hi2c1, ADDRESS, &amp;amp;temp, 1, 1000)!=HAL_OK);
 temp=((cmd &amp;lt;&amp;lt; 4) &amp;amp; 0xF0)|RS0_EN0|BackLight;
 while(HAL_I2C_Master_Transmit(&amp;amp;hi2c1, ADDRESS, &amp;amp;temp, 1, 1000)!=HAL_OK);
 delay_us(50);
}
void LCD_INIT(void) {
 delay_ms(100);
 LCD_CMD_4bit(0x03); delay_ms(5);
 LCD_CMD_4bit(0x03); delay_us(100);
 LCD_CMD_4bit(0x03); delay_us(100);
 LCD_CMD_4bit(0x02); delay_us(100);
 LCD_CMD(0x28);  // 4 bits, 2 line, 5x8 font
 LCD_CMD(0x08);  // display off, cursor off, blink off
 LCD_CMD(0x01);  // clear display
 delay_ms(3);
 LCD_CMD(0x06);  // cursor movint direction
 LCD_CMD(0x0C);  // display on, cursor off, blink off
}
void LCD_XY(char x, char y) {
 if      (y == 0) LCD_CMD(0x80 + x);
 else if (y == 1) LCD_CMD(0xC0 + x);
 else if (y == 2) LCD_CMD(0x94 + x);
 else if (y == 3) LCD_CMD(0xD4 + x);
}
void LCD_CLEAR(void) {
 LCD_CMD(0x01);
 delay_ms(2);
}
void LCD_PUTS(char *str) {
 while (*str) LCD_DATA(*str++);
}&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;(LCD관련 함수)&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;background-color: #d4d4d4; color: #000000;&quot;&gt;LCD_INIT&lt;/span&gt;&lt;span style=&quot;background-color: #ffffff; color: #000000;&quot;&gt;(); //I2C 1602LCD를 초기화한다!&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;background-color: #d4d4d4; color: #000000;&quot;&gt;LCD_XY&lt;/span&gt;&lt;span style=&quot;background-color: #ffffff; color: #000000;&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;background-color: #ffffff; color: #7f0055;&quot;&gt;char&lt;/span&gt;&lt;span style=&quot;background-color: #ffffff; color: #000000;&quot;&gt; x, &lt;/span&gt;&lt;span style=&quot;background-color: #ffffff; color: #7f0055;&quot;&gt;char&lt;/span&gt;&lt;span style=&quot;background-color: #ffffff; color: #000000;&quot;&gt; y); //LCD에서 입력커서의 위치를 결정한다!&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;background-color: #d4d4d4; color: #000000;&quot;&gt;LCD_XY&lt;/span&gt;&lt;span style=&quot;background-color: #ffffff; color: #000000;&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;background-color: #ffffff; color: #7f0055;&quot;&gt;0&lt;/span&gt;&lt;span style=&quot;background-color: #ffffff; color: #000000;&quot;&gt;, &lt;/span&gt;&lt;span style=&quot;background-color: #ffffff; color: #7f0055;&quot;&gt;0&lt;/span&gt;&lt;span style=&quot;background-color: #ffffff; color: #000000;&quot;&gt;); //LCD의 좌측상단 모서리부터 문자를 순서대로 출력하겠다!&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;background-color: #d4d4d4; color: #000000;&quot;&gt;LCD_XY&lt;/span&gt;&lt;span style=&quot;background-color: #ffffff; color: #000000;&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;background-color: #ffffff; color: #7f0055;&quot;&gt;0&lt;/span&gt;&lt;span style=&quot;background-color: #ffffff; color: #000000;&quot;&gt;, &lt;/span&gt;&lt;span style=&quot;background-color: #ffffff; color: #7f0055;&quot;&gt;1&lt;/span&gt;&lt;span style=&quot;background-color: #ffffff; color: #000000;&quot;&gt;); //LCD의 좌측하단 모서리부터 문자를 순서대로 출력하겠다!&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;background-color: #ffffff; color: #000000;&quot;&gt;LCD_CLEAR&lt;/span&gt;&lt;span style=&quot;background-color: #ffffff; color: #000000;&quot;&gt;(); //LCD에 입력되어있는 모든 문자열을 지워버린다!&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;background-color: #ffffff; color: #000000;&quot;&gt;LCD_PUTS&lt;/span&gt;&lt;span style=&quot;background-color: #ffffff; color: #000000;&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;background-color: #ffffff; color: #7f0055;&quot;&gt;char&lt;/span&gt;&lt;span style=&quot;background-color: #ffffff; color: #000000;&quot;&gt; *str); //입력된 문자열을 커서의 시작위치부터 해서 순서대로 출력한다!(실제로 화면에 글자가 보인다)&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;br /&gt;1.STM32프로젝트를&amp;nbsp;생성하고&amp;nbsp;IOC에서&amp;nbsp;I2C통신을&amp;nbsp;활성화한다음&amp;nbsp;첫번째줄에는&amp;nbsp;&amp;ldquo;NOCKANDA&amp;rdquo;라고&amp;nbsp;출력하고&amp;nbsp;두번째&amp;nbsp;줄에는&amp;nbsp;&amp;ldquo;STM32&amp;nbsp;TEST!&amp;rdquo;라고&amp;nbsp;출력하시오!&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;01.PNG&quot; data-origin-width=&quot;891&quot; data-origin-height=&quot;433&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/dbbOEh/dJMcagDUe9f/pOrktwWF9uUWxafRcbekm0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/dbbOEh/dJMcagDUe9f/pOrktwWF9uUWxafRcbekm0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/dbbOEh/dJMcagDUe9f/pOrktwWF9uUWxafRcbekm0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FdbbOEh%2FdJMcagDUe9f%2FpOrktwWF9uUWxafRcbekm0%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;440&quot; height=&quot;214&quot; data-filename=&quot;01.PNG&quot; data-origin-width=&quot;891&quot; data-origin-height=&quot;433&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;pre id=&quot;code_1763548169297&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 */
 LCD_INIT(); //1회호출(메인루프 시작전)
 //예제1번에 지정된 문자열을 커서위치를 잡으면서 출력한다!
 LCD_XY(0, 0); LCD_PUTS(&quot;NOCKANDA        &quot;);
 LCD_XY(0, 1); LCD_PUTS(&quot;STM32 TEST!     &quot;);
 /* USER CODE END 2 */
 /* Infinite loop */
 /* USER CODE BEGIN WHILE */
 while (1)
 {
	  //메인루프는 아무것도 할게 없음!
   /* USER CODE END WHILE */
   /* USER CODE BEGIN 3 */
 }&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;br /&gt;2.STM32에서&amp;nbsp;1초간격으로&amp;nbsp;1씩&amp;nbsp;증가하는&amp;nbsp;변수가&amp;nbsp;있다!&amp;nbsp;이&amp;nbsp;값을&amp;nbsp;첫번째&amp;nbsp;줄에&amp;nbsp;&amp;ldquo;CNT&amp;nbsp;=&amp;nbsp;????&amp;rdquo;형식으로&amp;nbsp;출력하시오!&lt;/p&gt;
&lt;pre id=&quot;code_1763548181551&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 */
 LCD_INIT(); //1회호출(메인루프 시작전)
 int cnt = 0;//카운터
 char buff[20]; //가변적인 문자열을 저장할 버퍼
 /* USER CODE END 2 */
 /* Infinite loop */
 /* USER CODE BEGIN WHILE */
 while (1)
 {
	  //cnt변수값을 %d자리에 넣어서 문자열을 생성한다음 buff에 입력한다!
	  sprintf(buff,&quot;CNT = %05d&quot;,cnt);
	  //LCD에 buff에 들어있는값을 출력한다!
	  LCD_XY(0, 0); LCD_PUTS(buff);
	  cnt++;
	  HAL_Delay(1000);
   /* USER CODE END WHILE */
   /* USER CODE BEGIN 3 */
 }&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;br /&gt;3.PB1에&amp;nbsp;연결된버튼을&amp;nbsp;누르면&amp;nbsp;LCD의&amp;nbsp;첫번째줄에&amp;nbsp;BTN1&amp;nbsp;PRESSED!라고&amp;nbsp;출력되고,&amp;nbsp;PA8에&amp;nbsp;연결된&amp;nbsp;버튼을&amp;nbsp;누르면&amp;nbsp;BTN2&amp;nbsp;PRESSED!라고&amp;nbsp;출력되도록&amp;nbsp;하시오!&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;03.PNG&quot; data-origin-width=&quot;504&quot; data-origin-height=&quot;251&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cdMLm0/dJMb995QKVe/8a9JPlUmHzLPuyAkXpHia1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cdMLm0/dJMb995QKVe/8a9JPlUmHzLPuyAkXpHia1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cdMLm0/dJMb995QKVe/8a9JPlUmHzLPuyAkXpHia1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FcdMLm0%2FdJMb995QKVe%2F8a9JPlUmHzLPuyAkXpHia1%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;504&quot; height=&quot;251&quot; data-filename=&quot;03.PNG&quot; data-origin-width=&quot;504&quot; data-origin-height=&quot;251&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;pre id=&quot;code_1763548190228&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 */
 LCD_INIT(); //1회호출(메인루프 시작전)
 /* USER CODE END 2 */
 /* Infinite loop */
 /* USER CODE BEGIN WHILE */
 while (1)
 {
	  if(HAL_GPIO_ReadPin(GPIOB, GPIO_PIN_1) == 0){
		  LCD_XY(0, 0); LCD_PUTS(&quot;BTN1 PRESSED!   &quot;);
		  HAL_Delay(300);
	  }
	  if(HAL_GPIO_ReadPin(GPIOA, GPIO_PIN_8) == 0){
		  LCD_XY(0, 0); LCD_PUTS(&quot;BTN2 PRESSED!   &quot;);
		  HAL_Delay(300);
	  }
   /* USER CODE END WHILE */
   /* USER CODE BEGIN 3 */
 }&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;br /&gt;4.버튼8개를&amp;nbsp;모두&amp;nbsp;이용해서,&amp;nbsp;LCD화면에&amp;nbsp;아래와&amp;nbsp;같은&amp;nbsp;형식으로&amp;nbsp;출력하시오!(버튼8개의&amp;nbsp;상태를&amp;nbsp;2진수로&amp;nbsp;출력해라!) &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;00000000&amp;nbsp;:&amp;nbsp;모든&amp;nbsp;버튼이&amp;nbsp;안눌려지고있다! &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;11110000&amp;nbsp;:&amp;nbsp;1~4까지는&amp;nbsp;눌려지고있고,&amp;nbsp;5~8까지는&amp;nbsp;안눌려지고있음! &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;10101010&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-filename=&quot;04.PNG&quot; data-origin-width=&quot;435&quot; data-origin-height=&quot;234&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/xfxcS/dJMcaf54c5U/vkW0bwkMN544JiorpTy8Fk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/xfxcS/dJMcaf54c5U/vkW0bwkMN544JiorpTy8Fk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/xfxcS/dJMcaf54c5U/vkW0bwkMN544JiorpTy8Fk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FxfxcS%2FdJMcaf54c5U%2FvkW0bwkMN544JiorpTy8Fk%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;435&quot; height=&quot;234&quot; data-filename=&quot;04.PNG&quot; data-origin-width=&quot;435&quot; data-origin-height=&quot;234&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;pre id=&quot;code_1763548199132&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 */
 LCD_INIT(); //1회호출(메인루프 시작전)
 char buff[20];
 /* USER CODE END 2 */
 /* Infinite loop */
 /* USER CODE BEGIN WHILE */
 while (1)
 {
	  //100밀리초간격으로 버튼1~8까지의 상태를 변수에 저장해서 한번에 출력한다!
	  uint8_t btn1 = !HAL_GPIO_ReadPin(GPIOB, GPIO_PIN_1);
	  uint8_t btn2 = !HAL_GPIO_ReadPin(GPIOA, GPIO_PIN_8);
	  uint8_t btn3 = !HAL_GPIO_ReadPin(GPIOB, GPIO_PIN_2);
	  uint8_t btn4 = !HAL_GPIO_ReadPin(GPIOB, GPIO_PIN_6);
	  uint8_t btn5 = !HAL_GPIO_ReadPin(GPIOC, GPIO_PIN_5);
	  uint8_t btn6 = !HAL_GPIO_ReadPin(GPIOC, GPIO_PIN_7);
	  uint8_t btn7 = !HAL_GPIO_ReadPin(GPIOA, GPIO_PIN_11);
	  uint8_t btn8 = !HAL_GPIO_ReadPin(GPIOA, GPIO_PIN_12);
	  sprintf(buff,&quot;%d%d%d%d%d%d%d%d&quot;,btn1,btn2,btn3,btn4,btn5,btn6,btn7,btn8);
	  LCD_XY(0, 0); LCD_PUTS(buff);
	  HAL_Delay(100);
   /* USER CODE END WHILE */
   /* USER CODE BEGIN 3 */
 }&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;br /&gt;5.쉴드에&amp;nbsp;붙어있는&amp;nbsp;로터리엔코더를&amp;nbsp;시계방향으로&amp;nbsp;돌리면&amp;nbsp;값이&amp;nbsp;1씩&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;ldquo;NOCKANDA&amp;nbsp;EX5&amp;rdquo;라고&amp;nbsp;출력하시오!&amp;nbsp;그리고&amp;nbsp;PC7에&amp;nbsp;연결된&amp;nbsp;스위치를&amp;nbsp;누르면&amp;nbsp;카운터값이&amp;nbsp;0으로&amp;nbsp;초기화되도록&amp;nbsp;하시오!&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;05.PNG&quot; data-origin-width=&quot;398&quot; data-origin-height=&quot;343&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bCQR0V/dJMcafrssFX/jw7jY4stfuwOqH19yJikh1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bCQR0V/dJMcafrssFX/jw7jY4stfuwOqH19yJikh1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bCQR0V/dJMcafrssFX/jw7jY4stfuwOqH19yJikh1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbCQR0V%2FdJMcafrssFX%2Fjw7jY4stfuwOqH19yJikh1%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;398&quot; height=&quot;343&quot; data-filename=&quot;05.PNG&quot; data-origin-width=&quot;398&quot; data-origin-height=&quot;343&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;pre id=&quot;code_1763548210576&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 */
 LCD_INIT(); //1회호출(메인루프 시작전)
 char buff[20];
 int cnt = 0;
 uint8_t old_rot_A = 0;
 LCD_XY(0, 0); LCD_PUTS(&quot;NOCKANDA! EX5!!!&quot;);
 /* USER CODE END 2 */
 /* Infinite loop */
 /* USER CODE BEGIN WHILE */
 while (1)
 {
	  //PA11에 A가 연결되었고 PA12에 B가 연결되었다!
	  //A의 상승엣지가 발생했을때 B의 상태가 HIGH면 CCW, LOW면 CW이다!
	  uint8_t now_rot_A = HAL_GPIO_ReadPin(GPIOA, GPIO_PIN_11);
	  if(now_rot_A == 1 &amp;amp;&amp;amp; old_rot_A == 0){
		  uint8_t now_rot_B = HAL_GPIO_ReadPin(GPIOA, GPIO_PIN_12);
		  if(now_rot_B){
			  //CCW
			  cnt--;
		  }else{
			  //CW
			  cnt++;
		  }
		  sprintf(buff,&quot;CNT = %05d&quot;,cnt);
		  LCD_XY(0, 1); LCD_PUTS(buff);
	  }
	  old_rot_A = now_rot_A;
	  HAL_Delay(10);
	  if(HAL_GPIO_ReadPin(GPIOC, GPIO_PIN_7) == 0){
		  cnt = 0;
		  sprintf(buff,&quot;CNT = %05d&quot;,cnt);
		  LCD_XY(0, 1); LCD_PUTS(buff);
		  HAL_Delay(300);
	  }
   /* USER CODE END WHILE */
   /* USER CODE BEGIN 3 */
 }&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;br /&gt;6.예제5와 동일하게 작동이 되는데, 증감되는 변수가 실수형이고 값을 0.5씩 증감되도록 하시오!&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;06.PNG&quot; data-origin-width=&quot;478&quot; data-origin-height=&quot;415&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/6kpQq/dJMcacuJI0n/VUydbKKcQI8i9nSPzbMyQ1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/6kpQq/dJMcacuJI0n/VUydbKKcQI8i9nSPzbMyQ1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/6kpQq/dJMcacuJI0n/VUydbKKcQI8i9nSPzbMyQ1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2F6kpQq%2FdJMcacuJI0n%2FVUydbKKcQI8i9nSPzbMyQ1%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;478&quot; height=&quot;415&quot; data-filename=&quot;06.PNG&quot; data-origin-width=&quot;478&quot; data-origin-height=&quot;415&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;pre id=&quot;code_1763548231546&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 */
 LCD_INIT(); //1회호출(메인루프 시작전)
 char buff[20];
 float cnt = 0;
 uint8_t old_rot_A = 0;
 LCD_XY(0, 0); LCD_PUTS(&quot;NOCKANDA! EX6!!!&quot;);
 /* USER CODE END 2 */
 /* Infinite loop */
 /* USER CODE BEGIN WHILE */
 while (1)
 {
	  //PA11에 A가 연결되었고 PA12에 B가 연결되었다!
	  //A의 상승엣지가 발생했을때 B의 상태가 HIGH면 CCW, LOW면 CW이다!
	  uint8_t now_rot_A = HAL_GPIO_ReadPin(GPIOA, GPIO_PIN_11);
	  if(now_rot_A == 1 &amp;amp;&amp;amp; old_rot_A == 0){
		  uint8_t now_rot_B = HAL_GPIO_ReadPin(GPIOA, GPIO_PIN_12);
		  if(now_rot_B){
			  //CCW
			  cnt -= 0.5;
		  }else{
			  //CW
			  cnt += 0.5;
		  }
		  //정수부3자리, 실수부1자리
		  //sprintf(buff,&quot;CNT = %3.1f&quot;,cnt);
		  sprintf(buff,&quot;CNT = %3d.%1d&quot;,(int)cnt,abs(((int)(cnt*10))%10));
		  LCD_XY(0, 1); LCD_PUTS(buff);
	  }
	  old_rot_A = now_rot_A;
	  HAL_Delay(1);
	  if(HAL_GPIO_ReadPin(GPIOC, GPIO_PIN_7) == 0){
		  cnt = 0;
		  sprintf(buff,&quot;CNT = %3d.%1d&quot;,(int)cnt,abs(((int)(cnt*10))%10));
		  LCD_XY(0, 1); LCD_PUTS(buff);
		  HAL_Delay(300);
	  }
   /* USER CODE END WHILE */
   /* USER CODE BEGIN 3 */
 }&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;br /&gt;7.PA0에 연결된 가변저항값을 측정해서 0~4095 범위로 두번쨰 줄에 값을 출력하고 첫번째 줄에는 적당한 문구를 출력하시오!&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;07.PNG&quot; data-origin-width=&quot;667&quot; data-origin-height=&quot;401&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/I2BmG/dJMcaaRdTqL/yC6QarhlCzEIixfIGzh890/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/I2BmG/dJMcaaRdTqL/yC6QarhlCzEIixfIGzh890/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/I2BmG/dJMcaaRdTqL/yC6QarhlCzEIixfIGzh890/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FI2BmG%2FdJMcaaRdTqL%2FyC6QarhlCzEIixfIGzh890%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;667&quot; height=&quot;401&quot; data-filename=&quot;07.PNG&quot; data-origin-width=&quot;667&quot; data-origin-height=&quot;401&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;pre id=&quot;code_1763548241394&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 */
 LCD_INIT(); //1회호출(메인루프 시작전)
 HAL_ADC_Start(&amp;amp;hadc1); //딱 한번만 호출
 uint16_t adc_value0 = 0;
 char buff[20];
 LCD_XY(0, 0); LCD_PUTS(&quot;NOCKANDA! EX7!!!&quot;);
 /* USER CODE END 2 */
 /* Infinite loop */
 /* USER CODE BEGIN WHILE */
 while (1)
 {
	  //100밀리초 간격으로 가변저항값을 측정해서 출력한다!
	  if(HAL_ADC_PollForConversion(&amp;amp;hadc1, 10) == HAL_OK)
	  {
		  // 값 처리
		  adc_value0 = HAL_ADC_GetValue(&amp;amp;hadc1); //0~4095
		  sprintf(buff,&quot;ROTARY = %4d&quot;,adc_value0);
		  LCD_XY(0, 1); LCD_PUTS(buff);
	  }
	  HAL_Delay(100);
   /* USER CODE END WHILE */
   /* USER CODE BEGIN 3 */
 }&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;br /&gt;8.PA0에 연결된 가변저항과 PA1에 연결된 CDS값을 동시에 측정해서 1602LCD의 두번째줄에 전압으로 나란하게 출력하시오!&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;08.PNG&quot; data-origin-width=&quot;600&quot; data-origin-height=&quot;374&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bN8HEU/dJMcaaRdTqN/eE2iW1Si0N2doT1HBnK5Yk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bN8HEU/dJMcaaRdTqN/eE2iW1Si0N2doT1HBnK5Yk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bN8HEU/dJMcaaRdTqN/eE2iW1Si0N2doT1HBnK5Yk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbN8HEU%2FdJMcaaRdTqN%2FeE2iW1Si0N2doT1HBnK5Yk%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;374&quot; data-filename=&quot;08.PNG&quot; data-origin-width=&quot;600&quot; data-origin-height=&quot;374&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;pre id=&quot;code_1763548255097&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 */
 LCD_INIT(); //1회호출(메인루프 시작전)
 float a0 = 0;
 float a1 = 0;
 char buff[20];
 LCD_XY(0, 0); LCD_PUTS(&quot;NOCKANDA! EX7!!!&quot;);
 /* USER CODE END 2 */
 /* Infinite loop */
 /* USER CODE BEGIN WHILE */
 while (1)
 {
	  //PA0 ADC1 RANK1
	  HAL_ADC_Start(&amp;amp;hadc1);
	  HAL_ADC_PollForConversion(&amp;amp;hadc1, 100);
	  a0 = 3.3*HAL_ADC_GetValue(&amp;amp;hadc1)/4095; //0.0~3.3
	  //PA1 ADC1 RANK2
	  HAL_ADC_Start(&amp;amp;hadc1);
	  HAL_ADC_PollForConversion(&amp;amp;hadc1, 100);
     a1 = 3.3*HAL_ADC_GetValue(&amp;amp;hadc1)/4095; //0.0~3.3
	  sprintf(buff,&quot;PA0=%.1f,PA1=%.1f&quot;,a0,a1);
	  LCD_XY(0, 1); LCD_PUTS(buff);
	  HAL_Delay(100);
   /* USER CODE END WHILE */
   /* USER CODE BEGIN 3 */
 }&lt;/code&gt;&lt;/pre&gt;</description>
      <category>프로그래밍/STM32</category>
      <author>덕력킹</author>
      <guid isPermaLink="true">https://bota.tistory.com/2454</guid>
      <comments>https://bota.tistory.com/2454#entry2454comment</comments>
      <pubDate>Wed, 19 Nov 2025 19:34:17 +0900</pubDate>
    </item>
    <item>
      <title>[STM32#11] L293D 모터드라이버를 이용해서 DC모터를 정역제어하고 PWM출력으로 속도제어하는 방법 알아보기!(녹칸다 내맘대로 STM32)</title>
      <link>https://bota.tistory.com/2453</link>
      <description>&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;stm32.png&quot; data-origin-width=&quot;1920&quot; data-origin-height=&quot;1080&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/k0UUQ/dJMb995PRWk/UnXwLOXQti7k4PUmOydBbK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/k0UUQ/dJMb995PRWk/UnXwLOXQti7k4PUmOydBbK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/k0UUQ/dJMb995PRWk/UnXwLOXQti7k4PUmOydBbK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fk0UUQ%2FdJMb995PRWk%2FUnXwLOXQti7k4PUmOydBbK%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;1920&quot; height=&quot;1080&quot; data-filename=&quot;stm32.png&quot; data-origin-width=&quot;1920&quot; data-origin-height=&quot;1080&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;[STM32#11]&amp;nbsp;L293D&amp;nbsp;모터드라이버를&amp;nbsp;이용해서&amp;nbsp;DC모터를&amp;nbsp;정역제어하고&amp;nbsp;PWM출력으로&amp;nbsp;속도제어하는&amp;nbsp;방법&amp;nbsp;알아보기!(녹칸다&amp;nbsp;내맘대로&amp;nbsp;STM32) &lt;br /&gt;&lt;br /&gt;심심한녹칸다의&amp;nbsp;내맘대로&amp;nbsp;STM32시리즈이다! &lt;br /&gt;&lt;br /&gt;STM32시리즈의&amp;nbsp;모든&amp;nbsp;자료는&amp;nbsp;구글&amp;nbsp;슬라이드에&amp;nbsp;작성하고&amp;nbsp;모두에게&amp;nbsp;공유되어있음! &lt;br /&gt;&lt;a href=&quot;https://docs.google.com/presentation/d/1myA5iYbjuKsLWLqtRLKAiRfwUwvqB1d1RGjiMIIgp3I/edit?slide=id.g3a44d9dbe16_1_0#slide=id.g3a44d9dbe16_1_0&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://docs.google.com/presentation/d/1myA5iYbjuKsLWLqtRLKAiRfwUwvqB1d1RGjiMIIgp3I/edit?slide=id.g3a44d9dbe16_1_0#slide=id.g3a44d9dbe16_1_0&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;이번편은&amp;nbsp;모터드라이버와&amp;nbsp;DC모터입니다~! &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-filename=&quot;회로도.PNG&quot; data-origin-width=&quot;1100&quot; data-origin-height=&quot;535&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/dje7do/dJMcafZhIUW/egHzkJx5it3cjM30QSfTLK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/dje7do/dJMcafZhIUW/egHzkJx5it3cjM30QSfTLK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/dje7do/dJMcafZhIUW/egHzkJx5it3cjM30QSfTLK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fdje7do%2FdJMcafZhIUW%2FegHzkJx5it3cjM30QSfTLK%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;1100&quot; height=&quot;535&quot; data-filename=&quot;회로도.PNG&quot; data-origin-width=&quot;1100&quot; data-origin-height=&quot;535&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&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;ㅇㅇ.PNG&quot; data-origin-width=&quot;1196&quot; data-origin-height=&quot;583&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/ySiPf/dJMcafEYWnv/FuTqRCdeTgk6V42ZUIau31/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/ySiPf/dJMcafEYWnv/FuTqRCdeTgk6V42ZUIau31/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/ySiPf/dJMcafEYWnv/FuTqRCdeTgk6V42ZUIau31/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FySiPf%2FdJMcafEYWnv%2FFuTqRCdeTgk6V42ZUIau31%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;1196&quot; height=&quot;583&quot; data-filename=&quot;ㅇㅇ.PNG&quot; data-origin-width=&quot;1196&quot; data-origin-height=&quot;583&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;br /&gt;1.STM32에&amp;nbsp;연결된&amp;nbsp;L293D에&amp;nbsp;DC모터를&amp;nbsp;연결하고&amp;nbsp;속도는&amp;nbsp;항상&amp;nbsp;100으로&amp;nbsp;고정하고&amp;nbsp;PB1버튼을&amp;nbsp;누르면&amp;nbsp;모터가&amp;nbsp;역회전,&amp;nbsp;PA8버튼을&amp;nbsp;누르면&amp;nbsp;브레이크,&amp;nbsp;PB2버튼을&amp;nbsp;누르면&amp;nbsp;정회전&amp;nbsp;하도록&amp;nbsp;하시오!(EN1핀을&amp;nbsp;PWM제어하지&amp;nbsp;않음)&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;1.PNG&quot; data-origin-width=&quot;907&quot; data-origin-height=&quot;578&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/pEVs8/dJMcahQkKpw/TCyU0XUjmNhXjLQqwca65k/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/pEVs8/dJMcahQkKpw/TCyU0XUjmNhXjLQqwca65k/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/pEVs8/dJMcahQkKpw/TCyU0XUjmNhXjLQqwca65k/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FpEVs8%2FdJMcahQkKpw%2FTCyU0XUjmNhXjLQqwca65k%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;907&quot; height=&quot;578&quot; data-filename=&quot;1.PNG&quot; data-origin-width=&quot;907&quot; data-origin-height=&quot;578&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;pre id=&quot;code_1763388030031&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 */
 //속도는 항상 100이다!
 HAL_GPIO_WritePin(GPIOB, GPIO_PIN_10, 1);
 //기본 모터는 브레이크 상태
 HAL_GPIO_WritePin(GPIOC, GPIO_PIN_0, 0); //IN1
 HAL_GPIO_WritePin(GPIOC, GPIO_PIN_3, 0); //IN2
 /* USER CODE END 2 */
 /* Infinite loop */
 /* USER CODE BEGIN WHILE */
 while (1)
 {
	  //PB1을 누르면 역회전
	  if(HAL_GPIO_ReadPin(GPIOB, GPIO_PIN_1) == 0){
		  //IN1이 0이고 IN2가 1일때
		  HAL_GPIO_WritePin(GPIOC, GPIO_PIN_0, 0); //IN1
		  HAL_GPIO_WritePin(GPIOC, GPIO_PIN_3, 1); //IN2
	  }
	  //PA8을 누르면 정지
	  if(HAL_GPIO_ReadPin(GPIOA, GPIO_PIN_8) == 0){
		  //둘다 0일떄
		  HAL_GPIO_WritePin(GPIOC, GPIO_PIN_0, 0); //IN1
		  HAL_GPIO_WritePin(GPIOC, GPIO_PIN_3, 0); //IN2
	  }
	  //PB2를 누르면 정회전
	  if(HAL_GPIO_ReadPin(GPIOB, GPIO_PIN_2) == 0){
		  //IN1이 1이고 IN2가 0일때
		  HAL_GPIO_WritePin(GPIOC, GPIO_PIN_0, 1); //IN1
		  HAL_GPIO_WritePin(GPIOC, GPIO_PIN_3, 0); //IN2
	  }
   /* USER CODE END WHILE */
   /* USER CODE BEGIN 3 */
 }&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;br /&gt;2.이번에는&amp;nbsp;DC모터가&amp;nbsp;항상&amp;nbsp;정회전으로&amp;nbsp;설정되어있고&amp;nbsp;PB1을&amp;nbsp;누르면&amp;nbsp;속도가&amp;nbsp;0%가되고&amp;nbsp;PA8을&amp;nbsp;누르면&amp;nbsp;50%가되고,&amp;nbsp;PB2를&amp;nbsp;누르면&amp;nbsp;100%가&amp;nbsp;되도록&amp;nbsp;하시오!(주파수490hz)&lt;/p&gt;
&lt;pre id=&quot;code_1763388038888&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 */
 HAL_TIM_PWM_Start(&amp;amp;htim2,TIM_CHANNEL_3);
 //무조건 정회전
 HAL_GPIO_WritePin(GPIOC, GPIO_PIN_0, 1); //IN1
 HAL_GPIO_WritePin(GPIOC, GPIO_PIN_3, 0); //IN2
 //시작하자 마자 속도는 0
 TIM2-&amp;gt;CCR3 = 0; //0~255
 /* USER CODE END 2 */
 /* Infinite loop */
 /* USER CODE BEGIN WHILE */
 while (1)
 {
	  //PB1을 누르면 속도는 0으로 설정
	  if(HAL_GPIO_ReadPin(GPIOB, GPIO_PIN_1) == 0){
		  TIM2-&amp;gt;CCR3 = 0;
	  }
	  //PA8을 누르면 속도는 50으로 설정
	  if(HAL_GPIO_ReadPin(GPIOA, GPIO_PIN_8) == 0){
		  TIM2-&amp;gt;CCR3 = 128;
	  }
	  //PB2를 누르면 속도를 100으로 설정
	  if(HAL_GPIO_ReadPin(GPIOB, GPIO_PIN_2) == 0){
		  TIM2-&amp;gt;CCR3 = 255;
	  }
   /* USER CODE END WHILE */
   /* USER CODE BEGIN 3 */
 }&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;br /&gt;3.속도제어될때&amp;nbsp;사람귀에&amp;nbsp;들리는&amp;nbsp;가청주파수&amp;nbsp;밖의&amp;nbsp;범위로&amp;nbsp;주파수를&amp;nbsp;설정해서&amp;nbsp;듀티비로&amp;nbsp;속도제어하시오!(20khz)&lt;/p&gt;
&lt;pre id=&quot;code_1763388049945&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 */
 HAL_TIM_PWM_Start(&amp;amp;htim2,TIM_CHANNEL_3);
 //무조건 정회전
 HAL_GPIO_WritePin(GPIOC, GPIO_PIN_0, 1); //IN1
 HAL_GPIO_WritePin(GPIOC, GPIO_PIN_3, 0); //IN2
 //시작하자 마자 속도는 0
 TIM2-&amp;gt;CCR3 = 0; //0~255
 /* USER CODE END 2 */
 /* Infinite loop */
 /* USER CODE BEGIN WHILE */
 while (1)
 {
	  //PB1을 누르면 속도는 0%으로 설정
	  if(HAL_GPIO_ReadPin(GPIOB, GPIO_PIN_1) == 0){
		  TIM2-&amp;gt;CCR3 = 0;
	  }
	  //PA8을 누르면 속도는 78%으로 설정
	  if(HAL_GPIO_ReadPin(GPIOA, GPIO_PIN_8) == 0){
		  TIM2-&amp;gt;CCR3 = 200;
	  }
	  //PB2를 누르면 속도를 100%으로 설정
	  if(HAL_GPIO_ReadPin(GPIOB, GPIO_PIN_2) == 0){
		  TIM2-&amp;gt;CCR3 = 255;
	  }
   /* USER CODE END WHILE */
   /* USER CODE BEGIN 3 */
 }&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;br /&gt;4.STM32에서&amp;nbsp;CCR에&amp;nbsp;입력하는&amp;nbsp;값으로&amp;nbsp;0~100을&amp;nbsp;입력했을때&amp;nbsp;DC모터의&amp;nbsp;속도가&amp;nbsp;0~100%구간으로&amp;nbsp;조절되도록&amp;nbsp;설정하시오!&lt;/p&gt;
&lt;pre id=&quot;code_1763388069946&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 */
 HAL_TIM_PWM_Start(&amp;amp;htim2,TIM_CHANNEL_3);
 //무조건 정회전
 HAL_GPIO_WritePin(GPIOC, GPIO_PIN_0, 1); //IN1
 HAL_GPIO_WritePin(GPIOC, GPIO_PIN_3, 0); //IN2
 //시작하자 마자 속도는 0
 TIM2-&amp;gt;CCR3 = 0; //0~100
 /* USER CODE END 2 */
 /* Infinite loop */
 /* USER CODE BEGIN WHILE */
 while (1)
 {
	  //PB1을 누르면 속도는 0%으로 설정
	  if(HAL_GPIO_ReadPin(GPIOB, GPIO_PIN_1) == 0){
		  TIM2-&amp;gt;CCR3 = 0;
	  }
	  //PA8을 누르면 속도는 50%으로 설정
	  if(HAL_GPIO_ReadPin(GPIOA, GPIO_PIN_8) == 0){
		  TIM2-&amp;gt;CCR3 = 80;
	  }
	  //PB2를 누르면 속도를 100%으로 설정
	  if(HAL_GPIO_ReadPin(GPIOB, GPIO_PIN_2) == 0){
		  TIM2-&amp;gt;CCR3 = 100;
	  }
   /* USER CODE END WHILE */
   /* USER CODE BEGIN 3 */
 }&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;br /&gt;5.PA0에&amp;nbsp;연결된&amp;nbsp;가변저항의&amp;nbsp;노브를&amp;nbsp;0~100%사이로&amp;nbsp;조절했을때&amp;nbsp;DC모터의&amp;nbsp;속도가&amp;nbsp;결정되고,&amp;nbsp;PB1을&amp;nbsp;누르면&amp;nbsp;역회전설정,&amp;nbsp;PA8을&amp;nbsp;누르면&amp;nbsp;브레이크,&amp;nbsp;PB1을&amp;nbsp;누르면&amp;nbsp;정회전으로&amp;nbsp;설정되도록&amp;nbsp;하시오!(주파수490hz)&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;5.PNG&quot; data-origin-width=&quot;918&quot; data-origin-height=&quot;552&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/b6Qnwq/dJMcaaDFHho/ZLiOvR07NkblTEgkX8gep0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/b6Qnwq/dJMcaaDFHho/ZLiOvR07NkblTEgkX8gep0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/b6Qnwq/dJMcaaDFHho/ZLiOvR07NkblTEgkX8gep0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fb6Qnwq%2FdJMcaaDFHho%2FZLiOvR07NkblTEgkX8gep0%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;918&quot; height=&quot;552&quot; data-filename=&quot;5.PNG&quot; data-origin-width=&quot;918&quot; data-origin-height=&quot;552&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;pre id=&quot;code_1763388079749&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 */
 HAL_TIM_PWM_Start(&amp;amp;htim2,TIM_CHANNEL_3);
 HAL_ADC_Start(&amp;amp;hadc1);
 //초기상태(브레이크, 속도0)
 HAL_GPIO_WritePin(GPIOC, GPIO_PIN_0, 0); //IN1
 HAL_GPIO_WritePin(GPIOC, GPIO_PIN_3, 0); //IN2
 //시작하자 마자 속도는 0
 TIM2-&amp;gt;CCR3 = 0; //0~255
 uint16_t adc_value0 = 0;
 /* USER CODE END 2 */
 /* Infinite loop */
 /* USER CODE BEGIN WHILE */
 while (1)
 {
	  if(HAL_ADC_PollForConversion(&amp;amp;hadc1, 10) == HAL_OK)
	  {
		  // 값 처리
		  adc_value0 = HAL_ADC_GetValue(&amp;amp;hadc1); //0~4095
		  TIM2-&amp;gt;CCR3 = 255*adc_value0/4095; //0~255
	  }
	  HAL_Delay(10); //ADC입력간격으로 0.01초유지
	  //PB1을 누르면 역회전
	  if(HAL_GPIO_ReadPin(GPIOB, GPIO_PIN_1) == 0){
		  HAL_GPIO_WritePin(GPIOC, GPIO_PIN_0, 0); //IN1
		  HAL_GPIO_WritePin(GPIOC, GPIO_PIN_3, 1); //IN2
	  }
	  //PA8을 누르면 브레이크
	  if(HAL_GPIO_ReadPin(GPIOA, GPIO_PIN_8) == 0){
		  HAL_GPIO_WritePin(GPIOC, GPIO_PIN_0, 0); //IN1
		  HAL_GPIO_WritePin(GPIOC, GPIO_PIN_3, 0); //IN2
	  }
	  //PB2를 누르면 정회전
	  if(HAL_GPIO_ReadPin(GPIOB, GPIO_PIN_2) == 0){
		  HAL_GPIO_WritePin(GPIOC, GPIO_PIN_0, 1); //IN1
		  HAL_GPIO_WritePin(GPIOC, GPIO_PIN_3, 0); //IN2
	  }
   /* USER CODE END WHILE */
   /* USER CODE BEGIN 3 */
 }&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;br /&gt;6.모터드라이버의&amp;nbsp;채널2번에&amp;nbsp;DC모터를&amp;nbsp;하나더&amp;nbsp;추가하고&amp;nbsp;예제5의&amp;nbsp;결과와&amp;nbsp;동일하게&amp;nbsp;바퀴&amp;nbsp;2개를&amp;nbsp;동시에&amp;nbsp;제어하시오!&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;6.PNG&quot; data-origin-width=&quot;830&quot; data-origin-height=&quot;551&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bmcqGc/dJMcahJzbnR/shLkHH0kSko64OLE6QDtI0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bmcqGc/dJMcahJzbnR/shLkHH0kSko64OLE6QDtI0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bmcqGc/dJMcahJzbnR/shLkHH0kSko64OLE6QDtI0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbmcqGc%2FdJMcahJzbnR%2FshLkHH0kSko64OLE6QDtI0%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;830&quot; height=&quot;551&quot; data-filename=&quot;6.PNG&quot; data-origin-width=&quot;830&quot; data-origin-height=&quot;551&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;pre id=&quot;code_1763388096729&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 */
 HAL_TIM_PWM_Start(&amp;amp;htim2,TIM_CHANNEL_3); //모터1
 HAL_TIM_PWM_Start(&amp;amp;htim3,TIM_CHANNEL_1); //모터2
 HAL_ADC_Start(&amp;amp;hadc1);
 //초기상태(브레이크, 속도0)
 HAL_GPIO_WritePin(GPIOC, GPIO_PIN_0, 0); //IN1
 HAL_GPIO_WritePin(GPIOC, GPIO_PIN_3, 0); //IN2
 HAL_GPIO_WritePin(GPIOC, GPIO_PIN_8, 0); //IN3
 HAL_GPIO_WritePin(GPIOC, GPIO_PIN_9, 0); //IN4
 uint16_t adc_value0 = 0;
 /* USER CODE END 2 */
 /* Infinite loop */
 /* USER CODE BEGIN WHILE */
 while (1)
 {
	  if(HAL_ADC_PollForConversion(&amp;amp;hadc1, 10) == HAL_OK)
	  {
		  // 값 처리
		  adc_value0 = HAL_ADC_GetValue(&amp;amp;hadc1); //0~4095
		  TIM2-&amp;gt;CCR3 = 255*adc_value0/4095; //0~255
		  TIM3-&amp;gt;CCR1 = 255*adc_value0/4095; //0~255
	  }
	  HAL_Delay(10); //ADC입력간격으로 0.01초유지
	  //PB1을 누르면 역회전
	  if(HAL_GPIO_ReadPin(GPIOB, GPIO_PIN_1) == 0){
		  HAL_GPIO_WritePin(GPIOC, GPIO_PIN_0, 0); //IN1
		  HAL_GPIO_WritePin(GPIOC, GPIO_PIN_3, 1); //IN2
		  HAL_GPIO_WritePin(GPIOC, GPIO_PIN_8, 1); //IN3
		  HAL_GPIO_WritePin(GPIOC, GPIO_PIN_9, 0); //IN4
	  }

	  //PA8을 누르면 브레이크
	  if(HAL_GPIO_ReadPin(GPIOA, GPIO_PIN_8) == 0){
		  HAL_GPIO_WritePin(GPIOC, GPIO_PIN_0, 0); //IN1
		  HAL_GPIO_WritePin(GPIOC, GPIO_PIN_3, 0); //IN2
		  HAL_GPIO_WritePin(GPIOC, GPIO_PIN_8, 0); //IN3
		  HAL_GPIO_WritePin(GPIOC, GPIO_PIN_9, 0); //IN4
	  }
	  //PB2를 누르면 정회전
	  if(HAL_GPIO_ReadPin(GPIOB, GPIO_PIN_2) == 0){
		  HAL_GPIO_WritePin(GPIOC, GPIO_PIN_0, 1); //IN1
		  HAL_GPIO_WritePin(GPIOC, GPIO_PIN_3, 0); //IN2
		  HAL_GPIO_WritePin(GPIOC, GPIO_PIN_8, 0); //IN3
		  HAL_GPIO_WritePin(GPIOC, GPIO_PIN_9, 1); //IN4
	  }
   /* USER CODE END WHILE */
   /* USER CODE BEGIN 3 */
 }&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;br /&gt;7.예제6번에서&amp;nbsp;PB6버튼을&amp;nbsp;누르면&amp;nbsp;모터1과&amp;nbsp;2가&amp;nbsp;둘다&amp;nbsp;정회전하고,&amp;nbsp;PC5를&amp;nbsp;누르면&amp;nbsp;모터1과&amp;nbsp;모터2가&amp;nbsp;둘다&amp;nbsp;역회전하도록&amp;nbsp;하시오!&lt;/p&gt;
&lt;pre id=&quot;code_1763388109359&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 */
 HAL_TIM_PWM_Start(&amp;amp;htim2,TIM_CHANNEL_3); //모터1
 HAL_TIM_PWM_Start(&amp;amp;htim3,TIM_CHANNEL_1); //모터2
 HAL_ADC_Start(&amp;amp;hadc1);
 //초기상태(브레이크, 속도0)
 HAL_GPIO_WritePin(GPIOC, GPIO_PIN_0, 0); //IN1
 HAL_GPIO_WritePin(GPIOC, GPIO_PIN_3, 0); //IN2
 HAL_GPIO_WritePin(GPIOC, GPIO_PIN_8, 0); //IN3
 HAL_GPIO_WritePin(GPIOC, GPIO_PIN_9, 0); //IN4
 uint16_t adc_value0 = 0;
 /* USER CODE END 2 */
 /* Infinite loop */
 /* USER CODE BEGIN WHILE */
 while (1)
 {
	  if(HAL_ADC_PollForConversion(&amp;amp;hadc1, 10) == HAL_OK)
	  {
		  // 값 처리
		  adc_value0 = HAL_ADC_GetValue(&amp;amp;hadc1); //0~4095
		  TIM2-&amp;gt;CCR3 = 255*adc_value0/4095; //0~255
		  TIM3-&amp;gt;CCR1 = 255*adc_value0/4095; //0~255
	  }
	  HAL_Delay(10); //ADC입력간격으로 0.01초유지
	  //PB1을 누르면 전진
	  if(HAL_GPIO_ReadPin(GPIOB, GPIO_PIN_1) == 0){
		  HAL_GPIO_WritePin(GPIOC, GPIO_PIN_0, 0); //IN1
		  HAL_GPIO_WritePin(GPIOC, GPIO_PIN_3, 1); //IN2
		  HAL_GPIO_WritePin(GPIOC, GPIO_PIN_8, 1); //IN3
		  HAL_GPIO_WritePin(GPIOC, GPIO_PIN_9, 0); //IN4
	  }

	  //PA8을 누르면 브레이크
	  if(HAL_GPIO_ReadPin(GPIOA, GPIO_PIN_8) == 0){
		  HAL_GPIO_WritePin(GPIOC, GPIO_PIN_0, 0); //IN1
		  HAL_GPIO_WritePin(GPIOC, GPIO_PIN_3, 0); //IN2
		  HAL_GPIO_WritePin(GPIOC, GPIO_PIN_8, 0); //IN3
		  HAL_GPIO_WritePin(GPIOC, GPIO_PIN_9, 0); //IN4
	  }
	  //PB2를 누르면 후진
	  if(HAL_GPIO_ReadPin(GPIOB, GPIO_PIN_2) == 0){
		  HAL_GPIO_WritePin(GPIOC, GPIO_PIN_0, 1); //IN1
		  HAL_GPIO_WritePin(GPIOC, GPIO_PIN_3, 0); //IN2
		  HAL_GPIO_WritePin(GPIOC, GPIO_PIN_8, 0); //IN3
		  HAL_GPIO_WritePin(GPIOC, GPIO_PIN_9, 1); //IN4
	  }
	  //PB6를 누르면 g턴1
	  if(HAL_GPIO_ReadPin(GPIOB, GPIO_PIN_6) == 0){
		  HAL_GPIO_WritePin(GPIOC, GPIO_PIN_0, 1); //IN1
		  HAL_GPIO_WritePin(GPIOC, GPIO_PIN_3, 0); //IN2
		  HAL_GPIO_WritePin(GPIOC, GPIO_PIN_8, 1); //IN3
		  HAL_GPIO_WritePin(GPIOC, GPIO_PIN_9, 0); //IN4
	  }
	  //PC5를 누르면 g턴2
	  if(HAL_GPIO_ReadPin(GPIOC, GPIO_PIN_5) == 0){
		  HAL_GPIO_WritePin(GPIOC, GPIO_PIN_0, 0); //IN1
		  HAL_GPIO_WritePin(GPIOC, GPIO_PIN_3, 1); //IN2
		  HAL_GPIO_WritePin(GPIOC, GPIO_PIN_8, 0); //IN3
		  HAL_GPIO_WritePin(GPIOC, GPIO_PIN_9, 1); //IN4
	  }
   /* USER CODE END WHILE */
   /* USER CODE BEGIN 3 */
 }&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;br /&gt;8.로터리엔코더를&amp;nbsp;시계방향으로&amp;nbsp;살짝&amp;nbsp;돌려서&amp;nbsp;팅구면&amp;nbsp;녹칸다의&amp;nbsp;자동차가&amp;nbsp;D모드가&amp;nbsp;되면서&amp;nbsp;모터1은&amp;nbsp;정회전,&amp;nbsp;모터2는&amp;nbsp;역회전하면서&amp;nbsp;전진한다,&amp;nbsp;반시계방향으로&amp;nbsp;딱&amp;nbsp;팅구면&amp;nbsp;R모드가&amp;nbsp;되면서&amp;nbsp;모터1은&amp;nbsp;역회전,&amp;nbsp;모터2는&amp;nbsp;정회전하면서&amp;nbsp;후진한다,&amp;nbsp;로터리엔코더를&amp;nbsp;누르면&amp;nbsp;P모드가&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-filename=&quot;8.PNG&quot; data-origin-width=&quot;870&quot; data-origin-height=&quot;571&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bXAIYi/dJMcabJlM1w/wR4cuh9ZGHejJdJIrsEIKk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bXAIYi/dJMcabJlM1w/wR4cuh9ZGHejJdJIrsEIKk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bXAIYi/dJMcabJlM1w/wR4cuh9ZGHejJdJIrsEIKk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbXAIYi%2FdJMcabJlM1w%2FwR4cuh9ZGHejJdJIrsEIKk%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;870&quot; height=&quot;571&quot; data-filename=&quot;8.PNG&quot; data-origin-width=&quot;870&quot; data-origin-height=&quot;571&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;pre id=&quot;code_1763388124096&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 */
 HAL_TIM_PWM_Start(&amp;amp;htim2,TIM_CHANNEL_3); //모터1
 HAL_TIM_PWM_Start(&amp;amp;htim3,TIM_CHANNEL_1); //모터2
 //초기상태(브레이크, 속도0)
 HAL_GPIO_WritePin(GPIOC, GPIO_PIN_0, 0); //IN1
 HAL_GPIO_WritePin(GPIOC, GPIO_PIN_3, 0); //IN2
 HAL_GPIO_WritePin(GPIOC, GPIO_PIN_8, 0); //IN3
 HAL_GPIO_WritePin(GPIOC, GPIO_PIN_9, 0); //IN4
 //속도는 최대
 TIM2-&amp;gt;CCR3 = 255; //0~255
 TIM3-&amp;gt;CCR1 = 255; //0~255
 uint8_t old_rot_A = 0;
 HAL_GPIO_WritePin(GPIOB, GPIO_PIN_3, 1); //LED(P)
 /* USER CODE END 2 */
 /* Infinite loop */
 /* USER CODE BEGIN WHILE */
 while (1)
 {
	  //A핀의 rising edge를 검출한다
	  //rising edge가 발생했을때 B의 신호가 HIGH면 CCW, LOW면 CW방향!
	  uint8_t now_rot_A = HAL_GPIO_ReadPin(GPIOA, GPIO_PIN_11);
	  if(now_rot_A == 1 &amp;amp;&amp;amp; old_rot_A == 0){
		  uint8_t now_rot_B = HAL_GPIO_ReadPin(GPIOA, GPIO_PIN_12);
		  if(now_rot_B){
			  //CCW R모드
			  HAL_GPIO_WritePin(GPIOB, GPIO_PIN_7, 1); //LED(R)
			  HAL_GPIO_WritePin(GPIOB, GPIO_PIN_3, 0); //LED(P)
			  HAL_GPIO_WritePin(GPIOB, GPIO_PIN_13, 0); //LED(D)
			  HAL_GPIO_WritePin(GPIOC, GPIO_PIN_0, 0); //IN1
			  HAL_GPIO_WritePin(GPIOC, GPIO_PIN_3, 1); //IN2
			  HAL_GPIO_WritePin(GPIOC, GPIO_PIN_8, 1); //IN3
			  HAL_GPIO_WritePin(GPIOC, GPIO_PIN_9, 0); //IN4

		  }else{
			  //CW D모드
			  HAL_GPIO_WritePin(GPIOB, GPIO_PIN_7, 0); //LED(R)
			  HAL_GPIO_WritePin(GPIOB, GPIO_PIN_3, 0); //LED(P)
			  HAL_GPIO_WritePin(GPIOB, GPIO_PIN_13, 1); //LED(D)
			  HAL_GPIO_WritePin(GPIOC, GPIO_PIN_0, 1); //IN1
			  HAL_GPIO_WritePin(GPIOC, GPIO_PIN_3, 0); //IN2
			  HAL_GPIO_WritePin(GPIOC, GPIO_PIN_8, 0); //IN3
			  HAL_GPIO_WritePin(GPIOC, GPIO_PIN_9, 1); //IN4
		  }
	  }
	  old_rot_A = now_rot_A;
	  HAL_Delay(10); //로터리엔코더 노이즈 방지용
	  if(HAL_GPIO_ReadPin(GPIOC, GPIO_PIN_7) == 0){
		  //P모드
		  HAL_GPIO_WritePin(GPIOB, GPIO_PIN_7, 0); //LED(R)
		  HAL_GPIO_WritePin(GPIOB, GPIO_PIN_3, 1); //LED(P)
		  HAL_GPIO_WritePin(GPIOB, GPIO_PIN_13, 0); //LED(D)
		  HAL_GPIO_WritePin(GPIOC, GPIO_PIN_0, 0); //IN1
		  HAL_GPIO_WritePin(GPIOC, GPIO_PIN_3, 0); //IN2
		  HAL_GPIO_WritePin(GPIOC, GPIO_PIN_8, 0); //IN3
		  HAL_GPIO_WritePin(GPIOC, GPIO_PIN_9, 0); //IN4
	  }
   /* USER CODE END WHILE */
   /* USER CODE BEGIN 3 */
 }&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;br /&gt;9.예제8에서&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;1씩&amp;nbsp;증가해서&amp;nbsp;최대&amp;nbsp;255까지&amp;nbsp;올라간다!&amp;nbsp;그리고&amp;nbsp;누르고있다가&amp;nbsp;떼면&amp;nbsp;감소해서&amp;nbsp;0으로&amp;nbsp;내려온다!&lt;/p&gt;
&lt;pre id=&quot;code_1763388150466&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 */
 HAL_TIM_PWM_Start(&amp;amp;htim2,TIM_CHANNEL_3); //모터1
 HAL_TIM_PWM_Start(&amp;amp;htim3,TIM_CHANNEL_1); //모터2
 //초기상태(브레이크, 속도0)
 HAL_GPIO_WritePin(GPIOC, GPIO_PIN_0, 0); //IN1
 HAL_GPIO_WritePin(GPIOC, GPIO_PIN_3, 0); //IN2
 HAL_GPIO_WritePin(GPIOC, GPIO_PIN_8, 0); //IN3
 HAL_GPIO_WritePin(GPIOC, GPIO_PIN_9, 0); //IN4
 //속도는 0으로 시작
 int speed = 0;
 TIM2-&amp;gt;CCR3 = 0; //0~255
 TIM3-&amp;gt;CCR1 = 0; //0~255
 uint8_t old_rot_A = 0;
 HAL_GPIO_WritePin(GPIOB, GPIO_PIN_3, 1); //LED(P)
 int mode = 1; //0이면 R, 1이면 P, 2이면 D
 /* USER CODE END 2 */
 /* Infinite loop */
 /* USER CODE BEGIN WHILE */
 while (1)
 {
	  //A핀의 rising edge를 검출한다
	  //rising edge가 발생했을때 B의 신호가 HIGH면 CCW, LOW면 CW방향!
	  uint8_t now_rot_A = HAL_GPIO_ReadPin(GPIOA, GPIO_PIN_11);
	  if(now_rot_A == 1 &amp;amp;&amp;amp; old_rot_A == 0){
		  uint8_t now_rot_B = HAL_GPIO_ReadPin(GPIOA, GPIO_PIN_12);
		  if(now_rot_B){
			  //CCW
			  mode--;
			  if(mode &amp;lt; 0) mode = 0;

		  }else{
			  //CW
			  mode++;
			  if(mode &amp;gt; 2) mode = 2;
		  }
		  if(mode == 0){
			  //R
			  HAL_GPIO_WritePin(GPIOB, GPIO_PIN_7, 1); //LED(R)
			  HAL_GPIO_WritePin(GPIOB, GPIO_PIN_3, 0); //LED(P)
			  HAL_GPIO_WritePin(GPIOB, GPIO_PIN_13, 0); //LED(D)
			  HAL_GPIO_WritePin(GPIOC, GPIO_PIN_0, 0); //IN1
			  HAL_GPIO_WritePin(GPIOC, GPIO_PIN_3, 1); //IN2
			  HAL_GPIO_WritePin(GPIOC, GPIO_PIN_8, 1); //IN3
			  HAL_GPIO_WritePin(GPIOC, GPIO_PIN_9, 0); //IN4
		  }else if(mode == 1){
			  //P
			  HAL_GPIO_WritePin(GPIOB, GPIO_PIN_7, 0); //LED(R)
			  HAL_GPIO_WritePin(GPIOB, GPIO_PIN_3, 1); //LED(P)
			  HAL_GPIO_WritePin(GPIOB, GPIO_PIN_13, 0); //LED(D)
			  HAL_GPIO_WritePin(GPIOC, GPIO_PIN_0, 0); //IN1
			  HAL_GPIO_WritePin(GPIOC, GPIO_PIN_3, 0); //IN2
			  HAL_GPIO_WritePin(GPIOC, GPIO_PIN_8, 0); //IN3
			  HAL_GPIO_WritePin(GPIOC, GPIO_PIN_9, 0); //IN4

		  }else if(mode == 2){
			  //D
			  HAL_GPIO_WritePin(GPIOB, GPIO_PIN_7, 0); //LED(R)
			  HAL_GPIO_WritePin(GPIOB, GPIO_PIN_3, 0); //LED(P)
			  HAL_GPIO_WritePin(GPIOB, GPIO_PIN_13, 1); //LED(D)
			  HAL_GPIO_WritePin(GPIOC, GPIO_PIN_0, 1); //IN1
			  HAL_GPIO_WritePin(GPIOC, GPIO_PIN_3, 0); //IN2
			  HAL_GPIO_WritePin(GPIOC, GPIO_PIN_8, 0); //IN3
			  HAL_GPIO_WritePin(GPIOC, GPIO_PIN_9, 1); //IN4
		  }
	  }
	  old_rot_A = now_rot_A;
	  HAL_Delay(10); //로터리엔코더 노이즈 방지용
	  if(mode == 1){
		  //속도0
		  speed = 0;
		  TIM2-&amp;gt;CCR3 = 0; //0~255
		  TIM3-&amp;gt;CCR1 = 0; //0~255
	  }else{
		  if(HAL_GPIO_ReadPin(GPIOC, GPIO_PIN_7) == 0){
			  //누르고있음 속도가 1씩 증가(최대값255)
			  speed++;
			  if(speed &amp;gt; 255) speed = 255;
			  TIM2-&amp;gt;CCR3 = speed; //0~255
			  TIM3-&amp;gt;CCR1 = speed; //0~255
		  }else{
			  //안누르고있음 속도가 1씩 감소(최소값0)
			  speed--;
			  if(speed &amp;lt; 0) speed = 0;
			  TIM2-&amp;gt;CCR3 = speed; //0~255
			  TIM3-&amp;gt;CCR1 = speed; //0~255
		  }
	  }
   /* USER CODE END WHILE */
   /* USER CODE BEGIN 3 */
 }&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;br /&gt;10.녹칸다가&amp;nbsp;터미널에서&amp;nbsp;usart2로&amp;nbsp;문자&amp;nbsp;&amp;lsquo;0&amp;rsquo;을&amp;nbsp;전송하면&amp;nbsp;모터2개는&amp;nbsp;멈춘다!&amp;nbsp;&amp;lsquo;1&amp;rsquo;을&amp;nbsp;전송하면&amp;nbsp;정회전하고&amp;nbsp;&amp;lsquo;2&amp;rsquo;를&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-filename=&quot;10.PNG&quot; data-origin-width=&quot;877&quot; data-origin-height=&quot;533&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/c3nx65/dJMcag4Xz26/Kae8R3Wqmj8xSViihEarRK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/c3nx65/dJMcag4Xz26/Kae8R3Wqmj8xSViihEarRK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/c3nx65/dJMcag4Xz26/Kae8R3Wqmj8xSViihEarRK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fc3nx65%2FdJMcag4Xz26%2FKae8R3Wqmj8xSViihEarRK%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;877&quot; height=&quot;533&quot; data-filename=&quot;10.PNG&quot; data-origin-width=&quot;877&quot; data-origin-height=&quot;533&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;pre id=&quot;code_1763388163262&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 */
 HAL_TIM_PWM_Start(&amp;amp;htim2,TIM_CHANNEL_3); //모터1
 HAL_TIM_PWM_Start(&amp;amp;htim3,TIM_CHANNEL_1); //모터2
 //초기상태(브레이크, 속도0)
 HAL_GPIO_WritePin(GPIOC, GPIO_PIN_0, 0); //IN1
 HAL_GPIO_WritePin(GPIOC, GPIO_PIN_3, 0); //IN2
 HAL_GPIO_WritePin(GPIOC, GPIO_PIN_8, 0); //IN3
 HAL_GPIO_WritePin(GPIOC, GPIO_PIN_9, 0); //IN4
 TIM2-&amp;gt;CCR3 = 255; //0~255
 TIM3-&amp;gt;CCR1 = 255; //0~255
 char recv;
 /* USER CODE END 2 */
 /* Infinite loop */
 /* USER CODE BEGIN WHILE */
 while (1)
 {
	  //시리얼입력으로 문자 1개를 받아서 '0','1','2'를 구분한다!
	  if(HAL_UART_Receive(&amp;amp;huart2, &amp;amp;recv, 1, 500) == HAL_OK){
		  if(recv == '0'){
			  //브레이크
			  HAL_GPIO_WritePin(GPIOC, GPIO_PIN_0, 0); //IN1
			  HAL_GPIO_WritePin(GPIOC, GPIO_PIN_3, 0); //IN2
			  HAL_GPIO_WritePin(GPIOC, GPIO_PIN_8, 0); //IN3
			  HAL_GPIO_WritePin(GPIOC, GPIO_PIN_9, 0); //IN4
			  HAL_UART_Transmit(&amp;amp;huart2, &quot;P mode!\n&quot;, 8, 100);


		  }else if(recv == '1'){
			  //정회전
			  HAL_GPIO_WritePin(GPIOC, GPIO_PIN_0, 1); //IN1
			  HAL_GPIO_WritePin(GPIOC, GPIO_PIN_3, 0); //IN2
			  HAL_GPIO_WritePin(GPIOC, GPIO_PIN_8, 0); //IN3
			  HAL_GPIO_WritePin(GPIOC, GPIO_PIN_9, 1); //IN4
			  HAL_UART_Transmit(&amp;amp;huart2, &quot;D mode!\n&quot;, 8, 100);
		  }else if(recv == '2'){
			  //역회전
			  HAL_GPIO_WritePin(GPIOC, GPIO_PIN_0, 0); //IN1
			  HAL_GPIO_WritePin(GPIOC, GPIO_PIN_3, 1); //IN2
			  HAL_GPIO_WritePin(GPIOC, GPIO_PIN_8, 1); //IN3
			  HAL_GPIO_WritePin(GPIOC, GPIO_PIN_9, 0); //IN4
			  HAL_UART_Transmit(&amp;amp;huart2, &quot;R mode!\n&quot;, 8, 100);
		  }
	  }
   /* USER CODE END WHILE */
   /* USER CODE BEGIN 3 */
 }&lt;/code&gt;&lt;/pre&gt;</description>
      <category>프로그래밍/STM32</category>
      <author>덕력킹</author>
      <guid isPermaLink="true">https://bota.tistory.com/2453</guid>
      <comments>https://bota.tistory.com/2453#entry2453comment</comments>
      <pubDate>Mon, 17 Nov 2025 23:05:20 +0900</pubDate>
    </item>
    <item>
      <title>[STM32#10] 스탭모터(28byj-48)를 폴링방식과 타이머인터럽트(TIM2 global interrupt)를 이용한 방식으로 각도제어 해보기!(녹칸다 내맘대로 STM32)</title>
      <link>https://bota.tistory.com/2452</link>
      <description>&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;stm32.png&quot; data-origin-width=&quot;1920&quot; data-origin-height=&quot;1080&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/m0V4k/dJMcabieZzM/43CMl7ju0c4dVcYLYhrrrK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/m0V4k/dJMcabieZzM/43CMl7ju0c4dVcYLYhrrrK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/m0V4k/dJMcabieZzM/43CMl7ju0c4dVcYLYhrrrK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fm0V4k%2FdJMcabieZzM%2F43CMl7ju0c4dVcYLYhrrrK%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;1920&quot; height=&quot;1080&quot; data-filename=&quot;stm32.png&quot; data-origin-width=&quot;1920&quot; data-origin-height=&quot;1080&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/live/bcttbM80CgY&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://youtube.com/live/bcttbM80CgY&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/watch?v=bcttbM80CgY&quot; data-video-thumbnail=&quot;https://scrap.kakaocdn.net/dn/eNI0iu/hyZNKou8LO/4KJijAiKiTGCGRils0ndiK/img.jpg?width=1280&amp;amp;height=720&amp;amp;face=0_0_1280_720,https://scrap.kakaocdn.net/dn/bmZ336/hyZMDLgCQM/YFoxDB4DtTcaker7uXnIUK/img.jpg?width=1280&amp;amp;height=720&amp;amp;face=0_0_1280_720&quot; data-video-width=&quot;860&quot; data-video-height=&quot;484&quot; data-video-origin-width=&quot;860&quot; data-video-origin-height=&quot;484&quot; data-ke-mobilestyle=&quot;widthContent&quot; data-video-title=&quot;[STM32#10] 스탭모터(28byj-48)를 폴링방식과 타이머인터럽트(TIM2 global interrupt)를 이용한 방식으로 각&quot; data-original-url=&quot;&quot;&gt;&lt;iframe src=&quot;https://www.youtube.com/embed/bcttbM80CgY&quot; width=&quot;860&quot; height=&quot;484&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;[STM32#10]&amp;nbsp;스탭모터(28byj-48)를&amp;nbsp;폴링방식과&amp;nbsp;타이머인터럽트(TIM2&amp;nbsp;global&amp;nbsp;interrupt)를&amp;nbsp;이용한&amp;nbsp;방식으로&amp;nbsp;각도제어&amp;nbsp;해보기!(녹칸다&amp;nbsp;내맘대로&amp;nbsp;STM32) &lt;br /&gt;&lt;br /&gt;심심한녹칸다의&amp;nbsp;내맘대로&amp;nbsp;STM32시리즈이다! &lt;br /&gt;&lt;br /&gt;STM32시리즈의&amp;nbsp;모든&amp;nbsp;자료는&amp;nbsp;구글&amp;nbsp;슬라이드에&amp;nbsp;작성하고&amp;nbsp;모두에게&amp;nbsp;공유되어있음! &lt;br /&gt;&lt;a href=&quot;https://docs.google.com/presentation/d/1myA5iYbjuKsLWLqtRLKAiRfwUwvqB1d1RGjiMIIgp3I/edit?slide=id.g3a1f238c87f_1_154#slide=id.g3a1f238c87f_1_154&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://docs.google.com/presentation/d/1myA5iYbjuKsLWLqtRLKAiRfwUwvqB1d1RGjiMIIgp3I/edit?slide=id.g3a1f238c87f_1_154#slide=id.g3a1f238c87f_1_154&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;이번편은&amp;nbsp;9편에&amp;nbsp;이어서&amp;nbsp;스탭모터(28byj-48)를&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;1.예를들어&amp;nbsp;버튼1을&amp;nbsp;계속&amp;nbsp;누르고&amp;nbsp;있으면&amp;nbsp;&quot;누르고&amp;nbsp;있는&amp;nbsp;동안&amp;rdquo;에&amp;nbsp;스탭모터가&amp;nbsp;시계방향으로&amp;nbsp;회전하고&amp;nbsp;버튼2를&amp;nbsp;계속&amp;nbsp;누르고&amp;nbsp;있으면&amp;nbsp;&amp;ldquo;누르는&amp;nbsp;동안&amp;rdquo;&amp;nbsp;반시계방향으로&amp;nbsp;회전한다!&lt;/p&gt;
&lt;pre id=&quot;code_1762939446331&quot; class=&quot;cpp&quot; data-ke-language=&quot;cpp&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;/* USER CODE BEGIN 0 */
uint8_t seq[][4]={
		{0,0,0,1}, //1
		{0,0,1,1}, //2
		{0,0,1,0}, //3
		{0,1,1,0}, //4
		{0,1,0,0}, //5
		{1,1,0,0}, //6
		{1,0,0,0}, //7
		{1,0,0,1}  //8
};
GPIO_TypeDef *mygroup[] = {GPIOC,GPIOC,GPIOC,GPIOD};
uint16_t mypin[] = {GPIO_PIN_10,GPIO_PIN_11,GPIO_PIN_12,GPIO_PIN_2};
int seq_num = 0; //0~7
//0이면 정지, 1이면 정회전, -1이면 역회전
int direct = 0;
void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim)
{
	if(direct == 1){
		//정회전 시퀀스를 전송한다
		for(int i = 0;i&amp;lt;4;i++){
			HAL_GPIO_WritePin(mygroup[i], mypin[i], seq[seq_num][i]);
		}
		seq_num++;
		if(seq_num == 8) seq_num = 0;
	}else if(direct == -1){
		//역회전 시퀀스를 전송한다
		for(int i = 0;i&amp;lt;4;i++){
			HAL_GPIO_WritePin(mygroup[i], mypin[i], seq[seq_num][i]);
		}
		seq_num--;
		if(seq_num == -1) seq_num = 7;
	}
}
/* USER CODE END 0 */

/* USER CODE BEGIN 2 */
 HAL_TIM_Base_Start_IT(&amp;amp;htim2);
 /* USER CODE END 2 */
 /* Infinite loop */
 /* USER CODE BEGIN WHILE */
 while (1)
 {
	  //PB1을 누르면 direct가 1이되고 안누르면 0이된다!
	  //PA8을 누르면 direct가 -1이되고 안누르면 0이된다!
	  if(HAL_GPIO_ReadPin(GPIOB, GPIO_PIN_1) == 0){
		  //정회전
		  direct = 1;
	  }else if(HAL_GPIO_ReadPin(GPIOA, GPIO_PIN_8) == 0){
		  //역회전
		  direct = -1;
	  }else{
		  //정지
		  direct = 0;
	  }
   /* USER CODE END WHILE */
   /* USER CODE BEGIN 3 */
 }&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;br /&gt;2.예제1에서&amp;nbsp;스탭모터의&amp;nbsp;현재&amp;nbsp;위치값을&amp;nbsp;100밀리초간격으로&amp;nbsp;시리얼출력해서&amp;nbsp;PC에서&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-filename=&quot;02.PNG&quot; data-origin-width=&quot;1052&quot; data-origin-height=&quot;676&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bQ85kp/dJMcabbtgRv/lSF4o695mRFnnltkr1AsL0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bQ85kp/dJMcabbtgRv/lSF4o695mRFnnltkr1AsL0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bQ85kp/dJMcabbtgRv/lSF4o695mRFnnltkr1AsL0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbQ85kp%2FdJMcabbtgRv%2FlSF4o695mRFnnltkr1AsL0%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;1052&quot; height=&quot;676&quot; data-filename=&quot;02.PNG&quot; data-origin-width=&quot;1052&quot; data-origin-height=&quot;676&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;pre id=&quot;code_1762939460049&quot; class=&quot;cpp&quot; data-ke-language=&quot;cpp&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;/* USER CODE BEGIN 0 */
uint8_t seq[][4]={
		{0,0,0,1}, //1
		{0,0,1,1}, //2
		{0,0,1,0}, //3
		{0,1,1,0}, //4
		{0,1,0,0}, //5
		{1,1,0,0}, //6
		{1,0,0,0}, //7
		{1,0,0,1}  //8
};
GPIO_TypeDef *mygroup[] = {GPIOC,GPIOC,GPIOC,GPIOD};
uint16_t mypin[] = {GPIO_PIN_10,GPIO_PIN_11,GPIO_PIN_12,GPIO_PIN_2};
int seq_num = 0; //0~7
//0이면 정지, 1이면 정회전, -1이면 역회전
int direct = 0;
int32_t now_pos = 0;
void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim)
{
	if(direct == 1){
		//정회전 시퀀스를 전송한다
		for(int i = 0;i&amp;lt;4;i++){
			HAL_GPIO_WritePin(mygroup[i], mypin[i], seq[seq_num][i]);
		}
		seq_num++;
		if(seq_num == 8) seq_num = 0;
		now_pos++;
	}else if(direct == -1){
		//역회전 시퀀스를 전송한다
		for(int i = 0;i&amp;lt;4;i++){
			HAL_GPIO_WritePin(mygroup[i], mypin[i], seq[seq_num][i]);
		}
		seq_num--;
		if(seq_num == -1) seq_num = 7;
		now_pos--;
	}
}
/* USER CODE END 0 */

/* USER CODE BEGIN 2 */
 HAL_TIM_Base_Start_IT(&amp;amp;htim2);
 uint32_t nockanda_t = 0;
 char buff[50];
 /* USER CODE END 2 */
 /* Infinite loop */
 /* USER CODE BEGIN WHILE */
 while (1)
 {
	  //100밀리초 간격으로 전송한다
	  if(HAL_GetTick()-nockanda_t &amp;gt; 100){
		  nockanda_t = HAL_GetTick();
		  //녹칸다가 위치를 계속 올려서 32000정도를 넘겼을때 이상한값이 나온다면 %d가 아닌것이다!
		  sprintf(buff,&quot;now_pos = %d\n&quot;,now_pos);
		  HAL_UART_Transmit(&amp;amp;huart2, buff, strlen(buff), 100);
	  }
	  //PB1을 누르면 direct가 1이되고 안누르면 0이된다!
	  //PA8을 누르면 direct가 -1이되고 안누르면 0이된다!
	  if(HAL_GPIO_ReadPin(GPIOB, GPIO_PIN_1) == 0){
		  //정회전
		  direct = 1;
	  }else if(HAL_GPIO_ReadPin(GPIOA, GPIO_PIN_8) == 0){
		  //역회전
		  direct = -1;
	  }else{
		  //정지
		  direct = 0;
	  }
   /* USER CODE END WHILE */
   /* USER CODE BEGIN 3 */
 }&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;br /&gt;3.로터리엔코더(PA11,PA12)를&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-filename=&quot;03.PNG&quot; data-origin-width=&quot;1081&quot; data-origin-height=&quot;670&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bE6mG4/dJMcabP4Qzg/feHh1kgJ3xBkesIkql3wlk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bE6mG4/dJMcabP4Qzg/feHh1kgJ3xBkesIkql3wlk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bE6mG4/dJMcabP4Qzg/feHh1kgJ3xBkesIkql3wlk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbE6mG4%2FdJMcabP4Qzg%2FfeHh1kgJ3xBkesIkql3wlk%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;1081&quot; height=&quot;670&quot; data-filename=&quot;03.PNG&quot; data-origin-width=&quot;1081&quot; data-origin-height=&quot;670&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;pre id=&quot;code_1762939482804&quot; class=&quot;cpp&quot; data-ke-language=&quot;cpp&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;/* USER CODE BEGIN 0 */
uint8_t seq[][4]={
		{0,0,0,1}, //1
		{0,0,1,1}, //2
		{0,0,1,0}, //3
		{0,1,1,0}, //4
		{0,1,0,0}, //5
		{1,1,0,0}, //6
		{1,0,0,0}, //7
		{1,0,0,1}  //8
};
GPIO_TypeDef *mygroup[] = {GPIOC,GPIOC,GPIOC,GPIOD};
uint16_t mypin[] = {GPIO_PIN_10,GPIO_PIN_11,GPIO_PIN_12,GPIO_PIN_2};
int seq_num = 0; //0~7
int32_t now_pos = 0;
int32_t target_pos = 0;
void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim)
{
	if(now_pos &amp;lt; target_pos){
		//정회전 시퀀스를 전송한다
		for(int i = 0;i&amp;lt;4;i++){
			HAL_GPIO_WritePin(mygroup[i], mypin[i], seq[seq_num][i]);
		}
		seq_num++;
		if(seq_num == 8) seq_num = 0;
		now_pos++;
	}else if(now_pos &amp;gt; target_pos){
		//역회전 시퀀스를 전송한다
		for(int i = 0;i&amp;lt;4;i++){
			HAL_GPIO_WritePin(mygroup[i], mypin[i], seq[seq_num][i]);
		}
		seq_num--;
		if(seq_num == -1) seq_num = 7;
		now_pos--;
	}
}
/* USER CODE END 0 */

/* USER CODE BEGIN 2 */
 HAL_TIM_Base_Start_IT(&amp;amp;htim2);
 uint32_t nockanda_t = 0;
 char buff[50];
 uint8_t old_A = 0;
 /* USER CODE END 2 */
 /* Infinite loop */
 /* USER CODE BEGIN WHILE */
 while (1)
 {
	  //100밀리초 간격으로 전송한다
	  if(HAL_GetTick()-nockanda_t &amp;gt; 100){
		  nockanda_t = HAL_GetTick();
		  //녹칸다가 위치를 계속 올려서 32000정도를 넘겼을때 이상한값이 나온다면 %d가 아닌것이다!
		  sprintf(buff,&quot;now_pos = %d, target_pos = %d\n&quot;,now_pos, target_pos);
		  HAL_UART_Transmit(&amp;amp;huart2, buff, strlen(buff), 100);
	  }
	  //A의 상승엣지가 검출되었을때 B가 LOW면 시계방향, HIGH면 반시계방향
	  uint8_t now_A = HAL_GPIO_ReadPin(GPIOA, GPIO_PIN_11);
	  if(now_A == 1 &amp;amp;&amp;amp; old_A == 0){
		  uint8_t now_B = HAL_GPIO_ReadPin(GPIOA, GPIO_PIN_12);
		  if(now_B == 0){
			  //시계
			  target_pos += 8;
		  }else{
			  //반시계
			  target_pos -= 8;
		  }
	  }
	  old_A = now_A;
   /* USER CODE END WHILE */
   /* USER CODE BEGIN 3 */
 }&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;br /&gt;4.예제3번처럼&amp;nbsp;로터리엔코더를&amp;nbsp;돌리면&amp;nbsp;실시간으로&amp;nbsp;따라가는게&amp;nbsp;아니라&amp;nbsp;로터리엔코더에&amp;nbsp;붙어있는&amp;nbsp;스위치(PC7)를&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-filename=&quot;04.PNG&quot; data-origin-width=&quot;1102&quot; data-origin-height=&quot;659&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/EvRXm/dJMcabP4Qzm/7IULpsxsynkTm97XKwa4ek/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/EvRXm/dJMcabP4Qzm/7IULpsxsynkTm97XKwa4ek/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/EvRXm/dJMcabP4Qzm/7IULpsxsynkTm97XKwa4ek/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FEvRXm%2FdJMcabP4Qzm%2F7IULpsxsynkTm97XKwa4ek%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;1102&quot; height=&quot;659&quot; data-filename=&quot;04.PNG&quot; data-origin-width=&quot;1102&quot; data-origin-height=&quot;659&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;pre id=&quot;code_1762939499664&quot; class=&quot;cpp&quot; data-ke-language=&quot;cpp&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;/* USER CODE BEGIN 0 */
uint8_t seq[][4]={
		{0,0,0,1}, //1
		{0,0,1,1}, //2
		{0,0,1,0}, //3
		{0,1,1,0}, //4
		{0,1,0,0}, //5
		{1,1,0,0}, //6
		{1,0,0,0}, //7
		{1,0,0,1}  //8
};
GPIO_TypeDef *mygroup[] = {GPIOC,GPIOC,GPIOC,GPIOD};
uint16_t mypin[] = {GPIO_PIN_10,GPIO_PIN_11,GPIO_PIN_12,GPIO_PIN_2};
int seq_num = 0; //0~7
int32_t now_pos = 0;
int32_t target_pos = 0;
void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim)
{
	if(now_pos &amp;lt; target_pos){
		//정회전 시퀀스를 전송한다
		for(int i = 0;i&amp;lt;4;i++){
			HAL_GPIO_WritePin(mygroup[i], mypin[i], seq[seq_num][i]);
		}
		seq_num++;
		if(seq_num == 8) seq_num = 0;
		now_pos++;
	}else if(now_pos &amp;gt; target_pos){
		//역회전 시퀀스를 전송한다
		for(int i = 0;i&amp;lt;4;i++){
			HAL_GPIO_WritePin(mygroup[i], mypin[i], seq[seq_num][i]);
		}
		seq_num--;
		if(seq_num == -1) seq_num = 7;
		now_pos--;
	}
}
/* USER CODE END 0 */

/* USER CODE BEGIN 2 */
 HAL_TIM_Base_Start_IT(&amp;amp;htim2);
 uint32_t nockanda_t = 0;
 char buff[50];
 uint8_t old_A = 0;
 int32_t rotary_pos = 0;
 /* USER CODE END 2 */
 /* Infinite loop */
 /* USER CODE BEGIN WHILE */
 while (1)
 {
	  //100밀리초 간격으로 전송한다
	  if(HAL_GetTick()-nockanda_t &amp;gt; 100){
		  nockanda_t = HAL_GetTick();
		  sprintf(buff,&quot;now_pos = %d, rotary_pos = %d\n&quot;,now_pos, rotary_pos);
		  HAL_UART_Transmit(&amp;amp;huart2, buff, strlen(buff), 100);
	  }
	  //PC7을 누르면 rotary_pos가 target_pos로 copy된다
	  if(HAL_GPIO_ReadPin(GPIOC, GPIO_PIN_7) == 0){
		  target_pos = rotary_pos;
	  }
	  //A의 상승엣지가 검출되었을때 B가 LOW면 시계방향, HIGH면 반시계방향
	  uint8_t now_A = HAL_GPIO_ReadPin(GPIOA, GPIO_PIN_11);
	  if(now_A == 1 &amp;amp;&amp;amp; old_A == 0){
		  uint8_t now_B = HAL_GPIO_ReadPin(GPIOA, GPIO_PIN_12);
		  if(now_B == 0){
			  //시계
			  rotary_pos += 8;
		  }else{
			  //반시계
			  rotary_pos -= 8;
		  }
	  }
	  old_A = now_A;
   /* USER CODE END WHILE */
   /* USER CODE BEGIN 3 */
 }&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;br /&gt;5.스탭모터가&amp;nbsp;시계방향으로&amp;nbsp;항상&amp;nbsp;회전을&amp;nbsp;하는데,&amp;nbsp;버튼1을&amp;nbsp;누르면&amp;nbsp;타이머인터럽트의&amp;nbsp;주기가&amp;nbsp;1.5밀리초로하고,&amp;nbsp;버튼2를&amp;nbsp;누르면&amp;nbsp;800마이크로초로하고,&amp;nbsp;버튼3을&amp;nbsp;누르면&amp;nbsp;10밀리초로&amp;nbsp;하시오!(TIM2의&amp;nbsp;ARR을&amp;nbsp;수정)&lt;/p&gt;
&lt;pre id=&quot;code_1762939518858&quot; class=&quot;cpp&quot; data-ke-language=&quot;cpp&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;/* USER CODE BEGIN 0 */
uint8_t seq[][4]={
		{0,0,0,1}, //1
		{0,0,1,1}, //2
		{0,0,1,0}, //3
		{0,1,1,0}, //4
		{0,1,0,0}, //5
		{1,1,0,0}, //6
		{1,0,0,0}, //7
		{1,0,0,1}  //8
};
GPIO_TypeDef *mygroup[] = {GPIOC,GPIOC,GPIOC,GPIOD};
uint16_t mypin[] = {GPIO_PIN_10,GPIO_PIN_11,GPIO_PIN_12,GPIO_PIN_2};
int seq_num = 0; //0~7
void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim)
{
	for(int i = 0;i&amp;lt;4;i++){
		HAL_GPIO_WritePin(mygroup[i], mypin[i], seq[seq_num][i]);
	}
	seq_num++;
	if(seq_num == 8) seq_num = 0;
}
/* USER CODE END 0 */

/* USER CODE BEGIN 2 */
 HAL_TIM_Base_Start_IT(&amp;amp;htim2);
 /* USER CODE END 2 */
 /* Infinite loop */
 /* USER CODE BEGIN WHILE */
 while (1)
 {
	  //PB1을 누르면 ARR이 1500-1이 된다!
	  if(HAL_GPIO_ReadPin(GPIOB, GPIO_PIN_1) == 0){
		  TIM2-&amp;gt;ARR = 1500-1;
	  }
	  //PA8을 누르면 ARR이 800-1이 된다
	  if(HAL_GPIO_ReadPin(GPIOA, GPIO_PIN_8) == 0){
		  TIM2-&amp;gt;ARR = 800-1;
	  }
	  //PB2을 누르면 ARR이 10000-1이 된다
	  if(HAL_GPIO_ReadPin(GPIOB, GPIO_PIN_2) == 0){
		  TIM2-&amp;gt;ARR = 10000-1;
	  }
   /* USER CODE END WHILE */
   /* USER CODE BEGIN 3 */
 }&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;br /&gt;6.버튼1을&amp;nbsp;누르면&amp;nbsp;스탭모터가&amp;nbsp;반시계방향으로&amp;nbsp;회전한다!&amp;nbsp;버튼2를&amp;nbsp;누르면&amp;nbsp;정지한다!&amp;nbsp;버튼3을&amp;nbsp;누르면&amp;nbsp;시계방향으로&amp;nbsp;회전한다!&amp;nbsp;이때&amp;nbsp;가변저항을&amp;nbsp;이용해서&amp;nbsp;속도를&amp;nbsp;0.8밀리초~10밀리초&amp;nbsp;범위로&amp;nbsp;조절하시오!(속도제어)&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;06.PNG&quot; data-origin-width=&quot;1152&quot; data-origin-height=&quot;607&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/ccCG70/dJMcacBrXLA/dFIN59bbyDNLfbCqm6Frwk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/ccCG70/dJMcacBrXLA/dFIN59bbyDNLfbCqm6Frwk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/ccCG70/dJMcacBrXLA/dFIN59bbyDNLfbCqm6Frwk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FccCG70%2FdJMcacBrXLA%2FdFIN59bbyDNLfbCqm6Frwk%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;1152&quot; height=&quot;607&quot; data-filename=&quot;06.PNG&quot; data-origin-width=&quot;1152&quot; data-origin-height=&quot;607&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;pre id=&quot;code_1762939538732&quot; class=&quot;cpp&quot; data-ke-language=&quot;cpp&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;/* USER CODE BEGIN 0 */
uint8_t seq[][4]={
		{0,0,0,1}, //1
		{0,0,1,1}, //2
		{0,0,1,0}, //3
		{0,1,1,0}, //4
		{0,1,0,0}, //5
		{1,1,0,0}, //6
		{1,0,0,0}, //7
		{1,0,0,1}  //8
};
GPIO_TypeDef *mygroup[] = {GPIOC,GPIOC,GPIOC,GPIOD};
uint16_t mypin[] = {GPIO_PIN_10,GPIO_PIN_11,GPIO_PIN_12,GPIO_PIN_2};
int seq_num = 0; //0~7
int direct = 0;
void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim)
{
	if(direct == 1){
		for(int i = 0;i&amp;lt;4;i++){
			HAL_GPIO_WritePin(mygroup[i], mypin[i], seq[seq_num][i]);
		}
		seq_num++;
		if(seq_num == 8) seq_num = 0;
	}else if(direct == -1){
		for(int i = 0;i&amp;lt;4;i++){
			HAL_GPIO_WritePin(mygroup[i], mypin[i], seq[seq_num][i]);
		}
		seq_num--;
		if(seq_num == -1) seq_num = 7;
	}
}
/* USER CODE END 0 */

/* USER CODE BEGIN 2 */
 HAL_TIM_Base_Start_IT(&amp;amp;htim2);
 HAL_ADC_Start(&amp;amp;hadc1);
 uint16_t adc_value0 = 0;
 uint32_t nockanda_t = 0;
 char buff[50];
 /* USER CODE END 2 */
 /* Infinite loop */
 /* USER CODE BEGIN WHILE */
 while (1)
 {
	  if(HAL_GetTick() - nockanda_t &amp;gt; 100){
		  nockanda_t = HAL_GetTick();
		  if(HAL_ADC_PollForConversion(&amp;amp;hadc1, 10) == HAL_OK)
		  {
			  // 값 처리
			  adc_value0 = HAL_ADC_GetValue(&amp;amp;hadc1); //0~4095
			  //0 ~ 4095구간을 10000 ~ 800으로 바꾼다
			  adc_value0 = 10000 - (10000-800) * adc_value0 / 4095.0;
			  sprintf(buff,&quot;A0 = %d\n&quot;,adc_value0);
			  HAL_UART_Transmit(&amp;amp;huart2, buff, strlen(buff), 100);
			  if(adc_value0 &amp;gt;= 800 &amp;amp;&amp;amp; adc_value0 &amp;lt;= 10000){
				  TIM2-&amp;gt;ARR = adc_value0;
			  }
		  }
	  }
	  //PB1을 누르면 역회전
	  if(HAL_GPIO_ReadPin(GPIOB, GPIO_PIN_1) == 0){
		  direct = -1;
	  }
	  //PA8을 누르면 정지
	  if(HAL_GPIO_ReadPin(GPIOA, GPIO_PIN_8) == 0){
		  direct = 0;
	  }
	  //PB2을 누르면 정회전
	  if(HAL_GPIO_ReadPin(GPIOB, GPIO_PIN_2) == 0){
		  direct = 1;
	  }
   /* USER CODE END WHILE */
   /* USER CODE BEGIN 3 */
 }&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;br /&gt;7.녹칸다가&amp;nbsp;스탭모터의&amp;nbsp;목표위치를&amp;nbsp;putty에서&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-filename=&quot;07.PNG&quot; data-origin-width=&quot;1072&quot; data-origin-height=&quot;607&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/Yb0Ge/dJMcagqjC7s/hT6BifW4XoltrH0Twg7W21/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/Yb0Ge/dJMcagqjC7s/hT6BifW4XoltrH0Twg7W21/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/Yb0Ge/dJMcagqjC7s/hT6BifW4XoltrH0Twg7W21/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FYb0Ge%2FdJMcagqjC7s%2FhT6BifW4XoltrH0Twg7W21%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;607&quot; data-filename=&quot;07.PNG&quot; data-origin-width=&quot;1072&quot; data-origin-height=&quot;607&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;pre id=&quot;code_1762939550649&quot; class=&quot;cpp&quot; data-ke-language=&quot;cpp&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;/* USER CODE BEGIN 0 */
uint8_t seq[][4]={
		{0,0,0,1}, //1
		{0,0,1,1}, //2
		{0,0,1,0}, //3
		{0,1,1,0}, //4
		{0,1,0,0}, //5
		{1,1,0,0}, //6
		{1,0,0,0}, //7
		{1,0,0,1}  //8
};
GPIO_TypeDef *mygroup[] = {GPIOC,GPIOC,GPIOC,GPIOD};
uint16_t mypin[] = {GPIO_PIN_10,GPIO_PIN_11,GPIO_PIN_12,GPIO_PIN_2};
int seq_num = 0; //0~7
int32_t now_pos = 0;
int32_t target_pos = 0;
void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim)
{
	if(now_pos &amp;lt; target_pos){
		for(int i = 0;i&amp;lt;4;i++){
			HAL_GPIO_WritePin(mygroup[i], mypin[i], seq[seq_num][i]);
		}
		seq_num++;
		if(seq_num == 8) seq_num = 0;
		now_pos++;
	}else if(now_pos &amp;gt; target_pos){
		for(int i = 0;i&amp;lt;4;i++){
			HAL_GPIO_WritePin(mygroup[i], mypin[i], seq[seq_num][i]);
		}
		seq_num--;
		if(seq_num == -1) seq_num = 7;
		now_pos--;
	}
}
/* USER CODE END 0 */

/* USER CODE BEGIN 2 */
 HAL_TIM_Base_Start_IT(&amp;amp;htim2);
 char rx_buff[50];
 char tx_buff[50];
 char recv = 0;
 /* USER CODE END 2 */
 /* Infinite loop */
 /* USER CODE BEGIN WHILE */
 while (1)
 {
	  //녹칸다가 입력한 숫자대로 스탭모터가 목표위치로 이동한다!
	  //녹칸다가 보낸 숫자를 그대로 echo해서 출력해라!
	  int rx_index = 0;
	  while(HAL_UART_Receive(&amp;amp;huart2, &amp;amp;recv, 1, 100) == HAL_OK){
		  rx_buff[rx_index] = recv;
		  rx_index++;
		  if(recv == '\r'){
			  //putty에서 마지막 종료문자가 왔다!
			  rx_buff[rx_index] = '\0';
			  sprintf(tx_buff,&quot;SET TARGET_POS = %s\n&quot;,rx_buff);
			  HAL_UART_Transmit(&amp;amp;huart2, tx_buff, strlen(tx_buff), 100);
			  target_pos = atoi(rx_buff);
			  break;
		  }
	  }
   /* USER CODE END WHILE */
   /* USER CODE BEGIN 3 */
 }&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;br /&gt;8.예제6에서&amp;nbsp;시계방향으로&amp;nbsp;회전할때&amp;nbsp;리미트스위치&amp;nbsp;역할을&amp;nbsp;버튼4가&amp;nbsp;하고,&amp;nbsp;반시계방향으로&amp;nbsp;회전할때&amp;nbsp;리미트스위치&amp;nbsp;역할을&amp;nbsp;버튼5가&amp;nbsp;할때&amp;nbsp;리미트스위치에&amp;nbsp;감지되면&amp;nbsp;스탭모터가&amp;nbsp;정지하도록&amp;nbsp;하시오!&lt;/p&gt;
&lt;pre id=&quot;code_1762939563767&quot; class=&quot;cpp&quot; data-ke-language=&quot;cpp&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;/* USER CODE BEGIN 0 */
uint8_t seq[][4]={
		{0,0,0,1}, //1
		{0,0,1,1}, //2
		{0,0,1,0}, //3
		{0,1,1,0}, //4
		{0,1,0,0}, //5
		{1,1,0,0}, //6
		{1,0,0,0}, //7
		{1,0,0,1}  //8
};
GPIO_TypeDef *mygroup[] = {GPIOC,GPIOC,GPIOC,GPIOD};
uint16_t mypin[] = {GPIO_PIN_10,GPIO_PIN_11,GPIO_PIN_12,GPIO_PIN_2};
int seq_num = 0; //0~7
int32_t direct = 0;
void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim)
{
	if(direct == 1){
		if(HAL_GPIO_ReadPin(GPIOB, GPIO_PIN_6) == 1){
			for(int i = 0;i&amp;lt;4;i++){
				HAL_GPIO_WritePin(mygroup[i], mypin[i], seq[seq_num][i]);
			}
			seq_num++;
			if(seq_num == 8) seq_num = 0;
		}
	}else if(direct == -1){
		if(HAL_GPIO_ReadPin(GPIOC, GPIO_PIN_5) == 1){
			for(int i = 0;i&amp;lt;4;i++){
				HAL_GPIO_WritePin(mygroup[i], mypin[i], seq[seq_num][i]);
			}
			seq_num--;
			if(seq_num == -1) seq_num = 7;
		}
	}
}
/* USER CODE END 0 */

/* USER CODE BEGIN 2 */
 HAL_TIM_Base_Start_IT(&amp;amp;htim2);
 /* USER CODE END 2 */
 /* Infinite loop */
 /* USER CODE BEGIN WHILE */
 while (1)
 {
	  //PB1을 누르면 역회전
	  if(HAL_GPIO_ReadPin(GPIOB, GPIO_PIN_1) == 0){
		  direct = -1;
	  }
	  //PA8을 누르면 정지
	  if(HAL_GPIO_ReadPin(GPIOA, GPIO_PIN_8) == 0){
		  direct = 0;
	  }
	  //PB2을 누르면 정회전
	  if(HAL_GPIO_ReadPin(GPIOB, GPIO_PIN_2) == 0){
		  direct = 1;
	  }
   /* USER CODE END WHILE */
   /* USER CODE BEGIN 3 */
 }&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;br /&gt;9.로터리엔코더를&amp;nbsp;돌려서&amp;nbsp;LED&amp;nbsp;8개중&amp;nbsp;1개의&amp;nbsp;LED만&amp;nbsp;켜지도록&amp;nbsp;하고,&amp;nbsp;LED가&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-filename=&quot;09.PNG&quot; data-origin-width=&quot;1049&quot; data-origin-height=&quot;648&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/JLA7C/dJMcagqjC7E/bu22V0DpfabgG3euFdrVQ1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/JLA7C/dJMcagqjC7E/bu22V0DpfabgG3euFdrVQ1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/JLA7C/dJMcagqjC7E/bu22V0DpfabgG3euFdrVQ1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FJLA7C%2FdJMcagqjC7E%2Fbu22V0DpfabgG3euFdrVQ1%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;1049&quot; height=&quot;648&quot; data-filename=&quot;09.PNG&quot; data-origin-width=&quot;1049&quot; data-origin-height=&quot;648&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;pre id=&quot;code_1762939574656&quot; class=&quot;cpp&quot; data-ke-language=&quot;cpp&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;/* USER CODE BEGIN 0 */
uint8_t seq[][4]={
		{0,0,0,1}, //1
		{0,0,1,1}, //2
		{0,0,1,0}, //3
		{0,1,1,0}, //4
		{0,1,0,0}, //5
		{1,1,0,0}, //6
		{1,0,0,0}, //7
		{1,0,0,1}  //8
};
GPIO_TypeDef *mygroup[] = {GPIOC,GPIOC,GPIOC,GPIOD};
uint16_t mypin[] = {GPIO_PIN_10,GPIO_PIN_11,GPIO_PIN_12,GPIO_PIN_2};
int seq_num = 0; //0~7
int32_t now_pos = 0;
int32_t target_pos = 0;
void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim)
{
	if(now_pos &amp;lt; target_pos){
		for(int i = 0;i&amp;lt;4;i++){
			HAL_GPIO_WritePin(mygroup[i], mypin[i], seq[seq_num][i]);
		}
		seq_num++;
		if(seq_num == 8) seq_num = 0;
		now_pos++;
	}else if(now_pos &amp;gt; target_pos){
		for(int i = 0;i&amp;lt;4;i++){
			HAL_GPIO_WritePin(mygroup[i], mypin[i], seq[seq_num][i]);
		}
		seq_num--;
		if(seq_num == -1) seq_num = 7;
		now_pos--;
	}
}
/* USER CODE END 0 */
/* USER CODE BEGIN 2 */
 HAL_TIM_Base_Start_IT(&amp;amp;htim2);
 uint8_t old_A = 0;
 int32_t rotary_pos = 0;
 GPIO_TypeDef *mygroup[] = {GPIOB,GPIOB,GPIOB,GPIOB,GPIOB,GPIOB,GPIOC,GPIOB};
 uint16_t mypin[] = {GPIO_PIN_3,GPIO_PIN_13,GPIO_PIN_5,GPIO_PIN_14,GPIO_PIN_4,GPIO_PIN_15,GPIO_PIN_4,GPIO_PIN_7};
 char buff[50];
 int led_pos = 0;
 HAL_GPIO_WritePin(mygroup[0],mypin[0], 1);
 /* USER CODE END 2 */
 /* Infinite loop */
 /* USER CODE BEGIN WHILE */
 while (1)
 {
	  if(HAL_GPIO_ReadPin(GPIOC, GPIO_PIN_7) == 0){
		  target_pos = rotary_pos;
	  }
	  //A의 상승엣지가 검출되었을때 B가 LOW면 시계방향, HIGH면 반시계방향
	  uint8_t now_A = HAL_GPIO_ReadPin(GPIOA, GPIO_PIN_11);
	  if(now_A == 1 &amp;amp;&amp;amp; old_A == 0){
		  uint8_t now_B = HAL_GPIO_ReadPin(GPIOA, GPIO_PIN_12);
		  if(now_B == 0){
			  //시계
			  rotary_pos += 512;
			  led_pos++;
			  if(led_pos == 8) led_pos = 0;
		  }else{
			  //반시계
			  rotary_pos -= 512;
			  led_pos--;
			  if(led_pos == -1) led_pos = 7;
		  }
		  for(int i = 0;i&amp;lt;8;i++){
			  if(i == led_pos) HAL_GPIO_WritePin(mygroup[i],mypin[i], 1);
			  else HAL_GPIO_WritePin(mygroup[i],mypin[i], 0);
		  }
		  //현재 스탭모터의 각도(디그리)를 출력한다!
		  sprintf(buff,&quot;degree = %d\n&quot;,360*rotary_pos/4096);
		  HAL_UART_Transmit(&amp;amp;huart2, buff, strlen(buff), 100);
	  }
	  old_A = now_A;
   /* USER CODE END WHILE */
   /* USER CODE BEGIN 3 */
 }&lt;/code&gt;&lt;/pre&gt;</description>
      <category>프로그래밍/STM32</category>
      <author>덕력킹</author>
      <guid isPermaLink="true">https://bota.tistory.com/2452</guid>
      <comments>https://bota.tistory.com/2452#entry2452comment</comments>
      <pubDate>Wed, 12 Nov 2025 18:28:20 +0900</pubDate>
    </item>
    <item>
      <title>[STM32#09] 스탭모터(28byj-48)를 폴링방식과 타이머인터럽트(TIM2 global interrupt)를 이용한 방식으로 각도제어 해보기!(녹칸다 내맘대로 STM32)</title>
      <link>https://bota.tistory.com/2451</link>
      <description>&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;stm32.png&quot; data-origin-width=&quot;1920&quot; data-origin-height=&quot;1080&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/DI80R/dJMcaaDCF4N/WKINvtChAkzcybyjWf18u1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/DI80R/dJMcaaDCF4N/WKINvtChAkzcybyjWf18u1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/DI80R/dJMcaaDCF4N/WKINvtChAkzcybyjWf18u1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FDI80R%2FdJMcaaDCF4N%2FWKINvtChAkzcybyjWf18u1%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;1920&quot; height=&quot;1080&quot; data-filename=&quot;stm32.png&quot; data-origin-width=&quot;1920&quot; data-origin-height=&quot;1080&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/live/p5zGr7EtAIY&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://youtube.com/live/p5zGr7EtAIY&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/watch?v=p5zGr7EtAIY&quot; data-video-thumbnail=&quot;https://scrap.kakaocdn.net/dn/edYsLL/hyZNoTRIg5/LvK6lJThniwcKakVKn4Jjk/img.jpg?width=1280&amp;amp;height=720&amp;amp;face=0_0_1280_720,https://scrap.kakaocdn.net/dn/isb7H/hyZNiszUZ3/OiLeiLDHWqoLn5fn2NI5m1/img.jpg?width=1280&amp;amp;height=720&amp;amp;face=0_0_1280_720&quot; data-video-width=&quot;860&quot; data-video-height=&quot;484&quot; data-video-origin-width=&quot;860&quot; data-video-origin-height=&quot;484&quot; data-ke-mobilestyle=&quot;widthContent&quot; data-video-title=&quot;[STM32#09] 스탭모터(28byj-48)를 폴링방식과 타이머인터럽트(TIM2 global interrupt)를 이용한 방식으로 각&quot; data-original-url=&quot;&quot;&gt;&lt;iframe src=&quot;https://www.youtube.com/embed/p5zGr7EtAIY&quot; width=&quot;860&quot; height=&quot;484&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;[STM32#09]&amp;nbsp;스탭모터(28byj-48)를&amp;nbsp;폴링방식과&amp;nbsp;타이머인터럽트(TIM2&amp;nbsp;global&amp;nbsp;interrupt)를&amp;nbsp;이용한&amp;nbsp;방식으로&amp;nbsp;각도제어&amp;nbsp;해보기!(녹칸다&amp;nbsp;내맘대로&amp;nbsp;STM32) &lt;br /&gt;&lt;br /&gt;심심한녹칸다의&amp;nbsp;내맘대로&amp;nbsp;STM32시리즈이다! &lt;br /&gt;&lt;br /&gt;STM32시리즈의&amp;nbsp;모든&amp;nbsp;자료는&amp;nbsp;구글&amp;nbsp;슬라이드에&amp;nbsp;작성하고&amp;nbsp;모두에게&amp;nbsp;공유되어있음! &lt;br /&gt;&lt;a href=&quot;https://docs.google.com/presentation/d/1myA5iYbjuKsLWLqtRLKAiRfwUwvqB1d1RGjiMIIgp3I/edit?slide=id.g3a1b0dc0a1e_1_75#slide=id.g3a1b0dc0a1e_1_75&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://docs.google.com/presentation/d/1myA5iYbjuKsLWLqtRLKAiRfwUwvqB1d1RGjiMIIgp3I/edit?slide=id.g3a1b0dc0a1e_1_75#slide=id.g3a1b0dc0a1e_1_75&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;이번편은&amp;nbsp;녹칸다의&amp;nbsp;STM32쉴드에&amp;nbsp;스탭모터(28bjy-48)와&amp;nbsp;드라이버(ULN2003)을&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&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;회로도1.PNG&quot; data-origin-width=&quot;1137&quot; data-origin-height=&quot;518&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/7e7YQ/dJMcadtz3qP/WIF4Mfq5heFWpbDfh1ZhG1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/7e7YQ/dJMcadtz3qP/WIF4Mfq5heFWpbDfh1ZhG1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/7e7YQ/dJMcadtz3qP/WIF4Mfq5heFWpbDfh1ZhG1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2F7e7YQ%2FdJMcadtz3qP%2FWIF4Mfq5heFWpbDfh1ZhG1%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;1137&quot; height=&quot;518&quot; data-filename=&quot;회로도1.PNG&quot; data-origin-width=&quot;1137&quot; data-origin-height=&quot;518&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;회로도2.PNG&quot; data-origin-width=&quot;963&quot; data-origin-height=&quot;588&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cqP2JG/dJMcadtz3qO/hegGl7MkIskKigkDsERfD1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cqP2JG/dJMcadtz3qO/hegGl7MkIskKigkDsERfD1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cqP2JG/dJMcadtz3qO/hegGl7MkIskKigkDsERfD1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FcqP2JG%2FdJMcadtz3qO%2FhegGl7MkIskKigkDsERfD1%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;963&quot; height=&quot;588&quot; data-filename=&quot;회로도2.PNG&quot; data-origin-width=&quot;963&quot; data-origin-height=&quot;588&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;(스탭모터 제어신호)&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;회로도3.PNG&quot; data-origin-width=&quot;1066&quot; data-origin-height=&quot;479&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/eyVRVN/dJMcacuFMLN/fi6lU1VUmcuC0GGl73jurK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/eyVRVN/dJMcacuFMLN/fi6lU1VUmcuC0GGl73jurK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/eyVRVN/dJMcacuFMLN/fi6lU1VUmcuC0GGl73jurK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FeyVRVN%2FdJMcacuFMLN%2Ffi6lU1VUmcuC0GGl73jurK%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;1066&quot; height=&quot;479&quot; data-filename=&quot;회로도3.PNG&quot; data-origin-width=&quot;1066&quot; data-origin-height=&quot;479&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;(스탭모터 신호의 해석)&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;1.녹칸다가&amp;nbsp;제시한&amp;nbsp;표에서&amp;nbsp;빼기기호(-)가&amp;nbsp;있는건&amp;nbsp;HIGH신호이고&amp;nbsp;비워져있는건&amp;nbsp;LOW신호를&amp;nbsp;의미한다! &lt;br /&gt;2.스탭모터제어에는&amp;nbsp;한&amp;nbsp;주기에&amp;nbsp;8개의&amp;nbsp;신호를&amp;nbsp;전송해야하는데,&amp;nbsp;1~8순으로&amp;nbsp;전송하면&amp;nbsp;시계(CW)방향,&amp;nbsp;8~1순으로&amp;nbsp;전송하면&amp;nbsp;반시계(CCW)방향으로&amp;nbsp;회전하게된다! &lt;br /&gt;3.STM32에서는&amp;nbsp;HIGH신호를&amp;nbsp;숫자1로&amp;nbsp;해석하고,&amp;nbsp;LOW신호를&amp;nbsp;숫자&amp;nbsp;0으로&amp;nbsp;해석한다! &lt;br /&gt;4.그러면&amp;nbsp;보내줘야할&amp;nbsp;1번신호의&amp;nbsp;경우&amp;nbsp;IN1,IN2,IN3,IN4순서로&amp;nbsp;보았을때&amp;nbsp;IN1은&amp;nbsp;0,&amp;nbsp;IN2는&amp;nbsp;0,&amp;nbsp;IN3은&amp;nbsp;0,&amp;nbsp;IN4는&amp;nbsp;1이라는&amp;nbsp;것을&amp;nbsp;전송해야함을&amp;nbsp;의미한다! &lt;br /&gt;5.IN1이&amp;nbsp;PC10이고,&amp;nbsp;IN2가&amp;nbsp;PC11이고,&amp;nbsp;IN3이&amp;nbsp;PC12고,&amp;nbsp;IN4가&amp;nbsp;PD2로&amp;nbsp;지정되어있으므로&amp;nbsp;해당되는&amp;nbsp;GPIO에&amp;nbsp;해당되는&amp;nbsp;신호가&amp;nbsp;타이밍에&amp;nbsp;맞게&amp;nbsp;출력되면&amp;nbsp;되는&amp;nbsp;것이다! &lt;br /&gt;6.신호의&amp;nbsp;시퀀스를&amp;nbsp;빠르게&amp;nbsp;보내주면&amp;nbsp;모터가&amp;nbsp;빠르게&amp;nbsp;회전하고&amp;nbsp;천천히&amp;nbsp;보내주면&amp;nbsp;천천히&amp;nbsp;회전한다! &lt;br /&gt;7.사용하는&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;8.그러면&amp;nbsp;신호를&amp;nbsp;가장&amp;nbsp;빠르게&amp;nbsp;전송할&amp;nbsp;수&amp;nbsp;있는&amp;nbsp;간격이&amp;nbsp;몇이냐?&amp;nbsp;(녹칸다도&amp;nbsp;모름) &lt;br /&gt;9.시퀀스를&amp;nbsp;1~8순으로&amp;nbsp;순서대로&amp;nbsp;1개씩&amp;nbsp;보낼때&amp;nbsp;1씩&amp;nbsp;카운트를&amp;nbsp;한다면&amp;nbsp;4096회&amp;nbsp;전송했을때&amp;nbsp;스탭모터는&amp;nbsp;360도&amp;nbsp;회전한다!(한바퀴에&amp;nbsp;대한&amp;nbsp;스탭량이&amp;nbsp;4096이다)&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;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;1.녹칸다와&amp;nbsp;함께&amp;nbsp;1차원배열과&amp;nbsp;2차원배열에&amp;nbsp;대해서&amp;nbsp;아주&amp;nbsp;간단히&amp;nbsp;알아보도록&amp;nbsp;하자!&lt;/p&gt;
&lt;pre id=&quot;code_1762783770920&quot; class=&quot;cpp&quot; data-ke-language=&quot;cpp&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;//1-1)배열은 크기를 미리 정해두고 사용하는 것이다!
	//1-1)크기를 미리 정해두지 않더라도 추측이 가능하면 생략이 가능하다!
	uint8_t array1[8]; //8개의 배열을 생성하겠다!
	//배열을 생성하는데, 1부터 8까지 8개를 담을 배열을 만들어라!
	uint8_t array2[] = {1,2,3,4,5,6,7,8};
	//배열을 지정된 갯수대로 생성하고 초기값을 안넣어주면 확정적이지 않은 값이 들어갔다!
	//배열을 선언하면서 초기값으로 모두 0을 입력을 하고싶다!
	uint8_t array3[8] = {0};
	
	//메인함수 안에서는 배열값의 대입이 가능하지만, 밖에서는 불가능하다!
	array1[0] = 10;
	array1[1] = 20;&lt;/code&gt;&lt;/pre&gt;
&lt;pre id=&quot;code_1762783779312&quot; class=&quot;cpp&quot; data-ke-language=&quot;cpp&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;//1-2) 2차원배열은 엑셀과 같은 모양을 딱 떠올리면 된다!
 uint8_t array1[2][2]; //2*2 배열이 만들어진다!
 //2차원배열의 선언과 초기화는 두번째 차원의 갯수를 확정해야한다!
 //2차원배열의 두번째차원은 갯수가 가변적일 수 없다!
 uint8_t array2[][3] = {
		  {1,2,3},
		  {4,5,6}
 };
 //녹칸다가 array2에서 1,2,3과 4,5,6을 그릅으로 다루고자 한다면
 //아래와 같이 2중 loop로 순회할 수 있음!
 for(int i = 0;i&amp;lt;2;i++){
	  for(int j = 0;j&amp;lt;3;j++){
		  //array2[i][j]
		  //i=0,j=0 array2[0][0] : 1
		  //i=0,j=1 array2[0][1] : 2
		  //i=0,j=2 array2[0][2] : 3
		  /////////////////////////
		  //i=1,j=0 array2[1][0] : 4
		  //i=1,j=1 array2[1][1] : 5
		  //i=1,j=2 array2[1][2] : 6
	  }
 }&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;br /&gt;2.IOC에서&amp;nbsp;스탭모터&amp;nbsp;제어핀을&amp;nbsp;출력으로&amp;nbsp;설정하고&amp;nbsp;폴링방식으로&amp;nbsp;시계방향으로&amp;nbsp;한바퀴,&amp;nbsp;반시계방향으로&amp;nbsp;한바퀴&amp;nbsp;무한반복하는데&amp;nbsp;전송간격을&amp;nbsp;1밀리초로&amp;nbsp;하시오!&lt;/p&gt;
&lt;pre id=&quot;code_1762783793629&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 */
 uint8_t seq[][4]={
 		{0,0,0,1}, //1
 		{0,0,1,1}, //2
 		{0,0,1,0}, //3
 		{0,1,1,0}, //4
 		{0,1,0,0}, //5
 		{1,1,0,0}, //6
 		{1,0,0,0}, //7
 		{1,0,0,1}  //8
 };
 /* USER CODE END 2 */
 /* Infinite loop */
 /* USER CODE BEGIN WHILE */
 while (1)
 {
	  //시계방향으로 한바퀴 회전
	  //시퀀스 8개 보낸게 8회니까 8회세트를 512번하면 4096회이다!
	  for(int i = 0;i&amp;lt;512;i++){
		  for(int j =0;j&amp;lt;8;j++){
			  HAL_GPIO_WritePin(GPIOC,GPIO_PIN_10,seq[j][0]);//IN1
			  HAL_GPIO_WritePin(GPIOC,GPIO_PIN_11,seq[j][1]);//IN2
			  HAL_GPIO_WritePin(GPIOC,GPIO_PIN_12,seq[j][2]);//IN3
			  HAL_GPIO_WritePin(GPIOD,GPIO_PIN_2,seq[j][3]);//IN4
			  HAL_Delay(1); //HAL_Delay가 지연할수 있는 최소 시간은 1밀리초이다!
		  }
	  }

	  //1초쉬고
	  HAL_Delay(1000);
	  //반시계방향으로 한바퀴 회전
	  for(int i = 0;i&amp;lt;512;i++){
		  for(int j =7;j&amp;gt;=0;j--){
			  HAL_GPIO_WritePin(GPIOC,GPIO_PIN_10,seq[j][0]);//IN1
			  HAL_GPIO_WritePin(GPIOC,GPIO_PIN_11,seq[j][1]);//IN2
			  HAL_GPIO_WritePin(GPIOC,GPIO_PIN_12,seq[j][2]);//IN3
			  HAL_GPIO_WritePin(GPIOD,GPIO_PIN_2,seq[j][3]);//IN4
			  HAL_Delay(1); //HAL_Delay가 지연할수 있는 최소 시간은 1밀리초이다!
		  }
	  }
	  //1초쉬고
	  HAL_Delay(1000);
   /* USER CODE END WHILE */
   /* USER CODE BEGIN 3 */
 }&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;br /&gt;3.예제2에서&amp;nbsp;IN1부터&amp;nbsp;IN4까지의&amp;nbsp;출력내용을&amp;nbsp;z-loop로&amp;nbsp;묶으시오!&amp;nbsp;&lt;/p&gt;
&lt;pre id=&quot;code_1762783806334&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 */
 uint8_t seq[][4]={
 		{0,0,0,1}, //1
 		{0,0,1,1}, //2
 		{0,0,1,0}, //3
 		{0,1,1,0}, //4
 		{0,1,0,0}, //5
 		{1,1,0,0}, //6
 		{1,0,0,0}, //7
 		{1,0,0,1}  //8
 };
 GPIO_TypeDef *mygroup[] = {GPIOC,GPIOC,GPIOC,GPIOD};
 uint16_t mypin[] = {GPIO_PIN_10,GPIO_PIN_11,GPIO_PIN_12,GPIO_PIN_2};
 /* USER CODE END 2 */
 /* Infinite loop */
 /* USER CODE BEGIN WHILE */
 while (1)
 {
	  //시계방향으로 한바퀴 회전
	  //시퀀스 8개 보낸게 8회니까 8회세트를 512번하면 4096회이다!
	  for(int i = 0;i&amp;lt;512;i++){
		  //시퀀스 1~8까지를 1밀리초 간격으로 연속으로 전송함!
		  for(int j =0;j&amp;lt;8;j++){
			  //IN1~IN4까지의 출력을 동시에 결정
			  for(int z = 0; z&amp;lt;4;z++){
				  HAL_GPIO_WritePin(mygroup[z],mypin[z],seq[j][z]);
			  }
			  HAL_Delay(1); //HAL_Delay가 지연할수 있는 최소 시간은 1밀리초이다!
		  }
	  }

	  //1초쉬고
	  HAL_Delay(1000);
	  //반시계방향으로 한바퀴 회전
	  for(int i = 0;i&amp;lt;512;i++){
		  for(int j =7;j&amp;gt;=0;j--){
			  for(int z = 0; z&amp;lt;4;z++){
				  HAL_GPIO_WritePin(mygroup[z],mypin[z],seq[j][z]);
			  }
			  HAL_Delay(1); //HAL_Delay가 지연할수 있는 최소 시간은 1밀리초이다!
		  }
	  }
	  //1초쉬고
	  HAL_Delay(1000);
   /* USER CODE END WHILE */
   /* USER CODE BEGIN 3 */
 }&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;br /&gt;4.기판에&amp;nbsp;붙어있는&amp;nbsp;버튼1번(PB1)을&amp;nbsp;누르면&amp;nbsp;스탭모터가&amp;nbsp;시계방향으로&amp;nbsp;360도&amp;nbsp;회전하고,&amp;nbsp;버튼2번(PA8)을&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_1762783838547&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 */
 uint8_t seq[][4]={
 		{0,0,0,1}, //1
 		{0,0,1,1}, //2
 		{0,0,1,0}, //3
 		{0,1,1,0}, //4
 		{0,1,0,0}, //5
 		{1,1,0,0}, //6
 		{1,0,0,0}, //7
 		{1,0,0,1}  //8
 };
 GPIO_TypeDef *mygroup[] = {GPIOC,GPIOC,GPIOC,GPIOD};
 uint16_t mypin[] = {GPIO_PIN_10,GPIO_PIN_11,GPIO_PIN_12,GPIO_PIN_2};
 /* USER CODE END 2 */
 /* Infinite loop */
 /* USER CODE BEGIN WHILE */
 while (1)
 {
	  //PB1을 누르면 시계방향으로 회전한다
	  if(HAL_GPIO_ReadPin(GPIOB, GPIO_PIN_1) == 0){
		  for(int i = 0;i&amp;lt;512;i++){
			  //시퀀스 1~8까지를 1밀리초 간격으로 연속으로 전송함!
			  for(int j =0;j&amp;lt;8;j++){
				  //IN1~IN4까지의 출력을 동시에 결정
				  for(int z = 0; z&amp;lt;4;z++){
					  HAL_GPIO_WritePin(mygroup[z],mypin[z],seq[j][z]);
				  }
				  HAL_Delay(1); //HAL_Delay가 지연할수 있는 최소 시간은 1밀리초이다!
			  }
		  }
	  }


	  //PA8을 누르면 반시계방향으로 한바퀴 회전
	  if(HAL_GPIO_ReadPin(GPIOA, GPIO_PIN_8) == 0){
		  for(int i = 0;i&amp;lt;512;i++){
			  for(int j =7;j&amp;gt;=0;j--){
				  for(int z = 0; z&amp;lt;4;z++){
					  HAL_GPIO_WritePin(mygroup[z],mypin[z],seq[j][z]);
				  }
				  HAL_Delay(1); //HAL_Delay가 지연할수 있는 최소 시간은 1밀리초이다!
			  }
		  }
	  }
   /* USER CODE END WHILE */
   /* USER CODE BEGIN 3 */
 }&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;br /&gt;5.예제4번에서&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;다를수있음)&lt;/p&gt;
&lt;pre id=&quot;code_1762783865329&quot; class=&quot;cpp&quot; data-ke-language=&quot;cpp&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;#define delay_ms HAL_Delay
#define SYS_CLOCK    64
#define SYSTICK_LOAD 63999
uint32_t millis_cnt = 0;
uint32_t millis() {
 return millis_cnt;
}
uint32_t micros() {
 return (millis_cnt &amp;amp; 0x3FFFFF) * 1000 + (SYSTICK_LOAD - SysTick-&amp;gt;VAL) / SYS_CLOCK;
}
void delay_us(uint32_t us) {  // 64MHz 보정
 if (us &amp;gt; 1) {
   uint32_t count = us * 7 - 6;
   while (count--);
 } else {
   uint32_t count = 2;
   while (count--);
 }
}

//delay_us관련 코드는 BEGIN 0쪽에 알아서 넣기~
/* USER CODE BEGIN 2 */
 uint8_t seq[][4]={
 		{0,0,0,1}, //1
 		{0,0,1,1}, //2
 		{0,0,1,0}, //3
 		{0,1,1,0}, //4
 		{0,1,0,0}, //5
 		{1,1,0,0}, //6
 		{1,0,0,0}, //7
 		{1,0,0,1}  //8
 };
 GPIO_TypeDef *mygroup[] = {GPIOC,GPIOC,GPIOC,GPIOD};
 uint16_t mypin[] = {GPIO_PIN_10,GPIO_PIN_11,GPIO_PIN_12,GPIO_PIN_2};
 /* USER CODE END 2 */
 /* Infinite loop */
 /* USER CODE BEGIN WHILE */
 while (1)
 {
	  //PB1을 누르면 시계방향으로 회전한다
	  if(HAL_GPIO_ReadPin(GPIOB, GPIO_PIN_1) == 0){
		  for(int i = 0;i&amp;lt;512;i++){
			  //시퀀스 1~8까지를 1밀리초 간격으로 연속으로 전송함!
			  for(int j =0;j&amp;lt;8;j++){
				  //IN1~IN4까지의 출력을 동시에 결정
				  for(int z = 0; z&amp;lt;4;z++){
					  HAL_GPIO_WritePin(mygroup[z],mypin[z],seq[j][z]);
				  }
				  delay_us(750);
			  }
		  }
	  }


	  //PA8을 누르면 반시계방향으로 한바퀴 회전
	  if(HAL_GPIO_ReadPin(GPIOA, GPIO_PIN_8) == 0){
		  for(int i = 0;i&amp;lt;512;i++){
			  for(int j =7;j&amp;gt;=0;j--){
				  for(int z = 0; z&amp;lt;4;z++){
					  HAL_GPIO_WritePin(mygroup[z],mypin[z],seq[j][z]);
				  }
				  delay_us(750);
			  }
		  }
	  }
   /* USER CODE END WHILE */
   /* USER CODE BEGIN 3 */
 }&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;br /&gt;6.예제5번에서&amp;nbsp;버튼3(PB2)을&amp;nbsp;누르면&amp;nbsp;PB3에&amp;nbsp;연결된&amp;nbsp;LED가&amp;nbsp;ON되고,&amp;nbsp;버튼4(PB6)를&amp;nbsp;누르면&amp;nbsp;LED가&amp;nbsp;OFF되도록&amp;nbsp;하시오!(모터가&amp;nbsp;돌아가는중에닌&amp;nbsp;LED&amp;nbsp;제어가&amp;nbsp;안될텐데&amp;nbsp;일단&amp;nbsp;무시~)&lt;/p&gt;
&lt;pre id=&quot;code_1762783876661&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 */
 uint8_t seq[][4]={
 		{0,0,0,1}, //1
 		{0,0,1,1}, //2
 		{0,0,1,0}, //3
 		{0,1,1,0}, //4
 		{0,1,0,0}, //5
 		{1,1,0,0}, //6
 		{1,0,0,0}, //7
 		{1,0,0,1}  //8
 };
 GPIO_TypeDef *mygroup[] = {GPIOC,GPIOC,GPIOC,GPIOD};
 uint16_t mypin[] = {GPIO_PIN_10,GPIO_PIN_11,GPIO_PIN_12,GPIO_PIN_2};
 /* USER CODE END 2 */
 /* Infinite loop */
 /* USER CODE BEGIN WHILE */
 while (1)
 {
	  if(HAL_GPIO_ReadPin(GPIOB, GPIO_PIN_2) == 0){
		  HAL_GPIO_WritePin(GPIOB,GPIO_PIN_3,1);
	  }
	  if(HAL_GPIO_ReadPin(GPIOB, GPIO_PIN_6) == 0){
		  HAL_GPIO_WritePin(GPIOB,GPIO_PIN_3,0);
	  }


	  //PB1을 누르면 시계방향으로 회전한다
	  if(HAL_GPIO_ReadPin(GPIOB, GPIO_PIN_1) == 0){
		  for(int i = 0;i&amp;lt;512;i++){
			  //시퀀스 1~8까지를 1밀리초 간격으로 연속으로 전송함!
			  for(int j =0;j&amp;lt;8;j++){
				  //IN1~IN4까지의 출력을 동시에 결정
				  for(int z = 0; z&amp;lt;4;z++){
					  HAL_GPIO_WritePin(mygroup[z],mypin[z],seq[j][z]);
				  }
				  delay_us(750);
			  }
		  }
	  }
	  //PA8을 누르면 반시계방향으로 한바퀴 회전
	  if(HAL_GPIO_ReadPin(GPIOA, GPIO_PIN_8) == 0){
		  for(int i = 0;i&amp;lt;512;i++){
			  for(int j =7;j&amp;gt;=0;j--){
				  for(int z = 0; z&amp;lt;4;z++){
					  HAL_GPIO_WritePin(mygroup[z],mypin[z],seq[j][z]);
				  }
				  delay_us(750);
			  }
		  }
	  }
   /* USER CODE END WHILE */
   /* USER CODE BEGIN 3 */
 }&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;br /&gt;7.예제6번에서&amp;nbsp;&amp;ldquo;버튼1,2를&amp;nbsp;누르면&amp;nbsp;스탭모터가&amp;nbsp;돌아간다&amp;rdquo;와&amp;nbsp;&amp;ldquo;버튼3,4를&amp;nbsp;누르면&amp;nbsp;LED가&amp;nbsp;제어된다&amp;rdquo;의&amp;nbsp;제어조건을&amp;nbsp;동시에&amp;nbsp;작동되도록&amp;nbsp;예시코드를&amp;nbsp;구현하시오!(EXIT를&amp;nbsp;활용함)&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;exit.PNG&quot; data-origin-width=&quot;852&quot; data-origin-height=&quot;510&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/pHFY7/dJMcahirEPx/1ZtxcOfcxGiWESocqXWzH0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/pHFY7/dJMcahirEPx/1ZtxcOfcxGiWESocqXWzH0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/pHFY7/dJMcahirEPx/1ZtxcOfcxGiWESocqXWzH0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FpHFY7%2FdJMcahirEPx%2F1ZtxcOfcxGiWESocqXWzH0%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;852&quot; height=&quot;510&quot; data-filename=&quot;exit.PNG&quot; data-origin-width=&quot;852&quot; data-origin-height=&quot;510&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;pre id=&quot;code_1762783889449&quot; class=&quot;cpp&quot; data-ke-language=&quot;cpp&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;/* USER CODE BEGIN 0 */
#define delay_ms HAL_Delay
#define SYS_CLOCK    64
#define SYSTICK_LOAD 63999
uint32_t millis_cnt = 0;
uint32_t millis() {
return millis_cnt;
}
uint32_t micros() {
return (millis_cnt &amp;amp; 0x3FFFFF) * 1000 + (SYSTICK_LOAD - SysTick-&amp;gt;VAL) / SYS_CLOCK;
}
void delay_us(uint32_t us) {  // 64MHz 보정
if (us &amp;gt; 1) {
  uint32_t count = us * 7 - 6;
  while (count--);
} else {
  uint32_t count = 2;
  while (count--);
}
}
void HAL_GPIO_EXTI_Callback(uint16_t GPIO_Pin)
{
  if(GPIO_Pin == GPIO_PIN_2)
  {
      //버튼3에 대한 EXTI
	   HAL_GPIO_WritePin(GPIOB,GPIO_PIN_3,1);
  }else if(GPIO_Pin == GPIO_PIN_6)
  {
	   //버튼4에 대한 EXTI
	   HAL_GPIO_WritePin(GPIOB,GPIO_PIN_3,0);
  }
}
/* USER CODE END 0 */

/* USER CODE BEGIN 2 */
 uint8_t seq[][4]={
 		{0,0,0,1}, //1
 		{0,0,1,1}, //2
 		{0,0,1,0}, //3
 		{0,1,1,0}, //4
 		{0,1,0,0}, //5
 		{1,1,0,0}, //6
 		{1,0,0,0}, //7
 		{1,0,0,1}  //8
 };
 GPIO_TypeDef *mygroup[] = {GPIOC,GPIOC,GPIOC,GPIOD};
 uint16_t mypin[] = {GPIO_PIN_10,GPIO_PIN_11,GPIO_PIN_12,GPIO_PIN_2};
 /* USER CODE END 2 */
 /* USER CODE BEGIN WHILE */
 while (1)
 {
	  //PB1을 누르면 시계방향으로 회전한다
	  if(HAL_GPIO_ReadPin(GPIOB, GPIO_PIN_1) == 0){
		  for(int i = 0;i&amp;lt;512;i++){
			  //시퀀스 1~8까지를 1밀리초 간격으로 연속으로 전송함!
			  for(int j =0;j&amp;lt;8;j++){
				  //IN1~IN4까지의 출력을 동시에 결정
				  for(int z = 0; z&amp;lt;4;z++){
					  HAL_GPIO_WritePin(mygroup[z],mypin[z],seq[j][z]);
				  }
				  delay_us(750);
			  }
		  }
	  }
	  //PA8을 누르면 반시계방향으로 한바퀴 회전
	  if(HAL_GPIO_ReadPin(GPIOA, GPIO_PIN_8) == 0){
		  for(int i = 0;i&amp;lt;512;i++){
			  for(int j =7;j&amp;gt;=0;j--){
				  for(int z = 0; z&amp;lt;4;z++){
					  HAL_GPIO_WritePin(mygroup[z],mypin[z],seq[j][z]);
				  }
				  delay_us(750);
			  }
		  }
	  }
   /* USER CODE END WHILE */
   /* USER CODE BEGIN 3 */
 }&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-filename=&quot;인터럽트1.PNG&quot; data-origin-width=&quot;1075&quot; data-origin-height=&quot;560&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/9s2Dk/dJMcaaXVs2u/xZrWpD8hrxOAzVWgUFJr11/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/9s2Dk/dJMcaaXVs2u/xZrWpD8hrxOAzVWgUFJr11/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/9s2Dk/dJMcaaXVs2u/xZrWpD8hrxOAzVWgUFJr11/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2F9s2Dk%2FdJMcaaXVs2u%2FxZrWpD8hrxOAzVWgUFJr11%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;560&quot; data-filename=&quot;인터럽트1.PNG&quot; data-origin-width=&quot;1075&quot; data-origin-height=&quot;560&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;인터럽트2.PNG&quot; data-origin-width=&quot;1182&quot; data-origin-height=&quot;333&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cLRuir/dJMcac9hknf/EWD07xCdE4sErqSqMqq7bk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cLRuir/dJMcac9hknf/EWD07xCdE4sErqSqMqq7bk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cLRuir/dJMcac9hknf/EWD07xCdE4sErqSqMqq7bk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FcLRuir%2FdJMcac9hknf%2FEWD07xCdE4sErqSqMqq7bk%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;1182&quot; height=&quot;333&quot; data-filename=&quot;인터럽트2.PNG&quot; data-origin-width=&quot;1182&quot; data-origin-height=&quot;333&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;br /&gt;8.타이머인터럽트를&amp;nbsp;이용해서&amp;nbsp;스탭모터를&amp;nbsp;시계방향으로&amp;nbsp;항상&amp;nbsp;회전시키는&amp;nbsp;예시를&amp;nbsp;구현하시오!(IOC설정)&amp;nbsp;버튼3과&amp;nbsp;버튼4를&amp;nbsp;누르면&amp;nbsp;LED가&amp;nbsp;제어된다는&amp;nbsp;것을&amp;nbsp;메인함수에서&amp;nbsp;표현하시오!&lt;/p&gt;
&lt;pre id=&quot;code_1762783904862&quot; class=&quot;cpp&quot; data-ke-language=&quot;cpp&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;/* USER CODE BEGIN 0 */
uint8_t seq[][4]={
 		{0,0,0,1}, //1
 		{0,0,1,1}, //2
 		{0,0,1,0}, //3
 		{0,1,1,0}, //4
 		{0,1,0,0}, //5
 		{1,1,0,0}, //6
 		{1,0,0,0}, //7
 		{1,0,0,1}  //8
 };
GPIO_TypeDef *mygroup[] = {GPIOC,GPIOC,GPIOC,GPIOD};
uint16_t mypin[] = {GPIO_PIN_10,GPIO_PIN_11,GPIO_PIN_12,GPIO_PIN_2};
int seq_num = 0;
void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim)
{
   //타이머 인터럽트 콜백함수
	//시퀀스 0 ~ 7까지 연속적으로 전송한다!
	//IN1~IN4까지의 출력을 동시에 결정
	for(int z = 0; z&amp;lt;4;z++){
	  HAL_GPIO_WritePin(mygroup[z],mypin[z],seq[seq_num][z]);
	}
	seq_num++;
	if(seq_num &amp;gt;= 8) seq_num = 0;
}
/* USER CODE END 0 */

/* USER CODE BEGIN 2 */
 //타이머 인터럽트 실행
 HAL_TIM_Base_Start_IT(&amp;amp;htim2);
 /* USER CODE END 2 */
 /* Infinite loop */
 /* USER CODE BEGIN WHILE */
 while (1)
 {
	  if(HAL_GPIO_ReadPin(GPIOB, GPIO_PIN_2) == 0){
		  HAL_GPIO_WritePin(GPIOB,GPIO_PIN_3,1);
	  }
	  if(HAL_GPIO_ReadPin(GPIOB, GPIO_PIN_6) == 0){
		  HAL_GPIO_WritePin(GPIOB,GPIO_PIN_3,0);
	  }
   /* USER CODE END WHILE */
   /* USER CODE BEGIN 3 */
 }&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;br /&gt;9.버튼1을&amp;nbsp;누르면&amp;nbsp;스탭모터가&amp;nbsp;시작위치에서&amp;nbsp;시계방향으로&amp;nbsp;360도&amp;nbsp;회전하고,&amp;nbsp;버튼2를&amp;nbsp;누르면&amp;nbsp;반시계방향으로&amp;nbsp;360도&amp;nbsp;회전하도록&amp;nbsp;하시오!(절대위치제어)&lt;/p&gt;
&lt;pre id=&quot;code_1762783916397&quot; class=&quot;cpp&quot; data-ke-language=&quot;cpp&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;/* USER CODE BEGIN 0 */
uint8_t seq[][4]={
 		{0,0,0,1}, //1
 		{0,0,1,1}, //2
 		{0,0,1,0}, //3
 		{0,1,1,0}, //4
 		{0,1,0,0}, //5
 		{1,1,0,0}, //6
 		{1,0,0,0}, //7
 		{1,0,0,1}  //8
 };
GPIO_TypeDef *mygroup[] = {GPIOC,GPIOC,GPIOC,GPIOD};
uint16_t mypin[] = {GPIO_PIN_10,GPIO_PIN_11,GPIO_PIN_12,GPIO_PIN_2};
int now_pos = 0; //스탭모터가 알고있는 자기의 현재 위치
int target_pos = 0; //녹칸다가 설정한 목표위치
int seq_num = 0;
void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim)
{
   //타이머 인터럽트 콜백함수
	if(now_pos &amp;lt; target_pos){
		//시계방향으로 회전해야하는 상황
		for(int z = 0; z&amp;lt;4;z++){
		  HAL_GPIO_WritePin(mygroup[z],mypin[z],seq[seq_num][z]);
		}
		seq_num++;
		if(seq_num &amp;gt;= 8) seq_num = 0;
		now_pos++; //시퀀스 1회당 현재위치 1 증가
	}else if(now_pos &amp;gt; target_pos){
		//반시계방향으로 회전해야 하는 상황
		for(int z = 0; z&amp;lt;4;z++){
		  HAL_GPIO_WritePin(mygroup[z],mypin[z],seq[seq_num][z]);
		}
		seq_num--;
		if(seq_num &amp;lt; 0) seq_num = 7;
		now_pos--; //시퀀스 1회당 현재위치 1 감소
	}
}
/* USER CODE END 0 */

/* USER CODE BEGIN 2 */
 //타이머 인터럽트 실행
 HAL_TIM_Base_Start_IT(&amp;amp;htim2);
 /* USER CODE END 2 */
 /* Infinite loop */
 /* USER CODE BEGIN WHILE */
 while (1)
 {
	  if(HAL_GPIO_ReadPin(GPIOB, GPIO_PIN_1) == 0){
		  target_pos = 4096;
	  }
	  if(HAL_GPIO_ReadPin(GPIOA, GPIO_PIN_8) == 0){
		  target_pos = 0;
	  }
   /* USER CODE END WHILE */
   /* USER CODE BEGIN 3 */
 }&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;br /&gt;10.버튼1은&amp;nbsp;원점(0),&amp;nbsp;버튼2는&amp;nbsp;+90도,&amp;nbsp;버튼3은&amp;nbsp;+180도,&amp;nbsp;버튼4는&amp;nbsp;+360도,&amp;nbsp;버튼5는&amp;nbsp;-90도,&amp;nbsp;버튼6은&amp;nbsp;-180도,&amp;nbsp;버튼7은&amp;nbsp;-360도&amp;nbsp;회전하도록&amp;nbsp;설정하시오!&lt;/p&gt;
&lt;pre id=&quot;code_1762783928766&quot; class=&quot;cpp&quot; data-ke-language=&quot;cpp&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;/* USER CODE BEGIN 0 */
uint8_t seq[][4]={
 		{0,0,0,1}, //1
 		{0,0,1,1}, //2
 		{0,0,1,0}, //3
 		{0,1,1,0}, //4
 		{0,1,0,0}, //5
 		{1,1,0,0}, //6
 		{1,0,0,0}, //7
 		{1,0,0,1}  //8
 };
GPIO_TypeDef *mygroup[] = {GPIOC,GPIOC,GPIOC,GPIOD};
uint16_t mypin[] = {GPIO_PIN_10,GPIO_PIN_11,GPIO_PIN_12,GPIO_PIN_2};
int now_pos = 0; //스탭모터가 알고있는 자기의 현재 위치
int target_pos = 0; //녹칸다가 설정한 목표위치
int seq_num = 0;
void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim)
{
   //타이머 인터럽트 콜백함수
	if(now_pos &amp;lt; target_pos){
		//시계방향으로 회전해야하는 상황
		for(int z = 0; z&amp;lt;4;z++){
		  HAL_GPIO_WritePin(mygroup[z],mypin[z],seq[seq_num][z]);
		}
		seq_num++;
		if(seq_num &amp;gt;= 8) seq_num = 0;
		now_pos++; //시퀀스 1회당 현재위치 1 증가
	}else if(now_pos &amp;gt; target_pos){
		//반시계방향으로 회전해야 하는 상황
		for(int z = 0; z&amp;lt;4;z++){
		  HAL_GPIO_WritePin(mygroup[z],mypin[z],seq[seq_num][z]);
		}
		seq_num--;
		if(seq_num &amp;lt; 0) seq_num = 7;
		now_pos--; //시퀀스 1회당 현재위치 1 감소
	}
}
/* USER CODE END 0 */

/* USER CODE BEGIN 2 */
 //타이머 인터럽트 실행
 HAL_TIM_Base_Start_IT(&amp;amp;htim2);
 /* USER CODE END 2 */
 /* Infinite loop */
 /* USER CODE BEGIN WHILE */
 while (1)
 {
	  if(HAL_GPIO_ReadPin(GPIOB, GPIO_PIN_1) == 0){
		  target_pos = 0; //0
	  }
	  if(HAL_GPIO_ReadPin(GPIOA, GPIO_PIN_8) == 0){
		  target_pos = 4096/4; //90
	  }
	  if(HAL_GPIO_ReadPin(GPIOB, GPIO_PIN_2) == 0){
	  		  target_pos = 4096/2; //180
	  }
	  if(HAL_GPIO_ReadPin(GPIOB, GPIO_PIN_6) == 0){
	  		  target_pos = 4096; //360
	  }
	  if(HAL_GPIO_ReadPin(GPIOC, GPIO_PIN_5) == 0){
	  		  target_pos = -4096/4; //-90
	  }
	  if(HAL_GPIO_ReadPin(GPIOC, GPIO_PIN_7) == 0){
	  		  target_pos = -4096/2; //-180
	  }
	  if(HAL_GPIO_ReadPin(GPIOA, GPIO_PIN_11) == 0){
	  		  target_pos = -4096; //-360
	  }
   /* USER CODE END WHILE */
   /* USER CODE BEGIN 3 */
 }&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>프로그래밍/STM32</category>
      <author>덕력킹</author>
      <guid isPermaLink="true">https://bota.tistory.com/2451</guid>
      <comments>https://bota.tistory.com/2451#entry2451comment</comments>
      <pubDate>Mon, 10 Nov 2025 23:13:50 +0900</pubDate>
    </item>
    <item>
      <title>[STM32#08] PWM의 듀티비를 변화시켜서 서보모터(SERVO)인 SG90의 각도를 제어하는 방법 알아보기!(녹칸다 내맘대로 STM32)</title>
      <link>https://bota.tistory.com/2450</link>
      <description>&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;stm32.png&quot; data-origin-width=&quot;1920&quot; data-origin-height=&quot;1080&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/tEXGP/dJMcahvXhyf/JB4mroyzFzOlrutIFBP0F1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/tEXGP/dJMcahvXhyf/JB4mroyzFzOlrutIFBP0F1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/tEXGP/dJMcahvXhyf/JB4mroyzFzOlrutIFBP0F1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FtEXGP%2FdJMcahvXhyf%2FJB4mroyzFzOlrutIFBP0F1%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;1920&quot; height=&quot;1080&quot; data-filename=&quot;stm32.png&quot; data-origin-width=&quot;1920&quot; data-origin-height=&quot;1080&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/live/IDd-IVeSmGE&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://youtube.com/live/IDd-IVeSmGE&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/watch?v=IDd-IVeSmGE&quot; data-video-thumbnail=&quot;https://scrap.kakaocdn.net/dn/AfX6p/hyZNbz4cDB/pP19MNAxQVAgM4AY6m2ff1/img.jpg?width=1280&amp;amp;height=720&amp;amp;face=0_0_1280_720,https://scrap.kakaocdn.net/dn/CCoU8/hyZMDp8PwA/rxl7UwbDQhqtmtLLs3OfCk/img.jpg?width=1280&amp;amp;height=720&amp;amp;face=0_0_1280_720&quot; data-video-width=&quot;860&quot; data-video-height=&quot;484&quot; data-video-origin-width=&quot;860&quot; data-video-origin-height=&quot;484&quot; data-ke-mobilestyle=&quot;widthContent&quot; data-video-title=&quot;[STM32#08] PWM의 듀티비를 변화시켜서 서보모터(SERVO)인 SG90의 각도를 제어하는 방법 알아보기!(녹칸&quot; data-original-url=&quot;&quot;&gt;&lt;iframe src=&quot;https://www.youtube.com/embed/IDd-IVeSmGE&quot; width=&quot;860&quot; height=&quot;484&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;[STM32#08]&amp;nbsp;PWM의&amp;nbsp;듀티비를&amp;nbsp;변화시켜서&amp;nbsp;서보모터(SERVO)인&amp;nbsp;SG90의&amp;nbsp;각도를&amp;nbsp;제어하는&amp;nbsp;방법&amp;nbsp;알아보기!(녹칸다&amp;nbsp;내맘대로&amp;nbsp;STM32) &lt;br /&gt;&lt;br /&gt;심심한녹칸다의&amp;nbsp;내맘대로&amp;nbsp;STM32시리즈이다! &lt;br /&gt;&lt;br /&gt;STM32시리즈의&amp;nbsp;모든&amp;nbsp;자료는&amp;nbsp;구글&amp;nbsp;슬라이드에&amp;nbsp;작성하고&amp;nbsp;모두에게&amp;nbsp;공유되어있음! &lt;br /&gt;&lt;a href=&quot;https://docs.google.com/presentation/d/1myA5iYbjuKsLWLqtRLKAiRfwUwvqB1d1RGjiMIIgp3I/edit?slide=id.g39fc004f5bb_2_169#slide=id.g39fc004f5bb_2_169&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://docs.google.com/presentation/d/1myA5iYbjuKsLWLqtRLKAiRfwUwvqB1d1RGjiMIIgp3I/edit?slide=id.g39fc004f5bb_2_169#slide=id.g39fc004f5bb_2_169&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;이번편은&amp;nbsp;녹칸다의&amp;nbsp;STM32쉴드에&amp;nbsp;SG90을&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;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;회로도1.PNG&quot; data-origin-width=&quot;1179&quot; data-origin-height=&quot;499&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/ctSCVR/dJMcaawPzPZ/m7kUoQ9qx02yWLjNXaUGy1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/ctSCVR/dJMcaawPzPZ/m7kUoQ9qx02yWLjNXaUGy1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/ctSCVR/dJMcaawPzPZ/m7kUoQ9qx02yWLjNXaUGy1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FctSCVR%2FdJMcaawPzPZ%2Fm7kUoQ9qx02yWLjNXaUGy1%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;499&quot; data-filename=&quot;회로도1.PNG&quot; data-origin-width=&quot;1179&quot; data-origin-height=&quot;499&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;회로도2.PNG&quot; data-origin-width=&quot;1137&quot; data-origin-height=&quot;636&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/Ckqki/dJMcai9tbSO/xObufeUmGR7I7dti88pJk0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/Ckqki/dJMcai9tbSO/xObufeUmGR7I7dti88pJk0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/Ckqki/dJMcai9tbSO/xObufeUmGR7I7dti88pJk0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FCkqki%2FdJMcai9tbSO%2FxObufeUmGR7I7dti88pJk0%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;1137&quot; height=&quot;636&quot; data-filename=&quot;회로도2.PNG&quot; data-origin-width=&quot;1137&quot; data-origin-height=&quot;636&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;br /&gt;1.서보모터(SG90)의&amp;nbsp;IOC설정을&amp;nbsp;하고&amp;nbsp;0도와&amp;nbsp;180도를&amp;nbsp;1초&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-filename=&quot;01.PNG&quot; data-origin-width=&quot;1227&quot; data-origin-height=&quot;645&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/S7y0o/dJMcafkBxdg/wuNbB0n1YKK3sqlVmjt1kK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/S7y0o/dJMcafkBxdg/wuNbB0n1YKK3sqlVmjt1kK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/S7y0o/dJMcafkBxdg/wuNbB0n1YKK3sqlVmjt1kK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FS7y0o%2FdJMcafkBxdg%2FwuNbB0n1YKK3sqlVmjt1kK%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;1227&quot; height=&quot;645&quot; data-filename=&quot;01.PNG&quot; data-origin-width=&quot;1227&quot; data-origin-height=&quot;645&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;pre id=&quot;code_1762327067467&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 */
 //PB11이 사용하는 TIM2_CH4를 시작하겠다!
 HAL_TIM_PWM_Start(&amp;amp;htim2,TIM_CHANNEL_4);
 /* USER CODE END 2 */
 /* Infinite loop */
 /* USER CODE BEGIN WHILE */
 while (1)
 {
	  //서보모터가 0도 위치로 이동한다!
	  TIM2-&amp;gt;CCR4 = 600;
	  //1초쉰다!
	  HAL_Delay(1000);
	  //서보모터가 180도 위치로 이동한다!
	  TIM2-&amp;gt;CCR4 = 2400;
	  //1초쉰다!
	  HAL_Delay(1000);
   /* USER CODE END WHILE */
   /* USER CODE BEGIN 3 */
 }&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;br /&gt;2.예제1번에서&amp;nbsp;0도부터&amp;nbsp;180도사이의&amp;nbsp;각도를&amp;nbsp;입력하면&amp;nbsp;각도대로&amp;nbsp;CCR4의&amp;nbsp;값을&amp;nbsp;설정하는&amp;nbsp;똑똑한&amp;nbsp;함수를&amp;nbsp;만들어보시오!&lt;/p&gt;
&lt;pre id=&quot;code_1762327083831&quot; class=&quot;cpp&quot; data-ke-language=&quot;cpp&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;/* USER CODE BEGIN 0 */
void set_servo(uint8_t degree){
	//degree는 0~180도 범위이고 CCR4는 600부터 2400의 범위이다!
	TIM2-&amp;gt;CCR4 = (uint32_t)(600+(2400-600)*degree/180.0);
}
/* USER CODE END 0 */
//중략
/* USER CODE BEGIN 2 */
 //PB11이 사용하는 TIM2_CH4를 시작하겠다!
 HAL_TIM_PWM_Start(&amp;amp;htim2,TIM_CHANNEL_4);
 /* USER CODE END 2 */
 /* Infinite loop */
 /* USER CODE BEGIN WHILE */
 while (1)
 {
	  //서보모터가 0도 위치로 이동한다!
	  set_servo(0);
	  //1초쉰다!
	  HAL_Delay(1000);
	  //서보모터가 180도 위치로 이동한다!
	  set_servo(180);
	  //1초쉰다!
	  HAL_Delay(1000);
   /* USER CODE END WHILE */
   /* USER CODE BEGIN 3 */
 }&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;br /&gt;3.서보모터를&amp;nbsp;0도부터&amp;nbsp;180도까지&amp;nbsp;10밀리초간격으로&amp;nbsp;1도씩&amp;nbsp;올리고,&amp;nbsp;180도부터&amp;nbsp;0도까지&amp;nbsp;10밀리초간격으로&amp;nbsp;내려서&amp;nbsp;왔다갔다&amp;nbsp;하는&amp;nbsp;예제를&amp;nbsp;만드시오!&lt;/p&gt;
&lt;pre id=&quot;code_1762327095058&quot; class=&quot;cpp&quot; data-ke-language=&quot;cpp&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;/* USER CODE BEGIN 0 */
void set_servo(uint8_t degree){
	//degree는 0~180도 범위이고 CCR4는 600부터 2400의 범위이다!
	TIM2-&amp;gt;CCR4 = (uint32_t)(600+(2400-600)*degree/180.0);
}
/* USER CODE END 0 */
//중략
/* USER CODE BEGIN 2 */
 //PB11이 사용하는 TIM2_CH4를 시작하겠다!
 HAL_TIM_PWM_Start(&amp;amp;htim2,TIM_CHANNEL_4);
 /* USER CODE END 2 */
 /* Infinite loop */
 /* USER CODE BEGIN WHILE */
 while (1)
 {
	  //0도부터 180도까지 1도씩 10밀리초간격으로 올라간다!
	  for(int i = 0;i&amp;lt;=180;i++){
		  set_servo(i);
		  HAL_Delay(10);
	  }
	  //180도부터 0도까지 1도씩 10밀리초간격으로 내려간다!
	  for(int i = 180;i&amp;gt;=0;i--){
		  set_servo(i);
		  HAL_Delay(10);
	  }
   /* USER CODE END WHILE */
   /* USER CODE BEGIN 3 */
 }&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;br /&gt;4.버튼5개(PB1,PA8,PB2,PB6,PC5)를&amp;nbsp;사용해서&amp;nbsp;PB1은&amp;nbsp;0도위치,&amp;nbsp;PA8은&amp;nbsp;45도위치,&amp;nbsp;PB2는&amp;nbsp;90도위치,&amp;nbsp;PB6은&amp;nbsp;135도위치,&amp;nbsp;PC5는&amp;nbsp;180도위치로&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-filename=&quot;04.PNG&quot; data-origin-width=&quot;721&quot; data-origin-height=&quot;693&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/ctNLJc/dJMcajUQi80/V9hfmAKDGQNPrrrsKZeVUk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/ctNLJc/dJMcajUQi80/V9hfmAKDGQNPrrrsKZeVUk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/ctNLJc/dJMcajUQi80/V9hfmAKDGQNPrrrsKZeVUk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FctNLJc%2FdJMcajUQi80%2FV9hfmAKDGQNPrrrsKZeVUk%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;721&quot; height=&quot;693&quot; data-filename=&quot;04.PNG&quot; data-origin-width=&quot;721&quot; data-origin-height=&quot;693&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;pre id=&quot;code_1762327107393&quot; class=&quot;cpp&quot; data-ke-language=&quot;cpp&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;/* USER CODE BEGIN 0 */
void set_servo(uint8_t degree){
	//degree는 0~180도 범위이고 CCR4는 600부터 2400의 범위이다!
	TIM2-&amp;gt;CCR4 = (uint32_t)(600+(2400-600)*degree/180.0);
}
/* USER CODE END 0 */
//중략
/* USER CODE BEGIN 2 */
 //PB11이 사용하는 TIM2_CH4를 시작하겠다!
 HAL_TIM_PWM_Start(&amp;amp;htim2,TIM_CHANNEL_4);
 /* USER CODE END 2 */
 /* Infinite loop */
 /* USER CODE BEGIN WHILE */
 while (1)
 {
	  //PB1을 누르면 0도로 이동한다!
	  if(HAL_GPIO_ReadPin(GPIOB, GPIO_PIN_1) == 0){
		  set_servo(0);
	  }
	  //PA8을 누르면 45도로 이동한다!
	  if(HAL_GPIO_ReadPin(GPIOA, GPIO_PIN_8) == 0){
		  set_servo(45);
	  }
	  //PB2을 누르면 90도로 이동한다!
	  if(HAL_GPIO_ReadPin(GPIOB, GPIO_PIN_2) == 0){
		  set_servo(90);
	  }
	  //PB6을 누르면 135도로 이동한다!
	  if(HAL_GPIO_ReadPin(GPIOB, GPIO_PIN_6) == 0){
		  set_servo(135);
	  }
	  //PC5을 누르면 180도로 이동한다!
	  if(HAL_GPIO_ReadPin(GPIOC, GPIO_PIN_5) == 0){
		  set_servo(180);
	  }
   /* USER CODE END WHILE */
   /* USER CODE BEGIN 3 */
 }&lt;/code&gt;&lt;/pre&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;br /&gt;5.PA8버튼을&amp;nbsp;누르면&amp;nbsp;누르고&amp;nbsp;있는&amp;nbsp;동안에&amp;nbsp;서보모터의&amp;nbsp;각도가&amp;nbsp;1도씩&amp;nbsp;증가하고&amp;nbsp;최대&amp;nbsp;180을&amp;nbsp;넘지않는다!&amp;nbsp;PB1을&amp;nbsp;누르면&amp;nbsp;각도가&amp;nbsp;1도씩&amp;nbsp;내려가고&amp;nbsp;0도이하로&amp;nbsp;내려가지는&amp;nbsp;않는다!&lt;/p&gt;
&lt;pre id=&quot;code_1762327121004&quot; class=&quot;cpp&quot; data-ke-language=&quot;cpp&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;/* USER CODE BEGIN 0 */
void set_servo(uint8_t degree){
	//degree는 0~180도 범위이고 CCR4는 600부터 2400의 범위이다!
	TIM2-&amp;gt;CCR4 = (uint32_t)(600+(2400-600)*degree/180.0);
}
/* USER CODE END 0 */
//중략
//PB11이 사용하는 TIM2_CH4를 시작하겠다!
 HAL_TIM_PWM_Start(&amp;amp;htim2,TIM_CHANNEL_4);
 int16_t degree = 0;
 set_servo(degree); //시작할때 서보모터는 0도 위치!
 /* USER CODE END 2 */
 /* Infinite loop */
 /* USER CODE BEGIN WHILE */
 while (1)
 {
	  //PB1을 누르면 1도씩 내려간다!(하한값 0)
	  if(HAL_GPIO_ReadPin(GPIOB, GPIO_PIN_1) == 0){
		  degree++;
		  if(degree &amp;gt; 180) degree = 180;
		  set_servo(degree);
		  HAL_Delay(10);
	  }
	  //PA8을 누르면 1도씩 증가한다! (상한값 180)
	  if(HAL_GPIO_ReadPin(GPIOA, GPIO_PIN_8) == 0){
		  degree--;
		  if(degree &amp;lt; 0) degree = 0; //오류 발생!
		  set_servo(degree);
		  HAL_Delay(10);
	  }
   /* USER CODE END WHILE */
   /* USER CODE BEGIN 3 */
 }&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;br /&gt;6.로터리엔코더(PA11,PA12)를&amp;nbsp;시계방향으로&amp;nbsp;돌리면&amp;nbsp;서보모터의&amp;nbsp;각도가&amp;nbsp;1도씩&amp;nbsp;올라가고,&amp;nbsp;반시계방향으로&amp;nbsp;돌리면&amp;nbsp;1도씩&amp;nbsp;내려가도록&amp;nbsp;하시오!(범위는&amp;nbsp;0~180도)&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;06.PNG&quot; data-origin-width=&quot;794&quot; data-origin-height=&quot;645&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/HhAps/dJMcagqhqwb/6DSbxsF1r6AkeBv6kxy811/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/HhAps/dJMcagqhqwb/6DSbxsF1r6AkeBv6kxy811/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/HhAps/dJMcagqhqwb/6DSbxsF1r6AkeBv6kxy811/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FHhAps%2FdJMcagqhqwb%2F6DSbxsF1r6AkeBv6kxy811%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;794&quot; height=&quot;645&quot; data-filename=&quot;06.PNG&quot; data-origin-width=&quot;794&quot; data-origin-height=&quot;645&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;pre id=&quot;code_1762327131413&quot; class=&quot;cpp&quot; data-ke-language=&quot;cpp&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;/* USER CODE BEGIN 0 */
void set_servo(uint8_t degree){
	//degree는 0~180도 범위이고 CCR4는 600부터 2400의 범위이다!
	TIM2-&amp;gt;CCR4 = (uint32_t)(600+(2400-600)*degree/180.0);
}
/* USER CODE END 0 */
//중략
//PB11이 사용하는 TIM2_CH4를 시작하겠다!
 HAL_TIM_PWM_Start(&amp;amp;htim2,TIM_CHANNEL_4);
 int16_t degree = 0;
 set_servo(degree); //시작할때 서보모터는 0도 위치!
 uint8_t old_A = 0;
 /* USER CODE END 2 */
 /* Infinite loop */
 /* USER CODE BEGIN WHILE */
 while (1)
 {
	  uint8_t now_A = HAL_GPIO_ReadPin(GPIOA, GPIO_PIN_11);
	  if(old_A == 0 &amp;amp;&amp;amp; now_A == 1){
		  uint8_t now_B = HAL_GPIO_ReadPin(GPIOA, GPIO_PIN_12);
		  if(!now_B){
			  //시계
			  degree-=3; //원래 degree가 가지고있는값에 3을 뺀다!
			  if(degree &amp;lt; 0) degree = 0;
			  set_servo(degree);
		  }else{
			  //반시계
			  degree+=3; //원래 degree가 가지고있는값에 3을 더한다!
			  if(degree &amp;gt; 180) degree = 180;
			  set_servo(degree);
		  }
	  }
	  old_A = now_A;
   /* USER CODE END WHILE */
   /* USER CODE BEGIN 3 */
 }&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;br /&gt;7.녹칸다가&amp;nbsp;사용하는&amp;nbsp;putty에서&amp;nbsp;&amp;lsquo;0&amp;rsquo;을&amp;nbsp;입력하면&amp;nbsp;0도,&amp;nbsp;&amp;lsquo;1&amp;rsquo;을&amp;nbsp;입력하면&amp;nbsp;45도,&amp;nbsp;&amp;rsquo;2&amp;rsquo;를&amp;nbsp;입력하면&amp;nbsp;90도,&amp;nbsp;&amp;lsquo;3&amp;rsquo;을&amp;nbsp;입력하면&amp;nbsp;135도,&amp;nbsp;&amp;lsquo;4&amp;rsquo;를&amp;nbsp;입력하면&amp;nbsp;180도로&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;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;07.PNG&quot; data-origin-width=&quot;1019&quot; data-origin-height=&quot;662&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cge5AP/dJMcagX7pQP/YYW6VoC2vv9c5IscYuod81/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cge5AP/dJMcagX7pQP/YYW6VoC2vv9c5IscYuod81/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cge5AP/dJMcagX7pQP/YYW6VoC2vv9c5IscYuod81/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fcge5AP%2FdJMcagX7pQP%2FYYW6VoC2vv9c5IscYuod81%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;1019&quot; height=&quot;662&quot; data-filename=&quot;07.PNG&quot; data-origin-width=&quot;1019&quot; data-origin-height=&quot;662&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;pre id=&quot;code_1762327143744&quot; class=&quot;cpp&quot; data-ke-language=&quot;cpp&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;/* USER CODE BEGIN 0 */
void set_servo(uint8_t degree){
	//degree는 0~180도 범위이고 CCR4는 600부터 2400의 범위이다!
	TIM2-&amp;gt;CCR4 = (uint32_t)(600+(2400-600)*degree/180.0);
}
/* USER CODE END 0 */
//중략
/* USER CODE BEGIN 2 */
 //PB11이 사용하는 TIM2_CH4를 시작하겠다!
 HAL_TIM_PWM_Start(&amp;amp;htim2,TIM_CHANNEL_4);
 set_servo(0); //시작할때 서보모터는 0도 위치!
 char recv;
 char buff[50];
 /* USER CODE END 2 */
 /* Infinite loop */
 /* USER CODE BEGIN WHILE */
 while (1)
 {
	  //PC에서 문자 1개가 수신되기로 약속되어있다!(0.5초 대기)
	  if(HAL_UART_Receive(&amp;amp;huart2, &amp;amp;recv, 1, 500) == HAL_OK){
		  //recv PC에서 보낸 1개의 문자가 들어있는 상태
		  if(recv == '0'){
			  set_servo(0);
			  sprintf(buff,&quot;NOW DEGREE = %d\n&quot;,0);
			  HAL_UART_Transmit(&amp;amp;huart2, buff, strlen(buff), 100);
		  }else if(recv == '1'){
			  set_servo(45);
			  sprintf(buff,&quot;NOW DEGREE = %d\n&quot;,45);
			  HAL_UART_Transmit(&amp;amp;huart2, buff, strlen(buff), 100);
		  }else if(recv == '2'){
			  set_servo(90);
			  sprintf(buff,&quot;NOW DEGREE = %d\n&quot;,90);
			  HAL_UART_Transmit(&amp;amp;huart2, buff, strlen(buff), 100);
		  }else if(recv == '3'){
			  set_servo(135);
			  sprintf(buff,&quot;NOW DEGREE = %d\n&quot;,135);
			  HAL_UART_Transmit(&amp;amp;huart2, buff, strlen(buff), 100);
		  }else if(recv == '4'){
			  set_servo(180);
			  sprintf(buff,&quot;NOW DEGREE = %d\n&quot;,180);
			  HAL_UART_Transmit(&amp;amp;huart2, buff, strlen(buff), 100);
		  }
	  }
   /* USER CODE END WHILE */
   /* USER CODE BEGIN 3 */
 }&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;br /&gt;8.녹칸다가&amp;nbsp;&amp;ldquo;0&amp;rdquo;부터&amp;nbsp;&amp;ldquo;180&amp;rdquo;까지의&amp;nbsp;각도값을&amp;nbsp;STM32로&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-filename=&quot;08.PNG&quot; data-origin-width=&quot;1056&quot; data-origin-height=&quot;667&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/mb4tQ/dJMcafZc4kn/KaeJs5umMx8kDfUKeATjJk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/mb4tQ/dJMcafZc4kn/KaeJs5umMx8kDfUKeATjJk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/mb4tQ/dJMcafZc4kn/KaeJs5umMx8kDfUKeATjJk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fmb4tQ%2FdJMcafZc4kn%2FKaeJs5umMx8kDfUKeATjJk%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;1056&quot; height=&quot;667&quot; data-filename=&quot;08.PNG&quot; data-origin-width=&quot;1056&quot; data-origin-height=&quot;667&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;pre id=&quot;code_1762327158537&quot; class=&quot;cpp&quot; data-ke-language=&quot;cpp&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;/* USER CODE BEGIN 0 */
void set_servo(uint8_t degree){
	//degree는 0~180도 범위이고 CCR4는 600부터 2400의 범위이다!
	TIM2-&amp;gt;CCR4 = (uint32_t)(600+(2400-600)*degree/180.0);
}
/* USER CODE END 0 */
//중략
/* USER CODE BEGIN 2 */
 //PB11이 사용하는 TIM2_CH4를 시작하겠다!
 HAL_TIM_PWM_Start(&amp;amp;htim2,TIM_CHANNEL_4);
 set_servo(0); //시작할때 서보모터는 0도 위치!
 char recv;
 int rx_index = 0;
 char rx_buff[50];
 char tx_buff[50];
 /* USER CODE END 2 */
 /* Infinite loop */
 /* USER CODE BEGIN WHILE */
 while (1)
 {
	  rx_index = 0;
	  while(HAL_UART_Receive(&amp;amp;huart2, &amp;amp;recv, 1, 500) == HAL_OK){
		  rx_buff[rx_index] = recv;
		  rx_index++;
		  if(recv == '\r'){
			  //PC에서 보낸 종료문자 확인!
			  rx_buff[rx_index] = '\0';
			  //rx_buff에 각도값이 들어있는건 알겠는데.. 숫자로 바꿔야하는데?
			  int degree = atoi(rx_buff);
			  //0~180도 사이로 입력이 되도록 설정
			  if(degree &amp;gt; 180) degree = 180;
			  if(degree &amp;lt; 0) degree = 0;
			  sprintf(tx_buff,&quot;NOW DEGREE = %d\n&quot;,degree);
			  HAL_UART_Transmit(&amp;amp;huart2, tx_buff, strlen(tx_buff), 100);
			  set_servo(degree);
		  }
	  }
   /* USER CODE END WHILE */
   /* USER CODE BEGIN 3 */
 }&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;br /&gt;9.PA0에&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-filename=&quot;09.PNG&quot; data-origin-width=&quot;992&quot; data-origin-height=&quot;646&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bP2LTR/dJMcacaloEz/UsnkrdoA1lpUpLC5YbduKK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bP2LTR/dJMcacaloEz/UsnkrdoA1lpUpLC5YbduKK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bP2LTR/dJMcacaloEz/UsnkrdoA1lpUpLC5YbduKK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbP2LTR%2FdJMcacaloEz%2FUsnkrdoA1lpUpLC5YbduKK%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;992&quot; height=&quot;646&quot; data-filename=&quot;09.PNG&quot; data-origin-width=&quot;992&quot; data-origin-height=&quot;646&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;pre id=&quot;code_1762327168565&quot; class=&quot;cpp&quot; data-ke-language=&quot;cpp&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;/* USER CODE BEGIN 0 */
void set_servo(uint8_t degree){
	//degree는 0~180도 범위이고 CCR4는 600부터 2400의 범위이다!
	TIM2-&amp;gt;CCR4 = (uint32_t)(600+(2400-600)*degree/180.0);
}
uint16_t map(uint16_t analog){
	return 180*analog/4095.0;
}
/* USER CODE END 0 */

//중략
/* USER CODE BEGIN 2 */
 //PB11이 사용하는 TIM2_CH4를 시작하겠다!
 HAL_TIM_PWM_Start(&amp;amp;htim2,TIM_CHANNEL_4);
 HAL_ADC_Start(&amp;amp;hadc1); //딱 한번만 호출(ADC1에 지정했을때)
 uint16_t adc_value0 = 0;
 /* USER CODE END 2 */
 /* Infinite loop */
 /* USER CODE BEGIN WHILE */
 while (1)
 {
	  if(HAL_ADC_PollForConversion(&amp;amp;hadc1, 10) == HAL_OK)
	  {
		  // 값 처리
		  adc_value0 = HAL_ADC_GetValue(&amp;amp;hadc1); //0~4095
		  //0~4095를 0~180도 범위로 조정해야한다!
		  set_servo(map(adc_value0));
	  }
	  HAL_Delay(10);
   /* USER CODE END WHILE */
   /* USER CODE BEGIN 3 */
 }&lt;/code&gt;&lt;/pre&gt;</description>
      <category>프로그래밍/STM32</category>
      <author>덕력킹</author>
      <guid isPermaLink="true">https://bota.tistory.com/2450</guid>
      <comments>https://bota.tistory.com/2450#entry2450comment</comments>
      <pubDate>Wed, 5 Nov 2025 16:22:37 +0900</pubDate>
    </item>
    <item>
      <title>[STM32#07] TIM3의 ARR와 CCR을 설정하고 PWM출력을 해서 부저(buzzer) 사운드 재생하는 방법 알아보기!(녹칸다 내맘대로 STM32)</title>
      <link>https://bota.tistory.com/2449</link>
      <description>&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;stm32.png&quot; data-origin-width=&quot;1920&quot; data-origin-height=&quot;1080&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/xojKw/dJMcabvJliK/38pT9JKqyu3kCaSxL72KRk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/xojKw/dJMcabvJliK/38pT9JKqyu3kCaSxL72KRk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/xojKw/dJMcabvJliK/38pT9JKqyu3kCaSxL72KRk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FxojKw%2FdJMcabvJliK%2F38pT9JKqyu3kCaSxL72KRk%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;1920&quot; height=&quot;1080&quot; data-filename=&quot;stm32.png&quot; data-origin-width=&quot;1920&quot; data-origin-height=&quot;1080&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/live/QPbT5pfgztc&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://youtube.com/live/QPbT5pfgztc&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/watch?v=QPbT5pfgztc&quot; data-video-thumbnail=&quot;https://scrap.kakaocdn.net/dn/f1wNe/hyZMHMASZF/gmtyHRB3KM6INoqd7OMkUK/img.jpg?width=1280&amp;amp;height=720&amp;amp;face=0_0_1280_720,https://scrap.kakaocdn.net/dn/HOfWO/hyZMTN8wbI/q7siObM1cl6sCHFeENkhtK/img.jpg?width=1280&amp;amp;height=720&amp;amp;face=0_0_1280_720&quot; data-video-width=&quot;860&quot; data-video-height=&quot;484&quot; data-video-origin-width=&quot;860&quot; data-video-origin-height=&quot;484&quot; data-ke-mobilestyle=&quot;widthContent&quot; data-video-title=&quot;[STM32#07] TIM3의 ARR와 CCR을 설정하고 PWM출력을 해서 부저(buzzer) 사운드 재생하는 방법 알아보기!(녹&quot; data-original-url=&quot;&quot;&gt;&lt;iframe src=&quot;https://www.youtube.com/embed/QPbT5pfgztc&quot; width=&quot;860&quot; height=&quot;484&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;[STM32#07]&amp;nbsp;TIM3의&amp;nbsp;ARR와&amp;nbsp;CCR을&amp;nbsp;설정하고&amp;nbsp;PWM출력을&amp;nbsp;해서&amp;nbsp;부저(buzzer)&amp;nbsp;사운드&amp;nbsp;재생하는&amp;nbsp;방법&amp;nbsp;알아보기!(녹칸다&amp;nbsp;내맘대로&amp;nbsp;STM32) &lt;br /&gt;&lt;br /&gt;심심한녹칸다의&amp;nbsp;내맘대로&amp;nbsp;STM32시리즈이다! &lt;br /&gt;&lt;br /&gt;STM32시리즈의&amp;nbsp;모든&amp;nbsp;자료는&amp;nbsp;구글&amp;nbsp;슬라이드에&amp;nbsp;작성하고&amp;nbsp;모두에게&amp;nbsp;공유되어있음! &lt;br /&gt;&lt;a href=&quot;https://docs.google.com/presentation/d/1myA5iYbjuKsLWLqtRLKAiRfwUwvqB1d1RGjiMIIgp3I/edit?slide=id.g39f7ee2e2d4_1_0#slide=id.g39f7ee2e2d4_1_0&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://docs.google.com/presentation/d/1myA5iYbjuKsLWLqtRLKAiRfwUwvqB1d1RGjiMIIgp3I/edit?slide=id.g39f7ee2e2d4_1_0#slide=id.g39f7ee2e2d4_1_0&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;이번편은&amp;nbsp;녹칸다의&amp;nbsp;STM32쉴드에&amp;nbsp;붙어있는&amp;nbsp;부저를&amp;nbsp;작동시켜보도록&amp;nbsp;하자! &lt;br /&gt;&lt;br /&gt;1.STM32에서 구조체와 포인터타입의 구조체에 대해서 차이를 알수있는 예시를 보이시오!&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;1.PNG&quot; data-origin-width=&quot;311&quot; data-origin-height=&quot;280&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/KbYo7/dJMcaacwhxV/7ySVh8XnU1r27rCIJhznr0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/KbYo7/dJMcaacwhxV/7ySVh8XnU1r27rCIJhznr0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/KbYo7/dJMcaacwhxV/7ySVh8XnU1r27rCIJhznr0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FKbYo7%2FdJMcaacwhxV%2F7ySVh8XnU1r27rCIJhznr0%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;311&quot; height=&quot;280&quot; data-filename=&quot;1.PNG&quot; data-origin-width=&quot;311&quot; data-origin-height=&quot;280&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;pre id=&quot;code_1762178520992&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 */
 char buff[50];
 typedef struct{
 	uint16_t num1;
 	int32_t num2;
 }Mystruct;
 //Mystruct type의 구조체를 s1이라는 이름으로 만들겠다!
 Mystruct s1;
 //Mystruct type의 구조체의 주소를 담는 포인터를 생성한다!
 Mystruct *s2;
 //s2에다가 s1의 주소를 넣겠다!
 //s2는 s1을 참조하게된다!
 s2 = &amp;amp;s1;
 /* USER CODE END 2 */
 /* Infinite loop */
 /* USER CODE BEGIN WHILE */
 while (1)
 {
	  //s1의 멤버인 num1에 10이라는 값을 대입하겠다!
	  s1.num1 = 10;
	  s1.num2 = 20;
	  sprintf(buff,&quot;CASE1 num1=%d, num2=%d\n&quot;,s1.num1,s1.num2);
	  HAL_UART_Transmit(&amp;amp;huart2, buff, strlen(buff), 100);
	  HAL_Delay(1000);
	  //s2를 통해서 s1의 num1의 값을 30으로 바꾸고, num2의 값을 40으로 바꾼다!
	  (*s2).num1 = 30;
	  (*s2).num2 = 40;
	  sprintf(buff,&quot;CASE2 num1=%d, num2=%d\n&quot;,s1.num1,s1.num2);
	  HAL_UART_Transmit(&amp;amp;huart2, buff, strlen(buff), 100);
	  HAL_Delay(1000);
	  s2-&amp;gt;num1 = 50;
	  s2-&amp;gt;num2 = 60;
	  sprintf(buff,&quot;CASE3 num1=%d, num2=%d\n&quot;,s1.num1,s1.num2);
	  HAL_UART_Transmit(&amp;amp;huart2, buff, strlen(buff), 100);
	  HAL_Delay(1000);
   /* USER CODE END WHILE */
   /* USER CODE BEGIN 3 */
 }&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;br /&gt;2.IOC를&amp;nbsp;설정해서&amp;nbsp;부저에&amp;nbsp;1초&amp;nbsp;간격으로&amp;nbsp;440hz의&amp;nbsp;부저음이&amp;nbsp;발생할&amp;nbsp;수&amp;nbsp;있도록&amp;nbsp;하시오!(PWM은&amp;nbsp;제일&amp;nbsp;처음&amp;nbsp;1회&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-filename=&quot;2.PNG&quot; data-origin-width=&quot;953&quot; data-origin-height=&quot;569&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/J8j8P/dJMcacBpgjF/oyzz3JC9mV09HuuWe7H3wK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/J8j8P/dJMcacBpgjF/oyzz3JC9mV09HuuWe7H3wK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/J8j8P/dJMcacBpgjF/oyzz3JC9mV09HuuWe7H3wK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FJ8j8P%2FdJMcacBpgjF%2Foyzz3JC9mV09HuuWe7H3wK%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;953&quot; height=&quot;569&quot; data-filename=&quot;2.PNG&quot; data-origin-width=&quot;953&quot; data-origin-height=&quot;569&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;pre id=&quot;code_1762178533474&quot; class=&quot;cpp&quot; data-ke-language=&quot;cpp&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;/* USER CODE BEGIN 0 */
static void Tone(uint32_t Frequency)
{
   TIM3-&amp;gt;ARR = (1000000UL / Frequency) - 1; //주파수
   TIM3-&amp;gt;CCR3 = (TIM3-&amp;gt;ARR &amp;gt;&amp;gt; 1); //듀티비 50%
}
/* USER CODE END 0 */
//중략
/* USER CODE BEGIN 2 */
 //TIM3_CH3의 PWM기능을 활성화하겠습니다!
 HAL_TIM_PWM_Start(&amp;amp;htim3,TIM_CHANNEL_3);
 //주파수값을 440hz로 설정한다
 Tone(440);
 //시작하면 일단 부저는 끈상태라
 HAL_GPIO_WritePin(GPIOC, GPIO_PIN_2, 0);
 /* USER CODE END 2 */
 /* Infinite loop */
 /* USER CODE BEGIN WHILE */
 while (1)
 {
	  //부저의 소리를 재생한다!(1초)
	  HAL_GPIO_WritePin(GPIOC, GPIO_PIN_2, 1);
	  HAL_Delay(1000);
	  //부저의 소리를 끈다!(1초)
	  HAL_GPIO_WritePin(GPIOC, GPIO_PIN_2, 0);
	  HAL_Delay(1000);
   /* USER CODE END WHILE */
   /* USER CODE BEGIN 3 */
 }&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;br /&gt;3.녹칸다가&amp;nbsp;쉴드에&amp;nbsp;붙혀놓은&amp;nbsp;8개의&amp;nbsp;버튼이&amp;nbsp;있다!&amp;nbsp;8개의&amp;nbsp;버튼을&amp;nbsp;도,레,미,파,솔,라,시,도까지를&amp;nbsp;버튼을&amp;nbsp;누를때&amp;nbsp;소리가&amp;nbsp;나오도록&amp;nbsp;하시오!(피아노&amp;nbsp;만들기)&lt;/p&gt;
&lt;pre id=&quot;code_1762178549671&quot; class=&quot;cpp&quot; data-ke-language=&quot;cpp&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;/* USER CODE BEGIN 0 */
static void Tone(uint32_t Frequency)
{
   TIM3-&amp;gt;ARR = (1000000UL / Frequency) - 1; //주파수
   TIM3-&amp;gt;CCR3 = (TIM3-&amp;gt;ARR &amp;gt;&amp;gt; 1); //듀티비 50%
}
#define NOTE_C6  1047 //도
#define NOTE_D6  1175 //레
#define NOTE_E6  1319 //미
#define NOTE_F6  1397 //파
#define NOTE_G6  1568 //솔
#define NOTE_A6  1760 //라
#define NOTE_B6  1976 //시
#define NOTE_C7  2093 //도

/* USER CODE END 0 */
//중략
/* USER CODE BEGIN 2 */
 //TIM3_CH3의 PWM기능을 활성화하겠습니다!
 HAL_TIM_PWM_Start(&amp;amp;htim3,TIM_CHANNEL_3);
 //시작하면 일단 부저는 끈상태라
 HAL_GPIO_WritePin(GPIOC, GPIO_PIN_2, 0);
 /* USER CODE END 2 */
 /* Infinite loop */
 /* USER CODE BEGIN WHILE */
 while (1)
 {
	  if(HAL_GPIO_ReadPin(GPIOB,GPIO_PIN_1) == 0){
		  HAL_GPIO_WritePin(GPIOC, GPIO_PIN_2, 1);
		  Tone(NOTE_C6);


	  }else if(HAL_GPIO_ReadPin(GPIOA,GPIO_PIN_8) == 0){
		  HAL_GPIO_WritePin(GPIOC, GPIO_PIN_2, 1);
		  Tone(NOTE_D6);
	  }else if(HAL_GPIO_ReadPin(GPIOB,GPIO_PIN_2) == 0){
		  HAL_GPIO_WritePin(GPIOC, GPIO_PIN_2, 1);
		  Tone(NOTE_E6);
	  }else if(HAL_GPIO_ReadPin(GPIOB,GPIO_PIN_6) == 0){
		  HAL_GPIO_WritePin(GPIOC, GPIO_PIN_2, 1);
		  Tone(NOTE_F6);
	  }else if(HAL_GPIO_ReadPin(GPIOC,GPIO_PIN_5) == 0){
		  HAL_GPIO_WritePin(GPIOC, GPIO_PIN_2, 1);
		  Tone(NOTE_G6);
	  }else if(HAL_GPIO_ReadPin(GPIOC,GPIO_PIN_7) == 0){
		  HAL_GPIO_WritePin(GPIOC, GPIO_PIN_2, 1);
		  Tone(NOTE_A6);
	  }else if(HAL_GPIO_ReadPin(GPIOA,GPIO_PIN_11) == 0){
		  HAL_GPIO_WritePin(GPIOC, GPIO_PIN_2, 1);
		  Tone(NOTE_B6);
	  }else if(HAL_GPIO_ReadPin(GPIOA,GPIO_PIN_12) == 0){
		  HAL_GPIO_WritePin(GPIOC, GPIO_PIN_2, 1);
		  Tone(NOTE_C7);
	  }else{
		  //소리를 끈다
		  HAL_GPIO_WritePin(GPIOC, GPIO_PIN_2, 0);
	  }
   /* USER CODE END WHILE */
   /* USER CODE BEGIN 3 */
 }&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;br /&gt;4.로터리엔코더를&amp;nbsp;이용해서&amp;nbsp;로터리엔코더의&amp;nbsp;회전이&amp;nbsp;감지되면&amp;nbsp;감지될때마다&amp;nbsp;아주&amp;nbsp;짧은&amp;nbsp;비프음을&amp;nbsp;발생시키시오!(시계&amp;nbsp;6옥타브미,&amp;nbsp;반시계는&amp;nbsp;6옥타브솔,로터리엔코더눌려지면&amp;nbsp;7옥타브도)&lt;/p&gt;
&lt;pre id=&quot;code_1762178562091&quot; class=&quot;cpp&quot; data-ke-language=&quot;cpp&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;/* USER CODE BEGIN 0 */
static void Tone(uint32_t Frequency)
{
   TIM3-&amp;gt;ARR = (1000000UL / Frequency) - 1; //주파수
   TIM3-&amp;gt;CCR3 = (TIM3-&amp;gt;ARR &amp;gt;&amp;gt; 1); //듀티비 50%
}
#define NOTE_C6  1047 //도
#define NOTE_D6  1175 //레
#define NOTE_E6  1319 //미
#define NOTE_F6  1397 //파
#define NOTE_G6  1568 //솔
#define NOTE_A6  1760 //라
#define NOTE_B6  1976 //시
#define NOTE_C7  2093 //도

/* USER CODE END 0 */
//중략
/* USER CODE BEGIN 2 */
 //TIM3_CH3의 PWM기능을 활성화하겠습니다!
 HAL_TIM_PWM_Start(&amp;amp;htim3,TIM_CHANNEL_3);
 //시작하면 일단 부저는 끈상태라
 HAL_GPIO_WritePin(GPIOC, GPIO_PIN_2, 0);
 uint8_t old_sensor_A  = 1;
 /* USER CODE END 2 */
 /* Infinite loop */
 /* USER CODE BEGIN WHILE */


while (1)
 {
	  uint8_t sensor_A = HAL_GPIO_ReadPin(GPIOA,GPIO_PIN_11); //A값
	  if(sensor_A == 0 &amp;amp;&amp;amp; old_sensor_A == 1){
		  //falling edge
		  uint8_t sensor_B = HAL_GPIO_ReadPin(GPIOA,GPIO_PIN_12); //B값
		  if(sensor_B == 0){
			  //시계
			  HAL_GPIO_WritePin(GPIOC, GPIO_PIN_2, 1);
			  Tone(NOTE_E6);
			  HAL_Delay(100);
			  HAL_GPIO_WritePin(GPIOC, GPIO_PIN_2, 0);
		  }else{
			  //반시계
			  HAL_GPIO_WritePin(GPIOC, GPIO_PIN_2, 1);
			  Tone(NOTE_G6);
			  HAL_Delay(100);
			  HAL_GPIO_WritePin(GPIOC, GPIO_PIN_2, 0);
		  }
	  }
	  old_sensor_A = sensor_A;
	  //PC7이 눌려지면 7옥타브 도 음이 재생된다!
	  if(HAL_GPIO_ReadPin(GPIOC,GPIO_PIN_7) == 0){
		  HAL_GPIO_WritePin(GPIOC, GPIO_PIN_2, 1);
		  Tone(NOTE_C7);
	  }else{
		  HAL_GPIO_WritePin(GPIOC, GPIO_PIN_2, 0);
	  }
   /* USER CODE END WHILE */
   /* USER CODE BEGIN 3 */
 }&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;br /&gt;5.PA0에&amp;nbsp;연결된&amp;nbsp;가변저항을&amp;nbsp;이용해서&amp;nbsp;부저의&amp;nbsp;피치를&amp;nbsp;6옥타브도부터&amp;nbsp;7옥타브&amp;nbsp;도까지를&amp;nbsp;설정하는데,&amp;nbsp;버튼1인&amp;nbsp;PB1을&amp;nbsp;누르면&amp;nbsp;부저가&amp;nbsp;재생되고,&amp;nbsp;버튼2인&amp;nbsp;PA8을&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-filename=&quot;5.PNG&quot; data-origin-width=&quot;783&quot; data-origin-height=&quot;555&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/c8GfaH/dJMcaezdVM8/CSkwLmroKQQ15I478uaaMK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/c8GfaH/dJMcaezdVM8/CSkwLmroKQQ15I478uaaMK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/c8GfaH/dJMcaezdVM8/CSkwLmroKQQ15I478uaaMK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fc8GfaH%2FdJMcaezdVM8%2FCSkwLmroKQQ15I478uaaMK%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;783&quot; height=&quot;555&quot; data-filename=&quot;5.PNG&quot; data-origin-width=&quot;783&quot; data-origin-height=&quot;555&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;pre id=&quot;code_1762178576112&quot; class=&quot;cpp&quot; data-ke-language=&quot;cpp&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;/* USER CODE BEGIN 0 */
static void Tone(uint32_t Frequency)
{
   TIM3-&amp;gt;ARR = (1000000UL / Frequency) - 1; //주파수
   TIM3-&amp;gt;CCR3 = (TIM3-&amp;gt;ARR &amp;gt;&amp;gt; 1); //듀티비 50%
}
#define NOTE_C6  1047 //도
#define NOTE_D6  1175 //레
#define NOTE_E6  1319 //미
#define NOTE_F6  1397 //파
#define NOTE_G6  1568 //솔
#define NOTE_A6  1760 //라
#define NOTE_B6  1976 //시
#define NOTE_C7  2093 //도

/* USER CODE END 0 */
//중략
/* USER CODE BEGIN 2 */
 //TIM3_CH3의 PWM기능을 활성화하겠습니다!
 HAL_TIM_PWM_Start(&amp;amp;htim3,TIM_CHANNEL_3);
 HAL_ADC_Start(&amp;amp;hadc1); //딱 한번만 호출
 uint16_t adc_value0 = 0;
 //시작하면 일단 부저는 끈상태라
 HAL_GPIO_WritePin(GPIOC, GPIO_PIN_2, 0);
 /* USER CODE END 2 */
 /* Infinite loop */
 /* USER CODE BEGIN WHILE */



while (1)
 {
	  //PB1을 누르면 부저의 소리가 난다
	  if(HAL_GPIO_ReadPin(GPIOB,GPIO_PIN_1) == 0){
		  HAL_GPIO_WritePin(GPIOC, GPIO_PIN_2, 1);
	  }
	  //PA8을 누르면 부저의 소리가 꺼진다
	  if(HAL_GPIO_ReadPin(GPIOA,GPIO_PIN_8) == 0){
		  HAL_GPIO_WritePin(GPIOC, GPIO_PIN_2, 0);
	  }
	  //측정할때마다 호출
	  if(HAL_ADC_PollForConversion(&amp;amp;hadc1, 10) == HAL_OK)
	  {
		  // 값 처리
		  adc_value0 = HAL_ADC_GetValue(&amp;amp;hadc1); //0~4095
		  //NOTE_C6 1047 ~ NOTE_C7 2094
		  adc_value0 = NOTE_C6+(NOTE_C7-NOTE_C6)*(adc_value0/4095.0);
		  Tone(adc_value0);
	  }
	  HAL_Delay(100);
   /* USER CODE END WHILE */
   /* USER CODE BEGIN 3 */
 }&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;br /&gt;6.예제5에서&amp;nbsp;했던&amp;nbsp;가변저항측정값을&amp;nbsp;CDS측정값으로&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-filename=&quot;6.PNG&quot; data-origin-width=&quot;727&quot; data-origin-height=&quot;550&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/nAGzh/dJMcaezdVNa/7ktt51gWYEcqhlb2Fi5BX0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/nAGzh/dJMcaezdVNa/7ktt51gWYEcqhlb2Fi5BX0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/nAGzh/dJMcaezdVNa/7ktt51gWYEcqhlb2Fi5BX0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FnAGzh%2FdJMcaezdVNa%2F7ktt51gWYEcqhlb2Fi5BX0%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;727&quot; height=&quot;550&quot; data-filename=&quot;6.PNG&quot; data-origin-width=&quot;727&quot; data-origin-height=&quot;550&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;pre id=&quot;code_1762178609469&quot; class=&quot;cpp&quot; data-ke-language=&quot;cpp&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;/* USER CODE BEGIN 0 */
static void Tone(uint32_t Frequency)
{
   TIM3-&amp;gt;ARR = (1000000UL / Frequency) - 1; //주파수
   TIM3-&amp;gt;CCR3 = (TIM3-&amp;gt;ARR &amp;gt;&amp;gt; 1); //듀티비 50%
}
#define NOTE_C6  1047 //도
#define NOTE_D6  1175 //레
#define NOTE_E6  1319 //미
#define NOTE_F6  1397 //파
#define NOTE_G6  1568 //솔
#define NOTE_A6  1760 //라
#define NOTE_B6  1976 //시
#define NOTE_C7  2093 //도

/* USER CODE END 0 */
//중략
/* USER CODE BEGIN 2 */
 //TIM3_CH3의 PWM기능을 활성화하겠습니다!
 HAL_TIM_PWM_Start(&amp;amp;htim3,TIM_CHANNEL_3);
 HAL_ADC_Start(&amp;amp;hadc1); //딱 한번만 호출
 uint16_t adc_value0 = 0;
 //시작하면 일단 부저는 끈상태라
 HAL_GPIO_WritePin(GPIOC, GPIO_PIN_2, 0);
 /* USER CODE END 2 */
 /* Infinite loop */
 /* USER CODE BEGIN WHILE */



while (1)
 {
	  //PB1을 누르면 부저의 소리가 난다
	  if(HAL_GPIO_ReadPin(GPIOB,GPIO_PIN_1) == 0){
		  HAL_GPIO_WritePin(GPIOC, GPIO_PIN_2, 1);
	  }
	  //PA8을 누르면 부저의 소리가 꺼진다
	  if(HAL_GPIO_ReadPin(GPIOA,GPIO_PIN_8) == 0){
		  HAL_GPIO_WritePin(GPIOC, GPIO_PIN_2, 0);
	  }
	  //측정할때마다 호출
	  if(HAL_ADC_PollForConversion(&amp;amp;hadc1, 10) == HAL_OK)
	  {
		  // 값 처리
		  adc_value0 = HAL_ADC_GetValue(&amp;amp;hadc1); //0~4095
		  //NOTE_C6 1047 ~ NOTE_C7 2094
		  adc_value0 = NOTE_C6+(NOTE_C7-NOTE_C6)*(adc_value0/4095.0);
		  Tone(adc_value0);
	  }
	  HAL_Delay(100);
   /* USER CODE END WHILE */
   /* USER CODE BEGIN 3 */
 }&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;7.PA1에&amp;nbsp;연결된&amp;nbsp;CDS의&amp;nbsp;아날로그&amp;nbsp;값을&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_1762178621128&quot; class=&quot;cpp&quot; data-ke-language=&quot;cpp&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;/* USER CODE BEGIN 0 */
static void Tone(uint32_t Frequency)
{
   TIM3-&amp;gt;ARR = (1000000UL / Frequency) - 1; //주파수
   TIM3-&amp;gt;CCR3 = (TIM3-&amp;gt;ARR &amp;gt;&amp;gt; 1); //듀티비 50%
}
#define NOTE_C6  1047 //도
#define NOTE_D6  1175 //레
#define NOTE_E6  1319 //미
#define NOTE_F6  1397 //파
#define NOTE_G6  1568 //솔
#define NOTE_A6  1760 //라
#define NOTE_B6  1976 //시
#define NOTE_C7  2093 //도

/* USER CODE END 0 */
//중략
/* USER CODE BEGIN 2 */
 //TIM3_CH3의 PWM기능을 활성화하겠습니다!
 HAL_TIM_PWM_Start(&amp;amp;htim3,TIM_CHANNEL_3);
 HAL_ADC_Start(&amp;amp;hadc1); //딱 한번만 호출
 uint16_t adc_value0 = 0;
 //시작하면 일단 부저는 끈상태라
 HAL_GPIO_WritePin(GPIOC, GPIO_PIN_2, 0);
 Tone(NOTE_G6);
 /* USER CODE END 2 */
 /* Infinite loop */
 /* USER CODE BEGIN WHILE */




while (1)
 {
	  //측정할때마다 호출
	  if(HAL_ADC_PollForConversion(&amp;amp;hadc1, 10) == HAL_OK)
	  {
		  // 값 처리
		  adc_value0 = HAL_ADC_GetValue(&amp;amp;hadc1); //0~4095
		  //측정값이 1000보다 크면 부저에 소리가 안나고
		  //그게 아니라면 소리가 난다
		  if(adc_value0 &amp;gt; 1000){
			  HAL_GPIO_WritePin(GPIOC, GPIO_PIN_2, 0);
		  }else{
			  HAL_GPIO_WritePin(GPIOC, GPIO_PIN_2, 1);
		  }
	  }
	  HAL_Delay(100);
   /* USER CODE END WHILE */
   /* USER CODE BEGIN 3 */
 }&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;br /&gt;8.로터리엔코더를&amp;nbsp;돌리면&amp;nbsp;세탁메뉴가&amp;nbsp;변경되는데&amp;nbsp;LED8개중에&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;부저로&amp;nbsp;재생하시오!&amp;nbsp;그리고&amp;nbsp;로터리엔코더가&amp;nbsp;회전할때&amp;nbsp;회전하는&amp;nbsp;사운드도&amp;nbsp;추가하시오!&lt;/p&gt;
&lt;pre id=&quot;code_1762178643714&quot; class=&quot;cpp&quot; data-ke-language=&quot;cpp&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;/* USER CODE BEGIN 0 */
static void Tone(uint32_t Frequency)
{
   TIM3-&amp;gt;ARR = (1000000UL / Frequency) - 1; //주파수
   TIM3-&amp;gt;CCR3 = (TIM3-&amp;gt;ARR &amp;gt;&amp;gt; 1); //듀티비 50%
}
#define NOTE_C6  1047 //도
#define NOTE_D6  1175 //레
#define NOTE_E6  1319 //미
#define NOTE_F6  1397 //파
#define NOTE_G6  1568 //솔
#define NOTE_A6  1760 //라
#define NOTE_B6  1976 //시
#define NOTE_C7  2093 //도
#define NOTE_D7  2349 //레
void play_melody(){
	HAL_GPIO_WritePin(GPIOC, GPIO_PIN_2,1);
	  Tone(NOTE_G6);
	  HAL_Delay(500);
	  Tone(NOTE_C7);
	  HAL_Delay(500/3);
	  Tone(NOTE_B6);
	  HAL_Delay(500/3);
	  Tone(NOTE_A6);
	  HAL_Delay(500/3);
	  Tone(NOTE_G6);
	  HAL_Delay(500);
	  Tone(NOTE_E6);
	  HAL_Delay(500);
	  //파솔라 레미파 미 솔
	  Tone(NOTE_F6);
	  HAL_Delay(500/3);

	  Tone(NOTE_G6);
	  HAL_Delay(500/3);
	  Tone(NOTE_A6);
	  HAL_Delay(500/3);
	  Tone(NOTE_D6);
	  HAL_Delay(500/3);
	  Tone(NOTE_E6);
	  HAL_Delay(500/3);
	  Tone(NOTE_F6);
	  HAL_Delay(500/3);
	  Tone(NOTE_E6);
	  HAL_Delay(500);
	  Tone(NOTE_G6);
	  HAL_Delay(500);
	  //
	  Tone(NOTE_G6);
	  HAL_Delay(500);
	  Tone(NOTE_C7);
	  HAL_Delay(500/3);
	  Tone(NOTE_B6);
	  HAL_Delay(500/3);
	  Tone(NOTE_A6);
	  HAL_Delay(500/3);
	  Tone(NOTE_G6);
	  HAL_Delay(500);
	  Tone(NOTE_C7);
	  HAL_Delay(500);
	  //도레도 시라시 도~
	  Tone(NOTE_C7);
	  HAL_Delay(500/3);
	  Tone(NOTE_D7);
	  HAL_Delay(500/3);
	  Tone(NOTE_C7);
	  HAL_Delay(500/3);
	  Tone(NOTE_B6);
	  HAL_Delay(500/3);

	  Tone(NOTE_A6);
	  HAL_Delay(500/3);
	  Tone(NOTE_B6);
	  HAL_Delay(500/3);
	  Tone(NOTE_C7);
	  HAL_Delay(1000);
	  HAL_GPIO_WritePin(GPIOC, GPIO_PIN_2,0);
}
GPIO_TypeDef *mygroup[] = {GPIOB,GPIOB,GPIOB,GPIOB,GPIOB,GPIOB,GPIOC,GPIOB};
uint16_t mypin[] = {GPIO_PIN_3,GPIO_PIN_13,GPIO_PIN_5,GPIO_PIN_14,GPIO_PIN_4,GPIO_PIN_15,GPIO_PIN_4,GPIO_PIN_7};
void set_led(int num){
	//LED의 상태 업데이트 현재 켜져야하는 LED는 CNT번째꺼
	  for(int i = 0;i&amp;lt;8;i++){
		  if(i == num){
			  HAL_GPIO_WritePin(mygroup[i],mypin[i],GPIO_PIN_SET);
		  }else{
			  HAL_GPIO_WritePin(mygroup[i],mypin[i],GPIO_PIN_RESET);
		  }
	  }
	  HAL_GPIO_WritePin(GPIOC, GPIO_PIN_2,1);
	  Tone(NOTE_G6);
	  HAL_Delay(100);
	  HAL_GPIO_WritePin(GPIOC, GPIO_PIN_2,0);
}
/* USER CODE END 0 */


/* USER CODE BEGIN 2 */
 //TIM3_CH3의 PWM기능을 활성화하겠습니다!
 HAL_TIM_PWM_Start(&amp;amp;htim3,TIM_CHANNEL_3);
 //시작하면 일단 부저는 끈상태라
 HAL_GPIO_WritePin(GPIOC, GPIO_PIN_2, 0);
 uint8_t old_A = 0;
 int cnt = 0;
   //시작하자마자 일단 12시방향의 LED는 1개 켜고 출발한다!
 HAL_GPIO_WritePin(mygroup[0],mypin[0],GPIO_PIN_SET);
 /* USER CODE END 2 */
 /* Infinite loop */
 /* USER CODE BEGIN WHILE */
 while (1)
 {
	  //PA11의 상승엣지가 발생했을때
	  uint8_t now_A = HAL_GPIO_ReadPin(GPIOA,GPIO_PIN_11);
	  if(old_A == 0 &amp;amp;&amp;amp; now_A == 1){
		  //PA12의 값을 측정해서 LOW면 시계, HIGH면 반시계
		  uint8_t now_B = HAL_GPIO_ReadPin(GPIOA,GPIO_PIN_12);
		  if(now_B){
			 //반시계
			  cnt--;
			  if(cnt &amp;lt; 0) cnt = 7;
			  set_led(cnt);

		  }else{
			 //시계
			  cnt++;
			  if(cnt &amp;gt; 7) cnt = 0;
			  set_led(cnt);
		  }
	  }
	  old_A = now_A;
	  //PC7을 누르면 세탁기 완료 사운드가 재생된다
	  if(HAL_GPIO_ReadPin(GPIOC,GPIO_PIN_7) == 0){
		  play_melody();
	  }
   /* USER CODE END WHILE */
   /* USER CODE BEGIN 3 */
 }&lt;/code&gt;&lt;/pre&gt;</description>
      <category>프로그래밍/STM32</category>
      <author>덕력킹</author>
      <guid isPermaLink="true">https://bota.tistory.com/2449</guid>
      <comments>https://bota.tistory.com/2449#entry2449comment</comments>
      <pubDate>Mon, 3 Nov 2025 23:05:38 +0900</pubDate>
    </item>
    <item>
      <title>[STM32#06] HAL_ADC_PollForConversion(),HAL_ADC_GetValue()을 이용해서 analog값 입력 방법 알아보기!(녹칸다 내맘대로 STM32)</title>
      <link>https://bota.tistory.com/2448</link>
      <description>&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;stm32.png&quot; data-origin-width=&quot;1920&quot; data-origin-height=&quot;1080&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/o18ID/dJMcacg4Z1F/BVW7NyVGxLXkODYapQfUtk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/o18ID/dJMcacg4Z1F/BVW7NyVGxLXkODYapQfUtk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/o18ID/dJMcacg4Z1F/BVW7NyVGxLXkODYapQfUtk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fo18ID%2FdJMcacg4Z1F%2FBVW7NyVGxLXkODYapQfUtk%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;1920&quot; height=&quot;1080&quot; data-filename=&quot;stm32.png&quot; data-origin-width=&quot;1920&quot; data-origin-height=&quot;1080&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/live/tYoSbV1Dg9I&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://youtube.com/live/tYoSbV1Dg9I&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/watch?v=tYoSbV1Dg9I&quot; data-video-thumbnail=&quot;https://scrap.kakaocdn.net/dn/eixGeL/hyZMFOkbkt/4jWh4FtTzogMHx6tRM4RPk/img.jpg?width=1280&amp;amp;height=720&amp;amp;face=0_0_1280_720&quot; data-video-width=&quot;860&quot; data-video-height=&quot;484&quot; data-video-origin-width=&quot;860&quot; data-video-origin-height=&quot;484&quot; data-ke-mobilestyle=&quot;widthContent&quot; data-video-title=&quot;[STM32#06] HAL_ADC_PollForConversion(),HAL_ADC_GetValue()을 이용해서 analog값 입력 방법 알아보기!(녹칸다 내맘&quot; data-original-url=&quot;&quot;&gt;&lt;iframe src=&quot;https://www.youtube.com/embed/tYoSbV1Dg9I&quot; width=&quot;860&quot; height=&quot;484&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;[STM32#06]&amp;nbsp;HAL_ADC_PollForConversion(),HAL_ADC_GetValue()을&amp;nbsp;이용해서&amp;nbsp;아날로그(analog)값을&amp;nbsp;입력받는&amp;nbsp;방법&amp;nbsp;알아보기!(녹칸다&amp;nbsp;내맘대로&amp;nbsp;STM32) &lt;br /&gt;&lt;br /&gt;심심한녹칸다의&amp;nbsp;내맘대로&amp;nbsp;STM32시리즈이다! &lt;br /&gt;&lt;br /&gt;STM32시리즈의&amp;nbsp;모든&amp;nbsp;자료는&amp;nbsp;구글&amp;nbsp;슬라이드에&amp;nbsp;작성하고&amp;nbsp;모두에게&amp;nbsp;공유되어있음! &lt;br /&gt;&lt;a href=&quot;https://docs.google.com/presentation/d/1myA5iYbjuKsLWLqtRLKAiRfwUwvqB1d1RGjiMIIgp3I/edit?slide=id.g398060de84c_1_222#slide=id.g398060de84c_1_222&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://docs.google.com/presentation/d/1myA5iYbjuKsLWLqtRLKAiRfwUwvqB1d1RGjiMIIgp3I/edit?slide=id.g398060de84c_1_222#slide=id.g398060de84c_1_222&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;이번편에는&amp;nbsp;녹칸다의&amp;nbsp;STM32쉴드에&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;(STM32에서&amp;nbsp;아날로그입력시&amp;nbsp;알고있으면&amp;nbsp;좋은점!)&lt;br /&gt;1.STM32에는&amp;nbsp;아날로그입력을&amp;nbsp;위한&amp;nbsp;ADC가&amp;nbsp;12bit가&amp;nbsp;적용된다!&lt;br /&gt;2.아두이노&amp;nbsp;우노는&amp;nbsp;ADC가&amp;nbsp;10bit이고&amp;nbsp;측정값의&amp;nbsp;범위가&amp;nbsp;0~1023이다!&lt;br /&gt;3.아하!&amp;nbsp;그러면&amp;nbsp;STM32는&amp;nbsp;0~4095의&amp;nbsp;범위를&amp;nbsp;가지는군요!(정답)&lt;br /&gt;4.아두이노의&amp;nbsp;경우&amp;nbsp;analogRead(핀번호)&amp;nbsp;라고&amp;nbsp;하면&amp;nbsp;아주&amp;nbsp;간단하게&amp;nbsp;값&amp;nbsp;측정이&amp;nbsp;가능하나,&amp;nbsp;STM32는&amp;nbsp;그렇게&amp;nbsp;간단하지&amp;nbsp;않다!&lt;br /&gt;5.아날로그값을&amp;nbsp;1개로&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;br /&gt;6.지금&amp;nbsp;사용하는&amp;nbsp;뉴클레오보드는&amp;nbsp;ADC1과&amp;nbsp;ADC2로&amp;nbsp;2개로&amp;nbsp;구성되어있고&amp;nbsp;이하에&amp;nbsp;IN이라는&amp;nbsp;여러개의&amp;nbsp;채널로&amp;nbsp;구성되어있다!&lt;br /&gt;7.내가&amp;nbsp;사용할&amp;nbsp;핀을&amp;nbsp;ADC1이나&amp;nbsp;ADC2의&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;(아날로그 3종세트 회로도)&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;회로도1.PNG&quot; data-origin-width=&quot;1176&quot; data-origin-height=&quot;663&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/b3VOGA/dJMcahCGTpu/rw5ok9haChPYkpJeBeiSGK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/b3VOGA/dJMcahCGTpu/rw5ok9haChPYkpJeBeiSGK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/b3VOGA/dJMcahCGTpu/rw5ok9haChPYkpJeBeiSGK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fb3VOGA%2FdJMcahCGTpu%2Frw5ok9haChPYkpJeBeiSGK%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;1176&quot; height=&quot;663&quot; data-filename=&quot;회로도1.PNG&quot; data-origin-width=&quot;1176&quot; data-origin-height=&quot;663&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;회로도2.PNG&quot; data-origin-width=&quot;1291&quot; data-origin-height=&quot;651&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/zDCHF/dJMb99Lqpvc/ECaIKu6EO4UIgg5a4U9JL0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/zDCHF/dJMb99Lqpvc/ECaIKu6EO4UIgg5a4U9JL0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/zDCHF/dJMb99Lqpvc/ECaIKu6EO4UIgg5a4U9JL0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FzDCHF%2FdJMb99Lqpvc%2FECaIKu6EO4UIgg5a4U9JL0%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;1291&quot; height=&quot;651&quot; data-filename=&quot;회로도2.PNG&quot; data-origin-width=&quot;1291&quot; data-origin-height=&quot;651&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;br /&gt;(예제목차) &lt;br /&gt;1.PB1과&amp;nbsp;PA8에&amp;nbsp;연결된&amp;nbsp;버튼을&amp;nbsp;EXTI로&amp;nbsp;설정한다음&amp;nbsp;PB1버튼을&amp;nbsp;누르면&amp;nbsp;PB3에&amp;nbsp;연결된&amp;nbsp;LED가&amp;nbsp;ON되고&amp;nbsp;PA8버튼을&amp;nbsp;누르면&amp;nbsp;OFF되도록&amp;nbsp;하는데,&amp;nbsp;main&amp;nbsp;loop에&amp;nbsp;10초간격으로&amp;nbsp;&amp;ldquo;NOCKANDA&amp;rdquo;라고&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-filename=&quot;ioc1.PNG&quot; data-origin-width=&quot;1197&quot; data-origin-height=&quot;605&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bxhFbe/dJMcaksEcJD/8U1lxL73VrfCtKyuVb94Xk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bxhFbe/dJMcaksEcJD/8U1lxL73VrfCtKyuVb94Xk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bxhFbe/dJMcaksEcJD/8U1lxL73VrfCtKyuVb94Xk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbxhFbe%2FdJMcaksEcJD%2F8U1lxL73VrfCtKyuVb94Xk%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;1197&quot; height=&quot;605&quot; data-filename=&quot;ioc1.PNG&quot; data-origin-width=&quot;1197&quot; data-origin-height=&quot;605&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;pre id=&quot;code_1761722135931&quot; class=&quot;cpp&quot; data-ke-language=&quot;cpp&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;/* USER CODE BEGIN 0 */
void HAL_GPIO_EXTI_Callback(uint16_t GPIO_Pin)
{
 if(GPIO_Pin == GPIO_PIN_1)
 {
	   //LED ON
	  HAL_GPIO_WritePin(GPIOB,GPIO_PIN_3, 1);
 }else if(GPIO_Pin == GPIO_PIN_8)
 {
	   //LED OFF
	  HAL_GPIO_WritePin(GPIOB,GPIO_PIN_3, 0);
 }
}
/* USER CODE END 0 */
//중략
/* USER CODE BEGIN WHILE */
 while (1)
 {
	  HAL_UART_Transmit(&amp;amp;huart2, &quot;NOCKANDA!!\n&quot;, 11, 100);
	  HAL_Delay(10000);
   /* USER CODE END WHILE */
   /* USER CODE BEGIN 3 */
 }&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;br /&gt;2.PA0에&amp;nbsp;연결된&amp;nbsp;가변저항값을&amp;nbsp;측정해서&amp;nbsp;100밀리초&amp;nbsp;간격으로&amp;nbsp;시리얼출력하시오!(ADC1&amp;nbsp;IN0에&amp;nbsp;지정)&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;ioc2.PNG&quot; data-origin-width=&quot;1098&quot; data-origin-height=&quot;666&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/0o0er/dJMcac2r6GF/32Bk9NqnTKy9kfK9BjJ1lk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/0o0er/dJMcac2r6GF/32Bk9NqnTKy9kfK9BjJ1lk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/0o0er/dJMcac2r6GF/32Bk9NqnTKy9kfK9BjJ1lk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2F0o0er%2FdJMcac2r6GF%2F32Bk9NqnTKy9kfK9BjJ1lk%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;1098&quot; height=&quot;666&quot; data-filename=&quot;ioc2.PNG&quot; data-origin-width=&quot;1098&quot; data-origin-height=&quot;666&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;pre id=&quot;code_1761722161512&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 */
 HAL_ADC_Start(&amp;amp;hadc1); //딱 한번만 호출
 uint16_t adc_value0 = 0;
 char buff[50];
 /* USER CODE END 2 */
 /* Infinite loop */
 /* USER CODE BEGIN WHILE */
 while (1)
 {
	  //측정할때마다 호출
	  if(HAL_ADC_PollForConversion(&amp;amp;hadc1, 10) == HAL_OK)
	  {
		  // 값 처리
		  adc_value0 = HAL_ADC_GetValue(&amp;amp;hadc1); //0~4095
		  sprintf(buff,&quot;A0 = %d\n&quot;,adc_value0);
		  HAL_UART_Transmit(&amp;amp;huart2, buff, strlen(buff), 100);
	  }
	  HAL_Delay(100);
   /* USER CODE END WHILE */
   /* USER CODE BEGIN 3 */
 }&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;br /&gt;3.측정한&amp;nbsp;가변저항이&amp;nbsp;대략&amp;nbsp;0~4095의&amp;nbsp;값이&amp;nbsp;나오는데,&amp;nbsp;이값을&amp;nbsp;이용해서&amp;nbsp;부착되어있는&amp;nbsp;LED&amp;nbsp;8개를&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-filename=&quot;03.PNG&quot; data-origin-width=&quot;1079&quot; data-origin-height=&quot;656&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/ccqVqW/dJMcaezcmEq/XW16TDSCakUai1w1B8kjA0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/ccqVqW/dJMcaezcmEq/XW16TDSCakUai1w1B8kjA0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/ccqVqW/dJMcaezcmEq/XW16TDSCakUai1w1B8kjA0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FccqVqW%2FdJMcaezcmEq%2FXW16TDSCakUai1w1B8kjA0%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;1079&quot; height=&quot;656&quot; data-filename=&quot;03.PNG&quot; data-origin-width=&quot;1079&quot; data-origin-height=&quot;656&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;pre id=&quot;code_1761722188763&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 */
 HAL_ADC_Start(&amp;amp;hadc1); //딱 한번만 호출
 uint16_t adc_value0 = 0;
 char buff[50];
 GPIO_TypeDef *mygroup[] = {GPIOB,GPIOB,GPIOB,GPIOB,GPIOB,GPIOB,GPIOC,GPIOB};
 uint16_t mypin[] = {GPIO_PIN_3,GPIO_PIN_13,GPIO_PIN_5,GPIO_PIN_14,GPIO_PIN_4,GPIO_PIN_15,GPIO_PIN_4,GPIO_PIN_7};
 /* USER CODE END 2 */
 /* Infinite loop */
 /* USER CODE BEGIN WHILE */
 while (1)
 {
	  //측정할때마다 호출
	  if(HAL_ADC_PollForConversion(&amp;amp;hadc1, 10) == HAL_OK)
	  {
		  // 값 처리
		  adc_value0 = HAL_ADC_GetValue(&amp;amp;hadc1); //0~4095
		  //0~4095의 범위를 0~7사이로 변환해라!
		  adc_value0 = 7 * adc_value0/4000.0;
		  sprintf(buff,&quot;A0 = %d\n&quot;,adc_value0);
		  HAL_UART_Transmit(&amp;amp;huart2, buff, strlen(buff), 100);
		  //8개의 LED를 0~7사이에 나온 LED의 갯수만큼 켠다
		  for(int i = 0;i &amp;lt; 8;i++){
			  if(i &amp;lt;= adc_value0){
				  HAL_GPIO_WritePin(mygroup[i],mypin[i], 1);
			  }else{
				  HAL_GPIO_WritePin(mygroup[i],mypin[i], 0);
			  }
		  }
	  }
	  HAL_Delay(100);
   /* USER CODE END WHILE */
   /* USER CODE BEGIN 3 */
 }&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;br /&gt;4.PA1에&amp;nbsp;연결되어있는&amp;nbsp;CDS의&amp;nbsp;값을&amp;nbsp;100밀리초&amp;nbsp;간격으로&amp;nbsp;측정해서&amp;nbsp;시리얼출력하시오!(ADC1&amp;nbsp;IN1에&amp;nbsp;지정)&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;04.PNG&quot; data-origin-width=&quot;1144&quot; data-origin-height=&quot;657&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/QtK0V/dJMb99LqpvJ/n81p34kZNIY2zWczMY9oD1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/QtK0V/dJMb99LqpvJ/n81p34kZNIY2zWczMY9oD1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/QtK0V/dJMb99LqpvJ/n81p34kZNIY2zWczMY9oD1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FQtK0V%2FdJMb99LqpvJ%2Fn81p34kZNIY2zWczMY9oD1%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;1144&quot; height=&quot;657&quot; data-filename=&quot;04.PNG&quot; data-origin-width=&quot;1144&quot; data-origin-height=&quot;657&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;pre id=&quot;code_1761722211665&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 */
 HAL_ADC_Start(&amp;amp;hadc1); //딱 한번만 호출
 uint16_t adc_value0 = 0;
 char buff[50];
 /* USER CODE END 2 */
 /* Infinite loop */
 /* USER CODE BEGIN WHILE */
 while (1)
 {
	  //측정할때마다 호출
	  if(HAL_ADC_PollForConversion(&amp;amp;hadc1, 10) == HAL_OK)
	  {
		  // 값 처리
		  adc_value0 = HAL_ADC_GetValue(&amp;amp;hadc1); //0~4095
		  sprintf(buff,&quot;A1 = %d\n&quot;,adc_value0);
		  HAL_UART_Transmit(&amp;amp;huart2, buff, strlen(buff), 100);
	  }
	  HAL_Delay(100);
   /* USER CODE END WHILE */
   /* USER CODE BEGIN 3 */
 }&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;br /&gt;5.측정한&amp;nbsp;CDS값이&amp;nbsp;1000을&amp;nbsp;넘으면&amp;nbsp;LED&amp;nbsp;8개를&amp;nbsp;모두&amp;nbsp;ON하고&amp;nbsp;1000보다&amp;nbsp;작으면&amp;nbsp;OFF하시오!&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;05.PNG&quot; data-origin-width=&quot;1068&quot; data-origin-height=&quot;671&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/dPvb6Y/dJMcaihiqGI/0k9f2wtsqz6TySZn2WxAS0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/dPvb6Y/dJMcaihiqGI/0k9f2wtsqz6TySZn2WxAS0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/dPvb6Y/dJMcaihiqGI/0k9f2wtsqz6TySZn2WxAS0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FdPvb6Y%2FdJMcaihiqGI%2F0k9f2wtsqz6TySZn2WxAS0%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;1068&quot; height=&quot;671&quot; data-filename=&quot;05.PNG&quot; data-origin-width=&quot;1068&quot; data-origin-height=&quot;671&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;pre id=&quot;code_1761722233108&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 */
 HAL_ADC_Start(&amp;amp;hadc1); //딱 한번만 호출
 uint16_t adc_value0 = 0;
 char buff[50];
 GPIO_TypeDef *mygroup[] = {GPIOB,GPIOB,GPIOB,GPIOB,GPIOB,GPIOB,GPIOC,GPIOB};
 uint16_t mypin[] = {GPIO_PIN_3,GPIO_PIN_13,GPIO_PIN_5,GPIO_PIN_14,GPIO_PIN_4,GPIO_PIN_15,GPIO_PIN_4,GPIO_PIN_7};
 /* USER CODE END 2 */
 /* Infinite loop */
 /* USER CODE BEGIN WHILE */
 while (1)
 {
	  //측정할때마다 호출
	  if(HAL_ADC_PollForConversion(&amp;amp;hadc1, 10) == HAL_OK)
	  {
		  // 값 처리
		  adc_value0 = HAL_ADC_GetValue(&amp;amp;hadc1); //0~4095
		  //CDS의 값이 1000미만이면 LED OFF고 1000이상이면 ON이다!
		  if(adc_value0 &amp;gt;= 1000){
			  for(int i = 0;i&amp;lt;8;i++){
				  HAL_GPIO_WritePin(mygroup[i], mypin[i], 0);
			  }
		  }else{
			  for(int i = 0;i&amp;lt;8;i++){
				  HAL_GPIO_WritePin(mygroup[i], mypin[i], 1);
			  }
		  }
		  sprintf(buff,&quot;A1 = %d\n&quot;,adc_value0);
		  HAL_UART_Transmit(&amp;amp;huart2, buff, strlen(buff), 100);
	  }
	  HAL_Delay(100);
   /* USER CODE END WHILE */
   /* USER CODE BEGIN 3 */
 }&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;br /&gt;6.측정한&amp;nbsp;CDS값을&amp;nbsp;전압으로&amp;nbsp;계산해서&amp;nbsp;100밀리초&amp;nbsp;간격으로&amp;nbsp;출력하시오!&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;06.PNG&quot; data-origin-width=&quot;1067&quot; data-origin-height=&quot;648&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/ZTFG4/dJMcajgcIxI/C7kaRKPtL2iajOEfzpa7Sk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/ZTFG4/dJMcajgcIxI/C7kaRKPtL2iajOEfzpa7Sk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/ZTFG4/dJMcajgcIxI/C7kaRKPtL2iajOEfzpa7Sk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FZTFG4%2FdJMcajgcIxI%2FC7kaRKPtL2iajOEfzpa7Sk%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;1067&quot; height=&quot;648&quot; data-filename=&quot;06.PNG&quot; data-origin-width=&quot;1067&quot; data-origin-height=&quot;648&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;pre id=&quot;code_1761722255676&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 */
 HAL_ADC_Start(&amp;amp;hadc1); //딱 한번만 호출
 uint16_t adc_value0 = 0;
 char buff[50];
 /* USER CODE END 2 */
 /* Infinite loop */
 /* USER CODE BEGIN WHILE */
 while (1)
 {
	  //측정할때마다 호출
	  if(HAL_ADC_PollForConversion(&amp;amp;hadc1, 10) == HAL_OK)
	  {
		  // 값 처리
		  adc_value0 = HAL_ADC_GetValue(&amp;amp;hadc1); //0~4095
		  float voltage = 3.3*(adc_value0/4095.0);
		  sprintf(buff,&quot;Voltage = %f\n&quot;,voltage);
		  HAL_UART_Transmit(&amp;amp;huart2, buff, strlen(buff), 100);
	  }
	  HAL_Delay(100);
   /* USER CODE END WHILE */
   /* USER CODE BEGIN 3 */
 }&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;br /&gt;7.PA4에&amp;nbsp;연결된&amp;nbsp;NTC서미스터의&amp;nbsp;온도값을&amp;nbsp;측정해서&amp;nbsp;100밀리초간격으로&amp;nbsp;출력하시오!(온도값을&amp;nbsp;소수점이하&amp;nbsp;2자리만&amp;nbsp;살리고&amp;nbsp;&amp;lsquo;C단위를&amp;nbsp;붙히시오)&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;07.PNG&quot; data-origin-width=&quot;1080&quot; data-origin-height=&quot;651&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/b2d1UO/dJMcajmYh5k/FzD0sLpub0z2Ikcy8wmB4k/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/b2d1UO/dJMcajmYh5k/FzD0sLpub0z2Ikcy8wmB4k/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/b2d1UO/dJMcajmYh5k/FzD0sLpub0z2Ikcy8wmB4k/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fb2d1UO%2FdJMcajmYh5k%2FFzD0sLpub0z2Ikcy8wmB4k%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;1080&quot; height=&quot;651&quot; data-filename=&quot;07.PNG&quot; data-origin-width=&quot;1080&quot; data-origin-height=&quot;651&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;pre id=&quot;code_1761722279196&quot; class=&quot;cpp&quot; data-ke-language=&quot;cpp&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;/* USER CODE BEGIN 0 */
#define R1 10000
#define c1 1.009249522e-03
#define c2 2.378405444e-04
#define c3 2.019202697e-07
/* USER CODE END 0 */
//중략
/* USER CODE BEGIN 2 */
 HAL_ADC_Start(&amp;amp;hadc1); //딱 한번만 호출
 uint16_t adc_value0 = 0;
 char buff[50];
 float logR2, R2, T, Tc, Tf;
 /* USER CODE END 2 */
 /* Infinite loop */
 /* USER CODE BEGIN WHILE */
 while (1)
 {
	  //측정할때마다 호출
	  if(HAL_ADC_PollForConversion(&amp;amp;hadc1, 10) == HAL_OK)
	  {
		  // 값 처리
		  adc_value0 = HAL_ADC_GetValue(&amp;amp;hadc1); //0~4095
		  R2 = R1 * (4095.0 / adc_value0 - 1.0);
		  logR2 = log(R2);
		  T = (1.0 / (c1 + c2*logR2 + c3*logR2*logR2*logR2));
		  Tc = T - 273.15;
		  //온도값을 출력하는데 .2라는것은 소수점 이하 2자리만 출력하라는 것이다!
		  sprintf(buff,&quot;Voltage = %.2f'C\n&quot;,Tc);
		  HAL_UART_Transmit(&amp;amp;huart2, buff, strlen(buff), 100);
	  }
	  HAL_Delay(100);
   /* USER CODE END WHILE */
   /* USER CODE BEGIN 3 */
 }&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;br /&gt;8.PA0과&amp;nbsp;PA1에&amp;nbsp;연결된&amp;nbsp;아날로그값을&amp;nbsp;ADC1과&amp;nbsp;ADC2로&amp;nbsp;분할해서&amp;nbsp;동시에&amp;nbsp;100밀리초&amp;nbsp;간격으로&amp;nbsp;출력하시오!&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;ioc8.PNG&quot; data-origin-width=&quot;930&quot; data-origin-height=&quot;658&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/dUWrps/dJMcaa4DvHs/jEkePOC2SOPwqkK4YBOEGK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/dUWrps/dJMcaa4DvHs/jEkePOC2SOPwqkK4YBOEGK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/dUWrps/dJMcaa4DvHs/jEkePOC2SOPwqkK4YBOEGK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FdUWrps%2FdJMcaa4DvHs%2FjEkePOC2SOPwqkK4YBOEGK%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;930&quot; height=&quot;658&quot; data-filename=&quot;ioc8.PNG&quot; data-origin-width=&quot;930&quot; data-origin-height=&quot;658&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;pre id=&quot;code_1761722304576&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 */
 HAL_ADC_Start(&amp;amp;hadc1); //딱 한번만 호출
 HAL_ADC_Start(&amp;amp;hadc2); //딱 한번만 호출
 uint16_t adc_value0 = 0;
 uint16_t adc_value1 = 0;
 char buff[50];
 /* USER CODE END 2 */
 /* Infinite loop */
 /* USER CODE BEGIN WHILE */
 while (1)
 {
	  //PA0
	  if(HAL_ADC_PollForConversion(&amp;amp;hadc1, 10) == HAL_OK)
	  {
		  // 값 처리
		  adc_value0 = HAL_ADC_GetValue(&amp;amp;hadc1); //0~4095
	  }
	  //PA1
	  if(HAL_ADC_PollForConversion(&amp;amp;hadc2, 10) == HAL_OK)
	  {
		  // 값 처리
		  adc_value1 = HAL_ADC_GetValue(&amp;amp;hadc2); //0~4095
	  }
	  sprintf(buff,&quot;PA0 = %d, PA1 = %d\n&quot;,adc_value0,adc_value1);
	  HAL_UART_Transmit(&amp;amp;huart2, buff, strlen(buff), 100);
	  HAL_Delay(100);
   /* USER CODE END WHILE */
   /* USER CODE BEGIN 3 */
 }&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;br /&gt;9.PA0과&amp;nbsp;PA1에&amp;nbsp;연결된&amp;nbsp;아날로그값을&amp;nbsp;ADC1의&amp;nbsp;IN0과&amp;nbsp;IN1로&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-filename=&quot;ioc9.PNG&quot; data-origin-width=&quot;987&quot; data-origin-height=&quot;667&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bwaMGq/dJMcabP0DIW/hTIkz1zE9hGwLCGyHB2Kl1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bwaMGq/dJMcabP0DIW/hTIkz1zE9hGwLCGyHB2Kl1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bwaMGq/dJMcabP0DIW/hTIkz1zE9hGwLCGyHB2Kl1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbwaMGq%2FdJMcabP0DIW%2FhTIkz1zE9hGwLCGyHB2Kl1%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;987&quot; height=&quot;667&quot; data-filename=&quot;ioc9.PNG&quot; data-origin-width=&quot;987&quot; data-origin-height=&quot;667&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;pre id=&quot;code_1761722328853&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 */
 uint16_t adc_value0 = 0;
 uint16_t adc_value1 = 0;
 char buff[50];
 /* USER CODE END 2 */
 /* Infinite loop */
 /* USER CODE BEGIN WHILE */
 while (1)
 {
	  //PA0 ADC1 RANK1
	  HAL_ADC_Start(&amp;amp;hadc1);
	  HAL_ADC_PollForConversion(&amp;amp;hadc1, 100);
	  adc_value0 = HAL_ADC_GetValue(&amp;amp;hadc1);
	  //PA1 ADC1 RANK2
	  HAL_ADC_Start(&amp;amp;hadc1);
	  HAL_ADC_PollForConversion(&amp;amp;hadc1, 100);
	  adc_value1 = HAL_ADC_GetValue(&amp;amp;hadc1);
	  sprintf(buff,&quot;PA0 = %d, PA1 = %d\n&quot;,adc_value0,adc_value1);
	  HAL_UART_Transmit(&amp;amp;huart2, buff, strlen(buff), 100);
	  HAL_Delay(100);
   /* USER CODE END WHILE */
   /* USER CODE BEGIN 3 */
 }&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;br /&gt;10.예제9의&amp;nbsp;방법으로&amp;nbsp;PA0,&amp;nbsp;PA1,&amp;nbsp;PA4의&amp;nbsp;값을&amp;nbsp;동시에&amp;nbsp;출력하시오!(PA4는&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-filename=&quot;ioc10.PNG&quot; data-origin-width=&quot;1110&quot; data-origin-height=&quot;652&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/pmw3Y/dJMcahbCwtG/yU1NBXeIDxSfsUVj8SyCWK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/pmw3Y/dJMcahbCwtG/yU1NBXeIDxSfsUVj8SyCWK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/pmw3Y/dJMcahbCwtG/yU1NBXeIDxSfsUVj8SyCWK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fpmw3Y%2FdJMcahbCwtG%2FyU1NBXeIDxSfsUVj8SyCWK%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;1110&quot; height=&quot;652&quot; data-filename=&quot;ioc10.PNG&quot; data-origin-width=&quot;1110&quot; data-origin-height=&quot;652&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;pre id=&quot;code_1761722362281&quot; class=&quot;cpp&quot; data-ke-language=&quot;cpp&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;/* USER CODE BEGIN 0 */
#define R1 10000
#define c1 1.009249522e-03
#define c2 2.378405444e-04
#define c3 2.019202697e-07
/* USER CODE END 0 */
//중략
/* USER CODE BEGIN 2 */
 uint16_t adc_value0 = 0;
 uint16_t adc_value1 = 0;
 uint16_t adc_value2 = 0;
 char buff[50];
 float logR2, R2, T, Tc, Tf;
 /* USER CODE END 2 */
 /* Infinite loop */
 /* USER CODE BEGIN WHILE */
 while (1)
 {
	  //PA0 ADC1 RANK1
	  HAL_ADC_Start(&amp;amp;hadc1);
	  HAL_ADC_PollForConversion(&amp;amp;hadc1, 100);
	  adc_value0 = HAL_ADC_GetValue(&amp;amp;hadc1);
	  //PA1 ADC1 RANK2
	  HAL_ADC_Start(&amp;amp;hadc1);
	  HAL_ADC_PollForConversion(&amp;amp;hadc1, 100);
	  adc_value1 = HAL_ADC_GetValue(&amp;amp;hadc1);
	  //PA4 ADC1 RANK3
	  HAL_ADC_Start(&amp;amp;hadc1);
	  HAL_ADC_PollForConversion(&amp;amp;hadc1, 100);
	  adc_value2 = HAL_ADC_GetValue(&amp;amp;hadc1);
	  //온도계산
	  R2 = R1 * (4095.0 / adc_value2 - 1.0);
	  logR2 = log(R2);
	  T = (1.0 / (c1 + c2*logR2 + c3*logR2*logR2*logR2));
	  Tc = T - 273.15;
	  sprintf(buff,&quot;PA0 = %d, PA1 = %d, PA4 = %.2f'C\n&quot;,adc_value0,adc_value1,Tc);
	  HAL_UART_Transmit(&amp;amp;huart2, buff, strlen(buff), 100);
	  HAL_Delay(100);
   /* USER CODE END WHILE */
   /* USER CODE BEGIN 3 */
 }&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;br /&gt;11.예제10에서&amp;nbsp;PA0의&amp;nbsp;값이&amp;nbsp;1000을&amp;nbsp;넘으면&amp;nbsp;PB3이&amp;nbsp;켜지고&amp;nbsp;그렇지않으면&amp;nbsp;꺼진다!,&amp;nbsp;PA1의&amp;nbsp;값이&amp;nbsp;1000보다&amp;nbsp;크면&amp;nbsp;PB13의&amp;nbsp;LED가&amp;nbsp;켜지고&amp;nbsp;그렇지않으면&amp;nbsp;꺼지다!&amp;nbsp;PA4에서&amp;nbsp;측정한&amp;nbsp;온도값이&amp;nbsp;20도를&amp;nbsp;넘으면&amp;nbsp;PB5의&amp;nbsp;LED가&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-filename=&quot;11.PNG&quot; data-origin-width=&quot;1018&quot; data-origin-height=&quot;622&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/ceKs1V/dJMcaf5WEaG/kHxEvtNSvojYTLcnEVIAH0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/ceKs1V/dJMcaf5WEaG/kHxEvtNSvojYTLcnEVIAH0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/ceKs1V/dJMcaf5WEaG/kHxEvtNSvojYTLcnEVIAH0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FceKs1V%2FdJMcaf5WEaG%2FkHxEvtNSvojYTLcnEVIAH0%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;1018&quot; height=&quot;622&quot; data-filename=&quot;11.PNG&quot; data-origin-width=&quot;1018&quot; data-origin-height=&quot;622&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;pre id=&quot;code_1761722397276&quot; class=&quot;cpp&quot; data-ke-language=&quot;cpp&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;/* USER CODE BEGIN 0 */
#define R1 10000
#define c1 1.009249522e-03
#define c2 2.378405444e-04
#define c3 2.019202697e-07
/* USER CODE END 0 */
//중략
/* USER CODE BEGIN 2 */
 uint16_t adc_value0 = 0;
 uint16_t adc_value1 = 0;
 uint16_t adc_value2 = 0;
 char buff[50];
 float logR2, R2, T, Tc, Tf;
 /* USER CODE END 2 */
 /* Infinite loop */
 /* USER CODE BEGIN WHILE */
 while (1)
 {
	  //PA0 ADC1 RANK1
	  HAL_ADC_Start(&amp;amp;hadc1);
	  HAL_ADC_PollForConversion(&amp;amp;hadc1, 100);
	  adc_value0 = HAL_ADC_GetValue(&amp;amp;hadc1);
	  //PA1 ADC1 RANK2
	  HAL_ADC_Start(&amp;amp;hadc1);
	  HAL_ADC_PollForConversion(&amp;amp;hadc1, 100);
	  adc_value1 = HAL_ADC_GetValue(&amp;amp;hadc1);
	  //PA4 ADC1 RANK3
	  HAL_ADC_Start(&amp;amp;hadc1);
	  HAL_ADC_PollForConversion(&amp;amp;hadc1, 100);
	  adc_value2 = HAL_ADC_GetValue(&amp;amp;hadc1);
	  //온도계산
	  R2 = R1 * (4095.0 / adc_value2 - 1.0);
	  logR2 = log(R2);
	  T = (1.0 / (c1 + c2*logR2 + c3*logR2*logR2*logR2));
	  Tc = T - 273.15;
	  if(adc_value0 &amp;gt; 1000){
		  HAL_GPIO_WritePin(GPIOB, GPIO_PIN_3, 1);
	  }else{
		  HAL_GPIO_WritePin(GPIOB, GPIO_PIN_3, 0);
	  }
	  if(adc_value1 &amp;gt; 1000){
		  HAL_GPIO_WritePin(GPIOB, GPIO_PIN_13, 1);
	  }else{
		  HAL_GPIO_WritePin(GPIOB, GPIO_PIN_13, 0);
	  }
	  if(Tc &amp;gt; 20){
		  HAL_GPIO_WritePin(GPIOB, GPIO_PIN_5, 1);
	  }else{
		  HAL_GPIO_WritePin(GPIOB, GPIO_PIN_5, 0);
	  }
	  sprintf(buff,&quot;PA0 = %d, PA1 = %d, PA4 = %.2f'C\n&quot;,adc_value0,adc_value1,Tc);
	  HAL_UART_Transmit(&amp;amp;huart2, buff, strlen(buff), 100);
	  HAL_Delay(100);
   /* USER CODE END WHILE */
   /* USER CODE BEGIN 3 */
 }&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;/p&gt;</description>
      <category>프로그래밍/STM32</category>
      <author>덕력킹</author>
      <guid isPermaLink="true">https://bota.tistory.com/2448</guid>
      <comments>https://bota.tistory.com/2448#entry2448comment</comments>
      <pubDate>Wed, 29 Oct 2025 16:20:14 +0900</pubDate>
    </item>
    <item>
      <title>[STM32#05] 로터리엔코더(rotary encoder)를 작동시키는 방법에 대해서 알아보고 GPIO 외부인터럽트(EXTI)를 활용해보기!(녹칸다 내맘대로 STM32)</title>
      <link>https://bota.tistory.com/2447</link>
      <description>&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;stm32.png&quot; data-origin-width=&quot;1920&quot; data-origin-height=&quot;1080&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cz1ncj/dJMcag4Qr8f/iJDfbwa4hbXWvYU781Oxl1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cz1ncj/dJMcag4Qr8f/iJDfbwa4hbXWvYU781Oxl1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cz1ncj/dJMcag4Qr8f/iJDfbwa4hbXWvYU781Oxl1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fcz1ncj%2FdJMcag4Qr8f%2FiJDfbwa4hbXWvYU781Oxl1%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;1920&quot; height=&quot;1080&quot; data-filename=&quot;stm32.png&quot; data-origin-width=&quot;1920&quot; data-origin-height=&quot;1080&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/live/CZO7eE0qtEg&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://youtube.com/live/CZO7eE0qtEg&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/watch?v=CZO7eE0qtEg&quot; data-video-thumbnail=&quot;https://scrap.kakaocdn.net/dn/zOm2c/hyZMfDhQm4/EBS14KaVKeyRFNHZezDkUK/img.jpg?width=1280&amp;amp;height=720&amp;amp;face=0_0_1280_720,https://scrap.kakaocdn.net/dn/eRiyB/hyZMjTdFfD/0gAAybH2JMLfZNUUKej8dk/img.jpg?width=1280&amp;amp;height=720&amp;amp;face=0_0_1280_720&quot; data-video-width=&quot;860&quot; data-video-height=&quot;484&quot; data-video-origin-width=&quot;860&quot; data-video-origin-height=&quot;484&quot; data-ke-mobilestyle=&quot;widthContent&quot; data-video-title=&quot;[STM32#05] 로터리엔코더(rotary encoder)를 작동시키는 방법에 대해서 알아보고 GPIO 외부인터럽트(EXTI)&quot; data-original-url=&quot;&quot;&gt;&lt;iframe src=&quot;https://www.youtube.com/embed/CZO7eE0qtEg&quot; width=&quot;860&quot; height=&quot;484&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;[STM32#05]&amp;nbsp;로터리엔코더(rotary&amp;nbsp;encoder)를&amp;nbsp;작동시키는&amp;nbsp;방법에&amp;nbsp;대해서&amp;nbsp;알아보고&amp;nbsp;GPIO&amp;nbsp;외부인터럽트(EXTI)를&amp;nbsp;활용해보기!(녹칸다&amp;nbsp;내맘대로&amp;nbsp;STM32) &lt;br /&gt;&lt;br /&gt;심심한녹칸다의&amp;nbsp;내맘대로&amp;nbsp;STM32시리즈이다! &lt;br /&gt;&lt;br /&gt;STM32시리즈의&amp;nbsp;모든&amp;nbsp;자료는&amp;nbsp;구글&amp;nbsp;슬라이드에&amp;nbsp;작성하고&amp;nbsp;모두에게&amp;nbsp;공유되어있음! &lt;br /&gt;&lt;a href=&quot;https://docs.google.com/presentation/d/1myA5iYbjuKsLWLqtRLKAiRfwUwvqB1d1RGjiMIIgp3I/edit?slide=id.g39d2b1dd9a3_1_0#slide=id.g39d2b1dd9a3_1_0&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://docs.google.com/presentation/d/1myA5iYbjuKsLWLqtRLKAiRfwUwvqB1d1RGjiMIIgp3I/edit?slide=id.g39d2b1dd9a3_1_0#slide=id.g39d2b1dd9a3_1_0&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;이번편에는&amp;nbsp;녹칸다의&amp;nbsp;STM32쉴드에&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;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;(STM32쉴드회로도)&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;1.PNG&quot; data-origin-width=&quot;1122&quot; data-origin-height=&quot;452&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/62yjm/dJMcacnP5l3/8InpL20QDgKpmrCk1M0EI0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/62yjm/dJMcacnP5l3/8InpL20QDgKpmrCk1M0EI0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/62yjm/dJMcacnP5l3/8InpL20QDgKpmrCk1M0EI0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2F62yjm%2FdJMcacnP5l3%2F8InpL20QDgKpmrCk1M0EI0%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;815&quot; height=&quot;328&quot; data-filename=&quot;1.PNG&quot; data-origin-width=&quot;1122&quot; data-origin-height=&quot;452&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-filename=&quot;2.PNG&quot; data-origin-width=&quot;794&quot; data-origin-height=&quot;553&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/dO0M38/dJMcacnP5l6/BpWFGLlar2lkGAKKxctEb0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/dO0M38/dJMcacnP5l6/BpWFGLlar2lkGAKKxctEb0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/dO0M38/dJMcacnP5l6/BpWFGLlar2lkGAKKxctEb0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FdO0M38%2FdJMcacnP5l6%2FBpWFGLlar2lkGAKKxctEb0%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;504&quot; height=&quot;351&quot; data-filename=&quot;2.PNG&quot; data-origin-width=&quot;794&quot; data-origin-height=&quot;553&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;(로터리엔코더의 인식원리)&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;1.일단&amp;nbsp;기본적으로&amp;nbsp;로터리엔코더는&amp;nbsp;시계방향으로&amp;nbsp;회전하냐?&amp;nbsp;반시계방향으로&amp;nbsp;회전하냐?&amp;nbsp;를&amp;nbsp;알수있다! &lt;br /&gt;2.회전방향과&amp;nbsp;몇스탭을&amp;nbsp;이동했는지?&amp;nbsp;스탭량을&amp;nbsp;알&amp;nbsp;수&amp;nbsp;있다! &lt;br /&gt;3.시계방향으로&amp;nbsp;회전할때와&amp;nbsp;반시계방향으로&amp;nbsp;회전할때의&amp;nbsp;신호값이&amp;nbsp;다르게된다! &lt;br /&gt;4.시계방향으로&amp;nbsp;1스탭&amp;nbsp;회전을&amp;nbsp;하게되면&amp;nbsp;A핀에&amp;nbsp;상승엣지가&amp;nbsp;발생하고&amp;nbsp;그때&amp;nbsp;B의&amp;nbsp;값은&amp;nbsp;LOW가&amp;nbsp;된다! &lt;br /&gt;5.반시계방향으로&amp;nbsp;1스탭&amp;nbsp;회전을&amp;nbsp;하게되면&amp;nbsp;A핀에&amp;nbsp;상승엣지가&amp;nbsp;발생하고&amp;nbsp;그때&amp;nbsp;B의&amp;nbsp;값은&amp;nbsp;HIGH가&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;p data-ke-size=&quot;size16&quot;&gt;(예제목차)&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;1.PB1에&amp;nbsp;상승엣지와&amp;nbsp;하강엣지를&amp;nbsp;이용해서&amp;nbsp;버튼이&amp;nbsp;눌려졌는지를&amp;nbsp;검출해서&amp;nbsp;시리얼출력하시오!&lt;/p&gt;
&lt;pre id=&quot;code_1761574588384&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 */
 //버튼을 안누르고 있을때가 기본상태이고 안누르고 있으면 HIGH신호가 나온다
 uint8_t old = 1;
 char * msg1 = &quot;PB1 PRESSED!!\n&quot;;
 char * msg2 = &quot;PB1 RELEASED!!\n&quot;;
 /* USER CODE END 2 */
 /* Infinite loop */
 /* USER CODE BEGIN WHILE */
 while (1)
 {
	  //PB1의 하강엣지 검출(버튼 눌러짐)
	  //PB1의 현재 값을 측정한다!
	  uint8_t now = HAL_GPIO_ReadPin(GPIOB,GPIO_PIN_1);
	  //now와 old가 공존하는 상태가 된다!
	  if(old == 1 &amp;amp;&amp;amp; now == 0){
		  //이전값은 HIGH인데, 현재값은 LOW인 상황!(하강엣지)
		  HAL_UART_Transmit(&amp;amp;huart2, msg1, strlen(msg1), 100);
	  }else if(old == 0 &amp;amp;&amp;amp; now == 1){
		  //이전값은 LOW이고, 현재값은 HIGH이다!(상승엣지)
		  HAL_UART_Transmit(&amp;amp;huart2, msg2, strlen(msg2), 100);
	  }
	  old = now;
   /* USER CODE END WHILE */
   /* USER CODE BEGIN 3 */
 }&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;br /&gt;2.인터럽트를&amp;nbsp;위해서&amp;nbsp;함수에&amp;nbsp;대해서&amp;nbsp;기본적으로&amp;nbsp;예제로&amp;nbsp;표현해보시오!&lt;/p&gt;
&lt;pre id=&quot;code_1761574618736&quot; class=&quot;cpp&quot; data-ke-language=&quot;cpp&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;/* USER CODE BEGIN 0 */
char *msg1 = &quot;NOCKANDA\n&quot;;
char buff[100];
//입력도 없고 출력도 없는 함수
void function1(){
	//이함수가 호출되면 usart2로 &quot;NOCKANDA\n&quot;를 출력한다!
	HAL_UART_Transmit(&amp;amp;huart2, msg1, strlen(msg1), 100);
}
//입력이 있고 출력은 없는 함수
void function2(int num){
	//숫자를 1개 입력받아서 그 값을 출력하는 함수!
	//함수의 입력으로 들어온 값은 지역변수처럼 쓸수있다!
	sprintf(buff,&quot;NUMBER=%d\n&quot;,num);
	HAL_UART_Transmit(&amp;amp;huart2, buff, strlen(buff), 100);
}
//입력이 없고 출력이 있는 함수
int function3(){
	//호출하면 5678이라는 값을 반환(return)하는 함수!
	return 5678;
}
//입력과 출력이 둘다 있는 함수
int function4(int num1, int num2){
	//num1과 num2를 더해서 반환하는 함수
	int output = num1+num2;
	return output;
}
/* USER CODE END 0 */

//중략

while (1)
 {
	  function1(); //함수를 호출한다(=콜한다)
	  function2(1234);
	  int test_num = function3();
	  sprintf(buff,&quot;function3=%d\n&quot;,test_num);
	  HAL_UART_Transmit(&amp;amp;huart2, buff, strlen(buff), 100);
	  int test_num2 = function4(111,222);
	  sprintf(buff,&quot;function4=%d\n&quot;,test_num2);
	  HAL_UART_Transmit(&amp;amp;huart2, buff, strlen(buff), 100);
	  HAL_Delay(2000);
   /* USER CODE END WHILE */
   /* USER CODE BEGIN 3 */
 }&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;br /&gt;3.PB1을&amp;nbsp;IOC에서&amp;nbsp;외부인터럽트로&amp;nbsp;등록해서&amp;nbsp;버튼을&amp;nbsp;눌렀을때&amp;nbsp;눌려졌다는&amp;nbsp;문구를&amp;nbsp;시리얼출력하시오!(EXTI1)&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;3.PNG&quot; data-origin-width=&quot;888&quot; data-origin-height=&quot;519&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/n63Bh/dJMcagw0uAx/3lAOOktAywMU9HAjE6wAuk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/n63Bh/dJMcagw0uAx/3lAOOktAywMU9HAjE6wAuk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/n63Bh/dJMcagw0uAx/3lAOOktAywMU9HAjE6wAuk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fn63Bh%2FdJMcagw0uAx%2F3lAOOktAywMU9HAjE6wAuk%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;888&quot; height=&quot;519&quot; data-filename=&quot;3.PNG&quot; data-origin-width=&quot;888&quot; data-origin-height=&quot;519&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;pre id=&quot;code_1761574632709&quot; class=&quot;cpp&quot; data-ke-language=&quot;cpp&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;/* USER CODE BEGIN 0 */
void HAL_GPIO_EXTI_Callback(uint16_t GPIO_Pin)
{
	//EXTI1
  if(GPIO_Pin == GPIO_PIN_1)
  {
	   HAL_UART_Transmit(&amp;amp;huart2, &quot;PB1 INTERRUPTS!\n&quot;, 16, 100);
  }
}
/* USER CODE END 0 */

////중략

while (1)
 {
   /* USER CODE END WHILE */
   /* USER CODE BEGIN 3 */
 }&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;br /&gt;4.로터리엔코더를&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-filename=&quot;4.PNG&quot; data-origin-width=&quot;859&quot; data-origin-height=&quot;523&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bhoUwc/dJMcaawM3Yu/mfQJr4vDXrW3lSh4Fgre3k/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bhoUwc/dJMcaawM3Yu/mfQJr4vDXrW3lSh4Fgre3k/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bhoUwc/dJMcaawM3Yu/mfQJr4vDXrW3lSh4Fgre3k/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbhoUwc%2FdJMcaawM3Yu%2FmfQJr4vDXrW3lSh4Fgre3k%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;859&quot; height=&quot;523&quot; data-filename=&quot;4.PNG&quot; data-origin-width=&quot;859&quot; data-origin-height=&quot;523&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;pre id=&quot;code_1761574643869&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 */
 uint8_t old_A = 0;
 /* USER CODE END 2 */
 /* Infinite loop */
 /* USER CODE BEGIN WHILE */
 while (1)
 {
	  //녹칸다가 풀업방식으로 연결해놓음
	  uint8_t sw = HAL_GPIO_ReadPin(GPIOC,GPIO_PIN_7);
	  if(sw == 0){
		  HAL_UART_Transmit(&amp;amp;huart2, &quot;SW\n&quot;, 3, 100);
		  HAL_Delay(200);
	  }
	  //PA11의 상승엣지가 발생했을때
	  uint8_t now_A = HAL_GPIO_ReadPin(GPIOA,GPIO_PIN_11);
	  if(old_A == 0 &amp;amp;&amp;amp; now_A == 1){
		  //PA12의 값을 측정해서 LOW면 시계, HIGH면 반시계
		  uint8_t now_B = HAL_GPIO_ReadPin(GPIOA,GPIO_PIN_12);
		  if(now_B){
			 //반시계
			  HAL_UART_Transmit(&amp;amp;huart2, &quot;CCW\n&quot;, 4, 100);
		  }else{
			 //시계
			  HAL_UART_Transmit(&amp;amp;huart2, &quot;CW\n&quot;, 3, 100);
		  }
	  }
	  old_A = now_A;
   /* USER CODE END WHILE */
   /* USER CODE BEGIN 3 */
 }&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;br /&gt;5.녹칸다가&amp;nbsp;로터리엔코더를&amp;nbsp;돌렸을때&amp;nbsp;시계방향으로&amp;nbsp;회전시키면&amp;nbsp;값을&amp;nbsp;0에서&amp;nbsp;7까지&amp;nbsp;증가시키는데&amp;nbsp;7에서&amp;nbsp;8이&amp;nbsp;되는게&amp;nbsp;아니라&amp;nbsp;0이&amp;nbsp;된다!,&amp;nbsp;반시계방향으로&amp;nbsp;회전하면&amp;nbsp;7에서&amp;nbsp;0방향으로&amp;nbsp;감소시키는데&amp;nbsp;0에서&amp;nbsp;1감소되면&amp;nbsp;-1이&amp;nbsp;되는게&amp;nbsp;아니라&amp;nbsp;7이된다!&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;5.PNG&quot; data-origin-width=&quot;948&quot; data-origin-height=&quot;493&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/oq3Lj/dJMcaawM3Yy/KjfxbEZK4mg2WdHyPtN1JK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/oq3Lj/dJMcaawM3Yy/KjfxbEZK4mg2WdHyPtN1JK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/oq3Lj/dJMcaawM3Yy/KjfxbEZK4mg2WdHyPtN1JK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Foq3Lj%2FdJMcaawM3Yy%2FKjfxbEZK4mg2WdHyPtN1JK%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;948&quot; height=&quot;493&quot; data-filename=&quot;5.PNG&quot; data-origin-width=&quot;948&quot; data-origin-height=&quot;493&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;pre id=&quot;code_1761574653566&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 */
 uint8_t old_A = 0;
 int cnt = 0;
 char buff[50];
 /* USER CODE END 2 */
 /* Infinite loop */
 /* USER CODE BEGIN WHILE */
 while (1)
 {
	  //녹칸다가 풀업방식으로 연결해놓음
	  uint8_t sw = HAL_GPIO_ReadPin(GPIOC,GPIO_PIN_7);
	  if(sw == 0){
		  HAL_UART_Transmit(&amp;amp;huart2, &quot;SW\n&quot;, 3, 100);
		  HAL_Delay(200);
	  }
	  //PA11의 상승엣지가 발생했을때
	  uint8_t now_A = HAL_GPIO_ReadPin(GPIOA,GPIO_PIN_11);
	  if(old_A == 0 &amp;amp;&amp;amp; now_A == 1){
		  //PA12의 값을 측정해서 LOW면 시계, HIGH면 반시계
		  uint8_t now_B = HAL_GPIO_ReadPin(GPIOA,GPIO_PIN_12);
		  if(now_B){
			 //반시계
			  cnt--;
			  if(cnt &amp;lt; 0) cnt = 7;
			  sprintf(buff,&quot;CNT = %d\n&quot;,cnt);
			  HAL_UART_Transmit(&amp;amp;huart2, buff, strlen(buff), 100);
		  }else{
			 //시계
			  cnt++;
			  if(cnt &amp;gt; 7) cnt = 0;
			  sprintf(buff,&quot;CNT = %d\n&quot;,cnt);
			  HAL_UART_Transmit(&amp;amp;huart2, buff, strlen(buff), 100);
		  }
	  }
	  old_A = now_A;
   /* USER CODE END WHILE */
   /* USER CODE BEGIN 3 */
 }&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;br /&gt;6.로터리&amp;nbsp;엔코더를&amp;nbsp;회전시킬때,&amp;nbsp;LED가&amp;nbsp;12시방향에서&amp;nbsp;출발해서&amp;nbsp;시계방향으로&amp;nbsp;로터리엔코더를&amp;nbsp;돌리면&amp;nbsp;함께&amp;nbsp;회전하고,&amp;nbsp;반시계방향으로&amp;nbsp;회전시키면&amp;nbsp;반시계방향으로&amp;nbsp;1칸씩&amp;nbsp;이동하시오!&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;6.PNG&quot; data-origin-width=&quot;928&quot; data-origin-height=&quot;523&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/dfDAVd/dJMcaawM3YA/TqO2QPbZKUmQIO3wXIfsU0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/dfDAVd/dJMcaawM3YA/TqO2QPbZKUmQIO3wXIfsU0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/dfDAVd/dJMcaawM3YA/TqO2QPbZKUmQIO3wXIfsU0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FdfDAVd%2FdJMcaawM3YA%2FTqO2QPbZKUmQIO3wXIfsU0%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;928&quot; height=&quot;523&quot; data-filename=&quot;6.PNG&quot; data-origin-width=&quot;928&quot; data-origin-height=&quot;523&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;pre id=&quot;code_1761574673195&quot; class=&quot;cpp&quot; data-ke-language=&quot;cpp&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;/* USER CODE BEGIN 0 */
GPIO_TypeDef *mygroup[] = {GPIOB,GPIOB,GPIOB,GPIOB,GPIOB,GPIOB,GPIOC,GPIOB};
uint16_t mypin[] = {GPIO_PIN_3,GPIO_PIN_13,GPIO_PIN_5,GPIO_PIN_14,GPIO_PIN_4,GPIO_PIN_15,GPIO_PIN_4,GPIO_PIN_7};
void set_led(int num){
	//LED의 상태 업데이트 현재 켜져야하는 LED는 CNT번째꺼
	  for(int i = 0;i&amp;lt;8;i++){
		  if(i == num){
			  HAL_GPIO_WritePin(mygroup[i],mypin[i],GPIO_PIN_SET);
		  }else{
			  HAL_GPIO_WritePin(mygroup[i],mypin[i],GPIO_PIN_RESET);
		  }
	  }
}
/* USER CODE END 0 */

//중략

/* USER CODE BEGIN 2 */
 uint8_t old_A = 0;
 int cnt = 0;
  //시작하자마자 일단 12시방향의 LED는 1개 켜고 출발한다!
  HAL_GPIO_WritePin(mygroup[0],mypin[0],GPIO_PIN_SET);
 /* USER CODE END 2 */
 /* Infinite loop */
 /* USER CODE BEGIN WHILE */
 while (1)
 {
	  //녹칸다가 풀업방식으로 연결해놓음
	  uint8_t sw = HAL_GPIO_ReadPin(GPIOC,GPIO_PIN_7);
	  if(sw == 0){
		  HAL_UART_Transmit(&amp;amp;huart2, &quot;SW\n&quot;, 3, 100);
		  HAL_Delay(200);
	  }
	  //PA11의 상승엣지가 발생했을때
	  uint8_t now_A = HAL_GPIO_ReadPin(GPIOA,GPIO_PIN_11);
	  if(old_A == 0 &amp;amp;&amp;amp; now_A == 1){
		  //PA12의 값을 측정해서 LOW면 시계, HIGH면 반시계
		  uint8_t now_B = HAL_GPIO_ReadPin(GPIOA,GPIO_PIN_12);
		  if(now_B){
			 //반시계
			  cnt--;
			  if(cnt &amp;lt; 0) cnt = 7;
			  set_led(cnt);
		  }else{
			 //시계
			  cnt++;
			  if(cnt &amp;gt; 7) cnt = 0;
			  set_led(cnt);
		  }
	  }
	  old_A = now_A;
   /* USER CODE END WHILE */
   /* USER CODE BEGIN 3 */
 }&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;br /&gt;7.이번에는&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-filename=&quot;7.PNG&quot; data-origin-width=&quot;901&quot; data-origin-height=&quot;538&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/b0vEKP/dJMb99SbvYf/wjUiKZkqIMQVAdKj91nPr1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/b0vEKP/dJMb99SbvYf/wjUiKZkqIMQVAdKj91nPr1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/b0vEKP/dJMb99SbvYf/wjUiKZkqIMQVAdKj91nPr1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fb0vEKP%2FdJMb99SbvYf%2FwjUiKZkqIMQVAdKj91nPr1%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;901&quot; height=&quot;538&quot; data-filename=&quot;7.PNG&quot; data-origin-width=&quot;901&quot; data-origin-height=&quot;538&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;pre id=&quot;code_1761574704179&quot; class=&quot;cpp&quot; data-ke-language=&quot;cpp&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;/* USER CODE BEGIN 0 */
volatile int direct = 0; //0이면 멈춤, 1이면 시계, -1이면 반시계
void HAL_GPIO_EXTI_Callback(uint16_t GPIO_Pin)
{
  if(GPIO_Pin == GPIO_PIN_11)
  {
      //로터리엔코드의 A핀에 상승엣지가 검출됨!
	   //B핀의 상태만 확인하면됨!
	   uint8_t now_B = HAL_GPIO_ReadPin(GPIOA,GPIO_PIN_12);
	   if(now_B){
		   //반시계
		   direct = -1;
	   }else{
		   //시계
		   direct = 1;
	   }
  }
}
/* USER CODE END 0 */
/* USER CODE BEGIN 2 */
 /* USER CODE END 2 */
 /* Infinite loop */
 /* USER CODE BEGIN WHILE */
 while (1)
 {
	  //어라? 로터리엔코더가 시계방향으로 돌아갔네?
	  if(direct == 1){
		  HAL_UART_Transmit(&amp;amp;huart2, &quot;CW\n&quot;, 3, 100);
		  direct = 0;
	  }else if(direct == -1){
		  HAL_UART_Transmit(&amp;amp;huart2, &quot;CCW\n&quot;, 4, 100);
		  direct = 0;
	  }
   /* USER CODE END WHILE */
   /* USER CODE BEGIN 3 */
 }&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;br /&gt;8.인터럽트&amp;nbsp;방식으로&amp;nbsp;예제&amp;nbsp;6번에서&amp;nbsp;했던&amp;nbsp;LED&amp;nbsp;빙글빙글&amp;nbsp;회전시키는&amp;nbsp;예제를&amp;nbsp;구현하시오!&lt;/p&gt;
&lt;pre id=&quot;code_1761574735054&quot; class=&quot;cpp&quot; data-ke-language=&quot;cpp&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;/* USER CODE BEGIN 0 */
volatile int direct = 0; //0이면 멈춤, 1이면 시계, -1이면 반시계
uint32_t nockanda_timer = 0;
//HAL_GetTick
void HAL_GPIO_EXTI_Callback(uint16_t GPIO_Pin)
{
  if(GPIO_Pin == GPIO_PIN_11)
  {
	   //로터리엔코더 인식부분을 1밀리초 간격으로 실행되도록 하겠다!
	   if(HAL_GetTick() - nockanda_timer &amp;gt; 1){
		   nockanda_timer = HAL_GetTick();
		   //로터리엔코드의 A핀에 상승엣지가 검출됨!
		   //B핀의 상태만 확인하면됨!
		   uint8_t now_B = HAL_GPIO_ReadPin(GPIOA,GPIO_PIN_12);
		   if(now_B){
			   //반시계
			   direct = -1;
		   }else{
			   //시계
			   direct = 1;
		   }
	   }
  }
}
GPIO_TypeDef *mygroup[] = {GPIOB,GPIOB,GPIOB,GPIOB,GPIOB,GPIOB,GPIOC,GPIOB};
uint16_t mypin[] = {GPIO_PIN_3,GPIO_PIN_13,GPIO_PIN_5,GPIO_PIN_14,GPIO_PIN_4,GPIO_PIN_15,GPIO_PIN_4,GPIO_PIN_7};
void set_led(int num){
	//LED의 상태 업데이트 현재 켜져야하는 LED는 CNT번째꺼
	  for(int i = 0;i&amp;lt;8;i++){
		  if(i == num){
			  HAL_GPIO_WritePin(mygroup[i],mypin[i],GPIO_PIN_SET);
		  }else{
			  HAL_GPIO_WritePin(mygroup[i],mypin[i],GPIO_PIN_RESET);
		  }
	  }
}
/* USER CODE END 0 */
/* USER CODE BEGIN 2 */
 int cnt = 0;
 HAL_GPIO_WritePin(mygroup[0],mypin[0],GPIO_PIN_SET);
 /* USER CODE END 2 */
 /* Infinite loop */
 /* USER CODE BEGIN WHILE */
 while (1)
 {
	  //어라? 로터리엔코더가 시계방향으로 돌아갔네?
	  if(direct == 1){
		  cnt++;
		  if(cnt &amp;gt; 7) cnt = 0;
		  set_led(cnt);
		  direct = 0;
	  }else if(direct == -1){
		  cnt--;
		  if(cnt &amp;lt; 0) cnt = 7;
		  set_led(cnt);
		  direct = 0;
	  }
   /* USER CODE END WHILE */
   /* USER CODE BEGIN 3 */
 }&lt;/code&gt;&lt;/pre&gt;</description>
      <category>프로그래밍/STM32</category>
      <author>덕력킹</author>
      <guid isPermaLink="true">https://bota.tistory.com/2447</guid>
      <comments>https://bota.tistory.com/2447#entry2447comment</comments>
      <pubDate>Mon, 27 Oct 2025 23:21:25 +0900</pubDate>
    </item>
    <item>
      <title>[STM32#04] HAL_UART_Transmit(), HAL_UART_Receive() 함수를 이용해서 USART2 시리얼통신 계속 해보기!(녹칸다 내맘대로 STM32)</title>
      <link>https://bota.tistory.com/2446</link>
      <description>&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;stm32.png&quot; data-origin-width=&quot;1920&quot; data-origin-height=&quot;1080&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/zSirH/dJMb9Nhvlhl/XDWi4rttRL5x7Eiyjqd4L0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/zSirH/dJMb9Nhvlhl/XDWi4rttRL5x7Eiyjqd4L0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/zSirH/dJMb9Nhvlhl/XDWi4rttRL5x7Eiyjqd4L0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FzSirH%2FdJMb9Nhvlhl%2FXDWi4rttRL5x7Eiyjqd4L0%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;1920&quot; height=&quot;1080&quot; data-filename=&quot;stm32.png&quot; data-origin-width=&quot;1920&quot; data-origin-height=&quot;1080&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/live/2mMDL1DBVEM&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://youtube.com/live/2mMDL1DBVEM&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/watch?v=2mMDL1DBVEM&quot; data-video-thumbnail=&quot;https://scrap.kakaocdn.net/dn/DQZMr/hyZMcfiHzY/B4GFcZep79vbNV3IrgG9pK/img.jpg?width=1280&amp;amp;height=720&amp;amp;face=0_0_1280_720,https://scrap.kakaocdn.net/dn/bCUZFd/hyZMahpGUs/2FTRnin7Elxvlv7rAlCQY1/img.jpg?width=1280&amp;amp;height=720&amp;amp;face=0_0_1280_720&quot; data-video-width=&quot;860&quot; data-video-height=&quot;484&quot; data-video-origin-width=&quot;860&quot; data-video-origin-height=&quot;484&quot; data-ke-mobilestyle=&quot;widthContent&quot; data-video-title=&quot;[STM32#04] HAL_UART_Transmit(), HAL_UART_Receive() 함수를 이용해서 USART2 시리얼통신 계속 해보기!(녹칸다 내&quot; data-original-url=&quot;&quot;&gt;&lt;iframe src=&quot;https://www.youtube.com/embed/2mMDL1DBVEM&quot; width=&quot;860&quot; height=&quot;484&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;[STM32#04]&amp;nbsp;HAL_UART_Transmit(),&amp;nbsp;HAL_UART_Receive()&amp;nbsp;함수를&amp;nbsp;이용해서&amp;nbsp;USART2&amp;nbsp;시리얼통신&amp;nbsp;계속&amp;nbsp;해보기!(녹칸다&amp;nbsp;내맘대로&amp;nbsp;STM32) &lt;br /&gt;&lt;br /&gt;심심한녹칸다의&amp;nbsp;내맘대로&amp;nbsp;STM32시리즈이다! &lt;br /&gt;&lt;br /&gt;STM32시리즈의&amp;nbsp;모든&amp;nbsp;자료는&amp;nbsp;구글&amp;nbsp;슬라이드에&amp;nbsp;작성하고&amp;nbsp;모두에게&amp;nbsp;공유되어있음! &lt;br /&gt;&lt;a href=&quot;https://docs.google.com/presentation/d/1myA5iYbjuKsLWLqtRLKAiRfwUwvqB1d1RGjiMIIgp3I/edit?slide=id.g39b3b733ade_1_225#slide=id.g39b3b733ade_1_225&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://docs.google.com/presentation/d/1myA5iYbjuKsLWLqtRLKAiRfwUwvqB1d1RGjiMIIgp3I/edit?slide=id.g39b3b733ade_1_225#slide=id.g39b3b733ade_1_225&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;기본&amp;nbsp;송수신은&amp;nbsp;되었고,&amp;nbsp;가변길이에&amp;nbsp;대한&amp;nbsp;송수신과&amp;nbsp;LED와&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;1.STM32의 PB1에 연결된 버튼을 누르면 usart2통신으로 PC에게 &amp;ldquo;PB1 PRESSED!!&amp;rdquo;라는 문자열이 버튼 누를때마다 전송되도록 하시오!&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/vwm2G/dJMb9YiWO9U/1Q4wgPgtT6wOVeI22xtqk1/ex1.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;ex1.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;
&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-filename=&quot;01.PNG&quot; data-origin-width=&quot;1051&quot; data-origin-height=&quot;530&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bx4VwM/dJMb9YpIq1y/Tr5KpujNzTvn3Y5EKpHmK0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bx4VwM/dJMb9YpIq1y/Tr5KpujNzTvn3Y5EKpHmK0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bx4VwM/dJMb9YpIq1y/Tr5KpujNzTvn3Y5EKpHmK0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fbx4VwM%2FdJMb9YpIq1y%2FTr5KpujNzTvn3Y5EKpHmK0%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;1051&quot; height=&quot;530&quot; data-filename=&quot;01.PNG&quot; data-origin-width=&quot;1051&quot; data-origin-height=&quot;530&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;pre id=&quot;code_1761061539660&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 */
 char *msg = &quot;PB1 PRESSED!!\n&quot;;
 /* USER CODE END 2 */
 /* Infinite loop */
 /* USER CODE BEGIN WHILE */
 while (1)
 {
	  //PB1을 눌렀다!
	  if(HAL_GPIO_ReadPin(GPIOB,GPIO_PIN_1) == GPIO_PIN_RESET){
	  	  //usart2로 메시지를 전송한다!
		  HAL_UART_Transmit(&amp;amp;huart2, msg, strlen(msg), 100);
		  HAL_Delay(200); //채터링 방지를 위한 소량의 딜레이
	  }
   /* USER CODE END WHILE */
   /* USER CODE BEGIN 3 */
 }&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;2.10초간격으로 STM32가 PC쪽으로 &amp;ldquo;NOCKANDA!!&amp;rdquo;라는 문자열을 전송한다! 그리고 이때 PB1버튼을 누르면 &amp;ldquo;PB1 PRESSED!!&amp;rdquo;라는 문자열이 이전 조건과는 별개로 전송된다!(HAL_Delay를 사용하지 마십시요!)&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/y4ezT/dJMb9hW8aVR/OQnk0xCj7yO4UYqDoZ7KK1/ex2.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;ex2.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;
&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-filename=&quot;02.PNG&quot; data-origin-width=&quot;1119&quot; data-origin-height=&quot;626&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/qw663/dJMb9YiWPat/6YXF6HYT3YkFzne86b1Pn0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/qw663/dJMb9YiWPat/6YXF6HYT3YkFzne86b1Pn0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/qw663/dJMb9YiWPat/6YXF6HYT3YkFzne86b1Pn0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fqw663%2FdJMb9YiWPat%2F6YXF6HYT3YkFzne86b1Pn0%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;1119&quot; height=&quot;626&quot; data-filename=&quot;02.PNG&quot; data-origin-width=&quot;1119&quot; data-origin-height=&quot;626&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;pre id=&quot;code_1761061560023&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 */
 char *msg1 = &quot;PB1 PRESSED!!\n&quot;;
 char *msg2 = &quot;NOCKANDA\n&quot;;
 uint32_t t = 0;
 /* USER CODE END 2 */
 /* Infinite loop */
 /* USER CODE BEGIN WHILE */
 while (1)
 {
	  //PB1을 눌렀다!
	  if(HAL_GPIO_ReadPin(GPIOB,GPIO_PIN_1) == GPIO_PIN_RESET){
	  	  //usart2로 메시지를 전송한다!
		  HAL_UART_Transmit(&amp;amp;huart2, msg1, strlen(msg1), 100);
		  HAL_Delay(200); //채터링 방지를 위한 소량의 딜레이
	  }
	  //10000이라는 값을 인터벌로해서 인터벌마다 한번씩 걸리는 조건문!
	  if(HAL_GetTick() - t &amp;gt;= 10000){
		  t = HAL_GetTick();
		  //지정된 메시지를 10초간격으로 전송한다!
		  HAL_UART_Transmit(&amp;amp;huart2, msg2, strlen(msg2), 100);
	  }
   /* USER CODE END WHILE */
   /* USER CODE BEGIN 3 */
 }&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;3.조건문의 재미난 특성에 대해서 간략한 예시를 구현하시오!(깨알지식)&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/WFWlX/dJMb9X5pDfP/E7b8XLKaUHNYP9XSScZR8K/ex3.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;ex3.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;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;pre id=&quot;code_1761061570883&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 */
 char *msg1 = &quot;condition1 print!!\n&quot;;
 char *msg2 = &quot;condition2 print!!\n&quot;;
 char *msg3 = &quot;condition3 print!!\n&quot;;
 /* USER CODE END 2 */
 /* Infinite loop */
 /* USER CODE BEGIN WHILE */
 while (1)
 {
	  //if는 괄호안에 들어가는 조건식이 참이면 중괄호 부분을 실행한다!
	  //조건식은 흔히 yes와 no같은 맞다 아니다로 해석하는데, 내부적으로는 참이 1이고 거짓이 0이다!
	  //참은 0이 아닌 숫자는 참으로 처리한다!
	  if(0){
		  HAL_UART_Transmit(&amp;amp;huart2, msg1, strlen(msg1), 100);
	  }
	  if(1){
		  HAL_UART_Transmit(&amp;amp;huart2, msg2, strlen(msg2), 100);
	  }
	  if(2){
		  HAL_UART_Transmit(&amp;amp;huart2, msg3, strlen(msg3), 100);
	  }
	  HAL_Delay(1000);
   /* USER CODE END WHILE */
   /* USER CODE BEGIN 3 */
 }&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;4.가변길이를 가지는 문자열 데이터를 PC에서 STM32로 전송했을때 수신을 하는 예시를 보이시오!(타임아웃을 기반으로 처리하기 버전1)&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/cartGZ/dJMb9bWUIz3/C9FcrDdcHEUVW3id4qlCW0/ex4.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;ex4.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;
&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-filename=&quot;04.PNG&quot; data-origin-width=&quot;1004&quot; data-origin-height=&quot;624&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bM2Rjh/dJMb9i2N3qS/nuaGjgAZk5ClX49xCnUHBK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bM2Rjh/dJMb9i2N3qS/nuaGjgAZk5ClX49xCnUHBK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bM2Rjh/dJMb9i2N3qS/nuaGjgAZk5ClX49xCnUHBK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbM2Rjh%2FdJMb9i2N3qS%2FnuaGjgAZk5ClX49xCnUHBK%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;1004&quot; height=&quot;624&quot; data-filename=&quot;04.PNG&quot; data-origin-width=&quot;1004&quot; data-origin-height=&quot;624&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;pre id=&quot;code_1761061587623&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 */
 char recv;
 char buff[100]; //수신메모리
 int pos = 0;
 /* USER CODE END 2 */
 /* Infinite loop */
 /* USER CODE BEGIN WHILE */
 while (1)
 {
	  //PC에서 보낸 데이터가 있는가? 있다면 읽기 시작한다!
	  if(HAL_UART_Receive(&amp;amp;huart2, &amp;amp;recv, 1, 500) == HAL_OK){
		  //보낸 데이터가 있다면 1바이트씩 읽는다!
		  buff[0] = recv;
		  pos = 1;
		  while(1){
			  //만약 PC에서 데이터를 연속으로 보내다가 흐름이 0.5초정도 끊어지면 읽기를 종료한다!
			  if(HAL_UART_Receive(&amp;amp;huart2, &amp;amp;recv, 1, 500) == HAL_OK){
				  //계속 데이터가 우체통에 있고~
				  buff[pos] = recv;
				  pos++;
			  }else{
				  //0.5초 기다려도 없네? 타임아웃이네?
				  //이 지점이 문자열의 끝지점인것을 의미한다!
				  buff[pos] = '\0';
				  //ECHO
				  HAL_UART_Transmit(&amp;amp;huart2, buff, pos, 100);
				  break;
			  }
		  }
	  }
   /* USER CODE END WHILE */
   /* USER CODE BEGIN 3 */
 }&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;5.가변길이를 가지는 문자열 데이터를 PC에서 STM32로 전송했을때 수신을 하는 예시를 보이시오!(타임아웃을 기반으로 처리하기 버전2)&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/mwiC6/dJMb9YpIq1a/fTd0U7PCMEV9QulBJmVWSk/ex5.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;ex5.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;
&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-filename=&quot;05.PNG&quot; data-origin-width=&quot;1158&quot; data-origin-height=&quot;660&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/XhyVI/dJMb9i2N3rI/zdvTjqMgocyfe3opVgi0p0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/XhyVI/dJMb9i2N3rI/zdvTjqMgocyfe3opVgi0p0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/XhyVI/dJMb9i2N3rI/zdvTjqMgocyfe3opVgi0p0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FXhyVI%2FdJMb9i2N3rI%2FzdvTjqMgocyfe3opVgi0p0%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;1158&quot; height=&quot;660&quot; data-filename=&quot;05.PNG&quot; data-origin-width=&quot;1158&quot; data-origin-height=&quot;660&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;pre id=&quot;code_1761061598498&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 */
 char recv;
 char buff[100]; //수신메모리
 int pos = 0;
 /* USER CODE END 2 */
 /* Infinite loop */
 /* USER CODE BEGIN WHILE */
 while (1)
 {
	  //PC에서 뭔가 데이터를 보내면 while루프는 동작한다!
	  pos = 0;
	  while(HAL_UART_Receive(&amp;amp;huart2, &amp;amp;recv, 1, 500) == HAL_OK){
		  buff[pos] = recv;
		  pos++;
	  }
	  buff[pos] = '\0';
	  //pos가 0이면 PC에서 온 데이터가 없고 0보다 크다면 있는것이다!
	  if(pos &amp;gt; 0){
		  //받은 데이터를 ECHO한다!
		  HAL_UART_Transmit(&amp;amp;huart2, buff, pos, 100);
	  }
   /* USER CODE END WHILE */
   /* USER CODE BEGIN 3 */
 }&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;6.이번에는&amp;nbsp;PC하고&amp;nbsp;STM32하고&amp;nbsp;종료문자를&amp;nbsp;라인피더(&amp;lsquo;\n&amp;rsquo;)로&amp;nbsp;설정했을때&amp;nbsp;STM32에서&amp;nbsp;1개씩&amp;nbsp;데이터를&amp;nbsp;빼오다가&amp;nbsp;라인피더가&amp;nbsp;확인되면&amp;nbsp;거기까지를&amp;nbsp;한덩어리로&amp;nbsp;해서&amp;nbsp;PC쪽으로&amp;nbsp;반환하시오!(보내는&amp;nbsp;쪽에서&amp;nbsp;무조건&amp;nbsp;종료문자를&amp;nbsp;붙힌다)&amp;nbsp;putty의&amp;nbsp;설정이&amp;nbsp;\n이&amp;nbsp;아니라&amp;nbsp;캐리지리턴인&amp;nbsp;\r로&amp;nbsp;되어있어서&amp;nbsp;수정함!&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;06.PNG&quot; data-origin-width=&quot;1045&quot; data-origin-height=&quot;651&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/ck791L/dJMb9MCTxEt/taWJjkxkAKIUv4Fa3hxc40/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/ck791L/dJMb9MCTxEt/taWJjkxkAKIUv4Fa3hxc40/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/ck791L/dJMb9MCTxEt/taWJjkxkAKIUv4Fa3hxc40/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fck791L%2FdJMb9MCTxEt%2FtaWJjkxkAKIUv4Fa3hxc40%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;1045&quot; height=&quot;651&quot; data-filename=&quot;06.PNG&quot; data-origin-width=&quot;1045&quot; data-origin-height=&quot;651&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;pre id=&quot;code_1761061608091&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 */
  char recv;
  char buff[100]; //수신메모리
  int pos = 0;
  /* USER CODE END 2 */
  /* Infinite loop */
  /* USER CODE BEGIN WHILE */
  while (1)
  {
 	  //PC에서 보낸 데이터가 있는가? 있다면 읽기 시작한다!
 	  if(HAL_UART_Receive(&amp;amp;huart2, &amp;amp;recv, 1, 500) == HAL_OK){
 		  //보낸 데이터가 있다면 1바이트씩 읽는다!
 		  buff[0] = recv;
 		  pos = 1;
 		  while(1){
 			  //만약 PC에서 데이터를 연속으로 보내다가 흐름이 0.5초정도 끊어지면 읽기를 종료한다!
 			  if(HAL_UART_Receive(&amp;amp;huart2, &amp;amp;recv, 1, 500) == HAL_OK){
 				  //지금 읽은 데이터가 종료문자이냐? 이면 끝이고 아니면 계속 읽는다!
 				  if(recv == '\r'){
 					buff[pos] = '\0';
 					HAL_UART_Transmit(&amp;amp;huart2, buff, pos, 100);
 					break;
 				  }else{
 					buff[pos] = recv;
 					pos++;
 				  }
 			  }
 		  }
 	  }
    /* USER CODE END WHILE */
    /* USER CODE BEGIN 3 */
  }&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;br /&gt;7.녹칸다가 &amp;ldquo;LED ON&amp;rdquo;이라고 전송하면 PB3에 연결된 LED가 켜지고, &amp;ldquo;LED OFF&amp;rdquo;라고 전송하면 LED가 꺼지도록 하시오!&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/vOnuU/dJMb9OAH6Ko/SaZLLxxatDJNV1BkiOZJF0/ex7.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;ex7.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;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;07.PNG&quot; data-origin-width=&quot;1074&quot; data-origin-height=&quot;615&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/xLTi1/dJMb9YpIq1L/aeX5XNJiXLU4bxfHMKm9MK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/xLTi1/dJMb9YpIq1L/aeX5XNJiXLU4bxfHMKm9MK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/xLTi1/dJMb9YpIq1L/aeX5XNJiXLU4bxfHMKm9MK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FxLTi1%2FdJMb9YpIq1L%2FaeX5XNJiXLU4bxfHMKm9MK%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;1074&quot; height=&quot;615&quot; data-filename=&quot;07.PNG&quot; data-origin-width=&quot;1074&quot; data-origin-height=&quot;615&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;pre id=&quot;code_1761061620593&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 */
  char recv;
  char buff[100]; //수신메모리
  int pos = 0;
 /* USER CODE END 2 */
 /* Infinite loop */
 /* USER CODE BEGIN WHILE */
  while (1)
  {
 	  //PC에서 보낸 데이터가 있는가? 있다면 읽기 시작한다!
 	  if(HAL_UART_Receive(&amp;amp;huart2, &amp;amp;recv, 1, 500) == HAL_OK){
 		  //보낸 데이터가 있다면 1바이트씩 읽는다!
 		  buff[0] = recv;
 		  pos = 1;
 		  while(1){
 			  //만약 PC에서 데이터를 연속으로 보내다가 흐름이 0.5초정도 끊어지면 읽기를 종료한다!
 			  if(HAL_UART_Receive(&amp;amp;huart2, &amp;amp;recv, 1, 500) == HAL_OK){
 				  //지금 읽은 데이터가 종료문자이냐? 이면 끝이고 아니면 계속 읽는다!
 				  if(recv == '\r'){
 					buff[pos] = '\0';
 					//LED ON이면 LED를 켜고 LED OFF면 끈다
 					if(strcmp(buff,&quot;LED ON&quot;) == 0){
 						HAL_GPIO_WritePin(GPIOB, GPIO_PIN_3, GPIO_PIN_SET);
 					}else if(strcmp(buff,&quot;LED OFF&quot;) == 0){
 						HAL_GPIO_WritePin(GPIOB, GPIO_PIN_3, GPIO_PIN_RESET);
 					}
 					break;
 				  }else{
 					buff[pos] = recv;
 					pos++;
 				  }
 			  }
 		  }
 	  }
   /* USER CODE END WHILE */
   /* USER CODE BEGIN 3 */
  }&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;8.STM32실습보드에 LED가 총 8개 연결되어있는데, LED다음에 번호를 1~8까지 붙히고 ON이면 켜지고 OFF면 꺼지도록 하시오! 예를들면 LED5 ON이라고 하면 다섯번째 LED가 켜지는 것이다!(LED가 만약 10개 이상이라면 숫자가 2자리가 되어서 복잡한데 지금은 한자리만 해석하면 되니까 간단!)&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/bolaOC/dJMb9YJ1l2y/YGZoCZ30RG1U3T104pRw11/ex8.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;ex8.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;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;08.PNG&quot; data-origin-width=&quot;1064&quot; data-origin-height=&quot;652&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/OA2gG/dJMb9i2N3ss/KovsCBIOKr86lVuKTCkmIk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/OA2gG/dJMb9i2N3ss/KovsCBIOKr86lVuKTCkmIk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/OA2gG/dJMb9i2N3ss/KovsCBIOKr86lVuKTCkmIk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FOA2gG%2FdJMb9i2N3ss%2FKovsCBIOKr86lVuKTCkmIk%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;1064&quot; height=&quot;652&quot; data-filename=&quot;08.PNG&quot; data-origin-width=&quot;1064&quot; data-origin-height=&quot;652&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;pre id=&quot;code_1761061634236&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 */
  char recv;
  char buff[100]; //수신메모리
  int pos = 0;
 /* USER CODE END 2 */
 /* Infinite loop */
 /* USER CODE BEGIN WHILE */
  while (1)
  {
 	  //PC에서 보낸 데이터가 있는가? 있다면 읽기 시작한다!
 	  if(HAL_UART_Receive(&amp;amp;huart2, &amp;amp;recv, 1, 500) == HAL_OK){
 		  //보낸 데이터가 있다면 1바이트씩 읽는다!
 		  buff[0] = recv;
 		  pos = 1;
 		  while(1){
 			  //만약 PC에서 데이터를 연속으로 보내다가 흐름이 0.5초정도 끊어지면 읽기를 종료한다!
 			  if(HAL_UART_Receive(&amp;amp;huart2, &amp;amp;recv, 1, 500) == HAL_OK){
 				  //지금 읽은 데이터가 종료문자이냐? 이면 끝이고 아니면 계속 읽는다!
 				  if(recv == '\r'){
 					buff[pos] = '\0';
 					//LED ON이면 LED를 켜고 LED OFF면 끈다
 					if(strcmp(buff,&quot;LED1 ON&quot;) == 0){
 						HAL_GPIO_WritePin(GPIOB, GPIO_PIN_3, GPIO_PIN_SET);
 					}else if(strcmp(buff,&quot;LED1 OFF&quot;) == 0){
 						HAL_GPIO_WritePin(GPIOB, GPIO_PIN_3, GPIO_PIN_RESET);
 					}else if(strcmp(buff,&quot;LED2 ON&quot;) == 0){
 						HAL_GPIO_WritePin(GPIOB, GPIO_PIN_13, GPIO_PIN_SET);
 					}else if(strcmp(buff,&quot;LED2 OFF&quot;) == 0){
 						HAL_GPIO_WritePin(GPIOB, GPIO_PIN_13, GPIO_PIN_RESET);
 					}else if(strcmp(buff,&quot;LED3 ON&quot;) == 0){
 						HAL_GPIO_WritePin(GPIOB, GPIO_PIN_5, GPIO_PIN_SET);
 					}else if(strcmp(buff,&quot;LED3 OFF&quot;) == 0){
 						HAL_GPIO_WritePin(GPIOB, GPIO_PIN_5, GPIO_PIN_RESET);
 					}else if(strcmp(buff,&quot;LED4 ON&quot;) == 0){
 						HAL_GPIO_WritePin(GPIOB, GPIO_PIN_14, GPIO_PIN_SET);


 					}else if(strcmp(buff,&quot;LED4 OFF&quot;) == 0){
 						HAL_GPIO_WritePin(GPIOB, GPIO_PIN_14, GPIO_PIN_RESET);
 					}else if(strcmp(buff,&quot;LED5 ON&quot;) == 0){
 						HAL_GPIO_WritePin(GPIOB, GPIO_PIN_4, GPIO_PIN_SET);
 					}else if(strcmp(buff,&quot;LED5 OFF&quot;) == 0){
 						HAL_GPIO_WritePin(GPIOB, GPIO_PIN_4, GPIO_PIN_RESET);
 					}else if(strcmp(buff,&quot;LED6 ON&quot;) == 0){
 						HAL_GPIO_WritePin(GPIOB, GPIO_PIN_15, GPIO_PIN_SET);
 					}else if(strcmp(buff,&quot;LED6 OFF&quot;) == 0){
 						HAL_GPIO_WritePin(GPIOB, GPIO_PIN_15, GPIO_PIN_RESET);
 					}else if(strcmp(buff,&quot;LED7 ON&quot;) == 0){
 						HAL_GPIO_WritePin(GPIOC, GPIO_PIN_4, GPIO_PIN_SET);
 					}else if(strcmp(buff,&quot;LED7 OFF&quot;) == 0){
 						HAL_GPIO_WritePin(GPIOC, GPIO_PIN_4, GPIO_PIN_RESET);
 					}else if(strcmp(buff,&quot;LED8 ON&quot;) == 0){
 						HAL_GPIO_WritePin(GPIOB, GPIO_PIN_7, GPIO_PIN_SET);
 					}else if(strcmp(buff,&quot;LED8 OFF&quot;) == 0){
 						HAL_GPIO_WritePin(GPIOB, GPIO_PIN_7, GPIO_PIN_RESET);
 					}
 					break;
 				  }else{
 					buff[pos] = recv;
 					pos++;
 				  }
 			  }
 		  }
 	  }
   /* USER CODE END WHILE */
   /* USER CODE BEGIN 3 */
  }&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;9.녹칸다가 LED1번부터 8번까지의 상태를 2진수로 전송한다! 0이면 OFF고 1이면 ON이다! 예를들어 11110000이라고 보내면 LED1~4까지는 ON이고 5~8까지는 OFF하라는 의미이다!(데이터가 고정길이다)&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/l3AEO/dJMb9XRSwXO/6b6Sfs4NYMz5SOFrtXevCk/ex9.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;ex9.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;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;09.PNG&quot; data-origin-width=&quot;1033&quot; data-origin-height=&quot;626&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/1jhI8/dJMb9MCTxES/K8F2bmniMVdMPxwEjSYwUk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/1jhI8/dJMb9MCTxES/K8F2bmniMVdMPxwEjSYwUk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/1jhI8/dJMb9MCTxES/K8F2bmniMVdMPxwEjSYwUk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2F1jhI8%2FdJMb9MCTxES%2FK8F2bmniMVdMPxwEjSYwUk%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;1033&quot; height=&quot;626&quot; data-filename=&quot;09.PNG&quot; data-origin-width=&quot;1033&quot; data-origin-height=&quot;626&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;pre id=&quot;code_1761061647555&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 */
  char buff[100]; //수신메모리
  GPIO_TypeDef *mygpio[] = {GPIOB,GPIOB,GPIOB,GPIOB,GPIOB,GPIOB,GPIOC,GPIOB};
  uint16_t mypin[] = {GPIO_PIN_3,GPIO_PIN_13,GPIO_PIN_5,GPIO_PIN_14,GPIO_PIN_4,GPIO_PIN_15,GPIO_PIN_4,GPIO_PIN_7};
 /* USER CODE END 2 */
 /* Infinite loop */
 /* USER CODE BEGIN WHILE */
  while (1)
  {
 	  //PC에서 보낸 데이터가 있는가? 있다면 읽기 시작한다!
 	  if(HAL_UART_Receive(&amp;amp;huart2, buff, 8, 500) == HAL_OK){
 		 //buff에 0~7까지 LED의 상태가 문자 '0'또는 '1'로 지정되어서 데이터가 왔다!
 		 //buff를 반복문으로 0~7까지 하나씩 순회하면서 문자로 해석한다!
 		 for(int i = 0;i &amp;lt; 8;i++){
 			 if(buff[i] == '0'){
 				 //i번째 LED가 OFF이다!
 				HAL_GPIO_WritePin(mygpio[i], mypin[i], GPIO_PIN_RESET);
 			 }else if(buff[i] == '1'){
 				 //i번째 LED가 ON이다!
 				HAL_GPIO_WritePin(mygpio[i], mypin[i], GPIO_PIN_SET);
 			 }
 		 }
 	  }
   /* USER CODE END WHILE */
   /* USER CODE BEGIN 3 */
  }&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;10.예제1번에서 연결해놓은 PB1버튼을 2초동안 누르면 길게눌렀다고 PC로 전송하고, 2초이내로 짧게 누르면 짧게 눌렀다고 전송하시오!&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/Andg6/dJMb9fdWsle/CaDULw5ArRElLmkFxkZ5k1/ex10.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;ex10.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;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;10.PNG&quot; data-origin-width=&quot;1063&quot; data-origin-height=&quot;604&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/wjPX0/dJMb9QeepxS/AMi9sqTzFrHwjOG3xBwIU0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/wjPX0/dJMb9QeepxS/AMi9sqTzFrHwjOG3xBwIU0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/wjPX0/dJMb9QeepxS/AMi9sqTzFrHwjOG3xBwIU0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FwjPX0%2FdJMb9QeepxS%2FAMi9sqTzFrHwjOG3xBwIU0%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;1063&quot; height=&quot;604&quot; data-filename=&quot;10.PNG&quot; data-origin-width=&quot;1063&quot; data-origin-height=&quot;604&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;pre id=&quot;code_1761061656346&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 */
 char *msg1 = &quot;LONG CLICK!!\n&quot;;
 char *msg2 = &quot;SHORT CLICK!!\n&quot;;
 /* USER CODE END 2 */
 /* Infinite loop */
 /* USER CODE BEGIN WHILE */
  while (1)
  {
	   //PB1을 눌렀다!
	  if(HAL_GPIO_ReadPin(GPIOB,GPIO_PIN_1) == GPIO_PIN_RESET){
		  //눌렀던 버튼을 뗄때까지 무한루프를 돌려버린다
		  //루프가 작동한 시간을 측정한다!
		  uint32_t t = HAL_GetTick(); //while루프에 진입하기 직전의 시간!
		  uint8_t is_longclick = 0;
		  while(HAL_GPIO_ReadPin(GPIOB,GPIO_PIN_1) == GPIO_PIN_RESET){
			  if(HAL_GetTick() - t &amp;gt; 2000){
				  //버튼을 2초이상 눌렀다!
				  is_longclick = 1;
				  break;
			  }
		  }
		  if(is_longclick){
			  //길게 눌러서 while루프가 강제종료된 경우
			  HAL_UART_Transmit(&amp;amp;huart2, msg1, strlen(msg1), 100);
			  //버튼 뗄때까지 무한대기
			  while(HAL_GPIO_ReadPin(GPIOB,GPIO_PIN_1) == GPIO_PIN_RESET);
			  //버튼 뗀다음에 오류를 방지하기 위한 소량의 지연시간
			  HAL_Delay(200);
		  }else{
			  //2초 이내에 눌렀다가 떼서 자연스럽게 종료된경우
			  HAL_UART_Transmit(&amp;amp;huart2, msg2, strlen(msg2), 100);
			  HAL_Delay(200);
		  }
	  }
   /* USER CODE END WHILE */
   /* USER CODE BEGIN 3 */
  }&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;11.PB1버튼을&amp;nbsp;짧게누르면&amp;nbsp;모든&amp;nbsp;LED를&amp;nbsp;ON한다!&amp;nbsp;PB1을&amp;nbsp;길게&amp;nbsp;누르면&amp;nbsp;모든&amp;nbsp;LED를&amp;nbsp;OFF한다!(예제10번내용&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/pAQTp/dJMb85bkcsz/8zXKIHmYNjw6zvZNwnT561/ex11.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;ex11.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;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;11.PNG&quot; data-origin-width=&quot;1028&quot; data-origin-height=&quot;580&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/73z09/dJMb9MCTxE1/Ggsv3OeRVLKnKiAr8IxPB0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/73z09/dJMb9MCTxE1/Ggsv3OeRVLKnKiAr8IxPB0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/73z09/dJMb9MCTxE1/Ggsv3OeRVLKnKiAr8IxPB0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2F73z09%2FdJMb9MCTxE1%2FGgsv3OeRVLKnKiAr8IxPB0%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;1028&quot; height=&quot;580&quot; data-filename=&quot;11.PNG&quot; data-origin-width=&quot;1028&quot; data-origin-height=&quot;580&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;pre id=&quot;code_1761061664478&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 */
 char *msg1 = &quot;LONG CLICK!!\n&quot;;
 char *msg2 = &quot;SHORT CLICK!!\n&quot;;
 GPIO_TypeDef *mygpio[] = {GPIOB,GPIOB,GPIOB,GPIOB,GPIOB,GPIOB,GPIOC,GPIOB};
 uint16_t mypin[] = {GPIO_PIN_3,GPIO_PIN_13,GPIO_PIN_5,GPIO_PIN_14,GPIO_PIN_4,GPIO_PIN_15,GPIO_PIN_4,GPIO_PIN_7};
 /* USER CODE END 2 */
 /* Infinite loop */
 /* USER CODE BEGIN WHILE */
  while (1)
  {
	   //PB1을 눌렀다!
	  if(HAL_GPIO_ReadPin(GPIOB,GPIO_PIN_1) == GPIO_PIN_RESET){
		  //눌렀던 버튼을 뗄때까지 무한루프를 돌려버린다
		  //루프가 작동한 시간을 측정한다!
		  uint32_t t = HAL_GetTick(); //while루프에 진입하기 직전의 시간!
		  uint8_t is_longclick = 0;
		  while(HAL_GPIO_ReadPin(GPIOB,GPIO_PIN_1) == GPIO_PIN_RESET){
			  if(HAL_GetTick() - t &amp;gt; 2000){
				  //버튼을 2초이상 눌렀다!
				  is_longclick = 1;
				  break;
			  }
		  }
		  if(is_longclick){
			  //길게 눌러서 while루프가 강제종료된 경우
			  HAL_UART_Transmit(&amp;amp;huart2, msg1, strlen(msg1), 100);
			  //LED컨트롤
			  for(int i = 0;i&amp;lt;8;i++){
				  HAL_GPIO_WritePin(mygpio[i], mypin[i], GPIO_PIN_RESET);
			  }
			  //버튼 뗄때까지 무한대기
			  while(HAL_GPIO_ReadPin(GPIOB,GPIO_PIN_1) == GPIO_PIN_RESET);
			  //버튼 뗀다음에 오류를 방지하기 위한 소량의 지연시간
			  HAL_Delay(200);
		  }else{
			  //2초 이내에 눌렀다가 떼서 자연스럽게 종료된경우
			  HAL_UART_Transmit(&amp;amp;huart2, msg2, strlen(msg2), 100);
			  for(int i = 0;i&amp;lt;8;i++){
				  HAL_GPIO_WritePin(mygpio[i], mypin[i], GPIO_PIN_SET);
			  }
			  HAL_Delay(200);
		  }
	  }
   /* USER CODE END WHILE */
   /* USER CODE BEGIN 3 */
  }&lt;/code&gt;&lt;/pre&gt;</description>
      <category>프로그래밍/STM32</category>
      <author>덕력킹</author>
      <guid isPermaLink="true">https://bota.tistory.com/2446</guid>
      <comments>https://bota.tistory.com/2446#entry2446comment</comments>
      <pubDate>Wed, 22 Oct 2025 00:47:43 +0900</pubDate>
    </item>
    <item>
      <title>[STM32#03] HAL_UART_Transmit(), HAL_UART_Receive() 함수를 이용해서 USART2 시리얼통신 해보기!(녹칸다 내맘대로 STM32)</title>
      <link>https://bota.tistory.com/2445</link>
      <description>&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;stm32.png&quot; data-origin-width=&quot;1920&quot; data-origin-height=&quot;1080&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cazHSD/dJMb9NogyOq/kFmnWfiSrk55Tpo5CJjpPK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cazHSD/dJMb9NogyOq/kFmnWfiSrk55Tpo5CJjpPK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cazHSD/dJMb9NogyOq/kFmnWfiSrk55Tpo5CJjpPK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FcazHSD%2FdJMb9NogyOq%2FkFmnWfiSrk55Tpo5CJjpPK%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;1920&quot; height=&quot;1080&quot; data-filename=&quot;stm32.png&quot; data-origin-width=&quot;1920&quot; data-origin-height=&quot;1080&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/live/VzvWwM-p04Q&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://youtube.com/live/VzvWwM-p04Q&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/watch?v=VzvWwM-p04Q&quot; data-video-thumbnail=&quot;https://scrap.kakaocdn.net/dn/2vdex/hyZL4VlLSY/mno5Fqpck8NW18odYpbqv1/img.jpg?width=1280&amp;amp;height=720&amp;amp;face=0_0_1280_720,https://scrap.kakaocdn.net/dn/Kx2Lm/hyZLWpu9BA/82uovFg1TzbdxAGJdTZAvK/img.jpg?width=1280&amp;amp;height=720&amp;amp;face=0_0_1280_720&quot; data-video-width=&quot;860&quot; data-video-height=&quot;484&quot; data-video-origin-width=&quot;860&quot; data-video-origin-height=&quot;484&quot; data-ke-mobilestyle=&quot;widthContent&quot; data-video-title=&quot;[STM32#03] HAL_UART_Transmit(), HAL_UART_Receive() 함수를 이용해서 USART2 시리얼통신 해보기!(녹칸다 내맘대&quot; data-original-url=&quot;&quot;&gt;&lt;iframe src=&quot;https://www.youtube.com/embed/VzvWwM-p04Q&quot; width=&quot;860&quot; height=&quot;484&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;[STM32#03]&amp;nbsp;STM32F103RB&amp;nbsp;NUCLEO보드에서&amp;nbsp;HAL_UART_Transmit(),&amp;nbsp;HAL_UART_Receive()&amp;nbsp;함수를&amp;nbsp;이용해서&amp;nbsp;USART2&amp;nbsp;시리얼통신&amp;nbsp;해보기!(녹칸다&amp;nbsp;내맘대로&amp;nbsp;STM32) &lt;br /&gt;&lt;br /&gt;심심한녹칸다의&amp;nbsp;내맘대로&amp;nbsp;STM32시리즈이다! &lt;br /&gt;&lt;br /&gt;STM32시리즈의&amp;nbsp;모든&amp;nbsp;자료는&amp;nbsp;구글&amp;nbsp;슬라이드에&amp;nbsp;작성하고&amp;nbsp;모두에게&amp;nbsp;공유되어있음! &lt;br /&gt;&lt;a href=&quot;https://docs.google.com/presentation/d/1myA5iYbjuKsLWLqtRLKAiRfwUwvqB1d1RGjiMIIgp3I/edit?slide=id.g39af4024cdb_1_0#slide=id.g39af4024cdb_1_0&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://docs.google.com/presentation/d/1myA5iYbjuKsLWLqtRLKAiRfwUwvqB1d1RGjiMIIgp3I/edit?slide=id.g39af4024cdb_1_0#slide=id.g39af4024cdb_1_0&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;이번편에서는&amp;nbsp;STM32보드에&amp;nbsp;설정되어있는&amp;nbsp;USART2를&amp;nbsp;이용해서&amp;nbsp;PC와&amp;nbsp;시리얼통신을&amp;nbsp;해보도록&amp;nbsp;한다! &lt;br /&gt;&lt;br /&gt;(아두이노와&amp;nbsp;비교해서&amp;nbsp;STM32가&amp;nbsp;더&amp;nbsp;좋다고&amp;nbsp;보는것&amp;nbsp;1)&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;01.PNG&quot; data-origin-width=&quot;1075&quot; data-origin-height=&quot;463&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/mZR99/dJMb9PM9C5n/JY4e5arXVugISzVtCGkWE1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/mZR99/dJMb9PM9C5n/JY4e5arXVugISzVtCGkWE1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/mZR99/dJMb9PM9C5n/JY4e5arXVugISzVtCGkWE1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FmZR99%2FdJMb9PM9C5n%2FJY4e5arXVugISzVtCGkWE1%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;463&quot; data-filename=&quot;01.PNG&quot; data-origin-width=&quot;1075&quot; data-origin-height=&quot;463&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;br /&gt;1.아두이노는&amp;nbsp;코드를&amp;nbsp;작성하고&amp;nbsp;아두이노&amp;nbsp;보드에&amp;nbsp;&amp;ldquo;업로드&amp;rdquo;를&amp;nbsp;하게&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;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;PC와&amp;nbsp;통신을&amp;nbsp;연결해서&amp;nbsp;PC쪽으로&amp;nbsp;값을&amp;nbsp;전송해야&amp;nbsp;알아낼&amp;nbsp;수&amp;nbsp;있다! &lt;br /&gt;3.지금&amp;nbsp;녹칸다가&amp;nbsp;사용하는&amp;nbsp;STM32보드는&amp;nbsp;뉴클레오&amp;nbsp;보드이고,&amp;nbsp;뉴클레오&amp;nbsp;보드는&amp;nbsp;ST링크가&amp;nbsp;내장되어&amp;nbsp;있는&amp;nbsp;방식이기&amp;nbsp;때문에&amp;nbsp;&amp;ldquo;디버깅&amp;rdquo;모드가&amp;nbsp;지원됨! &lt;br /&gt;4.디버깅모드를&amp;nbsp;활용하게&amp;nbsp;되면&amp;nbsp;STM32보드에&amp;nbsp;적용될&amp;nbsp;코드에&amp;nbsp;변수값이라던지,&amp;nbsp;작동되는&amp;nbsp;메커니즘&amp;nbsp;등을&amp;nbsp;STM32cubeIDE에서&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;p data-ke-size=&quot;size16&quot;&gt;(예제목차)&lt;br /&gt;1.STM32의&amp;nbsp;디버깅&amp;nbsp;기능을&amp;nbsp;이용해서&amp;nbsp;1초간격으로&amp;nbsp;1씩&amp;nbsp;증가하는&amp;nbsp;nockanda_cnt라는&amp;nbsp;변수의&amp;nbsp;값을&amp;nbsp;stm32cubeide에서&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/c7SQqB/dJMb9PGn9oY/YT6CdxKo4UfZpjO2aKqtjK/ex1.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;ex1.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;
&lt;pre id=&quot;code_1760969332532&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 */
 int nockanda_cnt = 0;
 /* USER CODE END 2 */
 /* Infinite loop */
 /* USER CODE BEGIN WHILE */
 while (1)
 {
	  nockanda_cnt++; //cnt값을 1씩 증가
	  HAL_Delay(1000); //1초 쉬기~
   /* 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;&lt;br /&gt;2.버튼중에&amp;nbsp;PB1번&amp;nbsp;버튼을&amp;nbsp;누르면&amp;nbsp;nockanda_cnt가&amp;nbsp;1씩&amp;nbsp;증가하는데,&amp;nbsp;녹칸다가&amp;nbsp;버튼을&amp;nbsp;누른게&amp;nbsp;STM32에서&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/23Ykm/dJMb9MJEFHC/WpySFG8GpBucQ9Nct94Y61/ex2.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;ex2.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;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;2.PNG&quot; data-origin-width=&quot;1003&quot; data-origin-height=&quot;484&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/DDaa7/dJMb9LYhRPA/ksS6NoGboeVxXUV4c4AO2k/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/DDaa7/dJMb9LYhRPA/ksS6NoGboeVxXUV4c4AO2k/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/DDaa7/dJMb9LYhRPA/ksS6NoGboeVxXUV4c4AO2k/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FDDaa7%2FdJMb9LYhRPA%2FksS6NoGboeVxXUV4c4AO2k%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;1003&quot; height=&quot;484&quot; data-filename=&quot;2.PNG&quot; data-origin-width=&quot;1003&quot; data-origin-height=&quot;484&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;pre id=&quot;code_1760969344787&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 */
 int nockanda_cnt = 0;
 /* USER CODE END 2 */
 /* Infinite loop */
 /* USER CODE BEGIN WHILE */
 while (1)
 {
	  //PB1버튼을 누르면 CNT가 1씩 증가한다~
	  if(HAL_GPIO_ReadPin(GPIOB,GPIO_PIN_1) == GPIO_PIN_RESET){
		  nockanda_cnt++;
	  }
   /* USER CODE END WHILE */
   /* USER CODE BEGIN 3 */&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;br /&gt;3.STM32에서&amp;nbsp;PC쪽으로&amp;nbsp;1초간격으로&amp;nbsp;&amp;ldquo;Hello&amp;nbsp;STM32!!&amp;rdquo;라는&amp;nbsp;문자열을&amp;nbsp;전송하고&amp;nbsp;PC에서&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/Aob0q/dJMb88MEtlE/IqQoeHQzJkpymYPvKZV9rK/ex3.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;ex3.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;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;3.PNG&quot; data-origin-width=&quot;926&quot; data-origin-height=&quot;508&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/p1EeR/dJMb9PTU0kR/QwN3GBgCoH8Ag8NGUK6Sxk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/p1EeR/dJMb9PTU0kR/QwN3GBgCoH8Ag8NGUK6Sxk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/p1EeR/dJMb9PTU0kR/QwN3GBgCoH8Ag8NGUK6Sxk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fp1EeR%2FdJMb9PTU0kR%2FQwN3GBgCoH8Ag8NGUK6Sxk%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;926&quot; height=&quot;508&quot; data-filename=&quot;3.PNG&quot; data-origin-width=&quot;926&quot; data-origin-height=&quot;508&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;pre id=&quot;code_1760969359540&quot; class=&quot;cpp&quot; data-ke-language=&quot;cpp&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;char text1[] = &quot;hello stm32\n&quot;;
 char *text2 = &quot;hello stm32\n&quot;; //얘는 text2자체가 이미 포인터임
 int num = 10;
 /* USER CODE END 2 */
 /* Infinite loop */
 /* USER CODE BEGIN WHILE */
 while (1)
 {
	  //1초간격으로 &quot;hello stm32\r&quot;라는 문자열을 전송해라!
	  //그런데 여기서 제일 마지막에 캐리지리턴를 포함하라고 했다!
	  //if(HAL_UART_Transmit(&amp;amp;huart2, text1, sizeof(text1), 100) == HAL_OK){ // OK!
     //if(HAL_UART_Transmit(&amp;amp;huart2, text2, sizeof(text2), 100) == HAL_OK){ // BAD!
     //if(HAL_UART_Transmit(&amp;amp;huart2, text1, strlen(text1), 100) == HAL_OK){ // OK!
     if(HAL_UART_Transmit(&amp;amp;huart2, text2, strlen(text2), 100) == HAL_OK){ //OK!
		  //전송 성공!
	  }else{
		  //전송 실패!
	  }
	  HAL_Delay(1000); //1초 쉬기~
   /* USER CODE END WHILE */
   /* USER CODE BEGIN 3 */
 }&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;br /&gt;4.STM32내부에&amp;nbsp;1초간격으로&amp;nbsp;증가하는&amp;nbsp;nockanda_cnt라는&amp;nbsp;변수가&amp;nbsp;있는데,&amp;nbsp;이&amp;nbsp;변수의&amp;nbsp;현재&amp;nbsp;값을&amp;nbsp;&amp;ldquo;nockanda_cnt&amp;nbsp;=&amp;nbsp;1234&amp;rdquo;와&amp;nbsp;같은&amp;nbsp;형식으로&amp;nbsp;putty로&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/GjGqu/dJMb88MEtlH/rnfdMwSKdSM8LxPQY4j5i1/ex4.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;ex4.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;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;4.PNG&quot; data-origin-width=&quot;900&quot; data-origin-height=&quot;543&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bcu3gf/dJMb9LYhRPV/ZKTSc7YEAtsiBOw7NkPje1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bcu3gf/dJMb9LYhRPV/ZKTSc7YEAtsiBOw7NkPje1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bcu3gf/dJMb9LYhRPV/ZKTSc7YEAtsiBOw7NkPje1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fbcu3gf%2FdJMb9LYhRPV%2FZKTSc7YEAtsiBOw7NkPje1%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;900&quot; height=&quot;543&quot; data-filename=&quot;4.PNG&quot; data-origin-width=&quot;900&quot; data-origin-height=&quot;543&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;pre id=&quot;code_1760969375852&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 */
 int nockanda_cnt = 0;
 char buff[100]; //아무리 길어도 100을 안넘겠지?
 /* USER CODE END 2 */
 /* Infinite loop */
 /* USER CODE BEGIN WHILE */
 while (1)
 {
	  //100개짜리 char배열에 nockanda_cnt = 1234와 같은 형식으로 데이터 집어넣기~
	  sprintf(buff,&quot;nockanda_cnt = %d\n&quot;,nockanda_cnt);
	  if(HAL_UART_Transmit(&amp;amp;huart2, buff, strlen(buff), 100) == HAL_OK){
		  //성공~
	  }else{
		  //실패~
	  }
     nockanda_cnt++; //값증가~
	  HAL_Delay(1000); //1초 쉬기~
   /* USER CODE END WHILE */
   /* USER CODE BEGIN 3 */
 }&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;br /&gt;5.이번에는&amp;nbsp;putty에서&amp;nbsp;STM32쪽으로&amp;nbsp;고정되어있는&amp;nbsp;데이터를&amp;nbsp;전송할때&amp;nbsp;그&amp;nbsp;데이터를&amp;nbsp;수신해서&amp;nbsp;디버깅모드에서&amp;nbsp;확인하시오!(전송하는&amp;nbsp;데이터=hello&amp;nbsp;nockanda!!)&amp;nbsp;그리고&amp;nbsp;정확히&amp;nbsp;hello&amp;nbsp;nockanda!!인게&amp;nbsp;확인이&amp;nbsp;되면&amp;nbsp;OK를&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/ph7K8/dJMb9OU0Cxg/Aemf15tjMp62LxUYDg4w1K/ex5.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;ex5.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;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;5.PNG&quot; data-origin-width=&quot;936&quot; data-origin-height=&quot;488&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/dGxqeO/dJMb9LYhRP1/OKEtl4kbvwweCaMrC4tC5K/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/dGxqeO/dJMb9LYhRP1/OKEtl4kbvwweCaMrC4tC5K/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/dGxqeO/dJMb9LYhRP1/OKEtl4kbvwweCaMrC4tC5K/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FdGxqeO%2FdJMb9LYhRP1%2FOKEtl4kbvwweCaMrC4tC5K%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;936&quot; height=&quot;488&quot; data-filename=&quot;5.PNG&quot; data-origin-width=&quot;936&quot; data-origin-height=&quot;488&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;pre id=&quot;code_1760969390215&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 */
 char buff[100]; //수신한 데이터를 저장할 버퍼
 char text[] = &quot;OK!!\n&quot;;
 /* USER CODE END 2 */
 /* Infinite loop */
 /* USER CODE BEGIN WHILE */
 while (1)
 {
	  //PC에서 우체통에 16개의 데이터를 넣어뒀는데 그것을 성공적으로 buff에 copy했다!
	  if(HAL_UART_Receive(&amp;amp;huart2, buff, 16, 500) == HAL_OK){
		 //성공
		 //내가 지금 수신한게 hello nockanda!!가 맞느냐?
		 if(strcmp(buff,&quot;hello nockanda!!&quot;) == 0){
			 //일치
			 HAL_UART_Transmit(&amp;amp;huart2, text, strlen(text), 100);
		 }
	  }else{
		 //실패
	  }
   /* USER CODE END WHILE */
   /* USER CODE BEGIN 3 */
 }&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;br /&gt;6.녹칸다가&amp;nbsp;&amp;ldquo;data1&amp;rdquo;이라고&amp;nbsp;전송하면&amp;nbsp;stm32는&amp;nbsp;&amp;ldquo;nockanda&amp;rdquo;라고&amp;nbsp;응답하고&amp;nbsp;&amp;ldquo;data2&amp;rdquo;라고&amp;nbsp;전송하면&amp;nbsp;stm32는&amp;nbsp;&amp;ldquo;forever&amp;rdquo;라고&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/bIYDLC/dJMb9YwtU6k/HufditXda55PcNwYfBNTr1/ex6.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;ex6.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;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;6.PNG&quot; data-origin-width=&quot;1001&quot; data-origin-height=&quot;557&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bjrAIF/dJMb9VGwy2n/7tC8IeMHG5AgUuFWjjzHqK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bjrAIF/dJMb9VGwy2n/7tC8IeMHG5AgUuFWjjzHqK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bjrAIF/dJMb9VGwy2n/7tC8IeMHG5AgUuFWjjzHqK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbjrAIF%2FdJMb9VGwy2n%2F7tC8IeMHG5AgUuFWjjzHqK%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;1001&quot; height=&quot;557&quot; data-filename=&quot;6.PNG&quot; data-origin-width=&quot;1001&quot; data-origin-height=&quot;557&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;pre id=&quot;code_1760969400699&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 */
 char buff[100] = {'\0'}; //배열을 100개 만드는데 초기값은 모두 null 문자이다!
 char text1[] = &quot;nockanda\n&quot;;
 char text2[] = &quot;forever\n&quot;;
 /* USER CODE END 2 */
 /* Infinite loop */
 /* USER CODE BEGIN WHILE */
 while (1)
 {
	  //PC에서 데이터를 무조건 5개로 해서 보내줄거야~
	  if(HAL_UART_Receive(&amp;amp;huart2, buff, 5, 500) == HAL_OK){
		 //성공
		 //내가 지금 수신한게 hello nockanda!!가 맞느냐?
		 if(strcmp(buff,&quot;data1&quot;) == 0){
			 //일치
			 HAL_UART_Transmit(&amp;amp;huart2, text1, strlen(text1), 100);
		 }else if(strcmp(buff,&quot;data2&quot;) == 0){
			 //일치
			 HAL_UART_Transmit(&amp;amp;huart2, text2, strlen(text2), 100);
		 }
	  }else{
		 //실패
	  }
	/* USER CODE END WHILE */
	/* USER CODE BEGIN 3 */
 }&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;br /&gt;7.예제6과&amp;nbsp;동일한&amp;nbsp;결과를&amp;nbsp;유지하되,&amp;nbsp;data1이면&amp;nbsp;PB3에&amp;nbsp;연결된&amp;nbsp;LED가&amp;nbsp;ON되고,&amp;nbsp;data2라고&amp;nbsp;전송하면&amp;nbsp;OFF되도록&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/oTQFo/dJMb9P7r9gC/zVkVU04iuyYisamFv319v1/ex7.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;ex7.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;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;7.PNG&quot; data-origin-width=&quot;821&quot; data-origin-height=&quot;566&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bRiUXM/dJMb9LYhRQe/IoxdyEb3QpQ900v8iSmRQK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bRiUXM/dJMb9LYhRQe/IoxdyEb3QpQ900v8iSmRQK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bRiUXM/dJMb9LYhRQe/IoxdyEb3QpQ900v8iSmRQK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbRiUXM%2FdJMb9LYhRQe%2FIoxdyEb3QpQ900v8iSmRQK%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;821&quot; height=&quot;566&quot; data-filename=&quot;7.PNG&quot; data-origin-width=&quot;821&quot; data-origin-height=&quot;566&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;pre id=&quot;code_1760969411395&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 */
 char buff[100] = {'\0'}; //배열을 100개 만드는데 초기값은 모두 null 문자이다!
 char text1[] = &quot;nockanda\n&quot;;
 char text2[] = &quot;forever\n&quot;;
 /* USER CODE END 2 */
 /* Infinite loop */
 /* USER CODE BEGIN WHILE */
 while (1)
 {
	  //PC에서 데이터를 무조건 5개로 해서 보내줄거야~
	  if(HAL_UART_Receive(&amp;amp;huart2, buff, 5, 500) == HAL_OK){
		 //성공
		 //내가 지금 수신한게 hello nockanda!!가 맞느냐?
		 if(strcmp(buff,&quot;data1&quot;) == 0){
			 //일치
			 HAL_UART_Transmit(&amp;amp;huart2, text1, strlen(text1), 100);
			 //LED ON
			 HAL_GPIO_WritePin(GPIOB,GPIO_PIN_3,GPIO_PIN_SET);
		 }else if(strcmp(buff,&quot;data2&quot;) == 0){
			 //일치
			 HAL_UART_Transmit(&amp;amp;huart2, text2, strlen(text2), 100);
			 //LED OFF
			 HAL_GPIO_WritePin(GPIOB,GPIO_PIN_3,GPIO_PIN_RESET);
		 }
	  }else{
		 //실패
	  }
   /* USER CODE END WHILE */
   /* USER CODE BEGIN 3 */
 }&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>프로그래밍/STM32</category>
      <author>덕력킹</author>
      <guid isPermaLink="true">https://bota.tistory.com/2445</guid>
      <comments>https://bota.tistory.com/2445#entry2445comment</comments>
      <pubDate>Mon, 20 Oct 2025 23:13:59 +0900</pubDate>
    </item>
    <item>
      <title>[STM32#02] 디지털출력함수인 HAL_GPIO_WritePin()과 디지털입력함수인 HAL_GPIO_ReadPin()에 대해서 알아보기!(녹칸다 내맘대로 STM32)</title>
      <link>https://bota.tistory.com/2444</link>
      <description>&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;stm32.png&quot; data-origin-width=&quot;1920&quot; data-origin-height=&quot;1080&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/P5fyF/btsRbpHF8VH/00DkQybJACTr23CXk9eQh1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/P5fyF/btsRbpHF8VH/00DkQybJACTr23CXk9eQh1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/P5fyF/btsRbpHF8VH/00DkQybJACTr23CXk9eQh1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FP5fyF%2FbtsRbpHF8VH%2F00DkQybJACTr23CXk9eQh1%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;1920&quot; height=&quot;1080&quot; data-filename=&quot;stm32.png&quot; data-origin-width=&quot;1920&quot; data-origin-height=&quot;1080&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/live/YhnQJ5wZIKQ&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://youtube.com/live/YhnQJ5wZIKQ&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/watch?v=YhnQJ5wZIKQ&quot; data-video-thumbnail=&quot;https://scrap.kakaocdn.net/dn/vyVQ1/hyZLqxvlrZ/tydetKDl0HNl95psBiWUaK/img.jpg?width=1280&amp;amp;height=720&amp;amp;face=0_0_1280_720,https://scrap.kakaocdn.net/dn/tgHUj/hyZLkjflqV/Mj6wmwtvN0c3Q55hi6JkWK/img.jpg?width=1280&amp;amp;height=720&amp;amp;face=0_0_1280_720&quot; data-video-width=&quot;860&quot; data-video-height=&quot;484&quot; data-video-origin-width=&quot;860&quot; data-video-origin-height=&quot;484&quot; data-ke-mobilestyle=&quot;widthContent&quot; data-video-title=&quot;[STM32#02] 디지털출력함수인 HAL_GPIO_WritePin()과 디지털입력함수인 HAL_GPIO_ReadPin()에 대해서 알아보기&quot; data-original-url=&quot;&quot;&gt;&lt;iframe src=&quot;https://www.youtube.com/embed/YhnQJ5wZIKQ&quot; width=&quot;860&quot; height=&quot;484&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;[STM32#02]&amp;nbsp;STM32F103RB&amp;nbsp;NUCLEO보드에서&amp;nbsp;디지털출력&amp;nbsp;함수인&amp;nbsp;HAL_GPIO_WritePin()과&amp;nbsp;디지털입력함수인&amp;nbsp;HAL_GPIO_ReadPin()에&amp;nbsp;대해서&amp;nbsp;알아보기!(녹칸다&amp;nbsp;내맘대로&amp;nbsp;STM32) &lt;br /&gt;&lt;br /&gt;심심한녹칸다의&amp;nbsp;내맘대로&amp;nbsp;STM32시리즈이다! &lt;br /&gt;&lt;br /&gt;STM32시리즈의&amp;nbsp;모든&amp;nbsp;자료는&amp;nbsp;구글&amp;nbsp;슬라이드에&amp;nbsp;작성하고&amp;nbsp;모두에게&amp;nbsp;공유되어있음! &lt;br /&gt;&lt;a href=&quot;https://docs.google.com/presentation/d/1myA5iYbjuKsLWLqtRLKAiRfwUwvqB1d1RGjiMIIgp3I/edit?slide=id.g38606a02edc_2_164#slide=id.g38606a02edc_2_164&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://docs.google.com/presentation/d/1myA5iYbjuKsLWLqtRLKAiRfwUwvqB1d1RGjiMIIgp3I/edit?slide=id.g38606a02edc_2_164#slide=id.g38606a02edc_2_164&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;이번편인&amp;nbsp;디지털입출력에&amp;nbsp;대해서&amp;nbsp;알아보도록&amp;nbsp;한다! &lt;br /&gt;디지털출력은&amp;nbsp;LED를&amp;nbsp;제어하고,&amp;nbsp;디지털입력은&amp;nbsp;버튼의&amp;nbsp;누름상태를&amp;nbsp;확인하는&amp;nbsp;것으로&amp;nbsp;한다! &lt;br /&gt;버튼을&amp;nbsp;누르면&amp;nbsp;LED가&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;LED 회로도&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;01.PNG&quot; data-origin-width=&quot;1242&quot; data-origin-height=&quot;666&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/biBIt9/btsRahDquZ2/PhT6lnwL2eaw2SgKqdhJRK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/biBIt9/btsRahDquZ2/PhT6lnwL2eaw2SgKqdhJRK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/biBIt9/btsRahDquZ2/PhT6lnwL2eaw2SgKqdhJRK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbiBIt9%2FbtsRahDquZ2%2FPhT6lnwL2eaw2SgKqdhJRK%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;1242&quot; height=&quot;666&quot; data-filename=&quot;01.PNG&quot; data-origin-width=&quot;1242&quot; data-origin-height=&quot;666&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-filename=&quot;02.PNG&quot; data-origin-width=&quot;1144&quot; data-origin-height=&quot;693&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/xyZTX/btsRbsYIm5b/ZyDdC8xxXWCfBKVGaikww0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/xyZTX/btsRbsYIm5b/ZyDdC8xxXWCfBKVGaikww0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/xyZTX/btsRbsYIm5b/ZyDdC8xxXWCfBKVGaikww0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FxyZTX%2FbtsRbsYIm5b%2FZyDdC8xxXWCfBKVGaikww0%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;1144&quot; height=&quot;693&quot; data-filename=&quot;02.PNG&quot; data-origin-width=&quot;1144&quot; data-origin-height=&quot;693&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;br /&gt;1.STM32에 LED 8개를 연결하고, LED를 1초 간격으로 On/Off를 반복하는데 HAL함수에서 토글시키는 함수를 이용해서 작동시키오!&lt;/p&gt;
&lt;pre id=&quot;code_1760521299052&quot; class=&quot;cpp&quot; data-ke-language=&quot;cpp&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;while (1)
 {
	//모든 LED가 토글 제어된다!
	  HAL_GPIO_TogglePin(GPIOB,GPIO_PIN_3); //PB3
	  HAL_GPIO_TogglePin(GPIOB,GPIO_PIN_13); //PB13
	  HAL_GPIO_TogglePin(GPIOB,GPIO_PIN_5); //PB5
	  HAL_GPIO_TogglePin(GPIOB,GPIO_PIN_14); //PB14
	  HAL_GPIO_TogglePin(GPIOB,GPIO_PIN_4); //PB4
	  HAL_GPIO_TogglePin(GPIOB,GPIO_PIN_15); //PB15
	  HAL_GPIO_TogglePin(GPIOC,GPIO_PIN_4); //PC4
	  HAL_GPIO_TogglePin(GPIOB,GPIO_PIN_7); //PB7
	//1초 쉰다
   HAL_Delay(1000);
   /* USER CODE END WHILE */
   /* USER CODE BEGIN 3 */
 }&lt;/code&gt;&lt;/pre&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/VTR5F/dJMb9Nu0ttt/7hG7eWuziAikkBkJ7rEv9K/ex1.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;ex1.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;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;2.홀수번쨰 LED와 짝수번째 LED가 서로 번갈아 가면서 토글제어 되도록 토글제어 함수를 이용해서 구현하시오!&lt;/p&gt;
&lt;pre id=&quot;code_1760521309657&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 */
 //짝수번째 LED를 켠상태로 출발한다!
 HAL_GPIO_WritePin(GPIOB,GPIO_PIN_13,GPIO_PIN_SET); //PB13
 HAL_GPIO_WritePin(GPIOB,GPIO_PIN_14,GPIO_PIN_SET); //PB14
 HAL_GPIO_WritePin(GPIOB,GPIO_PIN_15,GPIO_PIN_SET); //PB15
 HAL_GPIO_WritePin(GPIOB,GPIO_PIN_7,GPIO_PIN_SET); //PB7
 /* USER CODE END 2 */
 /* Infinite loop */
 /* USER CODE BEGIN WHILE */
 while (1)
 {
	//모든 LED가 토글 제어된다!
	  HAL_GPIO_TogglePin(GPIOB,GPIO_PIN_3); //PB3
	  HAL_GPIO_TogglePin(GPIOB,GPIO_PIN_13); //PB13
	  HAL_GPIO_TogglePin(GPIOB,GPIO_PIN_5); //PB5
	  HAL_GPIO_TogglePin(GPIOB,GPIO_PIN_14); //PB14
	  HAL_GPIO_TogglePin(GPIOB,GPIO_PIN_4); //PB4
	  HAL_GPIO_TogglePin(GPIOB,GPIO_PIN_15); //PB15
	  HAL_GPIO_TogglePin(GPIOC,GPIO_PIN_4); //PC4
	  HAL_GPIO_TogglePin(GPIOB,GPIO_PIN_7); //PB7
	//1초 쉰다
   HAL_Delay(1000);
   /* USER CODE END WHILE */
   /* USER CODE BEGIN 3 */
 }&lt;/code&gt;&lt;/pre&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/bpRkKN/dJMb9PM788N/yLefqbzDmKb5OINYYvJ7CK/ex2.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;ex2.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;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;3.LED1번을 시작으로 1초간격으로 LED8까지 시계방향으로 순차적으로 빙글빙글 돌면서 LED를 켜시오!(가장 허접한 방법) (깜빡하고 예제파일 저장을 안함)&lt;/p&gt;
&lt;pre id=&quot;code_1760521327567&quot; class=&quot;cpp&quot; data-ke-language=&quot;cpp&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;while (1)
 {
	//LED1만 ON, 나머지는 OFF
	HAL_GPIO_WritePin(GPIOB,GPIO_PIN_3,GPIO_PIN_SET); //PB3
	HAL_GPIO_WritePin(GPIOB,GPIO_PIN_13,GPIO_PIN_RESET); //PB13
	HAL_GPIO_WritePin(GPIOB,GPIO_PIN_5,GPIO_PIN_RESET); //PB5
	HAL_GPIO_WritePin(GPIOB,GPIO_PIN_14,GPIO_PIN_RESET); //PB14
	HAL_GPIO_WritePin(GPIOB,GPIO_PIN_4,GPIO_PIN_RESET); //PB4
	HAL_GPIO_WritePin(GPIOB,GPIO_PIN_15,GPIO_PIN_RESET); //PB15
	HAL_GPIO_WritePin(GPIOC,GPIO_PIN_4,GPIO_PIN_RESET); //PC4
	HAL_GPIO_WritePin(GPIOB,GPIO_PIN_7,GPIO_PIN_RESET); //PB7
	//1초 쉰다
   	HAL_Delay(1000);
 	  //LED2만 ON, 나머지는 OFF
	HAL_GPIO_WritePin(GPIOB,GPIO_PIN_3,GPIO_PIN_RESET); //PB3
	HAL_GPIO_WritePin(GPIOB,GPIO_PIN_13,GPIO_PIN_SET); //PB13
	HAL_GPIO_WritePin(GPIOB,GPIO_PIN_5,GPIO_PIN_RESET); //PB5
	HAL_GPIO_WritePin(GPIOB,GPIO_PIN_14,GPIO_PIN_RESET); //PB14
	HAL_GPIO_WritePin(GPIOB,GPIO_PIN_4,GPIO_PIN_RESET); //PB4
	HAL_GPIO_WritePin(GPIOB,GPIO_PIN_15,GPIO_PIN_RESET); //PB15
	HAL_GPIO_WritePin(GPIOC,GPIO_PIN_4,GPIO_PIN_RESET); //PC4
	HAL_GPIO_WritePin(GPIOB,GPIO_PIN_7,GPIO_PIN_RESET); //PB7
	//1초 쉰다
	HAL_Delay(1000);
	//LED3만 ON, 나머지는 OFF
	HAL_GPIO_WritePin(GPIOB,GPIO_PIN_3,GPIO_PIN_RESET); //PB3
	HAL_GPIO_WritePin(GPIOB,GPIO_PIN_13,GPIO_PIN_RESET); //PB13
	HAL_GPIO_WritePin(GPIOB,GPIO_PIN_5,GPIO_PIN_SET); //PB5
	HAL_GPIO_WritePin(GPIOB,GPIO_PIN_14,GPIO_PIN_RESET); //PB14
	HAL_GPIO_WritePin(GPIOB,GPIO_PIN_4,GPIO_PIN_RESET); //PB4
	HAL_GPIO_WritePin(GPIOB,GPIO_PIN_15,GPIO_PIN_RESET); //PB15
	HAL_GPIO_WritePin(GPIOC,GPIO_PIN_4,GPIO_PIN_RESET); //PC4
	HAL_GPIO_WritePin(GPIOB,GPIO_PIN_7,GPIO_PIN_RESET); //PB7
	//1초 쉰다
	HAL_Delay(1000);
	//LED4만 ON, 나머지는 OFF
	HAL_GPIO_WritePin(GPIOB,GPIO_PIN_3,GPIO_PIN_RESET); //PB3
	HAL_GPIO_WritePin(GPIOB,GPIO_PIN_13,GPIO_PIN_RESET); //PB13
	HAL_GPIO_WritePin(GPIOB,GPIO_PIN_5,GPIO_PIN_RESET); //PB5
	HAL_GPIO_WritePin(GPIOB,GPIO_PIN_14,GPIO_PIN_SET); //PB14
	HAL_GPIO_WritePin(GPIOB,GPIO_PIN_4,GPIO_PIN_RESET); //PB4
	HAL_GPIO_WritePin(GPIOB,GPIO_PIN_15,GPIO_PIN_RESET); //PB15
	HAL_GPIO_WritePin(GPIOC,GPIO_PIN_4,GPIO_PIN_RESET); //PC4
	HAL_GPIO_WritePin(GPIOB,GPIO_PIN_7,GPIO_PIN_RESET); //PB7
	//1초 쉰다
	HAL_Delay(1000);

	//LED5만 ON, 나머지는 OFF
	HAL_GPIO_WritePin(GPIOB,GPIO_PIN_3,GPIO_PIN_RESET); //PB3
	HAL_GPIO_WritePin(GPIOB,GPIO_PIN_13,GPIO_PIN_RESET); //PB13
	HAL_GPIO_WritePin(GPIOB,GPIO_PIN_5,GPIO_PIN_RESET); //PB5
	HAL_GPIO_WritePin(GPIOB,GPIO_PIN_14,GPIO_PIN_RESET); //PB14
	HAL_GPIO_WritePin(GPIOB,GPIO_PIN_4,GPIO_PIN_SET); //PB4
	HAL_GPIO_WritePin(GPIOB,GPIO_PIN_15,GPIO_PIN_RESET); //PB15
	HAL_GPIO_WritePin(GPIOC,GPIO_PIN_4,GPIO_PIN_RESET); //PC4
	HAL_GPIO_WritePin(GPIOB,GPIO_PIN_7,GPIO_PIN_RESET); //PB7
	//1초 쉰다
	HAL_Delay(1000);
	//LED6만 ON, 나머지는 OFF
	HAL_GPIO_WritePin(GPIOB,GPIO_PIN_3,GPIO_PIN_RESET); //PB3
	HAL_GPIO_WritePin(GPIOB,GPIO_PIN_13,GPIO_PIN_RESET); //PB13
	HAL_GPIO_WritePin(GPIOB,GPIO_PIN_5,GPIO_PIN_RESET); //PB5
	HAL_GPIO_WritePin(GPIOB,GPIO_PIN_14,GPIO_PIN_RESET); //PB14
	HAL_GPIO_WritePin(GPIOB,GPIO_PIN_4,GPIO_PIN_RESET); //PB4
	HAL_GPIO_WritePin(GPIOB,GPIO_PIN_15,GPIO_PIN_SET); //PB15
	HAL_GPIO_WritePin(GPIOC,GPIO_PIN_4,GPIO_PIN_RESET); //PC4
	HAL_GPIO_WritePin(GPIOB,GPIO_PIN_7,GPIO_PIN_RESET); //PB7
	//1초 쉰다
	HAL_Delay(1000);
	//LED7만 ON, 나머지는 OFF
	HAL_GPIO_WritePin(GPIOB,GPIO_PIN_3,GPIO_PIN_RESET); //PB3
	HAL_GPIO_WritePin(GPIOB,GPIO_PIN_13,GPIO_PIN_RESET); //PB13
	HAL_GPIO_WritePin(GPIOB,GPIO_PIN_5,GPIO_PIN_RESET); //PB5
	HAL_GPIO_WritePin(GPIOB,GPIO_PIN_14,GPIO_PIN_RESET); //PB14
	HAL_GPIO_WritePin(GPIOB,GPIO_PIN_4,GPIO_PIN_RESET); //PB4
	HAL_GPIO_WritePin(GPIOB,GPIO_PIN_15,GPIO_PIN_RESET); //PB15
	HAL_GPIO_WritePin(GPIOC,GPIO_PIN_4,GPIO_PIN_SET); //PC4
	HAL_GPIO_WritePin(GPIOB,GPIO_PIN_7,GPIO_PIN_RESET); //PB7
	//1초 쉰다
	HAL_Delay(1000);
	//LED8만 ON, 나머지는 OFF
	HAL_GPIO_WritePin(GPIOB,GPIO_PIN_3,GPIO_PIN_RESET); //PB3
	HAL_GPIO_WritePin(GPIOB,GPIO_PIN_13,GPIO_PIN_RESET); //PB13
	HAL_GPIO_WritePin(GPIOB,GPIO_PIN_5,GPIO_PIN_RESET); //PB5
	HAL_GPIO_WritePin(GPIOB,GPIO_PIN_14,GPIO_PIN_RESET); //PB14
	HAL_GPIO_WritePin(GPIOB,GPIO_PIN_4,GPIO_PIN_RESET); //PB4
	HAL_GPIO_WritePin(GPIOB,GPIO_PIN_15,GPIO_PIN_RESET); //PB15
	HAL_GPIO_WritePin(GPIOC,GPIO_PIN_4,GPIO_PIN_RESET); //PC4
	HAL_GPIO_WritePin(GPIOB,GPIO_PIN_7,GPIO_PIN_SET); //PB7
	//1초 쉰다
	HAL_Delay(1000);
   /* USER CODE END WHILE */
   /* USER CODE BEGIN 3 */
 }&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;br /&gt;&lt;span style=&quot;color: #333333; text-align: start;&quot;&gt;4.예제3을&amp;nbsp;for루프를&amp;nbsp;이용해서&amp;nbsp;아주&amp;nbsp;현명하게&amp;nbsp;해결해보시오!&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;color: #333333; text-align: start;&quot;&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;(깜빡하고 예제파일 저장을 안함)&lt;/span&gt;&lt;/p&gt;
&lt;pre id=&quot;code_1760521374128&quot; class=&quot;cpp&quot; data-ke-language=&quot;cpp&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;//포트그룹을 배열로 만드는데 8개니까 배열 8개 만들기~
 GPIO_TypeDef *mygroup[8];
 //핀번호가 8개니가 8개 만들기~
 uint16_t mypin[8];
 mygroup[0] = GPIOB;
 mygroup[1] = GPIOB;
 mygroup[2] = GPIOB;
 mygroup[3] = GPIOB;
 mygroup[4] = GPIOB;
 mygroup[5] = GPIOB;
 mygroup[6] = GPIOC;
 mygroup[7] = GPIOB;
 mypin[0] = GPIO_PIN_3;
 mypin[1] = GPIO_PIN_13;
 mypin[2] = GPIO_PIN_5;
 mypin[3] = GPIO_PIN_14;
 mypin[4] = GPIO_PIN_4;
 mypin[5] = GPIO_PIN_15;
 mypin[6] = GPIO_PIN_4;
 mypin[7] = GPIO_PIN_7;
 /* USER CODE END 2 */
 /* Infinite loop */

 /* USER CODE BEGIN WHILE */
 while (1)
 {
	//i는 현재 LED가 켜져야할 번호
	for(int i = 0; i&amp;lt;8 ; i++){
		//i가 0이라면 LED1면 켜져야 하는상황이고 현재 LED1은 배열의 번호가 0인 상황이다!
		//i가 1이라면 배열의 번호는 1인 녀석만 켜져야하고 나머지는 꺼져야한다!
		//i가 2이라면 배열 번호 2인 녀석이 켜져야한다
		//i가 j라면 배열번호 j인 녀석만 켜지고 나머지는 꺼져야한다!
		for(int j = 0;j&amp;lt;8;j++){
			if(i == j){
				HAL_GPIO_WritePin(mygroup[j],mypin[j],GPIO_PIN_SET);
			}else{
				HAL_GPIO_WritePin(mygroup[j],mypin[j],GPIO_PIN_RESET);
			}
		}
		HAL_Delay(1000);
	}
   /* USER CODE END WHILE */
   /* USER CODE BEGIN 3 */
 }&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;br /&gt;5.STM32에 붙어있는 버튼 1번을 누르면 LED 1번이 켜지고, 버튼 2번을 누르면 LED1번이 꺼지는 예제를 구현하시오!&lt;/p&gt;
&lt;pre id=&quot;code_1760521390327&quot; class=&quot;cpp&quot; data-ke-language=&quot;cpp&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;while (1)
 {
	//PB1을 누른게 감지된다면~
	if(HAL_GPIO_ReadPin(GPIOB,GPIO_PIN_1) == GPIO_PIN_RESET){
	   //PB3에 연결된 LED를 ON한다
	   HAL_GPIO_WritePin(GPIOB,GPIO_PIN_3,GPIO_PIN_SET);
	}
	//PA8을 누른게 감지된다면~
	if(HAL_GPIO_ReadPin(GPIOA,GPIO_PIN_8) == GPIO_PIN_RESET){
	   //PB3에 연결된 LED를 OFF한다
	   HAL_GPIO_WritePin(GPIOB,GPIO_PIN_3,GPIO_PIN_RESET);
	}
   /* USER CODE END WHILE */
   /* USER CODE BEGIN 3 */
 }&lt;/code&gt;&lt;/pre&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/Hos0S/dJMb9LKI85q/ZmCsw8qR7n1EZxQu9kfAQK/ex5.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;ex5.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;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;6.STM32에 버튼 8개를 다 연결하고, 버튼1을 누르면 LED1이 토글되고, 버튼2를 누르면 LED2가 토글되는 방식으로 순서대로 8개의 LED를 8개의 버튼으로 토글제어하시오!&lt;/p&gt;
&lt;pre id=&quot;code_1760521399530&quot; class=&quot;cpp&quot; data-ke-language=&quot;cpp&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;while (1)
 {
	//PB1/PB3, PA8/PB13, PB2/PB5, PB6/PB14, PC5/PB4, PC7/PB15, PA11/PC4, PA12/PB7
	if(HAL_GPIO_ReadPin(GPIOB,GPIO_PIN_1) == GPIO_PIN_RESET){
		HAL_GPIO_TogglePin(GPIOB,GPIO_PIN_3);
		HAL_Delay(200);//0.2초 동안의 스파크는 무시하겠다!
	}
	if(HAL_GPIO_ReadPin(GPIOA,GPIO_PIN_8) == GPIO_PIN_RESET){
		HAL_GPIO_TogglePin(GPIOB,GPIO_PIN_13);
		HAL_Delay(200);//0.2초 동안의 스파크는 무시하겠다!
	}
	if(HAL_GPIO_ReadPin(GPIOB,GPIO_PIN_2) == GPIO_PIN_RESET){
		HAL_GPIO_TogglePin(GPIOB,GPIO_PIN_5);
		HAL_Delay(200);//0.2초 동안의 스파크는 무시하겠다!
	}
	if(HAL_GPIO_ReadPin(GPIOB,GPIO_PIN_6) == GPIO_PIN_RESET){
		HAL_GPIO_TogglePin(GPIOB,GPIO_PIN_14);
		HAL_Delay(200);//0.2초 동안의 스파크는 무시하겠다!
	}
	if(HAL_GPIO_ReadPin(GPIOC,GPIO_PIN_5) == GPIO_PIN_RESET){
		HAL_GPIO_TogglePin(GPIOB,GPIO_PIN_4);
		HAL_Delay(200);//0.2초 동안의 스파크는 무시하겠다!
	}
	if(HAL_GPIO_ReadPin(GPIOC,GPIO_PIN_7) == GPIO_PIN_RESET){
		HAL_GPIO_TogglePin(GPIOB,GPIO_PIN_15);
		HAL_Delay(200);//0.2초 동안의 스파크는 무시하겠다!
	}
	if(HAL_GPIO_ReadPin(GPIOA,GPIO_PIN_11) == GPIO_PIN_RESET){
		HAL_GPIO_TogglePin(GPIOC,GPIO_PIN_4);
		HAL_Delay(200);//0.2초 동안의 스파크는 무시하겠다!
	}
	if(HAL_GPIO_ReadPin(GPIOA,GPIO_PIN_12) == GPIO_PIN_RESET){
		HAL_GPIO_TogglePin(GPIOB,GPIO_PIN_7);
		HAL_Delay(200);//0.2초 동안의 스파크는 무시하겠다!
	}
   /* USER CODE END WHILE */
   /* USER CODE BEGIN 3 */
 }&lt;/code&gt;&lt;/pre&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/uSA4A/dJMb9QkXZRi/s3nIyLbYg2RLk2Kk9zduKk/ex6.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;ex6.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;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;7.PB1에&amp;nbsp;연결된&amp;nbsp;버튼을&amp;nbsp;누를때마다&amp;nbsp;LED가&amp;nbsp;1번부터&amp;nbsp;8번방향으로&amp;nbsp;이동하고,&amp;nbsp;PA8에&amp;nbsp;연결된&amp;nbsp;버튼을&amp;nbsp;누르면&amp;nbsp;반대방향으로&amp;nbsp;LED를&amp;nbsp;켜지도록&amp;nbsp;하시오!&lt;/p&gt;
&lt;pre id=&quot;code_1760521421040&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 */
 //현재 켜져있어야할 LED의 번호
 int led_num = 0;
 //포트그룹을 배열로 만드는데 8개니까 배열 8개 만들기~
	GPIO_TypeDef *mygroup[8];
	//핀번호가 8개니가 8개 만들기~
	uint16_t mypin[8];
	mygroup[0] = GPIOB;
	mygroup[1] = GPIOB;
	mygroup[2] = GPIOB;
	mygroup[3] = GPIOB;
	mygroup[4] = GPIOB;
	mygroup[5] = GPIOB;
	mygroup[6] = GPIOC;
	mygroup[7] = GPIOB;
	mypin[0] = GPIO_PIN_3;
	mypin[1] = GPIO_PIN_13;
	mypin[2] = GPIO_PIN_5;
	mypin[3] = GPIO_PIN_14;
	mypin[4] = GPIO_PIN_4;
	mypin[5] = GPIO_PIN_15;
	mypin[6] = GPIO_PIN_4;
	mypin[7] = GPIO_PIN_7;
	//시작할때 LED1을 켜놓고 시작한다!
	HAL_GPIO_WritePin(mygroup[0],mypin[0],GPIO_PIN_SET);
 /* USER CODE END 2 */
 /* Infinite loop */
 /* USER CODE BEGIN WHILE */

 while (1)
 {
	//PB1을 누르면 LED가 시계방향으로 하나씩 켜진다
	if(HAL_GPIO_ReadPin(GPIOB,GPIO_PIN_1) == GPIO_PIN_RESET){
		led_num++;
		//led번호는 8번이 되면 0으로 초기화한다!
		if(led_num &amp;gt; 7){
			led_num = 0;
		}
		//LED1~LED8까지의 작동상태를 설정한다
		for(int i = 0;i&amp;lt;8;i++){
			//i와 led_num이 같은 녀석만 켜지고 나머지는 꺼진다
			if(i == led_num){
				//ON
				HAL_GPIO_WritePin(mygroup[i],mypin[i],GPIO_PIN_SET);
			}else{
				//OFF
				HAL_GPIO_WritePin(mygroup[i],mypin[i],GPIO_PIN_RESET);
			}
		}
		HAL_Delay(200);//0.2초 동안의 스파크는 무시하겠다!
	}
	//PA8을 누르면 LED가 반시계방향으로 하나씩 켜진다
	if(HAL_GPIO_ReadPin(GPIOA,GPIO_PIN_8) == GPIO_PIN_RESET){
		led_num--;
		//LED번호를 하나씩 내리다가 0이되면 제일 마지막번호인 7인된다
		if(led_num &amp;lt; 0){
			led_num = 7;
		}
		for(int i = 0;i&amp;lt;8;i++){
			//i와 led_num이 같은 녀석만 켜지고 나머지는 꺼진다
			if(i == led_num){
				//ON
				HAL_GPIO_WritePin(mygroup[i],mypin[i],GPIO_PIN_SET);
			}else{
				//OFF
				HAL_GPIO_WritePin(mygroup[i],mypin[i],GPIO_PIN_RESET);
			}
		}
		HAL_Delay(200);//0.2초 동안의 스파크는 무시하겠다!
	}
   /* USER CODE END WHILE */
   /* USER CODE BEGIN 3 */
 }&lt;/code&gt;&lt;/pre&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/cBGAfk/dJMb9eF5j0i/anO36S92N3CW7qx44CADG1/ex7.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;ex7.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>
      <author>덕력킹</author>
      <guid isPermaLink="true">https://bota.tistory.com/2444</guid>
      <comments>https://bota.tistory.com/2444#entry2444comment</comments>
      <pubDate>Wed, 15 Oct 2025 18:43:50 +0900</pubDate>
    </item>
    <item>
      <title>[STM32#01] STM32F103RB NUCLEO보드와 STM32CubeIDE를 이용해서 시작해보기!(녹칸다 내맘대로 STM32/튜토리얼)</title>
      <link>https://bota.tistory.com/2443</link>
      <description>&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;stm32.png&quot; data-origin-width=&quot;1920&quot; data-origin-height=&quot;1080&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/eaQHLR/btsQ8INLgAP/UrAFb8eaAQvqv88HdJrro0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/eaQHLR/btsQ8INLgAP/UrAFb8eaAQvqv88HdJrro0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/eaQHLR/btsQ8INLgAP/UrAFb8eaAQvqv88HdJrro0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FeaQHLR%2FbtsQ8INLgAP%2FUrAFb8eaAQvqv88HdJrro0%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;1920&quot; height=&quot;1080&quot; data-filename=&quot;stm32.png&quot; data-origin-width=&quot;1920&quot; data-origin-height=&quot;1080&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/live/ghofKLsPOV8&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://youtube.com/live/ghofKLsPOV8&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/watch?v=ghofKLsPOV8&quot; data-video-thumbnail=&quot;https://scrap.kakaocdn.net/dn/4xbAr/hyZLlWDUeJ/SBFap9ophR5q5KOqAlpFsK/img.jpg?width=1280&amp;amp;height=720&amp;amp;face=0_0_1280_720,https://scrap.kakaocdn.net/dn/ca2DL3/hyZLdK3Mji/L3S8HjzK57EM7sKnvKNoMK/img.jpg?width=1280&amp;amp;height=720&amp;amp;face=0_0_1280_720&quot; data-video-width=&quot;860&quot; data-video-height=&quot;484&quot; data-video-origin-width=&quot;860&quot; data-video-origin-height=&quot;484&quot; data-ke-mobilestyle=&quot;widthContent&quot; data-video-title=&quot;[STM32#01] STM32F103RB NUCLEO보드와 STM32CubeIDE를 이용해서 시작해보기!(녹칸다 내맘대로 STM32/튜토리얼)&quot; data-original-url=&quot;&quot;&gt;&lt;iframe src=&quot;https://www.youtube.com/embed/ghofKLsPOV8&quot; width=&quot;860&quot; height=&quot;484&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;[STM32#01]&amp;nbsp;STM32F103RB&amp;nbsp;NUCLEO보드와&amp;nbsp;STM32CubeIDE를&amp;nbsp;이용해서&amp;nbsp;시작해보기!(녹칸다&amp;nbsp;내맘대로&amp;nbsp;STM32/튜토리얼) &lt;br /&gt;&lt;br /&gt;심심한녹칸다의&amp;nbsp;내맘대로&amp;nbsp;STM32시리즈이다! &lt;br /&gt;&lt;br /&gt;STM32시리즈의&amp;nbsp;모든&amp;nbsp;자료는&amp;nbsp;구글&amp;nbsp;슬라이드에&amp;nbsp;작성하고&amp;nbsp;모두에게&amp;nbsp;공유되어있음! &lt;br /&gt;&lt;a href=&quot;https://docs.google.com/presentation/d/1myA5iYbjuKsLWLqtRLKAiRfwUwvqB1d1RGjiMIIgp3I/edit?slide=id.p#slide=id.p&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://docs.google.com/presentation/d/1myA5iYbjuKsLWLqtRLKAiRfwUwvqB1d1RGjiMIIgp3I/edit?slide=id.p#slide=id.p&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;STM32시리즈에서&amp;nbsp;사용하는&amp;nbsp;보조도구는&amp;nbsp;아래&amp;nbsp;녹칸다의&amp;nbsp;블로그에&amp;nbsp;거버파일과&amp;nbsp;BOM이&amp;nbsp;있음! &lt;br /&gt;&lt;a href=&quot;https://bota.tistory.com/2442&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://bota.tistory.com/2442&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;이번편은&amp;nbsp;녹칸다의&amp;nbsp;내맘대로&amp;nbsp;STM32시리즈의&amp;nbsp;시작하기&amp;nbsp;편으로&amp;nbsp;어떻게&amp;nbsp;시리즈를&amp;nbsp;이끌어&amp;nbsp;나갈지를&amp;nbsp;알아보도록&amp;nbsp;한다! &lt;br /&gt;그리고&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;한다!&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-filename=&quot;01.PNG&quot; data-origin-width=&quot;1163&quot; data-origin-height=&quot;540&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/kzuu2/btsQ5X6Kw3K/Xj3DKSf0vwoNFfWHWjxAXk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/kzuu2/btsQ5X6Kw3K/Xj3DKSf0vwoNFfWHWjxAXk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/kzuu2/btsQ5X6Kw3K/Xj3DKSf0vwoNFfWHWjxAXk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fkzuu2%2FbtsQ5X6Kw3K%2FXj3DKSf0vwoNFfWHWjxAXk%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;1163&quot; height=&quot;540&quot; data-filename=&quot;01.PNG&quot; data-origin-width=&quot;1163&quot; data-origin-height=&quot;540&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&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;01.PNG&quot; data-origin-width=&quot;1242&quot; data-origin-height=&quot;666&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bRaxUz/btsQ9VAZte9/mnPobWWfwH6k0PaMrtydPK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bRaxUz/btsQ9VAZte9/mnPobWWfwH6k0PaMrtydPK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bRaxUz/btsQ9VAZte9/mnPobWWfwH6k0PaMrtydPK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbRaxUz%2FbtsQ9VAZte9%2FmnPobWWfwH6k0PaMrtydPK%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;1242&quot; height=&quot;666&quot; data-filename=&quot;01.PNG&quot; data-origin-width=&quot;1242&quot; data-origin-height=&quot;666&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;br /&gt;1.STM32의 작동이 되는지 테스트 하기 위해서 LED를 1개 1초 간격으로 ON/OFF하는 예제를 구현하시오!&lt;/p&gt;
&lt;pre id=&quot;code_1760364773083&quot; class=&quot;cpp&quot; data-ke-language=&quot;cpp&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;while (1)
 {
	  //PB3 ON
	  HAL_GPIO_WritePin(GPIOB,GPIO_PIN_3,GPIO_PIN_SET); //ON
	  //1000ms delay
	  HAL_Delay(1000);
	  //PB3 OFF
	  HAL_GPIO_WritePin(GPIOB,GPIO_PIN_3,GPIO_PIN_RESET);  //OFF
	  //1000ms delay
	  HAL_Delay(1000);
	 
   /* USER CODE END WHILE */
   /* USER CODE BEGIN 3 */
 }&lt;/code&gt;&lt;/pre&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/cGLPci/dJMb862lSzC/hW91bd8k4YSSU9UVmnuWR0/ex1.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;ex1.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;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;2.IOC에서 PB3핀을 LED1이라는 별명을 붙혀서 예제 1과 동일하게 제어해보시오!&lt;/p&gt;
&lt;pre id=&quot;code_1760364822740&quot; class=&quot;cpp&quot; data-ke-language=&quot;cpp&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;while (1)
 {
	  //PB3 ON
	  HAL_GPIO_WritePin(LED1_GPIO_Port,LED1_Pin,GPIO_PIN_SET); //ON
	  //1000ms delay
	  HAL_Delay(1000);
	  //PB3 OFF
	  HAL_GPIO_WritePin(LED1_GPIO_Port,LED1_Pin,GPIO_PIN_RESET);  //OFF
	  //1000ms delay
	  HAL_Delay(1000);
   /* USER CODE END WHILE */
   /* USER CODE BEGIN 3 */
 }&lt;/code&gt;&lt;/pre&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/5v0ns/dJMb9aXY2qM/Aag1Eez8fCvxkS1DOkbqKK/ex2.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;ex2.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;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;3.녹칸다가 달아놓은 8개의 LED를 1초 간격으로 모두 ON/OFF하시오!&lt;/p&gt;
&lt;pre id=&quot;code_1760364834537&quot; class=&quot;cpp&quot; data-ke-language=&quot;cpp&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;while (1)
 {
	  //ALL ON
	  HAL_GPIO_WritePin(LED1_GPIO_Port,LED1_Pin,GPIO_PIN_SET); //ON
	  HAL_GPIO_WritePin(LED2_GPIO_Port,LED2_Pin,GPIO_PIN_SET); //ON
	  HAL_GPIO_WritePin(LED3_GPIO_Port,LED3_Pin,GPIO_PIN_SET); //ON
	  HAL_GPIO_WritePin(LED4_GPIO_Port,LED4_Pin,GPIO_PIN_SET); //ON
	  HAL_GPIO_WritePin(LED5_GPIO_Port,LED5_Pin,GPIO_PIN_SET); //ON
	  HAL_GPIO_WritePin(LED6_GPIO_Port,LED6_Pin,GPIO_PIN_SET); //ON
	  HAL_GPIO_WritePin(LED7_GPIO_Port,LED7_Pin,GPIO_PIN_SET); //ON
	  HAL_GPIO_WritePin(LED8_GPIO_Port,LED8_Pin,GPIO_PIN_SET); //ON
	  //1000ms delay
	  HAL_Delay(1000);
	  //ALL OFF
	  HAL_GPIO_WritePin(LED1_GPIO_Port,LED1_Pin,GPIO_PIN_RESET); //ON
	  HAL_GPIO_WritePin(LED2_GPIO_Port,LED2_Pin,GPIO_PIN_RESET); //ON
	  HAL_GPIO_WritePin(LED3_GPIO_Port,LED3_Pin,GPIO_PIN_RESET); //ON
	  HAL_GPIO_WritePin(LED4_GPIO_Port,LED4_Pin,GPIO_PIN_RESET); //ON
	  HAL_GPIO_WritePin(LED5_GPIO_Port,LED5_Pin,GPIO_PIN_RESET); //ON
	  HAL_GPIO_WritePin(LED6_GPIO_Port,LED6_Pin,GPIO_PIN_RESET); //ON
	  HAL_GPIO_WritePin(LED7_GPIO_Port,LED7_Pin,GPIO_PIN_RESET); //ON
	  HAL_GPIO_WritePin(LED8_GPIO_Port,LED8_Pin,GPIO_PIN_RESET); //ON
	  //1000ms delay
	  HAL_Delay(1000);
   /* USER CODE END WHILE */
   /* USER CODE BEGIN 3 */
 }&lt;/code&gt;&lt;/pre&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/7xX1S/dJMb9XqMOsM/CgHmUd75F20NkqaP33MXu1/ex3.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;ex3.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;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;4.LED가&amp;nbsp;8개&amp;nbsp;있는데,&amp;nbsp;극단적으로&amp;nbsp;1000개쯤&amp;nbsp;된다고&amp;nbsp;하면&amp;nbsp;관리하기가&amp;nbsp;상당히&amp;nbsp;어렵겠지?&amp;nbsp;그러면&amp;nbsp;일괄적으로&amp;nbsp;동시에&amp;nbsp;ON/OFF하려면&amp;nbsp;어떻게&amp;nbsp;하면&amp;nbsp;좋을까?(반복문)&lt;/p&gt;
&lt;pre id=&quot;code_1760364847702&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 */
 GPIO_TypeDef *Nockanda_port[] = {LED1_GPIO_Port,LED2_GPIO_Port,LED3_GPIO_Port,LED4_GPIO_Port,LED5_GPIO_Port,LED6_GPIO_Port,LED7_GPIO_Port,LED8_GPIO_Port};
 uint16_t Nockanda_pin[] = {LED1_Pin,LED2_Pin,LED3_Pin,LED4_Pin,LED5_Pin,LED6_Pin,LED7_Pin,LED8_Pin};
 /* USER CODE END 2 */
 /* Infinite loop */
 /* USER CODE BEGIN WHILE */
 while (1)
 {
	  //ALL ON
	  for(int i = 0;i&amp;lt;8;i++){
		  HAL_GPIO_WritePin(Nockanda_port[i],Nockanda_pin[i],GPIO_PIN_SET); //ON
	  }
	  //1000ms delay
	  HAL_Delay(1000);
	  //ALL OFF
	  for(int i = 0;i&amp;lt;8;i++){
		  HAL_GPIO_WritePin(Nockanda_port[i],Nockanda_pin[i],GPIO_PIN_RESET); //OFF
	  }
	  //1000ms delay
	  HAL_Delay(1000);
   /* USER CODE END WHILE */
   /* USER CODE BEGIN 3 */
 }&lt;/code&gt;&lt;/pre&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/c2Jn5j/dJMb9fdVa5F/ckbOUZfPjCjv8QWpmDNkPk/ex4.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;ex4.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>
      <author>덕력킹</author>
      <guid isPermaLink="true">https://bota.tistory.com/2443</guid>
      <comments>https://bota.tistory.com/2443#entry2443comment</comments>
      <pubDate>Mon, 13 Oct 2025 23:14:14 +0900</pubDate>
    </item>
  </channel>
</rss>