原创 cc1020项目部分代码(整理)

2009-9-21 19:48 3005 5 6 分类: MCU/ 嵌入式

SPI 读写函数:
每次对CC1020 的读写操作都包含7 位地址位(A6:A0)、1 位写操作位(写为高)、一字节数据,写操作前必须先让PSEL 使能有效(低有效)。在PCLK 的上升沿,先发送地址MSB 位(A6)。
/**********************************************************
**************************
函数功能:写一字节数据到CC1020
入口参数:val:要写入的数据
出口参数:无
备注 : 无
***********************************************************
**************************/
void WriteCC1020(char val)
{
char BitCounter;
for (BitCounter=8;BitCounter!=0;BitCounter--)
{
PCLK_LOW;
PDI_LOW;
if(val&0x80)
PDI_HIGH;
val<<=1;
PCLK_HIGH;
}
PCLK_LOW;
}
/**********************************************************
**************************
函数功能:写CC1020 寄存器值
入口参数:addr:寄存器地址 data:写入数据
出口参数:无
备注 : 无
***********************************************************
**************************/
void WriteToCC1020Register(char addr, char data)
{
PSEL_LOW;
WriteCC1020((addr<<1)|0x01); //写数最低位是1
WriteCC1020(data);
PSEL_HIGH;
}
SPI 读操作:
PCLK 的上升沿,先发送读寄存器的地址MSB 位,地址发送结束后发送写操作位(写操作为低),之后在PCLK 的下降沿把寄存器值所存到单片机。
/**********************************************************
**************************
函数功能:读cc1020 寄存器值
入口参数:addr:寄存器地址
出口参数:返回寄存器内容
备注 : 无
***********************************************************
**************************/
char ReadFromCC1020Register(char addr)
{
char BitCounter;
char Byte;
PSEL_LOW; // Send address bits
WriteCC1020(addr<<1);  //CC1020 读操作 发送7Bit 地址 1Bit R/W 0-W,位移后最低位一定是0。
for(BitCounter=8;BitCounter!=0;BitCounter--)
{
PCLK_HIGH;
Byte<<=1;
if(PDO_IN)
Byte|=1;
PCLK_LOW;
}
PSEL_HIGH;
return Byte;
}
程序设计采用状态机切换方式,主程序处理发送缓冲区数据及把从cc1020 接收到接收缓冲区的数据通过UART 发送到PC 机显示。当没有按键触发发送数据及接收缓冲区为空的时候状态机处于IDLE_STATE 状态,模块不断检测数据包前导码,如果检测到正确的前导码及一字节同步字,状态切换到RX_STATE 接收同步字、地址、数据包长度、数据。如果有按键触发,主程序初始化发送缓冲区数据
包长度及装载发送数据,切换到TX_STATE 发送数据包数据,先发送前导码。


