一、嵌入式C语言
重点笔记:
6.10.枚举类型及应用案例
枚举类型是一种用户基于int类型自定义的数据类型,它可以让数据更简洁、易读:
(1)当数据只有有限个数的数值组成时,通常用枚举类型来表示。
(2)语法格式:
enum 枚举类型名称 {枚举元素1,枚举元素2,...}
注意:
(1)枚举元素的类型是int类型,如果没有明确赋值,数值从0开始,依次递增1。
(2)}后面需要有;号。
(3)枚举元素可以进行赋值。
for循环和while循环的功能基本相同,for循环一般选用于事先知道需要循环的次数,while循环选用于为了达到某个目标之后才停止的条件。
本次学习内容有,枚举类型的应用,for循环语句及for循环语句嵌套的应用,while循环语句和do while语句的简单了解,最后是break(终止循环)和continue(跳出本次循环)语句的使用。
二、51单片机(7-8章节)
1、定时器和中断(单片机的核心内容)
7.1 中断的概念
在主程序正在执行过程中,外界发生了紧急事件的请求,此时需要先打断主程序的运行先去处理紧急事件,当紧急事件处理完后再回到原来被打断的地方继续执行;
中断是可以多级嵌套的,优先级较高的先执行。
中断响应条件:
1.中断源有中断请求
2.此中断的中断允许位为1
3.CPU开中中断(即EA=1)
注意:以上三点同时满足时,cpu才响应中断。
其余可阅读技术文档进行配置!
7.2 体验单片机的外部中断
中断函数的写法
void 函数名() interrupt 中断号
{
内部中断服务程序
}
注意:
(1).中断函数使用前不需要申明
(2).中断函数自动执行,不需要任何函数调用
外部中断配置:
EA = 1; 打开总中断
EX0 = 1; 打开外部中断
IT0 = 1; 设置中断类型为下降沿
写一个中断程序,作用是在我们用杜邦线接地后与P32口短接后蜂鸣器长响,此时需要注意如果中断类型为低电平触发,则会导致数码管闪烁,出现这种现象的原因是因为由低电平触发的话,当在线没有断开的时候cpu会不断检测,不断进入到中断函数中,打扰了主程序的运行。
7.3 关系运算
在C语言中判断一个条件是真与假,成立则真,不成立则假
特别注意:关系表达式是一个运算,它的输出结果只有一个(真或者假)
这是一个疑问句。
7.5 定时器和中断的详解
学习根据芯片手册配置定时器。
7.6 定时器装初值的计算方法
当定时器低8位从0开始加满到高8位需要65535个机器周期,再加1个后溢出,产生中断,所以65535+1=65536个机器周期,而每个机器周期是12个时钟周期。
如果是12M的晶振,每个时钟周期为:1/12000000=0.083us;
每个机器周期为:12*0.083=1us,即每加一个数消耗的时间为:1us;
如果TH0和TL0初值都为0,那么加满一次需要耗时65536*1us=65.536ms;
此时为了方便计时,我们通常取整数,如:一次中断耗时50ms,20次中断即1秒;
50ms的初值计算方法:
初值 = 65536 - 50000 = 15536,
TH0 = 15536/256 TL0 = 15536%256
TH0 = (65536-50000)/256 TL0 = (65536-50000)%256
7.7 定时器0模式1用法
使用定时器的流程:
1.TMOD确定T0和T1的工作方式 TMOD=0x01
2.计算初值,并写入TL和TH寄存器、TH0 = 1;TL0 = 1;
3.开启总中断,开启定时器中断,启动定时器 EA = 1;
4.编写中断函数,在中断函数中再次写初值
5.处理其它事务的程序
2、按键检测原理
8.1 实现按键检测的方法
1.独立按键检测
2.矩阵按键扫描
3.AD采样电压
4.使用模拟开关CD4051或CD4067
5.专用芯片
8.2 逻辑运算符
也称为布尔运算,结果只有两个值,1或0,真或假
逻辑与:&& 只有两个操作数都为真,结果才为真,否则为假
(用于判断两个条件必须成立时)
逻辑或:|| 只要有一个操作数为真,结果就为真,两个都为假,结果为假
(用于判断或者,或者条件时)
逻辑非:! 取反,非0就是真,非真就是假
优先级别:!>&& > ||
混合运算时:! > 算数运算 > 关系运算 > && > || > 赋值运算
主要用于if和while语句中
8.3 查询法实现独立按键检测
#include<stc89c5xrc.h>
#include<intrins.h>
#define uint unsigned int
#define uchar unsigned char
#define beep P23
#define dula P26
#define wela P27
//uchar num,temp;
uint num,num1,dis,key;
uchar code table[]={
0x3f,0x06,0x5b,0x4f,
0x66,0x6d,0x7d,0x07,
0x7f,0x6f,0x77,0x7c,
0x39,0x5e,0x79,0x71};
//声明函数
void DelayMs(uint c);
void Display(uint shu);
void Init();
/*--------------------------*/
void main ()
{
P34=0;
Init();
while(1)
{
if(key==1)
{
while(!P23)
Display(num);
key=0;
num++;
}
Display(num);
}
}
/*--------------------------*/
void Init()
{
TMOD=0x11;//配置定时器0和1都是工作模式1
TH0=(65536-46296)/256;
TL0=(65536-46296)%256;//装初值
TH1=(65536-45296)/256;
TL1=(65536-45296)%256;//装初值
EA=1;//打开总中断
ET0=1;//打开定时器0的中断
ET1=1;//打开定时器1的中断
// TR0=1;//启动定时器0
// TR1=1;//启动定时器1
EX0=1;//打开外部中断0
IT0=1;//设置中断类型为下降沿
}
void Int0() interrupt 0
{
// beep=~beep;
key=1;
}
void Time0() interrupt 1
{
TH0=(65536-46296)/256;
TL0=(65536-46296)%256;//装初值
num++;
}
void Time1() interrupt 3
{
TH1=(65536-45296)/256;
TL1=(65536-45296)%256;//装初值
num1++;
}
void DelayMs(uint c)
{
uint a,b;
for(a=c;a>0;a--)
for(b=115;b>0;b--);
}
void Display(uint shu)
{
wela=1;
P0=0xfe;//11111110 打开第一个数码管的位选11000000
wela=0;P0=0;
dula=1;
P0=table[shu/100];//显示0
dula=0;
DelayMs(2);
wela=1;
P0=0xfd;//11111101 打开第2个数码管的位选11000000
wela=0;P0=0;
dula=1;
P0=table[shu/10%10];//显示0
dula=0;
DelayMs(2);
wela=1;
P0=0xfb;//11111011 打开第3个数码管的位选11000000
wela=0;P0=0;
dula=1;
P0=table[shu%10];//显示0
dula=0;
DelayMs(2);
}