《8051U深度入门到32位51大型实战视频》学习打卡 | 已送
兴趣是最好的学习动力。有句话说:活到老,学到老!学习从什么时候开始都不晚。今天开始第一步!第一集:主要介绍8051U的一些强劲功能和实验板上的实验演示。
这个世界发展很快,只有不断充实自己,才能跟上时代步伐。
第二集:先跟着喊一下口号:哪怕梦想让我们拼得遍体鳞伤,这一次我们也要通往直前。
开发板功能介绍:
环境的搭建:
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:18 编辑
# 第三集 点亮第一颗LED
## 1. 新建Keil工程
* 打开Keil软件,点击菜单Project->New uVision Project,将工程文件名保存到相应的文件夹中
* 按下图所示选择STC8051U-32Bit Series

* 新建一个文件(Ctrl+N),并将其保存成main.c,并将main.c加入到工程文件中
!(data/attachment/forum/202412/03/214022vbmo2xe5gs52btge.png "image.png")
* 将Options选项按以下方式设置


* 点击Configuration,配置文本编码和Tab键插入的空格数

* 代码编写
* !(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")
## 第四集 USB不断电下载
### 下载USB驱动
* 从官网下载USB库文件,并解压

得到以下的文件
!(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

通过这样的设置后,除第一次需要按P3.2和电源键外,后面每次都可以自动下载程序。
## 第五集 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-串口调试

### 进制简介
二进制,八进制,十进制,十六进制
### 数据的基本类型

如果要使用64位的变量,比如double,需要要文件头加入语句:`#pragma float64`
### C语言的常用运算符
* 算术运算符:+ - * / % ++ --
* 关系运算符:><==>=<=!=
* 逻辑运算符:&& || ^
* 赋值运算符:=+=-=*=/=<<=<<=&=|=^=
* 位运算符:<<>>& | ^ ~
## 第六集 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是否被按下。按键被按下进,分出现拉动的现像,如下图所示:

因此在判断时,因延时20ms后再判断一次按键是否被按下
#### 延时函数
打开IPS软件,选择如下:

将代码复制到工程中,并编写如下代码:
```
#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灭的功能
<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 &= 0x7F; //定时器时钟12T模式
TMOD &= 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 <AI8051U.H>
#include "stc32_stc8_usb.h"
char *USER_DEVICEDESC = NULL;
char *USER_PRODUCTDESC = NULL;
char *USER_STCISPCMD = "@STCISP#"; /* 对应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 &= 0x7F; //定时器时钟12T模式
TMOD &= 0xF0; //设置定时器模式
TL0 = 0x3F; //设置定时初始值
TH0 = 0x01; //设置定时初始值
TF0 = 0; //清除TF0标志
TR0 = 1; //定时器0开始计时
ET0 = 1; //使能定时器0中断
}
void Timer0_Isr(void) interrupt 1
{
LED0 = ~LED0;
}
</code></pre>
再接再励,免费送试验箱一套方便前几集的硬件操作+后续学习! 昨天已安排了,请注意查收 <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 <AI8051U.H>
void SYS_Init(void);
#endif
</code></pre>
<ul>
<li>新建并编写sys_init.c文件,主要是系统初始化函数编写处,并将文件文件加入工程项目中。</li>
</ul>
<pre><code>#include "sys_init.h"
void SYS_Init(void)
{
// 代码编写
}
</code></pre>
<ul>
<li>main.c文件</li>
</ul>
<pre><code>#include "sys_init.h"
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 "delay.h"
#include <intrins.h>
#include <AI8051U.H>
#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 "led.h"
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 <intrins.h>
void Delay1ms(void);
void Delay_ms(unsigned int ms);
#endif
</code></pre>
<pre><code>#include "delay.h"
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-- > 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 <AI8051U.H>
#include "sys_config.h"
#include "led.h"
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 "sys_init.h"
/**
* @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 "sys_init.h"
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&aid=74053"></video>
</li>
</ol>
页:
[1]
2