Sean 发表于 2025-1-15 19:06:54

Ai8051U 学习 打卡

非常感谢STC官方 主讲人冲哥

《第一集 序言》学习笔记


“Ai8051U 系列是32位8051 也是优秀的16位机 更是兼容8位机的最强悍的1位机”


32位机、16位机甚至8位机 我们都不难理解 那么这里的1位机应该说的就是 特殊寄存器(SFR、ebdata)的位寻址方式

两个最重要网址:
STC官网:www.STCAI.com
STC论坛:www.STCAIMCU.com

两个重要文件:
Ai8051U单片机原理及应用:AI8051U.pdf
Ai8051U实验箱使用说明书:AI8051U实验箱V1.2使用说明书.pdf

Ai8051U 强在哪里 用以下几个实例分别表述
1、屏幕显示和视频播放(flash编程器)
    1.高帧率 汉字显示 界面旋转效果等 手写效果演示(精度很高 反应灵敏)
    2.视频级动画效果显示
      使用AIapp-ISP 的串行Flash编程器工具 根据提供的Flash型号和数据起始地址直接写入数据
      动画播放流畅
2、IIS录放音
   单片机直接驱动Microphone和喇叭实现录放功能 较以往需要外部模块的方式方便和简单
3、PWN_DMA
   实现了WS2812点阵屏电子钟 该方式可以直接驱动1000多颗2812灯珠 且不会有任何干扰
4、频谱分析仪(上位机)
   主要演示音频信号的频谱分析功能 利用了IIS录音以及高速运算能力实现FFT(快速傅里叶变换)
5、手写计算器
   名字中Ai的体现 可以对手写表达式识别和计算 经过优化的模型 速度快且准确
6、QSPI,PWM移相,硬件乘除,单精度浮点
   
Ai8051单片主要参数

1、USB型1T 8051 支持32位和8位指令集 34K SRAM(2K edata,32K xdata),64K Flash
2、价格 RMB 2.3元
3、管脚兼容89C52RC 12C5A60S2(可以直接利用51单片机最小系统板)
4、可以用Keil C51/IAR/SDCC 开发 8位8051程序 相当于增强版的8H8K64U
5、可以用Keil C251开发32位8051程序 相当于增强版32G12K128、32G8K64
6、TFPU@120MHz,硬件浮点、硬件三角函数运算
7、DMA支持PWM,DMA支持外设直接到外设 P2P
8、120MHz-PWM支持硬件移相,16位PWM 真12位ADC
9、USB,4组串口,轨到轨比较器 QSPI SPI I2S I2C TFT-i8080/M6800接口
10、封装 PDIP40,LQFP44,LQFP48

附带学习 基本的程序下载方式
软件:AIapp-ISP V6.94X


根据流程图可以看到既可以串口下载也可以USB口下载 (USB型8051)串口(TXD,RXD)USB口(D+ D-)Ai8051U直接处理


哪怕梦想让我们拼的遍体鳞伤,这一次我们也要勇往直前!!!



Sean 发表于 2025-1-15 19:16:28

非常感谢STC官方 主讲人冲哥

《第二集 硬件及工具介绍》学习笔记


“Ai8051U 系列是32位8051 也是优秀的16位机 更是兼容8位机的最强悍的1位机”

一、AI8051U实验箱 介绍 (组件:系统板、 外壳、 跳线帽)

要点:
正面(从左下角开始顺时针方向解释)
               1、USB-Type A、USB-Type C 的USB接入
               2、USB转双串口的串口接入(STC公司自研替换CH340芯片 最高波特率可达10M)
               3、USB Link 1D STC官方下载、烧录调试工具 接口
               4、TF卡支持 示波器输入(板载波形调整电容)录、放音接口
               5、显示屏 OLED SPI I2C 8/7线接口 板载贴片LED(点灯程序 流水灯程序) 8位数码管 TFT彩屏接口(并口)
               6、掉电检测电压调节
               7、红外接收、红外发射
               8、矩阵键盘(4行两列 6个单片机引脚控制8个按键) ADC键盘(8行两列 1个单片机引脚控制16个按键)T0 T1 INT0 INT1独立按键
               9、MCU Ai8051U LQFP48      
               10、复位按键 电源按键(单片机断电上电)
               11、Flash(QSPI) 片外数据存储芯片(AIapp-ISP 可以直接写入数据)
               12、LCD对比度调节电位器
               13、RTC电池 提供掉点后MCU内部计时器工作电压
               14、跳线接口 若干

