冰封眸 发表于 2024-12-2 22:41:54

《8051U深度入门到32位51大型实战视频》学习打卡 | 已送

兴趣是最好的学习动力。有句话说:活到老,学到老!学习从什么时候开始都不晚。今天开始第一步!
第一集:主要介绍8051U的一些强劲功能和实验板上的实验演示。

这个世界发展很快,只有不断充实自己,才能跟上时代步伐。

冰封眸 发表于 2024-12-3 14:13:24



第二集:先跟着喊一下口号:哪怕梦想让我们拼得遍体鳞伤,这一次我们也要通往直前。
开发板功能介绍:


环境的搭建:



1. keil C251的安装及注册

2. 在STC官网下载ISP及Keil 中断拓展插件

打开AIapp-ISP-v6.94Z.exe。并按以下步骤添加头文件和仿真驱动至Keil,ps:选择自己的安装目录

3. 解压拓展Keil的C代码中断号.zip,安装中断号拓展插件

4. 下载程序验证,(由于没有实验板,只记录硬件操作)
* 按下板子上的 P3.2/INT0 按键
* 给目标芯片重新上电,等待电脑端 ISP 下载软件中自动识别出“(HID1) USB Writer”
* 松开P3.2按键,就可以将编译好的hex文件下载到实验板中验证实验结果了。




冰封眸 发表于 2024-12-3 22:13:11

本帖最后由 冰封眸 于 2024-12-3 22:18 编辑

# 第三集 点亮第一颗LED

## 1. 新建Keil工程

* 打开Keil软件,点击菜单Project->New uVision Project,将工程文件名保存到相应的文件夹中
* 按下图所示选择STC8051U-32Bit Series
![屏幕截图2024-12-03213334.png](data/attachment/forum/202412/03/213502w0z0sypp0jobpjob.png "屏幕截图 2024-12-03 213334.png")
* 新建一个文件(Ctrl+N),并将其保存成main.c,并将main.c加入到工程文件中
!(data/attachment/forum/202412/03/214022vbmo2xe5gs52btge.png "image.png")
* 将Options选项按以下方式设置
![屏幕截图2024-12-03214339.png](data/attachment/forum/202412/03/214445n41gdm6f6cs2dcrg.png "屏幕截图 2024-12-03 214339.png")
![屏幕截图2024-12-03214517.png](data/attachment/forum/202412/03/214630v9ub633d91p3neen.png "屏幕截图 2024-12-03 214517.png")
* 点击Configuration,配置文本编码和Tab键插入的空格数
![屏幕截图2024-12-03214958.png](data/attachment/forum/202412/03/221705qshx78oc1cqq2lbj.png "屏幕截图 2024-12-03 214958.png")
* 代码编写
* !(data/attachment/forum/202412/03/215525xc5zjmji6rvpfrkv.png "image.png")
## 2. 点亮LED灯
* Ai8051U系列单片机所有I/O口均有4种工作模式:准双向口、推挽输出、高阻输入、开漏模式。使用端口模式配置寄存器(PxM0,PxM1)配置
!(data/attachment/forum/202412/03/220211mulsq4u8sz4ltb8x.png "image.png")
* 实验板上LED原理图如下:
!(data/attachment/forum/202412/03/220456ippf1p594q1ptq1q.png "image.png")
* 设置P40,P00输出0,可点亮LED00,代码编写如下:
!(data/attachment/forum/202412/03/221300bzfrgrz1597mo58k.png "image.png")

冰封眸 发表于 2024-12-4 23:05:38

## 第四集 USB不断电下载

### 下载USB驱动

* 从官网下载USB库文件,并解压
![屏幕截图2024-12-04222016.png](data/attachment/forum/202412/04/222112nwmsffve8supvvsb.png "屏幕截图 2024-12-04 222016.png")
得到以下的文件
!(data/attachment/forum/202412/04/224903lanv7fzmmbmfv6yq.png "image.png")

### 库文件加入工程
* 将stc32_stc8_usb.h和查询模式STC-CDC库文件夹中的stc_usb_cdc_32.LIB加入到工程文件中
!(data/attachment/forum/202412/04/224728ek7klo8kzpko2i5z.png "image.png")
* 参考例程编写如下代码

