MSP430F5529学习笔记(3)——实现LED闪烁和呼吸灯

volatile用法MSP430F5529学习笔记(2)——点亮LED

目录

实现LED闪烁

利用while语句实现延时

代码

关于编译器优化

利用for语句实现延时

代码

精准延时

代码

获取开发板主频

修改主频

使用示范

实现呼吸灯

采用精准定时的方法实现呼吸灯

采用for语句实现呼吸灯


LED闪烁,说白了就是点亮之后,延时,熄灭,点亮,然后一直反复就行。

但是有一个需要注意的点,就是延时的时间需要把握好。如果延时时间太短,我们就看不到LED的闪烁,只是看到一个微弱是小灯,如果延时时间太长,我们看到灯熄灭时候,再点亮的间隙太长。

实现LED闪烁

利用while语句实现延时

代码

我们学习单片机,基本都是从一个自己写的延时函数开始。代码如下

void main(void)
{
    //注意,因为MSP430是16位的编译环境,所以这里的 unsigned int只有2个字节,16个bit,又是无符号的,所以范围是0-65535
    volatile unsigned int uint16_delay;
    WDTCTL = WDTPW | WDTHOLD;   // stop watchdog timer
    //P4.7为输出
    P4DIR=0x80;  //0x80=1000 0000,查看数据手册可知,P4.7为输出,P4其他脚为输入
    while(1)
    {
        //P4.7输出高电平
        P4OUT=0x80;  //0x80=1000 0000,查看数据手册可知,P4.7为输出高电平,P4其他脚为下拉输入
        //延时
        uint16_delay =50000;
        while(uint16_delay--);

        P4OUT=0x00;  //0x80=0000 0000,查看数据手册可知,P4.7为输出低电平,P4其他脚为下拉输入
        uint16_delay =50000;
        while(uint16_delay--);
    }
}

这里只有一个注意的点,就是必须写volatile(不明白的点链接),这个防止编译器优化。如果被编译器优化了之后,延时将会不准确,甚至可能没有现象

关于编译器优化

如果我们觉得写volatile很麻烦,总是忘记写了。怎么办呢?

我们可以自己设置,鼠标靠近工程——>右键——>properties——>build——>MSP430 Compiler——>Optimizition——>Optimizition level(--opt_level,-O)——>选择off——>Apply and Close

利用for语句实现延时

代码

这个也是官方的视频教程里面的代码,他代码里面没有volatile,可能是for循环里面步骤,CCS编译器不会进行优化。

void main(void)
{
    //注意,因为MSP430是16位的编译环境,所以这里的 unsigned int只有2个字节,16个bit,又是无符号的,所以范围是0-65535
    unsigned int uint16_delay;
	WDTCTL = WDTPW | WDTHOLD;	// stop watchdog timer
	//P4.7为输出
	P4DIR=0x80;  //0x80=1000 0000,查看数据手册可知,P4.7为输出,P4其他脚为输入
	while(1)
	{
	    //P4.7输出高电平
	    P4OUT=0x80;  //0x80=1000 0000,查看数据手册可知,P4.7为输出高电平,P4其他脚为下拉输入
	    for(uint16_delay=0;uint16_delay<50000;uint16_delay++);
	    P4OUT=0x00;  //0x80=0000 0000,查看数据手册可知,P4.7为输出低电平,P4其他脚为下拉输入
	    for(uint16_delay=0;uint16_delay<50000;uint16_delay++);

	}
}

精准延时

代码

#include <msp430.h> 

#define CPU_F ((double)1000000)
#define delay_us(x) __delay_cycles((long)(CPU_F*(double)x/1000000.0))
#define delay_ms(x) __delay_cycles((long)(CPU_F*(double)x/1000.0))

/**
 * main.c
 */
void main(void)
{
  WDTCTL = WDTPW | WDTHOLD;   // stop watchdog timer
  //P4.7为输出
  P4DIR=0x80;  //0x80=1000 0000,查看数据手册可知,P4.7为输出,P4其他脚为输入
  while(1)
  {
      //P4.7输出高电平
      P4OUT=0x80;  //0x80=1000 0000,查看数据手册可知,P4.7为输出高电平,P4其他脚为下拉输入
      delay_ms(1000);
      P4OUT=0x00;  //0x80=0000 0000,查看数据手册可知,P4.7为输出低电平,P4其他脚为下拉输入
      delay_ms(1000);
  }
}

如上为MSP430F5529的精准延时。这个里面我们只需要修改#define CPU_F ((double)1000000)这一行即可。如果系统主时钟(MCLK)是多少,(double)后写多少。因为默认情况下,MSP430F5529的主时钟为1Mhz。所以此处写成1000000。

简单方法获取开发板主频

如果不知道我们当前板子的系统时钟是多少,可以尝试写入如上代码。(1)然后将 delay_ms(1000);改为 delay_ms(5000);。(2)然后打开手机计时器,和下载程序到开发板中。(3)在运行程序的瞬间,按下手机计时器开始计时。(4)如果手机是5S左右,那么表示当前开发板时钟是1MHZ。如果是5MHZ,那么手机的时间应该是1S左右。计算方法如下

实际主频= (程序定时时间  / 手机计时器时间 )* 当前程序设置主频

将手机计时器时间5s,程序定时时间5s,当前程序设置1MHZ(1MHZ=1000000HZ)带入。可以得到实际主频为1MHZ。

将手机计时器时间1s,程序定时时间5s,当前程序设置1MHZ(1MHZ=1000000HZ)带入。可以得到实际主频为5MHZ。

修改主频

假设我们现在有一个板子的主频是5MHZ,那么这样写

