⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 spi_test.c

📁 以MSP430F149为核
💻 C
字号:
#include"msp430x14x.h"
#include"mc13192.h"
#include"pub_def.h"
#include"port.h"
#define CE_HIGHT  P4OUT|=0x04;
#define CE_LOW P4OUT&=0xFB;
typedef struct{
        char MaxDatalength;
        char datalength;
        char *data;
} tTxpacket;
typedef struct{
  char datalength;
  char *data;
}tRxpacket;
int i;
char workmode;
char mc13192_softreset(void);
char get_rficversion(void);
char datarequest(tTxpacket *txpacket);
void RAMdrvwritetx(tTxpacket *txpkt);
void RAMdrvreadrx(tRxpacket *rxpkt)
void SPI_Init();
unsigned char spi_send(unsigned char num);
void spidrvwrite(char addr,int content);
unsigned int spidrvread(char addr);
unsigned char spi_send(unsigned char num);
char setchannel(char channel);
void mcu_init();
void mc13192_init();
void wait(unsigned int timeout);
void GPIO_init();
void IRQInit(void);
void disableinterrupt();
void  enableinterrupt();
char mc13912_paoutputadjust(char value);
void putchar(char c);
void put16int(int i);
void uart_printf(char *s);
void main(void)
{
  tRxpacket tx_packet;
  char rx_data_buffer[];
  WDTCTL = WDTPW + WDTHOLD;
  // int temp1;
   //初始化发送包
  // int reg;
   rx_packet.datalength=0;
   rx_packet.data=&rx_data_buffer[0];

   mcu_init();
   mc13192_init();
   setchannel(0);
   SPI_Init();
   IRQInit();
   //mc13912_paoutputadjust(100);
   mc13912_paoutputadjust(MAX_POWER);
   //_EINT;//打开全局中断
    enableinterrupt();//打开p2.7外部中断
    int reg;



}
///////////////////////////////////////////////////
//                   SPI初始化              //////
/////////////////////////////////////////////////
void SPI_Init()
{
  P3SEL |= BIT1 + BIT2 + BIT3;//P3用于SPI模式
  U0CTL |= CHAR + SYNC + MM +SWRST;//8位SPI,主模式
  //U0TCTL |= CKPL +SSEL0 + STC;//时钟极性,UCLK,3线
  U0TCTL |=  SSEL0 + STC;
  ME1 |= USPIE0;//模块使能
  UBR00=0x80;
  UBR10=0x00;
  UMCTL0=0x00;
  IE1 &= ~URXIE0;//禁止接受中断
  IE1 &= ~UTXIE0;//禁止发送中断
  U0CTL &= ~SWRST;//使能SPI
}
/////////////////////////////////////////////////////////////
/////从SPI口发送一个数据并从接收缓冲中返回一个值////////////
////////////////////////////////////////////////////////////
unsigned char spi_send(unsigned char num)
{
  unsigned char i;
  TXBUF0=num;
  while( ((IFG1 & UTXIFG0)==0)||((IFG1 & URXIFG0)==0));
  //i=TXBUF0;
  i=RXBUF0;
  return i;
}
/*
对MC13192的寄存器的写操作。一帧命令为24位,在高8位中,最高位设位0,次高位设为0,低
6位位对象寄存器的地址,低16位为寄存器的赋值
*/
void spidrvwrite(char addr,int content)
{
  CE_LOW;
  spi_send(addr & 0x3F);//取低6位地址,高二位为0;
  spi_send(content>>8);//发送高8位
  spi_send((char)content&0x00FF);//发送低8位
  P5OUT|=0x70;
  CE_HIGHT;
}
/*
对MC13192寄存器的读操作。一帧命令位24位,最高位设位1,次高位设为0
低6位为寄存器的地址,低16位为对象寄存器的现有值。
*/
unsigned int spidrvread(char addr)
{
  unsigned int i;
  unsigned int k;
  CE_LOW;
  spi_send(addr & 0x3f | 0x80);//最高位1,次高位为0,低6位为地址
  i=spi_send(0x00);
  k=(i<<8)& 0xff00;
  i=spi_send(0x00);
  k=k|i;
  CE_HIGHT;
  return k;
}
//////////////////////////////////////////////////////////////////////////////////////////
//向MC13192传输准备发送的数据。此项操作分为两步:先向MC13192的TX_PKT_CTL寄存器(0x03)的///
//低7位写入需要传输的数据长度,MC13912一次最多可以传输125Byte的数据,然后先向MC13192的///
//TX_PKT_RAM寄存器(0X02)发送起始命令,//////////////////////////////////////////////////
//然后依次写入准备发送的数据。///////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////
void RAMdrvwritetx(tTxpacket *txpkt)
{
  unsigned int reg;
    unsigned char tempvalue;
    reg=spidrvread(0x03);//数据长度寄存器 TX_PKT_LEN;BIT6~0
    reg=(0xff80 & reg)|(txpkt->datalength+2);
    spidrvwrite(0x03,reg);
    CE_LOW;
    spi_send(0x02);//先发送6位地址0x02;0000 0010;
    tempvalue=0;
    for(int i=0;i<(txpkt->datalength);i++)
    {
      spi_send(txpkt->data[tempvalue+1]);  //写高字节
      spi_send(txpkt->data[tempvalue]);
      tempvalue+=2;//write LSB
    }
               CE_HIGHT
}
/*
接收MC13192已经收到的数据,与传输要发送的数据相似,先从MC13192的rx_status寄存器(0x2d)的低
7位读取接收到的数据长度;然后向MC13192的rx_pkt_ram的寄存器(0x01)依次读取接收到数据。
*/
void RAMdrvreadrx(tRxpacket *rxpkt)
{
  unsigned int rxlength;
  char tempvalue;
  rxlength=spidrvread(0x2D);//读0x2D寄存器获取数据长度
  rxlength &=0x007f;
  if (rxlength>2)
  {
    rxpkt->datalength=rxlength-2;
  }
  else
  {
    rxpkt->datalength=0;
  }
  if ((rxpkt->datalength>=1)&&(rxpkt->datalength<=125))
  {
    CE_LOW;
    spi_send(RX_PKT |80);//读
    spi_send(0x00);//garbge
    spi_send(0x00);//garbge

  }
  tempvalue=0;
  for(int i=0;i<rxlength;i++)
  {
    rxpkt->data[tempvalue+1]=spi_send(0x00);//read msb
    rxpkt->data[tempvalue]=spi_send(0x00);//read lsb
    tempvalue=tempvalue+2;
    }
  CE_HIGHT;
}
 /*
  功能:发送一个数据包
  参数:psPacket 发送数据的指针
  返回值:  SUCCESS
 */
