前段时间学51单片机的时候做了一个简单的智能家居,实现了三个传感器采集数据,于OLED显示。当时并没有深入的去研究,仅仅是51采集数据显示:单片机==简易智能家居OLED。这次扩展了一下这个项目。
项目需求:
采集房间的温度、湿度、光照、烟雾等信息,51采集完数据在OLED上显示,采用2.4G射频模块NRF24L01,将51采集的数据发送给STM32,STM32接收完数据在TFT屏中显示一下。当温度、湿度、烟雾过高时,启动蜂鸣器报警电路。
项目过程:
首先这个项目已经在普中开发板上运行过了,详细信息请到前文博客查看::单片机==简易智能家居OLED。
第一步,制作单片机电路原理图和PCB图:
原理图:
PCB图:
绘制原理图和PCB图是最基础的一步,PCB绘制成功后便开始了PCB板子的制作。本项目采用的是单层板,首先将PCB图用激光打印机打印至热转印纸上,然后将热转印纸和单层铜板贴合,放至热转印机中来回5-6次,取出撕掉热转印纸,将铜板放至腐蚀液中半小时左右,取出,打孔。PCB板便做成功了。
注意:在制作PCB板时,一开始没有采用镜像打印,导致了后期电路不好焊,又重新做了一个。打印时一点要添加镜像。
总结:此次PCB图绘制时没有考虑到布局的影响,导致了最终很多器件挤在一起,这是本次的一个大失误。
成品:
51制作完毕后,限于实验条件的影响,STM32的PCB板子不好制作,所以STM32直接在淘宝上买了一个最小系统板使用。
STM32移植了UCOS-III系统,使用TFT屏显示无线接收的数据,按照原计划我本来是想移植STEMWin的GUI来显示,奈何买的STM32最小系统板没有带外部SRAM,所以导致GUI的空间分配不够,最终无奈放弃了。
这里我就分享一下24L01的收发代码吧,其他传感器的程序在上次的博客中说过,就不在讲了。
/********************STC89C51发送数据****************************/
#ifndef _24L01_H_
#define _24L01_H_
sbit MISO = P1^3;
sbit MOSI = P1 ^ 4;
sbit SCLK1 = P1^5;
sbit CE = P1^7;
sbit CSN = P1^6;
unsigned char code RxAddr[]={'m','n','m','n','i'};
unsigned char code TxAddr[]={'m','n','m','n','i'};
unsigned char bdata sta;
sbit RX_DR=sta^6;
sbit TX_DS=sta^5;
sbit MAX_RT=sta^4;
#define TX_ADDR_WITDH 5
#define RX_ADDR_WITDH 5
#define TX_DATA_WITDH 32
#define RX_DATA_WITDH 32
#define R_REGISTER 0x00
#define W_REGISTER 0x20
#define R_RX_PAYLOAD 0x61
#define W_TX_PAYLOAD 0xa0
#define FLUSH_TX 0xe1
#define FLUSH_RX 0xe2
#define REUSE_TX_PL 0xe3
#define NOP 0xff
#define CONFIG 0x00
#define EN_AA 0x01
#define EN_RXADDR 0x02
#define SETUP_AW 0x03
#define SETUP_RETR 0x04
#define RF_CH 0x05
#define RF_SETUP 0x06
#define STATUS 0x07
#define OBSERVE_TX 0x08
#define CD 0x09
#define RX_ADDR_P0 0x0a
#define RX_ADDR_P1 0x0b
#define RX_ADDR_P2 0x0c
#define RX_ADDR_P3 0x0d
#define RX_ADDR_P4 0x0e
#define RX_ADDR_P5 0x0f
#define TX_ADDR 0x10
#define RX_PW_P0 0x11
#define RX_PW_P1 0x12
#define RX_PW_P2 0x13
#define RX_PW_P3 0x14
#define RX_PW_P4 0x15
#define RX_PW_P5 0x16
#define FIFO_STATUS 0x17
/**************************************************
函数:NRFSPI()
描述:
根据SPI协议,写一字节数据到nRF24L01,同时从nRF24L01
读出一字节
/**************************************************/
unsigned char NRFSPI(unsigned char date)
{
unsigned char i;
for(i=0;i<8;i++)
{
if(date&0x80)
MOSI=1;
else
MOSI=0;
date<<=1;
SCLK1=1;
if(MISO)
date|=0x01;
SCLK1=0;
}
return(date);
}
/**************************************************
函数:NRFReadReg()
描述:
从reg寄存器读一字节
/**************************************************/
unsigned char NRFReadReg(unsigned char RegAddr)
{
unsigned char BackDate;
CSN=0;
NRFSPI(RegAddr);
BackDate=NRFSPI(0x00);
CSN=1;
return(BackDate);
}
/**************************************************
函数:NRFWriteReg()
描述:
写数据value到reg寄存器
/**************************************************/
unsigned char NRFWriteReg(unsigned char RegAddr,unsigned char date)
{
unsigned char BackDate;
CSN=0;
BackDate=NRFSPI(RegAddr);
NRFSPI(date);
CSN=1;
return(BackDate);
}
/**************************************************
函数:NRFWriteTxDate()
描述:
把pBuf缓存中的数据写入到nRF24L01,通常用来写入发
射通道数据或接收/发送地址
/**************************************************/
unsigned char NRFWriteTxDate(unsigned char RegAddr,unsigned char *TxDate,unsigned char DateLen)
{
unsigned char BackDate,i;
CSN=0;
BackDate=NRFSPI(RegAddr);
for(i=0;i
/**********************STM32F103ZET6接收数据******************************/
#ifndef _24L01_H_
#define _24L01_H_
#include
#include "delay.h"
#define MISOIN GPIO_ReadInputDataBit(GPIOA,GPIO_Pin_6)
#define SCK_1 GPIO_SetBits(GPIOA,GPIO_Pin_5)
#define SCK_0 GPIO_ResetBits(GPIOA,GPIO_Pin_5)
#define MOSI_1 GPIO_SetBits(GPIOA,GPIO_Pin_7)
#define MOSI_0 GPIO_ResetBits(GPIOA,GPIO_Pin_7)
#define CSN_1 GPIO_SetBits(GPIOC,GPIO_Pin_4)
#define CSN_0 GPIO_ResetBits(GPIOC,GPIO_Pin_4)
#define CE_1 GPIO_SetBits(GPIOA,GPIO_Pin_4)
#define CE_0 GPIO_ResetBits(GPIOA,GPIO_Pin_4)
unsigned char RxAddr[]={'m','n','m','n','i'};
unsigned char TxAddr[]={'m','n','m','n','i'};
unsigned char sta;
u8 RX_DR;
#define TX_DS sta&(1<<5)
#define MAX_RT sta&(1<<4)
#define TX_ADDR_WITDH 5
#define RX_ADDR_WITDH 5
#define TX_DATA_WITDH 32
#define RX_DATA_WITDH 32
#define R_REGISTER 0x00
#define W_REGISTER 0x20
#define R_RX_PAYLOAD 0x61
#define W_TX_PAYLOAD 0xa0
#define FLUSH_TX 0xe1
#define FLUSH_RX 0xe2
#define REUSE_TX_PL 0xe3
#define NOP 0xff
#define CONFIG 0x00
#define EN_AA 0x01
#define EN_RXADDR 0x02
#define SETUP_AW 0x03
#define SETUP_RETR 0x04
#define RF_CH 0x05
#define RF_SETUP 0x06
#define STATUS 0x07
#define OBSERVE_TX 0x08
#define CD 0x09
#define RX_ADDR_P0 0x0a
#define RX_ADDR_P1 0x0b
#define RX_ADDR_P2 0x0c
#define RX_ADDR_P3 0x0d
#define RX_ADDR_P4 0x0e
#define RX_ADDR_P5 0x0f
#define TX_ADDR 0x10
#define RX_PW_P0 0x11
#define RX_PW_P1 0x12
#define RX_PW_P2 0x13
#define RX_PW_P3 0x14
#define RX_PW_P4 0x15
#define RX_PW_P5 0x16
#define FIFO_STATUS 0x17
void _NOP_()
{
int i;
i++;i--;
}
void NRF24L01Int(void)
{
GPIO_InitTypeDef GPIO_InitStructure;
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB|RCC_APB2Periph_GPIOA|RCC_APB2Periph_GPIOC, ENABLE);
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_4|GPIO_Pin_5|GPIO_Pin_7|GPIO_Pin_11;//ce pb13 csn pb12 sck pb10 mosi pb11 miso pb9
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP; //推挽输出
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; //IO口速度为50MHz
GPIO_Init(GPIOA, &GPIO_InitStructure);
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_6;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(GPIOA, &GPIO_InitStructure);
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_4;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(GPIOC, &GPIO_InitStructure);
CE_0;
CSN_1;
SCK_0;
delay_ms(2);
}
unsigned char NRFSPI(unsigned char date)
{
unsigned char i;
for(i=0;i<8;i++)
{
_NOP_();
if(date&0x80)
MOSI_1;
else
MOSI_0;
date<<=1;
_NOP_();
SCK_1;
_NOP_();
if(MISOIN)
date|=0x01;
SCK_0;
}
return(date);
}
unsigned char NRFReadReg(unsigned char RegAddr)
{
unsigned char BackDate;
CSN_0;
NRFSPI(RegAddr);
BackDate=NRFSPI(0x00);
CSN_1;
return(BackDate);
}
unsigned char NRFWriteReg(unsigned char RegAddr,unsigned char date)
{
unsigned char BackDate;
CSN_0;
BackDate=NRFSPI(RegAddr);
NRFSPI(date);
CSN_1;
return(BackDate);
}
unsigned char NRFWriteTxDate(unsigned char RegAddr,unsigned char *TxDate,unsigned char DateLen)
{
unsigned char BackDate,i;
CSN_0;
BackDate=NRFSPI(RegAddr);
for(i=0;i
效果图:
keil工程分享51
keil工程分享32