微机原理实验7实验8
洪玉希
2011012706
合辑
前言:本报告记录了实验7实验8的任务实现和知识理解,详细介绍了如何实现任务7任
务8的各项任务。实验原理图在本实验报告最后附上,本文档跟源程序一起打包上传,请过目。
实验7.中断技术
一、 实验目的
1. 了解中断原理,包括对中断源,中断向量,中断类型号,中断程序,以及中断
过程的理解。
2. 掌握汇编语言中断程序设计方法。
3. 掌握C语言项目上机过程和了解C语言程序结构。 4. (选作)掌握C语言中断程序设计方法。
二、 实验任务
1. 中断过程的理解
阅读下面汇编语言中断程序L7_P1_int.s43,说明程序执行的流程和实现功能。上机实践,回答下面问题。了解汇编语言编写中断程序的方法。
1) 阅读程序L7_P1_int.s43,从程序中判断用的是哪个中断源?其中断类型号是多
少?
答:程序中有如下句子
从以上两个图可以知道,此程序打开了p1.0~p1.7的中断源,中断类型号是4。在此基础上打开了p1.1的中断使能所以系统接受p1.1的中断请求。
2) 在L7_P1_int.s43,无call调用语句,中断程序如何能被执行?何时会被执行?
答:因为系统打开了p1.1的中断使能,中断总控位,所以当CPU接收到有效的中断请求后,将暂停正在运行的程序,并自动转去执行相应实现中断源(p1.1)请求功能的程序即,中断子程。当CPU执行完中断子程中的返回指令后,CPU又返回到被中断的程序继续运行。
3) 在L7_P1_int.s43,如果中断子程中不清分中断标志P1IFG的后果会是什么?
答:如果中断子程不清分中断标志P1IFG系统将一直接受到中断请求,总控位是开的,所以CPU将一直执行中断子程。
4) 如果L7_P1_int.s43中的port1_vector改为port2_vector,其他不变,程序执行
的后果是什么?为什么?
答:按下key1无反应。因为程序只打开了port2的中断源,按下key1当然没有反应。并且即使此时port2上有高电平也不能发生中断,因为程序中port2的中断使能没有打开。
5) 如果去掉L7_P1_int.s43程序最后的那条无限循环语句,程序执行的流程是怎样的?
为什么?
程序执行完所有语句后会从0x0000开始执行,俗称“跑飞”。如下
因为执行完所有语句后程序没有指定PC去哪儿执行指令,所以自动选择了0x0执行。
6) 如果中断源采用的是p2.2按键用key7,请设计连线,修改L7_P1_int.s43程序完成
以中断方式响应key7的操作。
答:将key7与p2.2的端口相连。由于p2端口本来是用于输出led灯的,所以为了避免混淆,如果条件允许可以将LED端口全部连接到PORT1端口。这时在程序上做如下修改
注意:
1) 查看msp430x14x.h
文件末尾处有关中断向量偏址的符号定义。
2) 为了便于了解程序执行流程,可以在中断子程入口处(即标号intP1处)设置一个断电,然后运行程序F5,观察按下键和不按下键时程序执行的流程。
答:不按下键时,程序不经过断点,一直在跑,按下键后程序停在断点处,表示程序进入中断程序。
3) 观察是否有按键抖动现象,思考有的话,如何消除?
答: 有按键抖动现象。可以采用软件防抖来消除。具体做法是当p2.2
2. 用汇编语言编写中断程序
在实验板上用跳线将按键key5,key6分别与单片机的p1.4,p1.5相连,编程以中断方式处理按键key5和key6的请求,当key5上有一个下降沿信号时,实验板上的蜂鸣器发出一警报声;当key6上有一个上升沿信号时,实验板上的发光二极管L1闪3次。 任务实现:
本题在L7_P1_int.s43上稍加修改即可。对主程序修改如下。程序名:asm.s43
将p2,p6的16个端口均设为输出,同时打开p1.4,p1.5的中断功能。
上两张截图为中断子程。可以看到,当程序进入中断子程先判断是哪一个键按下,利用P1IFG来判断,如果是key5进入key5,如果是key6进入key6。Key5的功能是LED灯L1闪三次,key6的功能是蜂鸣器发出一声警报。在程序执行的最后要清零相对应的IFG标志信号,然后返回主程序。
思考:如果用长导线将按键key5,key6分别连接在p2.2和p2.3上,如何修改程序以实现上述中断响应?可否将按键key5,key6分别连接在p5.1和p5.2上,用中断方式来完成任务2?为什么?
答:可以将按键key5,key6分别连接在p2.2和p2.3上。用跳线将key5,key6分别连接在p2.2和p2.3。并修改程序如下:程序:asmxiugai.s43
至此就是可完成任务目标。
不能将按键key5,key6分别连接在p5.1和p5.2上。因为在中断向量表里没有安排p5.1和p5.2的中断向量,系统不支持,所以不能。
3. C语言项目上机过程和C语言程序的结构学习
1) 建立C语言程序项目的方法:
2) 读懂LC_testc.c,掌握C语言下对I/O口的寄存器进行操作。
如上图。对端口的赋值用“=”,for(;;)表示无限循环。
3) 在debug状态下,用view/disassembly查看程序LC_TEST_C的反汇编代码,了解
MCU的C程序语句与汇编语句的对应关系。
这是截图。可以看到C语言和汇编语言的对应关系。C语言中的赋值就是寄存器操作mov 指令等。
4) 打开io430.h文件和io430x14x.h文件该文件由#include语句包含在LC_test_c.c
文件中,了解io430xlxx.h文件中与MCU有关的IO寄存器以及这些IO寄存器中各有效位的位域符号定义,以编程使用。Io430.h文件通常在EW430安装目录的子目录下。
如图。此为LC_test_c.c的io430xlxx.h文件。
由于关于IO口的定义的篇幅非常大。在此只截取一个完整的片段进行解读。
__no_init volatile union {
unsigned char P1OUT; /* Port 1 Output */
struct {
unsigned char P0 : 1; /* */ unsigned char P1 : 1; /* */ unsigned char P2 : 1; /* */ unsigned char P3 : 1; /* */ unsigned char P4 : 1; /* */ unsigned char P5 : 1; /* */ unsigned char P6 : 1; /* */ unsigned char P7 : 1; /* */ }P1OUT_bit;
Cchar),整int为方便操作MCUio430x14x.h等头文件中采用共同体,struct 可以按字节操作: P1SEL=0; P1OUT=0; P1IFG=0;
2.也可以按位域操作:
P1SEL_BIT.P1=0; P1OUT_BIT.P1=0; P1IFG_BIT.P1=0;
(5) C语言中程序中断程序设计
参看“补充讲义C语言的中断程序设计”,阅读下面C语言中断程序L8_P1_int。 1) 如果程序中没有#pragma vector=port1_vector的后果?
这就相当于汇编语言中没有ORG 0FFE0h+PORT1_VECTOR 显然,没有给出中断向量,系统是不会执行中断程序的。
2) 在C语言中操作符“==”和“=”有什么不同?
“==”是判断符号,如
if (P1IFG_bit.P4==1) { key5(); P1IFG_bit.P4=0; }
If语句后面的括号内,就是一个判断语句,P1IFG_bit.P4是否等于1。如果是,执行接下来的语句。
而“=”是赋值的意思,如
for(;;) //无限循环
{ P2OUT=~P2OUT; //将端口2的值取反后输出 for (i=0;i
中,P2OUT=~P2OUT指将P2OUT取反赋值给P2OUT。
(6) 完成本次实验任务2的同样功能。
对实验任务2 的汇编语言进行修改即可。下面给出程序和注释。 这里着重注意几点
1. 所有子程序要在开头声明。 2. 书写要按照C语言的方式书写。
#include "io430.h"
#include "intrinsics.h" void key5(); void key6(); void delay(); int main( void ) {
// Stop watchdog timer to prevent time out reset WDTCTL = WDTPW + WDTHOLD;
__disable_interrupt(); //_DINT();
P2SEL=0; //置P2为基本I/O功能 P2OUT=0xFF; //置P2输出初值 P2DIR=0xFF; //置P2为输出 P6SEL=0; //置P2为基本I/O功能 P6OUT=0xFF; //置P2输出初值 P6DIR=0xFF; //置P2为输出
P1SEL_bit.P4=0; //设置p1.4为基本I/O功能 P1DIR_bit.P4=0; //设置P1.4为输入
P1IES_bit.P4=1; //设置p1.4为上升沿输入 P1IFG_bit.P4=0; //清零标志位
P1IE_bit.P4=1; //打开p1.4中断使能 P1SEL_bit.P5=0; //设置p1.5为基本I/O功能 P1DIR_bit.P5=0; //设置P1.5为输入
P1IES_bit.P5=1; //设置p1.5为下升沿输入 P1IFG_bit.P5=0; //清零标志位
P1IE_bit.P5=1; //打开p1.5中断使能 __enable_interrupt(); //_EINT();
while(1){ }; }
//#pragma vector=4*2
#pragma vector=PORT1_VECTOR __interrupt void port_int(void) {
if (P1IFG_bit.P4==1) {
key5();
P1IFG_bit.P4=0; }
if (P1IFG_bit.P5==1) {
key6();
P1IFG_bit.P5=0; } }
void key5() {P2OUT=0XF8; delay(); P2OUT=0XFF; delay(); P2OUT=0XF8; delay(); P2OUT=0XFF;
delay(); P2OUT=0XF8; delay(); P2OUT=0XFF; delay(); }
void key6() {P6OUT=0x10; delay(); P6OUT=0XFF; }
void delay() {unsigned int i;
for (i=0;i
实验8.基本时钟和定时器
一、实验目的
1. 掌握数字示波器的使用方法
2. 了解MSP430基本时钟模块的工作原理,掌握其控制方法。
3. 了解MSP430定时器A工作原理,掌握MSP430定时器A的使用方法。 二、实验任务
1. 数字示波器的使用
1) 测量示波器自带的周期性方波信号,掌握其测量周期,频率峰峰值的使用方法。
测量方法:按下示波器上方measure按钮,调出测量窗口,调整光标cursory即可测量峰峰值和频率。峰峰值用Y光标测,频率用X光标测。
2) 用孔孔导线将实验板的地信号与示波器的地信号相连,测量实验板上的5v,
3.3v电源信号是否正常。 已测量,正常。但未截图。
2. 掌握基本时钟模块的编程
参看附录D实验板原理图,从题中可以看到,在单片机引脚XIN和XOUT,XT2IN,XT2OUT上分别连着32.768KHZ,8MHZ的晶振,编程控制基本时钟模块,使ACLK=4096HZ并通过P5.6或P2.0输出该ACLK。利用示波器光差输出的ACLK时钟信号,测量其频率。 任务实现:
基本时钟模块主要与3个寄存器息息相关。 数字控制振荡器:DCOCTL
XT2OFF: 0:打开BCSCTL2 1:关闭BCSCTL2 DIVA: 分频控制
RSELx:粗调DC0数字控制振荡器
BCSCTL2 SELMx:选择MCLK: 00:DCOCLK 01: DCOCLK 10:XT2
11: LFXT1CLK DIVAx:MCLK分频
00:1 01:2 10:4 11:8
SELS:选择SMCLK 0:DCOCLK 1:XT2
SMCLK分频控制 00:1 01:2 10:4 11:8
只要合理的赋予这三个寄存器值就能得到想要的ACLK,MCLK,SMCLK的值。上图用图解的方式给出上述三个寄存器的工作原理。 而时钟的输出,参考讲义可知
某些引脚只要设定它的SEL为1(模块功能)即能从这个端输出想要的时钟。 下面编程实现ACLK=4096HZ,通过p2.0输出。
上图为程序。因为复位以后ACLK的时钟是LFXT1CLK,是32.768KHZ,8分频以后正好是4096HZ,所以只要将BCSCTL1的DIVA置3,变成8分频即可。 然后通过P2.0输出ACLK。 下图是拍照所得。
图上显示频率为4.098KHZ,与4096HZ差不多。
思考:1)可否编程在引脚P5.2上输出ACLK,为什么? 答:理论上这是可以实现的,因为我们拥有XT2clk 8Mhz的时钟,我们可以得到任意比8MHZ频率低的方波信号,然后通过P5.2输出,但这样已经是通过编程得到的信号了,已经不是一个时钟信号了。而本题的意义在于,ACLK能否直接在5.2上输出,这显然是不能的,因为P5.2的功能模块里没有输出ACLK这一项功能。
2) 上电复位后,CPU工作的时钟信号MCLK的频率是多少?是8MHz吗?编程在P5.4
上输出MCLK并记录。
如上图记录的频率值为748.5KHZ约为750KHZ,故不是8Mhz。
3. 定时器A的定时功能学习
采用定时器A的计数方式(UP MODE),每秒产生一次CCR0的TACCR0 CCIFG中断,计数秒值,将计数值通过8个发光二极管显示出来,并控制蜂鸣器每5秒发出一次警报。
思考:采用定时器的计时,实验6中任务一延时方式的计时,这两种方法CPU在执行流程上有什么不同? 任务实现:
首先开头添加如下两句,设置TACCR0的中断向量
ORG 0FFE0h+TIMERA0_VECTOR ;设置TACCR0中断向量
DC16 TACCR0_ISR ;entrance of interrupt 然后在主程序中设置TimerA
MOV #32767,&TACCR0 ;TACCR0
MOV #TASSEL_1+MC_1+TACLR,&TACTL ;ACLK,up mode MOV #CCIE,&TACCTL0 ;enable interrupt 这里TACL 采用ACLK, ACLK是32.768khz 那么计算TACCRO
(TACCR01)
1
32768
TACCR0=32767。
也就是说,大约每一秒进入一次中断子程,这就是timerA所完成的任务,计时。
如上图所示。同时,把P2,P6端口调为输出端口,因为需要用到LED和蜂鸣器。
上图是TACCR0中断子程,调用timer这个子程序。R11是LED灯的状态寄存器, 由于LED低电平点亮,所以R11一开始置FF,取反后加1 再取反就是LED1亮,没进行一次循环R5加1,这是计数寄存器,R6中存的数是5如果R5R6相减出现0说明已经到了第五秒,继续调用buzz子程序,BUZZ就是让蜂鸣器发出警报声,注意,蜂鸣器也是低电平点亮。在这里需要用到延时子程,因为这是TACCR0中断子程序内部了,没有延时效应了,需要自己添加。
思考:采用定时器的计时,实验6中任务一延时方式的计时,这两种方法CPU在执行流程上有什么不同?
答:实验六任务1的延时是“暴力”延时,因为任何一条指令都会有完成时间,于是只要我指令足够多,那么会产生一定的时间延迟。实验六任务1的思想就是我给一个寄存器赋4000(FA0)并自减,如果寄存器到0了执行需要的指令。于是这中间产生了4000条指令,如果再加上一个循环嵌套那么会产生相当显著的延时。而定时器延时则是系统中设计好的一个计数器,它是系统给的。执行的时候系统会调用timerA。他们两个是不一样的。
但是从本质上来讲,这两个方式的延时,都是通过执行大量指令来完成延时。 4. 定时器A的定时功能的应用
完成一个电子表的设计,其中电子表的分钟值通过数码管显示,秒值通过发光二极管显示。1秒的定时采用定时器A完成,分钟值采用16进制形式显示在数码管上,秒值采用2进制显示在LED上。例如:最大计时数是15分59秒,显示为F00111011,其中F显示在数码管上,00111011通过发光二极管显示。 任务实现:
1秒的实现在任务3 中已经实现,而计时的程序在实验6中也写过相应的代码,数码管显示在实验6中也写过相应的代码。 首先添加数组,
定义了LED需要显示的0~F。存放在DATA16_C。
以上为程序段和全部注释。各部分功能已经注释的非常清楚。
5. (选做)掌握基本时钟模块及其相关控制寄存器
当三个寄存器全部是复位值时,三个时钟的波形如下图所示。
Figure 1ACLK 复位值32.68KHZ
Figure 2 MCLK和SMCLK的复位值748.5KHZ
当BCSCTL1赋87h时,下图为三个时钟的波形图。
Figure 3 ACLK
Figure 4MCLK 和SMCLK
当BCSCTL2=8Eh,BCSCTL1=30h时,三个时钟的波形为
Figure 5 ACLK
Figure 6 MCLK
Figure 7
SMCLK
各实验最小系统原理图
PS:(由于是用手机拍摄然后没有传输工具,所以先传到微博上然后再download,所以会有水印,但这是本人手画。)
上图为实验8任务3,任务4的原理图。
上图为实验7任务2以及C语言的原理图。
上图为带晶振电路的原理图,即实验8任务2的原理图。
微机原理实验7实验8
洪玉希
2011012706
合辑
前言:本报告记录了实验7实验8的任务实现和知识理解,详细介绍了如何实现任务7任
务8的各项任务。实验原理图在本实验报告最后附上,本文档跟源程序一起打包上传,请过目。
实验7.中断技术
一、 实验目的
1. 了解中断原理,包括对中断源,中断向量,中断类型号,中断程序,以及中断
过程的理解。
2. 掌握汇编语言中断程序设计方法。
3. 掌握C语言项目上机过程和了解C语言程序结构。 4. (选作)掌握C语言中断程序设计方法。
二、 实验任务
1. 中断过程的理解
阅读下面汇编语言中断程序L7_P1_int.s43,说明程序执行的流程和实现功能。上机实践,回答下面问题。了解汇编语言编写中断程序的方法。
1) 阅读程序L7_P1_int.s43,从程序中判断用的是哪个中断源?其中断类型号是多
少?
答:程序中有如下句子
从以上两个图可以知道,此程序打开了p1.0~p1.7的中断源,中断类型号是4。在此基础上打开了p1.1的中断使能所以系统接受p1.1的中断请求。
2) 在L7_P1_int.s43,无call调用语句,中断程序如何能被执行?何时会被执行?
答:因为系统打开了p1.1的中断使能,中断总控位,所以当CPU接收到有效的中断请求后,将暂停正在运行的程序,并自动转去执行相应实现中断源(p1.1)请求功能的程序即,中断子程。当CPU执行完中断子程中的返回指令后,CPU又返回到被中断的程序继续运行。
3) 在L7_P1_int.s43,如果中断子程中不清分中断标志P1IFG的后果会是什么?
答:如果中断子程不清分中断标志P1IFG系统将一直接受到中断请求,总控位是开的,所以CPU将一直执行中断子程。
4) 如果L7_P1_int.s43中的port1_vector改为port2_vector,其他不变,程序执行
的后果是什么?为什么?
答:按下key1无反应。因为程序只打开了port2的中断源,按下key1当然没有反应。并且即使此时port2上有高电平也不能发生中断,因为程序中port2的中断使能没有打开。
5) 如果去掉L7_P1_int.s43程序最后的那条无限循环语句,程序执行的流程是怎样的?
为什么?
程序执行完所有语句后会从0x0000开始执行,俗称“跑飞”。如下
因为执行完所有语句后程序没有指定PC去哪儿执行指令,所以自动选择了0x0执行。
6) 如果中断源采用的是p2.2按键用key7,请设计连线,修改L7_P1_int.s43程序完成
以中断方式响应key7的操作。
答:将key7与p2.2的端口相连。由于p2端口本来是用于输出led灯的,所以为了避免混淆,如果条件允许可以将LED端口全部连接到PORT1端口。这时在程序上做如下修改
注意:
1) 查看msp430x14x.h
文件末尾处有关中断向量偏址的符号定义。
2) 为了便于了解程序执行流程,可以在中断子程入口处(即标号intP1处)设置一个断电,然后运行程序F5,观察按下键和不按下键时程序执行的流程。
答:不按下键时,程序不经过断点,一直在跑,按下键后程序停在断点处,表示程序进入中断程序。
3) 观察是否有按键抖动现象,思考有的话,如何消除?
答: 有按键抖动现象。可以采用软件防抖来消除。具体做法是当p2.2
2. 用汇编语言编写中断程序
在实验板上用跳线将按键key5,key6分别与单片机的p1.4,p1.5相连,编程以中断方式处理按键key5和key6的请求,当key5上有一个下降沿信号时,实验板上的蜂鸣器发出一警报声;当key6上有一个上升沿信号时,实验板上的发光二极管L1闪3次。 任务实现:
本题在L7_P1_int.s43上稍加修改即可。对主程序修改如下。程序名:asm.s43
将p2,p6的16个端口均设为输出,同时打开p1.4,p1.5的中断功能。
上两张截图为中断子程。可以看到,当程序进入中断子程先判断是哪一个键按下,利用P1IFG来判断,如果是key5进入key5,如果是key6进入key6。Key5的功能是LED灯L1闪三次,key6的功能是蜂鸣器发出一声警报。在程序执行的最后要清零相对应的IFG标志信号,然后返回主程序。
思考:如果用长导线将按键key5,key6分别连接在p2.2和p2.3上,如何修改程序以实现上述中断响应?可否将按键key5,key6分别连接在p5.1和p5.2上,用中断方式来完成任务2?为什么?
答:可以将按键key5,key6分别连接在p2.2和p2.3上。用跳线将key5,key6分别连接在p2.2和p2.3。并修改程序如下:程序:asmxiugai.s43
至此就是可完成任务目标。
不能将按键key5,key6分别连接在p5.1和p5.2上。因为在中断向量表里没有安排p5.1和p5.2的中断向量,系统不支持,所以不能。
3. C语言项目上机过程和C语言程序的结构学习
1) 建立C语言程序项目的方法:
2) 读懂LC_testc.c,掌握C语言下对I/O口的寄存器进行操作。
如上图。对端口的赋值用“=”,for(;;)表示无限循环。
3) 在debug状态下,用view/disassembly查看程序LC_TEST_C的反汇编代码,了解
MCU的C程序语句与汇编语句的对应关系。
这是截图。可以看到C语言和汇编语言的对应关系。C语言中的赋值就是寄存器操作mov 指令等。
4) 打开io430.h文件和io430x14x.h文件该文件由#include语句包含在LC_test_c.c
文件中,了解io430xlxx.h文件中与MCU有关的IO寄存器以及这些IO寄存器中各有效位的位域符号定义,以编程使用。Io430.h文件通常在EW430安装目录的子目录下。
如图。此为LC_test_c.c的io430xlxx.h文件。
由于关于IO口的定义的篇幅非常大。在此只截取一个完整的片段进行解读。
__no_init volatile union {
unsigned char P1OUT; /* Port 1 Output */
struct {
unsigned char P0 : 1; /* */ unsigned char P1 : 1; /* */ unsigned char P2 : 1; /* */ unsigned char P3 : 1; /* */ unsigned char P4 : 1; /* */ unsigned char P5 : 1; /* */ unsigned char P6 : 1; /* */ unsigned char P7 : 1; /* */ }P1OUT_bit;
Cchar),整int为方便操作MCUio430x14x.h等头文件中采用共同体,struct 可以按字节操作: P1SEL=0; P1OUT=0; P1IFG=0;
2.也可以按位域操作:
P1SEL_BIT.P1=0; P1OUT_BIT.P1=0; P1IFG_BIT.P1=0;
(5) C语言中程序中断程序设计
参看“补充讲义C语言的中断程序设计”,阅读下面C语言中断程序L8_P1_int。 1) 如果程序中没有#pragma vector=port1_vector的后果?
这就相当于汇编语言中没有ORG 0FFE0h+PORT1_VECTOR 显然,没有给出中断向量,系统是不会执行中断程序的。
2) 在C语言中操作符“==”和“=”有什么不同?
“==”是判断符号,如
if (P1IFG_bit.P4==1) { key5(); P1IFG_bit.P4=0; }
If语句后面的括号内,就是一个判断语句,P1IFG_bit.P4是否等于1。如果是,执行接下来的语句。
而“=”是赋值的意思,如
for(;;) //无限循环
{ P2OUT=~P2OUT; //将端口2的值取反后输出 for (i=0;i
中,P2OUT=~P2OUT指将P2OUT取反赋值给P2OUT。
(6) 完成本次实验任务2的同样功能。
对实验任务2 的汇编语言进行修改即可。下面给出程序和注释。 这里着重注意几点
1. 所有子程序要在开头声明。 2. 书写要按照C语言的方式书写。
#include "io430.h"
#include "intrinsics.h" void key5(); void key6(); void delay(); int main( void ) {
// Stop watchdog timer to prevent time out reset WDTCTL = WDTPW + WDTHOLD;
__disable_interrupt(); //_DINT();
P2SEL=0; //置P2为基本I/O功能 P2OUT=0xFF; //置P2输出初值 P2DIR=0xFF; //置P2为输出 P6SEL=0; //置P2为基本I/O功能 P6OUT=0xFF; //置P2输出初值 P6DIR=0xFF; //置P2为输出
P1SEL_bit.P4=0; //设置p1.4为基本I/O功能 P1DIR_bit.P4=0; //设置P1.4为输入
P1IES_bit.P4=1; //设置p1.4为上升沿输入 P1IFG_bit.P4=0; //清零标志位
P1IE_bit.P4=1; //打开p1.4中断使能 P1SEL_bit.P5=0; //设置p1.5为基本I/O功能 P1DIR_bit.P5=0; //设置P1.5为输入
P1IES_bit.P5=1; //设置p1.5为下升沿输入 P1IFG_bit.P5=0; //清零标志位
P1IE_bit.P5=1; //打开p1.5中断使能 __enable_interrupt(); //_EINT();
while(1){ }; }
//#pragma vector=4*2
#pragma vector=PORT1_VECTOR __interrupt void port_int(void) {
if (P1IFG_bit.P4==1) {
key5();
P1IFG_bit.P4=0; }
if (P1IFG_bit.P5==1) {
key6();
P1IFG_bit.P5=0; } }
void key5() {P2OUT=0XF8; delay(); P2OUT=0XFF; delay(); P2OUT=0XF8; delay(); P2OUT=0XFF;
delay(); P2OUT=0XF8; delay(); P2OUT=0XFF; delay(); }
void key6() {P6OUT=0x10; delay(); P6OUT=0XFF; }
void delay() {unsigned int i;
for (i=0;i
实验8.基本时钟和定时器
一、实验目的
1. 掌握数字示波器的使用方法
2. 了解MSP430基本时钟模块的工作原理,掌握其控制方法。
3. 了解MSP430定时器A工作原理,掌握MSP430定时器A的使用方法。 二、实验任务
1. 数字示波器的使用
1) 测量示波器自带的周期性方波信号,掌握其测量周期,频率峰峰值的使用方法。
测量方法:按下示波器上方measure按钮,调出测量窗口,调整光标cursory即可测量峰峰值和频率。峰峰值用Y光标测,频率用X光标测。
2) 用孔孔导线将实验板的地信号与示波器的地信号相连,测量实验板上的5v,
3.3v电源信号是否正常。 已测量,正常。但未截图。
2. 掌握基本时钟模块的编程
参看附录D实验板原理图,从题中可以看到,在单片机引脚XIN和XOUT,XT2IN,XT2OUT上分别连着32.768KHZ,8MHZ的晶振,编程控制基本时钟模块,使ACLK=4096HZ并通过P5.6或P2.0输出该ACLK。利用示波器光差输出的ACLK时钟信号,测量其频率。 任务实现:
基本时钟模块主要与3个寄存器息息相关。 数字控制振荡器:DCOCTL
XT2OFF: 0:打开BCSCTL2 1:关闭BCSCTL2 DIVA: 分频控制
RSELx:粗调DC0数字控制振荡器
BCSCTL2 SELMx:选择MCLK: 00:DCOCLK 01: DCOCLK 10:XT2
11: LFXT1CLK DIVAx:MCLK分频
00:1 01:2 10:4 11:8
SELS:选择SMCLK 0:DCOCLK 1:XT2
SMCLK分频控制 00:1 01:2 10:4 11:8
只要合理的赋予这三个寄存器值就能得到想要的ACLK,MCLK,SMCLK的值。上图用图解的方式给出上述三个寄存器的工作原理。 而时钟的输出,参考讲义可知
某些引脚只要设定它的SEL为1(模块功能)即能从这个端输出想要的时钟。 下面编程实现ACLK=4096HZ,通过p2.0输出。
上图为程序。因为复位以后ACLK的时钟是LFXT1CLK,是32.768KHZ,8分频以后正好是4096HZ,所以只要将BCSCTL1的DIVA置3,变成8分频即可。 然后通过P2.0输出ACLK。 下图是拍照所得。
图上显示频率为4.098KHZ,与4096HZ差不多。
思考:1)可否编程在引脚P5.2上输出ACLK,为什么? 答:理论上这是可以实现的,因为我们拥有XT2clk 8Mhz的时钟,我们可以得到任意比8MHZ频率低的方波信号,然后通过P5.2输出,但这样已经是通过编程得到的信号了,已经不是一个时钟信号了。而本题的意义在于,ACLK能否直接在5.2上输出,这显然是不能的,因为P5.2的功能模块里没有输出ACLK这一项功能。
2) 上电复位后,CPU工作的时钟信号MCLK的频率是多少?是8MHz吗?编程在P5.4
上输出MCLK并记录。
如上图记录的频率值为748.5KHZ约为750KHZ,故不是8Mhz。
3. 定时器A的定时功能学习
采用定时器A的计数方式(UP MODE),每秒产生一次CCR0的TACCR0 CCIFG中断,计数秒值,将计数值通过8个发光二极管显示出来,并控制蜂鸣器每5秒发出一次警报。
思考:采用定时器的计时,实验6中任务一延时方式的计时,这两种方法CPU在执行流程上有什么不同? 任务实现:
首先开头添加如下两句,设置TACCR0的中断向量
ORG 0FFE0h+TIMERA0_VECTOR ;设置TACCR0中断向量
DC16 TACCR0_ISR ;entrance of interrupt 然后在主程序中设置TimerA
MOV #32767,&TACCR0 ;TACCR0
MOV #TASSEL_1+MC_1+TACLR,&TACTL ;ACLK,up mode MOV #CCIE,&TACCTL0 ;enable interrupt 这里TACL 采用ACLK, ACLK是32.768khz 那么计算TACCRO
(TACCR01)
1
32768
TACCR0=32767。
也就是说,大约每一秒进入一次中断子程,这就是timerA所完成的任务,计时。
如上图所示。同时,把P2,P6端口调为输出端口,因为需要用到LED和蜂鸣器。
上图是TACCR0中断子程,调用timer这个子程序。R11是LED灯的状态寄存器, 由于LED低电平点亮,所以R11一开始置FF,取反后加1 再取反就是LED1亮,没进行一次循环R5加1,这是计数寄存器,R6中存的数是5如果R5R6相减出现0说明已经到了第五秒,继续调用buzz子程序,BUZZ就是让蜂鸣器发出警报声,注意,蜂鸣器也是低电平点亮。在这里需要用到延时子程,因为这是TACCR0中断子程序内部了,没有延时效应了,需要自己添加。
思考:采用定时器的计时,实验6中任务一延时方式的计时,这两种方法CPU在执行流程上有什么不同?
答:实验六任务1的延时是“暴力”延时,因为任何一条指令都会有完成时间,于是只要我指令足够多,那么会产生一定的时间延迟。实验六任务1的思想就是我给一个寄存器赋4000(FA0)并自减,如果寄存器到0了执行需要的指令。于是这中间产生了4000条指令,如果再加上一个循环嵌套那么会产生相当显著的延时。而定时器延时则是系统中设计好的一个计数器,它是系统给的。执行的时候系统会调用timerA。他们两个是不一样的。
但是从本质上来讲,这两个方式的延时,都是通过执行大量指令来完成延时。 4. 定时器A的定时功能的应用
完成一个电子表的设计,其中电子表的分钟值通过数码管显示,秒值通过发光二极管显示。1秒的定时采用定时器A完成,分钟值采用16进制形式显示在数码管上,秒值采用2进制显示在LED上。例如:最大计时数是15分59秒,显示为F00111011,其中F显示在数码管上,00111011通过发光二极管显示。 任务实现:
1秒的实现在任务3 中已经实现,而计时的程序在实验6中也写过相应的代码,数码管显示在实验6中也写过相应的代码。 首先添加数组,
定义了LED需要显示的0~F。存放在DATA16_C。
以上为程序段和全部注释。各部分功能已经注释的非常清楚。
5. (选做)掌握基本时钟模块及其相关控制寄存器
当三个寄存器全部是复位值时,三个时钟的波形如下图所示。
Figure 1ACLK 复位值32.68KHZ
Figure 2 MCLK和SMCLK的复位值748.5KHZ
当BCSCTL1赋87h时,下图为三个时钟的波形图。
Figure 3 ACLK
Figure 4MCLK 和SMCLK
当BCSCTL2=8Eh,BCSCTL1=30h时,三个时钟的波形为
Figure 5 ACLK
Figure 6 MCLK
Figure 7
SMCLK
各实验最小系统原理图
PS:(由于是用手机拍摄然后没有传输工具,所以先传到微博上然后再download,所以会有水印,但这是本人手画。)
上图为实验8任务3,任务4的原理图。
上图为实验7任务2以及C语言的原理图。
上图为带晶振电路的原理图,即实验8任务2的原理图。