N3SSS 发表于 2025-1-16 17:20:57

AI8051U学习记录

第一节Ai8051U简介1.1Ai8051应用1.    屏幕显示和视频播放(flash编程器)2.    IIS录放音3.    PWM_DMA4.    频谱分析仪(上位机)5.    手写计算器(Ai功能)6.    QSPI,PWM相移,硬件乘除,单精度浮点1.2 Ai8051基本信息支持8位/32位指令集,性价比高管脚兼容:89C52RC,12C5A60S234K SRAM(2Kedata, 32K xdata), 64K FlashTFPU@120MHz, 硬件浮点/硬件三角函数 运算器DMA支持PWM, DMA支持外设直接到外设, P2P120MHz-PWM支持硬件移相,16位PWM; 真12位ADCUSB, 4组串口,12位ADC, 轨到轨比较器QSPI, SPI, I2S, I2C,TFT-i8080/M6800接口第二节实验环境介绍2.1硬件简介:Ai8051U实验箱1.调试与通讯接口:USB-TypeC、USB-TypeA、USB转双串口、USB Link 1D接口2.声光部件:8路流水灯、8位数码管、OLED显示屏接口、TFT彩屏接口、无源蜂鸣器、话筒录音、立体声线路输出、立体声耳机输出3.按键:矩阵按键、ADC键盘、T0、T1按键、INT0、INT1按键、复位按键、电源按键4. 其他外设:示波器BNC输入、DS18B20温度传感器、32768Hz无源晶振、RTC电池、红外发射接收2.2软件和工具1.编程软件:KeilC251,用于编写程序2.ISP软件:AIapp-ISP,用于下载程序与调试,提供头文件,同时提供多种常用工具3.下载插件:Keil中断拓展插件,可将中断号拓展到2544.下载代码包和手册:方便学习参考2.3下载程序 第三节    点亮LED3.1新建工程3.1.1选择单片机型号3.1.2添加文件添加main.c文件到工程3.1.3配置相关选项CPU Mode :Source模式,Ai8051U系列目前只支持Source模式,由于Ai8051U系列单片机在中断中的压栈和出栈都是4字节模式,勾选”4 Byte Interrupt Fram Size”Memory Model:Xsmall模式,Ai8051U的程序逻辑地址为FF:0000H~FF:FFFFH,需要使用24位地址线才能正确访问,默认的常量类型必须使用“far”类型,默认指针变量必须为4字节Code Rom Size:代码大小在64k以内选择”Large”,超过64k选择”Huge”,同时设置ROM地址和大小HEX文件格式选择:程序大小在64k以内选择HEX-80,超过64k选择HEX-3863.2程序编写3.2.0实验原理(1)当P40为低电平时,控制三极管导通,当P00为低电平时,点亮LED(2)编写程序时,首先要添加单片机对应型号的头文件(3)IO口工作模式配置:通过端口模式配置寄存器PxM0、PxM1进行配置3.2.1添加头文件利用ISP软件添加头文件”ai8051u.h”3.2.2实验程序#include "ai8051u.h"                //调用头文件
//使用擎天柱进行练习

void main(void)                              
{
      P2M1 = 0X00; P2M0 = 0X00;
      
//      P0M1 = 0X00; P0M0 = 0X00;      //配置I/O口模式,准双向
//      P4M1 = 0X00; P4M0 = 0X00;
      
//      P40 = 0;                              //打开开关三极管
      
      while(1)                              
      {
                P20 = 0;
               
//                P00 = 0;                        //低电平点亮LED
               
      }
}

3.2.3实验结果(擎天柱版)成功点亮LED

