找回密码
 立即注册
查看: 1442|回复: 3

AI8051U学习记录

[复制链接]
  • 打卡等级:偶尔看看I
  • 打卡总天数:10
  • 最近打卡:2025-03-05 16:01:08

1

主题

2

回帖

71

积分

注册会员

积分
71
发表于 2025-1-16 17:20:57 | 显示全部楼层 |阅读模式
第一节Ai8051U简介
1.1Ai8051应用
1.    屏幕显示和视频播放(flash编程器)
2.    IIS录放音
3.    PWM_DMA
4.    频谱分析仪(上位机)
5.    手写计算器(Ai功能)
6.    QSPI,PWM相移,硬件乘除,单精度浮点
1.2 Ai8051基本信息
支持8位/32位指令集,性价比高
管脚兼容:  89C52RC,  12C5A60S2
34K SRAM(2Kedata, 32K xdata), 64K Flash
TFPU@120MHz, 硬件浮点/硬件三角函数 运算器
DMA支持PWM, DMA支持外设直接到外设, P2P
120MHz-PWM支持硬件移相,16位PWM; 真12位ADC
USB, 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中断拓展插件,可将中断号拓展到254
4.下载代码包和手册:方便学习参考
2.3下载程序
截图202501231404472840.jpg
第三节    点亮LED
3.1新建工程
3.1.1选择单片机型号
截图202501191601379210.jpg
3.1.2添加文件
添加main.c文件到工程
3.1.3配置相关选项
截图202501191602278925.jpg
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地址和大小
截图202501191602537671.jpg
HEX文件格式选择:程序大小在64k以内选择HEX-80,超过64k选择HEX-386
3.2程序编写
3.2.0实验原理
(1)当P40为低电平时,控制三极管导通,当P00为低电平时,点亮LED
(2)编写程序时,首先要添加单片机对应型号的头文件
(3)IO口工作模式配置:通过端口模式配置寄存器PxM0、PxM1进行配置
截图202501191603061713.jpg
3.2.1添加头文件
截图202501191603201158.jpg
利用ISP软件添加头文件”ai8051u.h”
3.2.2实验程序
  1. #include "ai8051u.h"                //调用头文件
  2. //使用擎天柱进行练习
  3. void main(void)                                
  4. {
  5.         P2M1 = 0X00; P2M0 = 0X00;
  6.         
  7. //        P0M1 = 0X00; P0M0 = 0X00;        //配置I/O口模式,准双向
  8. //        P4M1 = 0X00; P4M0 = 0X00;
  9.         
  10. //        P40 = 0;                                //打开开关三极管
  11.         
  12.         while(1)                                
  13.         {
  14.                 P20 = 0;
  15.                
  16. //                P00 = 0;                        //低电平点亮LED
  17.                
  18.         }
  19. }
复制代码

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实验程序
截图202501191603571277.jpg
4.4实验结果
下载程序后识别到USB-CDC,可以实现不停电下载
截图202501191604092691.jpg

第五节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 参数中指定的每个 % 标签。
关于附加参数,既可以是变量,也可以是常量。
截图202501210114251854.jpg
截图202501210114492731.jpg
截图202501210115041302.jpg
2.位置:printf()函数的普通字符和转换说明放在" "双引号内,附加参数
放在双引号外,每个附加参数之间用逗号隔开。
3.数量:printf() 的附加参数与转换说明符是⼀⼀对应关系,如果有 n 个转
换说明符, printf() 的参数就应该有 n + 1 个。如果参数个数少于对应的转
换说明符,printf() 可能会输出内存中的任意值。
5.2数的进制:2进制、8进制、10进制、16进制
5.3数据的基本类型
截图202501210115348402.jpg
想要使用64位变量,需要在程序文件里面添加申明:#pragma float64
5.4C语言常用运算符
截图202501210115586074.jpg
截图202501210116077346.jpg
截图202501210116217936.jpg
截图202501210116309436.jpg
截图202501210116398095.jpg
截图202501210116472804.jpg
第六节I/O输入输出
6.1GPIO简介
GPIO(General Purpose I/O Ports)意思为通用输入/输出端口,可以读入引脚状态(高电平/低电平)和输出高低电平,高电平:VCC,低电平:GND
GPIO工作模式配置:通过PnM1和PnM0进行配置
截图202501210117309098.jpg
驱动LED的方法:
截图202501210117487092.jpg
GPIO电压需要在一定范围才能正确识别高低电平
截图202501210117592641.jpg
6.2按键输入检测
6.2.0实验原理
使用“==”直接读取引脚电平,按键按下时引脚通过电阻与GND相连,为低电平
截图202501210118255902.jpg
按键按下后一小段时间内电平会出现波动,一般在20ms以内,使用软件延时进行消抖
截图202501210118349202.jpg

