王昱顺 发表于 2025-3-3 22:27:09

Ai8051U 使用内部自带的 硬件USB 直接仿真 的演示视频:
https://v.stcai.com/sv/441001ec-1955ec96d2e/441001ec-1955ec96d2e.mp4
视频中使用到的程序:


王昱顺 发表于 2025-3-5 17:34:25

按键控制点灯并使用USB仿真查看汇编代码-演示视频及附带代码
https://v.stcai.com/sv/3ac65752-19565b59541/3ac65752-19565b59541.mp4

代码文件下载:

王昱顺 发表于 2025-3-5 17:38:59

使用USB-CDC读取按键状态并点灯-演示视频
https://v.stcai.com/sv/371ea5b4-19565b5956f/371ea5b4-19565b5956f.mp4

程序文件:

神农鼎 发表于 2025-3-6 19:28:59


本楼附件有参考程序

I/O 口的工作模式 实验建议:
【准双向口/弱上拉】;
【强推挽输出】;
【高阻输入】,内部还有6K上拉电阻配合;
===打开内部上拉6K上拉配合读外部状态
【开漏模式】,内部还有6K上拉电阻配合;
===打开内部上拉6K,就相当于【准双向口/弱上拉】

I/O读外部状态,可以用如下三种模式:
【准双向口/弱上拉】;
【高阻输入】,内部还有6K上拉电阻配合;
===打开内部上拉6K上拉配合读外部状态
【开漏模式】,内部还有6K上拉电阻配合;
===打开内部上拉6K,就相当于【准双向口/弱上拉】

I/O对外输出高/低,可以用如下三种模式:
【准双向口/弱上拉】;
【强推挽输出】;
【开漏模式】
===对外输出低,就是强推挽的低
===对外输出高,就是高阻输入,没电流流进,也没电流流出,灯不亮

P3.2/P3.3/P3.4/P3.5 都有按键接地,建议:



P0口 都有单独的指示灯

实验1, 位操作,用USB直接仿真来调试:
单独 读这几个独立I/O的状态,P3.2/P3.3/P3.4/P3.5
输出到 P0.2/P0.3/P0.4/P0.5 对应的指示灯
单独读时,分别用三种I/O口的工作模式测试下
单独输出时,分别用三种I/O口的工作模式测试下


I/O读外部状态,可以用如下三种模式:
【准双向口/弱上拉】;
【高阻输入】,内部还有6K上拉电阻配合;
===打开内部上拉6K上拉配合读外部状态
【开漏模式】,内部还有6K上拉电阻配合;
===打开内部上拉6K,就相当于【准双向口/弱上拉】

I/O对外输出高/低,可以用如下三种模式:
【准双向口/弱上拉】;
【强推挽输出】;
【开漏模式】
===对外输出低,就是强推挽的低
===对外输出高,就是高阻输入,没电流流进,也没电流流出,灯不亮


实验2, 整组8位端口操作,用USB直接仿真来调试:
整组 读这几个I/O的状态【P3.2/P3.3/P3.4/P3.5】,一次性读全部P3口
整体输出到 【P0.2/P0.3/P0.4/P0.5】在的P0口对应的指示灯
整组读时,分别用三种I/O口的工作模式测试下
整组输出时,分别用三种I/O口的工作模式测试下


I/O读外部状态,可以用如下三种模式:
【准双向口/弱上拉】;
【高阻输入】,内部还有6K上拉电阻配合;
===打开内部上拉6K上拉配合读外部状态
【开漏模式】,内部还有6K上拉电阻配合;
===打开内部上拉6K,就相当于【准双向口/弱上拉】

I/O对外输出高/低,可以用如下三种模式:
【准双向口/弱上拉】;
【强推挽输出】;
【开漏模式】
===对外输出低,就是强推挽的低
===对外输出高,就是高阻输入,没电流流进,也没电流流出,灯不亮


