怀揣少年梦 发表于 2021-2-24 16:56

【AT32-START-407测评】+无线通信模块SI24R1测试

本帖最后由 怀揣少年梦 于 2021-3-10 19:45 编辑

一、背景:因之前在搞小四轴,一直卡在无线模块,后来买了两个模块来测试自己的程序,是否是正确的。正好此时申请到AT32开发板,过年一直在测试。现发出来给大家参考或者指教一下。
二、模块是安信可的2.4GHz si24r1无线通信模块。
三、测试过程:用户按键按一下,实现发送与接收。开机第一次能正常收发,第二次再按就只会产生发送完成中断。再按就产生重发次数中断。断电再按键就会收发成功。过了几天才发现问题,原来没有清理状态寄存器里的status.清理就可以了。
四、程序:
1)主程序
上传不了。会乱码
2)中断程序
void EXTI9_5_IRQHandler(void)
{
      u8 state;
      if(EXTI_GetFlagStatus(EXTI_Line9) != RESET)
      {
                EXTI_ClearIntPendingBit(EXTI_Line9);
                SI24R1_CE_Low;
                state = SI24R1_Read_Reg(R_REGISTER+STATUS);
                /* 发送完成中断*/
                if(state & TX_DS)
                {
                        TX_Flag=true;
                        SI24R1_Set_Mode(IT_RX);
                        SI24R1_Write_Reg(R_REGISTER+STATUS,TX_DS);
                        SI24R1_Write_Reg(FLUSH_TX,0xff);      3)配置程序(两个模块配置一模一样,只是用的SPI不一样)
#include "si24r1.h"
#include "systick.h"
#include "stdio.h"
#include "stdlib.h"
#define SI24R1AddrMAX 50                                                //SI24R1最后一个字节地址最大为50
u8 SI24R1addr = 0xFF;                                                                        //初始化SI24R1最后一个字节地址
u8 SI24R1_TX_DATA={0}      ;      //SI24R1发送缓冲区
u8 SI24R1_RX_DATA={0}      ;      //SI24R1接收缓冲区

u8 TX_ADDRESS= {0x34,0x43,0x10,0x10,0x01};//发送地址
u8 RX_ADDRESS= {0x34,0x43,0x10,0x10,0x01};//接收地址

/****************************************************************************
* 名      称:void SI24R1_Init(void)      
* 功      能:SI24R1初始化及检查通信
* 入口参数:无
* 出口参数:无
* 说      明:SI24R1spi最大速度不超过10Mbps
****************************************************************************/
void SI24R1_Init(void)
{
      SI24R1_GPIO_Init();      //初始化管脚
      SI24R1_SPI_Init();      //                初始化SPI2
      SI24R1_CSN_High;                        //片选信号失能
      
      SI24R1_CE_Low;                              //待机模式
      
}

/****************************************************************************
* 名      称:void SI24R1_GPIO_Init(void)      
* 功      能:配置在SI24R1与stm32间spi通信的引脚及控制SI24R1的引脚
* 入口参数:无
* 出口参数:无
* 说      明:SI24R1spi最大速度不超过10Mbps
****************************************************************************/
void SI24R1_GPIO_Init(void)
{
      GPIO_InitType GPIO_InitStructure;
      
      RCC_APB2PeriphClockCmd(RCC_APB2PERIPH_GPIOB | RCC_APB2PERIPH_GPIOD |RCC_APB2PERIPH_AFIO,ENABLE);
      
      //PB13 SCLK;PB14 MISO;PB15MOSI
      GPIO_InitStructure.GPIO_Pins = GPIO_Pins_13 | GPIO_Pins_14 | GPIO_Pins_15;
      GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
      GPIO_InitStructure.GPIO_MaxSpeed = GPIO_MaxSpeed_10MHz;                                                                                                //si24r1 最大读写速度为10M
GPIO_Init(GPIOB,&GPIO_InitStructure);

//CSN 片选管脚
      GPIO_InitStructure.GPIO_Pins = GPIO_Pins_12;
      GPIO_InitStructure.GPIO_Mode = GPIO_Mode_OUT_PP;
      GPIO_InitStructure.GPIO_MaxSpeed = GPIO_MaxSpeed_10MHz;                                                                                                //si24r1 最大读写速度为10M
GPIO_Init(GPIOB,&GPIO_InitStructure);
GPIO_ResetBits(GPIOB,GPIO_Pins_12);
//CE 使能管脚
      GPIO_InitStructure.GPIO_Pins = GPIO_Pins_8;
      GPIO_InitStructure.GPIO_Mode = GPIO_Mode_OUT_PP;
      GPIO_InitStructure.GPIO_MaxSpeed = GPIO_MaxSpeed_10MHz;                                                                                                
GPIO_Init(GPIOD,&GPIO_InitStructure);         
      GPIO_ResetBits(GPIOD,GPIO_Pins_8);
      

}

/****************************************************************************
* 名      称:void SI24R1_SPI_Init(void)      
* 功      能:配置在SI24R1与stm32间spi通信的初始化
* 入口参数:无
* 出口参数:无
* 说      明:SI24R1spi最大速度不超过10Mbps
****************************************************************************/
void SI24R1_SPI_Init(void)
{

      SPI_InitType SPI_InitStructure;
      
      RCC_APB1PeriphClockCmd(RCC_APB1PERIPH_SPI2,ENABLE);
      
      //配置SPI1相关参数:全双工通信、MSB/LSB、通信速度、工作模式(mode0~mode3)......
      SPI_InitStructure.SPI_TransMode = SPI_TRANSMODE_FULLDUPLEX;                //全双工通信
      SPI_InitStructure.SPI_Mode = SPI_MODE_MASTER;                                                                                                      //主机角色
      SPI_InitStructure.SPI_FrameSize =SPI_FRAMESIZE_8BIT;                                 //看时序图,8位数据位
      SPI_InitStructure.SPI_CPOL = SPI_CPOL_LOW;                                                                                                                //时钟线空闲的时候是什么电平,当前配置为低电平
      SPI_InitStructure.SPI_CPHA = SPI_CPHA_1EDGE;                        //主机在时钟线哪一个时刻读取MISO引脚的电平,在时钟第一个边沿来采集数据
      SPI_InitStructure.SPI_NSSSEL = SPI_NSSSEL_SOFT;                                                                                                                        //片选需要代码控制
      SPI_InitStructure.SPI_MCLKP = SPI_MCLKP_32;                //SPI1的通信硬件时钟=72MHz/8=9MHz    SI24R1最大为10M
      SPI_InitStructure.SPI_FirstBit = SPI_FIRSTBIT_MSB;                                                                              //最高有效位优先传输
      SPI_InitStructure.SPI_CPOLY = 7;
      SPI_Init(SPI2,&SPI_InitStructure);
      
      
      SPI_Enable(SPI2,ENABLE);

}

/****************************************************************************
* 名      称:u8 SPI2_WriteReadByte(u8 Data)      
* 功      能:SPI2读写一个字节
* 入口参数:无
* 出口参数:无
* 说      明:无
****************************************************************************/
u8 SPI2_WriteReadByte(u8 Data)
{
      u8 cnt = 0;
      while(SPI_I2S_GetFlagStatus(SPI2,SPI_I2S_FLAG_TE) == RESET)      //等待发送区为空
      {
                cnt++;
                if( cnt > 100)
                        return 0;
               
      }
      
      SPI_I2S_TxData(SPI2,Data);                                                                                                                                        //发送一个字节的数据
      cnt = 0;
      while(SPI_I2S_GetFlagStatus(SPI2,SPI_I2S_FLAG_RNE) == RESET)      //等待接收完一个Byte
      {      
                cnt++;
                if( cnt > 100)
                        return 0;
      }
      return SPI_I2S_RxData(SPI2);                                                                                                //接收一个字节的数据
      
}

/****************************************************************************
* 名      称:u8 SI24R1_Write_Reg(u8 reg,u8 val)      
* 功      能:对SI24R1写一个字节到寄存器
* 入口参数:无
* 出口参数:无
* 说      明:无
****************************************************************************/
u8 SI24R1_Write_Reg(u8 reg,u8 val)
{
      u8 ReceiveData;
      
      SI24R1_CSN_Low;
      
      ReceiveData = SPI2_WriteReadByte(reg);
      SPI2_WriteReadByte(val);
      
      SI24R1_CSN_High;
      
      return ReceiveData;
}

/****************************************************************************
* 名      称:u8 SI24R1_Read_Reg(u8 reg,u8 val)      
* 功      能:对SI24R1读寄存器的值
* 入口参数:无
* 出口参数:无
* 说      明:无
****************************************************************************/
u8 SI24R1_Read_Reg(u8 reg)
{
      u8 RegData;
      
      SI24R1_CSN_Low;
      
      SPI2_WriteReadByte(reg);
      RegData = SPI2_WriteReadByte(0xff);
      
      SI24R1_CSN_High;
      
      return RegData;
}

/****************************************************************************
* 名      称:u8 SI24R1_Write_Buffer(u8 reg,u8 *pBuf,u8 len)      
* 功      能:向某一个寄存器写入一组数据
* 入口参数                reg                寄存器地址
                                                pBuf      写入的数据地址   
                                                len   数据长度
* 出口参数:ReceiveData
* 说      明:无
****************************************************************************/
u8 SI24R1_Write_Buffer(u8 reg,u8 *pBuf,u8 len)
{
      u8 ReceiveData;
      int i=0;
      
      SI24R1_CSN_Low;
      
      ReceiveData = SPI2_WriteReadByte(reg);
      
      for(i= 0;i < len;i++)
      {
                SPI2_WriteReadByte(*pBuf);
                pBuf++;
      }
      SI24R1_CSN_High;
      
      return ReceiveData;
}


/****************************************************************************
* 名      称:u8 SI24R1_Read_Buffer(u8 reg,u8 *pBuf,u8 len)      
* 功      能:向某一个寄存器读出一组数据
* 入口参数                reg                寄存器地址
                                                pBuf      写入的数据地址   
                                                len   数据长度
* 出口参数:ReceiveData
* 说      明:无
****************************************************************************/
u8 SI24R1_Read_Buffer(u8 reg,u8 *pBuf,u8 len)
{
      u8 status;
      int i;
      
      SI24R1_CSN_Low;
      
      status = SPI2_WriteReadByte(reg);
      
      for(i= 0;i < len;i++)
      {
                *pBuf = SPI2_WriteReadByte(0xff);
                pBuf++;
      }
      SI24R1_CSN_High;
      
      return status;
}
/****************************************************************************
* 名      称:void SI24R1__Set_Mode(u8 mode)      
* 功      能:设置SI24R1发送还是接收模式
* 入口参数                mode                模式设置
* 出口参数:无
* 说      明:无
****************************************************************************/
void SI24R1_Set_Mode(u8 mode)
{
      if(mode == IT_TX)
      {
                SI24R1_CE_Low;
                SI24R1_Write_Reg(W_REGISTER+CONFIG,IT_TX);
                SI24R1_Write_Reg(W_REGISTER+STATUS,0x7E);                //关闭所有中断,防止一进入发送模式就中断
               
                SI24R1_CE_High;
//                delay_us(20);
      }
      else
      {
                SI24R1_CE_Low;
                SI24R1_Write_Reg(W_REGISTER+CONFIG,IT_RX);
                SI24R1_Write_Reg(W_REGISTER+STATUS,0x7E);                //关闭所有中断,防止一进入接收模式中断
               
                SI24R1_CE_High;
                delay_us(200);
      }
}


/****************************************************************************
* 名      称:SI24R1_Config(void)      
* 功      能:SI24R1基本参数配置,并初始化为发射模式
* 入口参数      :无
* 出口参数:无
* 说      明:无
****************************************************************************/
void SI24R1_Config(void)
{
      SI24R1_CE_Low;
      
//接收模式的配置               
      SI24R1_Write_Reg(W_REGISTER + SETUP_AW,0x03);                               //配置通信地址长度,默认值时0x03,即5字节      
SI24R1_Write_Buffer(W_REGISTER + TX_ADDR,TX_ADDRESS,TX_ADR_WIDTH);
      SI24R1_Write_Buffer(W_REGISTER + RX_ADDR_P0,TX_ADDRESS,TX_ADR_WIDTH);//设置RX节点地址
SI24R1_Write_Reg(W_REGISTER + EN_AA,0x01);                                        //使能通道0自动应答
      SI24R1_Write_Reg(W_REGISTER + EN_RXADDR,0x01);                              //使能通道0的接收地址
      SI24R1_Write_Reg(W_REGISTER + SETUP_RETR,0x1A);
      SI24R1_Write_Reg(W_REGISTER + RF_CH,40);                                           //设置RF通道为40Hz
      SI24R1_Write_Reg(W_REGISTER + RX_PW_P0,TX_PAYLO_WIDTH);                                                                                  //设置接收管道字节数为32字节
      SI24R1_Write_Reg(W_REGISTER + RF_SETUP,0x0e);                                          //设置TX发射参数,7db增益,2Mbps,低噪声增益关闭
      SI24R1_Set_Mode(IT_RX);                                                                                                                                                                                                                        //默认为接收模式                                                                                                                                                                                                      
      
//发送模式的配置
      
//      SI24R1_Write_Reg(W_REGISTER + SETUP_AW,0x03);                               //配置通信地址长度,默认值时0x03,即5字节
//      SI24R1_Write_Buffer(W_REGISTER + TX_ADDR,(u8*)TX_ADDRESS,TX_ADR_WIDTH);   //写TX节点地址(发送地址)
//      SI24R1_Write_Buffer(W_REGISTER + RX_ADDR_P0,(u8*)TX_ADDRESS,TX_ADR_WIDTH);//设置RX节点地址(为了应答接收设备,接收通道0和发送地址相同)
//      
//      SI24R1_Write_Reg(W_REGISTER + EN_AA,0x01);                                        //使能通道0自动应答
//      SI24R1_Write_Reg(W_REGISTER + EN_RXADDR,0x01);                              //使能通道0的接收地址
//      SI24R1_Write_Reg(W_REGISTER + SETUP_RETR,0x1A);                                                                                                                //设置自动重发延时为500us,最大自动重发次数为10
//      SI24R1_Write_Reg(W_REGISTER + RF_CH,40);                                                                                                                                                //设置RF通道为40Hz
//      SI24R1_Write_Reg(W_REGISTER + RF_SETUP,0x27);                                          //设置TX发射参数,7db增益,2Mbps,低噪声增益关闭
//      SI24R1_Set_Mode(IT_TX);                                                                                                                                                                                                                        //默认为发射模式                        
      SI24R1_CE_High;                        
      delay_us(20);
}


/****************************************************************************
* 名      称:void SI24R1_TxPacket(u8 *txbuf)      
* 功      能:SI24R1发送一包数据
* 入口参数      :txbuf 要发送的数据地址
* 出口参数:无
* 说      明:无
****************************************************************************/
void SI24R1_TxPacket(u8 *txbuf)
{

      
      SI24R1_Config();
      SI24R1_CE_Low;
      SI24R1_Write_Buffer(W_REGISTER + TX_ADDR,(u8*)TX_ADDRESS,TX_ADR_WIDTH);   //写TX节点地址
      SI24R1_Write_Buffer(W_REGISTER + RX_ADDR_P0,(u8*)RX_ADDRESS,RX_ADR_WIDTH);//写RX节点地址
      SI24R1_Write_Reg(FLUSH_TX ,0xFF);      
      SI24R1_Write_Buffer(W_TX_PAYLOAD,txbuf,TX_PAYLO_WIDTH);                                                         //写数据到TX_BUFF
      SI24R1_Write_Reg(W_REGISTER + CONFIG,IT_TX);                                                                                                                              //设置为发送模式,开启所有中断      
      SI24R1_Write_Reg(W_REGISTER + STATUS,0x7E);                                                                                                                              //清除所有中断,防止一进去发送模式就触发中断

      SI24R1_CE_High;
      delay_us(10);
      
}



/****************************************************************************
* 名      称:void SI24R1_RxPacket(u8 *txbuf)      
* 功      能:SI24R1接收一包数据
* 入口参数      :rxbuf 要接收的数据地址
* 出口参数:无
* 说      明:无
****************************************************************************/
void SI24R1_RxPacket(u8 *rxbuf)
{
      SI24R1_CE_Low;
      
      SI24R1_Read_Buffer(R_RX_PAYLOAD,rxbuf,TX_PAYLO_WIDTH);                                                                                  //读取RX的有效数据
      SI24R1_Write_Reg(FLUSH_RX ,0xFF);                                                                                                                                                                              //清除RX_FIFO

      SI24R1_CE_High;
}

/****************************************************************************
* 名      称:u8 SPI_Test_Connection(void)
* 功      能:测试SPI是否与MCU正常通信
* 入口参数      :无
* 出口参数:无
* 说      明:无
****************************************************************************/
u8 SPI2_Test_Connection(void)
{
      u8 test_txbuf = {0xC0,0xC1,0xC2,0xC3,0xC4};
      u8 test_rxbuf = {0};
      u8 i;
      SI24R1_Write_Buffer(W_REGISTER + TX_ADDR,test_txbuf,5);                //      写入5个字节的数据
      SI24R1_Read_Buffer(TX_ADDR,test_rxbuf,5);                                                                        //读出写入的数据
      for(i=0;i< 5; i++)
      {
//                printf("SI24R1 test_rxbuf[%d]=%x\r\n",i,test_rxbuf);
                if(test_rxbuf != test_txbuf)
                {
                        break;
                }
      }
      if(i != 5 )
      {
                return 0;                        //      SPI与MCU通信有误
      }
      return 1;       //正常通信
}

/****************************************************************************
* 名      称:void SI24R1_Check(void)
* 功      能:测试MCU与SI24R1是否连接
* 入口参数      :无
* 出口参数:无
* 说      明:无
****************************************************************************/
void SI24R1_Check(void)
{
      while(!SPI2_Test_Connection())
      {
                printf("\r SI24R1 has no connection with MCU! \r\n");
      }
      if(SPI2_Test_Connection())
                printf("\r SI24R1 has connections with MCU! \r\n");
}


/****************************************************************************
* 名      称:u8 SI24R1_Test_Connection(void)
* 功      能:测试飞控SI24R1和遥控SI24R1是否正常通信
* 入口参数      :无
* 出口参数:无
* 说      明:无
****************************************************************************/
void SI24R1_Test_Connection(void)
{
      u8 i=0;
         for(i = 0; i < 32;i++)
      {
                SI24R1_TX_DATA = 1;
      }
      SI24R1_TxPacket(SI24R1_TX_DATA);      
}




谢谢大家指教



页: [1]
查看完整版本: 【AT32-START-407测评】+无线通信模块SI24R1测试