找回密码
 立即注册
查看: 586|回复: 16

AI8051U单片机学用打卡 | 到这步可直接要 【免费+包邮送】的AI8051U实验箱

[复制链接]
  • 打卡等级:以坛为家II
  • 打卡总天数:582
  • 最近打卡:2025-10-15 07:15:58

27

主题

123

回帖

443

积分

中级会员

积分
443
发表于 2025-9-16 17:42:38 | 显示全部楼层 |阅读模式
新学期伊始,不忘助力国产替代初心,手头没有试验箱,先用“擎天柱”带领大一同学,跟随冲哥视频,学用STC AI8051U芯片讲义放在附件可下载。
第一节,搭建学用环境
一、下载必要软件工具
1. 下载AI 8051U使用手册,下载地址:
2. 下载安装pdf查看工具,推进下载wps办公软件,WPS办公软件下载地址:
3. 打开上面下载AI 8051U使用手册,参考第二章内容和步骤,下载安装keil开发工具。
图片1.png
file:////tmp/wps-lyj/ksohtml/wpsW1GNOV.jpg
4. 下载安装STC烧录工具,下载地址:
5. 下载并解压AI 8051U 试验箱参考学习代码包,下载地址:
二、设置烧录工具
1. 打开STC烧录工具,参考AI 8051U使用手册第二章第五节,添加型号和头文件,参考第二章第七节新建一个328051项目,如下图。
图片2.png file:////tmp/wps-lyj/ksohtml/wpskGPgn2.jpg
2. keil开发工具设置,参考AI 8051U使用手册第二章第七节2.2部分设置各个参数。
图片3.png file:////tmp/wps-lyj/ksohtml/wpsYGpOg9.jpg
三、创建第一个流水灯程序
1. 复制AI 8051U 试验箱参考学习代码包中流水灯main.c里代码到keil编辑栏main.c中,
图片4.png file:////tmp/wps-lyj/ksohtml/wpskYk6bg.jpg
并参考如下代码修改:
#include "AI8051U.h"
typedef unsigned char u8;
typedef unsigned int u16;
typedef unsigned long u32;
#define MAIN_Fosc        24000000UL
void  delay_ms(u8 ms);
void main(void)
{
    WTST = 0;  //设置程序指令延时参数,赋值为0可将CPU执行指令的速度设置为最快
    EAXFR = 1; //扩展寄存器(XFR)访问使能
    CKCON = 0; //提高访问XRAM速度
    P2M1 = 0x00;   P2M0 = 0x00;   //设置擎天柱p2端口为准双向口   
    while(1)
    {
        P20 = 0; //擎天柱LED 1点亮
        delay_ms(250);
        P20 = 1; //擎天柱LED 1熄灭
        P21 = 0; //擎天柱LED 2点亮
        delay_ms(250);
        P21 = 1; //擎天柱LED 2熄灭
        P22 = 0; //擎天柱LED 3点亮
        delay_ms(250);
        P22 = 1; //擎天柱LED 3熄灭
        P23 = 0; //擎天柱LED 4点亮
        delay_ms(250);
        P23 = 1; //擎天柱LED 4熄灭
        P24 = 0; //擎天柱LED 5点亮
        delay_ms(250);
        P24 = 1; //擎天柱LED 5熄灭
        P25 = 0; //擎天柱LED 6点亮
        delay_ms(250);
        P25 = 1; //擎天柱LED 6熄灭
        P26 = 0; //擎天柱LED 7点亮
        delay_ms(250);
        P26 = 1; //擎天柱LED 7熄灭
        P27 = 0; //擎天柱LED 8点亮
        delay_ms(250);
        P27 = 1; //擎天柱LED 8熄灭
    }
}
void  delay_ms(u8 ms)
{
     u16 i;
     do{
          i = MAIN_Fosc / 6000;
          while(--i);
     }while(--ms);
}
3. 编译下载到擎天柱。先参考下图,点击编译生成芯片烧录文件。
图片5.png file:////tmp/wps-lyj/ksohtml/wps4Zhi0m.jpg
2. 用数据线把擎天柱连接到电脑,如下图,同时按下Ap32)和B(电源开关)两个键,先松B键再松A键。
图片6.png file:////tmp/wps-lyj/ksohtml/wpsyRnnQt.png
烧录工具扫描串口会出现“USB-Write”字样,然后对照下图,红框选择编译的文件,最后按下“下载/编程”按钮烧录程序,擎天柱LED等流动起来了。
图片7.png file:////tmp/wps-lyj/ksohtml/wpsuZQ3Rz.jpg

学用STC公司AI8051U芯片日记.docx

1.11 MB, 下载次数: 10

回复

使用道具 举报 送花

  • 打卡等级:以坛为家II
  • 打卡总天数:582
  • 最近打卡:2025-10-15 07:15:58

27

主题

123

回帖

443

积分

中级会员

