本笔记整理自B站教程MSP430F5529单片机学习视频汇总
基于库函数的开发—GPIO库函数
右边部分写错了,看的时候注意
基于库函数的开发—GPIO实践操作
LED交替闪烁
#include <msp430.h>
/*
* EXP-GPIO-01.C
*
* Created on: 2023年3月10日
* Author: ASUS
*/
#include "driverlib.h"
void main(void)
{
//关闭看门狗
WDT_A_hold(WDT_A_BASE);
//设置P1.0为输出(LED1)
GPIO_setAsOutputPin(GPIO_PORT_P1, GPIO_PIN0);
//设置P4.7为输出(LED2)
GPIO_setAsOutputPin(GPIO_PORT_P4, GPIO_PIN7);
//设置P1.0输出高电平(LED1点亮)
GPIO_setOutputHighOnPin(GPIO_PORT_P1, GPIO_PIN0);
//设置P4.7输出低电平(LED2熄灭)
GPIO_setOutputLowOnPin(GPIO_PORT_P4, GPIO_PIN7);
while(1)
{
//取反P4.7引脚的输出
GPIO_toggleOutputOnPin(GPIO_PORT_P4, GPIO_PIN7);
//取反P1.0引脚的输出
GPIO_toggleOutputOnPin(GPIO_PORT_P1, GPIO_PIN0);
//软件延迟
__delay_cycles(1000000);
}
}
注意#include“driverlib.h”头文件时要注意:
添加MSP430F5xx_6xx文件夹到当前工程下
MSP430F5xx_6xx文件夹是在导入的msp430ware_3_80_13_03包中找
把上述MSP430F5xx_6xx文件夹的路径包含进来
按键控制LED
#include <msp430.h>
/*
* EXP-GPIO-02.C
*
* Created on: 2023年3月10日
* Author: ASUS
*/
#include "driverlib.h"
void main(void)
{
//关闭看门狗
WDT_A_hold(WDT_A_BASE);
//设置P1.0为输出(LED1)
GPIO_setAsOutputPin(GPIO_PORT_P1, GPIO_PIN0);
//设置P4.7为输出(LED2)
GPIO_setAsOutputPin(GPIO_PORT_P4, GPIO_PIN7);
//设置P1.0输出低电平(LED1熄灭)
GPIO_setOutputLowOnPin(GPIO_PORT_P1, GPIO_PIN0);
//设置P4.7输出低电平(LED2熄灭)
GPIO_setOutputLowOnPin(GPIO_PORT_P4, GPIO_PIN7);
//设置P2.1为输入,上拉(S1)
GPIO_setAsInputPinWithPullUpResistor(GPIO_PORT_P2, GPIO_PIN1);
//设置P1.1为输入,上拉(S2)
GPIO_setAsInputPinWithPullUpResistor(GPIO_PORT_P1, GPIO_PIN1);
while(1)
{
//没有按键按下时,为高电平;按键按下时为低电平
if((GPIO_INPUT_PIN_LOW == GPIO_getInputPinValue(GPIO_PORT_P2, GPIO_PIN1)) ||
(GPIO_INPUT_PIN_LOW == GPIO_getInputPinValue(GPIO_PORT_P1, GPIO_PIN1))
)
{
//软件延时,相当于是按键消抖
__delay_cycles(5000);
if(GPIO_INPUT_PIN_LOW == GPIO_getInputPinValue(GPIO_PORT_P2, GPIO_PIN1))
{
//等待按键释放
while(GPIO_INPUT_PIN_LOW == GPIO_getInputPinValue(GPIO_PORT_P2, GPIO_PIN1));
//改变LED1的状态,(取反P1.0引脚的输出)
GPIO_toggleOutputOnPin(GPIO_PORT_P1, GPIO_PIN0);
}
if(GPIO_INPUT_PIN_LOW == GPIO_getInputPinValue(GPIO_PORT_P1, GPIO_PIN1))
{
//等待按键释放
while(GPIO_INPUT_PIN_LOW == GPIO_getInputPinValue(GPIO_PORT_P1, GPIO_PIN1));
//改变LED1的状态,(取反P4.7引脚的输出)
GPIO_toggleOutputOnPin(GPIO_PORT_P4, GPIO_PIN7);
}
}
//软件延时
__delay_cycles(5000);
}
}
单个LED闪烁
#include <msp430.h>
/*
* EXAMPLE007.C
*
* Created on: 2023年3月10日
* Author: ASUS
*/
/**
* main.c
*/
void main(void)
{
unsigned i, j;
WDTCTL = WDTPW | WDTHOLD; //stop watchdog timer关闭看门狗
P4DIR |= BIT7; //p4.7方向设置为输出
P4OUT |= BIT7; //p4.7输出高电平,点亮LED
P4OUT &= ~BIT7; //p4.7输出低电平,熄灭LED
while(1)
{
P4OUT |= BIT7; //p4.7输出高电平,点亮LED
for(i = 60000; i > 0; i --)
{
for(j = 200; j > 0; j --) //延时
{
;
}
}
P4OUT &= ~BIT7; //p4.7输出低电平,熄灭LED
for(i = 60000; i > 0; i --)
{
for(j = 200; j > 0; j --) //延时
{
;
}
}
}
}
时钟系统(UCS:Unified Clock System)
有三个系统时钟可以选择ACLK、SMCLK、MCLK
VLOCLK、DCOCLK、DCOCLKDIV、REFOCLK是内部时钟源
VLOCLK受温度变化影响较大;DCOCLK、DCOCLKDIV稳定度稍微高一点;REFOCLK稳定度更高,是经过内部修整之后的
上电之后MCLK、SMCLK时钟信号默认来自DCOCLKDIV时钟源,这是DCOCLK经过2分频得到的,ACLK主要来自XT1CLK
MCLK时钟信号默认来自DCOCLKDIV时钟源,这题的表述可能不是很准确
时钟源如果来自LFXT1低频晶振,当低频晶振发生故障,不工作,系统会自动切换到REFOCLK(32768),场景2也同理,这是系统的防护机制
TimerA定时器基本功能
LED1通过定时器控制不断闪烁
/*
* TimerA.C
*
* Created on: 2023年3月11日
* Author: ASUS
*/
#include <msp430.h>
int main(void)
{
//关闭看门狗
WDTCTL = WDTPW + WDTHOLD;
//引脚设置为输出
P1DIR |= 0x01;
//使能CCR0中断
TA0CCTL0 = CCIE;
//设置计数值
TA0CCR0 = 50000;
//选择时钟源,选择工作模式
TA0CTL = TASSEL_2 + MC_1 + TACLR;
//进入LPM0,开启全局中断
__bis_SR_register(LPM0_bits + GIE);
__no_operation();
}
//Timer0 A0中断服务函数
#pragma vector = TIMER0_A0_VECTOR
__interrupt void TIMER0_A0_ISR(void)
{
//引脚P1.0的输出取反
P1OUT ^= 0x01;
}
TimerA工作模式和中断
定时器控制红色LED闪烁
具体要求
解题思路
请思考,用软件延时的方式,有利弊?
代码示例
#include <msp430.h>
/*
* TimerA_LED.C
* 代码示例1:采用溢出中断的方式
* Created on: 2023年3月11日
* Author: ASUS
*/
int main(void)
{
//停用看门狗
WDTCTL = WDTPW + WDTHOLD;
//P1.0设置为输出
P1DIR |= BIT0;
//设置开始计数值;16384 / 32768 = 0.5s,65535-16384
TA0R = 65535 - 16384;
//选择ACLK,连续计数模式,不要清除TAR
TA0CTL = TASSEL__ACLK + MC_2 + TAIE;
//开启中断
_EINT();
while(1)
{
__no_operation(); //调试用
}
}
//Timer0 A1中断服务函数
#pragma vector = TIMER0_A1_VECTOR
__interrupt void TIMER0_A1_ISR(void)
{
switch(__even_in_range(TA0IV, 14))
{
case 0: //无中断
break;
case 2: //CCR1中断
break;
case 4: //CCR2中断
break;
case 6: //CCR3中断
break;
case 8: //CCR4中断
break;
case 10: //CCR5中断
break;
case 12: //CCR6中断
break;
//溢出中断
case 14:
TA0R = 65535 - 16384;
P1OUT ^= BIT0;
break;
default:
break;
}
}
#include <msp430.h>
/*
* TimerA_LED2.C
*
* Created on: 2023年3月11日
* Author: ASUS
*/
unsigned char u8_count_10ms;
int main(void)
{
//停用看门狗
WDTCTL = WDTPW + WDTHOLD;
//P1.0设置为输出
P1DIR |= BIT0;
//使能CCR0中断
TA0CCTL0 = CCIE;
//设置目标计数值
TA0CCR0 = 10000; //10ms
//选择SMCLK,增计数模式,清除TAR
TA0CTL = TASSEL__SMCLK + MC_1 + TACLR;
u8_count_10ms = 0;
//开启中断
_EINT();
while(1)
{
__no_operation();
}
}
//Timer0 A0中断服务函数
#pragma vector = TIMER0_A0_VECTOR
__interrupt void TIMER0_A0_ISR(void)
{
u8_count_10ms ++;
if(u8_count_10ms >= 50)
{
P1OUT ^= BIT0; //P1.0的输出取反
u8_count_10ms = 0;
}
}
#include <msp430.h>
/*
* TimerA_LED3.C
*
* Created on: 2023年3月11日
* Author: ASUS
*/
int main(void)
{
//停用看门狗
WDTCTL = WDTPW + WDTHOLD;
//P1.0设置为输出
P1DIR |= BIT0;
//使能CCR0中断
TA0CCTL0 = CCIE;
//设置目标计数值
TA0CCR0 = 50000; //500ms
//选择SMCLK,增计数模式,清除TAR
TA0CTL = TASSEL__SMCLK + ID__2 + MC_1 + TACLR; //ID__2表示2分频
TA0EX0 = TAIDEX_5; //TAIDEX_5表示5分频,加起来10分频
//开启中断
_EINT();
while(1)
{
__no_operation();
}
}
//Timer0 A0中断服务函数
#pragma vector = TIMER0_A0_VECTOR
__interrupt void TIMER0_A0_ISR(void) //每500ms进一次中断
{
//P1.0的输出取反
P1OUT ^= BIT0;
}