CC2420.c

来源:互联网 发布:衣服搭配男软件 编辑:程序博客网 时间:2024/06/05 22:57

#include "cc2420.h"
#include "spi.h"
#include "common.h"
#include "uart.h"

/**************************************************
函数功能:写SPI一个字节
输入参数:SPI指令
返回值:对应指令的结果
**************************************************/
unsigned char spi_write(unsigned char data_spi)
{
  unsigned char temp,temp1;
 
  SPDR=data_spi;
  while(!(SPSR & (1<<SPIF))){;}//等待传输结束
  temp1=SPDR;
  temp = SPSR;
 
  return temp1;
}

/*******************************************
*函数功能:使能SPI口
*输入参数:无
*输出参数:无
*返 回 值:无
********************************************/
void spi_enable(void)
{
  PORTB &= ~CSn;     //使能SPI口
}

/*******************************************
*函数功能:禁止SPI口
*输入参数:无
*输出参数:无
*返 回 值:无
********************************************/
void spi_disable(void)
{
  PORTB |= CSn;      //禁止SPI口 
}

/*******************************************
*函数功能:写命令寄存器
*输入参数:命令字
*输出参数:无
*返 回 值:状态寄存器的值
********************************************/
unsigned char write_command(unsigned char command)
{
  unsigned char statueval;
 
  spi_enable();     //使能SPI口
  statueval=SpiWrite(command);
  spi_disable();      //禁止SPI口 
 
  return statueval;
}

/*******************************************
*函数功能:读状态寄存器
*输入参数:无
*输出参数:无
*返 回 值:状态寄存器的值
********************************************/
unsigned char read_status(void)
{
  unsigned char statuevalue;
 
  statuevalue=write_command(SNOP);        //空操作命令,为了读取当前状态寄存器的值
  return statuevalue;
}

/*******************************************
*函数功能:写配置字
*输入参数:Addr:配置寄存器的地址;
           DataH:配置字的高字节;
     DataL:配置字的低字节;
*输出参数:无
*返 回 值:状态寄存器的值
********************************************/
unsigned char write_configure_word(unsigned char Addr,unsigned char DataH,unsigned char DataL)
{
  unsigned char statuevalue;
 
  // spi_enable();     //使能SPI口   以具体情况而定使能/禁止SPI口放在何处
  statuevalue=spi_write(Addr);  //发送配置寄存器的地址,同时返回当前状态寄存器的值
  spi_write(DataH); //发送配置字的高字节
  spi_write(DataL); //发送配置字的低字节
  // spi_disable();      //禁止SPI口 
 
  return statuevalue;
}

/*******************************************
*函数功能:读配置字
*输入参数:Addr:配置寄存器的地址;   
*输出参数:DataH:配置字的高字节;
           DataL:配置字的低字节;
*返 回 值:状态寄存器的值
********************************************/
unsigned char read_configure_word(unsigned char Addr,unsigned char *DataH,unsigned char *DataL)
{
  unsigned char statuevalue;
 
  Addr|=0x40;     //读标志位为1
  spi_enable();     //使能SPI口   以具体情况而定使能/禁止SPI口放在何处
  statuevalue=spi_write(Addr);  //发送配置寄存器的地址,同时返回当前状态寄存器的值
  *DataH=spi_write(0xff); //读配置字的高字节
  *DataL=spi_write(0xff); //读配置字的低字节
  spi_disable();      //禁止SPI口 
 
  return statuevalue;
}

/*******************************************
*函数功能:读RXFIFO
*输入参数:Data_Num:欲读取的字节个数
*输出参数:p_Data:存储数据的缓存首地址;
*返 回 值:状态寄存器的值
********************************************/
unsigned char read_rxfifo(unsigned char Data_Num,unsigned char *p_Data)
{
  unsigned char statuevalue,Addr,i;
 
  Addr=RXFIFO|0x40;     //读标志位为1
  spi_enable();         //使能SPI口
  statuevalue=spi_write(Addr);
 
  for(i=0;i<Data_Num;i++)
  {
    *(p_Data+i)=spi_write(0xff);
  }
 
  spi_disable();      //禁止SPI口 
 
  return statuevalue;
}

/*******************************************
*函数功能:读一字节RXFIFO
*输入参数:无
*输出参数:无
*返 回 值:读取的数据
********************************************/
unsigned char read_rxfifo_byte(void)
{
  unsigned char readvalue,Addr;
 
  Addr=RXFIFO|0x40;     //读标志位为1
  spi_enable();         //使能SPI口
  spi_write(Addr);
  readvalue=spi_write(0xff);
  spi_disable();      //禁止SPI口 
  return readvalue; 
}