```
#include <AI8051U.H>
#include "stc32_stc8_usb.h"

char *USER_DEVICEDESC = NULL;
char *USER_PRODUCTDESC = NULL;
char *USER_STCISPCMD = "@STCISP#";      /* 对应ISP设置的自定义命令 */

void main()
{
      P_SW2 |= 0x80;                      /* 需要使用扩展的特殊功能寄存器SFR(XFR) */

      /* 将P0~P7端口全部设置为准双向*/
      P0M1 = 0x00;   P0M0 = 0x00;   
      P1M1 = 0x00;   P1M0 = 0x00;
      P2M1 = 0x00;   P2M0 = 0x00;
      P3M1 = 0x00;   P3M0 = 0x00;
      P4M1 = 0x00;   P4M0 = 0x00;
      P5M1 = 0x00;   P5M0 = 0x00;
      P6M1 = 0x00;   P6M0 = 0x00;
      P7M1 = 0x00;   P7M0 = 0x00;

      usb_init();                                     /* USB CDC 接口配置 */

      EA = 1;                                       /* 总中断使能 */

      while (DeviceState != DEVSTATE_CONFIGURED);   /* 等待USB完成配置 */
      while(1)
      {
          if (bUsbOutReady)
          {
            USB_SendData(UsbOutBuffer,OutNumber);   /* 发送数据缓冲区,长度(接收数据原样返回, 用于测试)*/

            usb_OUT_done();
          }
          /* 用户代码 */
      }
}
```

### 设置ISP选项

* 按以下选项设置ISP
![屏幕截图2024-12-04230123.png](data/attachment/forum/202412/04/230334k8122x1fkgtio5id.png "屏幕截图 2024-12-04 230123.png")
通过这样的设置后,除第一次需要按P3.2和电源键外,后面每次都可以自动下载程序。

冰封眸 发表于 2024-12-5 21:51:53

## 第五集 C语言基础

### USB-CDC串口printf函数的实现

在头文件stc32_stc8_usb.h中,打开 `#define PRINTF_USB`,这将使 `#define printfprintf_usb`语言变为有效,我们在程序中使用的printf被重定向为printf_usb。

代码实现如下

```
while(1)
{
    if (bUsbOutReady)                           /**/
    {
      //USB_SendData(UsbOutBuffer,OutNumber);   /* 发送数据缓冲区,长度(接收数据原样返回, 用于测试)*/
      printf("Ai8051 yyds/r/n");
      usb_OUT_done();
    }
    /* 用户代码 */
}
```

打开ISP软件,可以进行CDC-串口调试

![屏幕截图2024-12-05213228.png](data/attachment/forum/202412/05/213421z0uc8zn0ctccbq0p.png "屏幕截图 2024-12-05 213228.png")

### 进制简介

二进制,八进制,十进制,十六进制

### 数据的基本类型

![屏幕截图2024-12-05171616.png](data/attachment/forum/202412/05/213606g24kwwqn2y864nn4.png "屏幕截图 2024-12-05 171616.png")

如果要使用64位的变量,比如double,需要要文件头加入语句:`#pragma float64`

### C语言的常用运算符

* 算术运算符:+ - * / % ++ --
* 关系运算符:><==>=<=!=
* 逻辑运算符:&& || ^
* 赋值运算符:=+=-=*=/=<<=<<=&=|=^=
* 位运算符:<<>>& | ^ ~

冰封眸 发表于 2024-12-6 00:58:03

## 第六集 IO输入输出

### GPIO概念

GPIO通用输入输出端口,以下是Ai8051U系统GPIO口的电气特性

!(data/attachment/forum/202412/06/001741n8zru888c8stmuac.png "image.png")

工作模式,在准双向口工作模式下,灌电流可达20mA,拉电流为270~150uA

!(data/attachment/forum/202412/06/001940bpjrrf3vyfgt3jbp.png "image.png")

在实验箱3.3V供电电压的特性如下表所示,默认情况下是打开施密特触发器,即高电平不能低于1.18V,低电平不能高于0.99V

!(data/attachment/forum/202412/06/002256lmr81llrsgv44mlc.png "image.png")

### 按键输入检测

#### 电路原理图

!(data/attachment/forum/202412/06/002619ig5xuda56qtudequ.png "image.png")

当SW2按下时,P32的输入为0,只要判断P32是否为0,即可判断出SW2是否被按下。按键被按下进,分出现拉动的现像,如下图所示:

![屏幕截图2024-12-05233934.png](data/attachment/forum/202412/06/002913o0vvpry1lbff2uff.png "屏幕截图 2024-12-05 233934.png")
因此在判断时,因延时20ms后再判断一次按键是否被按下

#### 延时函数

打开IPS软件,选择如下:

![屏幕截图2024-12-06003152.png](data/attachment/forum/202412/06/003244e9aooo96w4z19t1c.png "屏幕截图 2024-12-06 003152.png")

