实验6 实验名称基本时钟和低功耗模式.docx
《实验6 实验名称基本时钟和低功耗模式.docx》由会员分享,可在线阅读,更多相关《实验6 实验名称基本时钟和低功耗模式.docx(14页珍藏版)》请在冰豆网上搜索。
实验6实验名称基本时钟和低功耗模式
实验名称:
基本时钟和低功耗模式
姓名:
学号:
实验班号:
机器号:
一.实验目的
1.了解MSP430Gxxx基本时钟模块的工作原理,掌握其控制方法;
2.掌握利用时钟信号和中断技术实现定时功能的方法;
3.掌握低功耗模式控制方法。
二.实验任务
1.数字示波器的使用(在实验5中已完成)
1)将信号源的波形在示波器上显示出来,掌握测量周期、频率、峰峰值的方法;
2)用导线将实验板的地信号与示波器的地信号相连,测量实验板上的Vcc电源信号是否正常。
2.测试上电复位系统ACLK、和SMCLK时钟频率,了解基本时钟模块控制寄存器各位作用。
新创建一个MSP430G2553项目,在给出的main.c基础上,编程输出单片机上电复位后的ACLK、和SMCLK时钟,用示波器测量其频率值,记录下来。
答:
上电复位后的ACLK时钟频率为32.77kHz
上电复位后的SMCLK时钟频率为1.04MHz
程序见程序清单中的程序2.c
思考:
1)将实验板上JP8中间的两个插针接到:
(1)32.768KH晶振侧,如图6-1;
(2)P2.6/P2.7侧,如图6-2。
测得ACLK的结果有何不同?
图6-1图6-2
答:
接到32.768KH晶振侧时,测得结果为32.77kHz,接到P2.6/P2.7侧,测得结果为890kHz。
2)在debug下如图6-3,通过View/Register更改SystemClock模块控制寄存器值,分别置DIVA1、DIVA0=01、11;DIVS1、DIVS0=10、11;置LFXT1S0、LFXT1S0=00、10,记录示波器测量得到的ACLK(P1.0输出)和SMCLK(P1.4输出)的频率值,填写在表6-1、6-2、6-3中,掌握时钟模块各控制寄存器相关位的作用。
图6-3通过View/Register更改SystemClock模块控制寄存器值
表6-1DIVAxx与ACLK关系
DIVA1
DIVA0
ACLK频率值
作用
0
1
16.39kHz
ACLK二分频
1
1
4.0963kHz
ACLK八分频
表6-2DIVSxx与SMCLK关系
DIVS1
DIVS0
SMCLK频率值
作用
1
0
26.6kHz
SMCLK四分频
1
1
133.0kHz
SMCLK八分频
表6-3LFXT1Sxx与ACLK关系
LFXT1S1
LFXT1S0
ACLK频率值
时钟来源
0
0
32.77kHz
外部晶振
1
0
11.762kHz
VLOCLK
3)分析上电复位后,CPU工作的时钟信号MCLK频率值是多少?
答:
根据上电复位后寄存器的值,可以发现上电复位后MCLK频率值实际上是与SMCLK频率值相等的(时钟源均为DCO,且均为一分频),而上电复位后测得的SMCLK时钟频率为1.04MHz,故上电复位后MCLK频率值为1.04MHz。
4)(提高)置RSEL3~RSEL0=1111;DCO2~DCO0=111;记录当前SMCLK的频率值。
这是基本时钟模块提供的最高频率值。
答:
SMLCK的值为20.1MHz。
3.掌握基本时钟模块的编程控制
参看附录A实验板原理图,如图6-1用跳线将JP8中的插针信号接到晶振32.768Khz侧。
编程控制基本时钟模块,设置ACLK分别为下面时钟频率,并通过P1.0输出ACLK,用示波器观察:
1)ACLK=16.384Hz;(外部晶振二分频,约为32768Hz/2)
答:
ACLK的频率为32.77kHz。
程序见程序清单中的程序3.1.c。
2)ACLK=VLOCLK/8;(内部VLOCLK八分频,约为12KHz/8)
答:
ACLK的频率为1.4243kHz。
程序见程序清单中的程序3.2.c。
思考:
可否通过对时钟模块编程在引脚P2.4上输出ACLK?
为什么?
答:
不可以,因为引脚P2.4在硬件层面上并未与ACLK的输出引脚相连,所以无论如何对时钟模块进行编程都无法做到在引脚P2.4上输出ACLK。
4.DCO出厂校验值的频率检测
1)利用出厂校验值,编程使DCO分别为1MHz、16MHz,通过P1.4输出,并用示波器测量实际值。
答:
1MHz的实际值为960kHz,16MHz的实际值为15.9MHz。
程序见程序清单中的程序4.1.c。
2)(提高)在实验1例程test_2553.c基础上,分别编程使主系统时钟工作在
(1)MCLK=复位频率/8约100KHz;
(2)MCLK=DCO=16MHz;两种不同MCLK频率下,观察灯的亮灭速度有何不同,掌握主系统时钟的变化对程序执行速度的影响。
答:
在MCLK=复位频率/8时,灯的亮灭速度较慢,在MCLK=DCO=16MHz时,灯的亮灭速度较快。
可见主系统时钟频率越高,程序执行的速度越快。
程序见程序清单中的程序4.2.c。
5.低功耗模式学习
程序L6_LPM.c见下,用跳线将P2.3与L4短接,将P2.4用长杜邦线与buzz短接,P1.1与K2短接,用示波器分别观察P1.0、P1.4输出的ACLK和SMCLK,了解低功耗模式的进入和退出。
1)运行程序,观察现象,并记录进入低功耗前、进入低功耗后、响应中断后、退出中断后的时钟、发光二极管和蜂鸣器状态,并做分析。
答:
进入低功耗前:
LED灯闪亮五次,随后蜂鸣器鸣响三次,ACLK=32.77kHz,SMCLK=1.09MHz。
进入低功耗后:
LED灯不亮,蜂鸣器不响,ACLK与SMCLK均无信号。
响应中断后:
LED灯不亮,蜂鸣器鸣响三次,ACLK=32.81kHz,SMCLK=1MHz。
退出中断后:
LED灯不亮,蜂鸣器不响,ACLK与SMCLK均无信号。
发生以上现象的原因是在程序执行至LPM4前,程序正常执行,时钟有信号;程序执行至LPM4后,单片机进入了LPM4,CPU、MCLK、SMCLK、DCO均禁止,故程序不再向下执行,时钟无信号;中断发生之后单片机被唤醒,恢复活动模式,中断子程开始执行,时钟有信号;在退出中断之后单片机又回到了LPM4,故程序不再向下执行,时钟无信号。
2)如果中断程序中有LPM4_EXIT语句,运行的结果会有什么不同?
请分析。
答:
在退出中断之后,LED闪亮五次,蜂鸣器不响,ACLK=32.77kHz,SMCLK=1.06MHz,随后LED灯不亮,蜂鸣器不响,ACLK与SMCLK均无信号。
因为中断子程中关闭了低功耗模式,所以中断子程结束之后单片机依旧为活动模式,所以程序继续向下执行,时钟有信号。
不过由于之后程序经过循环体的循环又执行了LPM4;语句,故单片机又回到了LPM4,故程序不再向下进行,时钟无信号。
6.(提高)利用输出的时钟信号做中断源,实现定时功能
将任务3中P1.0输出的ACLK=VLOCLK/8时钟信号,作为P1.7的中断申请信号,用导线将P1.7与P1.0相连即可,在中断函数中设置一个计数变量,计数中断函数被执行的次数,如果ACLK的频率值为1.5KHz(实验时,以实测的为准),那么中断函数每被执行1500次表示一秒时间到。
利用该定时功能,将8个发光二级管设计成一个秒表,显示秒值,每秒改变一次8个发光二级管的显示。
答:
程序见程序清单中的程序6.1.c。
思考:
如果要每隔5秒蜂鸣器响一声,如何在任务6的基础上编程实现?
答:
程序见程序清单中的程序6.2.c。
程序清单:
程序2.c
#include"io430.h"
intmain(void)
{
//Stopwatchdogtimertopreventtimeoutreset
WDTCTL=WDTPW+WDTHOLD;
//P1.0输出时钟ACLK,P1.4输出时钟SMCLK
P1SEL|=BIT0+BIT4;
P1SEL2&=~(BIT0+BIT4);
P1DIR|=BIT0+BIT4;
while
(1);
}
程序3.1.c
#include"io430.h"
unsignedinti;
intmain(void)
{
//Stopwatchdogtimertopreventtimeoutreset
WDTCTL=WDTPW+WDTHOLD;
//P1.0输出时钟ACLK,P1.4输出时钟SMCLK
P1SEL|=BIT0+BIT4;
P1SEL2&=~(BIT0+BIT4);
P1DIR|=BIT0+BIT4;
while((IFG1&OFIFG)!
=0)
{
IFG1&=~OFIFG;
for(i=0;i<=0xffff;i++);
};
BCSCTL3|=LFXT1S_0;
BCSCTL1|=DIVA_1;
while
(1);
}
程序3.2.c
#include"io430.h"
intmain(void)
{
//Stopwatchdogtimertopreventtimeoutreset
WDTCTL=WDTPW+WDTHOLD;
//P1.0输出时钟ACLK,P1.4输出时钟SMCLK
P1SEL|=BIT0+BIT4;
P1SEL2&=~(BIT0+BIT4);
P1DIR|=BIT0+BIT4;
BCSCTL3|=LFXT1S_2;
BCSCTL1|=DIVA_3;
while
(1);
}
程序4.1.c
#include"io430.h"
intmain(void)
{
//Stopwatchdogtimertopreventtimeoutreset
WDTCTL=WDTPW+WDTHOLD;
//P1.0输出时钟ACLK,P1.4输出时钟SMCLK
P1SEL|=BIT0+BIT4;
P1SEL2&=~(BIT0+BIT4);
P1DIR|=BIT0+BIT4;
//
(1)使DCO为1MHz
if(CALBC1_1MHZ!
=0xff)
{
BCSCTL1=CALBC1_1MHZ;
DCOCTL=CALDCO_1MHZ;
}
//
(2)使DCO为16MHz
/*
if(CALBC1_16MHZ!
=0xff)
{
BCSCTL1=CALBC1_16MHZ;
DCOCTL=CALDCO_16MHZ;
}
*/
while
(1);
}
程序4.2.c
#include"io430.h"
unsignedinti;
intmain(void)
{unsignedintj;//定义延时变量
WDTCTL=WDTPW+WDTHOLD;//关闭看门狗
//
(1)MCLK=复位频率/8
BCSCTL2|=DIVM_3;
//
(2)MCLK=DCO=16MHz
/*
if(CALBC1_16MHZ!
=0xff)
{
BCSCTL1=CALBC1_16MHZ;
DCOCTL=CALDCO_16MHZ;
}
*/
P2SEL&=~(BIT2+BIT5);//设置引脚P2.2和P2.5为基本输入输出功能
P2SEL2&=~(BIT2+BIT5);
P2OUT|=BIT2+BIT5;//设置引脚P2.2和P2.5输出的初值为1
P2DIR|=BIT2+BIT5;//设置端口P2.2和P2.5为输出方向
for(;;)//主循环
{P2OUT^=(BIT2+BIT5);//将P2.2和P2.5的值取反后输出
for(i=0;i<0xffff;i++);//延时
};
}
程序L6_LPM.c
#include"io430.h"
#include"in430.h"
voiddelay(unsignedinti)//延时函数
{unsignedintk;//定义局部变量
for(k=0;k
}
voidBlink()//LED闪
{unsignedinti;
for(i=0;i<5;i++)
{P2OUT&=~BIT3;
delay(0xe000);
P2OUT|=BIT3;
delay(0xe000);
};
}
voidBuzz()//蜂鸣响
{unsignedinti;
for(i=0;i<3;i++)
{P2OUT&=~BIT4;
delay(0xf800);
P2OUT|=BIT4;
delay(0xf800);
};
}
intmain(void)
{WDTCTL=WDTPW+WDTHOLD;//关闭看门狗
//设置端口P2.3输出,控制LED,P2.4输出,控制蜂鸣器
P2SEL&=~(BIT3+BIT4);
P2SEL2&=~(BIT3+BIT4);
P2OUT|=BIT3+BIT4;
P2DIR|=BIT3+BIT4;
//设置端口P1.1允许中断
P1SEL&=~BIT1;
P1SEL2&=~BIT1;
P1REN|=BIT1;
P1OUT|=BIT1;
P1DIR&=~BIT1;
P1IES|=BIT1;
P1IFG&=~BIT1;
P1IE|=BIT1;
_EINT();
//P1.0输出时钟ACLK,P1.4输出时钟SMCLK
P1SEL|=BIT0+BIT4;
P1SEL2&=~(BIT0+BIT4);
P1DIR|=BIT0+BIT4;
Blink();
Buzz();
for(;;)//主循环
{
LPM4;//
Blink();
}
}
#pragmavector=PORT1_VECTOR
__interruptvoidport_ISR()
{Buzz();
P1IFG&=~(BIT1);//清中断标志
//LPM4_EXIT;
}
程序6.1.c
#include"io430.h"
#include"in430.h"
intmain(void)
{
//Stopwatchdogtimertopreventtimeoutreset
WDTCTL=WDTPW+WDTHOLD;
//P1.0输出时钟ACLK
P1SEL|=BIT0;
P1SEL2&=~BIT0;
P1DIR|=BIT0;
//设置输入输出
P1SEL&=~BIT7;
P1SEL2&=~BIT7;
P1DIR&=~BIT7;
P1SEL&=~BIT1;
P1SEL2&=~BIT1;
P1DIR|=BIT1;
P1OUT|=BIT1;
P2SEL=0x00;
P2SEL2=0x00;
P2DIR=0xff;
//设置时钟
BCSCTL3|=LFXT1S_2;
BCSCTL1|=DIVA_3;
//设置中断
P1IES|=BIT7;
P1IFG&=~BIT7;
P1IE|=BIT7;
_EINT();
LPM0;
}
unsignedintcount=0;
unsignedcharnum=0;
#pragmavector=PORT1_VECTOR//置P1中断向量
__interruptvoidLED()
{
count++;
if(count==1424)//1424根据之前的实测值确定
{
num++;
P2OUT=~num;
count=0;
}
P1IFG&=~BIT7;
}
程序6.2.c
#include"io430.h"
#include"in430.h"
intmain(void)
{
//Stopwatchdogtimertopreventtimeoutreset
WDTCTL=WDTPW+WDTHOLD;
//P1.0输出时钟ACLK
P1SEL|=BIT0;
P1SEL2&=~BIT0;
P1DIR|=BIT0;
//设置输入输出
P1SEL&=~BIT7;
P1SEL2&=~BIT7;
P1DIR&=~BIT7;
P1SEL&=~BIT1;
P1SEL2&=~BIT1;
P1DIR|=BIT1;
P1OUT|=BIT1;
P2SEL=0x00;
P2SEL2=0x00;
P2DIR=0xff;
//设置时钟
BCSCTL3|=LFXT1S_2;
BCSCTL1|=DIVA_3;
//设置中断
P1IES|=BIT7;
P1IFG&=~BIT7;
P1IE|=BIT7;
_EINT();
LPM0;
}
unsignedinti,count=0;
unsignedcharnum=0,buzz=0;
#pragmavector=PORT1_VECTOR//置P1中断向量
__interruptvoidLED()
{
count++;
if(count==1424)//1424根据之前的实测值确定
{
num++;
P2OUT=~num;
count=0;
buzz++;
if(buzz==5)
{
P1OUT&=~BIT1;
for(i=0;i<=3000;i++);
P1OUT|=BIT1;
buzz=0;
}
}
P1IFG&=~BIT7;
}