积分
443
发表于 2025-9-16 23:33:20 | 显示全部楼层
新学期伊始,不忘助力国产替代初心,手头没有试验箱,先用“擎天柱”带领大一同学,跟随冲哥视频,学用STC AI8051U芯片讲义(适合有c语言基础的同学)。
单片机(Single-Chip Microcomputer),又称微控制单元(MCU),是一种将中央处理器(CPU)、存储器(包括ROMRAM)、输入/输出(I/O)接口、定时器/计数器、中断系统等主要计算机组件电路元件集成在一块芯片上,并且可以用代码控制的微型计算机系统
上节课提到的P2端口就是单片机输入/输出(I/O)接口代码就是控制单片机的指令。学习单片机需要硬件电路和编程基础,零基础的同学在跟随着学习之外,抽空补习一点相关知识,建议遇到了哪儿就学哪儿,带着问题学,后期我们将实践PCB电路板,另外自行准备相关基础工具,比如电洛铁、万用表等。
第二节,实现不停电下载
1.利用烧录工具AICube助手自动生成代码。打开STC烧录工具,参考下图红框,三个步骤设置
file:///C:/Users/Administrator/AppData/Local/Temp/ksohtml6640/wps1.jpg
注意文件名最好都用英文,避免出现乱码,点击确定后,工具软件自动生成代码,并自动关联keil启动打开代码,stc工程师真牛!
file:///C:/Users/Administrator/AppData/Local/Temp/ksohtml6640/wps2.jpg
一个是main.c另一个是usb库文件
2. Main.c文件去掉绿色注释后的代码如下:
#include "config.h"                     //默认已包含stdio.hintrins.h等头文件
void main(void)
{
    SYS_Init();
    while (1)
    {
        USBLIB_OUT_Done();              //查询方式处理USB接收的数据
    }
}
void SYS_Init(void)
{
    EnableAccessXFR();                  //使能访问扩展XFR
    AccessCodeFastest();                //设置最快速度访问程序代码
    AccessIXramFastest();               //设置最快速度访问内部XDATA
    IAP_SetTimeBase();                  //设置IAP等待参数,产生1us时基
    P0M0 = 0x00; P0M1 = 0x00;           //初始化P0口为准双向口模式
    P1M0 = 0x00; P1M1 = 0x00;           //初始化P1口为准双向口模式
    P2M0 = 0x00; P2M1 = 0x00;           //初始化P2口为准双向口模式
    P3M0 = 0x00; P3M1 = 0x00;           //初始化P3口为准双向口模式
    P4M0 = 0x00; P4M1 = 0x00;           //初始化P4口为准双向口模式
    P5M0 = 0x00; P5M1 = 0x00;           //初始化P5口为准双向口模式
    P6M0 = 0x00; P6M1 = 0x00;           //初始化P6口为准双向口模式
    P7M0 = 0x00; P7M1 = 0x00;           //初始化P7口为准双向口模式
    delay_ms(1);
    USBLIB_Init();                      //USB库初始化
    delay_ms(1);
    EnableGlobalInt();                  //使能全局中断
}
void delay_us(uint16_t us)
{
    do
    {
        NOP(34);                        //(MAIN_Fosc + 500000) / 1000000 - 6
    } while (--us);
}
void delay_ms(uint16_t ms)
{
    uint16_t i;
    do
    {
        i = MAIN_Fosc / 6000;
        while (--i);
    } while (--ms);
}
void USBLIB_Init(void)
{
    usb_init();                         //初始化USB模块
    USB_SetIntPriority(0);              //设置中断为最低优先级
    set_usb_ispcmd("@STCISP#");         //设置USB不停电下载命令
}
void USBLIB_WaitConfiged(void)
{
    while (DeviceState != DEVSTATE_CONFIGURED) //等待USB完成配置
        WDT_Clear();                    //清看门狗定时器 (防止硬件自动使能看门狗)
}
void USBLIB_OUT_Done(void)
{
    if (bUsbOutReady)                   //查询是否有接收到USB主机发送数据
    {         
        USB_SendData(UsbOutBuffer, OutNumber); //原路返回, 用于测试        
        usb_OUT_done();                 //当前包的数据处理完成,通知USB主机可以发送下一包数据
    }
}
3. 添加流水灯代码:
在上方主函数void main(void)里面USBLIB_OUT_Done();”下一行添加上节课代码:
P20 = 0;  //擎天柱LED 1点亮
        delay_ms(250);
        P20 = 1;  //擎天柱LED 1熄灭
P22 = 0;  //擎天柱LED 3点亮
        delay_ms(250);
        P22 = 1;  //擎天柱LED 3熄灭