维护状态函数:
/**********************************************************
************
函数功能:维护状态
入口参数:无
出口参数:无
备注 :空闲状态下CC1020 为接收模式,通过中断查询前导码
***********************************************************
***********/
void ChangeState(void)
{
switch(NextState) //下一个状态
{
case RX_STATE: //下一状态为接收
if(State==TX_STATE) //当前为发送
{
/* MSP430 calls */
TI_CC_DCLK_PxIES &= ~DCLK; // Int on raising edge
TI_CC_DIO_PxDIR &= ~DIO; // Set DIO as input
SetupCC1020RX(RXANALOG, PA_POWER); //发送到接收模式切换
}
State=RX_STATE; //接收状态
BitCounter =0; //位计数器清零
ByteCounter=0; //字计数器清零
break;
case TX_STATE: //下一个状态为发送状态
if(State!=TX_STATE) //当前不是发送状态
{
TI_CC_DCLK_PxIES |= DCLK; //INT on falling edge
TI_CC_DIO_PxDIR |= DIO; // Set DIO as output
SetupCC1020TX(TXANALOG, PA_POWER); //从接收到发送切换
}
State=TX_STATE; //状态为发送
BytesToSend=TXBufferIndex; // Number of bytes to send 发送字节数 包含 Preable 和Header
TXBuffer[PreambleLength+3]=BytesToSend-HEADER_SIZE-Preamble Length; //装载数据长度
LastDataBit = FALSE; //标志清零
TXBufferIndex=0; //发送索引清零
BitCounter=0; //位计数器清零
ShiftReg=TXBuffer[TXBufferIndex++]; // 装载发送数据 装载第一个发送数据
printfch(ShiftReg);/////////////////
break;
case IDLE_STATE: //下一状态为空闲
if(State==TX_STATE)
{ // 当前状态为发送
TI_CC_DCLK_PxIES &= ~DCLK; // Int on raising edge
TI_CC_DIO_PxDIR &= ~DIO; // Set DIO as input
SetupCC1020RX(RXANALOG, PA_POWER); // 从发送到接收切换
}
State=IDLE_STATE; //当前状态为空闲
//空闲状态初始化发送缓冲区下标
TXBufferIndex=HEADER_SIZE+PreambleLength;
PreambleCount=0;
PreambleError=0;
PreambleFound=FALSE; // Preamble 头标志清零
UI1Found=FALSE; // UI1 标志清零
break;
}
}
CC1020 和单片机的通信采用中断方式,在DLCK 产生的中断函数中通过DIO 完成通信。定义了一个字节的移位寄存器共用体:
// Union for shifting bits in or out of the CC1020 union
{
char ShiftReg; //发送,接收字节
struct {
unsigned char ShiftRegLSB :1;
unsigned char :1;
unsigned char :1;
unsigned char :1;
unsigned char :1;
unsigned char :1;
unsigned char :1;
unsigned char ShiftRegMSB :1;
};
};
中断接收及发送函数:
/**********************************************************
**************************
函数功能:CC1020 收发数据中断处理
入口参数:无
出口参数:无
备注 : 空闲状态下先接收前导码
***********************************************************
**************************/
#pragma vector="PORT1"_VECTOR
__interrupt void PORT1_ISR(void)
{
// This function must execute as fast as possible.
// Therefore, as much processing as possible is left  to the main program.

switch (State)
{
case TX_STATE:
// Write data to CC1020
//DIO=ShiftRegMSB;
if (ShiftRegMSB) // MCU 发送数据到 CC1020
TI_CC_DIO_PxOUT |= DIO;
else
TI_CC_DIO_PxOUT &= ~ DIO;
ShiftReg=ShiftReg<<1;
BitCounter++;
// If last data bit has been sent
if(LastDataBit) //是否是最后一个数据
{
// Remain in TX until last data bit has been sent on
RF:
if(BitCounter > RFPACKET_EXTENSION) // 发送最后RFPACKET_EXTENSION bit 位 保持输出功率
{
BitCounter = 0;
TXBufferIndex = 0;
LastDataBit = FALSE;
NextState=IDLE_STATE;
break;
}
else
{ }
// Else (not last data bit)
}
else
{
// Load new TX data and monitor end of packet //装载新的发送数据 并检测是不是最后一个数据
if(BitCounter==1)
{
if(TXBufferIndex>BytesToSend) //是否发完最后一个发送数据
{
BitCounter = 0;
LastDataBit = TRUE; //最后字节数据标志
ShiftReg = 0x00;  //发送完数据 发送0x00 作为结束标志
}
}
//发完一个字节
if(BitCounter==8)
{
BitCounter=0;
ShiftReg=TXBuffer[TXBufferIndex++];
}
}
break;
case RX_STATE:
// Read data from CC1020
ShiftReg=ShiftReg<<1;
ShiftRegLSB= ((TI_CC_DIO_PxIN & DIO)>>1); // Low-side
LO (DIO not inverted) //移位到最后一位
BitCounter++;
// If received 8bits=1byte
if(BitCounter==8) //接收到一个字节
{
BitCounter=0;
// Process received RF data:
switch(ByteCounter)
{
// Byte-0 = SOF part 1:
case 0 :
if(ShiftReg!=UI2) //UI2 接收不正确回到空闲状态
{
NextState=IDLE_STATE;
}
break;
// Byte-1 = address:
case 1 : //接收到地址字节
// Addressing not implemented
break;
// Byte-2 = packet length/size:
case 2 : //数据包长度
BytesToReceive=ShiftReg; //为长度减1
if(BytesToReceive>TX_BUFFER_SIZE) //接收到的数据长度大于 缓冲区长度
{
BytesToReceive=0;
}
break;
// Rest of the packet is data, store it in the receive buffer default :
RXBuffer[RXBufferWriteIndex]=ShiftReg;
//存入缓冲区
//RXBufferWriteIndex=(RXBufferWriteIndex+1)%RX_BUFFER_SIZE;
RXBufferWriteIndex++;
RXBufferWriteIndex&=0x3F;
break;
}
if(ByteCounter>=BytesToReceive+2) //如果接收数据包完成
{
NextState=IDLE_STATE; //转到空闲状态
}
ByteCounter++;
}
break;
case IDLE_STATE: //
// Read data from CC1020
ShiftReg=ShiftReg<<1; //空闲状态小 从读CC1020 数据
//ShiftRegLSB=DIO; // Low-side LO (DIO not inverted)
ShiftRegLSB= ((TI_CC_DIO_PxIN & DIO)>>1); //读DIO P2.4
BitCounter++;
// If preamble found, look for Start Of Frame (SOF)
if(PreambleFound) //前导标志置1 受到有效前导
{
// If first unique identifier found,
enter RX mode
if(ShiftReg==UI1) //UI1 被找到
{
// Initialise RX processing state directly:
// Avoid latency with background scheduler.
BitCounter=0; //
ByteCounter=0;
State = RX_STATE; //收到一个则进入接收状态
NextState=RX_STATE;
// Else if we are still receiving preamble, do nothing
} //没有正确收到 UI1
else
if((ShiftReg==VALID_PREAMBLE_BYTE_1)||(ShiftReg==VALID_PREA
MBLE_BYTE_2)) //如果仍然在收到前导 什么都不做
{
// Else if we are not receiving a correct preamble, declare
an error
}else if(PreambleError==0) //否则前导错误
{
PreambleError++; //前导错误变量加1
}else
{
}
// If preamble error found, increase the error counter
regardless of bits read
if(PreambleError>0)
{ //前导错误变量加 1
PreambleError++;
}
// Once an error condition has occurred, a correct SOF must be
found
// within 9 bits (error counter is initially incremented by 2),
otherwise
// we abort and start looking for preamble again
if(PreambleError>10) //如果大于10
{
PreambleFound=FALSE; //前导错误标志 复位
}
// Else (preamble has not been found) //前导标志没有置位
}else
{ //从CC1020 读取值 首先读取前导
// If valid preamble, increase counter
if(ShiftReg==VALID_PREAMBLE_BYTE_1)||(ShiftReg==VALID_PREAM
BLE_BYTE_2)) //如果读取到有效的 Preamble
{
PreambleCount++; // 读到前导 Preamble 加1
// Else (not valid preamble), reset counter
}else
{
PreambleCount=0; //如果收到有一次错误Preamble 则 前导码计数器清零
}
// If required preamble reached, indicate preamble found
if(PreambleCount>=PREAMBLE_REQ) // 指示 Preamble 找到
{
PreambleFound=TRUE; //置位前导标志
PreambleError=0;
}
//printfch(PreambleCount);
}
break;
default:
// Enter known state in case something goes haywire
NextState=IDLE_STATE;
break;
}
//INTF=0;
TI_CC_DCLK_PxIFG &= ~DCLK; // Clear flag
}