将代码复制到工程中,并编写如下代码:

```
#include <AI8051U.H>
#include <intrins.h>                   /* _nop_()函数的头文件 */
#include "stc32_stc8_usb.h"

char *USER_DEVICEDESC = NULL;
char *USER_PRODUCTDESC = NULL;
char *USER_STCISPCMD = "@STCISP#";      /* 对应ISP设置的自定义命令 */

sbit SW2 = P3^2;                        /* 定义按键SW2对应IO口 */
sbit LED0 = P0^0;                     /* 定义LED0对应IO口 */

void Delay20ms(void)        //@24.000MHz
{
        unsigned long edata i;

        _nop_();
        _nop_();
        i = 119998UL;
        while (i) i--;
}

void main()
{
    u8 state = 0;                     /* 按键是否按下标志位 */
    WTST = 0;                           /* 设置程序指令延时参数,0:CPU执行速度最快 */
    EAXFR = 1;                        /* 需要使用扩展的特殊功能寄存器SFR(XFR) */
    CKCON = 0;                        /* 提高访问XRAM速度 */

    /* 将P0~P7端口全部设置为准双向*/
    P0M1 = 0x00;   P0M0 = 0x00;   
    P1M1 = 0x00;   P1M0 = 0x00;
    P2M1 = 0x00;   P2M0 = 0x00;
    P3M1 = 0x00;   P3M0 = 0x00;
    P4M1 = 0x00;   P4M0 = 0x00;
    P5M1 = 0x00;   P5M0 = 0x00;
    P6M1 = 0x00;   P6M0 = 0x00;
    P7M1 = 0x00;   P7M0 = 0x00;

    usb_init();                                     /* USB CDC 接口配置 */

    EA = 1;                                       /* 总中断使能 */
    P40 = 0;
    while (DeviceState != DEVSTATE_CONFIGURED);   /* 等待USB完成配置 */
    while(1)
    {
      if (bUsbOutReady)                           /**/
      {
            //USB_SendData(UsbOutBuffer,OutNumber);   /* 发送数据缓冲区,长度(接收数据原样返回, 用于测试)*/
            usb_OUT_done();
      }
      if (SW2 == 0)                                 /* 按键被按下 */
      {
            Delay20ms();                              /* 延时20MS消抖 */
            if (SW2 == 0)
            {
                state = ~state;
                LED0 = state;
                while (SW2 == 0)
                  ;                                 /* 等待按键松开 */
            }
      }
    }
}
```

以上代码实现SW2按一下,LED0亮,再按一下,LED0灭的功能

冰封眸 发表于 2024-12-7 00:15:34

<h2>第七集 定时器中断</h2>
<h3>定时器简介</h3>
<p><img src="data/attachment/forum/202412/06/212457cbaooo7u71z9cn8r.png" alt="屏幕截图2024-12-06134556.png" title="屏幕截图 2024-12-06 134556.png" /></p>
<p><img src="data/attachment/forum/202412/06/213152w0j08wcb0bs2z013.png" alt="image.png" title="image.png" /></p>
<h3>使用定时器</h3>
<p>打开ISP软件,进行如下设置:</p>
<p><img src="data/attachment/forum/202412/06/214504w2zwn2cnmpk2j8gj.png" alt="屏幕截图2024-12-06214342.png" title="屏幕截图 2024-12-06 214342.png" /></p>
<p>复印以下代码到工程文件中:</p>
<pre><code>void Timer0_Isr(void) interrupt 1
{
}

void Timer0_Init(void)                //3秒@24.000MHz
{
        TM0PS = 0x5B;                        //设置定时器时钟预分频 ( 注意:并非所有系列都有此寄存器,详情请查看数据手册 )
        AUXR &amp;= 0x7F;                        //定时器时钟12T模式
        TMOD &amp;= 0xF0;                        //设置定时器模式
        TL0 = 0x3F;                                //设置定时初始值
        TH0 = 0x01;                                //设置定时初始值
        TF0 = 0;                                //清除TF0标志
        TR0 = 1;                                //定时器0开始计时
        ET0 = 1;                                //使能定时器0中断
}