背面(从左上角开始逆时针解释)
               1、32768Hz无源晶振
               2、24C02 EEPROM (重要单片机数据存储器)
               3、DS18B20 温度传感器
               4、无源蜂鸣器
               5、SP3485(485协议芯片)
               6、AI8H2K12U USB转双串口芯片
               7、(TP2604S)( 74HC4051、TP2604S)(LMV358)(TLLV320AIC23B I2S DAC)后续章节重点介绍

二、开发软件和工具介绍

1、开发软件: Keil C251 (Keil 官方网站)(如果希望 Keil C251 51 MDK共存 可参考手册6.1.2节)
2、下载ISP软件:AIapp-ISP 最新版(STC官网)www.stcai.com AI8051U手册 AIapp-ISP软件最新版下载(目前最新版 V6.95E )
3、添加头文件:AIapp-ISP软件内操作
4、Keil插件:Keil中断拓展
5、AI8051U实验箱代码包和手册

关键步骤:1、按住P3.2 按电源按键并松开 可以发现HID1 USB-Writer 设备
                2、IRC频率选择 (程序源代码main.c 有声明)
               
实验部分:1、下载安装Keil C251安装包,AIapp-ISP 下载烧录工具
                2、头文件注入
                3、下载并运行 跑马灯 例程






哪怕梦想让我们拼的遍体鳞伤,这一次我们也要勇往直前!!!

Sean 发表于 2025-1-16 00:02:33

非常感谢STC官方 主讲人冲哥

《第三集 点亮第一颗LED》学习笔记


“Ai8051U 系列是32位8051 也是优秀的16位机 更是兼容8位机的最强悍的1位机”

仔细阅读 《Ai8051U 单片机原理及应用》第六章相关内容 重点阅读 6.4节 6.5节(工程项目生成和必要设置)