第四节USB不停电下载4.1下载USB库文件4.2移植关键部分到工程4.2.0实验原理(1)功能脚切换控制(P_SW2)B7:EAXFR,置1使能访问XFR,扩展特殊功能寄存器(2)中断使能寄存器(IE)B7:EA,总中断允许控制位,置1使CPU开放中断4.2.1添加头文件添加“stc_usb_cdc_32.lib”和“stc32_stc8_usb.h”文件4.2.2USB初始化函数由lib与.h文件实现4.2.3命令参数设置自定义命令(相当于密码),用于实现不停电下载4.2.4设置寄存器设置P_SW2与EA(或IE),使能中断功能4.3实验程序4.4实验结果下载程序后识别到USB-CDC,可以实现不停电下载
第五节C语言基础5.1USB-CDC串口之printf函数的实现打开USB库中的PRINTF_HID宏定义(去掉//),将printf重定向到printf_hid最新库文件直接定向到printf_usb,无需使用printf_hid原型函数printf_hid(const char *fmt, …);参数fmt -- 是格式控制字符串,包含了两种类型的对象:普通字符和转换说明。普通字符:在输出时,普通字符将原样不动地复制到标准输出。 printf("8051U深度入门到32位51大型实战视频\r\n");转换说明:不直接输出,用于控制 printf 中参数的转换和打印。每个转换说明都由一个百分号字符(%)开始,以转换说明符结束,从而说明输出数据的类型、宽度、精度等。printf("8051U深度入门到32位51大型实战视频,%s\r\n","加油");转换说明简介:1.类型:根据不同的 fmt 字符串,函数可能需要一系列的附加参数,每个参数包含了一个要被插入的值,替换了 fmt 参数中指定的每个 % 标签。关于附加参数,既可以是变量,也可以是常量。2.位置:printf()函数的普通字符和转换说明放在" "双引号内,附加参数放在双引号外,每个附加参数之间用逗号隔开。3.数量:printf() 的附加参数与转换说明符是⼀⼀对应关系,如果有 n 个转换说明符, printf() 的参数就应该有 n + 1 个。如果参数个数少于对应的转换说明符,printf() 可能会输出内存中的任意值。5.2数的进制:2进制、8进制、10进制、16进制5.3数据的基本类型想要使用64位变量,需要在程序文件里面添加申明:#pragma float645.4C语言常用运算符第六节I/O输入输出6.1GPIO简介GPIO(General Purpose I/O Ports)意思为通用输入/输出端口,可以读入引脚状态(高电平/低电平)和输出高低电平,高电平:VCC,低电平:GNDGPIO工作模式配置:通过PnM1和PnM0进行配置驱动LED的方法: GPIO电压需要在一定范围才能正确识别高低电平6.2按键输入检测6.2.0实验原理使用“==”直接读取引脚电平,按键按下时引脚通过电阻与GND相连,为低电平按键按下后一小段时间内电平会出现波动,一般在20ms以内,使用软件延时进行消抖
软件延时程序:使用ISP软件自动生成6.2.1实验程序常用函数编写在头文件中,便于重复使用//第六节main.h
#include "ai8051u.h"
#include "stc32_stc8_usb.h"
#include "intrins.h"

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

void gpio_Init(void)
{
    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;
}

void usb_Init_p(void)
{
<p style="line-height: 30px; text-indent: 2em;"></p><div style="text-align: left;">    WTST = 0;</div>    EAXFR = 1;
    CKCON = 0;
    usb_init();                                    
   
    EA = 1;
   
    while (DeviceState != DEVSTATE_CONFIGURED);   //等待USB完成配置
      
}

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

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

void usb_Init_p(void);
void Delay20ms(void);
void gpio_Init(void);


//第六节main.c
#include "ai8051u.h"
#include "stc32_stc8_usb.h"
#include "main.h"

#define u8         unsigned char                //8位无符号变量
#define u16 unsigned int                //16位无符号变量

u8 state = 0;
u8 led_state = 0xff;

void main()
{      
      gpio_Init();                                                               
      usb_Init_p();                                                                        //USB初始化

    while (1)
    {      
                if (bUsbOutReady)                                                      //如果接收到了数据
      {
                        USB_SendData(UsbOutBuffer,OutNumber);         //发送数据缓冲区,长度(接收数据原样返回, 用于测试)
            
            usb_OUT_done();                                                      
      }
               
//                //任务3
//                if(P32 == 0)                                                      //判断按键是否按下
//                {
//                        Delay20ms();
//                        if(P32 == 0)
//                        {
//                              state = !state;
//                              P40 = state;
//                              printf("state:%d\r\n", (int)state );
//                        }
//                     
//                        while(P32 == 0);                                        //等待P32松开
//                }
                //课后任务1
//                if(P32 == 0)                                                      //判断按键是否按下
//                {
//                        Delay20ms();
//                        if(P32 == 0)
//                        {
//                              state = !state;
//                              P40 = 0;
//                              printf("亮\r\n");
//                        }
//                     
//                        while(P32 == 0);                                        //等待P32松开
//                }
//                if(P33 == 0)                                                      //判断按键是否按下
//                {
//                        Delay20ms();
//                        if(P33 == 0)
//                        {
//                              P40 = 1;
//                              printf("灭\r\n");
//                        }
//                     
//                        while(P33 == 0);                                        //等待P32松开
//                }
                //课后任务2
                if(P32 == 0)                                                      //判断按键是否按下
                {
                        Delay20ms();
                        if(P32 == 0)
                        {
                              led_state <<= 1;
                              P0 = led_state;
                              printf("%x\r\n", led_state);
                        }
                     
                        while(P32 == 0);                                        //等待P32松开
                }                     
    }
}6.2.2实验结果(课后练习)成功实现要求的功能535第七节定时器中断7.1定时器简介由于MCU是单核的,同一时间只能执行一个事情,没有特殊情况不能被打断。所以这里就要引入一个特殊的情况,定时器中断。定时器作用:    (1) 用于计时系统,可实现软件计时,或者使程序每隔一固定时间完成一项操作    (2) 替代长时间的Delay,提高程序的运行效率和处理速度(可以打断主循环)7.2定时器应用使用ISP软件进行定时器配置7.2.1定时器工作原理(定时器0模式0)系统时钟经过预分频、12分频/不分频作为定时器的输入C/T控制定时器/计数器0作为定时器(置0)还是计数器(置1,输入为外部引脚)T0_M1,T0_M0控制定时器模式,00为16位自动重装载模式TL0与TH0设置定时初始值使能中断后即可实现定时中断功能定时器计算公式:7.2.2实验程序
//main.h
#include "ai8051u.h"
#include "stc32_stc8_usb.h"
#include "intrins.h"

#define u8         unsigned char                //8位无符号变量
#define u16 unsigned int                //16位无符号变量
      
char *USER_DEVICEDESC = NULL;
char *USER_PRODUCTDESC = NULL;
char *USER_STCISPCMD = "@STCISP#";

u16 key_times = 0;
u8 state = 0;
u8 time = 1;
u16 total = 0;


void gpio_Init(void)
{
    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;
}

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

    usb_init();                                     //USB CDC 接口配置
   
    EA = 1;
   
    while (DeviceState != DEVSTATE_CONFIGURED);   //等待USB完成配置
      
}