PARTNER CONTENT

文章评论1条评论)

登录后参与讨论

用户951650 2011-9-8 10:07

深圳市亿威盛世科技有限公司 TI德州仪器芯片专卖 无线收发射频芯片优势。 ?:0755-36931959。QQ:280972937 电话:13480930731.刘'R. CC1000PWR CC2520RHDR MSP430FW427IPMR CC1020RUZR CC2530F128RHAR MSP430F149IPMR CC1021RSSR CC2530F256RHAR MSP430F1612IPMR CC1070RSQR CC2530F32RHAR MSP430F2121IPWR CC1070RSQR CC2531F256RHAR MSP430F2274IDAR CC1100ERTKR CC2550RSTR MSP430F235TPMR CC1100RTKR CC2590RGVT MSP430F247TPMR CC1101RTKR CC2591RGVT MSP430F417IPMR CC1150RSTR CC2500RTKR MSP430FW427IPMR CC2400RSUR CC2510F32RSPR MSP430F5438IPZR CC2420RTCR CC2511F16RSPR CC2430ZF128RTCR 原装 UC3846DWTR 正品 UC3846N 优势现货
相关推荐阅读
用户1482397 2009-11-06 15:02
曼彻斯特和差分曼彻斯特编码的实现
 //----------------------------------------------------------------------------     |//  标题: 曼彻斯特和差分...
用户1482397 2009-09-29 15:03
基于ZigBee协议的无线传感器网络设计
 引 言              传感器作为人们感官的延伸,在现代社会中得到了越来越广泛的应用。随着通信技术、嵌入式技术、传感器技术的发展,             传感器正逐渐向智能化、微型化、无...
用户1482397 2009-09-28 10:31
MSP430单片机的框架程序(转)
MSP430单片机的框架程序(转)下面给出MSP430的程序框架,我们可以在此基础上修改以及添加自己所需的程序。/*******************************************...
用户1482397 2009-09-23 11:00
利用USART实现单片机与串口通信[C语言]
利用USART实现单片机与串口通信[C语言]//实验目的:熟悉USART通信//通过“串口调试助手”协助工作//串口调试助手发送数据给877,877收到后再转发回串口助手//硬件要求:拨码开关S7全置...
用户1482397 2009-09-23 10:51
at89c2051制作的超声波测距源程序
#include <REG2051.H>#define k1 P3_4#define csbout    P3_5                  //超声波发送#define csbi...
用户1482397 2009-09-23 10:37
定时器程序
 #include <REGX52.H>     //AT89S52头文件#define uint unsigned int#define uchar unsigned charuchar...
我要评论
1
5
关闭 站长推荐上一条 /3 下一条