dmdll
发表于 2024-9-18 14:52:16
这学习很认真啊
阿杰爱学单片机
发表于 2024-9-18 16:14:38
加油啊
惦饭宝
发表于 2024-9-20 10:48:46
本帖最后由 惦饭宝 于 2024-9-20 10:49 编辑
惦饭宝 发表于 2024-9-18 09:04
第十一集:定时器的使用👌
1.定时器的作用和意义
定时器的工作原理基于定时器芯片上的计数器。当开始 ...
第十二集:计数器的使用✋😘
1.计数器的用途
记录和显示输入信号的数量
计数器是一种重要的电子设备,用于记录和显示输入信号的数量。 它具有事件计数、频率测量和定时功能等作用,广泛应用于数字电路和计算机系统中。 根据工作原理和应用场景的不同,计数器可以分为同步计数器、异步计数器、预置计数器和可递减计数器等不同类型。
2.计数器的配置
使用T1_pin引脚输入外部输入
T1_CT需要写1,不然是定时器模式了
T1_C/T:控制定时器1用作定时器或计数器,清0则用作定时器(对内部系统时钟进行计数),置1用作计数器(对引脚T1/P3.5外部脉冲进行计数)。
TO_GATE:控制定时器0,置1时只有在INTO脚为高及TRO控制位置1时才可打开定时器/计数器O。
65536溢出
通过TMOD的0X40的设置将他写为计数器模式
TL1 TH1设置为0xff,相当于每来一个脉冲就能进中断
TR1 启动定时器
ET1 EA == 1,使得它可以进入中断
通过按钮来模拟脉冲
上拉电阻控制寄存器(PxPU),在对应位置写1启动上拉电阻。
上拉电阻的作用:确保在未按下按钮时输入引脚上具有高电平状态,避免信号浮动和噪音干扰。
快捷计算软件
ENABLE使能打开上拉电阻
DISABLE关闭上拉电阻
3.计数器的应用
使用下降沿检测,从高电平到低电平来检测
1.修改动态数码管显示,使前四个数码管不显示
u8 Show_Tab = {20,20,20,20,0,0,0,0};
2.新增一个Count_T1来计数
u16 Count_T1 = 0;
3.初始化计数器
TMOD = 0x50; //设置计数器模式
TL1 = 0x00; //设置计数初始值
TH1 = 0x00; //设置计数初始值
TF1 = 0; //清除TF1标志
TR1 = 1; //定时器1开始计时
ET1 = 1; //使能定时器1中断
P3PU = 0x20; //打开内部上拉4.1K
Timer0_Init();
4.编写计数器0服务函数:
void Timer0_Isr(void) interrupt 1
{
TimCount++; //每隔1ms+1 //计数到2000 = 2s
if( TimCount>=2000 ) //2秒定时时间到了
{
TimCount = 0;
Count_T1 = (TH1 *256 )+ TL1; // 转/2s转/min TH1和TL1溢出之后直接触发中断,如果没有溢出那么可以直接读取。
TH1 = 0;
TL1 = 0;
Show_Tab = Count_T1/1000%10;
Show_Tab = Count_T1/100%10;
Show_Tab = Count_T1/10%10;
Show_Tab = Count_T1/1%10;//取10位
}
SEG_Fre(); //数码管刷新的
}
视频文件:
课后练习:
1.尝试将单位转化成转/秒或者转l分钟
思路:将定时器时间改为1s✋
TimCount>=1000
将定时时间改为60s
TimCount>=60000
void Timer0_Isr(void) interrupt 1
{
TimCount++; //每隔1ms+1 //计数到2000 = 2s
if( TimCount>=1000 ) //1秒定时时间到了
{
TimCount = 0;
Count_T1 = (TH1 *256 )+ TL1; // 转/2s转/min TH1和TL1溢出之后直接触发中断,如果没有溢出那么可以直接读取。
TH1 = 0;
TL1 = 0;
Show_Tab = Count_T1/1000%10;
Show_Tab = Count_T1/100%10;
Show_Tab = Count_T1/10%10;
Show_Tab = Count_T1/1%10;//取10位
}
SEG_Fre(); //数码管刷新的
}
2.思考如果计数器溢出了程序要怎么写
思路:在计数器溢出时,需要重置计数器,并确保程序不会因为溢出而产生错误。在计数器每次读取时检查溢出并做处理。
if (TH1 == 0xFF && TL1 == 0xFF)// 检查计数器是否溢出
{
// 处理溢出情况
TH1 = 0;
TL1 = 0;
Count_T1 = 0;// 重新计数
}
END👆
惦饭宝
发表于 2024-9-21 18:02:13
本帖最后由 惦饭宝 于 2024-9-21 18:07 编辑
惦饭宝 发表于 2024-9-20 10:48
第十二集:计数器的使用✋😘
1.计数器的用途
第十三集:简易多任务处理😁
一.回顾
1.认识单片机
2.了解单片机硬件(介绍开发板)
3.开发环境搭建和下载,新工程建立资料下载
4.点亮点一个LED(CDC和HID下载)
5.C语言运算符和进制数入门
6.LED闪烁和花式点灯
7.按键点亮灯
8.蜂鸣器
9.数码管的静态使用
10.数码管动态点亮
11.定时器
12.计数器的使用
重点理清程序的逻辑思路。
二.应用模块化的编程(.c+.h)
添加示例:
右键新建示例
1)创建程序文件三步:
新建文件并保存
添加到工程添加
引用路径
2)引脚定义都在.h文件:
sbit名称=P10;
#define 名称 P10
3)函数定义三步:
定义
声明
调用
4)修饰符extern用在变量或者函数的声明前,用来说明“此变量1函数是在别处定义的,要在此处引用”
举例1:如果文件a.c需要引用b.c中变量intv,就可以在a.c中声明extern intV,然后就可以引用变量V。
举例2:如果文件a.c需要引用b.c中变量intv,就可以在b.h中声明extern intV,然后a.c调用b.h就可以引用变量V。
注意extern修饰的变量不能赋初值。
5)bdata位寻址变量的使用
a.c
u8 bdata LED =0x00:
sbit LEDO = LED^0:
sbit LED1 = LED^4.
a.h
extern u8 bdata LED:
extern bit LED0:
extern bit LED1.
Static: 只有第一次进入函数的时候可以赋值[只赋值一次]。
蜂鸣器文件:
按键文件:
数码管文件:
定时器文件:
惦饭宝
发表于 2024-9-22 08:31:23
本帖最后由 惦饭宝 于 2024-9-22 08:33 编辑
惦饭宝 发表于 2024-9-21 18:02
第十三集:简易多任务处理😁
一.回顾
第十四集:矩阵按键😄
1.矩阵按键是什么
在按键数量较多时,为了减少IO口的占用,将按键排列成矩阵排列的形式的按键阵列我们称位矩阵按键。
2.矩阵按键的控制原理
按键识别原理:端口默认为高电平,实时读取到引脚为低电平是表示按下
第一步:现将P0.0-P0.3输出低电平,P0.6-P0.7输出高电平,如果有按键按下,按下的那一列的I0就会变成低电平,就可以判断出哪一列按下了。
第二步:现将P0.0-P0.3输出高电平,P0.6-P0.7输出低电平,如果有按键按下,按下的那一行的I0就会变成低电平,就可以判断出哪一行按下了。
第三步:行列组合一下就可以判断出是哪个按键按下了
这样的行列式键盘结构能够有效地提高单片机系统中I/O口的利用率。
节约单片机的资源,其本质和独立按键类似,就是进行逐行扫描和逐列扫描,然后判断是第几行的第几列个按键,进而进行整体按键值得确定,我们使用的矩阵键盘是接到了单片机的P1口通过读取P1口电平变换即可完成矩阵键盘的数值读取
3.矩阵按键程序的编写
读取一个矩阵按键的按键状态,判断哪个按键被按下,并返回对应的按键编码(键码)。代码分为三个主要步骤:扫描列、扫描行、判断按键状态并通过 switch 语句将按键状态值映射到具体的键码,并返回相应的值。
u8 MateixKEY_Read(void) //矩阵按键读取当前是哪一个按钮按下
{
static u8 keystate_last; //表示当前的按钮的上一次的状态值
u8 keystate; //表示当前的按钮的状态值
u8 key_val = 0; //表示当前按键的键码
//第一步:先将P0.0-P0.3输出低电平,P0.6-P0.7输出高电平,如果有按键按下,按下的那一列的IO就会变成低电平,就可以判断出哪一列按下了。
MateixKEY = 0XC0; //1100 0000
MateixKEY_delay();
keystate = (MateixKEY ^ 0XC0); //0100 0000 ^ 1100 0000 =1000 0000
//第二步:先将P0.0-P0.3输出高电平,P0.6-P0.7输出低电平,如果有按键按下,按下的那一行的IO就会变成低电平,就可以判断出哪一行按下了。
MateixKEY = 0X0f; //0000 1111
MateixKEY_delay();
keystate |= (MateixKEY ^ 0X0f); //0000 1110 ^ 0000 1111 =0000 0001 | 1000 0000 = 0x81
//第三步:行列组合一下就可以判断出是哪个按键按下了。
// printf("0x%02x\r\n",keystate);
if( keystate_last != keystate ) //如果说本次获取到的按键状态值和之前的不一样
{
keystate_last = keystate; //把本次的按键状态值写入进去
switch ( keystate ) //根据这案件的状态值,返回对应的键码
{
case 0x41: key_val = 1;
break;
case 0x42: key_val = 2;
break;
case 0x44: key_val = 3;
break;
case 0x48: key_val = 4;
break;
case 0x81: key_val = 5;
break;
case 0x82: key_val = 6;
break;
case 0x84: key_val = 7;
break;
case 0x88: key_val = 8;
break;
default: key_val = 0;
break;
}
//printf("%d\r\n",(int)key_val);
}
return key_val; //返回最终的键码,没有按下时返回0
}
4.课上小练
密码锁:
1.通过LED0模拟门锁状态,LED点亮表示门锁打开,熄灭表示门锁锁上。
2.增加8位数码管,可以动态显示8位的密码,无密码时显示"------- "
3.通过矩阵按键可以输入1-8的数字表示密码,并依次显示在数码管上。
4.每输入一个数字,蜂鸣器响20ms表示有数字按下。
5.密码正确打开LED0,密码错误蜂鸣响2秒。
思路:
初始化时,将LED0设置为输出模式,初始状态为熄灭,配置8位数码管和矩阵按键的扫描功能,并初始化蜂鸣器的控制端口。输入密码时,通过矩阵按键扫描,识别用户按下的数字键,并将相应数字显示在数码管对应位置,同时蜂鸣器响20ms作为反馈。当8位密码输入完成时,系统自动进入密码验证环节。密码验证中,系统将输入的8位密码与预设密码进行比较。如果密码正确,LED0点亮;如果密码错误,蜂鸣器响2秒提示错误,数码管恢复显示“-------”。密码输入错误或验证完成后,系统会重置状态,清空数码管,等待下一次输入。
5.课后小练
1.LEDO(门锁)打开后,5秒后自动关闭:
2.增加门内的手动开门按钮,按下按钮门锁打开:
3.10秒内没有输入密码自动数码管熄灭省电;有按键按下时再显示。
思路:
LED0(门锁)打开后,5秒后自动关闭:
在检测到密码输入正确并打开LED0后,启动一个计时器(5秒计时)。当计时器到达5秒时,关闭LED0,模拟门锁自动上锁。
增加门内的手动开门按钮,按下按钮门锁打开:
增加一个新按键(假设为 KEY_OPEN),用于手动开门。检测到 KEY_OPEN 按下时,立即打开门锁(LED0亮起)。
10秒内没有输入密码自动数码管熄灭省电,有按键按下时再显示:
通过计时器实现自动熄灭功能。如果在10秒内没有检测到按键输入,则熄灭数码管显示。检测到新的按键输入时重新点亮数码管。
白水大虾2016
发表于 2024-9-22 09:40:13
这学习态度值得点赞!相比之下我还在8051的固化思维中{:cry:}
惦饭宝
发表于 2024-9-22 19:51:56
本帖最后由 惦饭宝 于 2024-9-22 19:53 编辑
惦饭宝 发表于 2024-9-22 08:31
第十四集:矩阵按键😄
1.矩阵按键是什么
第十五集:外部中断👌😄
一.中断和中断系统
什么是中断:
当中央处理机 CPU 正在处理某件事的时候外界发生了紧急事件请求,要求 CPU 暂停当前的工作,转而去处理这个紧急事件,处理完以后,再回到原来被中断的地方,继续原来的工作,这样的过程称头中断。
中断源:请示 CPU 中断的请求源
优点:CPU 总是先响应优先级别最高的中断请求。
如果 CPU 能够暂停对原来中断源的服务程序,转而去处理优先级更高的中断请求源,处理完以后,再回到原低级中断服务程序,这样的过程称为中断嵌套。
用户可以用关总中断允许位(EAIE.7)或相应中断的允许位屏蔽相应的中断请求,也可以用打开相应的中断允许位来使 CPU 响应相应的中断申请,每一个中断源可以用软件独立地控制为开中断或关中断状态,部分中断的优先级别均可用软件设置。
中断系统包含哪些中断:
使用别的芯片时注意有无对应的中断源👇
............
中断次序:
二.什么是外部中断
外部中断就是在单片机的一个引脚上,由于外部因素导致了一个电平的变化(比如由高变低),而通过捕获这个变化,单片机内部自主运行的程序就会被暂时打断,转而去执行相应的中断处理程序,执行完后又回到原来中断的地方继续执行原来的程序。
INT开头的都是外部中断,INT0中断号--0,INT1中断号--2,INT2中断号--10,INT3中断号--11,INT0中断号--16。
什么引脚可以作为外部中断口?
看芯片原理图,上面标注了INT或者其他中断,像INT0只能在P3^2引脚使用。
三.外部中断的用法
INT0是一个可配置为下降沿或低电平触发的外部中断,其中断优先级可以通过PX0位来控制。通过EX0位和EA位来控制是否使能INT0中断。在多个中断发生时,INT0的处理优先级将根据PX0的设定与其他中断相比较,从而确定处理顺序。
外部中断0/外部中断1/外部中断x:x=2-4
ITO IT1 INTXIF
IEO IE1 IE1
EX0 EX1 EXn
EA EA EA
一个按键按下的时候是上升沿,松开时时下降沿,所以配置IT0来选择哪个方式来触发
此处最好手动清0,防止误进中断
外部中断的应用场景:
紧急停止按钮:在工业设备或生产线工作时,操作员可以按下紧急停止按钮,立即中断机器的运行,以防止事故发生。
传感器报警:在安全监控系统中,某个传感器(如烟雾或温度传感器)检测到异常情况时,会触发外部中断,立即向控制系统发送警报,启动应急措施。
运动控制:在机器人或自动化设备中,可以通过外部中断来响应外部事件,如检测到物体的出现,立即停止或改变机器的运动轨迹。
外部中断的理解:
外部中断程序和主程序是两个分开独立运行的程序,只不过通过一些变量的交互来发生作用。这么多外部中断,意味着我可以一次性有许多独立的程序运行。🤔
搜索:外部中断的多个端口意味着你的系统可以同时响应多个独立事件。虽然它们在处理时是独立的,但实际上是在一个时间片内交替运行的,这样能让系统看起来像是在“同时”处理多个任务。
墨染
发表于 2024-9-23 16:38:14
向大佬学习
晓飛飛
发表于 2024-9-24 23:25:01
打卡写的比较认真,超过了99%的其它用户,赞一个!
惦饭宝
发表于 2024-9-25 14:00:23
晓飛飛 发表于 2024-9-24 23:25
打卡写的比较认真,超过了99%的其它用户,赞一个!
谢谢😘