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

定时器中断 | 集中在这个帖子打卡

[复制链接]
  • 打卡等级:初来乍到
  • 打卡总天数:7
  • 最近打卡:2026-01-14 15:10:29
已绑定手机

5

主题

13

回帖

59

积分

注册会员

积分
59
发表于 2025-12-24 21:35:13 | 显示全部楼层 |阅读模式
学习了第七集定时器中断,效果很好,加上自己修改、综合了其他程序加入,也成功实现了,在之前没解决的问题也解决了,对于新手小白非常友好!还得是8051u!


#include <AI8051U.H>
#include "led.h"
#include "ai_usb.h"
#include "timer.h"

//LED变量
unsigned char ucLed = 0x01;                //0000 0001


//Timer变量
unsigned int xms = 0;
unsigned int Led_Dly = 0;

//function
void Led_Proc(void);

void main(void)
{
        EAXFR = 1;                                        //
        WTST = 0;                                        //
        CKCON = 0;                                        //
        
    P0M0 = 0x00; P0M1 = 0x00;        //
    P1M0 = 0x00; P1M1 = 0x00;
    P2M0 = 0x00; P2M1 = 0x00;
    P3M0 = 0x00; P3M1 = 0x00;
    P4M0 = 0x00; P4M1 = 0x00;
    P5M0 = 0x00; P5M1 = 0x00;
    P6M0 = 0x00; P6M1 = 0x00;
    P7M0 = 0x00; P7M1 = 0x00;

        Timer0_Init();
        usb_init();
        EA = 1;
        
        while(1)
        {
                if(bUsbOutReady)
                {
                        usb_OUT_done();
                }
                Led_Proc();
        }
}



void Timer0_Isr(void) interrupt 1
{
        xms++;
        Led_Dly++;
        
        Led_Display(ucLed);
}


void Led_Proc(void)
{
        if(Led_Dly < 500)return;
        Led_Dly = 0;
        
        ucLed = _crol_(ucLed,1);        //zuoyi 1 wei
}

回复

使用道具 举报 送花

  • 打卡等级:以坛为家I
  • 打卡总天数:324
  • 最近打卡:2026-02-12 09:05:32

835

主题

1万

回帖

2万

积分

管理员

积分
22170
发表于 2025-12-24 21:52:08 | 显示全部楼层
截图202512242151544340.jpg



#include <AI8051U.H>                //AI8051U的通用头文件,头文件不分大小写
#include "ai_usb.h"                        //USB库的头文件,头文件不分大小写
/*
如何获得上面这2个头文件,如已按照前面介绍的方法:
www.STCAI.com 网站,【软件工具 | 工具软件】处,下载安装最新的【AIapp-ISP 软件】,
选择其中的选项卡 【Keil仿真设置 】,
点击【添加型号和头文件到Keil中,并添加仿真器驱动到Keil中】按钮,
则 Ai8051U.h 和 AI_usb.h 都会自动复制到Keil 中, 包含进来就可以直接使用,
大家可以打开看下其中的内容,AI_usb.h 和 stc32_stc8_usb.h是相似的,只需用其中的1个头文件,
具体见 Keil_v5\C251\INC\STC 目录,或 Keil_v5\C51\INC\STC 目录。
如将对应的 USB库文件添加到 项目中,后续用户程序中,USB如收到命令字符串 "@STCISP#"
USB库函数就会自动软复位到系统ISP程序区,实现 USB不停电下载,具体见相应部分的说明。
//char *USER_DEVICEDESC = NULL;
//char *USER_PRODUCTDESC = NULL;
//char *USER_STCISPCMD = "@STCISP#";
//使用20250319之前版本的库函数时需要在用户代码中增加上面3行定义。
//使用20250319及以后的版本都不再需要上面的定义
*/

bit         t0_flag = 0;                   //定义1个位变量,T0事件位变量标志,记录定时器0已产生中断
// 供主循环查询到该定时器已产生中断,在主循环中处理定时器0的中断任务,不堵塞其他中断
bit         t1_flag = 0;                   //定义1个位变量,T1事件位变量标志,记录定时器1已产生中断
// 供主循环查询到该定时器已产生中断,在主循环中处理定时器1的中断任务,不堵塞其他中断

void Timer0_Isr(void) interrupt TMR0_VECTOR                //定时器0中断服务程序
{
        P00 = ~P00;                                //P00灯闪烁,中断服务程序中尽量少执行长的任务,防止堵塞其他中断
        t0_flag = 1;                        //置1,记录定时器0已产生中断,供主循环判断要处理定时器0的中断任务
}
//定时器0中断服务程序,TMR0_VECTOR在AI8051U.H头文件中已宏定义为1

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

void  Timer1_Isr(void)  interrupt  TMR1_VECTOR  
{
        P07 = ~P07;                                //P07灯闪烁,中断服务程序中尽量少执行长的任务,防止堵塞其他中断
        t1_flag = 1;                        //置1,记录定时器1已产生中断,供主循环判断要处理定时器1的中断任务
}
//定时器1中断服务程序,TMR1_VECTOR在AI8051U.H头文件中已宏定义为3

