0、项目背景
基于MCU的SPI驱动CMT2300A射频收发器,实现数据的发送和接收。
1、单工模式下数据的发送与接收
(1)STM32的驱动收发芯片CMT2300A,实现数据的发送端TX:
//单工模式下,数据发送
u8 Radio_Send_FixedLen(const u8 pBuf[], u8 len)
{
u32 delay;
CMT2300A_GoStby();
CMT2300A_ClearInterruptFlags();
CMT2300A_ClearTxFifo();
CMT2300A_EnableWriteFifo(); //使能SPI写入FIFO,
CMT2300A_WriteFifo(pBuf, len); // 将pBuf中的内容,写入到CMT2300A_FIFO
CMT2300A_GoTx(); // 启动发送
delay = 1000;
while(1)
{
//查询数据是否发送完成
if(CMT2300A_ReadGpio3()) /* Read INT2, TX_DONE */
{
CMT2300A_ClearInterruptFlags();
CMT2300A_GoSleep();
return 1; //
}
if(delay==0) 发送超时溢出,防止芯片死机,客户可根据实际开发情况调整超时时间
{
RF_Init(); //初始化CMT2300A的读写寄存器
return 0; // 发送超时
}
system_delay_100us(2);
delay--;
}
}
(2)STM32的驱动收发芯片CMT2300A,实现数据的接收端RX:
//单工模式:接收数据
u8 Radio_Recv_FixedLen(u8 pBuf[],u8 len)
{
#ifdef ENABLE_ANTENNA_SWITCH
//查询一帧数据数据是否接收完成: PKT_DONE
//先查询接收一包数据是否完成,再进入接收状态
if(CMT2300A_ReadGpio2()) /* Read INT2, PKT_DONE */
{
CMT2300A_GoStby(); //进入睡眠模式
CMT2300A_ReadFifo(pBuf,len); //读FIFO中的内容
CMT2300A_ClearRxFifo(); //清除接收FIFO
CMT2300A_ClearInterruptFlags();
CMT2300A_GoRx(); //进入接收模式
return 1;
}
return 0;
}
int main(void) //单收例程
{
u8 i=0;
//CMT2300A是否存在
if(TRUE==CMT2300A_IsExist()) {
views_print_line(0, "CMT2300A ready RX");
}
while(1)
{
if(Radio_Recv_FixedLen(g_rxBuffer,RF_PACKET_SIZE))
{
g_nRfRxtimeoutCount=0; //清除 Time Out计数
g_nRecvCount++; //接收计数
for(i=0;i<RF_PACKET_SIZE;i++) //Clear Buff
g_rxBuffer[i]=0;
}
if(g_nRfRxtimeoutCount>RF_RX_TIMEOUT) //根据实际应用可以调整Time Out
{
g_nRfRxtimeoutCount=0;
CMT2300A_GoSleep();
CMT2300A_GoStby();
CMT2300A_ClearInterruptFlags();
CMT2300A_ClearRxFifo();
CMT2300A_GoRx();
}
}
}
2、半双工模式下数据的发送与接收
(1)MCU的驱动芯片CMT2300,实现数据发送:(数据发送完进入接收状态)
//半双工模式:数据发送,发送完数据后设备进入接收状态
void Radio_Send_FixedLen(const u8 pBuf[], int len)
{
u32 delay;
int sendlen = 0;
while(sendlen < len)
{
CMT2300A_GoStby();
CMT2300A_ClearInterruptFlags();
CMT2300A_ClearTxFifo();
CMT2300A_EnableWriteFifo();
//pBuf+sendlen写到CMT2300的FIFO中,一次写64byte
CMT2300A_WriteFifo(pBuf+sendlen, 64);
//进入发送状态
CMT2300A_GoTx();
delay = 1000;
while(1)
{
//发送完成标识:TX_DONE_FLG
if(CMT2300A_MASK_TX_DONE_FLG & CMT2300A_ReadReg(CMT2300A_CUS_INT_CLR1))
{
break;
}
}
}
CMT2300A_ClearTxFifo();
CMT2300A_ClearRxFifo();
CMT2300A_ClearInterruptFlags();
CMT2300A_GoStby();
CMT2300A_EnableReadFifo(); //读FIFO使能
CMT2300A_GoRx(); //发送完数据,进入接收状态
CMT2300A_DelayMs(1);
}
(2)MCU的驱动芯片CMT2300,实现数据接收:
u8 Radio_Recv_FixedLen(u8 pBuf[],u8 len)
{
if(CMT2300A_MASK_PKT_OK_FLG & CMT2300A_ReadReg(CMT2300A_CUS_INT_FLAG))
{
CMT2300A_GoStby();
CMT2300A_ReadFifo(pBuf,len);//读FIFO中的数据,接收到的数据先存储在FIFO中
CMT2300A_ClearRxFifo();
CMT2300A_ClearInterruptFlags();
CMT2300A_EnableReadFifo();
CMT2300A_GoRx(); //进入接收状态
return 1;
}
return 0;
}
(3)两个设备之间进行半双工通信,主发,从收
主机发送数据,发送完成后,进入接收状态
从机接收主机发送的数据后,自己发送数据,发送数据完成后,进入接收状态
int32_t main(void)
{
while (1)
{
if(timer1ms >= 1000)
{
//主机模式:发送
if(MorS == MASTER)
{
for(i = 0; i < RF_PACKET_SIZE; i++)
{
//UART串口发送数据:u_txBuffer[i]
Uart_SendDataPoll(M0P_UART1,u_txBuffer[i]);
}
if(IsExist_2300a)
{
//2300发送数据
Radio_Send_FixedLen(g_txBuffer,FIFO_DEPTH);
}
}
}
//从机模式:接收
//从机接收完主机发送的数据,自己再发送数据,发送数据完成后,进入接收状态
if(IsExist_2300a)
{
//判断数据接收完成,再发送数据
if(Radio_Recv_FixedLen(g_rxBuffer,FIFO_DEPTH))
{
if(MorS == SLAVE)//从机模式
{
//把2300接收到数据,复制到串口的发送缓存区
//u_txBuffer <== g_rxBuffer
memcpy(u_txBuffer,g_rxBuffer+2,FIFO_DEPTH-2);
//发送数据
Radio_Send_FixedLen(g_txBuffer,RF_PACKET_SIZE);
}
if(r_rf_frameindex < (RF_PACKET_SIZE / FIFO_DEPTH))
r_rf_frameindex++;
}
//最后进入接收状态
if(g_nRfRxtimeoutCount>RF_RX_TIMEOUT0)
{
g_nRfRxtimeoutCount=0;
CMT2300A_GoSleep();
CMT2300A_GoStby();
CMT2300A_ClearInterruptFlags();
CMT2300A_ClearRxFifo();
CMT2300A_GoRx();
}
}
}
}
|