要点:
       1、创建工程,选择单片机型号(STC单片机由AIapp-ISP软件注入)
       2、添加main.c文件
       3、Target设置
                  CPU Mode:Source(251 native)
            Memory Model:XSmall
            Code Rom Size:Large:64K program(代码超过64K则选择 Huge:64Kfunctions,16M progr 并且设置 External Memory:#1 ROM start:0xFE0000 Size:0x20000 注意:设置的是ROM区域)

         Output设置
            勾选Create HEX File 生成单片机下载需要的.hex文件
            HEX Format:程序空间<64K HEX-80程序空间>64K HEX-386
       4、头文件的添加
            <>和“” 引用头文件的区别
            <> 在系统路径查找头文件
            “” 在当前目录和系统路径查找头文件
             ai8051u.h头文件 可以通过AIapp-ISP 注入

手动输入如下代码:
      #include “ai8051u.h”//单行注释写在这里
       void main(void)
       {
         //此处代码执行一次
          while(1)
          {
         //重复执行此处代码
          }
       }

联想:Arduino 程序结构


void setup() {
// put your setup code here, to run once://执行一次

}

void loop() {
// put your main code here, to run repeatedly://重复执行

}


修改上述代码如下 点亮板载LED

      #include “ai8051u.h”
       void main(void)
       {
         P0M1=0x00;P0M0=0x00; //设置P0端口为准双向口

         P4M1=0x00;P4M0=0x00; //设置P4端口为准双向口
         
          P40=0;//P4.0低电平控制打开Q2SS8550三极管LED供电

          while(1)
          {
         P00=0;//低电平点亮LED
          }
       }

   IO设置可以通过AIapp-ISP 可视化生成代码 复制 粘贴到main.c即可      


IO口 四种模式:准双向口 推挽输出 高阻输入 开漏输出(参考13.2节 IO口模式解释)

   熟悉二进制 十六进制 对数值的表达方式
   BIN:0000 0000
   HEX:0x00


哪怕梦想让我们拼的遍体鳞伤,这一次我们也要勇往直前!!!

Sean 发表于 2025-1-16 10:16:22

非常感谢STC官方 主讲人冲哥

《第四集 USB不停电下载》学习笔记

“Ai8051U 系列是32位8051 也是优秀的16位机 更是兼容8位机的最强悍的1位机”

资源列表:STC官网-软件工具-库函数-USB库文件(STC_USB_LIBRARY.zip)
               选择CDC(USB-CDC方式) 暂时忽略HID(USB-HID方式)和ASM(汇编语言)的库文件和头文件 (stc_usb_cdc_32.LIB、stc32_stc8_usb.h)
            
模式选择:查询模式(执行到相关代码时执行,使用这种方式的库文件)、中断模式(中断触发立即执行 需要实现BOOL usb_OUT_callback()方法)


需要在自己的工程中添加如下代码:
               ......
               #include“stc32_stc8_usb.h”
               ......
               char *USER_DEVICEDESC=NULL;
               char *USER_PRODUCTDESC=NULL;
               char *USER_STCISPCMD="@STCISP#";//"@STCISP#"对应AIapp-ISP中相关设置
               ......
               void main(void)
               {
                        P_SW2|=0x80;         //P_SW2的B7位写1,使能访问XFR 或 EAXFR=1
                        ......
                        usb_init();    //USB CDC 接口配置
                        IE2|=0x80;//IE2的B7位写1,使能USB中断 或 EUSB=1 USB中断小开关最新Demo 已移除此行
                        EA=1;       //IE的B7位写1,位寻址 或者 IE|=0x80 打开中断总开关
                        while(DeviceState!=DEVSTATE_CONFIGURED)//等待USB完成配置
                        ......
                        while(1)
                        {
                               ......
                               if (bUsbOutReady)
                               {
                                    USB_SendData(UsbOutBuffer,OutNumber); //发送数据缓冲区,长度(接收数据原样返回, 用于测试)

                                    usb_OUT_done();
                               }
                              ......
                        }
               }


小提示:可在Options for Target 'Target1'-L251Misc-disable Warning Numbers:中添加57 禁用UNCALLED FUNCTION,警告信息


哪怕梦想让我们拼的遍体鳞伤,这一次我们也要勇往直前!!!

Sean 发表于 2025-1-16 11:41:57

非常感谢STC官方 主讲人冲哥

《第五集 C语言基础》学习笔记

“Ai8051U 系列是32位8051 也是优秀的16位机 更是兼容8位机的最强悍的1位机”

复习C语言相关基础知识


1.C语言 USB-CDC串口之printf函数的实现
    ①stc32_stc8_usb.h中去掉#define PRINTF_HID 前的//注释
    ②printf_hid()的实现
          #define printfprintf_hid
          int printf_hid (const char *fmt, ...);//参数fmt 是格式控制字符串,包含了两种类型的对象:普通字符和转换说明
格式控制符列表:

ASCII字符代码表:

   
      USB-CDC方式模拟的串口波特率设置任意 实际上是USB口的通讯
2.数的进制:2进制、10进制、16进制(8进制)


3.数据的基本类型

若要使用64位变量 #pragma float64


4.C语言常用运算符





此课复习了以前学习C语言相关内容 加深印象

哪怕梦想让我们拼的遍体鳞伤,这一次我们也要勇往直前!!!

Sean 发表于 2025-1-16 12:43:07

非常感谢STC官方 主讲人冲哥

《第六集 I/O输入输出》学习笔记

“Ai8051U 系列是32位8051 也是优秀的16位机 更是兼容8位机的最强悍的1位机”


GPIO(General Purpose I/O Ports):通用输入/输出端口。
通俗地说,就是一些引脚,可以通过它们输出高低电平或者通过它们读入引脚的状态-是高电平或是低电平。

高低电平:
                高电平 输出VCC电压
                低电平 输出GND电压

IO口


VDD=3.3V时 高电平 低电平 允许范围见下表

施密特触发器相关寄存器设置见下表

{:weiqu:}

按键输入检测
没按下是高电平 按下是低电平 代码中用逻辑运算符“==”判断 1代表高电平 0代表低电平

完成三个任务


任务1:按下P32按钮灯亮,松开P32按钮灯灭;
任务2:按下P32按钮灯灭,松开P32按钮灯亮;
任务3:按一下灯亮,按一下灯灭;



代码如下:
#include "ai8051u.h"                        //调用头文件
#include "stc32_stc8_usb.h"                //调用头文件
#include "intrins.h"                        //调用头文件不要忘记添加

#define u8unsigned char                //8位无符号变量(0-255)
#define u16 unsigned int                //16位无符号变量(0-65535)      
      
u8 state = 0;                                        //初始状态

char *USER_DEVICEDESC = NULL;
char *USER_PRODUCTDESC = NULL;
char *USER_STCISPCMD = "@STCISP#";

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

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


void main(void)
{
    WTST = 0;                                                                                  //设置程序指令延时参数,赋值为0可将CPU执行指令的速度设置为最快
    EAXFR = 1;                                                                                 //扩展寄存器(XFR)访问使能
    CKCON = 0;                                                                                 //提高访问XRAM速度
      
    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 接口配置

    IE2 |= 0x80;                                    //使能USB中断
    EA = 1;                                                                                        //IE |= 0X80;
      
      P40 = 0;
      
      while (DeviceState != DEVSTATE_CONFIGURED);   //等待USB完成配置
      
      while(1)
      {
               
      if (bUsbOutReady)                                                      //如果接收到了数据
      {
            //USB_SendData(UsbOutBuffer,OutNumber);   //发送数据缓冲区,长度(接收数据原样返回, 用于测试)
            
            usb_OUT_done();                                                      //
      }
               
//                //任务1:按下P32按钮灯亮,松开P32按钮灯灭;
//                if( P32 == 0 )                                                                //判断P32按钮是否按下
//                {
//                        P00 = 0;
//                }
//                else
//                {
//                        P00 = 1;
//                }
//               
               
               
//                //任务2:按下P32按钮灯灭,松开P32按钮灯亮;
//                if( P32 == 1 )                                                                //判断P32按钮是否按下
//                {
//                        P00 = 0;
//                }
//                else
//                {
//                        P00 = 1;
//                }
               
                //任务3:按一下灯亮,按一下灯灭
                if( P32 == 0 )                                                                //判断P32按钮是否按下
                {
                        Delay20ms();                                                      //延时20ms消抖
                        if( P32 == 0 )
                        {
                              state = !state;                                                //变量取反 0 1 0 1 0 1
                              P00 = state;
                              printf("state:%d\r\n",(int)state);
                              
                              while( P32 == 0 );                                        //等待P32松开
                              
                        }
                }
      
               
      }
}


按键抖动和防抖



WTST = 0;//设置程序指令延时参数,
EAXFR = 1; //扩展寄存器(XFR)访问使能
CKCON = 0; //提高访问XRAM速度




期待实验箱的到来{:weiqu:}就可以愉快的做实验了
课后任务1:按一下P32按钮灯亮,按一下P33按钮灯灭;

#include "ai8051u.h"                        //调用头文件
#include "stc32_stc8_usb.h"                //调用头文件
#include "intrins.h"                        //调用头文件不要忘记添加

#define u8unsigned char                //8位无符号变量(0-255)
#define u16 unsigned int                //16位无符号变量(0-65535)      

u8 state = 0;                                        //初始状态

char *USER_DEVICEDESC = NULL;
char *USER_PRODUCTDESC = NULL;
char *USER_STCISPCMD = "@STCISP#";

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

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


void main(void)
{
    WTST = 0;                                                                                  //设置程序指令延时参数,赋值为0可将CPU执行指令的速度设置为最快
    EAXFR = 1;                                                                                 //扩展寄存器(XFR)访问使能
    CKCON = 0;                                                                                 //提高访问XRAM速度

    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 接口配置

    IE2 |= 0x80;                                    //使能USB中断
    EA = 1;                                                                                        //IE |= 0X80;

      P40 = 0;

      while (DeviceState != DEVSTATE_CONFIGURED);   //等待USB完成配置

      while(1)
      {

      if (bUsbOutReady)                                                      //如果接收到了数据
      {
            //USB_SendData(UsbOutBuffer,OutNumber);   //发送数据缓冲区,长度(接收数据原样返回, 用于测试)
            
            usb_OUT_done();                                                      //
      }


                if( P32 == 0 )                                                                //判断P32按钮是否按下
                {
                        Delay20ms();                                                      //延时20ms消抖
                        if( P32 == 0 )
                        {
                              P00 = 0;
                              printf("state:%s\r\n","灯亮");

                              while( P32 == 0 );                                        //等待P32松开

                        }
                }

                if( P33 == 0 )                                                                //判断P33按钮是否按下
                {
                        Delay20ms();                                                      //延时20ms消抖
                        if( P33 == 0 )
                        {
                              P00 = 1;
                              printf("state:%s\r\n","灯灭");

                              while( P33 == 0 );                                        //等待P33松开

                        }
                }



      }
}

课后任务2:按一下亮一颗灯,在按一下亮两颗灯,直到全亮(变量+加法和乘法)


#include "ai8051u.h"                        //调用头文件
#include "stc32_stc8_usb.h"                //调用头文件
#include "intrins.h"                        //调用头文件不要忘记添加

#define u8unsigned char                //8位无符号变量(0-255)
#define u16 unsigned int                //16位无符号变量(0-65535)      

u8 state = 0xfe;                                        //初始状态

char *USER_DEVICEDESC = NULL;
char *USER_PRODUCTDESC = NULL;
char *USER_STCISPCMD = "@STCISP#";

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

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


void main(void)
{
    WTST = 0;                                                                                  //设置程序指令延时参数,赋值为0可将CPU执行指令的速度设置为最快
    EAXFR = 1;                                                                                 //扩展寄存器(XFR)访问使能
    CKCON = 0;                                                                                 //提高访问XRAM速度

    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 接口配置

    IE2 |= 0x80;                                    //使能USB中断
    EA = 1;                                                                                        //IE |= 0X80;

      P40 = 0;

      while (DeviceState != DEVSTATE_CONFIGURED);   //等待USB完成配置

      while(1)
      {

      if (bUsbOutReady)                                                      //如果接收到了数据
      {
            //USB_SendData(UsbOutBuffer,OutNumber);   //发送数据缓冲区,长度(接收数据原样返回, 用于测试)
            
            usb_OUT_done();                                                      //
      }

               P0=0xff;
                if( P32 == 0)                                                      //判断P32按钮按下
                {
                        Delay20ms();                                                //延时20ms消抖
                        if( P32 == 0 )                                                
                        {
                              if( P0 == 0x00 )
                              {
                                        state = 0xfe ;
                                        P0 = 0xff;
                              }
                              else
                              {
                                        P0 = state;
                                    state <<=1;
                              }

                        while( P32 == 0);                              //等待P32松开
                        }
                }


      }
}

期待实验箱的到来{:weiqu:}就可以愉快的做实验了
哪怕梦想让我们拼的遍体鳞伤,这一次我们也要勇往直前!!!

Sean 发表于 2025-1-16 13:32:47

非常感谢STC官方 主讲人冲哥

《第七集 定时器中断》学习笔记


“Ai8051U 系列是32位8051 也是优秀的16位机 更是兼容8位机的最强悍的1位机”

单核MCU,同一时间只能执行一个事情,没有特殊情况不能被打断。

这里就要引入定时器中断。


定时器作用:
    (1) 用于计时系统,可实现软件计时,或者使程序每隔一固定时间完成一项操作
    (2) 替代长时间的Delay,提高程序的运行效率和处理速度(可以打断主循环)

利用AIapp-ISP 定时器计算器 生成代码

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                //3秒执行一次
{

}
注意\xfd问题 详见 手册 附录J 关于Keil软件中 0xFD 问题的说明
printf("按键按下次数\xfd:%d 次\r\n",(int)count);


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


定时器实现机制:












   TM0PS = 91
   AUXR&=0x7F(12T模式)      /12
   THO-TL0 = 319


定时器计算公式


函数的定义、声明、调用


返回值类型 函数名(入口参数)
    {
      // 函数体
      // 函数执行的代码
      return 返回值;
    }



定义:包含返回值,函数名和入口参数,并定义了函数具体功能。


函数的名称应当能够描述函数的功能,便于代码的阅读和理解。
    函数名称应当使用有意义的英文单词或者组合的英文单词,避免使用特殊字符或数字。
    函数名称不能与C语言的关键字同名。


返回值类型 函数名(入口参数);
声明:在头文件或者被调用之前使用,注意末尾要加分号

函数名(入口参数);

调用:在需要调用的地方直接使用函数名,加上括号和分号。如果有入口参数的,需要在括号的多个参数之间加逗号隔开。



电子功德箱:
   1.按下按钮1,串口显示“双倍功德时间”,再次按下显示“单倍功德时间”;
      2.按下按键2,双倍功德时间下串口显示“功德+2当前功德:xxx”;      
      3.按下按键2,单倍功德时间下串口显示“功德+1当前功德:xxx”;·
      4.功德+1时,LED点亮1秒后熄灭表示功德成功点亮;
      5.功德+2时,LED点亮2秒后熄灭表示功德成功点亮,



[*]#include <AI8051U.H>
[*]#include "stc32_stc8_usb.h"
[*]#include <intrins.h>
[*]
[*]char *USER_DEVICEDESC = NULL;
[*]char *USER_PRODUCTDESC = NULL;
[*]char *USER_STCISPCMD = "@STCISP#";
[*]
[*]u8 Count_GD = 0;      //功德计数
[*]u8 State_GD = 0;      //功德状态
[*]u8 State_Delay = 1;                //延时状态
[*]
[*]void Delay20ms(void)      //@24.000MHz
[*]{
[*]      unsigned long edata i;
[*]
[*]      _nop_();
[*]      _nop_();
[*]      i = 119998UL;
[*]      while (i) i--;
[*]}
[*]
[*]void Timer1_Isr(void);
[*]
[*]void Timer1_Init(void)                //1秒@24.000MHz
[*]{
[*]      TM1PS = 0x1E;                        //设置定时器时钟预分频 ( 注意:并非所有系列都有此寄存器,详情请查看数据手册 )
[*]      AUXR &= 0xBF;                        //定时器时钟12T模式
[*]      TMOD &= 0x0F;                        //设置定时器模式
[*]      TL1 = 0xFC;                              //设置定时初始值
[*]      TH1 = 0x03;                              //设置定时初始值
[*]      TF1 = 0;                              //清除TF1标志
[*]      TR1 = 1;                              //定时器1开始计时
[*]      ET1 = 1;                              //使能定时器1中断
[*]}
[*]
[*]void main()                                                                                                //按键1为P33按键,按键2为P35按键,在实验箱的右下角两个键。
[*]{
[*]      EAXFR = 1;                                                                                        //打开扩展特殊功能寄存器,等同:P_SW2 |= 0x80;
[*]      CKCON = 0;                                                                                        //提高访问XRAM速度
[*]      WTST = 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;
[*]
[*]      usb_init();                                                                                        //USB口初始化配置
[*]
[*]      IE2 |= 0x80;                                                                              //EUSB位置位,打开USB
[*]      EA = 1;                                                                                                //总中断置位,打开中断
[*]
[*]      P40 = 0;                                                                                        //使能LED总开关
[*]
[*]      while(DeviceState != DEVSTATE_CONFIGURED);                        //等待USB完成配置
[*]
[*]      while(1)
[*]      {
[*]                if(P33 == 0)                                                                        //按下P33触发程序
[*]                {
[*]                        Delay20ms();                                                                //延时消抖
[*]                        if(P33 == 0)                                                                //确实按下按钮
[*]                        {
[*]                              switch(State_GD)                                        //判断功德状态      1=单倍功德;2=双倍功德
[*]                              {
[*]                                        case 0:
[*]                                              break;
[*]                                        case 1:
[*]                                                TR1 = 0;                                                //停止定时器1计时
[*]                                                printf("单倍功德时间\r\n");
[*]                                                P00 = 0;                                                //点亮P00
[*]                                                State_GD = 1;                              //功德状态设为1
[*]                                                Timer1_Init();                                        //开始延时
[*]                                                State_GD = 2;                              //功德状态设为2
[*]                                                break;
[*]                                        case 2:
[*]                                                TR1 = 0;                                                //停止定时器1计时
[*]                                                printf("双倍功德时间\r\n");
[*]                                                P00 = 0;                                                //点亮P00
[*]                                                Timer1_Init();                                        //开始延时
[*]                                                State_GD = 1;                              //功德状态设为1
[*]                                                break;
[*]                              }
[*]                              while(P33 == 0);                                                //等待按键恢复
[*]                        }
[*]                }
[*]
[*]                if(P35 == 0)                                                                        //按下P35触发程序
[*]                {
[*]                        Delay20ms();                                                                //延时消抖
[*]                        if(P35 == 0)                                                                //确实按下按钮
[*]                        {
[*]                              switch(State_GD)                                        //判断功德状态
[*]                              {
[*]                                        case 0:
[*]                                                break;
[*]                                        case 2:                                                                //注意这个模式2是指的P33按键进入单倍功德状态
[*]                                                Count_GD++;                                        //功德计数加1
[*]                                                printf("功德+1 当前功德:%d\r\n",Count_GD);
[*]                                                break;
[*]                                        case 1:                                                                //注意这个模式1是指的P33按键进入双倍功德状态
[*]                                                Count_GD += 2;                              //功德计数加2
[*]                                                printf("功德+2 当前功德:%d\r\n",Count_GD);
[*]                                                break;
[*]                              }
[*]                              while(P35 == 0);                                                //等待按键恢复
[*]                        }
[*]                }
[*]      }
[*]}
[*]
[*]void Timer1_Isr(void) interrupt 3                                                //定时器1回调函数,每秒调用一次
[*]{
[*]      switch(State_GD)
[*]      {
[*]                case 2:                                                                                        //注意这个模式2是指的P33按键进入单倍功德状态
[*]                        P00 = 1;                                                                        //关闭P00
[*]                        TR1 = 0;                                                                        //停止定时器1计时
[*]                        State_GD = 0;                                                      //功德置0
[*]                        break;
[*]                case 1:                                                                                        //注意这个模式1是指的P33按键进入双倍功德状态
[*]                        if(State_Delay == 1)                                                //判断是否是第一次循环
[*]                        {
[*]                              State_Delay++;
[*]                              break;
[*]                        }
[*]                        else
[*]                        {
[*]                              P00 = 1;                                                                //关闭P00
[*]                              TR1 = 0;                                                                //停止定时器1计时
[*]                              State_GD = 0;                                                //功德置0
[*]                              State_Delay = 1;                                                //重新置1
[*]                              break;
[*]                        }
[*]      }
[*]}


哪怕梦想让我们拼的遍体鳞伤,这一次我们也要勇往直前!!!
页: [1]
查看完整版本: Ai8051U 学习 打卡