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寄存器有描述,當進入中斷後自動清零標誌位
}


以上程序在開發板上正常運行:



發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章