前言
现在越来越多的智能家居,遥控飞机进入了我们大家的生活中,而2.4G的无线传输因为其免费开源被广泛使用,而现在MCU国产化又是我们国家发展芯片的大趋势,所以本文就CW32F030系列的开发板实现无线传输通信,为以后的智能家居可能会提供一点帮助。
一、无线传输的基础
我们是使用CW32F030的SPI已经市面上常见的NRF24L01模块来实现两块开发板之间的无线传输,可以远程控制另一块开发板的点灯或者其他操作
二、配置步骤以及功能实现
1.配置LED以及按键KEY,SPI的设置
代码如下:
#include "cw32f030.h"
#include "led.h"
#include "cw32f030_rcc.h"
void LED_Init(void)
{
GPIO_InitTypeDef GPIO_InitStructure;
RCC_AHBPeriphClk_Enable(RCC_AHB_PERIPH_GPIOB, ENABLE);
GPIO_InitStructure.Pins = GPIO_PIN_9;
GPIO_InitStructure.Mode = GPIO_MODE_OUTPUT_PP;
GPIO_InitStructure.Speed = GPIO_SPEED_HIGH;
GPIO_Init(CW_GPIOB, &GPIO_InitStructure);
GPIO_WritePin(CW_GPIOB, GPIO_PIN_9, GPIO_Pin_RESET);
GPIO_InitStructure.Pins = GPIO_PIN_8;
GPIO_InitStructure.Mode = GPIO_MODE_OUTPUT_PP;
GPIO_InitStructure.Speed = GPIO_SPEED_HIGH;
GPIO_Init(CW_GPIOB, &GPIO_InitStructure);
GPIO_WritePin(CW_GPIOB, GPIO_PIN_8, GPIO_Pin_RESET);
}
#include "cw32f030.h"
#include "key.h"
#include "led.h"
#include "cw32f030_rcc.h"
void KEY_Init(void)
{
GPIO_InitTypeDef GPIO_InitStructure;
RCC_AHBPeriphClk_Enable(RCC_AHB_PERIPH_GPIOA, ENABLE);
GPIO_InitStructure.Pins = GPIO_PIN_1;
GPIO_InitStructure.Mode = GPIO_MODE_INPUT_PULLUP;//上拉输入
GPIO_InitStructure.Speed = GPIO_SPEED_HIGH ;
GPIO_Init(CW_GPIOA, &GPIO_InitStructure);
GPIO_InitStructure.Pins = GPIO_PIN_2;
GPIO_InitStructure.Mode = GPIO_MODE_INPUT_PULLUP;
GPIO_InitStructure.Speed = GPIO_SPEED_HIGH ;
GPIO_Init(CW_GPIOA, &GPIO_InitStructure);
}
//引脚配置
extern uint8_t status_key;
void KEY_Scan(void)
{
static uint8_t flag_key0,flag_key1;
if(KEY0==0)
{
flag_key0++;
if(flag_key0==1)
{
status_key=1;
}
if(flag_key0>2)flag_key0=2;
}
else
{
flag_key0=0;
}
if(KEY1==0)
{
flag_key1++;
if(flag_key1==1)
status_key=2;
if(flag_key1>2)flag_key1=2;
}
else
{
flag_key1=0;
}
delay1ms(10);
}
void SPI2_Init(void)
{
SPI_InitTypeDef SPI_InitStructure;
GPIO_InitTypeDef GPIO_InitStructure;
//配置SPI2管脚
RCC_AHBPeriphClk_Enable( SPIx_MISO_GPIO_CLK|SPIx_SCK_GPIO_CLK | SPIx_MOSI_GPIO_CLK | SPIx_CS_GPIO_CLK, ENABLE);
SPIx_APBClkENx(SPIx_CLK,ENABLE);
SPIx_SCK_AF();
SPIx_MOSI_AF();
SPIx_MISO_AF();
//SPIx_CS_AF();
GPIO_InitStructure.Pins = GPIO_PIN_6 | GPIO_PIN_10;
GPIO_InitStructure.Speed = GPIO_SPEED_HIGH;
GPIO_InitStructure.Mode = GPIO_MODE_OUTPUT_PP;
GPIO_Init(CW_GPIOB, &GPIO_InitStructure);
GPIO_InitStructure.Pins = GPIO_PIN_1;
GPIO_InitStructure.Speed = GPIO_SPEED_HIGH;
GPIO_InitStructure.Mode = GPIO_MODE_OUTPUT_PP;
GPIO_Init(CW_GPIOF, &GPIO_InitStructure);
GPIO_InitStructure.Pins = GPIO_PIN_7;
GPIO_InitStructure.Mode = GPIO_MODE_INPUT;
GPIO_InitStructure.Speed = GPIO_SPEED_HIGH;
GPIO_Init(CW_GPIOB, &GPIO_InitStructure);
(CW_GPIOF->BRR = bv1);
//SPI2配置选项
RCC_APBPeriphClk_Enable1(RCC_APB1_PERIPH_SPI2,ENABLE);
SPI_InitStructure.SPI_Direction = SPI_Direction_2Lines_FullDuplex;
SPI_InitStructure.SPI_Mode = SPI_Mode_Master;
SPI_InitStructure.SPI_DataSize = SPI_DataSize_8b;
SPI_InitStructure.SPI_CPOL = SPI_CPOL_Low;
SPI_InitStructure.SPI_CPHA = SPI_CPHA_1Edge;
SPI_InitStructure.SPI_NSS = SPI_NSS_Soft;
SPI_InitStructure.SPI_BaudRatePrescaler = SPI_BaudRatePrescaler_8;
SPI_InitStructure.SPI_FirstBit = SPI_FirstBit_MSB;
SPI_InitStructure.SPI_Speed = SPI_Speed_Low;
SPI_Init(CW_SPI2, &SPI_InitStructure);
//使能SPI2
SPI_Cmd(CW_SPI2, ENABLE); }
2.配置NRF24L01的初始化以及收发的函数
void NRF24L01_Init(void)
{
GPIO_InitTypeDef GPIO_InitStructure;
RCC_AHBPeriphClk_Enable(RCC_AHB_PERIPH_GPIOA , ENABLE );
GPIO_InitStructure.Pins = GPIO_PIN_5;//CE
GPIO_InitStructure.Mode = GPIO_MODE_OUTPUT_PP ;
GPIO_InitStructure.Speed = GPIO_SPEED_HIGH;
GPIO_Init(CW_GPIOA, &GPIO_InitStructure);
GPIO_InitStructure.Pins = GPIO_PIN_4;//CS
GPIO_Init(CW_GPIOA, &GPIO_InitStructure);
GPIO_WritePin(CW_GPIOA,GPIO_PIN_4 ,GPIO_Pin_SET);
GPIO_InitStructure.Pins = GPIO_PIN_3;//IRQ
GPIO_InitStructure.Mode = GPIO_MODE_INPUT_PULLUP;
GPIO_Init(CW_GPIOA, &GPIO_InitStructure);
SPI2_Init(); //初始化SPI,在这里所有的引脚配置完毕
GPIO_WritePin(CW_GPIOA, GPIO_PIN_5, GPIO_Pin_RESET); //Standby
GPIO_WritePin(CW_GPIOA, GPIO_PIN_4, GPIO_Pin_RESET);//SPI片选
while(NRF24L01_Check()); //2.检查NRF24L01是否在位.
NRF24L01_RX_Mode();
}
uint8_t NRF24L01_TxPacket(uint8_t *txbuf)
{
uint8_t sta;
GPIO_WritePin(CW_GPIOA, GPIO_PIN_5, GPIO_Pin_RESET);
NRF24L01_Write_Buf(WR_TX_PLOAD,txbuf,TX_PLOAD_WIDTH);//写数据到TX BUF 32个字节
GPIO_WritePin(CW_GPIOA, GPIO_PIN_5, GPIO_Pin_SET);//启动发送
while(NRF24L01_IRQ!=0);//等待发送完成
sta=NRF24L01_Read_Reg(STATUS); //读取状态寄存器的值
NRF24L01_Write_Reg(NRF_WRITE_REG+STATUS,sta); //清除TX_DS或MAX_RT中断标志
if(sta&MAX_TX)//达到最大重发次数
{
NRF24L01_Write_Reg(FLUSH_TX,0xff);//清除TX FIFO寄存器
return MAX_TX;
}
if(sta&TX_OK)//发送完成
{
return TX_OK;
}
return 0xff;//其他原因发送失败
}
uint8_t NRF24L01_RxPacket(uint8_t *rxbuf)
{
uint8_t sta;
//SPI1_SetSpeed(SPI_BaudRatePrescaler_8); //spi速度为9Mhz(24L01的最大SPI时钟为10Mhz)
sta=NRF24L01_Read_Reg(STATUS); //读取状态寄存器的值
NRF24L01_Write_Reg(NRF_WRITE_REG+STATUS,sta); //清除TX_DS或MAX_RT中断标志
if(sta&RX_OK)//接收到数据
{
NRF24L01_Read_Buf(RD_RX_PLOAD,rxbuf,RX_PLOAD_WIDTH);//读取数据
NRF24L01_Write_Reg(FLUSH_RX,0xff);//清除RX FIFO寄存器
return 0;
}
return 1;//没收到任何数据
}
3.主函数的实现
void RCC_Configuration(void);
const char on[]={"ledon"};
const char off[]="ledoff";
uint8_t command[8];
uint8_t status_key;
int main(void)
{
RCC_Configuration();
uint8_t momo,key,mode;
uint16_t t=0;
LED_Init();
KEY_Init();
NRF24L01_Init();
uint8_t tmp_buf[33]={0x03,0x03};
uint8_t tmp_buf_2[33]={0x30,0x30};
while(1)
{
NRF24L01_TX_Mode();
if(KEY0==0)//读取按键0
{
delay1ms(10);
if(KEY0==0)//读取按键0
{
momo=1;
// NRF24L01_TxPacket(tmp_buf);
}
}
if(KEY1==0)//读取按键0
{
delay1ms(10);
if(KEY1==0)//读取按键0
{
//NRF24L01_TxPacket(tmp_buf_2);
momo=0;
}
}
if(momo==0)
{
NRF24L01_TxPacket(tmp_buf);
LED0_OFF;
}
if(momo==1)
{
NRF24L01_TxPacket(tmp_buf_2);
LED0_ON;
}
{
delay1ms(10);
}
}
}
void RCC_Configuration(void)
{
//SYSCLK = HSI = 24MHz = HCLK = PCLK
RCC_HSI_Enable(RCC_HSIOSC_DIV2);
//外设时钟使能
RCC_AHBPeriphClk_Enable(RCC_AHB_PERIPH_GPIOA | RCC_AHB_PERIPH_GPIOB, ENABLE);
RCC_APBPeriphClk_Enable1(RCC_APB1_PERIPH_SPI2,ENABLE);
}
接收端的配置
void RCC_Configuration(void);
const char on[]={"ledon"};
const char off[]="ledoff";
uint8_t command[8];
uint8_t status_key;
uint8_t tmp_buf[33];
int main(void)
{
RCC_Configuration();
uint8_t momo,key,mode;
uint16_t t=0;
LED_Init();
KEY_Init();
NRF24L01_Init();
while(1)
{
NRF24L01_RX_Mode();
NRF24L01_RxPacket(tmp_buf);
if(tmp_buf[0]==0x03|tmp_buf[1]==0x03)
{
LED0_ON;
}
else{
LED0_OFF;
}
delay1ms(10);
}
}
void RCC_Configuration(void)
{
//SYSCLK = HSI = 24MHz = HCLK = PCLK
RCC_HSI_Enable(RCC_HSIOSC_DIV2);
//外设时钟使能
RCC_AHBPeriphClk_Enable(RCC_AHB_PERIPH_GPIOA | RCC_AHB_PERIPH_GPIOB, ENABLE);
RCC_APBPeriphClk_Enable1(RCC_APB1_PERIPH_SPI2,ENABLE);
}
总结
通过设置中断是可以实现两块板子之间的双向传输功能。
|
|