📄 spi_test.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 + -