实验三,不用USB仿真,用 USB-CDC通信:
电脑 ISP软件中的,USB-CDC串口助手 通知 单片机读 P3.2/P3.3/P3.4/P3.5的状态。
1,送回 USB-CDC串口助手 显示
2,送到 AIapp-ISP 软件中的 【调试仿真接口 | 擎天柱-LED-PID40】虚拟显示
===通信协议见 【调试仿真接口 | 接口协议及帮助】部分















功能2:控制DIP40的指定组管脚上LED的状态
命令格式:4CH 45H 44H 28H 02H x1 px
命令说明:

第1~4字节:命令头
第5字节:后面有效数据长度
第6字节:P0~P5端口的屏蔽位
(01H:P0, 02H:P1, 04H:P2, 08H:P3, 10H:P4, 20H:P5)
第7字节:端口的状态

使用串口通讯请参考下面的示例发送串口数据
示例1:发送4CH 45H 44H 28H 02H 01H 55H

设置P0口的状态为55H
示例2:发送4CH 45H 44H 28H 02H 04H AAH

设置P2口的状态为AAH
库函数声明:void LED40_SetPort(BYTE port, BYTE dat);
*** 包含库函数的头文件后,不用另外声明 ***

项目中包含库函数后,可直接调用下面的库函数
库函数调用:LED40_SetPort(0, 0x55);    //设置P0口输出55H
LED40_SetPort(1, 0xaa);    //设置P1口输出AAH


功能3:控制DIP40的指定管脚输出高电平
命令格式:4CH 45H 44H 28H 02H 00H px ...
命令说明:

第1~4字节:命令头
第5字节:后面有效数据长度
第6字节:固定为00H
第7字节:端口的状态数据px
px的bit7:固定为1
px的bit6~bit3:指定第几组管脚(0:P0,1:P1,2:P2,...)
px的bit2~bit0:指定管脚的第几位(0:bit0,1:bit1,...)

使用串口通讯请参考下面的示例发送串口数据
示例1:发送4CH 45H 44H 28H 02H 00H 83H

设置P0.3口输出高电平
示例2:发送4CH 45H 44H 28H 02H 00H a5H

设置P4.5口输出高电平
库函数声明:void LED40_SetBit(BYTE port, BYTE bt);
*** 包含库函数的头文件后,不用另外声明 ***

项目中包含库函数后,可直接调用下面的库函数
库函数调用:LED40_SetBit(0, 3);    //设置P0.3口输出高电平
LED40_SetBit(4, 5);    //设置P4.5口输出高电平


功能4:控制DIP40的指定管脚输出低电平
命令格式:4CH 45H 44H 28H 02H 00H px ...
命令说明:

第1~4字节:命令头
第5字节:后面有效数据长度
第6字节:固定为00H
第7字节:端口的状态数据px
px的bit7:固定为0
px的bit6~bit3:指定第几组管脚(0:P0,1:P1,2:P2,...)
px的bit2~bit0:指定管脚的第几位(0:bit0,1:bit1,...)

使用串口通讯请参考下面的示例发送串口数据
示例1:发送4CH 45H 44H 28H 02H 00H 03H

设置P0.3口输出低电平
示例2:发送4CH 45H 44H 28H 02H 00H 25H

设置P4.5口输出低电平
库函数声明:void LED40_ClrBit(BYTE port, BYTE bt);
*** 包含库函数的头文件后,不用另外声明 ***

项目中包含库函数后,可直接调用下面的库函数
库函数调用:LED40_ClrBit(0, 3);    //设置P0.3口输出低电平
LED40_ClrBit(4, 5);    //设置P4.5口输出低电平


神农鼎 发表于 2025-3-10 13:14:37





I/O 口章节的实验5的思考:
实验5,I/O口 行列式按键扫描 大型实战,利用主循环次数去抖动
如1个按键要判断为正常按下,而不是抖动,
假定需要该按键保持按下持续保持为低状态时间是 50mS ~ 200mS;
假定1个主循环的运行时间大概 10mS ~ 30mS
则如发现某个按键按下,需要连续 6次主循环都能读到该按键按下
===如发现多个按键按下,则归0,重新开始