//主频为1MHZ的板子
#define CPU_F ((double)1000000)
#define delay_us(x) __delay_cycles((long)(CPU_F*(double)x/1000000.0))
#define delay_ms(x) __delay_cycles((long)(CPU_F*(double)x/1000.0))


//主频为5MHZ的板子
#define CPU_F ((double)5000000)
#define delay_us(x) __delay_cycles((long)(CPU_F*(double)x/1000000.0))
#define delay_ms(x) __delay_cycles((long)(CPU_F*(double)x/1000.0))

使用示范

delay_us(1);         //延时1微秒

delay_ms(1);         //延时1毫秒
 
delay_us(4.5);       //延时4.5微秒

delay_ms(4.5);       //延时4.5毫秒

delay_us(1000000);   //延时1秒

delay_ms(1000);      //延时1秒

实现呼吸灯

采用精准定时的方法实现呼吸灯

因为我们这个for和while的延时多多少少还是有点不太准确,所以一开始我采用精准延时。

void main(void)
{
  long delay_time;
  WDTCTL = WDTPW | WDTHOLD;   // stop watchdog timer
  //P4.7为输出
  P4DIR=0x80;  //0x80=1000 0000,查看数据手册可知,P4.7为输出,P4其他脚为输入
  while(1)
  {
      for(delay_time=0;delay_time<500;delay_time++)
      {
          //P4.7输出高电平
          P4OUT=0x80;  //0x80=1000 0000,查看数据手册可知,P4.7为输出高电平,P4其他脚为下拉输入
          delay_ms(delay_time);
          P4OUT=0x00;  //0x80=0000 0000,查看数据手册可知,P4.7为输出低电平,P4其他脚为下拉输入
          delay_ms(1000-delay_time);
      }
  }
}

后面我一编译就开始报错,expected an integer constant。

后面查找了相关资料发现,delay_ms();的延时只能是传入常量,像delay_time这种变量是无法编译通过。

delay_ms(1000);          //传入的是1000,这是个常量。可以编译成功
delay_ms(delay_time);    //传入的是delay_time,这是个变量,编译失败

采用for语句实现呼吸灯

因为for语句整体写起来是在同一行,更加容易理解。所以我采用for语句进行延时

#include <msp430.h> 

#define LED_all_time   200  //这里是为了方便修改呼吸灯的周期

/**
 * main.c
 */
void delay(volatile int delay_time)
{
    volatile unsigned int uint16_delay;
    while(delay_time--)
    {
        for(uint16_delay=0;uint16_delay<5;uint16_delay++);
    }
}

void main(void)
{
  volatile long delay_time;
  WDTCTL = WDTPW | WDTHOLD;   // stop watchdog timer
  //P4.7为输出
  P4DIR=0x80;  //0x80=1000 0000,查看数据手册可知,P4.7为输出,P4其他脚为输入
  while(1)
  {
      for(delay_time=0;delay_time<LED_all_time;delay_time++)
      {
          //P4.7输出高电平
          P4OUT=0x80;  //0x80=1000 0000,查看数据手册可知,P4.7为输出高电平,P4其他脚为下拉输入
          delay(delay_time);
          P4OUT=0x00;  //0x80=0000 0000,查看数据手册可知,P4.7为输出低电平,P4其他脚为下拉输入
          delay(LED_all_time-delay_time);
      }
      for(delay_time=LED_all_time;delay_time>0;delay_time--)
      {
          //P4.7输出高电平
          P4OUT=0x80;  //0x80=1000 0000,查看数据手册可知,P4.7为输出高电平,P4其他脚为下拉输入
          delay(delay_time);
          P4OUT=0x00;  //0x80=0000 0000,查看数据手册可知,P4.7为输出低电平,P4其他脚为下拉输入
          delay(LED_all_time-delay_time);
      }
  }
}

  • 17
    点赞
  • 68
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
好的,我会为您提供关于 MSP430F5529 的 ADC12 学习笔记MSP430F5529 是德州仪器(Texas Instruments)公司推出的一款低功耗微控制器,它具有 12 位的模数转换器(ADC12)模块,可以用于采集模拟信号。 ADC12 模块具有多个配置选项和功能,下面是一些相关的学习笔记: 1. ADC12 基本配置:首先,您需要对 ADC12 进行基本的配置。这包括选择参考电压源、设置采样保持时间、选择转换时钟源等。可以通过配置控制寄存器(ADC12CTL0 和 ADC12CTL1)来完成这些设置。 2. 通道选择:ADC12 可以选择多个输入通道进行采样。您可以使用 ADC12MCTLx 寄存器来选择所需的输入通道,并进行相关的配置,如参考电压源、输入通道的输入方式(单端或差分)等。 3. 触发方式:ADC12 可以通过软件触发或外部触发进行转换。您可以使用 ADC12CTL0 寄存器来选择触发方式,并设置相应的触发源。 4. 转换结果:ADC12 转换后的结果可以通过 ADC12MEMx 寄存器进行读取。对于 12 位的转换结果,您可以直接读取 ADC12MEMx 寄存器的值。 5. 中断和DMA:ADC12 可以使用中断或 DMA 来处理转换完成后的结果。通过配置 ADC12CTL0、ADC12CTL1 和相关中断/ DMA 控制寄存器,您可以实现转换完成后的中断或 DMA 传输。 请注意,上述仅为一些基本的学习笔记MSP430F5529 的 ADC12 模块还有更多高级功能和配置选项。您可以参考 MSP430F5529 的用户手册和相关文档,以深入了解 ADC12 模块的更多细节和应用。 希望这些笔记能对您有所帮助!如果您对其他问题感兴趣,请随时提问。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

风正豪

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值