<?xml version="1.0" encoding="utf-8"?><rss xmlns:dc="http://purl.org/dc/elements/1.1/" version="2.0"><channel><title>浪人栖 | 笔记</title><link>https://sblog.kdrnn.online/</link><description>Ronin's Residence</description><item><title>三极管 - 数据手册核心参数</title><link>https://sblog.kdrnn.online/?id=7</link><description>&lt;h2&gt;&lt;span style=&quot;font-size: 24px;&quot;&gt;极限参数 | Maximum Ratings&lt;/span&gt;&lt;/h2&gt;&lt;p&gt;&lt;span style=&quot;font-family: 微软雅黑, &amp;quot;Microsoft YaHei&amp;quot;; font-size: 16px;&quot;&gt;&lt;span style=&quot;font-family: 微软雅黑, &amp;quot;Microsoft YaHei&amp;quot;; margin: 0px; padding: 0px; border: 0px; font-variant-numeric: inherit; font-variant-east-asian: inherit; font-variant-alternates: inherit; font-variant-position: inherit; font-variant-emoji: inherit; font-weight: 600; font-stretch: inherit; line-height: inherit; font-optical-sizing: inherit; font-size-adjust: inherit; font-kerning: inherit; font-feature-settings: inherit; font-variation-settings: inherit; font-language-override: inherit; vertical-align: baseline; white-space: break-spaces; background-color: #FFFFFF;&quot;&gt;集电极-发射极电压 | Collector-Emitter Voltage | V&lt;/span&gt;&lt;sub&gt;&lt;span style=&quot;font-family: 微软雅黑, &amp;quot;Microsoft YaHei&amp;quot;; margin: 0px; padding: 0px; border: 0px; font-variant-numeric: inherit; font-variant-east-asian: inherit; font-variant-alternates: inherit; font-variant-position: inherit; font-variant-emoji: inherit; font-weight: 600; font-stretch: inherit; line-height: inherit; font-optical-sizing: inherit; font-size-adjust: inherit; font-kerning: inherit; font-feature-settings: inherit; font-variation-settings: inherit; font-language-override: inherit; vertical-align: baseline; white-space: break-spaces; background-color: #FFFFFF;&quot;&gt;CEO&lt;/span&gt;&lt;/sub&gt;&lt;span style=&quot;font-family: 微软雅黑, &amp;quot;Microsoft YaHei&amp;quot;; margin: 0px; padding: 0px; border: 0px; font-variant-numeric: inherit; font-variant-east-asian: inherit; font-variant-alternates: inherit; font-variant-position: inherit; font-variant-emoji: inherit; font-weight: 600; font-stretch: inherit; line-height: inherit; font-optical-sizing: inherit; font-size-adjust: inherit; font-kerning: inherit; font-feature-settings: inherit; font-variation-settings: inherit; font-language-override: inherit; vertical-align: baseline; white-space: break-spaces; background-color: #FFFFFF;&quot;&gt;：工作电压必须（远）低于此值；&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style=&quot;margin: 0px; padding: 0px; border: 0px; font-variant-numeric: inherit; font-variant-east-asian: inherit; font-variant-alternates: inherit; font-variant-position: inherit; font-variant-emoji: inherit; font-weight: 600; font-stretch: inherit; line-height: inherit; font-optical-sizing: inherit; font-size-adjust: inherit; font-kerning: inherit; font-feature-settings: inherit; font-variation-settings: inherit; font-language-override: inherit; vertical-align: baseline; white-space: break-spaces; background-color: #FFFFFF; font-family: 微软雅黑, &amp;quot;Microsoft YaHei&amp;quot;; font-size: 16px;&quot;&gt;集电极电流 | Collector Current | I&lt;sub&gt;C&lt;/sub&gt;：负载电流要在此范围内；&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style=&quot;margin: 0px; padding: 0px; border: 0px; font-variant-numeric: inherit; font-variant-east-asian: inherit; font-variant-alternates: inherit; font-variant-position: inherit; font-variant-emoji: inherit; font-weight: 600; font-stretch: inherit; line-height: inherit; font-optical-sizing: inherit; font-size-adjust: inherit; font-kerning: inherit; font-feature-settings: inherit; font-variation-settings: inherit; font-language-override: inherit; vertical-align: baseline; white-space: break-spaces; background-color: #FFFFFF; font-family: 微软雅黑, &amp;quot;Microsoft YaHei&amp;quot;; font-size: 16px;&quot;&gt;集电极功耗 | Collector Power Dissipation | P&lt;sub&gt;C&lt;/sub&gt;：计算实际功耗(Ic×Vce)不能超过此值。&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;h2 style=&quot;margin: 1.75rem 0px 0.9375rem; padding: 0px; border: 0px; font-variant-numeric: normal; font-variant-east-asian: normal; font-variant-alternates: normal; font-size-adjust: none; font-language-override: normal; font-kerning: auto; font-optical-sizing: auto; font-feature-settings: normal; font-variation-settings: normal; font-variant-position: normal; font-variant-emoji: normal; font-stretch: normal; font-size: 1rem; line-height: 1.2; font-family: -apple-system, BlinkMacSystemFont, &amp;quot;Segoe UI&amp;quot;, &amp;quot;PingFang SC&amp;quot;, Roboto, Ubuntu, &amp;quot;Helvetica Neue&amp;quot;, Helvetica, Arial, &amp;quot;Hiragino Sans GB&amp;quot;, &amp;quot;Microsoft YaHei UI&amp;quot;, &amp;quot;Microsoft YaHei&amp;quot;, &amp;quot;Source Han Sans CN&amp;quot;, sans-serif; vertical-align: baseline; text-wrap-mode: wrap; background-color: rgb(255, 255, 255);&quot;&gt;&lt;span style=&quot;margin: 0px; padding: 0px; border: 0px; font-style: inherit; font-variant: inherit; font-stretch: inherit; line-height: inherit; font-optical-sizing: inherit; font-size-adjust: inherit; font-kerning: inherit; font-feature-settings: inherit; font-variation-settings: inherit; font-language-override: inherit; vertical-align: baseline; font-family: 微软雅黑, &amp;quot;Microsoft YaHei&amp;quot;; font-size: 24px;&quot;&gt;电气特性 | Electrical Characteristics&lt;/span&gt;&lt;/h2&gt;&lt;p&gt;&lt;span style=&quot;margin: 0px; padding: 0px; border: 0px; font-style: inherit; font-variant: inherit; font-stretch: inherit; line-height: inherit; font-optical-sizing: inherit; font-size-adjust: inherit; font-kerning: inherit; font-feature-settings: inherit; font-variation-settings: inherit; font-language-override: inherit; vertical-align: baseline; font-family: 微软雅黑, &amp;quot;Microsoft YaHei&amp;quot;; font-size: 16px;&quot;&gt;&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style=&quot;margin: 0px; padding: 0px; border: 0px; font-style: inherit; font-variant: inherit; font-stretch: inherit; line-height: inherit; font-optical-sizing: inherit; font-size-adjust: inherit; font-kerning: inherit; font-feature-settings: inherit; font-variation-settings: inherit; font-language-override: inherit; vertical-align: baseline; font-family: 微软雅黑, &amp;quot;Microsoft YaHei&amp;quot;; font-size: 16px;&quot;&gt;懒了，待补充&lt;/span&gt;&lt;/p&gt;</description><pubDate>Tue, 20 Jan 2026 06:06:39 +0800</pubDate></item><item><title>练习 - 二路温湿度传感器及自动报警加热</title><link>https://sblog.kdrnn.online/?id=6</link><description>&lt;h1&gt;实现功能&lt;/h1&gt;&lt;p&gt;&lt;span style=&quot;text-wrap-mode: nowrap;&quot;&gt;板上有两路温湿度传感器，用来检测不同位置的环境温湿度；&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style=&quot;text-wrap-mode: nowrap;&quot;&gt;板上有两组三位一体数码管用于显示温度和湿度，两路传感器每隔 2s 交替显示温湿度；&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style=&quot;text-wrap-mode: nowrap;&quot;&gt;每路传感器对应一块加热器，当环境湿度大于设置的湿度起动阈值时，打开对应加热器，低于设置的湿度截止阈值或高于设置的高温阈值时退出加热模式；&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style=&quot;text-wrap-mode: nowrap;&quot;&gt;当：&lt;/span&gt;&lt;/p&gt;&lt;ol class=&quot; list-paddingleft-2&quot; style=&quot;list-style-type: decimal;&quot;&gt;&lt;li&gt;&lt;p&gt;&lt;span style=&quot;text-wrap-mode: nowrap;&quot;&gt;有传感器湿度高于起动阈值后未降低至截止阈值，此时传感器温度均低于高温阈值；&lt;/span&gt;&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;&lt;span style=&quot;text-wrap-mode: nowrap;&quot;&gt;有传感器湿度高于起动阈值后未降低至截止阈值，此时有传感器温度高于高温阈值；&lt;/span&gt;&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;&lt;span style=&quot;text-wrap-mode: nowrap;&quot;&gt;传感器湿度均低于截止阈值，此时有传感器温度高于高温阈值。&lt;/span&gt;&lt;/p&gt;&lt;/li&gt;&lt;/ol&gt;&lt;p&gt;&lt;span style=&quot;text-wrap-mode: nowrap;&quot;&gt;为以上每种情况配置不同频率的报警频率；&amp;nbsp;&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style=&quot;text-wrap-mode: nowrap;&quot;&gt;湿度启动阈值/湿度截止阈值/高温阈值通过自拟协议实现上位机修改，并每隔2s将二路传感器的温湿度数据上报给上位机；&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style=&quot;text-wrap-mode: nowrap;&quot;&gt;设置6路开关量输入接口，当开关量有输入时，板上有对应LED亮灯反馈。&lt;/span&gt;&lt;/p&gt;&lt;h1&gt;硬件设计&lt;/h1&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p class=&quot;ue-upload&quot; style=&quot;line-height: 16px;&quot;&gt;&lt;img style=&quot;vertical-align: middle; margin-right: 2px;&quot; src=&quot;https://sblog.kdrnn.online/zb_system/image/filetype/pdf.png&quot;/&gt;&lt;a style=&quot;font-size:12px; color:#0066cc;&quot; href=&quot;https://sblog.kdrnn.online/zb_users/upload/2025/12/202512131765612864620847.pdf&quot; title=&quot;SCH_P1_2_2025-12-13.pdf&quot;&gt;SCH_P1_2_2025-12-13.pdf&lt;/a&gt;&lt;/p&gt;&lt;h2 style=&quot;line-height: 16px;&quot;&gt;电源模块&lt;/h2&gt;&lt;p&gt;选用AC-DC电源模块HLK-PM01NBX，依照数据手册设置EMC解决方案电路。&lt;/p&gt;&lt;h2&gt;隔离电源模块&lt;br/&gt;&lt;/h2&gt;&lt;p&gt;选用B0505S-1W隔离电源模块，依照数据手册设置纹波噪音严格方案线路。&lt;/p&gt;&lt;h2&gt;MCU&lt;br/&gt;&lt;/h2&gt;&lt;p&gt;选用STC89C52RC-40I-LQFP44，输&lt;span style=&quot;text-wrap-mode: wrap;&quot;&gt;入+5V；&lt;/span&gt;&lt;/p&gt;&lt;p&gt;VCC引脚处选用一个100nF去耦电容与一个10μF滤波电容；&lt;br/&gt;&lt;/p&gt;&lt;p&gt;复位引脚采用：+5V ---&amp;gt; 10μF电解电容/常开按钮 ---&amp;gt; RST ---&amp;gt; 10kΩ电阻 ---&amp;gt; GND，确保可靠高电平复位；&lt;br/&gt;&lt;/p&gt;&lt;p&gt;外接晶振选用11.0592MHz频率，配备2*47pF电容。&lt;/p&gt;&lt;h2&gt;报警模块&lt;br/&gt;&lt;/h2&gt;&lt;p&gt;选用2.4kHz有源蜂鸣器，并联整流二极管用以控制反向电动势（设计选用M7，实际选用M1），&lt;/p&gt;&lt;p&gt;单片机P42引脚接三极管MMBT3904-E基极控制蜂鸣器电路通断；&lt;br/&gt;&lt;/p&gt;&lt;p&gt;两个LED为共阴极设计，接单片机P20/P21。&lt;/p&gt;&lt;h2&gt;数码管&lt;br/&gt;&lt;/h2&gt;&lt;p&gt;使用P00-P07配合SN74HC245D段选，P15-P17配合SN74HC138DR位选，P0口根据数据手册特性说明，外接10kΩ上拉电阻；&lt;/p&gt;&lt;p&gt;&lt;span style=&quot;text-wrap-mode: wrap;&quot;&gt;由数据手册，SN74HC138DR的G1接高电平，G2A#/G2B#接低电平时有效；&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style=&quot;text-wrap-mode: wrap;&quot;&gt;因为数码管为6位，而138可输出Y0-Y7八位，此处接Y0-Y5，Y6/Y7悬空；&lt;br/&gt;&lt;/span&gt;&lt;/p&gt;&lt;p&gt;因为&lt;span style=&quot;text-wrap-mode: wrap;&quot;&gt;SN74HC245D的Ax接单片机P0x，Bx接数码管A-DP，需要：Ax输入，Bx=Ax。根据数据手册，配置OE(输出使能输入)引脚低电平，DIR(传输方向控制)引脚高电平;&lt;/span&gt;&lt;/p&gt;&lt;h2&gt;&lt;span style=&quot;text-wrap-mode: wrap;&quot;&gt;六路开关量输入&lt;br/&gt;&lt;/span&gt;&lt;/h2&gt;&lt;p&gt;使用EL817C光电耦合器进行电气隔离，发射端接入隔离电源并设置一个2*6的12P排针作为外部开关量输入接口控制光耦发射端通断；&lt;/p&gt;&lt;p&gt;接收端集电极分别接单片机P22-P27引脚并接+5V上拉，发射极接地；&lt;br/&gt;&lt;/p&gt;&lt;p&gt;简单设置P32-P37引脚控制六个LED用以反馈外部开关量状态。&lt;br/&gt;&lt;/p&gt;&lt;h2&gt;IIC硬件&lt;br/&gt;&lt;/h2&gt;&lt;p&gt;IIC硬件总共使用：一个EEPROM，两个AM2301B温湿度传感器。&lt;/p&gt;&lt;p&gt;AM2301B传感器地址唯一且固定，所以选用了TCA9548APWR作为多路IIC开关；&lt;/p&gt;&lt;p&gt;&lt;span style=&quot;text-wrap-mode: wrap;&quot;&gt;EEPROM选用&lt;/span&gt;&lt;span style=&quot;text-wrap-mode: wrap;&quot;&gt;M24C64-RMN6TP，WC写入控制脚接P13；&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style=&quot;text-wrap-mode: wrap;&quot;&gt;TCA9548APWR的RESET引脚接P12；&lt;/span&gt;&lt;/p&gt;&lt;p&gt;因为STC89C52RC没有IIC模块，所以选用P40做SDA，P41做SCL，使用软件模拟IIC信号进行通讯，&lt;/p&gt;&lt;p&gt;P40/P41接EEPROM以及&lt;span style=&quot;text-wrap-mode: wrap;&quot;&gt;TCA9548APWR，&lt;span style=&quot;text-wrap-mode: wrap;&quot;&gt;TCA9548APWR的SC7/SD7和SC6/SD6接两排4P端子用以外接AM2301B。&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;</description><pubDate>Sat, 13 Dec 2025 15:19:41 +0800</pubDate></item><item><title>51单片机 | IIC | 软件模拟 | 基础驱动</title><link>https://sblog.kdrnn.online/?id=5</link><description>&lt;p&gt;在Dri_IIC中先定义SCL和SDA：&lt;/p&gt;&lt;pre class=&quot;prism-highlight prism-language-c&quot;&gt;#define&amp;nbsp;SCL&amp;nbsp;P17
#define&amp;nbsp;SDA&amp;nbsp;P16&lt;/pre&gt;&lt;h3&gt;1.初始化/开始信号&lt;/h3&gt;&lt;p&gt;当SCL高电平时，SDA由高电平变为低电平，视为起始信号。&lt;/p&gt;&lt;p&gt;所以SCL与SDA要设置初始状态为高电平：&lt;/p&gt;&lt;pre class=&quot;prism-highlight prism-language-c&quot;&gt;SCL&amp;nbsp;=&amp;nbsp;1;
SDA&amp;nbsp;=&amp;nbsp;1;&lt;/pre&gt;&lt;p&gt;此时SDA变为低电平，发出起始信号，然后SCL置为低电平，等待数据位：&lt;/p&gt;&lt;pre class=&quot;prism-highlight prism-language-c&quot;&gt;SDA&amp;nbsp;=&amp;nbsp;0;
SCL&amp;nbsp;=&amp;nbsp;0;&lt;/pre&gt;&lt;p&gt;起始阶段结束，完整代码：&lt;/p&gt;&lt;pre class=&quot;prism-highlight prism-language-c&quot;&gt;void&amp;nbsp;Dri_IIC_Start()
{
&amp;nbsp;&amp;nbsp;SCL&amp;nbsp;=&amp;nbsp;1;
&amp;nbsp;&amp;nbsp;SDA&amp;nbsp;=&amp;nbsp;1;
&amp;nbsp;&amp;nbsp;SDA&amp;nbsp;=&amp;nbsp;0;
&amp;nbsp;&amp;nbsp;SCL&amp;nbsp;=&amp;nbsp;0;
}&lt;/pre&gt;&lt;h3&gt;2.发送数据&lt;/h3&gt;&lt;p&gt;IIC协议在SCL位于高电平时读取SDA，故要先设定好SDA，再将SCL置为高电平，&lt;br/&gt;&lt;/p&gt;&lt;p&gt;SCL高电平期间稳定SDA，随后将SCL设低电平，流程逻辑：&lt;br/&gt;&lt;/p&gt;&lt;pre class=&quot;prism-highlight prism-language-c&quot;&gt;SDA&amp;nbsp;=&amp;nbsp;data;
SCL&amp;nbsp;=&amp;nbsp;1;
SCL&amp;nbsp;=&amp;nbsp;0;&lt;/pre&gt;&lt;p&gt;要发送八位数据（一字节），可使用&lt;/p&gt;&lt;pre class=&quot;prism-highlight prism-language-c&quot;&gt;for&amp;nbsp;(i&amp;nbsp;=&amp;nbsp;0;&amp;nbsp;i&amp;nbsp;&amp;lt;&amp;nbsp;8;&amp;nbsp;i++)&lt;/pre&gt;&lt;p&gt;来进行八次扫描。&lt;/p&gt;&lt;p&gt;因为数据从高位起始，利用 1000 0000 右移 i 位并和byte进行与运算，对结果进行判断并填充SDA：&lt;/p&gt;&lt;pre class=&quot;prism-highlight prism-language-c&quot;&gt;SDA&amp;nbsp;=&amp;nbsp;(byte&amp;nbsp;&amp;amp;&amp;nbsp;(0x80&amp;nbsp;&amp;gt;&amp;gt;&amp;nbsp;i))&amp;nbsp;==&amp;nbsp;0&amp;nbsp;?&amp;nbsp;0&amp;nbsp;:&amp;nbsp;1;&lt;/pre&gt;&lt;p&gt;完整代码：&lt;/p&gt;&lt;pre class=&quot;prism-highlight prism-language-c&quot;&gt;void&amp;nbsp;Dri_IIC_SendByte(unsigned&amp;nbsp;char&amp;nbsp;byte)
{
&amp;nbsp;&amp;nbsp;unsigned&amp;nbsp;char&amp;nbsp;i;
&amp;nbsp;&amp;nbsp;for&amp;nbsp;(i&amp;nbsp;=&amp;nbsp;0;&amp;nbsp;i&amp;nbsp;&amp;lt;&amp;nbsp;8;&amp;nbsp;i++){
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;SDA&amp;nbsp;=&amp;nbsp;(byte&amp;nbsp;&amp;amp;&amp;nbsp;(0x80&amp;nbsp;&amp;gt;&amp;gt;&amp;nbsp;i))&amp;nbsp;==&amp;nbsp;0&amp;nbsp;?&amp;nbsp;0&amp;nbsp;:&amp;nbsp;1;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;SCL&amp;nbsp;=&amp;nbsp;1;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;SCL&amp;nbsp;=&amp;nbsp;0;
&amp;nbsp;&amp;nbsp;}
}&lt;/pre&gt;&lt;h3&gt;3.接收确认位&lt;/h3&gt;&lt;p&gt;IIC所有设备引脚以开漏模式接入总线，故要在数据传输完毕后释放SDA，使从机可以操纵SDA电平：&lt;br/&gt;&lt;/p&gt;&lt;pre class=&quot;prism-highlight prism-language-c&quot;&gt;SDA&amp;nbsp;=&amp;nbsp;1;&lt;/pre&gt;&lt;p&gt;释放SDA后，SCL置为低电平，供SDA调整，随后SCL需位于高电平读取确认位后回到低电平。&lt;/p&gt;&lt;p&gt;完整代码：&lt;/p&gt;&lt;pre class=&quot;prism-highlight prism-language-c&quot;&gt;bit&amp;nbsp;Dri_IIC_ReceiveAck()
{
&amp;nbsp;&amp;nbsp;bit&amp;nbsp;ack;
&amp;nbsp;&amp;nbsp;SDA&amp;nbsp;=&amp;nbsp;1;
&amp;nbsp;&amp;nbsp;SCL&amp;nbsp;=&amp;nbsp;1;
&amp;nbsp;&amp;nbsp;ack&amp;nbsp;=&amp;nbsp;SDA;
&amp;nbsp;&amp;nbsp;SCL&amp;nbsp;=&amp;nbsp;0;
&amp;nbsp;&amp;nbsp;return&amp;nbsp;ack;
}&lt;/pre&gt;&lt;h3&gt;4.接收数据&lt;/h3&gt;&lt;p&gt;只需要先准备SDA，再将SCL置高电平读取即可。&lt;/p&gt;&lt;p&gt;完整代码：&lt;/p&gt;&lt;pre class=&quot;prism-highlight prism-language-c&quot;&gt;void&amp;nbsp;Dri_IIC_SendAck(bit&amp;nbsp;ack)
{
&amp;nbsp;&amp;nbsp;SDA&amp;nbsp;=&amp;nbsp;ack;
&amp;nbsp;&amp;nbsp;SCL&amp;nbsp;=&amp;nbsp;1;
&amp;nbsp;&amp;nbsp;SCL&amp;nbsp;=&amp;nbsp;0;
}&lt;/pre&gt;&lt;h3&gt;5.结束信号&lt;br/&gt;&lt;/h3&gt;&lt;p&gt;在SCL高电平期间，若SDA拉高，视为结束信号，所以此时所需初始值SDA/SCL均为低电平。&lt;/p&gt;&lt;p&gt;因为无法确定SDA当前电位，所以在拉高SCL前先拉低SDA，避免SCL置为高电平后SDA降低而误发送起始信号。&lt;br/&gt;&lt;/p&gt;&lt;p&gt;完整代码：&lt;/p&gt;&lt;pre class=&quot;prism-highlight prism-language-c&quot;&gt;void&amp;nbsp;Dri_IIC_Stop()
{
&amp;nbsp;&amp;nbsp;SDA&amp;nbsp;=&amp;nbsp;0;
&amp;nbsp;&amp;nbsp;SCL&amp;nbsp;=&amp;nbsp;1;
&amp;nbsp;&amp;nbsp;SDA&amp;nbsp;=&amp;nbsp;1;
}&lt;/pre&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;</description><pubDate>Sat, 30 Aug 2025 06:58:39 +0800</pubDate></item><item><title>IIC总线</title><link>https://sblog.kdrnn.online/?id=4</link><description>&lt;h3&gt;From &lt;a href=&quot;https://www.bilibili.com/video/BV139sSe7E2K?spm_id_from=333.788.player.switch&amp;vd_source=d224a2ea6ff02a271ec9d90c245a80b6&amp;p=113&quot; target=&quot;_blank&quot; textvalue=&quot;尚硅谷&quot;&gt;尚硅谷&lt;/a&gt;&lt;/h3&gt;&lt;h3&gt;1.1 &lt;span style=&quot;font-family: 黑体;&quot;&gt;概述&lt;/span&gt;&lt;/h3&gt;&lt;p&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;I&lt;sup&gt;2&lt;/sup&gt;C&lt;span style=&quot;font-family: 宋体&quot;&gt;（&lt;/span&gt;Inter-Integrated Circuit&lt;span style=&quot;font-family:宋体&quot;&gt;），通常简称为&lt;/span&gt;IIC&lt;span style=&quot;font-family:宋体&quot;&gt;，是一种用在集成电路（&lt;/span&gt;IC&lt;span style=&quot;font-family:宋体&quot;&gt;）之间的串行通信总线。它是由&lt;/span&gt;Philips&lt;span style=&quot;font-family:宋体&quot;&gt;（现在的&lt;/span&gt;NXP&lt;span style=&quot;font-family:宋体&quot;&gt;半导体）在上世纪&lt;/span&gt;80&lt;span style=&quot;font-family:宋体&quot;&gt;年代开发的，并在之后广泛应用于各种电子设备和嵌入式系统中。&lt;/span&gt;&lt;/p&gt;&lt;h3&gt;1.2 &lt;span style=&quot;font-family: 黑体&quot;&gt;信号线&lt;/span&gt;&lt;/h3&gt;&lt;p&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;I&lt;sup&gt;2&lt;/sup&gt;C&lt;span style=&quot;font-family: 宋体&quot;&gt;为&lt;strong&gt;同步串行&lt;/strong&gt;通信，使用两根线路进行通信，分别是数据线（&lt;/span&gt;SDA&lt;span style=&quot;font-family:宋体&quot;&gt;）和时钟线（&lt;/span&gt;SCL&lt;span style=&quot;font-family:宋体&quot;&gt;），&lt;/span&gt;SDA&lt;span style=&quot;font-family: 宋体&quot;&gt;线用于数据传输，&lt;/span&gt;SCL&lt;span style=&quot;font-family:宋体&quot;&gt;线用于数据传输的同步。&lt;/span&gt;SCL&lt;span style=&quot;font-family:宋体&quot;&gt;的每个时钟周期，&lt;/span&gt;SDA&lt;span style=&quot;font-family:宋体&quot;&gt;传输一位数据。&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;I&lt;sup&gt;2&lt;/sup&gt;C&lt;span style=&quot;font-family: 宋体&quot;&gt;规定，数据的接收方会在每个时钟周期的&lt;strong&gt;高电平&lt;/strong&gt;期间读取数据，具体来讲就是在&lt;/span&gt;SCL&lt;span style=&quot;font-family:宋体&quot;&gt;处于高电平时，读取&lt;/span&gt;SDA&lt;span style=&quot;font-family:宋体&quot;&gt;上的数据，如下图所示。&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;img class=&quot;ue-image&quot; src=&quot;https://s21.ax1x.com/2025/08/29/pV6x2oF.jpg&quot;/&gt;&lt;/p&gt;&lt;p&gt;&lt;span style=&quot;font-family:宋体&quot;&gt;&amp;nbsp;因此，&lt;/span&gt;SDA&lt;span style=&quot;font-family:宋体&quot;&gt;必须在&lt;/span&gt;SCL&lt;span style=&quot;font-family: 宋体&quot;&gt;低电平期准备好要发送的下一位数据，然后在&lt;/span&gt;SCL&lt;span style=&quot;font-family:宋体&quot;&gt;高电平期间保持稳定。&lt;/span&gt;&lt;/p&gt;&lt;h3&gt;1.3 &lt;span style=&quot;font-family: 黑体&quot;&gt;主从架构&lt;/span&gt;&lt;/h3&gt;&lt;p&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;I&lt;sup&gt;2&lt;/sup&gt;C&lt;span style=&quot;font-family: 宋体&quot;&gt;采用主从架构，一个主设备可连接多个从设备。主设备负责发起通信和控制总线，而从设备负责响应主设备的请求。如下图所示。&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;img class=&quot;ue-image&quot; src=&quot;https://s21.ax1x.com/2025/08/29/pV6xyLV.jpg&quot;/&gt;&lt;/p&gt;&lt;p&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;I&lt;sup&gt;2&lt;/sup&gt;C&lt;span style=&quot;font-family: 宋体&quot;&gt;总线中的每个设备都有一个唯一的地址（用&lt;/span&gt;7&lt;span style=&quot;font-family:宋体&quot;&gt;位二进制数字表示），用于在总线上标识自己。主设备可以根据地址选择性的与特定的从设备进行通信。&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style=&quot;font-family:宋体&quot;&gt;&amp;nbsp;需要注意的是，&lt;/span&gt;SCL&lt;span style=&quot;font-family:宋体&quot;&gt;信号线上的时钟信号始终由&lt;strong&gt;主设备&lt;/strong&gt;产生，而&lt;/span&gt;SDA&lt;span style=&quot;font-family:宋体&quot;&gt;信号线上的数据信号既可由主设备产生，也可由从设备产生。当主设备向从设备发送数据时，&lt;/span&gt;SDA&lt;span style=&quot;font-family:宋体&quot;&gt;信号由主设备产生，从设备接收信号；当主设备从从设备读取数据时，&lt;/span&gt;SDA&lt;span style=&quot;font-family:宋体&quot;&gt;信号由从设备产生，主设备接收信号。&lt;/span&gt;&lt;/p&gt;&lt;h3&gt;1.4 &lt;span style=&quot;font-family: 黑体&quot;&gt;通信协议&lt;/span&gt;&lt;/h3&gt;&lt;h4&gt;1.4.1 &lt;span style=&quot;font-family: 宋体&quot;&gt;空闲状态&lt;/span&gt;&lt;/h4&gt;&lt;p&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;I&lt;sup&gt;2&lt;/sup&gt;C&lt;span style=&quot;font-family: 宋体&quot;&gt;协议规定，当&lt;/span&gt;SDA&lt;span style=&quot;font-family:宋体&quot;&gt;和&lt;/span&gt;SCL&lt;span style=&quot;font-family:宋体&quot;&gt;均为高电平时，总线为空闲状态。&lt;/span&gt;&lt;/p&gt;&lt;h4&gt;1.4.2 &lt;span style=&quot;font-family: 宋体&quot;&gt;起始和结束信号&lt;/span&gt;&lt;/h4&gt;&lt;p&gt;&lt;span style=&quot;font-family:宋体&quot;&gt;&amp;nbsp;主设备和从设备间的每次通信，都需要以一个&lt;strong&gt;起始信号&lt;/strong&gt;开始，以一个&lt;strong&gt;结束信号&lt;/strong&gt;终止。起始信号和结束信号的定义如下：&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;strong&gt;&lt;span style=&quot;font-family:宋体&quot;&gt;&amp;nbsp;起始信号&lt;/span&gt;&lt;/strong&gt;&lt;span style=&quot;font-family: 宋体&quot;&gt;：当&lt;/span&gt;SCL&lt;span style=&quot;font-family:宋体&quot;&gt;处于高电平时，&lt;/span&gt;SDA&lt;span style=&quot;font-family:宋体&quot;&gt;由高变低。&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;strong&gt;&lt;span style=&quot;font-family:宋体&quot;&gt;&amp;nbsp;停止信号&lt;/span&gt;&lt;/strong&gt;&lt;span style=&quot;font-family: 宋体&quot;&gt;：当&lt;/span&gt;SCL&lt;span style=&quot;font-family:宋体&quot;&gt;处于高电平时，&lt;/span&gt;SDA&lt;span style=&quot;font-family:宋体&quot;&gt;由低变高。&lt;/span&gt; &lt;/p&gt;&lt;p&gt;&lt;span style=&quot;font-family:宋体&quot;&gt;&amp;nbsp;如下图所示。&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;img class=&quot;ue-image&quot; src=&quot;https://s21.ax1x.com/2025/08/29/pV6xcZT.jpg&quot;/&gt;&lt;/p&gt;&lt;p&gt;&lt;span style=&quot;font-family:宋体&quot;&gt;&amp;nbsp;起始信号和结束信号，都只能由&lt;strong&gt;主设备&lt;/strong&gt;产生。&lt;/span&gt;&lt;/p&gt;&lt;h4&gt;1.4.3 &lt;span style=&quot;font-family: 宋体&quot;&gt;确认信号&lt;/span&gt;&lt;/h4&gt;&lt;p&gt;&amp;nbsp;I&lt;sup&gt;2&lt;/sup&gt;C&lt;span style=&quot;font-family: 宋体&quot;&gt;协议规定，发送方每发送一个字节（&lt;/span&gt;8&lt;span style=&quot;font-family:宋体&quot;&gt;位）的数据，接收方都要向发送方回复一个&lt;/span&gt;1&lt;span style=&quot;font-family:宋体&quot;&gt;位的确认信号，如下图所示。&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;img class=&quot;ue-image&quot; src=&quot;https://s21.ax1x.com/2025/08/29/pV6xWi4.jpg&quot;/&gt;&lt;/p&gt;&lt;p&gt;&lt;span style=&quot;font-family:宋体&quot;&gt;&amp;nbsp;如果该确认信号为&lt;/span&gt;0&lt;span style=&quot;font-family:宋体&quot;&gt;表示接收方已成功接收到该字节，发送方可继续发送下一字节，这个信号在&lt;/span&gt;I&lt;sup&gt;2&lt;/sup&gt;C&lt;span style=&quot;font-family:宋体&quot;&gt;协议中称为&lt;/span&gt;ACK&lt;span style=&quot;font-family:宋体&quot;&gt;（&lt;/span&gt;Acknowledge&lt;span style=&quot;font-family:宋体&quot;&gt;）；如果该信号为&lt;/span&gt;1&lt;span style=&quot;font-family:宋体&quot;&gt;，则表示接收方未能成功接收到该字节，或者不希望接收更多数据，该信号在&lt;/span&gt;I&lt;sup&gt;2&lt;/sup&gt;C&lt;span style=&quot;font-family:宋体&quot;&gt;协议中称为&lt;/span&gt;NACK&lt;span style=&quot;font-family:宋体&quot;&gt;（&lt;/span&gt;Not Acknowledge&lt;span style=&quot;font-family:宋体&quot;&gt;）。&lt;/span&gt;&lt;/p&gt;&lt;h4&gt;1.4.4 &lt;span style=&quot;font-family: 宋体&quot;&gt;从机地址和读写标识&lt;/span&gt;&lt;/h4&gt;&lt;p&gt;&lt;span style=&quot;font-family:宋体&quot;&gt;&amp;nbsp;由于一个&lt;/span&gt;I&lt;sup&gt;2&lt;/sup&gt;C&lt;span style=&quot;font-family:宋体&quot;&gt;总线上可能有多个从设备，所以开始通信前，主设备需要先与目标设备取得联系，然后再进行数据传输，除此之外，主机还需要向目标设备明确本次通信的操作是写数据还是读数据。&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style=&quot;font-family:宋体&quot;&gt;&amp;nbsp;上述操作的实现思路如下：&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style=&quot;font-family:宋体&quot;&gt;&amp;nbsp;当主设备发送起始信号之后，会向所有设备发送一个字节的数据，这一个字节中，前&lt;/span&gt;7&lt;span style=&quot;font-family:宋体&quot;&gt;位为目标设备地址，第&lt;/span&gt;8&lt;span style=&quot;font-family:宋体&quot;&gt;位为读&lt;/span&gt;/&lt;span style=&quot;font-family: 宋体&quot;&gt;写标识（&lt;/span&gt;1&lt;span style=&quot;font-family:宋体&quot;&gt;表示读，&lt;/span&gt;0&lt;span style=&quot;font-family:宋体&quot;&gt;表示写），如下图所示。&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;img class=&quot;ue-image&quot; src=&quot;https://s21.ax1x.com/2025/08/29/pV6xss0.jpg&quot;/&gt;&lt;/p&gt;&lt;p&gt;&lt;span style=&quot;font-family:宋体&quot;&gt;&amp;nbsp;当各从设备收到这个字节的数据后，会将&lt;/span&gt;7&lt;span style=&quot;font-family:宋体&quot;&gt;位地址与自身进行对比，相同则会向主设备回复确认信号，不相同则不做任何回应。&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style=&quot;font-family:宋体&quot;&gt;&amp;nbsp;当主设备收到目标设备的确认信号后，便会开始与该设备进行通信。&lt;/span&gt;&lt;/p&gt;&lt;h4&gt;1.4.5 &lt;span style=&quot;font-family: 宋体&quot;&gt;完整通信流程&lt;/span&gt;&lt;/h4&gt;&lt;p&gt;&lt;span style=&quot;font-family:宋体&quot;&gt;&amp;nbsp;综上所述，当主设备想要与某个从设备进行通信时，需要经历如下流程。&lt;/span&gt;&lt;/p&gt;&lt;p style=&quot;margin-left:0&quot;&gt;&amp;nbsp;（1）&lt;span style=&quot;font-family:宋体&quot;&gt;发送起始信号&lt;/span&gt;&lt;/p&gt;&lt;p style=&quot;margin-left:0&quot;&gt;&amp;nbsp;（2）&lt;span style=&quot;font-family:宋体&quot;&gt;发送目标从设备地址&lt;/span&gt;+&lt;span style=&quot;font-family:宋体&quot;&gt;读写标识位&lt;/span&gt;&lt;/p&gt;&lt;p style=&quot;margin-left:0&quot;&gt;&amp;nbsp;（3）&lt;span style=&quot;font-family:宋体&quot;&gt;接收从设备回复的确认信号&lt;/span&gt;&lt;/p&gt;&lt;p style=&quot;margin-left:0&quot;&gt;&amp;nbsp;（4）&lt;span style=&quot;font-family:宋体&quot;&gt;与从设备进行数据传输（发送&lt;/span&gt;/&lt;span style=&quot;font-family:宋体&quot;&gt;接收）&lt;/span&gt;&lt;/p&gt;&lt;p style=&quot;margin-left:0&quot;&gt;&amp;nbsp;（5）&lt;span style=&quot;font-family:宋体&quot;&gt;发送终止信号&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;img class=&quot;ue-image&quot; src=&quot;https://s21.ax1x.com/2025/08/29/pV6xgdU.jpg&quot;/&gt;&lt;/p&gt;</description><pubDate>Fri, 29 Aug 2025 16:28:56 +0800</pubDate></item><item><title>51单片机 | UART | 接收数据 | 判定字符串接收完毕</title><link>https://sblog.kdrnn.online/?id=3</link><description>&lt;p&gt;实现思路：&lt;br/&gt;每接收一个字符，重置定时器，若定时器达到设定值则判定为字符串完整接收。&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;实现过程：&lt;/p&gt;&lt;p&gt;定义一个变量记录空闲时间，&lt;/p&gt;&lt;pre class=&quot;prism-highlight prism-language-c&quot;&gt;static&amp;nbsp;unsigned&amp;nbsp;char&amp;nbsp;s_idle_count&amp;nbsp;=&amp;nbsp;0;&lt;/pre&gt;&lt;p&gt;现阶段思路：每毫秒加一，每收到一个字符置零。&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;定义定时器0回调:&lt;br/&gt;&lt;/p&gt;&lt;pre class=&quot;prism-highlight prism-language-c&quot;&gt;void&amp;nbsp;Dri_UART_Timer0Callback()
{
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;s_idle_count++;
}&lt;/pre&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;在初始化函数Dri_UART_Init中注册空闲检测函数:&lt;/p&gt;&lt;p&gt;Dri_Timer0_RegisterCallback(&lt;span style=&quot;text-wrap-mode: wrap;&quot;&gt;Dri_UART_Timer0Callback&lt;/span&gt;);&lt;/p&gt;&lt;p&gt;此时s_idle_count每毫秒加一。&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;每收到一个新字符，重新计时（重置s_idle_count)，&lt;/p&gt;&lt;p&gt;在串口中断中重置：&lt;br/&gt;&lt;/p&gt;&lt;pre class=&quot;prism-highlight prism-language-c&quot;&gt;void&amp;nbsp;Dri_UART_Handler()&amp;nbsp;interrupt&amp;nbsp;4
{
&amp;nbsp;&amp;nbsp;if(RI&amp;nbsp;==&amp;nbsp;1)&amp;nbsp;{
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;s_idle_count&amp;nbsp;=&amp;nbsp;0;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;RI&amp;nbsp;=&amp;nbsp;0;
&amp;nbsp;&amp;nbsp;}
}&lt;/pre&gt;&lt;p&gt;判断：当s_idle_count &amp;gt; 10时处理逻辑，&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;定义数组用于接收SBUF：&lt;/p&gt;&lt;pre class=&quot;prism-highlight prism-language-c&quot;&gt;static&amp;nbsp;char&amp;nbsp;idata&amp;nbsp;s_buffer[16];&lt;/pre&gt;&lt;p&gt;（最长16字符）&lt;br/&gt;&lt;/p&gt;&lt;p&gt;定义索引：&lt;/p&gt;&lt;pre class=&quot;prism-highlight prism-language-c&quot;&gt;static&amp;nbsp;unsigned&amp;nbsp;char&amp;nbsp;s_index;&lt;/pre&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;修改串口中断逻辑，给s_buffer的索引位赋值并自增索引位：&lt;br/&gt;&lt;/p&gt;&lt;pre class=&quot;prism-highlight prism-language-c&quot;&gt;void&amp;nbsp;Dri_UART_Handler()&amp;nbsp;interrupt&amp;nbsp;4
{
&amp;nbsp;&amp;nbsp;if(RI&amp;nbsp;==&amp;nbsp;1)&amp;nbsp;{
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;s_buffer[s_index++]&amp;nbsp;=&amp;nbsp;SBUF;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;RI&amp;nbsp;=&amp;nbsp;0;
&amp;nbsp;&amp;nbsp;}
}&lt;/pre&gt;&lt;p style=&quot;text-wrap-mode: wrap;&quot;&gt;&lt;br/&gt;&lt;/p&gt;&lt;p style=&quot;text-wrap-mode: wrap;&quot;&gt;修改Dri_UART_Timer0Callback()，判断空闲时间大于十毫秒，同时数组应不为空（s_index不为0）：&lt;/p&gt;&lt;pre class=&quot;prism-highlight prism-language-c&quot;&gt;s_idle_count++;
if&amp;nbsp;(s_index&amp;nbsp;&amp;gt;&amp;nbsp;0&amp;nbsp;&amp;amp;&amp;amp;&amp;nbsp;s_idle_count&amp;nbsp;&amp;gt;=10)
{
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;//数据处理逻辑
}&lt;/pre&gt;&lt;p style=&quot;text-wrap-mode: wrap;&quot;&gt;需要ReceiveString方法，在main中重复调用ReceiveString函数，&lt;/p&gt;&lt;p style=&quot;text-wrap-mode: wrap;&quot;&gt;如果字符串接收完毕，函数返回1，将s_buffer内容赋给字符串，否则返回0。&lt;/p&gt;&lt;p style=&quot;text-wrap-mode: wrap;&quot;&gt;&lt;br/&gt;&lt;/p&gt;&lt;p style=&quot;text-wrap-mode: wrap;&quot;&gt;判断是否接收完毕，定义标志位并赋初始值：&lt;/p&gt;&lt;pre class=&quot;prism-highlight prism-language-c&quot;&gt;static&amp;nbsp;bit&amp;nbsp;s_is_complete&amp;nbsp;=&amp;nbsp;0;&lt;/pre&gt;&lt;p style=&quot;text-wrap-mode: wrap;&quot;&gt;完善空闲计时方法，一旦接收完毕，标志位置1，&lt;/p&gt;&lt;pre class=&quot;prism-highlight prism-language-c&quot;&gt;void&amp;nbsp;Dri_UART_Timer0Callback()
{
&amp;nbsp;&amp;nbsp;s_idle_count++；
&amp;nbsp;&amp;nbsp;if&amp;nbsp;(s_index&amp;nbsp;&amp;gt;&amp;nbsp;0&amp;nbsp;&amp;amp;&amp;amp;&amp;nbsp;s_idle_count&amp;nbsp;&amp;gt;=&amp;nbsp;10)
&amp;nbsp;&amp;nbsp;{
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;s_is_complete&amp;nbsp;=&amp;nbsp;1;
&amp;nbsp;&amp;nbsp;}
}&lt;/pre&gt;&lt;p style=&quot;text-wrap-mode: wrap;&quot;&gt;定义方法，将s_buffer数组内容赋给str，&lt;/p&gt;&lt;p style=&quot;text-wrap-mode: wrap;&quot;&gt;并将标志位和索引清零：&lt;/p&gt;&lt;pre class=&quot;prism-highlight prism-language-c&quot;&gt;bit&amp;nbsp;Dri_UART_ReceiveString(char&amp;nbsp;*str)
{
&amp;nbsp;&amp;nbsp;if&amp;nbsp;(s_is_complete&amp;nbsp;==&amp;nbsp;1)
&amp;nbsp;&amp;nbsp;{
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;for&amp;nbsp;(i&amp;nbsp;=&amp;nbsp;0;&amp;nbsp;i&amp;nbsp;&amp;lt;&amp;nbsp;s_index;&amp;nbsp;i++)
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;{
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;str[i]&amp;nbsp;=&amp;nbsp;s_buffer[i];
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;s_is_complete&amp;nbsp;=&amp;nbsp;0;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;s_index&amp;nbsp;=&amp;nbsp;0;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;return&amp;nbsp;1;
&amp;nbsp;&amp;nbsp;}
&amp;nbsp;&amp;nbsp;return&amp;nbsp;0;
}&lt;/pre&gt;&lt;p style=&quot;text-wrap-mode: wrap;&quot;&gt;&lt;br/&gt;&lt;/p&gt;&lt;p style=&quot;text-wrap-mode: wrap;&quot;&gt;在main.c中：&lt;/p&gt;&lt;pre class=&quot;prism-highlight prism-language-c&quot;&gt;#include&amp;nbsp;&amp;lt;STRING.H&amp;gt;&lt;/pre&gt;&lt;p style=&quot;text-wrap-mode: wrap;&quot;&gt;声明数组：&lt;/p&gt;&lt;pre class=&quot;prism-highlight prism-language-c&quot;&gt;unsigned&amp;nbsp;char&amp;nbsp;idata&amp;nbsp;str[16];&lt;/pre&gt;&lt;p style=&quot;text-wrap-mode: wrap;&quot;&gt;初始化定时器和串口：&lt;/p&gt;&lt;pre class=&quot;prism-highlight prism-language-c&quot;&gt;Dri_Timer0_Init();
Dri_UART_Init();&lt;/pre&gt;&lt;p style=&quot;text-wrap-mode: wrap;&quot;&gt;（先初始化定时器以设置NULL，否则无法正常注册）&lt;/p&gt;&lt;p style=&quot;text-wrap-mode: wrap;&quot;&gt;&lt;br/&gt;&lt;/p&gt;&lt;p style=&quot;text-wrap-mode: wrap;&quot;&gt;使用STRING.H的strcmp比较字符串：&lt;/p&gt;&lt;pre class=&quot;prism-highlight prism-language-c&quot;&gt;strcmp(str,&amp;quot;on&amp;quot;)&amp;nbsp;==&amp;nbsp;0&lt;/pre&gt;&lt;p style=&quot;text-wrap-mode: wrap;&quot;&gt;main方法：&lt;/p&gt;&lt;pre class=&quot;prism-highlight prism-language-c&quot;&gt;void&amp;nbsp;main()
{
&amp;nbsp;&amp;nbsp;unsigned&amp;nbsp;char&amp;nbsp;idata&amp;nbsp;str[16];
&amp;nbsp;&amp;nbsp;Dri_Timer0_Init();
&amp;nbsp;&amp;nbsp;Dri_UART_Init();
&amp;nbsp;&amp;nbsp;while(1)
&amp;nbsp;&amp;nbsp;{
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;if&amp;nbsp;(Dri_UART_ReceiveString(str))
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;{
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;if&amp;nbsp;(strcmp(str,&amp;quot;on&amp;quot;))
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;{
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;P00&amp;nbsp;=&amp;nbsp;~P00;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;Dri_UART_SendString(&amp;quot;LED1&amp;nbsp;IS&amp;nbsp;ON&amp;quot;);
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}&amp;nbsp;else&amp;nbsp;if&amp;nbsp;(strcmp(str,&amp;quot;off&amp;quot;))&amp;nbsp;{
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;P01&amp;nbsp;=&amp;nbsp;~P01;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;Dri_UART_SendString(&amp;quot;LED2&amp;nbsp;IS&amp;nbsp;ON&amp;quot;);
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}&amp;nbsp;else&amp;nbsp;{
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;Dri_UART_SendString(&amp;quot;UNKNOWN&amp;nbsp;COMMAND&amp;quot;)
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}
&amp;nbsp;&amp;nbsp;}
}&lt;/pre&gt;&lt;p style=&quot;text-wrap-mode: wrap;&quot;&gt;&lt;br/&gt;&lt;/p&gt;&lt;p style=&quot;text-wrap-mode: wrap;&quot;&gt;此时应可以正常接收命令，但若上一条命令长于本条，则无法正确识别，&lt;/p&gt;&lt;p style=&quot;text-wrap-mode: wrap;&quot;&gt;原因：&lt;/p&gt;&lt;p style=&quot;text-wrap-mode: wrap;&quot;&gt;短命令无法完全覆写长命令，而strcmp检测&amp;quot;\0&amp;quot;，故将无法检测正确内容&lt;/p&gt;&lt;p style=&quot;text-wrap-mode: wrap;&quot;&gt;解决方式：&lt;/p&gt;&lt;ol class=&quot; list-paddingleft-2&quot; style=&quot;list-style-type: decimal;&quot;&gt;&lt;li&gt;&lt;p style=&quot;text-wrap-mode: wrap;&quot;&gt;每次接受命令后后清空str[]数组&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p style=&quot;text-wrap-mode: wrap;&quot;&gt;每次收到完整字符串，在最后一个字符后加&amp;quot;\0&amp;quot;&lt;/p&gt;&lt;/li&gt;&lt;/ol&gt;&lt;p style=&quot;text-wrap-mode: wrap;&quot;&gt;&lt;br/&gt;&lt;/p&gt;&lt;p style=&quot;text-wrap-mode: wrap;&quot;&gt;方式2的实现：&lt;/p&gt;&lt;p style=&quot;text-wrap-mode: wrap;&quot;&gt;修改Dri_UART_ReceiveString方法，在for循环后于i位设&amp;#39;\0&amp;#39;：&lt;/p&gt;&lt;pre class=&quot;prism-highlight prism-language-c&quot;&gt;bit&amp;nbsp;Dri_UART_ReceiveString(char&amp;nbsp;*str)
{
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;if&amp;nbsp;(s_is_complete&amp;nbsp;==&amp;nbsp;1)
&amp;nbsp;&amp;nbsp;{
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;for&amp;nbsp;(i&amp;nbsp;=&amp;nbsp;0;&amp;nbsp;i&amp;nbsp;&amp;lt;&amp;nbsp;s_index;&amp;nbsp;i++)
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;{
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;str[i]&amp;nbsp;=&amp;nbsp;s_buffer[i];
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;str[i]&amp;nbsp;=&amp;nbsp;&amp;#39;\0&amp;#39;;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;s_is_complete&amp;nbsp;=&amp;nbsp;0;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;s_index&amp;nbsp;=&amp;nbsp;0;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;return&amp;nbsp;1;
&amp;nbsp;&amp;nbsp;}
&amp;nbsp;&amp;nbsp;return&amp;nbsp;0;
}&lt;/pre&gt;&lt;p style=&quot;text-wrap-mode: wrap;&quot;&gt;&lt;br/&gt;&lt;/p&gt;</description><pubDate>Thu, 28 Aug 2025 17:04:56 +0800</pubDate></item></channel></rss>