4. 编译好后按照下图设置,还得按上节课方法,同时按下擎天柱p32键(A键)和电源开关(B键)后,先松开电源开关,再松开p32,烧录程序扫描到USBWriter后点击“下载/编程”按钮把程序烧录到擎天柱后,LED1LED3闪烁,实现了可以不断电自动下载。
file:///C:/Users/Administrator/AppData/Local/Temp/ksohtml6640/wps3.jpg
file:///C:/Users/Administrator/AppData/Local/Temp/ksohtml6640/wps4.png
这种方法方便,将来有利于提高开发效率,值得提倡使用,但不利于初学者学习,可能看了一头雾水。作为初学者建议要学习理解其中原理。STC单片机的不断电自动下载功能是一种基于芯片内部ISP监控区的特殊编程技术,它通过软件复位机制触发单片机从ISP监控区启动,从而实现程序更新的无缝操作。这项技术巧妙地解决了传统下载方式需要频繁断电的痛点,显著提升了开发效率和系统可靠性。
STC单片机采用双启动区设计,包含两个关键程序存储区域:用户程序区和ISP监控区。ISP监控区是STC单片机出厂前已固化好的引导程序,负责接收上位机指令并执行存储器擦写操作。具体可参考学习芯片手册2.36.4章节。
file:///C:/Users/Administrator/AppData/Local/Temp/ksohtml6640/wps5.jpgfile:///C:/Users/Administrator/AppData/Local/Temp/ksohtml6640/wps6.jpg
参考芯片手册351页,USB范例程序,和手册第1005页,细心同学会发现,冲哥视频中代码有自定义三行代码,主要是ubs库版本问题。20250319以后的USB库就不需要自定义三行代码。
file:///C:/Users/Administrator/AppData/Local/Temp/ksohtml6640/wps7.jpgfile:///C:/Users/Administrator/AppData/Local/Temp/ksohtml6640/wps8.jpg
至于usb库文件有兴趣同学可自行找USB专题章节深入研究学习。

学用STC公司AI8051U芯片讲义2.docx

1.61 MB, 下载次数: 10

回复

使用道具 举报 送花

  • 打卡等级:偶尔看看III
  • 打卡总天数:44
  • 最近打卡:2025-10-10 14:30:18

16

主题

133

回帖

1168

积分

版主

积分
1168
发表于 2025-9-17 08:33:57 | 显示全部楼层
推荐优先看的 printf_usb("Hello World !\r\n")及usb不停电下载, 演示视频链接

回复

使用道具 举报 送花

  • 打卡等级:偶尔看看III
  • 打卡总天数:44
  • 最近打卡:2025-10-10 14:30:18

16

主题

133

回帖

1168

积分

版主

积分
1168
发表于 2025-9-19 13:59:15 | 显示全部楼层
新学期伊始,不忘助力国产替代初心,手头没有试验箱,先用“擎天柱”带领大一同学,跟随冲哥视频,学用STC AI8051U芯片讲义(适合有c语言基础的同学)。

单片机(Single-Chip Microcomputer),又称微控制单元(MCU),是一种将中央处理器(CPU)、存储器(包括ROM和RAM)、输入/输出(I/O)接口、定时器/计数器、中断系统等主要计算机组件电路元件集成在一块芯片上,并且可以用代码控制的微型计算机系统。
上节课提到的P2端口就是单片机输入/输出(I/O)接口,代码就是控制单片机的指令。学习单片机需要硬件电路和编程基础,零基础的同学在跟随着学习之外,抽空补习一点相关知识,建议遇到了哪儿就学哪儿,带着问题学,后期我们将实践PCB电路板,另外自行准备相关基础工具,比如电洛铁、万用表等。

第二节,实现不停电下载
1.利用烧录工具AICube助手自动生成代码。打开STC烧录工具,参考下图红框,三个步骤设置:
file:///C:/Users/Administrator/AppData/Local/Temp/ksohtml3188/wps1.jpg
注意文件名最好都用英文,避免出现乱码,点击确定后,工具软件自动生成代码,并自动关联keil启动打开代码,stc工程师真牛!
file:///C:/Users/Administrator/AppData/Local/Temp/ksohtml3188/wps2.jpg
一个是main.c另一个是usb库文件
2. Main.c文件去掉绿色注释后的代码如下:
#include "config.h"                     //默认已包含stdio.h、intrins.h等头文件

void main(void)
{
    SYS_Init();
    while (1)
    {
        USBLIB_OUT_Done();              //查询方式处理USB接收的数据
    }
}

void SYS_Init(void)
{
    EnableAccessXFR();                  //使能访问扩展XFR
    AccessCodeFastest();                //设置最快速度访问程序代码
    AccessIXramFastest();               //设置最快速度访问内部XDATA
    IAP_SetTimeBase();                  //设置IAP等待参数,产生1us时基
    P0M0 = 0x00; P0M1 = 0x00;           //初始化P0口为准双向口模式
    P1M0 = 0x00; P1M1 = 0x00;           //初始化P1口为准双向口模式
    P2M0 = 0x00; P2M1 = 0x00;           //初始化P2口为准双向口模式
    P3M0 = 0x00; P3M1 = 0x00;           //初始化P3口为准双向口模式
    P4M0 = 0x00; P4M1 = 0x00;           //初始化P4口为准双向口模式
    P5M0 = 0x00; P5M1 = 0x00;           //初始化P5口为准双向口模式
    P6M0 = 0x00; P6M1 = 0x00;           //初始化P6口为准双向口模式
    P7M0 = 0x00; P7M1 = 0x00;           //初始化P7口为准双向口模式
    delay_ms(1);
    USBLIB_Init();                      //USB库初始化
    delay_ms(1);
    EnableGlobalInt();                  //使能全局中断
}

