CC2530开发板实验笔记----01

/****************************************************
* 安德联CC2530与网关开发板历程zigbee实验1-13
*
* 功能:1、S1按键切换正常模式与睡眠模式 
*       2、S2打印当前芯片温度
*       3、串口助手发送"LED_ON@"可开启LED1
*          "LED_OFF@"关闭LED1
*       
*  日期:2018.7.13
*****************************************************/
#include <ioCC2530.h>
#include <string.h>
#include <stdio.h>

typedef  unsigned char  u8;
typedef  unsigned int  u16;

#define  ENABLE   1
#define  DISABLE  0

#define LED1 P1_0
#define LED2 P1_1
#define S1   (P0_1 == 0 ? 1 : 0) 
#define S2   (P2_0 == 0 ? 1 : 0) 

u8 SysSleep = 0;
u8 USARTFlag = 0;
u8 USARTCount = 0;
char UsartBuff[50];



float ADC_ConvTem(void);



void Delay_MS(u16 time)
{
  u16 i,j;
  
  for(i=0;i<time;i++)
    for(j=0;j<1070;j++);
}

/******************** 外设初始化 **************************/

//printf 链接函数
__near_func int putchar(int c)
{
    UTX0IF = 0;
    U0DBUF = (char)c;
    while(UTX0IF == 0);
    return(c);
}

void LED_Init(void)
{
   P1SEL &= ~0x03;  //IO口的类型,0为通用IO,1为复用IO
   P1DIR |= 0x03;  //IO方向,1为输出,0为输入
}

void KEY_Init(void)
{
   //初始化S1 中断模式
   P0SEL &= ~0X02;  //普通IO模式
   P0DIR &= ~0X02;  //输入模式
   P0INP &= ~0X02;  //上下拉模式
   
   
   P0IFG &= 0;      //P0中断状态标志位清零
   P0IF = 0;        //清中断标志
   PICTL |= 0x01;   //0上升沿   1下降沿触发
   P0IEN |= 0x02;   //P0中断使能打开
   P0IE  = 1;       //打开P0中断
   EA = 1;          //打开总中断


   //初始化S2 普通模式
   P2SEL &= ~0x01;
   P2DIR &= ~0x01; 
   P2INP &= ~0xa1; //P2输入模式,0为上下拉模式,1为高阻态
}

void TIM3_Init(void)
{
   T3CTL  |= 0x08;    //开启溢出中断
   T3CTL  |= 0xe0;     //TIM1 128分频
   T3CTL  &= ~0x03;    //自动装载模式,从0计数到0xff
   
   T3IE = 1;          //打开T1中断
   EA = 1;            //打开总中断
   
   T3CTL  |= 0x10;    //开启T3,开始计数  
}


void USART_Init(void)
{
   //初始化串口0GPIO
   PERCFG &= ~0x01;  //串口0IO复用到位置1
   P0SEL  |= 0x0c;   //引脚为复用IO 
   P0DIR  |= 0x0c;   //引脚方向为输出
   P0INP  &= ~0x0c;  //引脚为上下拉模式
   P2INP  &= ~0x20;  //引脚为上拉
   
   //初始化串口0
   U0CSR |= 0x80;   //USART模式
   U0CSR |= 0x40;   //USART接受允许
   
   U0UCR &= ~0x10;  //一次传输8位数据
   U0UCR &= ~0x08;  //奇偶校验关闭
   U0UCR &= ~0x04;  //1个停止位
     
   U0GCR  |= 11;    //波特率115200 根据datasheet表格,因为CLK为16M所以12
   U0BAUD |= 216;   //波特率115200
     
   URX0IE = 1;      //使能USART0接收中断
   EA = 1;          //打开总中断
  
}


void ADC_Init(void)
{
    ADCIE = 0;  //关闭ADC中断
    ADCIF = 0;  //清除标志位
    
    ADCCON1 &= ~0x30;  //清零标志位
    ADCCON1 |= 0x30;   //STSEL 选择启动方式为ST置1控制
    
    ADC_ConvTem();  //ADC前两次转换为异常值
    Delay_MS(10);
    ADC_ConvTem(); 
}



void SysPowerMode(u8 mode)
{
    if(mode < 4 && mode > 0)
    {
        SLEEPCMD |= mode;
        PCON = 0X01;
    }
    else  PCON = 0;
    
}



/******************** 功能性函数 **************************/

//串口发送1个byte的数据
void USART_Send(u8 dat)
{
    U0DBUF = dat;
    URX0IF = 0;
    while(UTX0IF==0);
    UTX0IF = 0;
}


//串口控制LED