void Timer1_Init(void)                //定时器1初始化,500毫秒@40.000MHz
{
        TM1PS = 0x19;                        //设置定时器时钟预分频 ( 注意:并非所有系列都有此寄存器,详情请查看数据手册 )
        AUXR &= 0xBF;                        //定时器时钟12T模式
        TMOD &= 0x0F;                        //设置定时器模式
        TL1 = 0x99;                                //设置定时初始值
        TH1 = 0x05;                                //设置定时初始值
        TF1 = 0;                                //清除TF1标志
        TR1 = 1;                                //定时器1开始计时
        ET1 = 1;                                //使能定时器1中断
}

void  sys_init(void)                        //系统初始化
{
        EAXFR = 1;                                        //允许访问扩展的特殊寄存器,XFR
        WTST = 0;                                        //设置取程序代码等待时间,赋值为 0 表示不等待,程序以最快速度运行
        CKCON = 0;                                        //设置访问片内的 xdata 速度,赋值为 0 表示用最快速度访问,不增加额外的等待时间

        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 口为准双向口模式
}

void  main(void)
{
        sys_init();                                        //调用系统初始化函数
        usb_init();                                        //调用USB初始化函数,不需要立即判断电脑已正确识别到USB从设备
        /*         USB型单片机从设备,如需要主动向电脑发送数据,
                在执行USB_SendData( )函数和printf_usb( )函数时,
                这两个函数已增加了判断电脑是否已正确识别到USB从设备的程序。
                如果电脑要主动发送数据给USB从设备,电脑自己会主动判断与USB从设备是否已正确连接。
        */
        EA = 1;                                                //使能中断

        Timer0_Init();                                //调用定时器0初始化函数
        Timer1_Init();                                //调用定时器1初始化函数

        P40 = 0;                                        //给LED灯供电

        while(1)                                          //主循环中查询需要处理的各种事件,如T0/T1中断事件,并打印输出状态
        {
                if(t0_flag)                                //主循环中查询,定时器0是否已产生中断,是否有需要处理的定时器0事件
                {
                        t0_flag = 0;                //清0,T0事件位变量标志
                        printf_usb("Timer0!\r\n");
                }
                if(t1_flag)                                //主循环中查询,定时器1是否已产生中断,是否有需要处理的定时器1事件
                {
                        t1_flag = 0;                //清0,T1事件位变量标志
                        printf_usb("Timer1!\r\n");
                }
        }
}


回复

使用道具 举报 送花

  • 打卡等级:以坛为家I
  • 打卡总天数:324
  • 最近打卡:2026-02-12 09:05:32

835

主题

1万

回帖

2万

积分

管理员

积分
22170
发表于 2025-12-24 23:18:01 | 显示全部楼层
要 做到 USB不停电下载
要 尝试 AiCube 图形化自动配置生成程序工具
推荐优先看的:  
printf_usb("Hello World !\r\n")
USB不停电下载, 演示视频链接:
https://www.stcaimcu.com/thread-19077-1-1.html

下载 最新的 AiCube-ISP-V6.96L 或以上版本软件 !

深圳国芯人工智能有限公司-工具软件

下载 最新的 USB库函数,永远用最新的 USB库函数 !
深圳国芯人工智能有限公司-库函数
下载 最新的 用户手册 !
下载 最新的 上机实践指导书 !

下载 最新的 Ai8051U 用户手册
https://www.stcaimcu.com/data/download/Datasheet/AI8051U.pdf

下载 最新的 Ai8051U 实验指导书,
AiCube 图形化自动配置生成程序工具使用说明
https://www.stcaimcu.com/data/do ... %AF%BC%E4%B9%A6.pdf


上面是 小李 演示:Ai8051U, printf_usb("Hello World !\r\n")及usb不停电下载@AiCube之图形化程序自动生成
回复

使用道具 举报 送花

  • 打卡等级:以坛为家I
  • 打卡总天数:324
  • 最近打卡:2026-02-12 09:05:32

835

主题

1万

回帖

2万

积分

管理员

积分
22170
发表于 2025-12-24 23:18:51 | 显示全部楼层
楼主 USB程序,不是我们最优化后的程序
回复

使用道具 举报 送花

  • 打卡等级:初来乍到
  • 打卡总天数:7
  • 最近打卡:2026-01-14 15:10:29
已绑定手机

5

主题

13

回帖

59

积分

注册会员

积分
59
发表于 2026-1-14 15:10:29 | 显示全部楼层
感谢 www.STCAI.com 的支持 !利用注册获得Ai8051U芯片 !以下是简单的的实验程序,效果非常好!


#include "ai8051u.h"
#include "ai_usb.h"

#define MAIN_Fosc 40000000ul

unsigned char n;

unsigned char ucLed = 0x01;