</code></pre>
<h3>寄存器介绍</h3>
<h4>TMxPS (x=0,1,2,3,4)</h4>
<p>定时器x时钟预分频寄存器(8位):定时器x的时钟 = 系统时钟SYSclk / (TMxPS + 1)</p>
<h4>AUXR辅助寄存器1</h4>
<p><img src="data/attachment/forum/202412/06/233754wpjjpp0h1a5qfsf3.png" alt="image.png" title="image.png" /></p>
<p>B7 B6位定时器0和1速度控制位,0:12T模式,1:1T模式</p>
<h4>TMOD定时器0/1模式寄存器</h4>
<p><img src="data/attachment/forum/202412/06/234408nkhamqxx3w2rm2x0.png" alt="image.png" title="image.png" /></p>
<h4>TL0/1,TH0/1 定时器0/1计数寄存器</h4>
<p>当定时器/计数器工作在16位模式时,TL和TH组合成一个16位寄存器。</p>
<h3>代码编写</h3>
<pre><code>#include &lt;AI8051U.H&gt;
#include &quot;stc32_stc8_usb.h&quot;

char *USER_DEVICEDESC = NULL;
char *USER_PRODUCTDESC = NULL;
char *USER_STCISPCMD = &quot;@STCISP#&quot;;      /* 对应ISP设置的自定义命令 */

sbit LED0 = P0^0;


void Timer0_Init(void);

void main()
{
    P_SW2 |= 0x80;                      /* 需要使用扩展的特殊功能寄存器SFR(XFR) */

    /* 将P0~P7端口全部设置为准双向*/
    P0M1 = 0x00;   P0M0 = 0x00;      
    P1M1 = 0x00;   P1M0 = 0x00;
    P2M1 = 0x00;   P2M0 = 0x00;
    P3M1 = 0x00;   P3M0 = 0x00;
    P4M1 = 0x00;   P4M0 = 0x00;
    P5M1 = 0x00;   P5M0 = 0x00;
    P6M1 = 0x00;   P6M0 = 0x00;
    P7M1 = 0x00;   P7M0 = 0x00;

    usb_init();                                     /* USB CDC 接口配置 */
    Timer0_Init();
    EA = 1;                                       /* 总中断使能 */
    P40 = 0;

    while (DeviceState != DEVSTATE_CONFIGURED);   /* 等待USB完成配置 */
    while(1)
    {
      if (bUsbOutReady)                           /**/
      {
            //USB_SendData(UsbOutBuffer,OutNumber);   /* 发送数据缓冲区,长度(接收数据原样返回, 用于测试)*/
            usb_OUT_done();
      }
    }
}

void Timer0_Init(void)                //3秒@24.000MHz
{
        TM0PS = 0x5B;                        //设置定时器时钟预分频 ( 注意:并非所有系列都有此寄存器,详情请查看数据手册 )
        AUXR &amp;= 0x7F;                        //定时器时钟12T模式
        TMOD &amp;= 0xF0;                        //设置定时器模式
        TL0 = 0x3F;                                //设置定时初始值
        TH0 = 0x01;                                //设置定时初始值
        TF0 = 0;                                //清除TF0标志
        TR0 = 1;                                //定时器0开始计时
        ET0 = 1;                                //使能定时器0中断
}

void Timer0_Isr(void) interrupt 1
{
    LED0 = ~LED0;
}
</code></pre>

8H8K64U 发表于 2024-12-10 14:29:05

再接再励,免费送试验箱一套方便前几集的硬件操作+后续学习!

8H8K64U 发表于 2024-12-11 10:47:26

昨天已安排了,请注意查收

冰封眸 发表于 2024-12-18 22:22:40

<h2>番外篇 代码整理</h2>
<p>几天前收到了实验箱,很感谢<img alt="baoquan" class="emoji" src="https://www.stcaimcu.com/static/image/smiley/default/baoquan.gif" title="baoquan" /> 论坛这种<strong>免费+包邮</strong>(而且还是包的是<strong>顺风</strong>)送实验箱的活动。 工具在手,天下我有。哈哈~~~!(这几天工作很忙,感谢晚了,见谅,见谅!)</p>
<p><img src="data/attachment/forum/202412/18/211427vl64l6pe4lp7llg4.png" alt="屏幕截图2024-12-18211418.png" title="屏幕截图 2024-12-18 211418.png" /></p>
<h3>前言</h3>
<p>第八集介绍了模块化编程的方式方法,再加上正好收到了实验箱,于是我将前几集的代码重新做了整理,并将实验结果进行了验证。</p>
<h3>工程模板建立</h3>
<ul>
<li>新建Template文件夹,并使用Keil在该文件夹中新建一个AI8051U工程</li>
<li>新建并编写sys_init.h文件,该文件将外设所需要的头文件include到此文件中</li>
</ul>
<pre><code>#ifndef __SYS_INIT_H
#define __SYS_INIT_H

