智能手表设计说明.docx

上传人:b****4 文档编号:3771116 上传时间:2022-11-25 格式:DOCX 页数:31 大小:5.32MB
下载 相关 举报
智能手表设计说明.docx_第1页
第1页 / 共31页
智能手表设计说明.docx_第2页
第2页 / 共31页
智能手表设计说明.docx_第3页
第3页 / 共31页
智能手表设计说明.docx_第4页
第4页 / 共31页
智能手表设计说明.docx_第5页
第5页 / 共31页
点击查看更多>>
下载资源
资源描述

智能手表设计说明.docx

《智能手表设计说明.docx》由会员分享,可在线阅读,更多相关《智能手表设计说明.docx(31页珍藏版)》请在冰豆网上搜索。

智能手表设计说明.docx

智能手表设计说明

如上图所示,触摸屏采用的是2.0寸的全视角IPSTFT彩屏采用8位数据口控制,大大减少IO的使用,驱动采用的ILI9335,更加容易地移植STemWin,触摸板是自己加上的,触摸IC为XTP2046,采用模拟SPI采集触摸屏AD值。

震动电机采用普通IO口控制,当有电话来或者接到短信的时候就打开,直到电话接起或者拒接。

利用MCU自带的ADC对心率传感器的电压进行采集,通过MCU处理后,利用STemWin的GRAPH控件构建心率图。

串口6连接蓝牙模块对智能开关进行控制,控制风扇、电灯等,并利用蓝牙模块进行温度无线采集。

用户按键的主要功能是锁、开屏和开、关机(进入停机模式),则按键用WKUP功能引脚。

SIM908通信模块带有GSM、GPRS和GPS功能,是此智能手表功能实现的主要核心,智能手表的通话、短信、远程追踪功能都是由此模块来实现。

SD卡模块用来保存中文字库和收到的短信。

为了提高安全性,采用管理员管理模式,当检测到管理员发来的短信命令时,才允许手表打开其追踪功能,管理员的账号密码保存在AT24c02这一非易失性存储IC中。

硬件设计:

此智能手表采用上下两层双层叠板,配合2.0寸液晶屏的大小而设计的

上智能手表的原理图:

此为主控MCU-stm32f411re及其外设的原理图(BUG:

旁路电容2.2UF忘记加了导致程序下载后时钟无法完成初始化,32.768KHz的晶振接口粗心大意接错了,导致RTC跑不起来)

此为SIM908原理图,包含SIM卡及四段式耳机等,SIM908对静电相当敏感,所以加入ESD防止静电干扰。

接下来就上,智能手表的PCB图了

再来一幅没有铺铜的,清晰看清上下层

实物图片展示:

实物展示:

 

软件部分:

基于stm32f411re的智能手表(整体介绍)

双层板已经叠起来了,跟市面上的手表相比,厚度的确有点厚,可是没办法,我一个人的能力是不能跟一个团队和工厂工艺相比的!

采用STemWin图像用户界面,实现窗口化管理,在手表的状态栏显示通信运营商的信息和信号大小,利用sim908自带ADC采集电池电量信息,并在状态栏显示。

在主窗口显示时间,用ICONVIEW小工具构建成手表的应用。

一共有六个应用,目前只写了三个,剩余的将在以后再完善。

手表说明:

按键设置在手表底部,用于锁屏用,底部还有个四段式耳机接口,用于通话功能!

手表顶部有个震动电机,来电的时候震动起来真心带感,USB接口用于充电用。

手表的侧面有两个充电状态指示灯,分别提示正在充电和已经充满。

另外一侧则是电源开关和心率传感器接口。

视频演示链接:

基于stm32f411re的智能手表(通话功能)

通话功能主要是基于SIM908模块建立起来的,所以不得不说一下串口字符处理。

那就从串口中断讲开去……

先看中断代码:

voidUSART1_IRQHandler(void)