软件延时程序:使用ISP软件自动生成
截图202501210119226088.jpg
6.2.1实验程序
常用函数编写在头文件中,便于重复使用
  1. //第六节main.h
  2. #include "ai8051u.h"
  3. #include "stc32_stc8_usb.h"
  4. #include "intrins.h"
  5. char *USER_DEVICEDESC = NULL;
  6. char *USER_PRODUCTDESC = NULL;
  7. char *USER_STCISPCMD = "@STCISP#";
  8. void gpio_Init(void)
  9. {
  10.     P0M1 = 0x00;   P0M0 = 0x00;
  11.     P1M1 = 0x00;   P1M0 = 0x00;
  12.     P2M1 = 0x00;   P2M0 = 0x00;
  13.     P3M1 = 0x00;   P3M0 = 0x00;
  14.     P4M1 = 0x00;   P4M0 = 0x00;
  15.     P5M1 = 0x00;   P5M0 = 0x00;
  16.     P6M1 = 0x00;   P6M0 = 0x00;
  17.     P7M1 = 0x00;   P7M0 = 0x00;
  18. }
  19. void usb_Init_p(void)
  20. {
  21. <p style="line-height: 30px; text-indent: 2em;"></p><div style="text-align: left;">    WTST = 0;</div>    EAXFR = 1;
  22.     CKCON = 0;
  23.     usb_init();                                    
  24.    
  25.     EA = 1;
  26.    
  27.     while (DeviceState != DEVSTATE_CONFIGURED);     //等待USB完成配置
  28.         
  29. }
  30. void Delay20ms(void)        //@24.000MHz
  31. {
  32.     unsigned long edata i;
  33.     NOP1();
  34.     NOP1();
  35.     i = 119998UL;
  36.     while (i) i--;
  37. }
  38. void usb_Init_p(void);
  39. void Delay20ms(void);
  40. void gpio_Init(void);
  41. //第六节main.c
  42. #include "ai8051u.h"
  43. #include "stc32_stc8_usb.h"
  44. #include "main.h"
  45. #define u8         unsigned char                //8位无符号变量
  46. #define u16 unsigned int                //16位无符号变量
  47. u8 state = 0;
  48. u8 led_state = 0xff;
  49. void main()
  50. {      
  51.         gpio_Init();                                                               
  52.         usb_Init_p();                                                                        //USB初始化
  53.     while (1)
  54.     {      
  55.                 if (bUsbOutReady)                                                        //如果接收到了数据
  56.         {
  57.                         USB_SendData(UsbOutBuffer,OutNumber);           //发送数据缓冲区,长度(接收数据原样返回, 用于测试)
  58.             
  59.             usb_OUT_done();                                                      
  60.         }
  61.                
  62. //                //任务3
  63. //                if(P32 == 0)                                                        //判断按键是否按下
  64. //                {
  65. //                        Delay20ms();
  66. //                        if(P32 == 0)
  67. //                        {
  68. //                                state = !state;
  69. //                                P40 = state;
  70. //                                printf("state:%d\r\n", (int)state );
  71. //                        }
  72. //                       
  73. //                        while(P32 == 0);                                        //等待P32松开
  74. //                }
  75.                 //课后任务1
  76. //                if(P32 == 0)                                                        //判断按键是否按下
  77. //                {
  78. //                        Delay20ms();
  79. //                        if(P32 == 0)
  80. //                        {
  81. //                                state = !state;
  82. //                                P40 = 0;
  83. //                                printf("亮\r\n");
  84. //                        }
  85. //                       
  86. //                        while(P32 == 0);                                        //等待P32松开
  87. //                }
  88. //                if(P33 == 0)                                                        //判断按键是否按下
  89. //                {
  90. //                        Delay20ms();
  91. //                        if(P33 == 0)
  92. //                        {
  93. //                                P40 = 1;
  94. //                                printf("灭\r\n");
  95. //                        }
  96. //                       
  97. //                        while(P33 == 0);                                        //等待P32松开
  98. //                }
  99.                 //课后任务2
  100.                 if(P32 == 0)                                                        //判断按键是否按下
  101.                 {
  102.                         Delay20ms();
  103.                         if(P32 == 0)
  104.                         {
  105.                                 led_state <<= 1;
  106.                                 P0 = led_state;
  107.                                 printf("%x\r\n", led_state);
  108.                         }
  109.                        
  110.                         while(P32 == 0);                                        //等待P32松开
  111.                 }                       
  112.     }
  113. }
