打印
[活动专区]

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

[复制链接]
966|0
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
本帖最后由 怀揣少年梦 于 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[TX_PAYLO_WIDTH]={0}        ;        //SI24R1发送缓冲区
u8 SI24R1_RX_DATA[RX_PAYLO_WIDTH]={0}        ;        //SI24R1接收缓冲区

u8 TX_ADDRESS[TX_ADR_WIDTH]= {0x34,0x43,0x10,0x10,0x01};//发送地址
u8 RX_ADDRESS[RX_ADR_WIDTH]= {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  ;PB15  MOSI
        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[5] = {0xC0,0xC1,0xC2,0xC3,0xC4};
        u8 test_rxbuf[5] = {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[i]);
                if(test_rxbuf[i] != test_txbuf[i])
                {
                        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[0] = 1;
        }
        SI24R1_TxPacket(SI24R1_TX_DATA);        
}




谢谢大家指教



使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

个人签名:一切皆有可能

28

主题

397

帖子

2

粉丝