{

chardata;

if(USART_GetITStatus(USART1,USART_IT_RXNE)!

=RESET)

{

//USART_ClearFlag(USART1,USART_IT_RXNE);

data=USART_ReceiveData(USART1);

if(GSM_RX_FLAG

{

TIM3->CNT=0;//清空计数器

if(GSM_RX_FLAG==0)

{

TIM3_Set

(1);//开计数器3

}

GSM_RX_BUFF[GSM_RX_FLAG++]=data;

}

else

{

GSM_RX_FLAG|=1<<15;//接收标志强制置1

}

}

}

由于stm的硬件buff只有一个字节,那就极可能造成字符串没接收完,就开始判断,这就会造成信息的丢失。

比如说,我要提取一字符串中的某些内容,这样如果字符串没接收完就会出现你前面判断对了,但是你要提取的信息在后头,这样提取的信息就变成空的了!

为了解决这个问题,我引入一个定时器在限定的时间内把缓冲区填满否则也判断完了,接着在开始对字符串进行处理。

如上面的代码如果整个缓冲区填满了,那样就使能标志位对字符串处理,如果还能进行保存数据则打开定时器3(定时6ms),定时器3中断后对字符串进行处理(判断为接收完了)。

接下来看看定时器3中的处理:

/*

函数名:

TIM3_Interrupt

描述:

tim3中断函数

输入:

输出:

*/

voidTIM3_IRQHandler(void)

{

uint8_twrite_buf[2];

u8mesaddr[3];

u8*p1=NULL;

u8*p2=NULL;

if(TIM_GetITStatus(TIM3,TIM_IT_Update)!

=RESET)

{

TIM_ClearITPendingBit(TIM3,TIM_IT_Update);

TIM3_Set(0);//关闭计时器

GSM_RX_BUFF[GSM_RX_FLAG&0x7fff]='\0';

GSM_IT_FLAG=1;

GSM_RX_FLAG=0;

if(NULL!

=strstr(GSM_RX_BUFF,"+CMTI:

"))

{

mesaddr[0]=*(strstr(GSM_RX_BUFF,",")+1);

mesaddr[1]=*(strstr(GSM_RX_BUFF,",")+2);

write_buf[0]=mesaddr[0];

write_buf[1]=mesaddr[1];

if(mesaddr[1]>='0'&&mesaddr[1]<='9')

{

Messagenum=(mesaddr[0]-'0')*10+(mesaddr[1]-'0');

}

else

{

Messagenum=(mesaddr[0]-'0');

}

Messagebuff[Messagenum-1]=1;

FlagNewMessage=1;

//将短信数量保存

if(ee_WriteBytes(write_buf,0,2)==0)

{

USART_printf(USART6,"写eeprom出错!

\r\n");

}

else

{

USART_printf(USART6,"写eeprom成功!

\r\n");

USART_printf(USART6,"\r\n%d\r\n",Messagenum);

}

}

elseif(NULL!

=strstr(GSM_RX_BUFF,"+CLIP:

"))

{

p1=(u8*)strstr((char*)GSM_RX_BUFF,"\"");

p2=(u8*)strstr((char*)(p1+1),"\"");

p2[0]='\0';

strcpy(RingNumber,p1+1);

if(!

WM_IsWindow(WinPara.hRing))//判断当前激活的窗口

WM_SendMessageNoPara(WinPara.hWinMain,MY_MESSAGE_RING);

Moter(ON);

}

elseif(NULL!

=strstr(GSM_RX_BUFF,"CLOSE"))

{

//GPRSFLAG=3;

}

}

}

巧妙使用strstr函数,减少出错率。

判断接收到的字符串是否含有+CMTI:

(来短信信息反馈)、+CLIP:

(来电信息反馈)、CLOSE(GPRS连接断开信息反馈)这几个信息。

当有电话来的时候,就会有带有+CLIP:

的字符串反馈,则我们就给主窗口发送来电信息(WM_SendMessageNoPara(WinPara.hWinMain,MY_MESSAGE_RING);),并提取来电号码、使能震动电机。

接下来看看主窗口回调函数部分代码:

/*

描述:

主窗口的回调函数

*/

staticvoid_cbMainWin(WM_MESSAGE*pMsg)

{

RTC_TimeTypeDefRTC_TimeStruct;

RTC_DateTypeDefRTC_DateStruct;

WM_HWINhText;

intNCode;

intid;

intSel;

chartext_buffer[20];

intxSize,ySize;

switch(pMsg->MsgId){

caseWM_NOTIFY_PARENT:

id=WM_GetId(pMsg->hWinSrc);//获取控件的ID

NCode=pMsg->Data.v;

if(id==GUI_ID_ICONVIEW0&&NCode==WM_NOTIFICATION_RELEASED)

{

Sel=ICONVIEW_GetSel(pMsg->hWinSrc);//获取图标索引

switch(Sel)

{

case0:

GUI_Phone();

break;

case1:

GUI_Message();

break;

case2:

GUI_time();

break;

case3:

break;

case4:

break;

case5:

break;

}

}

break;

caseMY_MESSAGE_RTC:

hText=WM_GetDialogItem(pMsg->hWin,GUI_ID_TEXT1);

RTC_GetTime(RTC_Format_BIN,&RTC_TimeStruct);

RTC_GetDate(RTC_Format_BIN,&RTC_DateStruct);

sprintf(text_buffer,"%02d:

%02d",RTC_TimeStruct.RTC_Hours,RTC_TimeStruct.RTC_Minutes);

TEXT_SetText(hText,text_buffer);

hText=WM_GetDialogItem(pMsg->hWin,GUI_ID_TEXT2);

sprintf(text_buffer,"20%02d-%02d-%02d",RTC_DateStruct.RTC_Year,RTC_DateStruct.RTC_Month,RTC_DateStruct.RTC_Date);

TEXT_SetText(hText,text_buffer);

hText=WM_GetDialogItem(pMsg->hWin,GUI_ID_TEXT3);

switch(RTC_DateStruct.RTC_WeekDay)

{

case1:

sprintf(text_buffer,"Monday");

break;

case2:

sprintf(text_buffer,"Tuesday");

break;

case3:

sprintf(text_buffer,"Wednesday");

break;

case4:

sprintf(text_buffer,"Thursday");

break;

case5:

sprintf(text_buffer,"Friday");

break;

case6:

sprintf(text_buffer,"Saturday");

break;

case7:

sprintf(text_buffer,"Sunday");

break;

default:

sprintf(text_buffer,"");

break;

}

TEXT_SetText(hText,text_buffer);

break;

caseMY_MESSAGE_RING:

Phone_Ring();

break;

caseWM_PAINT:

//重绘背景

xSize=WM_GetWindowSizeX(pMsg->hWin);

ySize=WM_GetWindowSizeY(pMsg->hWin);

GUI_DrawGradientV(0,0,xSize-1,ySize-1,0xfffff56c,0xffffffe8);

GUI_DrawGradientV(0,0,240,280,0xffff0d23,0xfffff56c);

break;

default:

WM_DefaultProc(pMsg);

}

}

当主窗口接到来电信息就会建立子窗口(即来电提示)。

代码繁多就不把来电显示窗口的代码放出来了!

这就是来电的效果图,有来电显示功能,点击YES就能接听电话,点击No则为拒接并退出此窗口,Back键主要用于,接听完电话退出界面的。

除了来电功能,还有拨话功能!

这为拨话的界面,编辑好电话号码后点击Call后就能进行拨话功能

这为正在拨话的界面,可以随时挂断电话

演示视频地址:

基于stm32f411re的智能手表(短信功能)

由于要讲详细点,所以要分开来讲,不便之处敬请原谅!

既然SIM908自带GSM功能,电话功能实现了,为何不加上短信功能呢,也许到时操作发短信有点复杂。

短信这部分有点复杂,因为采用管理员管理模式,要在AT24C02中保存短信的数量,还要保存短信的性质,接着还要判断短信内容是命令还是非命令,发短信的界面也复杂,T9键盘的建立,字符的索引。

接收到短信后,使能短信读取标志位,然后进入主函数

while

(1)

{

GUI_Delay(20);

if(FlagNewMessage)

{

//USART_printf(USART6,"%d\r\n",Messagenum);

FlagNewMessage=0;

if(SIM_ERR_NONE==Sim908_ReadMessage(Messagenum,1))

{

USART_printf(USART6,"readcmd\r\n");

Messagebuff[Messagenum]=MESSAGE_CMD;

//I2C_EE_BufferWrite(Messagebuff,MESSAGE_FLASH_ADDR,sizeof(Messagebuff));

}

else

{

USART_printf(USART6,"readnotcmd\r\n");

Messagebuff[Messagenum]=MESSAGE_NOTCMD;

}

ee_WriteBytes(Messagebuff,1,sizeof(Messagebuff));//保存短信属性

}

}

 

进入主函数后就开始进入Sim908_ReadMessage函数读取短信内容了

u8Sim908_ReadMessage(u8addr,u8mode)

{

u8res=SIM_ERR_OTHER;

u8messageaddr[20];

u8address[3];

u8*p1=NULL;

u8*p2=NULL;

//USART_printf(USART6,"addr=%d\r\n",addr);

//USART_printf(USART6,"mode=%d\r\n",mode);

if(addr>50||addr<1)

{

return0;

}

if(addr<10)

{

address[0]=addr+'0';

address[1]='\0';

}

else

{

address[0]=addr/10+'0';

address[1]=addr%10+'0';

address[2]='\0';

}

//USART_printf(USART6,"address=%s\r\n",address);

Sim908_SendCmd("AT+CMGF=1","OK",50);

Sim908_SendCmd("AT+CSCS=\"GSM\"","OK",50);

sprintf((char*)messageaddr,"AT+CMGR=%s",address);

if(SIM_ERR_NONE==Sim908_SendCmd(messageaddr,"+CMGR:

",100))

{

//USART_printf(USART6,"\r\n%s\r\n",GSM_RX_BUFF);

p1=(u8*)strstr((char*)GSM_RX_BUFF,",");

p2=(u8*)strstr((char*)(p1+2),"\"");

p2[0]='\0';//添加结束符

strcpy((char*)MES_STR.Phonenum,(char*)(p1+2));//保存电话号码

//USART_printf(USART6,"\r\n%s\r\n",MES_STR.Phonenum);

p1=(u8*)strstr((char*)(p2+1),":

");

p2=(u8*)strstr((char*)(p1),"+");

p2[0]='\0';

strcpy((char*)MES_STR.Time,(char*)(p1-11));//保存接收时间

//USART_printf(USART6,"\r\n%s\r\n",MES_STR.Time);

p1=(u8*)strstr((char*)(p2+1),"\r");

p2=(u8*)strstr((char*)(p1+1),"\r");

p2[0]='\0';

strcpy((char*)MES_STR.Message,(char*)(p1+2));

USART_printf(USART6,"\r\n%s\r\n",MES_STR.Message);

USART_printf(USART6,"\r\njudgemessage\r\n");

if(SIM_ERR_NONE==Sim908_JudgeMessage(&MES_STR))

{

res=SIM_ERR_NONE;

}

}

returnres;

}

保存了短信的发送电话、时间。

就对短信内容进行判断了。

/*

函数名:

Sim908_JudgeMessage

描述:

判断短信内容

输入:

u8*message保存短信内容的数组指针

输出:

*/

u8Sim908_JudgeMessage(Messagestr*mes_str)

{

u8res=SIM_ERR_OTHER;

if(NULL!

=strstr((char*)mes_str->Message,"DW"))

{

USART_printf(USART6,"\r\nDW\r\n");

Sim908_GPSSet

(1);

GPS_IT_FLAG=1;

DW_FLAG=1;

Sim908_SendMessage(ADMINISTRATORPHONE,"Pleasewaitting....",1);

/*if(SIM_ERR_NONE==Sim908_GetGPSInformation(&GPS_STR,NULL))

{

Sim908_GPSConvert(GPS_STR.Latitude,GPS_STR.Longtude,LOCATION);

Sim908_SendMessage(ADMINISTRATORPHONE,(char*)LOCATION,1);

}

else

{

Sim908_SendMessage(ADMINISTRATORPHONE,"tryagain",1);

}*/

res=SIM_ERR_NONE;

}

elseif(NULL!

=strstr((char*)mes_str->Message,"GMM"))

{

u8*p1=NULL;

USART_printf(USART6,"\r\nGMM\r\n");

p1=strstr((char*)mes_str->Phonenum,ADMINISTRATORPHONE);

if(NULL==p1)

{

res=SIM_ERR_MESCMD;

//USART_printf(USART1,"\r\nphonenumis%s\r\n",mes_str->Phonenum);

//USART_printf(USART1,"\r\nADMINISTRATORPHONEis%s\r\n",ADMINISTRATORPHONE);

Sim908_SendMessage((char*)(mes_str->Phonenum),"youarenottheadministrator",1);

}

else

{

charmm[30];

u8*p1=NULL;

u8*p2=NULL;

p1=strstr((char*)mes_str->Message,"\"");

p2=strstr((char*)(p1+1),"\"");

p2[0]=0;

strcpy(PASSWORD,(char*)(p1+1));

//USART_printf(USART1,"\r\nnewPASSWORDis$%s$\r\n",PASSWORD);

//I2C_EE_BufferWrite(PASSWORD,PASSWORD_FLASH_ADDR,sizeof(PASSWORD));

//Flash_Write(PASSWORD_FLASH_ADDR,(u16*)PASSWORD,sizeof(PASSWORD));

sprintf(mm,"newpasswordis%s",PASSWORD);

Sim908_SendMessage((char*)ADMINISTRATORPHONE,mm,1);

展开阅读全文
相关资源
猜你喜欢
相关搜索

当前位置:首页 > 求职职场 > 简历

copyright@ 2008-2022 冰豆网网站版权所有

经营许可证编号:鄂ICP备2022015515号-1