void USART_LED(void)
{
     if(USARTFlag)
    {
        if(!strcmp(UsartBuff,"LED_ON@"))
          LED1 = 0;
         
        if(!strcmp(UsartBuff,"LED_OFF@"))
          LED1 = 1;
       
        for(u8 i=0;i<USARTCount;i++)  //清空缓冲区
        {
          printf("%c",UsartBuff[i]);
          UsartBuff[i] = 0;
        }
          
        printf("\r\n");
        
        USARTFlag  = DISABLE;
        USARTCount = 0;
    }
}

//ADC获取芯片内部温度值
float ADC_ConvTem(void)
{
   float temp;
   
     P0IE = 0;        //P0中断关闭
     P0IEN &= ~0x02;  //否则ATEST = 1;时会产生P0外部中断
     
       TR0 =1;     //连接内部温度传感器,配置此寄存器后,外部中断不能用
    ATEST = 1;    //连接内部温度传感器
  
    
   ADCCON2  = 0X3E;   //ADCCON2与ADCCON3寄存器,实现效果相同
   //ADCCON3  = 0X3E;  //选择内部电压为参考电压,12位分辨率
   
   ADCCON1 |= 0x30;   //STSEL 选择启动方式为ST置1控制

   //转换2次,去除第一次转换时,误差较大的返回值
   for(char i =0;i<2;i++)
   {
       ADCCON1 |= 0x40;   //开始转换
       while(ADCCON1&0x80 == 0); //等待转换完成
     
       temp = ADCH<<4 | ADCL>>4;  //12位分辨率下ADCL右4位无效
       temp = (temp - 1367.5)/4.5;
   }
 
       TR0 =0;     //连接内部温度传感器,配置寄存器后,外部中断不能用
    ATEST = 0;  //连接内部温度传感器
    
     P0IFG = 0;     //清中断标志
     P0IE = 1;     //P0中断开启
     P0IEN |= 0x02;   //P0中断使能
    
   return temp;
  
}

//设置系统时钟位32M
void SetCLK32M(void)
{
  CLKCONCMD &= ~0x40;
  
  while(CLKCONSTA&0x40);
  
  CLKCONCMD &= ~0x47;
}



/******************** 主函数 **************************/

int main(void)
{
 
  LED_Init();

  TIM3_Init();
  USART_Init();  
  ADC_Init();
  SetCLK32M();
   KEY_Init();

  while(1)
  {
      //根据S1按键触发的中断标志位切换模式
      if(SysSleep)   
      {
          printf("进入睡眠模式\r\n");
          Delay_MS(1);
          SysPowerMode(3);
          Delay_MS(1);
          printf("进入正常模式\r\n");
      }
    
      //按下S2打印当前芯片温度
      if(S2) 
      {
        while(S2);
        printf("芯片温度为:%2.2f度\r\n",ADC_ConvTem());
      }
    
      //根据串口字符控制LED亮灭
      USART_LED();

      Delay_MS(100);
  }
  
}


/******************** 中断函数 **************************/

//P0_1 S1按键中断函数
#pragma vector = P0INT_VECTOR
__interrupt void P0_ISR(void)
{
    SysSleep = !SysSleep;
  
    if(!SysSleep) 
    {
        
        SysPowerMode(4);
    }
  
    P0IFG = 0;     //清中断标志
    P0IF = 0;      //清中断标志
}


//TIM3 定时器中断
#pragma vector = T3_VECTOR
__interrupt void T3_ISR(void)
{
    static unsigned int i = 0;
    
    i++;
    if(i>244)
    {
      LED2 = ~LED2;   //改变 LED2 状态
      
      i=0;
    }
    //IRCON寄存器有描述,当进入中断后自动清零标志位
}


//串口0接收中断
#pragma vector = URX0_VECTOR
__interrupt void U0Rx_ISR(void)
{
  unsigned char RxBuff;
  
  RxBuff = U0DBUF;
  
  //缓存串口数据,当超过50个字符或者接收到结束符
  //缓存数组停止接收数据,只有当MAIN函数处理完数据
  //缓存数组才能再次接收数据
  if(USARTCount<50 && USARTFlag == DISABLE)
  {
    UsartBuff[USARTCount] = RxBuff;
    USARTCount++;
    
    if(RxBuff == '@') 
    {     
      USARTFlag  = ENABLE;
    }
  }
  else 
  {
    USARTFlag  = ENABLE;
  }

  //TCON寄存器有描述,当进入中断后自动清零标志位
}


以上程序在开发板上正常运行:



猜你喜欢

转载自blog.csdn.net/a3748622/article/details/81025228