找回密码
 立即注册
楼主: 曹会杰

擎天柱 核心板学习打卡

[复制链接]
  • 打卡等级:偶尔看看II
  • 打卡总天数:28
  • 最近打卡:2025-07-01 08:26:48
已绑定手机

2

主题

53

回帖

240

积分

中级会员

积分
240
发表于 前天 21:48 | 显示全部楼层

谢谢老板回复,终于通过了,原来是下面这两个库文件选错了
Screenshot 2025-06-29 214743.png
回复 支持 反对

使用道具 举报 送花

  • 打卡等级:偶尔看看II
  • 打卡总天数:28
  • 最近打卡:2025-07-01 08:26:48
已绑定手机

2

主题

53

回帖

240

积分

中级会员

积分
240
发表于 前天 22:03 | 显示全部楼层
第7集定时器中断与按键处理


#include  "ai8051u.h"        //头文件不分大小写,但关键字分大小写
#include  "ai_usb.h"        //USB库和USB虚拟设备的头文件
#include  "KEY.H"

#define u8 unsigned char
#define u16 unsigned int
       
/*---------变量声明区---------*/
u8 X = 20;
u8 Y = 10;
u8 Key_Slow_Down;                                        //按键减速变量用于按键消抖
u8 Key_Val,Key_Down,Key_Up,Key_Old; //按键处理变量,按键值,按键下降沿,上升沿,长按变量
u8 Key_Num;                                                        //按键按下次数
u16 Timer1000ms_Count;                                //定时器1秒计时变量       
u8 Led_Start;                                                //LED闪烁标志

/*---------函数声明区---------*/
void Timer0_Init(void);                //1毫秒@24.000MHz

/*---------按键处理---------*/
void Key_Proc()
{
        if(Key_Slow_Down)return;
        Key_Slow_Down = 1;
       
        Key_Val=Key_Read();
        Key_Down = Key_Val&(Key_Val^Key_Old);
        Key_Up = ~Key_Val&(Key_Val^Key_Old);
        Key_Old=Key_Val;
       
        switch(Key_Down)
        {
                case 1:
                        Key_Num++;
                printf("Key_Num:%d\r\n",Key_Num);       
                break;
                case 2:
                        P20 = 1;
                        P21 = 0;
                break;
        }       
}
/*---------MAIN主函数--------*/
void  main(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口为准双向口模式

        usb_init();
        //初始化USB模块,并且会将【P3.0,P3.1】初始化为高阻输入,不影响USB【D-,D+】通讯
                Timer0_Init();                //1毫秒@24.000MHz
        EA = 1;                //使能总中断

        while (1)
        {
                        if(bUsbOutReady)
                                //USB库中有定义bUsbOutReady位变量,查询方式必须用一次“usb_OUT_done();”
                        {
                                printf("X/Y=%d\r\n",(u16)X/Y);
                                printf("X%%Y=%d\r\n",(u16)X%Y);
                               
                               
                                usb_OUT_done();
                                //当使用查询方式if(bUsbOutReady),查询调用USB库函数时,在数据处理完成后
                                //必须调用一次“usb_OUT_done();”这样才能接收下一包数据。
                        }

                        Key_Proc();
        }
}
/*---定时器0初始化函数---*/
void Timer0_Init(void)                //1毫秒@24.000MHz
{
        AUXR &= 0x7F;                        //定时器时钟12T模式
        TMOD &= 0xF0;                        //设置定时器模式
        TL0 = 0x30;                                //设置定时初始值
        TH0 = 0xF8;                                //设置定时初始值
        TF0 = 0;                                //清除TF0标志
        TR0 = 1;                                //定时器0开始计时
        ET0 = 1;                                //使能定时器0中断
}
/*---定时器0中断服务函数---*/
void Timer0_Isr(void) interrupt 1
{
        if(++Key_Slow_Down==10)Key_Slow_Down=0;
        if(++Timer1000ms_Count==1000)
        {
                Timer1000ms_Count=0;
                Led_Start^=1;
                P20 = Led_Start;
        }
}

