ANop
发表于 2023-8-10 22:58:15
【第九集】心得体会
主要内容:1、认识数码管 2、数码管的控制原理(静态显示) 3、实现数码管0-9的显示
static/image/hrline/4.gif
1、认识数码管
数码管分为共阴极和共阳极,型号尾缀A表示共阳极,K表示共阴极。
本质是由7个LED灯按照特定位置排列成断码数字,因此控制起来和驱动LED灯相似
2、数码管的控制原理-数码管的静态使用
控制断码屏显示,需要控制两组IO口,一组负责位选,一组负责段选
共阳数码管段选IO给低电平点亮 共阴数码管段选IO给高电平点亮
3、数码管1-9的显示
共阳极数码管显示数字对应的段码
10进制段码数组 {192,249,164,176,153,146,130,248,128,144}
16进制段码数组 {0xC0,0xF9,0xA4,0xB0,0x99,0x92,0x82,0xF8,0x80,0x90}
共阴极数码管显示数字对应的段码
10进制段码数组 {63,6,91,79,102,109,125,7,127,111}
16进制段码数组 {0x3F,0x06,0x5B,0x4F,0x66,0x6D,0x7D,0x07,0x7F,0x6F}
共阳和共阴数码管段码是相互按位取反的关系
ANop
发表于 2023-8-11 13:22:59
【第十集】心得体会
主要内容:1、数码管动态刷新的原理
2、数码管动态显示控制原理
3、8位数码管同时点亮
1、数码管动态刷新的原理
同时显示多个数码管时,为何使用动态刷新的方式显示:由于多个数码管公用同一组断码控制引脚,多个数码管显示不同数字时,会相互冲突,因此通过动态刷新的方式,利用人眼的视觉暂留特性,短时间内快速切换断码和位选实现多数码管同时显示的效果。
补充:人眼的视觉不容易分辨出50HZ 以上的动态刷新,需要注意每个延时不能太短且需要保证总共一个循环结束的时间不能大于 20ms
2、数码管动态显示控制原理
3、8位数码管同时点亮
ANop
发表于 2023-8-11 13:55:02
【第十一集】心得体会
主要内容: 1.了解定时器的意义和作用 2、学习使用定时器(初始化配置)3、通过定时器初步了解中断这一概念
1、软件定时的缺点:占用CPU时间,影响CPU的运行效率和处理速断,有时会造成很大的定时误差。
2、中断的概念:中断请求、中断响应(中断处理程序)、中断返回,本节主要是讲定时器中断。
3、定时器的使用(以T0为例)
1)设置为定时器/计数器
寄存器TMOD的T0_CT位:0为定时模式,1为计数模式
2)设置不分频或12分频
通过设置辅助寄存器AUXR的T0x12:0为12分频(默认为0),1为不分频。
3)定时器工作模式T0_M1/T0_M0
16位自动重载模式比较常用。
4)定时器设置 (定时器 0/1 控制寄存器TCON)
TF0:T0 溢出中断标志。该位软件清0,也可以不清0。
TR0:定时器 T0 的运行控制位。该位软件置1,开启定时器。
5)中断
IE:中断使能寄存器,EA:总中断允许控制位。EA=1允许中断。
ET0:定时 / 计数器 T0 的溢出中断允许位。ET0=1允许定时器中断。
4、实现T0定时器中断的主要程序
T0初始化程序
TMOD =0x00; // 设置定时器 0 位 16 位自动重载模式
TL0=0x30; // 计算出的 24M 时钟下的 1ms 的定时时间初始值
TH0=0xF8:
TR0=1; //启动定时器
ET0 =1; // 使能定时器中断
EA = 1; //CPU 开放中断,打开总中
T0中断响应程序
void Tim0_Isr() interrupt 1 //1-定时器0中断号
{
}
补充:利用STC-ISP的“定时器计算器”自动生成定时器初始化程序
中断处理函数(回调函数)要遵循快进快出的原则,避免在中断中编写会产生阻滞的代码
ANop
发表于 2023-8-11 14:01:15
【第十二集】心得体会
主要内容:计数器的常见用途、基本配置及使用
1、计数器的用途
只要输出信号带高低电平变化,想要计算个数的就可以用计数器的功能。
2、计数器的配置
T1_C/T:控制定时器1用作定时器或计数器。T1_C/T=1为计数器
T1_GATE:控制定时器 1,置 1 时只有在 INT1 脚为高及 TR1 控制位置 1 时才可打开定时器 / 计数器 1。此例将T1_GATE清零。
3、计数器的使用
定时器1计数器初始化代码:
TMOD=0x40; // 设置计数器模式
TL1=0xFF; // 设置计数初始值
TH1=0xFF; // 设置计数初始值
TF1=0; // 清除 TF1 标志
TR1=1; // 定时器 1 开始计时
ET1=1; // 使能定时器 1 中断
P3PU=0x20; //打开内部4.1k上拉电阻
定时器1中断响应函数
void Tim1_Isr() interrupt 3 //3-定时器1中断号
{
}
4、计数器应用实例
void Timer0_Isr(void) interrupt 1
{
TinCount++; // 每隔 1ms+1,计数到 2000=2s
if(TimCount>=2000) //2 秒定时时间到了
{
TinCount = 0;
Count_T1=(TH1 *256)+ 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(); // 数码管刷新的
}
}
ANop
发表于 2023-8-11 14:55:29
【第十三集】心得体会
主要内容:初步建立起模块化编程的思想,并学习编写工程文件
1、模块化编程:
----------------------------------------------
创建程序文件三步
新建文件并保存
添加到工程 (添加.c文件)
添加引用路径
一般可以建立hardware、object、system、user四个文件夹,分别放置硬件外设相关的.c.h文件、编译输出文件、片上外设相关的.c.h文件、用户代码
感觉也有其他的分类方式根据习惯分门别类建立文件就好{:4_186:}
函数定义三步
定义
声明
调用
模块化程序的编写
一个模块需要.c和.h两个文件,以seg_led为例:
seg_led.h
#ifndef __SEG_LED_H
#define__SEG_LED_H
//------------------调用头文件------------------
//------------------引脚定义---------------------
//------------------变量声明---------------------
//------------------函数声明---------------------
#endif
同时在要调用的.c文件中需要引入头文件
seg_led.c
#include "seg_led.h"
补充:
修饰符 extern 的使用
修饰符 extern 用在变量或者函数的声明前,用来说明“此变量 / 函数是在别处定义的,要在此处引用”。
举例 1:如果文件 a.c 需要引用 b.c 中变量 int v,就可以在 a.c 中声明 extern int v,然后就可以引用变量 v。
举例 2:如果文件 a.c 需要引用 b.c 中变量 int v,就可以在 b.h 中声明 extern int v,然后 a.c 调用 b.h 就可以引用变量 v。
注意 extern 修饰的变量不能赋初值。
----------------------------------------------------------
这一集中,冲哥介绍了Keil中template的使用,终于不用再重复敲函数注释啦{:4_171:}
为函数添加相应的说明/注释,以便后期维护和其他开发者使用
注释信息一般包含:
//========================================
// 函数名称:
// 函数功能:
// 入口参数:@
// 函数返回:
// 当前版本:VER 1.0
// 修改日期:2023
// 当前作者:
// 其他备注:
//=========================================
ANop
发表于 2023-8-11 15:09:42
【第十四集】心得体会
主要内容:学习使用矩阵键盘
矩阵键盘的读取 在程序上,感觉和数码管的动态显示有相似之处,矩阵键盘里行列的概念和数码管断码/位码很像
编程思路(分别行扫/列扫,两次确定按下按键的坐标,坐标映射好键值就可以了)
1、连接按键行的端口位输出高电平,列输出低电平,延时后读取端口值,如果有按键按下相应的行就是低电平,获得值与发送值进行异或;
2、连接按键行的端口位输出低电平,列输出高电平,延时后读取端口值,如果有按键按下相应的列就是低电平,获得值与发送值进行异或;
3、两次结果相与得到按键码。
u8 MaterixKey_Read()
{
u8 keystate; //状态
u8 key_val = 0;
MaterixKey = 0xC0;
delay_ms(10);
keystate = MateixKey ^ 0xC0;
MaterixKey = 0x0f;
delay_ms(10);
keystate |= (MateixKey ^ 0x0f);
printf("0x%02x \r\n",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;
}
KEY_NUM = MaterixKey_Read();
SEG7 = KEY_NUM;
return keystate;
}
ANop
发表于 2023-8-11 15:35:32
【第十五集】心得体会
static/image/hrline/2.gif
1、中断和外部中断:
打断主程序或其他低优先级中断,临时处理紧急事件,处理后立即跳回之前地址继续运行,对提高程序的实时性很有帮助
外部电平变化产生的中断,INT引脚为外部中断口(可用来读取外部的电平变化)
2、中断程序编写
//中断初始化函数-一外部中断INT0为例
void INT0_Init(void) // 外部中断 0 的初给化
{
IT0=1; //1:下降沿中断 0:上升下降沿中断
EX0=1; // 允许中断
IE0=0; // 清除中断标志位
}
//主程序
void main()
{
EA=1; //开总中断
}
//中断响应程序
void INT0_Isr(void) interrupt 0
{
..........
}
课后练习:
外部中断1的程序
***********************************
void INT1_Init(void) // 外部中断 0 的初给化
{
IT1=1; //1:下降沿中断 0:上升下降沿中断
EX1=1; // 允许中断
IE1=0; // 清除中断标志位
}
//主程序
void main()
{
EA=1; //开总中断
}
//中断响应程序
void INT1_Isr(void) interrupt 2
{
..........
}
************************************
什么情况使用外部中断
当需要输入或者输出时就要用到外部设备,而外部设备相比于处理器要慢得多。在等待的时候,处理器只能不停的扫描外部设备的状态变化,这轮询扫描的方式无疑会占用处理器资源
此时外部中断的使用能更加高效的节约硬件资源,仅在外部状态变化时,才通知处理器前来处理
Teddy_xpz
发表于 2023-8-11 16:23:50
首次学习
Teddy_xpz
发表于 2023-8-11 16:24:55
首次学习,老师讲解很棒。
ANop
发表于 2023-8-15 17:21:09
Teddy_xpz 发表于 2023-8-11 16:24
首次学习,老师讲解很棒。
嗯呢嗯呢{:4_166:}{:4_166:}