jiuyue77 发表于 2025-8-23 21:48:06

<h1>ai8051U--虚拟键盘LED和数码管--打卡8</h1>
<p>灵活调用各各接口进行使用。</p>

jiuyue77 发表于 2025-9-2 08:49:36

<h1><strong>ai8051U矩阵按键--打卡9</strong></h1>
<h2>矩阵按键原理</h2>
<p>分<strong>行端口</strong>和<strong>列端口</strong>。当行端口为高电平时,列端口为低电平,按键按下会将按下行的高电平改为低电平,确认按键所在行;当行端口为低电平时,列端口为高电平,按键会将按下的列的高电平改为低电平,确认按键所在列。行号和列号确认即可找到对应的按键。<br />
<strong>缺点</strong>:<font color="red">只能有一个按键按下,检测一个按钮被按下。不支持多按键按下。</font></p>
<p><img src="data/attachment/forum/202509/02/084933bf1x8lh1kx49vv9x.png" alt="图片.png" title="图片.png" /></p>
<p><img src="data/attachment/forum/202509/02/085352lzw8oxu38y3r3xwu.png" alt="图片.png" title="图片.png" /></p>
<h2>按键内容</h2>
<p>第一种写法:顺序操作判断每个端口</p>
<pre><code>// 键号
unsigned char keyNum = 0xFF;
// 行号
#define ROW1 端口号(例如P00)
#define ROW2
// 列号
#define COLUMN1 端口号(例如P05)
#define COLUMN2
#define COLUMN3
#define COLUMN4
void matrixButtons(){
// 1.先确认行号,行端口:高电平,列端口:低电平,行端口判断低电平
COLUMN1 = 0;
COLUMN2 = 0;
COLUMN3 = 0;
COLUMN4 = 0;
ROW1= 1;
ROW2= 1;

if((ROW1 == 0) || (ROW2 == 0)){
    if(ROW1 == 0) &amp;&amp; (ROW2 ==0)){
      ROW1 = 1;
      ROW2 = 1;
      keyNum = 0;
      printf_usb(&quot; 非法操作,有多个按键被按下 \r\n&quot;);
    }else if((ROW1 == 0) &amp;&amp;(ROW2 == 1)) || ((ROW1 == 1) &amp;&amp;(ROW2 == 0)){
      // 2.确认列号,行端口:低电平,列端口:高电平,列端口判断低电平
      COLUMN1 = 1;
      COLUMN2 = 1;
      COLUMN3 = 1;
      COLUMN4 = 1;
      ROW1= 0;
      ROW2= 0;
      if(ROW1 == 0){
            // 行按键起始号
            keyNum = 1;
            if((COLUMN1 == 0) &amp;&amp; (COLUMN2 == 1) &amp;&amp; (COLUMN3 == 1) &amp;&amp; (COLUMN4 == 1){
               keyNum = keyNum + 1;
            printf_usb(&quot; 按键位置:第1行第1列 \r\n&quot;);
            }else if(COLUMN1 == 1) &amp;&amp; (COLUMN2 == 0) &amp;&amp; (COLUMN3 == 1) &amp;&amp; (COLUMN4 == 1){
               keyNum = keyNum + 2;
               printf_usb(&quot; 按键位置:第1行第2列 \r\n&quot;);
            }else if(COLUMN1 == 1) &amp;&amp; (COLUMN2 == 1) &amp;&amp; (COLUMN3 == 0) &amp;&amp; (COLUMN4 == 1){
               keyNum = keyNum + 3;
            printf_usb(&quot; 按键位置:第1行第3列 \r\n&quot;);
            }else if(COLUMN1 == 1) &amp;&amp; (COLUMN2 == 1) &amp;&amp; (COLUMN3 == 1) &amp;&amp; (COLUMN4 == 0){
               keyNum = keyNum + 4;
            printf_usb(&quot; 按键位置:第1行第4列 \r\n&quot;);
            }
      }else if(ROW2 == 0){
            // 行按键起始号
            keyNum = 4;
            if((COLUMN1 == 0) &amp;&amp; (COLUMN2 == 1) &amp;&amp; (COLUMN3 == 1) &amp;&amp; (COLUMN4 == 1){
               keyNum = keyNum + 1;
            printf_usb(&quot; 按键位置:第2行第1列 \r\n&quot;);
            }else if(COLUMN1 == 1) &amp;&amp; (COLUMN2 == 0) &amp;&amp; (COLUMN3 == 1) &amp;&amp; (COLUMN4 == 1){
               keyNum = keyNum + 2;
               printf_usb(&quot; 按键位置:第2行第2列 \r\n&quot;);
            }else if(COLUMN1 == 1) &amp;&amp; (COLUMN2 == 1) &amp;&amp; (COLUMN3 == 0) &amp;&amp; (COLUMN4 == 1){
               keyNum = keyNum + 3;
            printf_usb(&quot; 按键位置:第2行第3列 \r\n&quot;);
            }else if(COLUMN1 == 1) &amp;&amp; (COLUMN2 == 1) &amp;&amp; (COLUMN3 == 1) &amp;&amp; (COLUMN4 == 0){
               keyNum = keyNum + 4;
            printf_usb(&quot; 按键位置:第2行第4列 \r\n&quot;);
            }
      }

      // 3.恢复初始值,过滤闪烁问题,行端口:高电平,列端口:低电平
      COLUMN1 = 0;
      COLUMN2 = 0;
      COLUMN3 = 0;
      COLUMN4 = 0;
      ROW1= 1;
      ROW2= 1;

    }else if((ROW1 == 1) &amp;&amp; (ROW2 == 1)){
         // 清空键值
      keyNum = 0xFF;
    }

}



}
</code></pre>
<p>第二种写法:使用十六进制数表示端口,端口组合模式判断匹配<br />
低位:行,高位:列</p>
<p>例如第一行第一列<br />
0x0F = 0000 1111<br />
ROW = P1 &amp; 0x0F = 0000 1110 &amp; 0000 1111 = 0000 1110<br />
0xF0 = 1111 0000<br />
COLUMN = P1 &amp; 0xF0 = 1110 0000 &amp; 1111 0000 = 1110 0000<br />
ROW + COLUMN = 0000 1110 + 1110 0000 = 1110 1110 = 0xEE<br />
所以第一行第一列的按键可以用0xEE来指向。</p>
<p><strong>按位与(&amp;)</strong>:只有两个数的二进制同时为1,结果才为1,否则为0。(负数按补码形式参加按位与运算)<br />
<strong>按位或(|)</strong>:参加运算的两个数只要两个数中的一个为1,结果就为1。<br />
<strong>按位异或(^)</strong>:参加运算的两个数,如果两个相应位为“异”(值不同),则该位结果为1,否则为0。<br />
即 0 ^ 0=0, 0 ^ 1= 1, 1 ^ 0= 1, 1 ^ 1= 0 。</p>

jiuyue77 发表于 2025-9-3 17:57:40

<h1><strong>ai8051U复位系统--打卡10</strong></h1>
<h2>系统复位</h2>
<p>系统复位类型:<strong>硬复位</strong>和<strong>软复位</strong></p>
<p><img src="data/attachment/forum/202509/07/082000xi0q47sqs34mqxxq.png" alt="0511F216-D5D7-414F-A8BE-A5D03D30EE2F.png" title="{0511F216-D5D7-414F-A8BE-A5D03D30EE2F}.png" /></p>
<h2>硬复位</h2>
<ul>
<li>
<p>硬复位</p>
<ul>
<li>上电复位</li>
<li><img src="data/attachment/forum/202509/07/085012dthqgrdvnrdi5fgq.png" alt="DB5997D8-7BA0-403F-8DFC-F202D6D8FD6E.png" title="{DB5997D8-7BA0-403F-8DFC-F202D6D8FD6E}.png" /></li>
<li>低压复位</li>
<li><img src="data/attachment/forum/202509/07/085155godhhdvkbjdxxhkd.png" alt="408A825C-0182-42A5-8869-95D6595825B9.png" title="{408A825C-0182-42A5-8869-95D6595825B9}.png" /></li>
<li>复位脚复位(低电平复位)</li>
<li><img src="data/attachment/forum/202509/07/085719aq2m29hlsyhy6tz2.png" alt="BD0FDCE5-37A1-4416-B758-D82D95E846B2.png" title="{BD0FDCE5-37A1-4416-B758-D82D95E846B2}.png" /></li>
<li>看门狗复位</li>
<li><img src="data/attachment/forum/202509/07/085831kfplsfd5faaltntp.png" alt="FFC9300A-CA31-4EEF-ADAA-6D85FBA752D2.png" title="{FFC9300A-CA31-4EEF-ADAA-6D85FBA752D2}.png" /></li>
</ul>
</li>
</ul>
<h2>软复位</h2>
<p><img src="data/attachment/forum/202509/07/090240deo1irt273eoi1jd.png" alt="2C2B9877-9352-4164-B544-96F7FC9EB113.png" title="{2C2B9877-9352-4164-B544-96F7FC9EB113}.png" /><br />
<strong>程序有USB功能需要先在前面加USB复位</strong></p>
<p>IAP_CONTR = 0x60;进入下载模式:点击按键实现下载准备,然后将程序下载进入。</p>
<p>IAP_CONTR = 0x20;从头开始运行用户程序,只有程序实现了上电起始的状态。</p>

jiuyue77 发表于 2025-9-7 09:09:57

<h1><strong>ai8051U外部中断--打卡11</strong></h1>
<p>外部中断:主程序事件运行中,有一紧急事件需要立即去执行处理,此时中断主程序去执行紧急事件,当紧急事件完成后,再继续执行主程序事件。</p>
<p><img src="data/attachment/forum/202509/07/100223v9lzgkkl0hz9ltmr.png" alt="00222F8C-23FA-4CBE-8CC6-D36ED6F50753.png" title="{00222F8C-23FA-4CBE-8CC6-D36ED6F50753}.png" /></p>
<h2>中断系统</h2>
<p><img src="data/attachment/forum/202509/07/100432iq99cojcuw8cejqe.png" alt="73ABBCED-76C8-4412-8F46-930F9F3D03CA.png" title="{73ABBCED-76C8-4412-8F46-930F9F3D03CA}.png" /></p>
<p><strong>中断级别:数值越小,中断等级越高优先执行。0高</strong></p>
<p><img src="data/attachment/forum/202509/07/101023oshkw2qv21d1zk17.png" alt="DC5A5D3D-87DD-4015-9AB4-003492B3ACC9.png" title="{DC5A5D3D-87DD-4015-9AB4-003492B3ACC9}.png" /></p>
<h2>外部中断</h2>
<p>由外部硬件或其他因素,使单片机引脚发生电平变化,观测变化去执行中断程序。</p>
<p>引脚有<font color="red"><strong>INTx</strong></font>标识可以作为外部中断口。</p>
<p>不同编号引脚支持不同类型中断(上升沿,下降沿)。</p>
<p><img src="data/attachment/forum/202509/07/101217gd66xn58xug4x455.png" alt="E043337E-B505-4293-8634-9C1621645AC9.png" title="{E043337E-B505-4293-8634-9C1621645AC9}.png" /></p>

jiuyue77 发表于 2025-9-7 11:05:38

<h1><strong>ai8051U--IO中断--打卡12</strong></h1>
<h2>IO中断介绍</h2>
<p><font color="red">IO中断和外部中断的区别</font>:</p>
<ol>
<li>IO中断仅支持一种中断模式(上升沿,下降沿),可以用两个IO端口实现双边沿检测;</li>
<li>IO中断可以配置上升沿,下降沿,高电平,低电平;</li>
<li>所有IO口都可以开启或关闭IO中断;</li>
<li>外部中断支持上升沿/下降沿中断,上升下降沿中断,外部中断只有特定的引脚可以进行中断。</li>
</ol>
<p><img src="data/attachment/forum/202509/07/111626remyr6ast5lf3ryt.png" alt="66EB5750-BD45-4E6A-81F8-35B761588C97.png" title="{66EB5750-BD45-4E6A-81F8-35B761588C97}.png" /></p>
<h2>IO中断使用</h2>
<ol>
<li>端口中断配置<br />
<img src="data/attachment/forum/202509/07/114618in46jjn3xhqqheo6.png" alt="BD67624C-A820-4775-B8E2-806C12CBCF8F.png" title="{BD67624C-A820-4775-B8E2-806C12CBCF8F}.png" /></li>
<li>端口中断使能<br />
<img src="data/attachment/forum/202509/07/114955xbpls1lhlksbhlsl.png" alt="F428F201-88D1-4833-B210-359B9B3D2E62.png" title="{F428F201-88D1-4833-B210-359B9B3D2E62}.png" /></li>
<li>中断号处理<br />
<img src="data/attachment/forum/202509/07/115145dtcl7cmbcctc9mt1.png" alt="2DB76FC6-BCD4-4CCB-8C08-D174C2B6164B.png" title="{2DB76FC6-BCD4-4CCB-8C08-D174C2B6164B}.png" /><br />
<strong>需要安装中断号支持插件</strong></li>
</ol>
<h2>中断优先级配置</h2>
<p><img src="data/attachment/forum/202509/07/145456pdh1ngciljal0szg.png" alt="1126A298-493B-4299-BB33-8DA31BA6FC6E.png" title="{1126A298-493B-4299-BB33-8DA31BA6FC6E}.png" /></p>

jiuyue77 发表于 2025-9-7 15:10:27

<h1><strong>ai8051U--定时器做计数器--打卡13</strong></h1>
<h2>计数器</h2>
<p><img src="data/attachment/forum/202509/07/154549ojsvwvvvcsjcjadi.png" alt="23968CD9-FD32-43B5-AAA7-58BA06105655.png" title="{23968CD9-FD32-43B5-AAA7-58BA06105655}.png" /></p>
<p><img src="data/attachment/forum/202509/07/154936u0hhlhssbebzwsgi.png" alt="FD422F04-5292-4691-800B-96E3837F1664.png" title="{FD422F04-5292-4691-800B-96E3837F1664}.png" /></p>
<p><img src="data/attachment/forum/202509/07/155009yh4zhwh4hczqc4cz.png" alt="AAD526B4-2D53-4A97-8655-3AC2507BF2BA.png" title="{AAD526B4-2D53-4A97-8655-3AC2507BF2BA}.png" /></p>
<pre><code>// 设置为计数器--外部计数
T1_CT = 1;
// 计数器工作模式--16位自动重载
T1_M1 = 0;
T1_M0 = 0;
// 控制计数器1--值为1,打开
T1_GATE = 1;

TH1
TL1

// 打开总中断
EA = 1;
// 打开定时器1中断允许
ET1 = 1;
// 打开定时器
TR1 = 1;
</code></pre>
<p>定时器1测量INT1引脚低电平脉冲宽度,常见案例就是按键按下到按键抬起的时间。</p>

jiuyue77 发表于 2025-9-7 16:47:47

<h1><strong>ai8051U--DS18B20测温--打卡14</strong></h1>
<h2>DS18B20温度传感器简介</h2>
<p><img src="data/attachment/forum/202509/07/172021tv86rgv7vgwrz5zn.png" alt="6AE7A871-E343-4E98-8414-5FFC6B299D23.png" title="{6AE7A871-E343-4E98-8414-5FFC6B299D23}.png" /></p>
<h2>DS18B20硬件连接</h2>
<p><img src="data/attachment/forum/202509/07/172141to99qjow8njn265j.png" alt="8AEEA194-A541-4E55-9510-4B99640BC9BD.png" title="{8AEEA194-A541-4E55-9510-4B99640BC9BD}.png" /></p>
<h2>DS18B20功能</h2>
<p><img src="data/attachment/forum/202509/07/172604fixkhkybbujnbxnb.png" alt="AD296C46-75E8-494D-8FAF-9CE04B20B8D6.png" title="{AD296C46-75E8-494D-8FAF-9CE04B20B8D6}.png" /></p>

jiuyue77 发表于 2025-9-7 17:33:25

<h1>计算机原码,反码,补码详解</h1>
<h3>一. 机器数和真值</h3>
<p>在学习原码, 反码和补码之前, 需要先了解机器数和真值的概念.</p>
<h4>1、机器数</h4>
<p>一个数在计算机中的二进制表示形式,叫做这个数的机器数。机器数是带符号的,在计算机用一个数的最高位存放符号, 正数为0, 负数为1.</p>
<p>比如,十进制中的数 +3 ,计算机字长为8位,转换成二进制就是00000011。如果是 -3 ,就是 10000011 。</p>
<p>那么,这里的 00000011 和 10000011 就是机器数。</p>
<h4>2、真值</h4>
<blockquote>
<p>因为第一位是符号位,所以机器数的形式值就不等于真正的数值。例如上面的有符号数10000011,其最高位1代表负,其真正数值是 -3而不是形式值131(10000011转换成十进制等于131)。所以,为区别起见,将带符号位的机器数对应的真正数值称为机器数的真值。</p>
</blockquote>
<p>例:0000 0001的真值 = +000 0001 = +1,1000 0001的真值 = –000 0001 = –1</p>
<h3>二. 原码, 反码, 补码的基础概念和计算方法.</h3>
<p>在探求为何机器要使用补码之前, 让我们先了解原码, 反码和补码的概念.对于一个数, 计算机要使用一定的编码方式进行存储. 原码, 反码, 补码是机器存储一个具体数字的编码方式.</p>
<h4>1. 原码</h4>
<p>原码就是符号位加上真值的绝对值, 即用第一位表示符号, 其余位表示值. 比如如果是8位二进制:</p>
<blockquote>
<p>[+1]~原 = 0000 0001</p>
<p>[-1]~原 = 1000 0001</p>
</blockquote>
<p>第一位是符号位. 因为第一位是符号位, 所以8位二进制数的取值范围就是:</p>
<blockquote>
<p></p>
</blockquote>
<p>即</p>
<blockquote>
<p>[-127 , 127]</p>
</blockquote>
<p>原码是人脑最容易理解和计算的表示方式.</p>
<h4>2. 反码</h4>
<p>反码的表示方法是:</p>
<p>正数的反码是其本身</p>
<p>负数的反码是在其原码的基础上, 符号位不变,其余各个位取反.</p>
<blockquote>
<p>[+1] = ~原 = ~反</p>
<p>[-1] = ~原 = ~反</p>
</blockquote>
<p>可见如果一个反码表示的是负数, 人脑无法直观的看出来它的数值. 通常要将其转换成原码再计算.</p>
<h4>3. 补码</h4>
<p>补码的表示方法是:</p>
<p>正数的补码就是其本身</p>
<p>负数的补码是在其原码的基础上, 符号位不变, 其余各位取反, 最后+1. (即在反码的基础上+1)</p>
<blockquote>
<p>[+1] = ~原 = ~反 = ~补</p>
<p>[-1] = ~原 = ~反 = ~补</p>
</blockquote>
<p>对于负数, 补码表示方式也是人脑无法直观看出其数值的. 通常也需要转换成原码在计算其数值.</p>
<blockquote>
<p>引用文章:计算机原码,反码,补码详解https://blog.csdn.net/u011080472/article/details/51280919</p>
</blockquote>

jiuyue77 发表于 2025-9-7 17:35:23

<h1><strong>ai8051U--串口的简单应用--打卡15</strong></h1>
页: 1 [2]
查看完整版本: ai8051U--学习记录