调整按键的灵敏度只需要修改,
===【判断按键已按下的时间,即读到为低经历了多少次主循环的次数】


Project9 实验程序 简要说明,详见附件:
1,上电P0口的8个LED闪烁3次当作开机画面,
2,接下来行列按键矩阵扫描,
   A, 每扫描到一个键,蜂鸣器发不同的声音,
         8个按键对应Do/Re/Mi/Fa/So/La/Si/Do,
   B, 同时在电脑端的CDC串口助手中显示“KeyX被按下”








王昱顺 发表于 2025-3-10 14:24:43

矩阵按键部分的拓展视频讲解,原理讲解,程序逐行解释:
I/O 口章节的实验5的思考:
实验5,I/O口 行列式按键扫描 大型实战,利用主循环次数去抖动

神农鼎 发表于 2025-3-15 08:43:37

传统外部中断 INT0/INT1/INT2/INT3/INT4 实验的思考

INT0/P3.2 外部中断实验演示程序:
1,边缘触发中断
P3.2设置为高阻输入,打开内部上拉电阻;

P3.2设置为准双向口,打开内部上拉电阻;
INT2/P3.2设置为 边缘触发中断;

将 P3.2按键按下,不松开;
进中断后,读到是 低,下降沿,点亮 P0.0,退出中断服务程序;

松开 P3.2中断;
进中断后,读到是 高,上升沿,点亮 P0.7, 退出中断服务程序;

利用仿真,可以设置运行到断点处,捕捉当前程序运行到哪,
是 下降沿,还是上升沿

2,下降沿触发中断

王昱顺 发表于 2025-3-17 11:45:39

USB仿真:
INT0 / INT1 模式0:边沿触发中断 /【下降沿,上升沿】;
INT0 / INT1 模式1:下降沿中断;并点灯指示状态,仿真断点功能讲解




USB仿真:用户程序主动控制 I/O口拉低 INT2/INT3 触发 下降沿中断









王昱顺 发表于 2025-3-23 14:54:53

深圳大学,实验课演示视频
定时器部分讲解-T0/T1 定时中断,并点灯,及更简单的USB-CDC回传信息
Timer0 定时 2S 产生中断,Timer1 定时 500mS 产生中断;
思考题:T2 定时 20mS,T3 定时 1mS ,T4 定时 200uS 产生中断



深圳大学,实验课演示视频
RTC实时时钟部分讲解-闹钟定时,及更简单的USB-CDC与电脑通信






神农鼎 发表于 2025-3-23 16:19:15

Timer0 定时 2S 产生中断
Timer1 定时 500mS 秒产生中断
思考题:
Timer2 定时 20mS 产生中断
Timer3 定时 1mS 秒产生中断
Timer4 定时 200uS 秒产生中断

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

bit t0_flag = 0, t1_flag = 0;
void Timer0_Isr(void) interrupt 1
{
      P00 = ~P00;
      t0_flag = 1;
}

void Timer0_Init(void)                //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 3
{
      P07 = ~P07;
      t1_flag = 1;
}

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


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 口为准双向口模式
      P6M0 = 0x00; P6M1 = 0x00; //设置 P6 口为准双向口模式
      P7M0 = 0x00; P7M1 = 0x00; //设置 P7 口为准双向口模式
      
      usb_init();
      EA = 1;
      
      Timer0_Init();
      Timer1_Init();
      
      P40 = 0;
      while(1)
      {
                if(t0_flag)
                {
                        t0_flag = 0;
                        printf_usb("Timer0 Int\r\n");
                }
                if(t1_flag)
                {
                        t1_flag = 0;
                        printf_usb("Timer1 Int\r\n");
                }
      }
}

页: 1 [2] 3 4 5 6 7
查看完整版本: 深圳大学《单片机原理及接口技术》上机实验演示视频@Ai8051U