char datarequest(tTxpacket *txpacket)//发送数据
{
   int reg;
   RAMdrvwritetx(txpacket); //必须在idle或工作模式下
   reg = spidrvread(MODE_ADDR);
   reg |= 0x03;//发送模式
   reg|=BIT9;//enable an interrupt request when the TX Packet has been sent
   spidrvwrite(MODE_ADDR, reg);//使接收机处于发送状态
   P5OUT|=BIT0;//发送势能
   return 1;
}
 /*
       功能:该函数对MC13192进行了软件复位
       参数:无
       返回值:SUCCESS
 */
char mc13192_softreset(void)
{
  spidrvwrite(RESET,0x00);
  return 1;
}
 /*
       功能:该函数用来读取MC13192的版本号
       参数:无
     返回值:8位两进制数值表示MC13192版本
   */
char get_rficversion(void)
{
  int reg;
  reg=spidrvread(VERSION_REG);
  reg&=VERSION_MASK;
  reg=reg>>10;
  return (char)reg;
}
 /*

   函数功能:设置通信信道,只有在同一信道的无线信号才能正确的收发。
       参数:信道参数:0~16
     返回值: SUCCESS,0x0F,0x10两个寄存器决定通信信道,具体寄存器赋值查阅手册4-21

 */
char setchannel(char channel)
{
  switch(channel)
  {
  case 0x00:                      //0信道
  spidrvwrite(LO1_IDIV_ADDR,0x0f95);
  spidrvwrite(LO1_NUM_ADDR,0x5000);
  break;
  case 0x01:                      //1信道
  spidrvwrite(LO1_IDIV_ADDR,0x0f95);
  spidrvwrite(LO1_NUM_ADDR,0xA000);
  break;
  case 0x02:                      //2信道
  spidrvwrite(LO1_IDIV_ADDR,0x0f95);
  spidrvwrite(LO1_NUM_ADDR,0xF000);
  break;
  case 0x03:                      //3信道
  spidrvwrite(LO1_IDIV_ADDR,0x0f96);
  spidrvwrite(LO1_NUM_ADDR,0x4000);
  break;
  case 0x04:                      //4信道
  spidrvwrite(LO1_IDIV_ADDR,0x0f96);
  spidrvwrite(LO1_NUM_ADDR,0x9000);
  break;
  case 0x05:                      //5信道
  spidrvwrite(LO1_IDIV_ADDR,0x0f96);
  spidrvwrite(LO1_NUM_ADDR,0xE000);
  break;
  case 0x06:                      //6信道
  spidrvwrite(LO1_IDIV_ADDR,0x0f97);
  spidrvwrite(LO1_NUM_ADDR,0x3000);
  break;
  case 0x07:                      //7信道
  spidrvwrite(LO1_IDIV_ADDR,0x0f97);
  spidrvwrite(LO1_NUM_ADDR,0x8000);
  break;
  case 0x08:                      //8信道
  spidrvwrite(LO1_IDIV_ADDR,0x0f97);
  spidrvwrite(LO1_NUM_ADDR,0xD000);
  break;
  case 0x09:                      //9信道
  spidrvwrite(LO1_IDIV_ADDR,0x0f98);
  spidrvwrite(LO1_NUM_ADDR,0x2000);
  break;
  case 0x0A:                      //A信道
  spidrvwrite(LO1_IDIV_ADDR,0x0f98);
  spidrvwrite(LO1_NUM_ADDR,0x7000);
  break;
  case 0x0B:                      //B信道
  spidrvwrite(LO1_IDIV_ADDR,0x0f98);
  spidrvwrite(LO1_NUM_ADDR,0xC000);
  break;
  case 0x0C:                      //C信道
  spidrvwrite(LO1_IDIV_ADDR,0x0f99);
  spidrvwrite(LO1_NUM_ADDR,0x1000);
  break;
  case 0x0D:                      //D信道
  spidrvwrite(LO1_IDIV_ADDR,0x0f99);
  spidrvwrite(LO1_NUM_ADDR,0x6000);
  break;
  case 0x0E:                      //E信道
  spidrvwrite(LO1_IDIV_ADDR,0x0f99);
  spidrvwrite(LO1_NUM_ADDR,0xB000);
  break;
  case 0x0F:                      //F信道
  spidrvwrite(LO1_IDIV_ADDR,0x0f9A);
  spidrvwrite(LO1_NUM_ADDR,0x0000);
  break;
  default:                    //8信道
  spidrvwrite(LO1_IDIV_ADDR,0x0f97);
  spidrvwrite(LO1_NUM_ADDR,0xD000);
  return 0;
  }
  return 1;
}
void mcu_init()
{
   workmode=RESET_DELAY;
   wait(5000);
   workmode=SYSTEM_RESET_MODE;
   GPIO_init();
   SPI_Init();
   IRQInit();
   workmode=MC13192_RESET_MODE;
   P5OUT|=BIT1;//RESET=1;
}
/*
 对MC13192进行初始化,初始化后,MC13192进入IDLE状态
*/
void mc13192_init()
{
  spidrvwrite(0x11,0x80FF);//Eliminate unclock conditions due to L01;
  spidrvwrite(0x1B,0x8000);//disable tc1;
  spidrvwrite(0x1D,0x8000);//disable tc2;
  spidrvwrite(0x1F,0x8000);//disable tc3;
  spidrvwrite(0x21,0x8000);//disable tc4;
  spidrvwrite(0x07,0x0E00);//EABLE CLK0 IN DOZE;
  spidrvwrite(0x0c,0x0300);//IRQ pullup disable
  spidrvread(0x25);//set the reset indicatin bit
  spidrvwrite(0x04,0xA08D);//neW cal value;
  spidrvwrite(0x08,0xFFF7);//prefered injection
  spidrvwrite(0x05,0x8351);//acoma tc1,doze ATTN MASKS LO1,CRC
  spidrvwrite(0x06,0x4720);//CCA,TX,RX,energy detect;
  workmode=IDLE_MODE;
}
void wait(unsigned int timeout)
{
	while (--timeout);
}
void IRQInit(void)
{
  P2DIR&=~BIT7;//方向,输入
  P2IES|=BIT7;//中断触发方式,下降沿使相应标志位置位。
  P2IE&=~BIT7;//禁止中断
}
void disableinterrupt()
{
  P2IE&=~BIT7;//禁止中断
}
void  enableinterrupt()
{
  P2IE|=BIT7;
}
char mc13912_paoutputadjust(char value)
{
  int reg;
  char pavalue;
  switch(value)
  {
  case MAX_POWER:
       pavalue=0xff;
  break;
  case MIN_POWER:
       pavalue=0x00;
   break;
  default:
    if (value>15)
    {
      return 0;
    }
    else
    {
      pavalue=value;
    }
    break;
  }
  reg=spidrvread(PA_ADJUST_ADDR);//读寄存器0x12.
  reg&=0xff00;
  if((value==MAX_POWER)||(value==MIN_POWER))
  {
    reg|=pavalue;
  }
  else
  {
    reg|=((pavalue<<4)|0x000C);
  }
    spidrvwrite(PA_ADJUST_ADDR,reg);
     return 1;

}
void putchar(char c)
{
   WDTCTL = WDTPW + WDTHOLD;                 // Stop WDT
  P3SEL |= 0xC0;                            // P3.6,7 = USART1 TXD/RXD
  ME2 |= UTXE1+URXE1;                     // Enable USART1 TXD/RXD
  UCTL1 |= CHAR;                            // 8-bit character
  UTCTL1 |= SSEL0;                          // UCLK = ACLK
  UBR01 = 0x03;                             // 32k/9600 - 3.41
  UBR11 = 0x00;                             //
  UMCTL1 = 0x4A;                            // Modulation
  UCTL1 &= ~SWRST;                          // Initialize USART state machine
  while(!(IFG2&UTXIFG1));
  TXBUF1=c;
}
void put16int(int i)
{
  char c;
  c=i>>8;
  putchar(c);
  putchar((char)i);
}
void uart_printf(char *s)
{
  while(*s)
  {
    if (*s=='\n')
        putchar('\r');
        putchar(*s);
              s++;
  }
}
#pragma vector=PORT2_VECTOR
 __interrupt void port2(void)
   {

    unsigned int reg;

     P2IE&=~BIT7;//禁止中断
     if((P2IFG& BIT7==BIT7))//管脚2。7发生中断。
     {
      P2IFG&=~BIT7;
       reg=spidrvread(0x24);//读状态寄存器。
       if (reg&0x0040==1)
       {
         P5OUT^=BIT4+BIT5+BIT6;
       }
       reg&=~BIT6;
       spidrvwrite(0x24,reg);
       P2DIR|=BIT7;
       P2OUT|=BIT7;
       IRQInit();
     }
     P2IE|=BIT7;
   }

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -