本帖最后由 zhanghuichun 于 2015-3-2 15:48 编辑
由于要讲详细点,所以分开来讲,造成不便敬请原谅 通话功能主要是基于SIM908模块建立起来的,所以不得不说一下串口字符处理。那就从串口中断讲开去…… 先看中断代码: - void USART1_IRQHandler(void)
- {
- char data;
- if(USART_GetITStatus(USART1, USART_IT_RXNE) != RESET)
- {
- // USART_ClearFlag(USART1,USART_IT_RXNE);
- data = USART_ReceiveData(USART1);
- if(GSM_RX_FLAG < DATA_BUFF_SIZE) //还能接收数据
- {
- 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中断函数
- 输入: 无
- 输出: 无
- */
- void TIM3_IRQHandler(void)
- {
- uint8_t write_buf[2];
- u8 mesaddr[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);
- }
-
- }
- else if( 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);
- }
-
- else if(NULL != strstr(GSM_RX_BUFF, "CLOSE"))
- {
- // GPRSFLAG = 3;
- }
- }
- }
巧妙使用strstr函数,减少出错率。判断接收到的字符串是否含有+CMTI:(来短信信息反馈)、+CLIP:(来电信息反馈)、CLOSE(GPRS连接断开信息反馈)这几个信息。 当有电话来的时候,就会有带有+CLIP:的字符串反馈,则我们就给主窗口发送来电信息(WM_SendMessageNoPara(WinPara.hWinMain,MY_MESSAGE_RING);),并提取来电号码、使能震动电机。 接下来看看主窗口回调函数部分代码: - /*
- 描述:主窗口的回调函数
- */
- static void _cbMainWin(WM_MESSAGE * pMsg)
- {
- RTC_TimeTypeDef RTC_TimeStruct;
- RTC_DateTypeDef RTC_DateStruct;
- WM_HWIN hText;
- int NCode;
- int id;
- int Sel;
- char text_buffer[20];
- int xSize, ySize;
-
- switch (pMsg->MsgId) {
- case WM_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)
- {
- case 0:
- GUI_Phone();
- break;
- case 1:
- GUI_Message();
- break;
- case 2:
- GUI_time();
- break;
- case 3:
-
- break;
- case 4:
-
- break;
- case 5:
-
- break;
- }
- }
- break;
- case MY_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)
- {
- case 1:sprintf(text_buffer,"Monday");
- break;
- case 2:sprintf(text_buffer,"Tuesday");
- break;
- case 3:sprintf(text_buffer,"Wednesday");
- break;
- case 4:sprintf(text_buffer,"Thursday");
- break;
- case 5:sprintf(text_buffer,"Friday");
- break;
- case 6:sprintf(text_buffer,"Saturday");
- break;
- case 7:sprintf(text_buffer,"Sunday");
- break;
- default:sprintf(text_buffer,"");
- break;
- }
- TEXT_SetText(hText, text_buffer);
- break;
- case MY_MESSAGE_RING:
- Phone_Ring();
- break;
- case WM_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后就能进行拨话功能 这为正在拨话的界面,可以随时挂断电话  -------------------------------------------------------------------------华丽温柔的分割线------------------------------------------------------------------
|
|