【PIC单片机】-- 中断、定时器相关知识
2022-07-21 来源:csdn
00 写在前面
该系列的文章,源自于担任过PIC单片机课程的助教,主要向学弟们讲解了几节实验课的内容。在此记录上课的一些知识。
本系列文章主要介绍的内容:
实验1–介绍和基本I/O–按钮和LED(学习嵌入式的第一步就是点一个灯,就像学习编程语言的第一步都是写一个“hello world”代码)
实验2–MPLAB+PICkit 3+LCD+I/O(这次主要是介绍液晶显示屏的使用,很多时候我们系统的调试都需要用到,比如做一个测温系统,那我们就可以通过液晶显示屏,显示传感器采集的数值,然后再通过软件来做进一步的处理)
实验3–ADC(这个是模数转化实验,就是之前模数电学习那些知识的一个综合运用)
实验4–串行通信–UART
实验5–串行通信–I2C
实验6–计时器和中断(这一部分也是很重要的知识点,在很多的嵌入式系统中都会用到,比如用单片机再加几个传感器就可以搭出智能车,智能车就会用到计时器、中断这些内容)
01 中断相关知识
中断很好理解,我们举个例子,比如你正在写作业,突然肚子不舒服,那你就会先去上厕所,然后回来再继续写作业。所以肚子不舒服就给你大脑发出一个信号,从而先把肚子不舒服这件事解决了,然后再回到刚才没写完的那道题,继续写下去。这个就是一整个中断的过程。
在我们PIC单片机中是什么样的呢?之前我们讲过,单片机开始执行程序就是从Main函数开始执行的,当发生中断的时候,发生中断的这个点我们把它称之为断点,计算机会把断点信息存入堆栈,接着程序跳到ISR中断服务程序中执行,中断服务程序执行完,就跳回到原本断点中继续接着执行主程序。
中断服务程序在代码里面就是这个:
不知道大家还有没有印象,之前我们学习ADC转换、串口通信,我会跟大家说,我们这次的实验是不需要用到中断的。因为我们可以通过某个寄存器的位,来判断ADC是否转换结束、数据是否通过串口通信传输完毕。 而其实我们 也是可以用中断的方法 ,也就是ADC转换结束、数据通过串口通信传输完毕,就会产生相应中断。然后我们在中断服务程序中就可以写后续的操作代码。
有一个点:就是中断服务程序执行时间要尽可能少,这样可以减少主程序的延时时间。
接下来我们来看一下PIC内部有哪些中断?
1、PIC单片机内部可以有15种中断,每个中断都是有2个输入的与门来表示。这两输入分别为中断标志位、中断使能位。然后左边这几个是外设中断,中间这几个是内部中断。另外还有一个总中断,就是只有总中断使能了,中断才会产生。
2、那些这些中断标志位、中断使能位都是放在寄存器里。比如我们晚点要讲的定时器0,定时器0的中断标志位和中断使能位就放在INTCON寄存器中。
3、接下来我们讲讲中断标志位和中断使能位有什么作用。中断使能位,就直接从字面来理解,只有使能了,相应的中断才会被使用到。比如我们之前ADC模块,当ADC转换结束后,如果ADIE没有使能,那它就不会产生ADC中断。
而中断标志位,也直接从字面来理解,比如我们让ADIE使能了,那么当ADC转换结束后就会让ADIF置位。就是等于1。
当中断发生的时候,CPU就会检测FLAG标志,看看是产生哪种中断,然后进行相应的处理。
那CPU检测FLAG标志位的时候,是不是可以有不同的顺序,那顺序在前面就是优先级比较高的。举个例子,比如ADC和定时器0同时发生中断,那我要先处理哪一个,就是看CPU先检测那个FLAG,先检测到的那个就先进行处理,也就是优先级比较高。
02 定时器相关知识
03 定时器相关寄存器
TMR0:8位累加计数器,这个刚刚咱们讲过,就是用来存放累加的值。
ITCON:这个寄存器很好理解
GIE:总中断控制使能位
比如,咱们要使用定时器中断,那就让TMR0IE、TMR0IF置位。
OPTION_REG:
前面这两位不用管RBPU、INTEDG
PS2、PS1、PS0这三位是用来设置预分频
PSA这一位主要是用来选择预分频是用来分配给定时器,还是分配给看门狗
T0CS:TMR0时钟源选择位
T0SE:TMR0 时钟源触发沿选择位
TMR0寄存器,这个寄存器是8位的,那每当经过一个时钟周期FOSC/4 = 1us,TMR0的值就会加1,因为它是八位的,所以总共256us就会加满。加满的时候,就像我们刚刚中断讲的那样,如果GIE和TMR0IE都使能,就会产生中断,TMR0IF标志位就会置位。
预分频设置为8,那预分频是什么意思,就是本来我们一个时钟周期1us,TMR0寄存器的值就是加1,但是预分频设置为8之后,就是要经过8个时钟周期,TMR0寄存器的值才会加1,也就是1x8=8us才会加1。这样要经过256x8=2048us定时器0才会溢出,产生中断。
04 定时器相关电路
05 定时器补充
1、你们实验六可能会用到定时器1,定时器1与定时器0的差别我们刚刚看过就是,那个存放那个计数值的是多少位,定时器0是八位的,而定时器1是16位,但是每个寄存器只能存8位,所以需要有两个寄存器来存放这16位数。
那我们打开芯片手册,看看与定时器1相关的寄存器。
2、比如我们要定时50ms,那我们需要怎么设置寄存器;
65536-50000 = 15536;
15536/256 = 60 化成二进制 0011 1100
15536%256 =176 化成二进制 1011 0000
3、If Fosc = 20Mhz, what is the maximum interrupt period possible with Timer0?
1/(20/4)256256 = 13,107.2 us