void delay_us(uint16_t us)
{
    do
    {
        NOP(34);                        //(MAIN_Fosc + 500000) / 1000000 - 6
    } while (--us);
}

void delay_ms(uint16_t ms)
{
    uint16_t i;
    do
    {
        i = MAIN_Fosc / 6000;
        while (--i);
    } while (--ms);
}

void USBLIB_Init(void)
{
    usb_init();                         //初始化USB模块
    USB_SetIntPriority(0);              //设置中断为最低优先级
    set_usb_ispcmd("@STCISP#");         //设置USB不停电下载命令
}

void USBLIB_WaitConfiged(void)
{
    while (DeviceState != DEVSTATE_CONFIGURED) //等待USB完成配置
        WDT_Clear();                    //清看门狗定时器 (防止硬件自动使能看门狗)
}

void USBLIB_OUT_Done(void)
{
    if (bUsbOutReady)                   //查询是否有接收到USB主机发送数据
    {         
        USB_SendData(UsbOutBuffer, OutNumber); //原路返回, 用于测试        
        usb_OUT_done();                 //当前包的数据处理完成,通知USB主机可以发送下一包数据
    }
}
3. 添加流水灯代码:
在上方主函数void main(void)里面“USBLIB_OUT_Done();”下一行添加上节课代码:
P20 = 0;  //擎天柱LED 1点亮
        delay_ms(250);
        P20 = 1;  //擎天柱LED 1熄灭
P22 = 0;  //擎天柱LED 3点亮
        delay_ms(250);
        P22 = 1;  //擎天柱LED 3熄灭
4. 编译好后按照下图设置,还得按上节课方法,同时按下擎天柱p32键(A键)和电源开关(B键)后,先松开电源开关,再松开p32键,烧录程序扫描到USB—Writer后点击“下载/编程”按钮把程序烧录到擎天柱后,LED1和LED3闪烁,实现了可以不断电自动下载。
file:///C:/Users/Administrator/AppData/Local/Temp/ksohtml3188/wps3.jpg

file:///C:/Users/Administrator/AppData/Local/Temp/ksohtml3188/wps4.png
这种方法方便,将来有利于提高开发效率,值得提倡使用,但不利于初学者学习,可能看了一头雾水。作为初学者建议要学习理解其中原理。STC单片机的不断电自动下载功能是一种基于芯片内部ISP监控区的特殊编程技术,它通过软件复位机制触发单片机从ISP监控区启动,从而实现程序更新的无缝操作。这项技术巧妙地解决了传统下载方式需要频繁断电的痛点,显著提升了开发效率和系统可靠性。
STC单片机采用双启动区设计,包含两个关键程序存储区域:用户程序区和ISP监控区。ISP监控区是STC单片机出厂前已固化好的引导程序,负责接收上位机指令并执行存储器擦写操作。具体可参考学习芯片手册2.36.4章节。
file:///C:/Users/Administrator/AppData/Local/Temp/ksohtml3188/wps5.jpg

file:///C:/Users/Administrator/AppData/Local/Temp/ksohtml3188/wps6.jpg
参考芯片手册351页,USB范例程序,和手册第1005页,细心同学会发现,冲哥视频中代码有自定义三行代码,主要是ubs库版本问题。20250319以后的USB库就不需要自定义三行代码。
file:///C:/Users/Administrator/AppData/Local/Temp/ksohtml3188/wps7.jpg

file:///C:/Users/Administrator/AppData/Local/Temp/ksohtml3188/wps8.jpg
至于usb库文件有兴趣同学可自行找USB专题章节深入研究学习。
回复

使用道具 举报 送花

  • 打卡等级:偶尔看看III
  • 打卡总天数:44
  • 最近打卡:2025-10-10 14:30:18

16

主题

133

回帖

1168

积分

版主

积分
1168
发表于 2025-9-19 13:59:53 | 显示全部楼层
新学期伊始,不忘助力国产替代初心,手头没有试验箱,先用“擎天柱”带领大一同学,跟随冲哥视频,学用STC AI8051U芯片讲义。
第三节,定时器周期性调度任务
本节课主要任务是移植AI8051U试验箱代码27通过定时器周期性调度任务综合例程,温习一下单片机的定时器,解析一下程序代码。
一、学习内容
1. 定时器。什么为定时器,20250825版本的AI8051U芯片手册在第十七章介绍定时器,AI8051U芯片内置6个定时器(T0、T1、T2、T3、T4、T11),建议认真学习T0、T11两个定时器就够了,其他类似。

2. 定时器工作三部曲:
一是‌初始化配置‌:通过控制寄存器设置工作模式、时钟源和预分频器参数。
二是‌启动计数‌:计数器从初值开始,对时钟信号进行递增或递减计数。
三是‌溢出处理‌:当计数值达到上限(如16位计数器为65535)时,产生溢出中断或自动重载初值,循环执行,下图就是计时器工作示意图。‌‌