回复 支持 反对

使用道具 举报 送花

  • 打卡等级:常住居民III
  • 打卡总天数:114
  • 最近打卡:2025-07-01 08:26:02

741

主题

1万

回帖

1万

积分

管理员

积分
17280
发表于 前天 22:36 | 显示全部楼层


截图202506292236221335.jpg

//外部中断INT0和INT1控制点灯并USB仿真
#include <AI8051U.H>                        //包含AI8051U的头文件
#include "intrins.h"                        //使用_nop_()函数所必须要包含的头文件,
                                                                //否则延时函数中调用的_nop_()函数没有被头文件引用过来,
                                                                //会导致编译器找不到这个而函数而报错。

bit int0_flag = 0;                                //定义1个位变量,INT0事件位变量标志,记录INT0已产生中断
// 供主循环查询INT0是否已产生中断,在主循环中处理INT0的中断事件任务,不堵塞其他中断
bit int1_flag = 0;                                //定义1个位变量,INT1事件位变量标志,记录INT1已产生中断
// 供主循环查询INT1是否已产生中断,在主循环中处理INT1的中断事件任务,不堵塞其他中断

void main (void)
{
        EAXFR = 1;                                          //允许访问扩展的特殊寄存器,XFR
        WTST = 0;                                     //设置取程序代码等待时间,赋值为 0 表示不等待,程序以最快速度运行
        CKCON = 0;                                    //设置访问片内的 xdata 速度,赋值为 0 表示用最快速度访问,不增加额外的等待时间
        P0M0 = 0x00; P0M1 = 0x00;
        P1M0 = 0x00; P1M1 = 0x00;
        P2M0 = 0x00; P2M1 = 0x00;
//        P3M0 = 0x00; P3M1 = 0x00;        //P32、P33设置为准双向口
        P3M0 = 0x00; P3M1 = 0xff;         //P32、P33设置为高阻输入(需要同步开启上拉电阻)
        P4M0 = 0x00; P4M1 = 0x00;
        P5M0 = 0x00; P5M1 = 0x00;
        P6M0 = 0x00; P6M1 = 0x00;
        P7M0 = 0x00; P7M1 = 0x00;
        P3PU = 0x0c;                                 //P32、P33打开上拉电阻
       
        IT0 = 0;                                         //使能 INT0 上升沿和下降沿中断
//        IT0 = 1;                                         //使能 INT0 下降沿中断
        EX0 = 1;                                         //使能 INT0 中断
       
//        IT1 = 0;                                         //使能 INT1 上升沿和下降沿中断
        IT1 = 1;                                         //使能 INT1 下降沿中断
        EX1 = 1;                                         //使能 INT1 中断
       
        IE0 = 0;                                        //清INT0中断标志
        IE1 = 0;                                        //清INT1中断标志
       
        EA = 1;                                         //打开所有中断
        P40 = 0;                                         //打开LED灯供电

        int0_flag = 0;                                //初始化用户标志位
        int1_flag = 0;                                //初始化用户标志位

        while(1)
        {
                if(int0_flag)                        //主循环中查询,INT0是否已产生中断,是否有需要处理的INT 0事件
                {
                        int0_flag = 0;                //清0,INT0事件位变量标志
                        _nop_();                        //用户在此添加需要处理的事件
                        _nop_();
                }
                if(int1_flag)                        //主循环中查询,INT1是否已产生中断,是否有需要处理的INT1事件
                {
                        int1_flag = 0;                //清0,INT1事件位变量标志
                        _nop_();                        //用户在此添加需要处理的事件
                        _nop_();
                }
        }
}

void int0_isr(void) interrupt INT0_VECTOR
{
        int0_flag = 1;                                // int0_flag置1是通知主循环处理部分INT0中断事件不需要特急处理的任务
                                                                //置1,记录INT0已产生中断,供主循环查询判断有无需处理的INT0任务

        if(INT0)                                         //边沿中断,进入后再次判断电平从而判断是什么样的电平
        {
                P00 = 0;                                //判断为高电平,则当前为上升沿,点亮P00端口上的LED灯
                _nop_();                                //可以在这里插入断点进行观察现象
                P00 = 1;                                //关闭LED灯
        }
        else
        {
                P07 = 0;                                //判断为低电平,则当前为下降沿,点亮P07端口上的LED灯
                _nop_();                                //可以在这里插入断点进行观察现象
                P07 = 1;                                //关闭LED灯
        }
}

