感知层编程实验四

南昌航空大学实验报告

011111

 

课程名称:  感知层编程实验  实验名称:TIME编程

班级学号:        姓名:           同组人:                           

指导教师评定:                                      签名:              

实验 TIMER编程

实验目的:

  1. 加深和巩固学生对于CC2530定时器的理解和掌握
  2. 让学生初步掌握CC2530定时器的PWM功能,及其编程方法
  3. 高学生的上机和编程过程中处理具体问题的能力

实验要求:

  1. 实验要求自己独立的完成
  2. 编写和调试过程中出现的问题记录,并事后总结到报告中
  3. 实验程序调试完成后, 用给定的平台进行测试,由老师检查测试结果,并给予相应的成绩
  4. 实验完成后,要上交实验报告

实验内容:

  1. 开发一个新的应用,能够利用定时器使用LED灯周期性闪烁,及通过PWM功能实现无级调光
    1. 首先使得LED灯可以周期性闪烁(利用定时器的计时功能)
    2. 利用定时器PWM功能控制LED的周期性渐亮、渐暗;
    3. 通过按键控制控制亮度变化,实现按下逐渐变亮,放开逐渐变暗。
  2. 在实验报告中分别给出上述三个阶段的源码

实验环境:

集成开发环境为IAR

实验过程

这次实验主要考察的定时器与PWM功能的设计,按照实验内容的要求分别在IAR上写好代码,连接板子烧录,观察实验现象。

实验代码

第一部分

#include<ioCC2530.h>

#define LED1 P1_0 //定义LED1P1_0口控制

#define LED2 P1_1 //定义LED2P1_1口控制

#define KEY1 P0_1        //定义KEY1P0_1口控制

 

void Delay(int n); //延时

void InitKEY(void);            //初始化KEY控制IO口函数

 

void Delay(int n)             //1ms

{

  int i,j;

   for(i=0;i<n;i++)

   for(j=0;j<535;j++);

}

 

void InitKEY(void)

{

  IEN1 |= 0x20; //端口0的总中断使能

  P0IEN |= 0x02; //P0_1口的中断使能,即KEY1的按键中断

  //PICTL |= 0x00; //端口中断触发延,默认所有端口都是上升沿

  PICTL |= 0x01; //设置成端口0下降沿触发

  

  IEN0 |= 0x80; //总中断开启

  P0IFG = 0x00; //清除端口0的中断状态标志

}

 

void main(void)

{

  P1DIR |= 0x03; //P1_0P1_1定义为输出

  LED1 = 1; //LED0灯初始化为关

  LED2 = 1; //LED1灯初始化为关

  InitKEY();

  while(1) //死循环 等待按键中断

  {

                

  }

}

 

#pragma vector = P0INT_VECTOR //P0中断向量

 __interrupt void P0_ISR(void)

{

  if(0x02 == (P0IFG & 0x02)) //判断一下是否是P0_1即按键1的中断请求

  {

    for(int i = 0;;i++)

    {

        if(i%2==0)

        {

        LED2 = 1;

LED1 = !LED1;

        }

        else

        {

        LED1 = 1;

        LED2 = !LED2;

        }

        Delay(1000);

    }

  }

 

  IRCON &= ~0x20; //清除端口0的总中断状态标志

  //P0IF = 0; //和上面的代码是一个意思

  P0IFG &= ~0x02; //清除具体端口P0_1的中断状态标志

}

第二部分

#include <ioCC2530.h>

typedef unsigned char uchar;
typedef unsigned int  uint;

#define LED1 P1_0     // P1.0口控制LED1

void Delay(uint ms)
{
  uint i,j;
  for(i=0;i<ms;i++)
    for(j=0;j<535;j++);
}

void InitLed(void)
{
    P1DIR |= 0x01;   //P1.0定义为输出
    LED1 = 0;     //使LED1灯上电默认为熄灭
}

void Init_Clock()
{
  CLKCONCMD &= ~0x40;   //系统时钟源选择:外部32MHz 。
  while(!(SLEEPSTA & 0x40));//等待晶振稳定
  CLKCONCMD &= ~0x47;    //128分频 CLKSPD不发分频
  SLEEPCMD |= 0x04;      //关闭不用的RC振荡器
}