3. 学会查阅AI 8051U使用手册掌握定时器寄存器设置。本节课涉及T0定时器,查阅WTST、EAXFR、CKCON、P2M1、P2M0、AUXR、TH0、THL、ET0、TR0、EA。以AUXR为例,


二、代码移植与解析
1. 代码移植
拷贝上节课不停电可自动下载例程,打开AI8051U试验箱代码27通过定时器周期性调度任务综合例程代码,移植相关代码,只有一个man.c和usb_cdc_32.LIB两个文件。

2. 解析代码
man.c的代码如下:
#include "AI8051U.h" //引用AI8051U头文件,里面定义寄存器、引脚等等
#include "ai_usb.h" //引用USB库函数,实现不停电自动下载等
#define MAIN_Fosc        24000000UL //定义主时钟为24兆赫兹
#define Timer0_Reload   (MAIN_Fosc / 1000) //定义定时器重载值
//为了区别讲解第二节课不停电自动下载例程,特意引用20250319以前版本USB库函数,所以得自定义下面三行代码
char *USER_DEVICEDESC = NULL;
char *USER_PRODUCTDESC = NULL;
char *USER_STCISPCMD = "@STCISP#";     //设置自动复位到ISP区的用户接口命令
//定义任务调用结构体
typedef struct
{
u8 Run;               //任务状态:Run/Stop
u16 TIMCount;         //定时计数器
u16 TRITime;          //重载计数器
void (*TaskHook) (void); //任务函数,这里是传递函数地址,是指针、实参
} TASK_COMPONENTS;
//申明闪LED函数,具体函数放在主函数void main(void)后面
void ShowLed(void);
//定义任务函数
static TASK_COMPONENTS Task_Comps[]=
{
//状态  计数  周期  函数   
    {0, 500, 500, ShowLed},          //闪LED任务初始不亮,间隔500毫秒,周期500毫秒,任务函数名ShowLed
    /* 有新任务,先申明定义任务,再对照上面参数往下添加 */
};
//计算任务个数。Task_Comps是任务数组,Task_Comps[0]是第一个任务,sizeof(Task_Comps)是计算总任务占用内存字节数,sizeof(Task_Comps[0]) 是计算单个任务占用内存字节数,由于每个任务数据格式一样,所以Tasks_Max就是记录任务总个数。
u8 Tasks_Max = sizeof(Task_Comps)/sizeof(Task_Comps[0]);
/*************  本地函数声明    **************/
void Timer_config(void);
void Task_Marks_Handler_Callback(void);
void Task_Pro_Handler_Callback(void);
/******************** 主函数 **************************/
void main(void)
{
    WTST = 0;   //设置程序指令延时参数,赋值为0可将CPU执行指令的速度设置为最快
    EAXFR = 1; //扩展寄存器(XFR)访问使能
    CKCON = 0; //提高访问XRAM速度
    P2M1 = 0x00; //设置为准双向口
P2M0 = 0x00;
Timer_config(); //启动定时器
usb_init();   //初始化USB
EA = 1;      //打开总中断
    while(1)
    {
      if( DeviceState != DEVSTATE_CONFIGURED ) //
continue;
if( bUsbOutReady )
{
usb_OUT_done();
}
Task_Pro_Handler_Callback();
    }
}
//========================================================================
// 函数: Task_Pro_Handler_Callback
// 描述: 任务处理回调函数.
// 参数: None.
// 返回: None.
//========================================================================
void Task_Pro_Handler_Callback(void)
{
    u8 i;
    for(i=0; i<Tasks_Max; i++)
    {
        if(Task_Comps.Run) /* If task can be run */
        {
            Task_Comps.Run = 0;      /* Flag clear 0 */
            Task_Comps.TaskHook();   /* Run task */
        }
    }
}
//========================================================================
// 函数: Task_Handler_Callback
// 描述: 任务标记回调函数.
// 参数: None.
// 返回: None.
//========================================================================
void Task_Marks_Handler_Callback(void)
{
    u8 i;
    for(i=0; i<Tasks_Max; i++)
    {
        if(Task_Comps.TIMCount)      /* If the time is not 0 */
        {
            Task_Comps.TIMCount--;   /* Time counter decrement */
            if(Task_Comps.TIMCount == 0) /* If time arrives */
            {
                /*Resume the timer value and try again */
                Task_Comps.TIMCount = Task_Comps.TRITime;  
                Task_Comps.Run = 1;      /* The task can be run */
            }
        }
    }
}
//========================================================================
// 函数: Timer_config
// 描述: 定时器配置
// 参数: none.
// 返回: none.
void Timer_config(void)
{
    AUXR = 0x80;    //Timer0 set as 1T, 16 bits timer auto-reload,
    TH0 = (u8)(Timer0_Reload / 256);
    TL0 = (u8)(Timer0_Reload % 256);
    ET0 = 1;        //Timer0 interrupt enable
    TR0 = 1;        //Tiner0 run
}
//========================================================================
// 函数: Timer0_ISR_Handler
// 描述: Timer0中断函数.
// 参数: none.
// 返回: none.
//========================================================================
void Timer0_ISR_Handler (void) interrupt TMR0_VECTOR //进中断时已经清除标志
{
  Task_Marks_Handler_Callback(); //任务标记回调函数
}
void ShowLed(void)
{
P20 =!P20;
P23 =!P23;
}
本例程是开启了定时器,主函数man循环不断调用Task_Pro_Handler_Callback(),循环判断任务体数组各任务成员属性Task_Comps.Run状态,状态为可运行(即可为1),将状态设置为不可运行,即Task_Comps.Run = 0,然后调用运行任务函数,本实例任务是闪LED灯,Task_Comps.TaskHook()这句就是调用 ShowLed()函数。ShowLed()函数是让擎天柱P20、P23两个LED灯同时闪烁。
定时器是1毫秒自动调用一次Task_Marks_Handler_Callback()函数,循环判断任务体数组各任务成员属性Task_Comps.TIMCount值是否大于0,TIMCount大于0就减1,直到TIMCount等于0时,将任务可运行标志设置为可运行即Task_Comps.Run=1,把任务周期值重新赋值给任务计数器,即Task_Comps.TIMCount = Task_Comps.TRITime。
回复

