fs_ajin
发表于 2025-6-19 09:14:32
学习
fs_ajin
发表于 2025-6-19 09:14:45
学习
dcc20250218
发表于 2025-6-19 09:39:06
每天进步一点点。
red枫叶
发表于 2025-6-19 14:43:39
努力学习
heceer
发表于 2025-6-19 16:35:51
大力支持!!!
srkxrolz
发表于 2025-6-20 01:38:15
打卡
第五课 C语言基础语法 运算符略
srkxrolz
发表于 2025-6-20 01:41:13
打卡
第六课 gpio
高电平接近VCC的电压
低电平 接近 GND的电压
接口可以承受的电压位位vcc+0.3V
如果单片机使用5V电压,那么gpio端口可以接受的对打电压就是5+0.3=5.3V
如果VCC是3.0v那么gpio最大就是3+.3=3.3V
所有GPIO在复位后默认都是打开施密特触发器的
例: VCC=3.3V高电>=1.18v低电平<=0.99
其他电器限制如下图:
P0M0与P0M1一起决定gpio的4种工作模式
M0=0M1=0 弱上拉
M0=1M1=0 推挽输出
M0=0M1=1 高阻态
M0=1M1=1 开漏模式
#include "ai8051u.h"
#include "ai_usb.h"
bit p32_status = 0;// 初始化状态
bit p33_status = 0;// 初始化状态
void Delay20ms(void) //@40.000MHz
{
unsigned long edata i;
_nop_();
_nop_();
i = 199998UL;
while (i)
i--;
}
void main()
{
WTST = 0;// 设置程序指令延时参数
EAXFR = 1; // 设置EAXFR位为1,允许访问扩展寄存器
CKCON = 0; // 提高访问xram速度
P2M0 = 0x00; // 设置P2口为通用I/O口
P2M1 = 0x00; // 设置P2口为通用I/O口
P2 = 0x0f; // 设置P2口初始状态
usb_init(); // 初始化USB
EA = 1; // 允许总中断
printf_usb("P32: %d, P33: %d\n", P32, P33); // 打印P32和P33的状态
while (1)
{
if (bUsbOutReady) // 检查Usb是否准备好
{
USB_SendData(UsbOutBuffer, OutNumber);
// printf_usb("1. Read Num:%d\n", OutNumber);
// printf_usb("2. Read Num:%d\n", OutNumber);
// printf_usb("3. Read Num:%d\n", OutNumber);
// printf_usb("4. Read Num:%d\n", OutNumber);
usb_OUT_done();
}
if (P32 == 0)
{
Delay20ms(); // 延时20ms
if (P32 == 0)
{
p32_status = !p32_status; // 切换状态
P20 = p32_status; // 设置P2.0为高电平
while (P32 == 0)
;
printf("P32 pressed, status: %d\n", p32_status);
}
}
if (P33 == 0)
{
Delay20ms(); // 延时20ms
if (P33 == 0)
{
p33_status = !p33_status; // 切换状态
P21 = p33_status; // 设置P2.0为高电平
while (P32 == 0)
;
printf("P33 pressed, status: %d\n", p33_status);
}
}
}
}
srkxrolz
发表于 2025-6-20 04:34:06
第七课:定时器和中断Stc-isp中可以生成定时器时钟和中断函数例子中使用定时器0 生成3秒一次的中断调用,在中断处理中控制LEd状态中断程序优先级高于while可以比较准确的实现程序定时执行,但是中断程序中尽量不要执行耗时太长的程序,一般只作为标志的更改,具体执行可以交给while进行 TM0PS = 0x1E; //设置定时器时钟预分频 ( 注意:并非所有系列都有此寄存器,详情请查看数据手册 ) AUXR &= 0x7F; //定时器时钟12T模式 TMOD &= 0xF0; //设置定时器模式 TL0 = 0xFC; //设置定时初始值 TH0 = 0x03; //设置定时初始值 TF0 = 0; //清除TF0标志 TR0 = 1; //定时器0开始计时 ET0 = 1; //使能定时器0中断定时器的结构 系统时钟sysclk时钟通过TM0PS设置分频(tm0ps的值+1:如果tmops设位0则表示不分频,但是实际计算的时需要为1,因此预分频会自动加1),然后得到的时钟还可以进行12分频或者1分频,然后获得的时钟通过GATE选择是时钟脉冲技术还是外部脉冲计数,计数器中由两套寄存器完成TH0和TL0可以组成一个16位的计数器,RL_TH0和RL_TL0是他们的影子寄存器,他们有同一个地址,这里具体过程需要看手册视频并没有详细讲解他们的工作过程,在这里反正就是用作自动重装载,当计数器从初始值计数到溢出则产生一个中断,这时候如果TF0中断标志位置1就调用中断函数,这个溢出信号还可以通过因gpio输出,但是这就需要T0clk允许位控制了 函数定义:返回值类型函数名 (参数){函数体;Return 返回值;} #include "ai8051u.h"#include "ai_usb.h"bit p32_status = 0; // 初始化状态bit p33_status = 0; // 初始化状态unsigned long systick_cont = 0; // 系统滴答计数器 void Delay1000ms(void) //@24.000MHz{ unsigned long edata i; _nop_(); _nop_(); i = 5999998UL; while (i) i--;} void Timer0_Isr(void) interrupt 1{ P20 = ~P20; // 切换P20状态 systick_cont++; // 增加系统滴答计数器 // printf_usb("systick_cont: %d\n", systick_cont);} void Timer0_Init(void) //1秒@24.000MHz{ TM0PS = 0x1E; //设置定时器时钟预分频 ( 注意:并非所有系列都有此寄存器,详情请查看数据手册 ) AUXR &= 0x7F; //定时器时钟12T模式 TMOD &= 0xF0; //设置定时器模式 TL0 = 0xFC; //设置定时初始值 TH0 = 0x03; //设置定时初始值 TF0 = 0; //清除TF0标志 TR0 = 1; //定时器0开始计时 ET0 = 1; //使能定时器0中断} void main(){ WTST = 0;// 设置程序指令延时参数 EAXFR = 1; // 设置EAXFR位为1,允许访问扩展寄存器 CKCON = 0; // 提高访问xram速度 P2M0 = 0x00; // 设置P2口为通用I/O口 P2M1 = 0x00; // 设置P2口为通用I/O口 P2 = 0x0f; // 设置P2口初始状态 Timer0_Init(); // 初始化定时器0 usb_init(); // 初始化USB EA = 1; // 允许总中断 while (1) { Delay1000ms(); // 延时1秒 P21 = ~P21; // 切换P21状态 printf("systick:%dP20: %d P21: %d\n", systick_cont, P20, P21); // 打印P21和P20状态 if (bUsbOutReady) // 检查Usb是否准备好 { USB_SendData(UsbOutBuffer, OutNumber);// printf_usb("1. Read Num:%d\n", OutNumber);// printf_usb("2. Read Num:%d\n", OutNumber);// printf_usb("3. Read Num:%d\n", OutNumber);// printf_usb("4. Read Num:%d\n", OutNumber); usb_OUT_done(); } }}
red枫叶
发表于 2025-6-20 07:32:06
好好学习
laohu_zhou
发表于 2025-6-20 08:15:57
继续打卡学习。