方案框图:
原理图:
JDY-30蓝牙模块电路设计
蓝牙模块是指集成蓝牙功能的芯片基本电路集合,用于无线网络通讯。本蓝牙模块就是为了只能无线数据传输而专门打造的,本模块支持串行接口,支持SP蓝牙串口协议,具有成本低、体积小、收发灵敏性高等特点,只需配备少许的外围元件就能实现大功能。
一、模块特点
(1)支持蓝牙 SPP 串口协议
(2)内置 PCB 天线
(3)支持 UART 接口
(4)蓝牙 Class 2
(5)数据传输比 BLE 蓝牙快、可达到 8K 每秒以上的速率
(6)支持与 SPP 主蓝牙模块连接通信(JDY-30 为从 SPP 蓝牙模块)
(7)支持与电脑 SPP 蓝牙通信
(8)支持 Android 手机 SPP 通信
二、产品应用范围
(1) POS 机
(2)蓝牙打印机
(3)蓝牙玩具
(4)蓝牙高速数据传输产品应用
(5)小家电
(6)汽车电子
三、模块技术参数
(1)工作电压:3.3V-6V
(2)工作温度:-40℃-85℃
(3)天线:PCB板载天线
(4)功耗:19mA
四、模块接口说明
(1)RXD 串口输入,电平为TTL电平
(2)TXD 串口输出,电平为TTL电平
(3)GND 接GND
(4)VCC 接3.3V-6V
蓝牙模块接口电路图如下图所示。
LED信号指示灯电路设计
LED灯即发光二极管,它是半导体二极管的一种,可以把电能转化成光能。发光二极管与普通二极管一样是由一个PN结组成,也具有单向导电性。在电路中,电阻的作用是限流,保护LED灯。只要单片机的控制引脚拉低,则LED灯亮,否则,LED灯不亮。其具体电路原理图如下图所示。
二挡拨动开关检测电路设计
拨动开关是通过拨动开关柄使电路接通或断开,从而达到切换电路的目的的。拨动开关常用的品种有单极双位、单极三位、双极双位以及双极三位等,它一般用于低压电路,具有滑块动作灵活、性能稳定可靠的特点,拨动开关主要广泛用于:各种仪器/仪表设备,各种电动玩具,传真机,音响设备,医疗设备,美容设备,等其它电子产品领域。
简单的说,拨动开关就是通过拨动其执行机构(开关柄),来接通或断开电路。
通过拨动开关实现对信号的切换,电阻为上拉电阻。当二档拨动开关拨下去时,单片机控制引脚为低电平。当二档拨动开关拨上去时,单片机控制引脚为高电平。进而实现对信号的完美切换。其电路图如下图所示。
程序流程图
#include "pbdata.h"
_record_obj record[NUM_RECORD]; //记录结构体
vu8 box_open=0;//记录药盒打开的状态,每一个二进制位代表一个药盒
u8 length_record = 0;//记录的个数
u8 count_save_record = 0;//记录保存的次数,需要保存时加1,完成一次保存则减1
void RecordInit(void)//记录初始化
{
u8 i;
//读写flash数据均为2个字节,所以数据长度为结构体数据长度除以2
STMFLASH_Read(ADDR_RECORD, (uint16_t *)&record[0].month,NUM_RECORD*sizeof(_record_obj)/2);
for(i=0;i<NUM_RECORD;i++){
if(record[i].alive==MSG_TRUE){
length_record++;
// break;
}
}
}
//读写flash数据均为2个字节,所以数据长度为结构体数据长度除以2
void RecordRead(u8 recordNum)
{
//从flash读取数据内容到内存
STMFLASH_Read(ADDR_RECORD+sizeof(_record_obj)*recordNum, (uint16_t *)&record[0].month,sizeof(_record_obj)/2);
}
//保存记录到flash
void RecordSaveAll()
{
count_save_record++;
// if(count_save_record&0x80){//任务4被挂起
// //当要保存的数据比较大时,保存数据的操作比较浪费时间,所以在一个单独的任务中执行
// OSTaskResume(TASK_4_PRIO); //恢复任务4,保存所有记录
// }
}
//删除记录
void RecordDelete(u8 recordNum)
{
record[recordNum].alive = MSG_FALSE;
MoveRecord();
RecordSaveAll();
length_record--;
}
//删除记录,如删除第二条,则将第三条移动到第二条
void MoveRecord(void){
u8 i=0,j=1;
for(i=0;i<NUM_RECORD-1;i++){
if(record[i].alive!=MSG_TRUE){
for(j=i+1;j<NUM_RECORD;j++){
if(record[j].alive==MSG_TRUE){
record[i]=record[j];
record[j].alive = MSG_FALSE;
break;
}
}
}
}
}
//添加一条记录
void AddRecord(_calendar_obj time_now,u8 num){
//记录总数有限制,保存满以后从头循环保存
if(length_record==NUM_RECORD){
record[0].alive=MSG_FALSE;
MoveRecord();
}
else{
length_record++;
}
//下面使用length_record-1,不是length_record,否则记录顺序不正确,甚至可能会数组越界而导致死机
record[length_record-1].month = time_now.w_month;
record[length_record-1].day = time_now.w_date;
record[length_record-1].hour = time_now.hour;
record[length_record-1].min = time_now.min;
record[length_record-1].num_box = num;
record[length_record-1].alive = MSG_TRUE;
RecordSaveAll();
}
//查询并保存药盒打开记录
void RecordNow(void){
u8 i=0;
u16 gpio_key=KEY_PIN_1,gpio_led=LED_PIN_1;
if(rtc_ok == MSG_FALSE){
return;
}
for(i=0;i<NUM_BOX;i++){
switch(i){
case 0:gpio_key=KEY_PIN_1;gpio_led=LED_PIN_1;break;
case 1:gpio_key=KEY_PIN_2;gpio_led=LED_PIN_2;break;
case 2:gpio_key=KEY_PIN_3;gpio_led=LED_PIN_3;break;
default:break;
}
if(GPIO_ReadInputDataBit(KEY_PORT,gpio_key)){//1号药盒打开
OSTimeDly(5);
if(GPIO_ReadInputDataBit(KEY_PORT,gpio_key) && !(box_open&(0x01<<i))){
box_open |= 0x01<<i;
alert_cancel |= 0x01<<i;//取消本次报警
LED_OFF(LED_PORT,gpio_led);
AddRecord(calendar,i+1);//记录药盒打开时间和编号
}
}
else {
box_open &= ~(0x01<<i);
}
}
if(alert_en&(~alert_cancel)){
Beep_ON();
}
else if(!alert_flash){
Beep_OFF();
}
}
.
链接:https://pan.baidu.com/s/1-pUy38R02RykPI3T6CKUhA
提取码:5sev
.