复制代码
6.2.2实验结果(课后练习)
成功实现要求的功能
第七节定时器中断
7.1定时器简介
由于MCU是单核的,同一时间只能执行一个事情,没有特殊情况不能被打断。所以这里就要引入一个特殊的情况,定时器中断。
定时器作用:
    (1) 用于计时系统,可实现软件计时,或者使程序每隔一固定时间完成一项操作
    (2) 替代长时间的Delay,提高程序的运行效率和处理速度(可以打断主循环)
7.2定时器应用
使用ISP软件进行定时器配置
截图202501210332595731.jpg
7.2.1定时器工作原理(定时器0模式0)
截图202501210333327802.jpg
系统时钟经过预分频、12分频/不分频作为定时器的输入
C/T控制定时器/计数器0作为定时器(置0)还是计数器(置1,输入为外部引脚)
T0_M1,T0_M0控制定时器模式,00为16位自动重装载模式
TL0与TH0设置定时初始值
使能中断后即可实现定时中断功能
定时器计算公式:
截图202501210333495619.jpg
7.2.2实验程序
  1. //main.h
  2. #include "ai8051u.h"
  3. #include "stc32_stc8_usb.h"
  4. #include "intrins.h"
  5. #define u8         unsigned char                //8位无符号变量
  6. #define u16 unsigned int                //16位无符号变量
  7.         
  8. char *USER_DEVICEDESC = NULL;
  9. char *USER_PRODUCTDESC = NULL;
  10. char *USER_STCISPCMD = "@STCISP#";
  11. u16 key_times = 0;
  12. u8 state = 0;
  13. u8 time = 1;
  14. u16 total = 0;
  15. void gpio_Init(void)
  16. {
  17.     P0M1 = 0x00;   P0M0 = 0x00;
  18.     P1M1 = 0x00;   P1M0 = 0x00;
  19.     P2M1 = 0x00;   P2M0 = 0x00;
  20.     P3M1 = 0x00;   P3M0 = 0x00;
  21.     P4M1 = 0x00;   P4M0 = 0x00;
  22.     P5M1 = 0x00;   P5M0 = 0x00;
  23.     P6M1 = 0x00;   P6M0 = 0x00;
  24.     P7M1 = 0x00;   P7M0 = 0x00;
  25. }
  26. void usb_Init_p(void)
  27. {
  28.     WTST = 0;
  29.         EAXFR = 1;
  30.         CKCON = 0;
  31.     usb_init();                                     //USB CDC 接口配置
  32.    
  33.     EA = 1;
  34.    
  35.     while (DeviceState != DEVSTATE_CONFIGURED);     //等待USB完成配置
  36.         
  37. }
  38. //BOOL usb_OUT_callback()
  39. //{
  40. //    USB_SendData(UsbOutBuffer,OutNumber);           //发送数据缓冲区,长度(接收数据原样返回, 用于测试)
  41. //    return 1;
  42. //}
  43. void Timer0_Init(void)                //1秒@24.000MHz根据要求修改
  44. {
  45.         WTST = 0;
  46.         EAXFR = 1;
  47.         CKCON = 0;
  48.         
  49.         TM0PS = 0x1E;                        //设置定时器时钟预分频 ( 注意:并非所有系列都有此寄存器,详情请查看数据手册 )
  50.         AUXR &= 0x7F;                        //定时器时钟12T模式
  51.         TMOD &= 0xF0;                        //设置定时器模式
  52.         TL0 = 0xFC;                                //设置定时初始值
  53.         TH0 = 0x03;                                //设置定时初始值
  54.         TF0 = 0;                                //清除TF0标志
  55.         TR0 = 1;                                //定时器0开始计时
  56.         ET0 = 1;                                //使能定时器0中断
  57.         EA = 1;
  58. }
  59. void Delay20ms(void)        //@24.000MHz
  60. {
  61.         unsigned long edata i;
  62.         NOP1();
  63.         NOP1();
  64.         i = 119998UL;
  65.         while (i) i--;
  66. }
  67. void key1_Press(void)
  68. {
  69.         if(P32 == 0)                                                        //判断按键是否按下
  70.         {
  71.                 Delay20ms();
  72.                 if(P32 == 0)
  73.                 {
  74.                         //ENTER YOUR CODE
  75.                         //任务1
  76. //                        key_times += 1;
  77. //                        printf("按下次数\xfd:%d\r\n", key_times);
  78.                         //任务2
  79. //                        P40 = 0;
  80. //                        Timer0_Init();
  81. //                        printf("start");
  82.                         //任务3
  83. //                        if(state == 0)                                        //交替闪烁状态
  84. //                        {
  85. //                                P40 = 0;
  86. //                                P45 = 1;
  87. //                                state = 1;
  88. //                                Timer0_Init();
  89. //                                printf("start");
  90. //                        }
  91. //                        else                                                        //熄灭
  92. //                        {
  93. //                                P40 = 1;
  94. //                                P46 = 1;
  95. //                                state = 0;
  96. //                                TR0 = 0;
  97. //                                printf("stop");
  98. //                        }
  99. //                                
  100.                         //课后小练
  101.                         if(time == 1)                                        //倍数切换
  102.                                 
  103.                         {
  104.                                 time = 2;
  105.                                 printf("双倍功德时间");
  106.                         }
  107.                         else
  108.                                 
  109.                         {
  110.                                 time = 1;
  111.                                 printf("单倍功德时间");
  112.                         }
  113.                 }
  114.                         
  115.                 while(P32 == 0);                                        //等待P32松开
  116.         }
  117. }
  118. void key2_Press(void)
  119. {
  120.         if(P33 == 0)                                                        //判断按键是否按下
  121.         {
  122.                 Delay20ms();
  123.                 if(P33 == 0)
  124.                 {
  125.                         //ENTER YOUR CODE
  126.                         //课后小练
  127.                         total += time;
  128.                         printf("功德+%d\r\n当前功德:%d\r\n", time, total);
  129.                         P40 = 0;                                                //亮灯,开始计时
  130.                         Timer0_Init();
  131.                         
  132.                 }
  133.                 while(P33 == 0);                                        //等待P32松开
  134.         }
  135. }
  136. void Timer0_Isr(void) interrupt 1
  137. {
  138.         //任务1
  139. //        P40 = !P40;
  140.         //任务2
  141. //        P40 = 1;
  142. //        TR0 = 0;
  143. //        printf("stop");
  144.         //任务3
  145. //        P40 = !P40;                                                                //交替闪烁
  146. //        P46 = !P46;
  147.         //课后小练
  148.         state++;
  149.         if(state == time)                                                //亮time秒后熄灭
  150.                
  151.         {
  152.                 P40 = 1;                                                        
  153.                 state = 0;
  154.                 TR0 = 0;
  155.         }
  156.         
  157. }
  158. //void LED_R(char led_r)
  159. //{
  160. //        P0 = led_r;
  161. //        
  162. //}
  163. //void LED_G(char led_g)
  164. //{
  165. //        P1 = led_g;
  166. //        
  167. //}
  168. //void LED_B(char led_b)
  169. //{
  170. //        P3 = led_b | 0x03;
  171. //        P5 = led_b | 0xfc;
  172. //        
  173. //}
  174. //void LED_Y(char led_y)
  175. //{
  176. //        P2 = led_y;
  177. //        
  178. //}
  179. void gpio_Init(void);
  180. void usb_Init_p(void);
  181. void Timer0_Init(void);
  182. void Delay20ms(void);
  183. void key1_Press(void);
  184. void key2_Press(void);
  185. //main.c
  186. #include "ai8051u.h"
  187. #include "stc32_stc8_usb.h"
  188. #include "main.h"
  189. #define u8         unsigned char                //8位无符号变量
  190. #define u16 unsigned int                //16位无符号变量
  191. void main()
  192. {        
  193.         gpio_Init();                                                                        //gpio初始化为准双向
  194. //        Timer0_Init();                                                                        //计时器0初始化
  195.         usb_Init_p();                                                                        //usb初始化
  196.     while (1)
  197.     {        
  198. //                if (bUsbOutReady)                                                        
  199. //        {
  200. //                        USB_SendData(UsbOutBuffer,OutNumber);           
  201. //            
  202. //                        printf("输入\n");
  203. //            usb_OUT_done();                                                        
  204. //        }
  205.                 key1_Press();
  206.                 key2_Press();
  207.                
  208.                
  209.     }
  210. }
  211. //void Timer0_Isr(void) interrupt 1
  212. //{
  213. //        //任务1
  214. ////        P40 = !P40;
  215. //}