使用道具 举报 送花

  • 打卡等级:以坛为家II
  • 打卡总天数:582
  • 最近打卡:2025-10-15 07:15:58

27

主题

123

回帖

443

积分

中级会员

积分
443
发表于 2025-9-19 14:57:47 | 显示全部楼层
新学期伊始,不忘助力国产替代初心,手头没有试验箱,先用“擎天柱”带领大一同学,跟随冲哥视频,学用STC AI8051U芯片讲义。
第四节,自动生成多文件项目代码,温习C/C++语言
本节课任务是学用AICube自动生成程序,温习c语言变量作用域
一、更新STC烧录工具和USB库,自动生成项目文件
1. 下载资料。STC烧录工具最新版是AiCube-ISP-V6.96CUSB最新库文件是20250716版;
2. 更新更新keil头文件。解压运行烧录工具(AiCube-ISP-V6.96C.exe),按下图顺序操作找到keil安装目录(keil_v5),更新头文件。

3. 打开AiCube自动生成项目代码。参考下图顺序,点击启动烧录工具AiCube.设置好单片机型号、项目名称、保存路径,这里项目类型设置为多代码文件项目。

点击确定后,勾选USB,通用串行总线和TIMER0,定时器0选相框,USB库函数设置“与printf函数关联”为是。

定时器0开启中断使能,如下图,点击自动生成代码按钮弹出提示项目创建成功提示,再点确定后会关联启动keil打开所生成的项目文件。

AiCube自动生成的项目包含三个c文件和usb库,查看各个文件内容,发现大量注释,分门别类提示放置用户的变量、函数,包含头文件等等,点击编译,编译器提示0错误0警告。足见AiCube功能强大方便。在看代码时,遇到不清楚函数、变量等,可鼠标右键点击追溯函数、变量定义,具体操作参考下图。

二、温习验证c语言变量生命周期
1. 移植AI8051U实验箱多任务代码。个人觉得官方推荐的实验箱代码:27-通过定时器周期性调度任务综合例程相当好。先拷贝其中Sources\src\Task.cSources\inc\Task.hdemo项目相应目录下。对照我刚才AiCube自动生成的项目,Task.c拷贝到G:\STCproject\AI8051U_PROJECT\demo\Sources\目录下,Task.h拷贝到G:\STCproject\AI8051U_PROJECT\demo\Sources\inc目录,下,路径可参考下图。

2. 将Task.c添加到项目中。展开demo,鼠标右键点击AiCube添加现存文件task.c,参考下图操作。

3. 主函数添加代码。main.c文件要在13#include "config.h"下面添加一句,#include "Task.h",即包含了Task.c的头文件,在第49行“在此添加主函数中用户主循环代码”下一行添加任务处理回调函数Task_Pro_Handler_Callback();备注:Task.c任务函数功能请参考上一节课解析。