void delay(unsigned int xms)
{
回复

使用道具 举报 送花

  • 打卡等级:初来乍到
  • 打卡总天数:7
  • 最近打卡:2026-01-14 15:10:29
已绑定手机

5

主题

13

回帖

59

积分

注册会员

积分
59
发表于 2026-1-14 15:12:46 | 显示全部楼层
用ai8051u核心功能板实现了简单流水灯的程序实现,非常棒!#include "ai8051u.h"
#include "ai_usb.h"
#define MAIN_Fosc 40000000ul
unsigned char n;
unsigned char ucLed = 0x01;
void delay(unsigned int xms)
{        unsigned int i;
        do{
                i = MAIN_Fosc / 6000;
                while(i--);
        }while(xms--);
}


void main(void)
{
        EAXFR = 1;
        WTST = 0;
        CKCON = 0;
      
        P2M0 = 0x00;
        P2M1 = 0x00;
      
        usb_init();
        EA = 1;
      
        P2 = 0x01;        //1111 1110
        while(1)
        {
                if(bUsbOutReady)
                {
                        usb_OUT_done();
                }
                for(n = 0; n < 8; n++)
                {
                        ucLed = 1 << n;
                        P2 = ~ucLed;
                        delay(500);
                }
      
        }
回复

使用道具 举报 送花

  • 打卡等级:初来乍到
  • 打卡总天数:7
  • 最近打卡:2026-01-14 15:10:29
已绑定手机

5

主题

13

回帖

59

积分

注册会员

积分
59
发表于 2026-1-14 15:14:32 | 显示全部楼层
学习了时钟和按键的结合,利用按键可以调整时钟的时、分、秒,结果太棒了!


#include <AI8051U.H>
#include "ai_usb.h"
#include "seg.h"
#include "timer.h"
#include "key.h"

unsigned int xms = 0;                  // 毫秒计时变量
unsigned char Seg_String[10];          // 显示字符串缓存(预留小数点/结束符)
unsigned char Seg_Code[8] = {0,0,0,0,0,0,0,0}; // 数码管段码数组
unsigned char pos = 0;                 // 数码管扫描位置
unsigned int Seg_Dly = 0;              // 显示刷新延时

unsigned char Key_Value;               // 按键扫描值
unsigned char Key_Old,Key_Down;        // 按键状态(旧值/下降沿)
unsigned char Key_Dly = 0;             // 按键消抖延时
unsigned char Seg_Mode = 0;            // 显示模式:0-正常时钟 1-调时 2-调分 3-调秒

// RTC时间变量
unsigned char hour = 22;
unsigned char min = 42;
unsigned char sec = 00;

void Seg_Proc(void);
void Key_Proc(void);
void RTC_Proc(void);

void main(void)
{
    EAXFR = 1;
    WTST = 0;
    CKCON = 0;

    // 所有端口设为推挽输出(根据硬件调整)
    P0M0 = 0x00; P0M1 = 0x00;
    P1M0 = 0x00; P1M1 = 0x00;
    P2M0 = 0x00; P2M1 = 0x00;
    P3M0 = 0x00; P3M1 = 0x00;
    P4M0 = 0x00; P4M1 = 0x00;
    P5M0 = 0x00; P5M1 = 0x00;
    P6M0 = 0x00; P6M1 = 0x00;
    P7M0 = 0x00; P7M1 = 0x00;

    Timer0_Init();   
    usb_init();
    EA = 1;

    while(1)
    {
        RTC_Proc();
        Seg_Proc();
        Key_Proc();
    }
}

void Seg_Proc(void)
{
    if(Seg_Dly < 500) return;
    Seg_Dly = 0;

    // 根据显示模式切换显示内容
    switch(Seg_Mode)
    {
        case 0: // 正常运行:显示时分秒(格式:HH:MM:SS)
            sprintf(Seg_String,"%02d-%02d-%02d", (int)hour, (int)min, (int)sec);
            break;
        case 1: // 调时模式:仅显示小时(闪烁/高亮,此处简化)
            sprintf(Seg_String,"  %02d    ", (int)hour);
            break;
        case 2: // 调分模式:仅显示分钟
            sprintf(Seg_String,"    %02d  ", (int)min);
            break;
        case 3: // 调秒模式:仅显示秒
            sprintf(Seg_String,"      %02d", (int)sec);
            break;
    }

    Seg_Trans(Seg_String, Seg_Code);
}

void Key_Proc(void)
{
    if(Key_Dly < 20) return; // 按键消抖(20ms)
    Key_Dly = 0;

    // 按键扫描:下降沿检测
    Key_Value = Key_Du_Read();
    Key_Down = Key_Value & (Key_Old ^ Key_Value); // 仅捕获按键按下的下降沿
    Key_Old = Key_Value;

    switch(Key_Down)
    {
        case 2: // 模式切换键:0→1→2→3→0
            Seg_Mode++;
            if(Seg_Mode == 4) Seg_Mode = 0;
            break;

        case 3: // P33按键:调小时(仅在调时模式/正常模式下生效)
            if(Seg_Mode == 0 || Seg_Mode == 1)
            {
                hour++;
                if(hour >= 24) hour = 0; // 24小时制循环
            }
            break;

        case 4: // P34按键:调分钟(仅在调分模式/正常模式下生效)
            if(Seg_Mode == 0 || Seg_Mode == 2)
            {
                min++;
                if(min >= 60) min = 0; // 分钟0-59循环
            }
            break;

        case 5: // P35按键:调秒(仅在调秒模式/正常模式下生效)
            if(Seg_Mode == 0 || Seg_Mode == 3)
            {
                sec++;
                if(sec >= 60) sec = 0; // 秒0-59循环
            }
            break;

        default:
            break;
    }
}

void Timer0_Isr(void) interrupt 1
{
    xms++;
    Seg_Dly++;
    Key_Dly++;

    // 数码管动态扫描
    Seg_Disp(Seg_Code, pos);
    if(++pos == 8) pos = 0;
}

void RTC_Proc(void)
{
    if(xms == 1000) // 1秒计时
    {
        xms = 0;
        if(++sec == 60) // 秒满60进1分
        {
            sec = 0;
            if(++min == 60) // 分满60进1小时
            {
                min = 0;
                if(++hour == 24) // 小时满24重置
                {
                    hour = 0; // 修复原代码未重置hour的BUG
                }
            }
        }
    }
}

160331iul99usqt668z8f8.jpg
回复

使用道具 举报 送花

  • 打卡等级:初来乍到
  • 打卡总天数:7
  • 最近打卡:2026-01-14 15:10:29
已绑定手机

5

主题

13

回帖

59

积分

注册会员

积分
59
发表于 2026-1-14 15:15:57 | 显示全部楼层
刚刚学习了流水灯+led的知识,完成代码的编写、修改和输出,最后利用ai8051u核心功能板显示输出,感觉非常不错!

#include <AI8051U.H>// ==================== 硬件配置宏定义 ====================#define LED_PORT P1       // LED控制端口(P10-P17)#define LED_ON  0         // 共阴极LED:0=亮,1=灭;共阳极则改为1#define LED_OFF 1// 按键引脚位掩码(P3口)- 替代P3_2/P3_3等位定义#define KEY1_MASK 0x04    // P32 = 第2位(0000 0100)#define KEY2_MASK 0x08    // P33 = 第3位(0000 1000)#define KEY3_MASK 0x10    // P34 = 第4位(0001 0000)#define KEY4_MASK 0x20    // P35 = 第5位(0010 0000)// ==================== 全局变量定义 ====================unsigned char led_mode = 1;       // 模式:1=流水灯 2=单独LED 3=全亮/全灭unsigned char flow_dir = 0;       // 流水灯方向:0=左→右 1=右→左unsigned char flow_pos = 0;       // 流水灯当前位置(0-7)unsigned char single_led = 0;     // 模式2下当前点亮的LED位bit all_led_state = 0;            // 模式3下LED状态:0=全灭 1=全亮// 按键相关变量unsigned char key_value;          // 按键扫描值unsigned char key_old, key_down;  // 按键旧值/下降沿unsigned int key_dly = 0;         // 按键消抖延时unsigned int led_dly = 0;         // LED刷新延时// ==================== 函数声明 ====================void Timer0_Init(void);void Key_Scan(void);void LED_Proc(void);// ==================== 主函数 ====================void main(void){    // AI8051U核心配置    EAXFR = 1;  // 使能扩展RAM访问    WTST = 0;   // 关闭等待状态    CKCON = 0;  // 时钟控制寄存器默认配置    // 端口模式配置:P1口推挽输出(LED),P3口准双向输入(按键)    P1M0 = 0xFF; P1M1 = 0x00;  // P1口推挽输出    P3M0 = 0x00; P3M1 = 0x00;  // P3口准双向输入(默认上拉)    // 定时器0初始化(1ms中断)    Timer0_Init();    EA = 1;  // 开启总中断    // 初始化LED为全灭    LED_PORT = 0xFF;    while(1)    {        Key_Scan();   // 按键扫描        LED_Proc();   // LED逻辑处理    }}// ==================== 定时器0初始化(1ms中断) ====================void Timer0_Init(void){    TMOD |= 0x01;  // 定时器0工作模式1(16位)    // 11.0592MHz晶振,定时1ms初值    TH0 = 0xFC;       TL0 = 0x66;    ET0 = 1;       // 开启定时器0中断    TR0 = 1;       // 启动定时器0}// ==================== 定时器0中断服务函数(1ms) ====================void Timer0_Isr(void) interrupt 1{    // 重装初值    TH0 = 0xFC;    TL0 = 0x66;    // 计时变量累加    if(key_dly < 20) key_dly++;    // 按键消抖20ms    if(led_dly < 200) led_dly++;   // LED刷新200ms}// ==================== 按键扫描函数(修正位操作问题) ====================void Key_Scan(void){    if(key_dly < 20) return;  // 未到消抖时间    key_dly = 0;              // 重置消抖延时    // 扫描P32-P35按键(低电平有效,通过位掩码判断)    key_value = 0;    if((P3 & KEY1_MASK) == 0) key_value = 1;  // P32按键(模式切换)    if((P3 & KEY2_MASK) == 0) key_value = 2;  // P33按键(方向切换)    if((P3 & KEY3_MASK) == 0) key_value = 3;  // P34按键(LED加1)    if((P3 & KEY4_MASK) == 0) key_value = 4;  // P35按键(LED减1)    // 下降沿检测:仅捕获按键按下的瞬间    key_down = key_value & (key_old ^ key_value);    key_old = key_value;    // 按键功能处理    switch(key_down)    {        case 1:  // P32:模式切换(1→2→3→1)            led_mode++;            if(led_mode > 3) led_mode = 1;            flow_pos = 0;            single_led = 0;            break;        case 2:  // P33:流水灯方向切换            flow_dir = !flow_dir;            break;        case 3:  // P34:模式2下LED加1            if(led_mode == 2)            {                single_led++;                if(single_led > 7) single_led = 0;            }            break;        case 4:  // P35:模式2下LED减1            if(led_mode == 2)            {                if(single_led == 0) single_led = 7;                else single_led--;            }            break;        default:            break;    }}// ==================== LED逻辑处理函数 ====================void LED_Proc(void){    if(led_dly < 200) return;  // 未到刷新时间    led_dly = 0;               // 重置LED延时    switch(led_mode)    {        // 模式1:流水灯        case 1:            LED_PORT = 0xFF;  // 先熄灭所有LED            if(flow_dir == 0)  // 左→右(P10→P17)            {                LED_PORT &= ~(1 << flow_pos);                flow_pos++;                if(flow_pos > 7) flow_pos = 0;            }            else  // 右→左(P17→P10)            {                LED_PORT &= ~(1 << (7 - flow_pos));                flow_pos++;                if(flow_pos > 7) flow_pos = 0;            }            break;        // 模式2:单独LED控制        case 2:            LED_PORT = 0xFF;  // 熄灭所有LED            LED_PORT &= ~(1 << single_led);  // 点亮指定LED            break;        // 模式3:全亮/全灭切换        case 3:            all_led_state = !all_led_state;            LED_PORT = all_led_state ? 0x00 : 0xFF;            break;        default:            led_mode = 1;  // 异常模式切回流水灯            break;    }}
202918bk4oqha0mh3em4bi.jpg
回复

使用道具 举报 送花

  • 打卡等级:初来乍到
  • 打卡总天数:7
  • 最近打卡:2026-01-14 15:10:29
已绑定手机

5

主题

13

回帖

59

积分

注册会员

积分
59
发表于 2026-1-14 16:07:57 | 显示全部楼层
顺利完成AI8051U AIcube实验一,效果非常好,AI很好用!
  1. //<<AICUBE_USER_HEADER_REMARK_BEGIN>>
  2. ////////////////////////////////////////
  3. // 在此添加用户文件头说明信息  
  4. // 文件名称: main.c
  5. // 文件描述:
  6. // 文件版本: V1.0
  7. // 修改记录:
  8. //   1. (2026-01-14) 创建文件
  9. ////////////////////////////////////////
  10. //<<AICUBE_USER_HEADER_REMARK_END>>
  11. #include "config.h"                     //默认已包含stdio.h、intrins.h等头文件
  12. //<<AICUBE_USER_INCLUDE_BEGIN>>
  13. // 在此添加用户头文件包含  
  14. //<<AICUBE_USER_INCLUDE_END>>
  15. //<<AICUBE_USER_GLOBAL_DEFINE_BEGIN>>
  16. // 在此添加用户全局变量定义、用户宏定义以及函数声明  
  17. //<<AICUBE_USER_GLOBAL_DEFINE_END>>
  18. ////////////////////////////////////////
  19. // 项目主函数
  20. // 入口参数: 无
  21. // 函数返回: 无
  22. ////////////////////////////////////////
  23. void main(void)
  24. {
  25.     //<<AICUBE_USER_MAIN_INITIAL_BEGIN>>
  26.     // 在此添加用户主函数初始化代码  
  27.     //<<AICUBE_USER_MAIN_INITIAL_END>>
  28.     SYS_Init();
  29.     //<<AICUBE_USER_MAIN_CODE_BEGIN>>
  30.     // 在此添加主函数中运行一次的用户代码  
  31.     //<<AICUBE_USER_MAIN_CODE_END>>
  32.     while (1)
  33.     {
  34.         //USBLIB_OUT_Done();              //查询方式处理USB接收的数据
  35.         //<<AICUBE_USER_MAIN_LOOP_BEGIN>>
  36.         // 在此添加主函数中用户主循环代码  
  37.                 printf_usb("Hello World !\r\n");
  38.         //<<AICUBE_USER_MAIN_LOOP_END>>
  39.     }
  40. }
  41. ////////////////////////////////////////
  42. // 系统初始化函数
  43. // 入口参数: 无
  44. // 函数返回: 无
  45. ////////////////////////////////////////
  46. void SYS_Init(void)
  47. {
  48.     EnableAccessXFR();                  //使能访问扩展XFR
  49.     AccessCodeFastest();                //设置最快速度访问程序代码
  50.     AccessIXramFastest();               //设置最快速度访问内部XDATA
  51.     IAP_SetTimeBase();                  //设置IAP等待参数,产生1us时基
  52.     //<<AICUBE_USER_PREINITIAL_CODE_BEGIN>>
  53.     // 在此添加用户预初始化代码  
  54.     //<<AICUBE_USER_PREINITIAL_CODE_END>>
  55.     P0M0 = 0x00; P0M1 = 0x00;           //初始化P0口为准双向口模式
  56.     P1M0 = 0x00; P1M1 = 0x00;           //初始化P1口为准双向口模式
  57.     P2M0 = 0x00; P2M1 = 0x00;           //初始化P2口为准双向口模式
  58.     P3M0 = 0x00; P3M1 = 0x00;           //初始化P3口为准双向口模式
  59.     P4M0 = 0x00; P4M1 = 0x00;           //初始化P4口为准双向口模式
  60.     P5M0 = 0x00; P5M1 = 0x00;           //初始化P5口为准双向口模式
  61.     PORT4_Init();                       //P4口初始化
  62.     delay_ms(1);
  63.     USBLIB_Init();                      //USB库初始化
  64.     delay_ms(1);
  65.     //<<AICUBE_USER_INITIAL_CODE_BEGIN>>
  66.     // 在此添加用户初始化代码  
  67.     //<<AICUBE_USER_INITIAL_CODE_END>>
  68.     EnableGlobalInt();                  //使能全局中断
  69. }
  70. ////////////////////////////////////////
  71. // 微秒延时函数
  72. // 入口参数: us (设置延时的微秒值)
  73. // 函数返回: 无
  74. ////////////////////////////////////////
  75. void delay_us(uint16_t us)
  76. {
  77.     do
  78.     {
  79.         NOP(34);                        //(MAIN_Fosc + 500000) / 1000000 - 6
  80.     } while (--us);
  81. }
  82. ////////////////////////////////////////
  83. // 毫秒延时函数
  84. // 入口参数: ms (设置延时的毫秒值)
  85. // 函数返回: 无
  86. ////////////////////////////////////////
  87. void delay_ms(uint16_t ms)
  88. {
  89.     uint16_t i;
  90.     do
  91.     {
  92.         i = MAIN_Fosc / 6000;
  93.         while (--i);
  94.     } while (--ms);
  95. }
  96. ////////////////////////////////////////
  97. // P4口初始化函数
  98. // 入口参数: 无
  99. // 函数返回: 无
  100. ////////////////////////////////////////
  101. void PORT4_Init(void)
  102. {
  103.     SetP4nInitLevelHigh(PIN_ALL);       //设置P4初始化电平
  104.     SetP4nQuasiMode(PIN_7 | PIN_5 | PIN_4 | PIN_3 | PIN_2 | PIN_1 | PIN_0); //设置P4.7,P4.5,P4.4,P4.3,P4.2,P4.1,P4.0为准双向口模式
  105.     SetP4nPushPullMode(PIN_6);          //设置P4.6为推挽输出模式
  106.     DisableP4nPullUp(PIN_ALL);          //关闭P4内部上拉电阻
  107.     DisableP4nPullDown(PIN_ALL);        //关闭P4内部下拉电阻
  108.     DisableP4nSchmitt(PIN_ALL);         //使能P4施密特触发
  109.     SetP4nSlewRateNormal(PIN_ALL);      //设置P4一般翻转速度
  110.     SetP4nDrivingNormal(PIN_ALL);       //设置P4一般驱动能力
  111.     SetP4nDigitalInput(PIN_ALL);        //使能P4数字信号输入功能
  112.     //<<AICUBE_USER_PORT4_INITIAL_BEGIN>>
  113.     // 在此添加用户初始化代码  
  114.     //<<AICUBE_USER_PORT4_INITIAL_END>>
  115. }
  116. ////////////////////////////////////////
  117. // USB库初始化函数
  118. // 入口参数: 无
  119. // 函数返回: 无
  120. ////////////////////////////////////////
  121. void USBLIB_Init(void)
  122. {
  123.     usb_init();                         //初始化USB模块
  124.     USB_SetIntPriority(0);              //设置中断为最低优先级
  125.     set_usb_ispcmd("@STCISP#");         //设置USB不停电下载命令
  126.     //<<AICUBE_USER_USBLIB_INITIAL_BEGIN>>
  127.     // 在此添加用户初始化代码  
  128.     //<<AICUBE_USER_USBLIB_INITIAL_END>>
  129. }
  130. ////////////////////////////////////////
  131. // 等待USB配置完成函数
  132. // 入口参数: 无
  133. // 函数返回: 无
  134. ////////////////////////////////////////
  135. void USBLIB_WaitConfiged(void)
  136. {
  137.     while (DeviceState != DEVSTATE_CONFIGURED) //等待USB完成配置
  138.         WDT_Clear();                    //清看门狗定时器 (防止硬件自动使能看门狗)
  139. }
  140. ////////////////////////////////////////
  141. // USB设备接收数据处理程序
  142. // 入口参数: 无
  143. // 函数返回: 无
  144. // bUsbOutReady:USB设备接收数据标志位
  145. // OutNumber:USB设备接收到的数据长度
  146. // UsbOutBuffer:保存USB设备接收到的数据
  147. ////////////////////////////////////////
  148. void USBLIB_OUT_Done(void)
  149. {
  150.     if (bUsbOutReady)                   //查询是否有接收到USB主机发送数据
  151.     {
  152.         //<<AICUBE_USER_USBLIB_ISR_CODE1_BEGIN>>
  153.         // 在此添加中断函数用户代码  
  154.         USB_SendData(UsbOutBuffer, OutNumber); //原路返回, 用于测试
  155.         // 在此处添加用户处理接收数据的代码
  156.         //<<AICUBE_USER_USBLIB_ISR_CODE1_END>>
  157.         usb_OUT_done();                 //当前包的数据处理完成,通知USB主机可以发送下一包数据
  158.     }
  159. }
  160. //<<AICUBE_USER_FUNCTION_IMPLEMENT_BEGIN>>
  161. // 在此添加用户函数实现代码  
  162. //<<AICUBE_USER_FUNCTION_IMPLEMENT_END>>
复制代码
屏幕截图 2026-01-14 160237.png
屏幕截图 2026-01-14 160405.png
回复

使用道具 举报 送花

  • 打卡等级:初来乍到
  • 打卡总天数:7
  • 最近打卡:2026-01-14 15:10:29
已绑定手机

5

主题

13

回帖

59

积分

注册会员

积分
59
发表于 2026-1-14 16:21:54 | 显示全部楼层
顺利完成AI8051U AIcube实验二,官方讲解视频非常详细,适合零基础小白学习!
  1. //<<AICUBE_USER_HEADER_REMARK_BEGIN>>
  2. ////////////////////////////////////////
  3. // 在此添加用户文件头说明信息  
  4. // 文件名称: main.c
  5. // 文件描述:
  6. // 文件版本: V1.0
  7. // 修改记录:
  8. //   1. (2026-01-14) 创建文件
  9. ////////////////////////////////////////
  10. //<<AICUBE_USER_HEADER_REMARK_END>>
  11. #include "config.h"                     //默认已包含stdio.h、intrins.h等头文件
  12. //<<AICUBE_USER_INCLUDE_BEGIN>>
  13. // 在此添加用户头文件包含  
  14. //<<AICUBE_USER_INCLUDE_END>>
  15. //<<AICUBE_USER_GLOBAL_DEFINE_BEGIN>>
  16. // 在此添加用户全局变量定义、用户宏定义以及函数声明  
  17. //<<AICUBE_USER_GLOBAL_DEFINE_END>>
  18. ////////////////////////////////////////
  19. // 项目主函数
  20. // 入口参数: 无
  21. // 函数返回: 无
  22. ////////////////////////////////////////
  23. void main(void)
  24. {
  25.     //<<AICUBE_USER_MAIN_INITIAL_BEGIN>>
  26.     // 在此添加用户主函数初始化代码  
  27.     //<<AICUBE_USER_MAIN_INITIAL_END>>
  28.     SYS_Init();
  29.     //<<AICUBE_USER_MAIN_CODE_BEGIN>>
  30.     // 在此添加主函数中运行一次的用户代码  
  31.     //<<AICUBE_USER_MAIN_CODE_END>>
  32.     while (1)
  33.     {
  34.         USBLIB_OUT_Done();              //查询方式处理USB接收的数据
  35.         //<<AICUBE_USER_MAIN_LOOP_BEGIN>>
  36.         // 在此添加主函数中用户主循环代码  
  37.         //<<AICUBE_USER_MAIN_LOOP_END>>
  38.     }
  39. }
  40. ////////////////////////////////////////
  41. // 系统初始化函数
  42. // 入口参数: 无
  43. // 函数返回: 无
  44. ////////////////////////////////////////
  45. void SYS_Init(void)
  46. {
  47.     EnableAccessXFR();                  //使能访问扩展XFR
  48.     AccessCodeFastest();                //设置最快速度访问程序代码
  49.     AccessIXramFastest();               //设置最快速度访问内部XDATA
  50.     IAP_SetTimeBase();                  //设置IAP等待参数,产生1us时基
  51.     //<<AICUBE_USER_PREINITIAL_CODE_BEGIN>>
  52.     // 在此添加用户预初始化代码  
  53.     //<<AICUBE_USER_PREINITIAL_CODE_END>>
  54.     P0M0 = 0x00; P0M1 = 0x00;           //初始化P0口为准双向口模式
  55.     P1M0 = 0x00; P1M1 = 0x00;           //初始化P1口为准双向口模式
  56.     P2M0 = 0x00; P2M1 = 0x00;           //初始化P2口为准双向口模式
  57.     P3M0 = 0x00; P3M1 = 0x00;           //初始化P3口为准双向口模式
  58.     P4M0 = 0x00; P4M1 = 0x00;           //初始化P4口为准双向口模式
  59.     P5M0 = 0x00; P5M1 = 0x00;           //初始化P5口为准双向口模式
  60.     PORT4_Init();                       //P4口初始化
  61.     delay_ms(1);
  62.     USBLIB_Init();                      //USB库初始化
  63.     delay_ms(1);
  64.     //<<AICUBE_USER_INITIAL_CODE_BEGIN>>
  65.     // 在此添加用户初始化代码  
  66.     //<<AICUBE_USER_INITIAL_CODE_END>>
  67.     EnableGlobalInt();                  //使能全局中断
  68. }
  69. ////////////////////////////////////////
  70. // 微秒延时函数
  71. // 入口参数: us (设置延时的微秒值)
  72. // 函数返回: 无
  73. ////////////////////////////////////////
  74. void delay_us(uint16_t us)
  75. {
  76.     do
  77.     {
  78.         NOP(34);                        //(MAIN_Fosc + 500000) / 1000000 - 6
  79.     } while (--us);
  80. }
  81. ////////////////////////////////////////
  82. // 毫秒延时函数
  83. // 入口参数: ms (设置延时的毫秒值)
  84. // 函数返回: 无
  85. ////////////////////////////////////////
  86. void delay_ms(uint16_t ms)
  87. {
  88.     uint16_t i;
  89.     do
  90.     {
  91.         i = MAIN_Fosc / 6000;
  92.         while (--i);
  93.     } while (--ms);
  94. }
  95. ////////////////////////////////////////
  96. // P4口初始化函数
  97. // 入口参数: 无
  98. // 函数返回: 无
  99. ////////////////////////////////////////
  100. void PORT4_Init(void)
  101. {
  102.     SetP4nInitLevelHigh(PIN_ALL);       //设置P4初始化电平
  103.     SetP4nQuasiMode(PIN_7 | PIN_6 | PIN_4 | PIN_3 | PIN_2 | PIN_1 | PIN_0); //设置P4.7,P4.6,P4.4,P4.3,P4.2,P4.1,P4.0为准双向口模式
  104.     SetP4nPushPullMode(PIN_5);          //设置P4.5为推挽输出模式
  105.     DisableP4nPullUp(PIN_ALL);          //关闭P4内部上拉电阻
  106.     DisableP4nPullDown(PIN_ALL);        //关闭P4内部下拉电阻
  107.     DisableP4nSchmitt(PIN_ALL);         //使能P4施密特触发
  108.     SetP4nSlewRateNormal(PIN_ALL);      //设置P4一般翻转速度
  109.     SetP4nDrivingNormal(PIN_ALL);       //设置P4一般驱动能力
  110.     SetP4nDigitalInput(PIN_ALL);        //使能P4数字信号输入功能
  111.     //<<AICUBE_USER_PORT4_INITIAL_BEGIN>>
  112.     // 在此添加用户初始化代码  
  113.     //<<AICUBE_USER_PORT4_INITIAL_END>>
  114. }
  115. ////////////////////////////////////////
  116. // USB库初始化函数
  117. // 入口参数: 无
  118. // 函数返回: 无
  119. ////////////////////////////////////////
  120. void USBLIB_Init(void)
  121. {
  122.     usb_init();                         //初始化USB模块
  123.     USB_SetIntPriority(0);              //设置中断为最低优先级
  124.     set_usb_ispcmd("@STCISP#");         //设置USB不停电下载命令
  125.     //<<AICUBE_USER_USBLIB_INITIAL_BEGIN>>
  126.     // 在此添加用户初始化代码  
  127.     //<<AICUBE_USER_USBLIB_INITIAL_END>>
  128. }
  129. ////////////////////////////////////////
  130. // 等待USB配置完成函数
  131. // 入口参数: 无
  132. // 函数返回: 无
  133. ////////////////////////////////////////
  134. void USBLIB_WaitConfiged(void)
  135. {
  136.     while (DeviceState != DEVSTATE_CONFIGURED) //等待USB完成配置
  137.         WDT_Clear();                    //清看门狗定时器 (防止硬件自动使能看门狗)
  138. }
  139. ////////////////////////////////////////
  140. // USB设备接收数据处理程序
  141. // 入口参数: 无
  142. // 函数返回: 无
  143. // bUsbOutReady:USB设备接收数据标志位
  144. // OutNumber:USB设备接收到的数据长度
  145. // UsbOutBuffer:保存USB设备接收到的数据
  146. ////////////////////////////////////////
  147. void USBLIB_OUT_Done(void)
  148. {
  149.     if (bUsbOutReady)                   //查询是否有接收到USB主机发送数据
  150.     {
  151.         //<<AICUBE_USER_USBLIB_ISR_CODE1_BEGIN>>
  152.         // 在此添加中断函数用户代码  
  153.        // USB_SendData(UsbOutBuffer, OutNumber); //原路返回, 用于测试
  154.         // 在此处添加用户处理接收数据的代码
  155.                 if (UsbOutBuffer[0] == 6)
  156.                                 printf_usb("Hello World !\r\n");
  157.                         else if (UsbOutBuffer[0] == 7)
  158.                                 printf_usb("China !\r\n");
  159.         //<<AICUBE_USER_USBLIB_ISR_CODE1_END>>
  160.         usb_OUT_done();                 //当前包的数据处理完成,通知USB主机可以发送下一包数据
  161.     }
  162. }
  163. //<<AICUBE_USER_FUNCTION_IMPLEMENT_BEGIN>>
  164. // 在此添加用户函数实现代码  
  165. //<<AICUBE_USER_FUNCTION_IMPLEMENT_END>>
复制代码
屏幕截图 2026-01-14 161454.png
屏幕截图 2026-01-14 161944.png
回复

使用道具 举报 送花

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

本版积分规则

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

GMT+8, 2026-2-12 18:02 , Processed in 0.123927 second(s), 81 queries .

Powered by Discuz! X3.5

© 2001-2026 Discuz! Team.

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