void InitT1()
{
    CLKCONCMD &= ~0x40;   //设置系统时钟源为32MHZ晶振
    while(CLKCONSTA & 0x40); //等待晶振稳定为32M
    CLKCONCMD &= ~0x07;    //设置系统主时钟频率为32MHZ
    CLKCONCMD |= 0x38;//时钟速度32 MHz 定时器标记输出设置[5:3]250kHz

    PERCFG |= 0x40; //定时器1 的IO位置   1:备用位置2
    P2SEL &= ~0x10;  //定时器1优先
    P2DIR |= 0xC0;  //第1优先级:定时器1通道2-3

    P1DIR |= 0xff; //端口1为输出
    P1SEL |= 0x01;  //timer1 通道2映射口P1_0

    T1CC0H = 0x00; //1ms的周期时钟,频率为976.516HZ
    T1CC0L = 0xff;
    T1CCTL2 = 0x1c;// 模式选择 通道2比较模式
    T1CTL = 0x02;  //250KHz 1分频
}

void main(void)
{
    InitLed();//调用初始化函数
    InitT1(); //定时器初始化及pwm配置
    Init_Clock(); //声明初始化时钟函数
    while(1)
    {
      uchar m;
      uchar array[11]={0xF7,0xE1,0xC8,0xAF,0x96,
                     0x7D,0x64,0x4B,0x32,0x19,0x0A};//占空比依次增大,LED逐渐变亮
   
      for(m = 0; m < 11; m++)
      {
        T1CC2H = 0x00;//高位不变
        T1CC2L = array[m];//依次改变占空比
        Delay(200);
      }
       for(m = 10; m >0; m--)
      {
        T1CC2H = 0x00;//高位不变
        T1CC2L = array[m];//依次改变占空比
        Delay(200);
      }
    }
}

第三部分

#include <ioCC2530.h>

#define uint  unsigned int

#define uchar unsigned char

#define LED1 P1_0 //定义LED1P10口控制

#define KEY1 P0_1      //KEY1P0.1口控制

 

void Delay(unsigned int t);

void InitIO(void);

void InitKey();

 

void main (void){                  

  unsigned int CYCLE=600,PWM=0;//定义周期并赋值

  InitIO();

  InitKey();

  while (1) {

    if(KEY1==0){

      //KEY1按下,一直按着

      PWM++;

      if(PWM>CYCLE){

        PWM=CYCLE-1;

      }

    }else{

      PWM--;

      if(PWM<1){

        PWM=1;

      }

    }

    if(PWM==1){

      LED1=0;

    }else if(PWM==CYCLE){

      LED1=1;

    }else if(CYCLE>PWM){

      LED1=1;

      Delay(PWM);

      LED1=0;

      Delay(CYCLE-PWM);

    }

  }

}

 

void Delay(unsigned int t){//延时函数

  while(t){

   t--;

   t++;

   t--;

  }

}

 

void InitIO(void){//初始化IO口程序

  P1DIR |= 0x13;  //P10P11P14定义为输出

}

 

void InitKey(){//按键初始化函数

  P0SEL &= ~0x02; //设置P0.1为普通IO

  P0DIR &= ~0X02; //按键接在P0.1口上,设P0.1为输入模式

}

实验结果

第一个:led灯呈现周期性闪烁

第二个:led灯自动渐亮渐灭

第三个:led灯最开始很暗,按下k1不动逐渐变亮,放开k1逐渐变暗。

实验总结

这次实验主要存在点困难的是如何用定时器去设计pwm,通过给的资料加上老师上课讲的找到了设计思路。

通过这次实验加深和巩固对于CC2530定时器的理解和掌握,以及学会了通过定时器设计一个pwm功能。

 

 

附录:

周期性闪烁的实现:在响应定时器的中断服务程序中切换LED的状态

PWM功能实现渐亮渐暗:

(1)根据板载LED选择合适的定时器及通道,要求所使用的定时器的通道的引脚与LED相连;

(2)选定定时器的工作模式,设置好预分频值,逐渐改变占空比以输出PWM信号

 

 

 

 

 

 

 

 

 

定时器各通道所使用的引脚:

 

 

T1CTL:

 

 

 

 

 

 

IRCON

 

T1STAT:

 

 

 

定时器框图:

 

初值寄存器:设置计数周期

比较寄存器:设置占空比

 

使用CC2530输出PWM信号,在选定通道后,要选定相应工作模式,确定该模式下初值寄存器、比较寄存器分别是2530中的哪个寄存器。确定好周期,适时修改比较寄存器即可输出PWM信号。

 

 

 

 

 

 

 

posted @ 2022-03-14 23:40  安良  阅读(977)  评论(0编辑  收藏  举报