4. 添加任务函数和变量。task.c文件添加一个数组变量,这里就拷贝27-通过定时器周期性调度任务综合例程app_Display.c文件的t_dispiay[]标准字库数组,定义一个用于验证变量display_index,再定义一个任务函数Test_Demo()驱动擎天柱p2端口led灯。task.h文件申明一下任务函数Test_Demo()timer.c文件第13#include "config.h"下面添加一句,#include "Task.h";在第61下面添加一句任务标记回调函数:Task_Marks_Handler_Callback();
5. 烧录验证。编译烧录看到擎天柱LED在闪烁,说明task.c文件display_index变量是全局变量,生命周期是程序运行到结束。
三、分析理解Keil多文件项目中变量生命周期
C/C++语言中,变量的作用域和链接性是两个独立但相互关联的概念。变量display_indextask.c文件中定义为全局变量,具有外部链接性,只要通过适当的声明可以在程序的任何地方被访问
1.作用域(Scope):决定变量在源代码中可见的范围全局变量在文件顶层定义,作用域为整个文件函数内部定义的变量作用域仅限于该函数内
2.链接性(Storage Class):决定变量在不同编译单元间的可见性外部链接(external linkage):默认情况下,未使用static关键字修饰的全局变量具有外部链接性,可在程序各处访问
3.内部链接 internal linkage:使用static关键字修饰的全局变量仅在当前文件内可见
task.c文件中的全局变量display_index没有使用static关键字修饰,因此它具有外部链接性。这使得即使主函数main.c文件未在头文件中声明extern int display_index,也能通过调用task.c文件中的函数Test_Demo()间接访问和修改display_index的值。因为函数Test_Demo()在定义时已经能够访问task.c文件中的全局变量display_index,且函数Test_Demo()的实现代码与display_index的存储位置已建立直接关联。
函数Test_Demo()作为task.c文件的接口,封装了对全局变量display_index的操作其核心机制在于函数封装作用主函数main.c文件调用Test_Demo()时,实际执行的是task.c文件中已绑定display_index变量地址的函数代码。函数Test_Demo()的作用域包含task.c文件的所有全局变量,因此可以直接访问和修改display_index的值,无需额外声明。这种机制是C/C++语言设计的基本特性之一,它允许通过函数封装实现对全局状态的修改,同时保持代码的模块化和可维护性。
附件内容:课件讲义、程序源代码、擎天柱验证视频

04自动生成多文件项目代码,温习CC 语言AiCube.rar

387.69 KB, 下载次数: 4

擎天柱闪灯验证变量.mp4

1.37 MB, 下载次数: 6

学用STC公司AI8051U芯片讲义4.docx

931.6 KB, 下载次数: 6

回复

使用道具 举报 送花

  • 打卡等级:以坛为家II
  • 打卡总天数:582
  • 最近打卡:2025-10-15 07:15:58

27

主题

123

回帖

443

积分

中级会员

积分
443
发表于 2025-9-21 12:28:39 | 显示全部楼层
新学期伊始,不忘助力国产替代初心,手头没有试验箱,先用“擎天柱”带领大一同学,跟随冲哥视频,学用STC AI8051U芯片讲义。

第五节,学用调试仿真接口(擎天柱LED_DIP40)
本节课主要任务是用擎天柱配合烧录工具cdc/hid串口助手,验证理解仿真接口擎天柱LED的指令意思,尝试调用封装接口函数。
一、准备验证工作。
拷贝上节课04自动生成代码AiCube,连接擎天柱到电脑上。由于上节课烧录到擎天柱的代码包含打开USB-CDC功能,打开烧录工具会多一个串口,我这里显示是(COM6USB-CDC(如下图)。鼠标点击菜单“调试仿真接口”找到并鼠标左键点击打开“擎天柱-LED-DIP404)”,再鼠标左键点击“调试仿真接口”菜单“接口协议及帮助”,鼠标左键点击打开“DIP40封装LED接口”,学习功能1-4
图片1.png
二、验证DIP40各功能指令。
1. 功能1控制DIP40的指定管脚输出低电平
字节数
1
2
3
4
5
6
7
命令格式:
4CH
45H
44H
28H
O2H
00H
Px
命令注解
命令头
后面有效数据长度
固定为00H
端口的状态数据
   px的注解一览表
px
Bit7
Bit6
Bit5
Bit4
Bit3
Bit2
Bit1
Bit0
px位解析
固定为0
管脚的组,作为高字节
管脚的位,作为低字节
计算时注意:Bit6Bit5Bit4Bit3作为一个字节计算
示例1末位px解析表
px
Bit7
Bit6
Bit5
Bit4
Bit3
Bit2
Bit1
Bit0
03H
0
0
0
0
0
0
1
1
px位解析
固定为0
值为0指定P0端口
值为3指定P0端口第3管脚
示例2末位px解析表
px
Bit7
Bit6
Bit5
Bit4
Bit3
Bit2
Bit1
Bit0
25H
0
0
1
0
0
1
0
1
px位解析
固定为0
值为4指定P4端口
值为5指定P4端口第5管脚
组:Bit6Bit5Bit4Bit3二进制值:0 1 0 0换算十六进制值为4
位:Bit2Bit1Bit0二进制值:1 0 1换算十六进制值为5
验证:设置点亮P5.7
P5.7
Bit7
Bit6
Bit5
Bit4
Bit3
Bit2
Bit1
Bit0
2FH
0
0
1
0
1
1
1
1
固定为0
值为5指定P5端口
值为7指定P5端口第7管脚
图片2.png
STC工程师封装了LED40_ClrBit函数,在ai_usb.h中申明,函数有两个参数,第一个参数是指定端口,第二个参数指定端口引脚
LED40_ClrBit(0, 3);    //设置P0.3口输出低电平
LED40_ClrBit(4, 5);    //设置P4.5口输出低电平
2. 功能2控制DIP40的指定管脚输出高电平
控制命令除了px的bit7:固定为1外,其他的跟上面“控制DIP40的指定管脚输出低电平”一模一样,STC工程师封装函数名LED40_SetBit,可直接调用。
LED40_SetBit(4, 5);    //设置P4.5口输出高电平
3. 功能3控制DIP40的各个管脚上LED的状态
字节数
1
2
3
4
5
6
7
命令格式:
4CH
45H
44H
28H
O2H
x1
Px
命令注解
命令头
后面有效数据长度
屏蔽位
端口的状态数据
6字节x1
x1位数
Bit7
Bit6
Bit5
Bit4
Bit3
Bit2
Bit1
Bit0
x1位解析
固定为0
P5
P4
P3
P2
P1
P0
验证命令结论:最好单独设置每个端口,一次设置多个端口有异常。比如:在CDC/HID串口助手发送HEX格式数据4CH 45H 44H 28H 02H 3FH 00HDIP40LED全部亮了,再发送4CH 45H 44H 28H 02H 3FH FFH
只有P0端口熄灭,其他等依然亮着(如下图)。但是,STC工程师封装函数名LED40_SetPort,可直接调用。
LED40_SetPort(0, 0x55);    //设置P0口输出55H
图片3.png

