新手上路
- 积分
- 25
- 金钱
- 25
- 注册时间
- 2016-6-5
- 在线时间
- 2 小时
|
基本思路:前段时间在毕业设计,用到了nrf24l01(刚开始也为中断接收与发送而烦恼)。(其中需要两个模块(stm32f103c8t6和stc12c5a60s2)与一个主模块(stm32f103zet6)的相互通信)。为了分享一下想法。下面以原子的实验33 无线通信实验为基础修改的。我尽可能的减小修改量。本人没有这个开发板,所以没有实际测试。
贴一部分程序,具体的见附件。
附件说明:
附件1:实验33 无线通信实验(中断接收方式) ——发送时,屏蔽中断。接收时,不屏蔽中断
附件2:附件1:实验33 无线通信实验(中断方式)——中断处理接收与发送两种情况。
//初始化24L01的IO口
void NRF24L01_Init(void)
{
GPIO_InitTypeDef GPIO_InitStructure;
SPI_InitTypeDef SPI_InitStructure;
EXTI_InitTypeDef EXTI_InitStructure;
NVIC_InitTypeDef NVIC_InitStructure;
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB|RCC_APB2Periph_GPIOG, ENABLE); //使能PB,G端口时钟
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_12; //PB12上拉 防止W25X的干扰
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP; //推挽输出
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(GPIOB, &GPIO_InitStructure); //初始化指定IO
GPIO_SetBits(GPIOB,GPIO_Pin_12);//上拉
RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO,ENABLE); //使能复用
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_7|GPIO_Pin_8; //PG8 7 推挽
GPIO_Init(GPIOG, &GPIO_InitStructure);//初始化指定IO
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_6;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU; //PG6 输入
GPIO_Init(GPIOG, &GPIO_InitStructure);
GPIO_ResetBits(GPIOG,GPIO_Pin_7|GPIO_Pin_8);//PG7,8下拉
//nRF24L01 NVIC配置
NVIC_InitStructure.NVIC_IRQChannel=EXTI9_5_IRQn;
NVIC_InitStructure.NVIC_IRQChannelSubPriority=3;
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority=3;
NVIC_InitStructure.NVIC_IRQChannelCmd=ENABLE;
NVIC_Init(&NVIC_InitStructure);
//将GPIO管脚与外部中断线连接
GPIO_EXTILineConfig(GPIO_PortSourceGPIOG,GPIO_PinSource6);
//nRF24L01 EXIT配置
EXTI_InitStructure.EXTI_Line=EXTI_Line6;
EXTI_InitStructure.EXTI_Mode=EXTI_Mode_Interrupt;
EXTI_InitStructure.EXTI_Trigger=EXTI_Trigger_Falling;
EXTI_InitStructure.EXTI_LineCmd=ENABLE;
EXTI_Init(&EXTI_InitStructure);
EXTI_ClearITPendingBit(EXTI_Line6);
SPI2_Init(); //初始化SPI
SPI_Cmd(SPI2, DISABLE); // SPI外设不使能
SPI_InitStructure.SPI_Direction = SPI_Direction_2Lines_FullDuplex; //SPI设置为双线双向全双工
SPI_InitStructure.SPI_Mode = SPI_Mode_Master; //SPI主机
SPI_InitStructure.SPI_DataSize = SPI_DataSize_8b; //发送接收8位帧结构
SPI_InitStructure.SPI_CPOL = SPI_CPOL_Low; //时钟悬空低
SPI_InitStructure.SPI_CPHA = SPI_CPHA_1Edge; //数据捕获于第1个时钟沿
SPI_InitStructure.SPI_NSS = SPI_NSS_Soft; //NSS信号由软件控制
SPI_InitStructure.SPI_BaudRatePrescaler = SPI_BaudRatePrescaler_16; //定义波特率预分频的值:波特率预分频值为16
SPI_InitStructure.SPI_FirstBit = SPI_FirstBit_MSB; //数据传输从MSB位开始
SPI_InitStructure.SPI_CRCPolynomial = 7; //CRC值计算的多项式
SPI_Init(SPI2, &SPI_InitStructure); //根据SPI_InitStruct中指定的参数初始化外设SPIx寄存器
SPI_Cmd(SPI2, ENABLE); //使能SPI外设
NRF24L01_CE=0; //使能24L01
NRF24L01_CSN=1; //SPI片选取消
}
中断部分:
//nRF24L01中断服务程序
void EXTI9_5_IRQHandler(void)
{
u8 istatus;
//判断是否是线路6引起的中断
if (EXTI_GetITStatus(EXTI_Line6)!=RESET)
{
if(GPIO_ReadInputDataBit(GPIOG,GPIO_Pin_6)==0)
{
istatus=NRF24L01_Read_Reg(STATUS); // 读取状态寄存其来判断数据接收状况
nrf_flag=istatus;
if(istatus&0x40)//bit6:数据接收中断
{
NRF24L01_Read_Buf(RD_RX_PLOAD,tmp_buf,RX_PLOAD_WIDTH);//读取数据
NRF24L01_Write_Reg(FLUSH_RX,0xff);//清除RX FIFO寄存器
}
else if((istatus&0x10)>0)////达到最大发送次数中断
{
NRF24L01_Write_Reg(FLUSH_TX,0xff);//清除TX FIFO寄存器
//NRF24L01_RX_Mode(); //发送结束,转为接收状态。
//(可以在中断中转为接收状态,也可在NRF24L01_TxPacket之后转为接收状态)。如果不处理达到最大发送次数的情况下。中断中转换更好一点。
}
else if((istatus&0x20)>0)//TX发送完成中断
{
NRF24L01_Write_Reg(FLUSH_TX,0xff);//清除TX FIFO寄存器
//NRF24L01_RX_Mode(); //发送结束,转为接收状态。
}
NRF24L01_Write_Reg(NRF_WRITE_REG+STATUS,istatus);//清除状态寄存器
}
EXTI_ClearITPendingBit(EXTI_Line6); //清除标志
}
}
|
|