//BOOL usb_OUT_callback()
//{
//    USB_SendData(UsbOutBuffer,OutNumber);         //发送数据缓冲区,长度(接收数据原样返回, 用于测试)
//    return 1;
//}

void Timer0_Init(void)                //1秒@24.000MHz根据要求修改
{
      WTST = 0;
      EAXFR = 1;
      CKCON = 0;
      
      TM0PS = 0x1E;                        //设置定时器时钟预分频 ( 注意:并非所有系列都有此寄存器,详情请查看数据手册 )
      AUXR &= 0x7F;                        //定时器时钟12T模式
      TMOD &= 0xF0;                        //设置定时器模式
      TL0 = 0xFC;                              //设置定时初始值
      TH0 = 0x03;                              //设置定时初始值
      TF0 = 0;                              //清除TF0标志
      TR0 = 1;                              //定时器0开始计时
      ET0 = 1;                              //使能定时器0中断

      EA = 1;
}

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

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

void key1_Press(void)
{
      if(P32 == 0)                                                      //判断按键是否按下
      {
                Delay20ms();
                if(P32 == 0)
                {
                        //ENTER YOUR CODE
                        //任务1
//                        key_times += 1;
//                        printf("按下次数\xfd:%d\r\n", key_times);
                        //任务2
//                        P40 = 0;
//                        Timer0_Init();
//                        printf("start");
                        //任务3
//                        if(state == 0)                                        //交替闪烁状态
//                        {
//                              P40 = 0;
//                              P45 = 1;
//                              state = 1;
//                              Timer0_Init();
//                              printf("start");
//                        }
//                        else                                                      //熄灭
//                        {
//                              P40 = 1;
//                              P46 = 1;
//                              state = 0;
//                              TR0 = 0;
//                              printf("stop");
//                        }
//                              
                        //课后小练
                        if(time == 1)                                        //倍数切换
                              
                        {
                              time = 2;
                              printf("双倍功德时间");
                        }
                        else
                              
                        {
                              time = 1;
                              printf("单倍功德时间");
                        }
                }
                        
                while(P32 == 0);                                        //等待P32松开
      }
}