4. 功能4 控制DIP40的各个管脚上LED的状态
命令格式: 4CH 45H 44H 28H x1 x2 px ...
字节数
1
2
3
4
5
6
7
命令格式:
4CH
45H
44H
28H
x1
X2
Px
命令注解
命令头
后面有效数据长度
屏蔽位
端口的状态数据
第五字节x1指定后面有效数长度
第六字节x2指定P0P5端口的屏蔽位,哪位值等于1就指定对应端口,比如Bit0值等1时指定P0端口。
X2
Bit7
Bit6
Bit5
Bit4
Bit3
Bit2
Bit1
Bit0
X2位解析
固定为0不用
P5
P4
P3
P2
P1
P0
验证指令:让DIP40LED全熄灭,可在CDC/HID串口助手发送HEX格式数据
4CH 45H 44H 28H 07H 3FH FFH FFH FFH FFH FFH FFH
DIP40LED全亮,可在CDC/HID串口助手发送HEX格式数据
4CH 45H 44H 28H 07H 3FH 00H 00H 00H 00H 00H 00H
图片4.png
STC工程师封装函数名LED40_SendData,可直接调用,函数有两个参数,第一个参数设置数组,第二参数指定数组长度。数组第一个值是x2指定P0P5端口的屏蔽位,数组第二个值是指定端口状态。
三、调用第三功能,让DIP40LED与擎天柱同步显示
任务函数
static TASK_COMPONENTS Task_Comps[]=
{
//状态  计数  周期  函数
{0, 2000, 2000, Test_Demo}
};
测试函数
void Test_Demo(void)
{
P2 = t_display[display_index];
LED40_SetPort(2, t_display[display_index]);
if(++display_index >= 40)  display_index = 0;
}

学用STC公司AI8051U芯片讲义5.docx

595.77 KB, 下载次数: 4

05学用调试接口擎天柱LED_DIP40.zip

462.5 KB, 下载次数: 5

擎天柱同步DIP40显示.mp4

1.51 MB, 下载次数: 5

点评

到这本,可以直接跟 客服 要 免费+包邮送的 AI8051U实验箱  详情 回复 发表于 2025-9-21 15:58
回复

使用道具 举报 送花

  • 打卡等级:以坛为家II
  • 打卡总天数:582
  • 最近打卡:2025-10-15 07:15:58

27

主题

123

回帖

443

积分

中级会员

积分
443
发表于 2025-9-21 12:35:11 | 显示全部楼层
请教大佬一下,如上贴子,把wps表格复制粘贴到论坛贴后,表格变形了,线条也不显示了,这个问题如何解决。谢谢
回复

使用道具 举报 送花

  • 打卡等级:以坛为家I
  • 打卡总天数:208
  • 最近打卡:2025-10-15 11:03:15

787

主题

1万

回帖

1万

积分

管理员

积分
19770
发表于 2025-9-21 15:57:13 | 显示全部楼层
回复

使用道具 举报 送花

  • 打卡等级:以坛为家I
  • 打卡总天数:208
  • 最近打卡:2025-10-15 11:03:15

787

主题

1万

回帖

1万

积分

管理员

积分
19770
发表于 2025-9-21 15:58:05 | 显示全部楼层
垂柳*** 发表于 2025-9-21 12:28
新学期伊始,不忘助力国产替代初心,手头没有试验箱,先用“擎天柱”带领大一同学,跟随冲哥视频,学用STC  ...

到这步,可以直接跟 客服 要 【免费+包邮送】的 AI8051U实验箱
回复

使用道具 举报 送花

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

QQ|手机版|深圳国芯人工智能有限公司 ( 粤ICP备2022108929号-2 )

GMT+8, 2025-10-16 03:41 , Processed in 0.136918 second(s), 97 queries .

Powered by Discuz! X3.5

© 2001-2025 Discuz! Team.

快速回复 返回顶部 返回列表