复制代码
7.2.3实验结果(课后练习)
回复

使用道具 举报 送花

  • 打卡等级:偶尔看看I
  • 打卡总天数:10
  • 最近打卡:2025-03-05 16:01:08

1

主题

2

回帖

71

积分

注册会员

积分
71
发表于 2025-1-21 01:36:30 | 显示全部楼层
test
回复

使用道具 举报 送花

  • 打卡等级:偶尔看看III
  • 打卡总天数:55
  • 最近打卡:2025-06-03 14:25:12
已绑定手机

0

主题

10

回帖

244

积分

中级会员

积分
244
发表于 2025-2-6 16:32:55 | 显示全部楼层
我收到的擎天柱怎么只有P20到P26有灯?你们的都是自己后焊上的吗
回复 支持 反对

使用道具 举报 送花

  • 打卡等级:偶尔看看I
  • 打卡总天数:10
  • 最近打卡:2025-03-05 16:01:08

1

主题

2

回帖

71

积分

注册会员

积分
71
发表于 2025-2-24 12:10:00 | 显示全部楼层
wangp*** 发表于 2025-2-6 16:32
我收到的擎天柱怎么只有P20到P26有灯?你们的都是自己后焊上的吗

自己焊的
回复 支持 反对

使用道具 举报 送花

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

本版积分规则

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

GMT+8, 2025-7-2 03:08 , Processed in 0.750087 second(s), 71 queries .

Powered by Discuz! X3.5

© 2001-2025 Discuz! Team.

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