void key2_Press(void)
{
      if(P33 == 0)                                                      //判断按键是否按下
      {
                Delay20ms();
                if(P33 == 0)
                {
                        //ENTER YOUR CODE
                        //课后小练
                        total += time;
                        printf("功德+%d\r\n当前功德:%d\r\n", time, total);
                        P40 = 0;                                                //亮灯,开始计时
                        Timer0_Init();
                        
                }
                while(P33 == 0);                                        //等待P32松开
      }
}

void Timer0_Isr(void) interrupt 1
{
      //任务1
//      P40 = !P40;
      //任务2
//      P40 = 1;
//      TR0 = 0;
//      printf("stop");
      //任务3
//      P40 = !P40;                                                                //交替闪烁
//      P46 = !P46;
      //课后小练
      state++;
      if(state == time)                                                //亮time秒后熄灭
               
      {
                P40 = 1;                                                      
                state = 0;
                TR0 = 0;
      }
      
}

//void LED_R(char led_r)
//{
//      P0 = led_r;
//      
//}

//void LED_G(char led_g)
//{
//      P1 = led_g;
//      
//}

//void LED_B(char led_b)
//{
//      P3 = led_b | 0x03;
//      P5 = led_b | 0xfc;
//      
//}

//void LED_Y(char led_y)
//{
//      P2 = led_y;
//      
//}

void gpio_Init(void);
void usb_Init_p(void);
void Timer0_Init(void);
void Delay20ms(void);
void key1_Press(void);
void key2_Press(void);

//main.c
#include "ai8051u.h"
#include "stc32_stc8_usb.h"
#include "main.h"

#define u8         unsigned char                //8位无符号变量
#define u16 unsigned int                //16位无符号变量



void main()
{      
      gpio_Init();                                                                        //gpio初始化为准双向
//      Timer0_Init();                                                                        //计时器0初始化
      usb_Init_p();                                                                        //usb初始化

    while (1)
    {      
//                if (bUsbOutReady)                                                      
//      {
//                        USB_SendData(UsbOutBuffer,OutNumber);         
//            
//                        printf("输入\n");
//            usb_OUT_done();                                                      
//      }
                key1_Press();
                key2_Press();
               
               
    }
}

//void Timer0_Isr(void) interrupt 1
//{
//      //任务1
////      P40 = !P40;
//}7.2.3实验结果(课后练习)536

N3SSS 发表于 2025-1-21 01:36:30

test

wangpengbo 发表于 2025-2-6 16:32:55

我收到的擎天柱怎么只有P20到P26有灯?你们的都是自己后焊上的吗

N3SSS 发表于 2025-2-24 12:10:00

wangpengbo 发表于 2025-2-6 16:32
我收到的擎天柱怎么只有P20到P26有灯?你们的都是自己后焊上的吗

自己焊的
页: [1]
查看完整版本: AI8051U学习记录