void int1_isr(void) interrupt INT1_VECTOR
{
        int1_flag = 1;                                // int1_flag置1是通知主循环处理部分INT1中断事件不需要特急处理的任务
                                                                //置1,记录INT1已产生中断,供主循环查询判断有无需处理的INT1任务

        P04 = 0;                                        //点亮P04端口上的LED灯
        _nop_();                                        //可以在这里插入断点观察现象
        P04 = 1;                                        //关闭LED灯
}


回复 支持 反对

使用道具 举报 送花

  • 打卡等级:常住居民III
  • 打卡总天数:114
  • 最近打卡:2025-07-01 08:26:02

741

主题

1万

回帖

1万

积分

管理员

积分
17280
发表于 前天 22:37 | 显示全部楼层
截图202506292237054693.jpg


#include <AI8051U.H>                        //AI8051U的通用头文件,头文件不分大小写
#include  "ai_usb.h"                        //USB库和USB虚拟设备的头文件
                                                                //由于在USB库函数的代码中已经定义了,不停电ISP下载命令字”@STCISP#”,
                                                                //只需要在下载软件的“收到用户命令后复位到ISP监控程序区”选项卡中进行相应的设置,
                                                                //即可实现USB不停电ISP下载功能,或串口不停电ISP下载功能。

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

void Timer0_Isr(void) interrupt TMR0_VECTOR                //定时器0中断服务程序
{
        P00 = ~P00;                                        //P00灯闪烁,中断服务程序中尽量少执行长的任务,防止堵塞其他中断
        //以上程序代表部分需特急处理的中断事件,可在中断服务程序中直接处理
        //但时间不要太长,否则会影响其他中断事件的实时响应速度
        t0_flag = 1;                                // t0_flag置1是通知主循环处理部分T0中断事件不需要特急处理的任务
                                                                //置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;                                // t1_flag置1是通知主循环处理部分T1中断事件不需要特急处理的任务
                                                                //置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");
                                                                //向电脑USB-CDC串口助手输出“Timer0!”字符串,代表主循环在处理T0不急的任务
                }
                if(t1_flag)                                //主循环中查询,定时器1是否已产生中断,是否有需要处理的定时器1事件
                {
                        t1_flag = 0;                //清0,T1事件位变量标志
                        printf_usb("Timer1!\r\n");
                                                                //向电脑USB-CDC串口助手输出“Timer1!”字符串,代表主循环在处理T1不急的任务
                }
        }
}


回复 支持 反对

使用道具 举报 送花

  • 打卡等级:偶尔看看II
  • 打卡总天数:28
  • 最近打卡:2025-07-01 08:26:48
已绑定手机

2

主题

53

回帖

240

积分

中级会员

积分
240
发表于 昨天 22:11 | 显示全部楼层
定时器多任务处理

Screenshot 2025-06-30 220835.png
Screenshot 2025-06-30 220923.png
回复 支持 反对

使用道具 举报 送花

  • 打卡等级:偶尔看看II
  • 打卡总天数:28
  • 最近打卡:2025-07-01 08:26:48
已绑定手机

2

主题

53

回帖

240

积分

中级会员

积分
240
发表于 昨天 22:13 | 显示全部楼层
ZIJIN*** 发表于 2025-6-30 22:11
定时器多任务处理

这是文件压缩包

main.zip

154.87 KB, 下载次数: 0

回复 支持 反对

使用道具 举报 送花

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

本版积分规则

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

GMT+8, 2025-7-1 09:16 , Processed in 0.119079 second(s), 76 queries .

Powered by Discuz! X3.5

© 2001-2025 Discuz! Team.

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