/*******************************************
*函数功能:写TXFIFO
*输入参数:Data_Num:欲写入的字节个数
*输出参数:p_Data:存储数据的缓存首地址;
*返 回 值:状态寄存器的值
********************************************/
unsigned char write_txfifo(unsigned char Data_Num,unsigned char *p_Data)
{
  unsigned char statuevalue=0;
  unsigned char i;
 
  spi_enable();         //使能SPI口
  spi_write(TXFIFO);
 
  for (i=0;i<Data_Num;i++)
  {
    statuevalue=spi_write(*(p_Data+i));
 
 if ((statuevalue&(1<<TX_UNDERFLOE))!=0x00)         //发生下溢
 {
   write_command(SFLUSHTX);
   spi_enable();     //重新使能SPI口
 }
  }
 
  spi_disable();      //禁止SPI口
  return statuevalue;
}

/*******************************************
*函数功能:写一字节TXFIFO
*输入参数:p_Data:要写入的数据
*输出参数:无
*返 回 值:状态寄存器的值
********************************************/
unsigned char write_txfifo_byte(unsigned char p_Data)
{
  unsigned char statuevalue;
 
  spi_enable();         //使能SPI口
  spi_write(TXFIFO); 
  statuevalue=spi_write(p_Data);
  spi_disable();      //禁止SPI口
  return statuevalue;
}

/*******************************************
*函数功能:写RAM
*输入参数:p_Data:存储数据的缓存首地址;
           Data_Num:要写入的字节数
     AddrH:在选定的RAM存储块中确定RAM地址
     AddrL:选择RAM存储块
*输出参数:无
*返 回 值:状态寄存器的值
********************************************/
unsigned char write_ram(unsigned char AddrH,unsigned char AddrL,unsigned char Data_Num,unsigned char *p_Data)
{
  unsigned char statuevalue,i;
  AddrH|=0X80;      //访问RAM位置1
  AddrL<<=6;
  AddrL&=0XDF;      //读写操作位置0,表示写操作
 
  spi_enable();         //使能SPI口
  statuevalue=spi_write(AddrH); 
  spi_write(AddrL);
 
  for (i=0;i<Data_Num;i++)
  {
    spi_write(*(p_Data+i));
  }
 
  spi_disable();      //禁止SPI口
  return statuevalue;
}

/*******************************************
*函数功能:写一字节RAM
*输入参数:p_Data:要写入的数据
           AddrH:在选定的RAM存储块中确定RAM地址
     AddrL:选择RAM存储块
*输出参数:无
*返 回 值:状态寄存器的值
********************************************/
unsigned char write_ram_byte(unsigned char AddrH,unsigned char AddrL,unsigned char p_Data)
{
  unsigned char statuevalue;
  AddrH|=0X80;      //访问RAM位置1
  AddrL<<=6;
  AddrL&=0XDF;      //读写操作位置0,表示写操作
 
  spi_enable();         //使能SPI口
  statuevalue=spi_write(AddrH); 
  spi_write(AddrL);
 
  spi_write(p_Data);
  
  spi_disable();      //禁止SPI口
  return statuevalue;
}

/*******************************************
*函数功能:读RAM
*输入参数:p_Data:存储数据的缓存首地址;
           Data_Num:要读取的字节数
     AddrH:在选定的RAM存储块中确定RAM地址
     AddrL:选择RAM存储块
*输出参数:无
*返 回 值:状态寄存器的值
********************************************/
unsigned char read_ram(unsigned char AddrH,unsigned char AddrL,unsigned char Data_Num,unsigned char *p_Data) 
{
  unsigned char statuevalue,i;
  AddrH|=0X80;      //访问RAM位置1
  AddrL<<=6;
  AddrL|=0X20;      //读写操作位置1,表示读操作
 
  spi_enable();         //使能SPI口
  statuevalue=spi_write(AddrH); 
  spi_write(AddrL);
 
  for (i=0;i<Data_Num;i++)
  {
    *(p_Data+i)=spi_write(0xff);
  }
 
  spi_disable();      //禁止SPI口
  return statuevalue;
}

/*******************************************
*函数功能:读一字节RAM
*输入参数:AddrH:在选定的RAM存储块中确定RAM地址
     AddrL:选择RAM存储块
*输出参数:无
*返 回 值:读取的数据值
********************************************/
unsigned char read_ram_byte(unsigned char AddrH,unsigned char AddrL)
{
  unsigned char readvalue;
  AddrH|=0X80;      //访问RAM位置1
  AddrL<<=6;
  AddrL|=0X20;      //读写操作位置1,表示读操作
 
  spi_enable();         //使能SPI口
  spi_write(AddrH); 
  spi_write(AddrL);                        
 
  readvalue=spi_write(0xff);
 
  spi_disable();      //禁止SPI口
  return readvalue;
}

/*******************************************
*函数功能:关闭电压校准器模式
*输入参数:无
*输出参数:无
*返 回 值:无
********************************************/
void power_off(void)
{
  PORTB &= ~VREGEN;     //禁止电压校准器  
}

