材料
電源:18650電池1節(2000mah)
主控:N76E003單片機
傳感器:BMP180氣壓傳感器、BH1750光照度傳感器
無線串口模塊:LC12S(2.4G)
LDO:XC6204
外殼:3D打印PLA
開發環境:KEIL4
電路
其中PPG與PPG1爲推輓輸出,用於給傳感器供電,與對IIC總線提供上拉電源。
其中CS1爲無線串口模塊休眠控制管腳,設置爲開漏輸出。(特點見下圖)
對於一些常用外設,如果直接連接到單片機供電迴路,當然是不理想的,即便是低功耗器件,哪怕有休眠模式,消耗電流也非常厲害的。怎麼辦呢?
1分開供電:對一些大功率的外圍,比如無線通訊模塊,可以用一個mos開關控制是否爲外設供電,對一些小功率器件,比如運放,存儲器可以結合實際最大消耗電流,可以直接使用i/o口輸出高電平爲芯片供電,i/o一般可以輸出 6-20ma,pp模式。當然別忘串一個很小的電阻,10歐,外設的退偶電容不能很大。一個i/o不夠可以過個一起供。
讓穩壓器的輸出電壓略高於電池電壓,這樣有外部電源供電的時候就可以不消耗電池了
運行邏輯
由上圖可知,本次DIY沒有任何外部供電(本來想用太陽能的,但因爲某些衆所周知的問題,放棄了),旨在檢驗N76E003單片機低功耗運行的能力(此前運行了8天,鋰電池電壓下降0.04V)。
本次實驗依然使用N76E003單片機的定時喚醒功能,50s喚醒一次,一小時開啓一次外設,並喚醒無線串口模塊發送檢測數據。發送完成後關閉所有外設,推輓模式置低,無線串口模塊進入睡眠模式。
有關N76E003單片機低功耗處理的知識請看這裏N76E003 低功耗(掉電模式&定時喚醒)
結構設計
裝配圖(外殼還在打印,需要大約八個小時,之後再補充成品圖)
底座(全部採用M4螺絲孔)
頂蓋(兩側凸起爲通氣孔擋板,防止雨水直接灌入;頂部開孔爲BH1750光照傳感器用)
下圖爲裝配完成的實物圖,底部由四顆磁鐵提供吸力,目前安裝在空調外機上
數據分析
【2019-02-06 05:37:17:648】T13.1P946L00000
【2019-02-06 06:37:32:917】T13.0P946L00000
【2019-02-06 07:37:48:428】T12.9P947L00021
【2019-02-06 08:38:04:639】T13.1P948L00593
【2019-02-06 09:38:23:768】T13.6P949L01644
【2019-02-06 10:39:03:042】T17.3P950L06451
【2019-02-06 11:40:59:770】T21.5P950L11015
【2019-02-06 12:43:24:925】T23.2P950L22975
【2019-02-06 13:45:51:873】T22.9P949L12294
【2019-02-06 15:51:29:183】T28.7P949L09477
【2019-02-06 16:54:04:207】T27.3P949L06950
【2019-02-06 17:55:50:921】T16.8P951L01640
【2019-02-06 18:56:29:171】T13.0P951L00002
分別是溫度,壓強,光照強度。通過上面的數據,可以粗略的分析每天的日落日出,以及溫度變化。
主程序代碼
#include "N76E003.h"
#include "Common.h"
#include "Delay.h"
#include "SFR_Macro.h"
#include "Function_define.h"
#include "BMP180.h"
#include "BH1750.h"
#define uint unsigned int
#define uchar unsigned char
uchar abc[17];//串口發送緩衝
uint WktCount=0;
bit WktFlag=0;
sbit CS1=P0^5;//CS睡眠管腳,開漏輸出
sbit PPG=P1^7;//供電管腳,推輓輸出
sbit PPG1=P3^0;//同上
int main (void)
{
int i;
Set_All_GPIO_Quasi_Mode;
P05_OpenDrain_Mode;//設置爲開漏模式
P13_OpenDrain_Mode;//設置爲開漏模式
P14_OpenDrain_Mode;//設置爲開漏模式
P17_PushPull_Mode;//推輓輸出
P30_PushPull_Mode;
//----------I/O口配置----------------
CS1=1;//無線模塊睡眠
PPG=0;//關閉外圍器件供電
PPG1=0;
set_P06;
set_P07;//初始化串口
//---------I/O口初始化------------
Init_BH1750();//初始化光照傳感器
set_ES_1;//開啓串口1中斷使能
InitialUART0_Timer1(9600);
//----------串口1、串口0配置----------------
WKCON =0x07; //預分頻配置2048
RWK =255-211;//設置爲50s定時——72個爲一小時
set_EWKT; //使能定時喚醒中斷
set_WKTR; //運行定時喚醒功能
//----------WKT配置------------------------
EA = 1;//開啓總中斷
while(1)
{
if(WktFlag)//判定是否溢出
{
WktCount++;
WktFlag=0;
if(WktCount>=72)//1h發送一次
{
PPG=1;//推輓輸出,給外圍器件供電
PPG1=1;
CS1=0;//拉低,接地喚醒無線透傳模塊
Timer3_Delay100ms(1);
Init_BMP085();//初始化氣壓計
bmp085Convert();
Timer3_Delay100ms(1);
EC_BH1750();//轉化光照度
abc[0]=0x54;//T溫度
abc[1]=temperature/100+48;
abc[2]=temperature%100/10+48;
abc[3]=0x2e;
abc[4]=temperature%10+48;
abc[5]=0x50;//P氣壓
abc[6]=pressure/10000+48;
abc[7]=pressure%10000/1000+48;
abc[8]=pressure%1000/100+48;
abc[9]=0x4c;//L光照
abc[10]=(int)BH1750_temp/10000+48;
abc[11]=(int)BH1750_temp%10000/1000+48;
abc[12]=(int)BH1750_temp%1000/100+48;
abc[13]=(int)BH1750_temp%100/10+48;
abc[14]=(int)BH1750_temp%10+48;
for(i=0;i<15;i++)
{
Send_Data_To_UART0(abc[i]);
}
WktCount=0;
}
ADCCON1 = 0X00;//關閉ADC
clr_BODEN;//關閉欠壓檢測
set_PD;// 進入掉電模式
PPG=0;//關閉外圍器件供電
PPG1=0;
CS1=1;//無線模塊進入睡眠
}
}
}
//---------定時喚醒中斷服務程序--------------
void WakeUp_Timer_ISR (void) interrupt 17
{
WktFlag=1;
clr_WKTF;//清除WKT溢出標誌位
}
總結
回顧之前那幾篇很水的博客(驅動各類傳感器的文章),可以看出最初我是想把GP2Y1010(灰塵檢測)、DHT11(溫溼度)、HMC5883(電子羅盤)、光電編碼器等都加上去,想測風速與方向(見下圖)。後來都因爲尺寸和供電問題一一放棄。其次就是缺少一個很好的上位機,接下來的日子重心會放在python和QT的學習上,希望能進入一個新的世界吧。祝大家新年快樂!