/* Includes ------------------------------------------------------------------*/
#include &lt;AI8051U.H&gt;

void SYS_Init(void);
#endif
</code></pre>
<ul>
<li>新建并编写sys_init.c文件,主要是系统初始化函数编写处,并将文件文件加入工程项目中。</li>
</ul>
<pre><code>#include &quot;sys_init.h&quot;
void SYS_Init(void)
{
    // 代码编写
}
</code></pre>
<ul>
<li>main.c文件</li>
</ul>
<pre><code>#include &quot;sys_init.h&quot;

void main()
{
    SYS_Init();
    while(1)
    {

    }
}
</code></pre>
<ul>
<li>新建并编写sys_config.h文件,其内容是系统的配置参数,比如主频等</li>
</ul>
<pre><code>#ifndef __SYS_CONFIG_H
#define __SYS_CONFIG_H

//========================================================================
//                               主时钟定义
//========================================================================
#define MAIN_Fosc      24000000L    //定义主时钟 24M

#endif
</code></pre>
<ul>
<li>至此工程模板建立完成</li>
<li>
<h3>流水灯项目</h3>
</li>
</ul>
<ol>
<li>在复制工程模板项目文件夹,并在该工程中新建并添加led.h和led.c文件</li>
</ol>
<pre><code class="language-led.h">#ifndef __LED_H
#define __LED_H

/* Includes ------------------------------------------------------------------*/
#include &quot;delay.h&quot;
#include &lt;intrins.h&gt;
#include &lt;AI8051U.H&gt;

#define      LED_PORT      P0            // 定义LED端口
#define      LED_SW          P40             // 定义LED组开关

void LED_Init();
void chasing_led();
#endif
</code></pre>
<pre><code class="language-led.c">#include &quot;led.h&quot;

void LED_Init()
{
    P0M1 = 0x00;   P0M0 = 0x00;   //设置为准双向口
    P4M1 = 0x00;   P4M0 = 0x00;   //设置为准双向口
    LED_PORT = 0xFE;
    LED_SW = 0;
}

void chasing_led()
{
    Delay_ms(1000);
    LED_PORT = _cror_(LED_PORT, 1);
}
</code></pre>
<ol start="2">
<li>新建delay.c和delay.h文件</li>
</ol>
<pre><code class="language-delay.h">#ifndef __DELAY_H
#define __DELAY_H

/* Includes ------------------------------------------------------------------*/
#include &lt;intrins.h&gt;

void Delay1ms(void);
void Delay_ms(unsigned int ms);
#endif
</code></pre>
<pre><code>#include &quot;delay.h&quot;

void Delay1ms(void)        //@24.000MHz
{
    unsigned long edata i;

    _nop_();
    _nop_();
    _nop_();
    i = 5998UL;
    while (i) i--;
}

void Delay_ms(unsigned int ms)
{
    while (ms-- &gt; 0)
    {
      Delay1ms();
    }
}
</code></pre>
<ol start="3">
<li>修改sys_init.h</li>
</ol>
<pre><code class="language-sys_init.h">#ifndef __SYS_INIT_H
#define __SYS_INIT_H

/* Includes ------------------------------------------------------------------*/
#include &lt;AI8051U.H&gt;
#include &quot;sys_config.h&quot;
#include &quot;led.h&quot;


void SYS_Init(void);
#endif
</code></pre>
<ol start="4">
<li>修改sys_init.c</li>
</ol>
<pre><code class="language-sys_init.c">/* Includes ------------------------------------------------------------------*/
#include &quot;sys_init.h&quot;
/**
* @brief       系统初始化函数
* @param       无
* @retval      无
*/
void SYS_Init(void)
{
    WTST = 0;//设置程序指令延时参数,赋值为0可将CPU执行指令的速度设置为最快
    EAXFR = 1; //扩展寄存器(XFR)访问使能
    CKCON = 0; //提高访问XRAM速度
    LED_Init();
}
</code></pre>
<ol start="5">
<li>修改main.c</li>
</ol>
<pre><code class="language-main.c">#include &quot;sys_init.h&quot;

void main()
{
    SYS_Init();
    while(1)
    {
      chasing_led();
    }
}
</code></pre>
<ol start="6">
<li>
<p>编译并将.hex文件下载至实验箱验证</p>
<video controls="controls" src="forum.php?mod=attachment&amp;aid=74053"></video>
</li>
</ol>
页: [1] 2
查看完整版本: 《8051U深度入门到32位51大型实战视频》学习打卡 | 已送