/*******************************************
*函数功能:从电压校准器关闭模式转换到掉电模式
*输入参数:无
*输出参数:无
*返 回 值:无
********************************************/
void pwoff_pwdown(void) 
{
  PORTB |= VREGEN;     //启动电压校准器 
  delay_nus(600); 
 
  spi_enable();     //使能SPI口
  write_configure_word(MAIN,0x78,0x00);  //先将reset位设置为低 
  write_configure_word(MAIN,0xf8,0x00);  //先将reset位设置为高,完成复位过程
  spi_disable();      //禁止SPI口
 
}

/*******************************************
*函数功能:其他任何模式转换到掉电模式
*输入参数:无
*输出参数:无
*返 回 值:无
********************************************/
void allstates_pwdown(void)  
{
  write_command(SXOSCOFF);
}

/*******************************************
*函数功能:从掉电模式转换到空闲模式
*输入参数:无
*输出参数:无
*返 回 值:无
********************************************/
void pwdown_idle(void)
{
  unsigned char statue;
  write_command(SXOSCON);
 
  while(1)              //等待晶体振荡器稳定运行
  {
    statue=read_status();
    if((statue&(1<<XOSC16M_STABLE))!=0)
 {
   break;
 }
  }
}

/*******************************************
*函数功能:从其他任何模式转换到空闲模式
*输入参数:无
*输出参数:无
*返 回 值:无
********************************************/
void allstates_idle(void)  
{
  write_command(SRFOFF);
}  

/*******************************************
*函数功能:从空闲模式启动发送
*输入参数:无
*输出参数:无
*返 回 值:无
********************************************/
void idle_tx(void) 
{
  write_command(STXON);
}   

/*******************************************
*函数功能:从接收状态转换到发送模式
*输入参数:无
*输出参数:无
*返 回 值:无
********************************************/
void rx_tx(void)                    
{
  while(1)
  {
    if((PINB&CCA) != 0)      //信道空闲
    {
    write_command(STXONCCA); 
 break;
    }
  }
}

/*******************************************
*函数功能:从空闲模式启动接收模式
*输入参数:无
*输出参数:无
*返 回 值:无
********************************************/
void idle_rx(void)
{
  write_command(SRXON);
}    

/*******************************************
*函数功能:设置配置字(用于初始化)
*输入参数:无
*输出参数:无
*返 回 值:无
********************************************/
void set_configure(void)      
{
  unsigned char RegisterValueH,RegisterValueL;
  power_off();   //???????????????????????????????
  pwoff_pwdown();  //在power down模式下设置配置寄存器
 
  spi_enable();     //使能SPI口
 
  RegisterValueH=0X0A;
  RegisterValueL=0XE2;  //地址认证使能,自动应答不使能
  write_configure_word(MDMCTRL0,RegisterValueH,RegisterValueL);
 
  RegisterValueH=0X05;
  RegisterValueL=0X00;
  write_configure_word(MDMCTRL1,RegisterValueH,RegisterValueL);
 
 // RegisterValueH=-50;
 // RegisterValueL=0X00;
 // write_configure_word(RSSI,RegisterValueH,RegisterValueL); //???????????????????????调试时修改
 
  RegisterValueH=0x41;
  RegisterValueL=0X92;    //2.45GHz
  write_configure_word(FSCTRL,RegisterValueH,RegisterValueL);
 
  RegisterValueH=0x01;
  RegisterValueL=0Xe4;    //安全模式不使能
  write_configure_word(SECCTRL0,RegisterValueH,RegisterValueL);
 
  //RegisterValueH=128;
  //RegisterValueL=128;
  //write_configure_word(SECCTRL1,RegisterValueH,RegisterValueL); //???????????????????????调试时修改
 
  RegisterValueH=0;
  RegisterValueL=TX_length;  //RXFIFO的极限值
  write_configure_word(IOCFG0,RegisterValueH,RegisterValueL); //???????????????????????调试时修改
 
  spi_disable();      //禁止SPI口
}
 
/*************************************************
函数功能:初始化CC2420
输入参数:无
返回值:无
**************************************************/
void cc2420_init(void)
{
 unsigned char temp;
   
 DDRB |= SPI_MOSI | SPI_CLK | SPI_SS | VREGEN;//设置MOSI、SCK和SS 为输出,其他为输入
 DDRD |= RST;

    SPCR = (1<<SPE)|(1<<MSTR);//|(1<<SPR0);// 使能SPI,主机模式,设置时钟速率为fck/4
 //SPSR = BIT(SPI2X);     //SPI时钟加倍
    temp = SPSR; //!!! 读一次SPSR为了清除SPIF位和WCOL位
    temp = SPDR; //清空SPI,和中断标志,使SPI空闲
   
    PORTB |= CSn;                //CSN引脚置位,停止SPI操作,
 PORTB |= SCK;                // Spi clock line init high
   PORTD |= RST;                //注意该引脚低电平时,cc2420处于复位状态
   
    set_configure();
    pwdown_idle();
}
 
 
                      
  
 
 
 
                                 

原创粉丝点击