MainTask.c 26 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019
  1. /********************************************************************************
  2. * File Name: MainTask.c
  3. * Function Describe:The main task for the system
  4. * Relate Module:
  5. * Explain: Hardware version is HS110C
  6. * Writer: ShiLiangWen
  7. * Date: 2015.1.20
  8. *******************************************************************************/
  9. #include "includes.h"
  10. #include "stm32f10x_pwr.h"
  11. #include "stm32f10x_iwdg.h"
  12. OS_EVENT *PcQ;
  13. void *PcMsg[PC_Q_NUM];
  14. char PcMsgBuf[PC_Q_NUM][PC_MSG_BUF_LEN];
  15. int PCMsgBufIndex=0;
  16. int g_iMcuVer=MCU_VER;
  17. //======================================
  18. #define APP_TASK_MAIN_STK_SIZE 1000
  19. static OS_STK AppMainTaskStk[APP_TASK_MAIN_STK_SIZE];
  20. const char g_apcFirstPowerOnFlag[]={
  21. "HS110C-1"
  22. };
  23. unsigned char g_ucRand;//伪随机数,根据MCU ID生成
  24. /***********************************************
  25. 强制复位
  26. ************************************************/
  27. void SystemReset(void)
  28. {
  29. *((u32 *)0xE000ED0C) = 0x05fa0001;
  30. while(1);
  31. }
  32. /***********************************************
  33. *SetDefNetPara
  34. *设置默认网络参数
  35. ************************************************/
  36. void SetDefNetPara(void)
  37. {
  38. }
  39. /***************************************************
  40. *IsFirstPowerOn
  41. 判断是否为第一次上电,根据EEPROM标志位来判断
  42. ****************************************************/
  43. int IsFirstPowerOn(void)
  44. {
  45. // int i;
  46. // char flag[8];
  47. // EEPROM_ReadS(EEPROM_FLAG,(unsigned char *)flag,8);
  48. // for(i=0;i<8;i++){
  49. // if(flag[i]!=g_apcFirstPowerOnFlag[i])break;
  50. // }
  51. // if(i!=8){
  52. // EEPROM_WriteS(EEPROM_FLAG,(unsigned char *)g_apcFirstPowerOnFlag,8);
  53. // return -1;
  54. // }
  55. return 0;
  56. }
  57. /******************************************************************
  58. *SysParaInit
  59. ********************************************************************/
  60. void SysParaInit(void)
  61. {
  62. int i;
  63. unsigned char *p=(unsigned char*)&sutNetPara;
  64. for(i=0;i<sizeof(SUT_NET_PARA);i++){
  65. *p=0;
  66. }
  67. //Read From Flash
  68. //ReadParaFromFlash();
  69. sutNetPara.PSN=ReadPsnFromFlash();
  70. sutNetPara.HVer=HARDWARE_VER;
  71. sutNetPara.Rand=GetRandBySTM32ID();
  72. sutNetPara.ModemType=MODEM_TYPE_CDMA;
  73. sutNetPara.GpsType=GPS_TYPE_GP;
  74. }
  75. void PowerCtrlInit(void)
  76. {
  77. GPIO_InitTypeDef GPIO_InitStructure;
  78. DelayMs(1000);
  79. RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO,ENABLE);//复用功能IO 时钟使能 这里必须先使能复用IO的时钟,再关闭JTAG功能
  80. GPIO_PinRemapConfig(GPIO_Remap_SWJ_JTAGDisable, ENABLE); // JTAG-DP Disabled and SW-DP Enabled
  81. //Configure PA15(JTDI) as output push-pull
  82. RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA|RCC_APB2Periph_GPIOB|RCC_APB2Periph_GPIOC, ENABLE);
  83. GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;//GPIO_Mode_IPU;
  84. GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
  85. GPIO_InitStructure.GPIO_Pin = PWR_EN_PIN;
  86. GPIO_Init(PWR_EN_PORT, &GPIO_InitStructure);
  87. PWR_EN_HIGH;
  88. //ONOFF_CK_PIN
  89. GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPD;
  90. GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
  91. GPIO_InitStructure.GPIO_Pin = ONOFF_CK_PIN;
  92. GPIO_Init(ONOFF_CK_PORT, &GPIO_InitStructure);
  93. }
  94. /*************************************************************************
  95. 拷贝数据,并判断与原数据是否相同
  96. 相同返回0
  97. 不同返回1
  98. **************************************************************************/
  99. unsigned char CopyData(unsigned char *pDst,unsigned char *pSrc,unsigned char len)
  100. {
  101. unsigned char i;
  102. unsigned char flag=0;
  103. for(i=0;i<len;i++){
  104. if(*pDst!=*pSrc){
  105. flag=1;
  106. *pDst=*pSrc;
  107. }
  108. pDst++;
  109. pSrc++;
  110. }
  111. return flag;
  112. }
  113. /*********************************************************************
  114. 通过PC设置参数
  115. 通过 UART1
  116. *********************************************************************/
  117. int SetParaFromPC(void)
  118. {
  119. return 0;
  120. }
  121. /**********************************************************************
  122. 1ms在8000~9000之间
  123. ***********************************************************************/
  124. void DelayMs(unsigned long ms)
  125. {
  126. unsigned long i;
  127. while(ms--){
  128. for(i=0;i<6000;i++);
  129. IWDG_ReloadCounter();
  130. }
  131. }
  132. /********************************************************************
  133. *开关机键检测
  134. *********************************************************************/
  135. int OnOffCheck(void)
  136. {
  137. static unsigned char sucCt=0;
  138. unsigned long k;
  139. k=ONOFF_CK_PORT->IDR;
  140. if((k&ONOFF_CK_PIN)==0){
  141. if(sucCt<5)sucCt++;
  142. else return 1;
  143. }else{
  144. sucCt=0;
  145. }
  146. return 0;
  147. }
  148. void GPIO_Config_ALL_AIN(void);
  149. /**********************************************************************
  150. *系统关机
  151. ***********************************************************************/
  152. void SysShutDown(void)
  153. {
  154. GPIO_InitTypeDef GPIO_InitStructure;
  155. unsigned long k;
  156. int len;
  157. g_ucNetTaskDisable=0xff;
  158. GPS_PWREN_LOW;
  159. MODEM_LED1_HIGH;
  160. MODEM_LED2_HIGH;
  161. ModemSendAT("AT+ZPWROFF\r\n");
  162. SlwTrace(INF,"Set modem OnOff down!\r\n");
  163. OSTimeDlyHMSM(0, 0, 0, 500);
  164. ModemSendAT("AT+ZPWROFF\r\n");
  165. //DelayMs(3000);
  166. OSTimeDlyHMSM(0, 0, 2, 500);
  167. SlwTrace(INF,"Set system power off!\r\n");
  168. SlwTraceWaitCompleted();
  169. MODEM_LED1_LOW;
  170. MODEM_LED2_LOW;
  171. //-------
  172. k=ONOFF_CK_PORT->IDR;
  173. if((k&ONOFF_CK_PIN)!=0){
  174. SlwTrace(INF,"Reset system!\r\n");
  175. SlwTraceWaitCompleted();
  176. SystemReset();
  177. }else{
  178. IWDG_ReloadCounter();
  179. GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPD;
  180. GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
  181. GPIO_InitStructure.GPIO_Pin = PWR_EN_PIN;
  182. GPIO_Init(PWR_EN_PORT, &GPIO_InitStructure);
  183. while(1);
  184. }
  185. }
  186. int g_iVbat=0;
  187. unsigned char AscToHex(unsigned char aHex)
  188. {
  189. if((aHex>=0)&&(aHex<=9))
  190. aHex += 0x30;
  191. else if((aHex>=10)&&(aHex<=15))//A-F
  192. aHex += 0x37;
  193. else aHex = 0xff;
  194. return aHex;
  195. }
  196. void AscStrToHexStr(char *AscStr, char *HexStr)
  197. {
  198. char *pAscStr=AscStr;
  199. unsigned char d,h,l;
  200. while(0!=(d=(unsigned char)*pAscStr++)){
  201. l=d&0x0f;
  202. h=d>>4;
  203. *HexStr++=AscToHex(h);
  204. *HexStr++=AscToHex(l);
  205. }
  206. *HexStr=0;
  207. }
  208. void PcMsgHandle(char *msg)
  209. {
  210. char *CmdList[]={
  211. "TM", //Trace Modem
  212. "TG", //Trace GPS
  213. "DM", //Download Modem
  214. "FOTA", //Fota Modem
  215. "STP", //Set Test Parameter
  216. "SMP", //Set Modem Parameter
  217. "SGP", //Set GPS Parameter
  218. "RMP", //Read Modem Parameter
  219. "PST", //PST Mode for modem
  220. "VER", //Read Version
  221. "BAT", //Battery voltage
  222. "" //必须以空字串为结束
  223. };
  224. unsigned short Port;
  225. unsigned long PSN;
  226. char buf[150];
  227. char buf1[300];
  228. char strIP[40];
  229. char strAccount[20];
  230. char strPassword[20];
  231. int i,len;
  232. char flag;
  233. char *pCmd;
  234. char *pMsg;
  235. int CmdListNum=0;
  236. while(*CmdList[CmdListNum++]);//计算命令列表个数
  237. CmdListNum--;
  238. //查找与命令列表相同的命令位置
  239. for(i=0;i<CmdListNum;i++){
  240. pCmd=CmdList[i];
  241. pMsg=&msg[3];
  242. flag=0;
  243. while(*pCmd){
  244. if(*pCmd!=*pMsg){
  245. flag=1;
  246. break;
  247. }
  248. pCmd++;
  249. pMsg++;
  250. }
  251. if(!flag){
  252. break;
  253. }
  254. }
  255. if(i==CmdListNum)return;
  256. //处理命令
  257. switch(i)
  258. {
  259. case 0://"TM"
  260. // g_ucNetTaskDisable=0xff;
  261. SlwTrace(INF,"GT+TM:OK\r\n");
  262. SlwTraceWaitCompleted();
  263. SetLedFlash(3,4);//3闪
  264. ComSelect(COM_SEL_MODEM);
  265. MODEM_LED1_HIGH;
  266. MODEM_LED2_LOW;
  267. while(1){
  268. IWDG_ReloadCounter();//喂狗
  269. if(OnOffCheck()){
  270. PWR_EN_LOW;
  271. }
  272. OSTimeDlyHMSM(0, 0, 0, 1);
  273. }
  274. break;
  275. case 1://"TG"
  276. SlwTrace(INF,"GT+TG:OK\r\n");
  277. SlwTraceWaitCompleted();
  278. SetLedFlash(3,3);//1s 快闪
  279. GPSInit();
  280. ComSelect(COM_SEL_GPS);
  281. break;
  282. case 2://"DM"
  283. g_ucNetTaskDisable=0xff;
  284. SlwTrace(INF,"GT+DM:OK\r\n");
  285. SlwTraceWaitCompleted();
  286. OSTimeDlyHMSM(0, 0, 1, 0);
  287. ComSelect(COM_SEL_MODEM);
  288. MODEM_LED1_LOW;
  289. MODEM_LED2_HIGH;
  290. GPS_PWREN_LOW;
  291. ModemSetDtrLow();
  292. ModemSetRingLow();
  293. MODEM_PWRKEY_HIGH;
  294. MODEM_RESET_HIGH;
  295. OSTimeDlyHMSM(0, 0, 1, 0);
  296. MODEM_RESET_LOW;
  297. while(1){
  298. IWDG_ReloadCounter();//喂狗
  299. if(OnOffCheck()){
  300. PWR_EN_LOW;
  301. }
  302. }
  303. break;
  304. case 3://"FOTA"
  305. g_ucNetTaskDisable=0xff;
  306. SlwTrace(INF,"GT+FOTA:OK\r\n");
  307. SlwTraceWaitCompleted();
  308. OSTimeDlyHMSM(0, 0, 0, 100);
  309. ModemSendAT("at+poc=10000018\r\n");
  310. while(1){
  311. IWDG_ReloadCounter();//喂狗
  312. if(OnOffCheck()){
  313. PWR_EN_LOW;
  314. }
  315. }
  316. break;
  317. case 4://"STP" GT+STP=IP=地址或域名;Port=端口号; Account=账号;Password=密码;
  318. g_ucNetTaskDisable=0xff;
  319. OSTimeDlyHMSM(0, 0, 0, 100);
  320. len=GetParaFromStr(msg,"IP",buf);
  321. if(len<1 || len>=40){
  322. SlwTrace(INF,"GT+STP:FAIL[IP Invalid]\r\n");
  323. break;
  324. }else strcpy(strIP,buf);
  325. len=GetParaFromStr(msg,"Port",buf);
  326. if(len==0)Port=0;
  327. else if(len>5){
  328. SlwTrace(INF,"GT+STP:FAIL[Port Invalid]\r\n");
  329. break;
  330. }else{
  331. Port=atoi(buf);
  332. }
  333. len=GetParaFromStr(msg,"Account",buf);
  334. if(len<1 || len>=20){
  335. SlwTrace(INF,"GT+STP:FAIL[Account Invalid]\r\n");
  336. break;
  337. }else strcpy(strAccount,buf);
  338. len=GetParaFromStr(msg,"Password",buf);
  339. if(len<1 || len>=20){
  340. SlwTrace(INF,"GT+STP:FAIL[Password Invalid]\r\n");
  341. break;
  342. }else strcpy(strPassword,buf);
  343. //send to modem
  344. sprintf(buf,"ip=%s;id=%s;pwd=%s;",strIP,strAccount,strPassword);
  345. AscStrToHexStr(buf,buf1);
  346. ModemSendAT("AT+POC=120000");
  347. ModemSendAT(buf1);
  348. ModemSendAT("\r\n");
  349. //send to pc
  350. sprintf(buf,"GT+STP:IP=%s;Port=%u;Account=%s;Password=%s\r\n",strIP,Port,strAccount,strPassword);
  351. SlwTrace(INF,buf);
  352. break;
  353. case 5://"SMP" GT+SMP=IP=地址或域名;Port=端口号;PSN=终端序列号
  354. len=GetParaFromStr(msg,"IP",buf);
  355. if(len<1 || len>=40){
  356. SlwTrace(INF,"GT+SMP:FAIL[IP Invalid]\r\n");
  357. break;
  358. }else strcpy(strIP,buf);
  359. len=GetParaFromStr(msg,"Port",buf);
  360. if(len==0)Port=0;
  361. else if(len>5){
  362. SlwTrace(INF,"GT+SMP:FAIL[Port Invalid]\r\n");
  363. break;
  364. }else{
  365. Port=atoi(buf);
  366. }
  367. len=GetParaFromStr(msg,"PSN",buf);
  368. if(len<1 || len>10){
  369. SlwTrace(INF,"GT+SMP:FAIL[PSN Invalid]\r\n");
  370. break;
  371. }else{
  372. PSN=atol(buf);
  373. }
  374. //PSN
  375. sutNetPara.PSN=PSN;
  376. strcpy(sutNetPara.PIP,strIP);
  377. sutNetPara.PPort=Port;
  378. //send to modem
  379. if(strlen(sutNetPara.MEID)<14){
  380. SlwTrace(INF,"GT+SMP:FAIL[MEID Invalid]\r\n");
  381. break;
  382. }
  383. sprintf(buf,"ip=%s;id=%u;pwd=%s;",strIP,sutNetPara.PSN,sutNetPara.MEID);
  384. AscStrToHexStr(buf,buf1);
  385. ModemSendAT("AT+POC=010000");
  386. ModemSendAT(buf1);
  387. ModemSendAT("\r\n");
  388. //save PSN to flash
  389. SavePsnToFlash(sutNetPara.PSN);
  390. sutNetPara.PSN=ReadPsnFromFlash();
  391. //Save para to flash
  392. // SaveParaToFlash();
  393. //send to pc
  394. sprintf(buf,"GT+SMP:IP=%s;Port=%u;PSN=%u\r\n",sutNetPara.PIP,sutNetPara.PPort,sutNetPara.PSN);
  395. SlwTrace(INF,buf);
  396. break;
  397. case 6://"SGP" GT+SGP=IP=地址或域名;Port=端口号;
  398. len=GetParaFromStr(msg,"IP",buf);
  399. if(len<1 || len>=40){
  400. SlwTrace(INF,"GT+SGP:FAIL[IP Invalid]\r\n");
  401. break;
  402. }else strcpy(strIP,buf);
  403. len=GetParaFromStr(msg,"Port",buf);
  404. if(len==0)Port=0;
  405. else if(len>5){
  406. SlwTrace(INF,"GT+SGP:FAIL[Port Invalid]\r\n");
  407. break;
  408. }else{
  409. Port=atoi(buf);
  410. }
  411. strcpy(sutNetPara.GIP,strIP);
  412. sutNetPara.GPort=Port;
  413. //Save para to flash
  414. //SaveParaToFlash();
  415. //Send to PC
  416. sprintf(buf,"GT+SGP:IP=%s;Port=%u;\r\n",sutNetPara.GIP,sutNetPara.GPort);
  417. SlwTrace(INF,buf);
  418. break;
  419. case 7://"RMP" GT+RMP<CR><LF> PSN=终端序列号;MEID=模块MEID号;CNUM=电信号;UIMID=电信UIMID;
  420. sutNetPara.PSN=ReadPsnFromFlash();
  421. //Read para from PC
  422. //ReadParaFromFlash();
  423. sprintf(buf,"GT+RMP:PSN=%u;MEID=%s;CNUM=%s;UIMID=%s\r\n",sutNetPara.PSN,sutNetPara.MEID,sutNetPara.CNUM,sutNetPara.UIMID);
  424. SlwTrace(INF,buf);
  425. break;
  426. case 8://"PST"
  427. g_ucNetTaskDisable=0xff;
  428. SlwTrace(INF,"GT+PST:OK\r\n");
  429. SlwTraceWaitCompleted();
  430. OSTimeDlyHMSM(0, 0, 0, 100);
  431. ComSelect(COM_SEL_MODEM);
  432. SetLedFlash(2,4);//2闪
  433. ModemSetDtrLow();
  434. MODEM_PWRKEY_LOW;
  435. MODEM_RESET_HIGH;
  436. OSTimeDlyHMSM(0, 0, 0, 500);
  437. MODEM_RESET_LOW;
  438. while(1){
  439. IWDG_ReloadCounter();//喂狗
  440. if(OnOffCheck()){
  441. PWR_EN_LOW;
  442. }
  443. }
  444. break;
  445. case 9://"VER"
  446. SlwTrace(INF,"GT+VER:\r\n");
  447. SlwTrace(INF,SOFTWARE_VER);
  448. SlwTrace(INF,"\r\n");
  449. break;
  450. case 10://BAT
  451. sprintf(buf,"GT+BAT: %d V\r\n",g_iVbat);
  452. SlwTrace(INF,buf);
  453. break;
  454. }
  455. }
  456. void ReportGps(void)
  457. {
  458. if(!sutGpsInfo.isGpsWork){
  459. //GPS异常 "470050005300025F385E"
  460. ModemSendAT("AT+ZTTS=1,\"470050005300025F385E\"\r\n");
  461. return;
  462. }
  463. if(sutGpsInfo.isServerLogin){
  464. ModemSendAT("AT+ZTTS=1,\"470050005300F25D7B764696"); //GPS已登陆
  465. }else{
  466. ModemSendAT("AT+ZTTS=1,\"4700500053002A677B764696"); //GPS未登陆
  467. }
  468. if(sutGpsInfo.isGpsValid){
  469. ModemSendAT("2C00F25D9A5B4D4F\"\r\n"); //,已定位
  470. }else{
  471. ModemSendAT("2C002A679A5B4D4F\"\r\n"); //,未定位
  472. }
  473. }
  474. /*******************************************************************
  475. *MainTask
  476. *主任务
  477. ********************************************************************/
  478. static void MainTask(void *pdata)
  479. {
  480. char *msg;
  481. INT8U err;
  482. static unsigned char sucCt=0;
  483. static unsigned char sucFunReportFlag=0;
  484. int Vbat;
  485. Uart1Init();//UART1初始化 用于PC通讯,映射到printf(...)
  486. Uart2Init();//UART2初始化 用于GPS通讯
  487. Uart3Init();//UART3初始化 用于Modem通讯
  488. SlwTrace(INF,SOFTWARE_VER);
  489. SlwTrace(INF," Start...\r\n");
  490. SlwTrace(INF,"Watchdog Init!\r\n");
  491. IWDG_Configuration();
  492. //GetSTM32ID(g_aucSTM32ID);
  493. //g_ucRand=GetKey(g_aucSTM32ID);
  494. //初始化系统参数
  495. SlwTrace(INF,"SysParaInit!\r\n");
  496. SysParaInit();
  497. //等待PC重新设置参数
  498. //SlwTrace(INF,"Wait for reset para from PC...\r\n");
  499. //SetParaFromPC();
  500. //创建LED指示应用服务
  501. SlwTrace(INF,"Create Led Task!\r\n");
  502. LedTaskCreate();
  503. SetLedFlash(1,7);//设置LED闪烁
  504. //ADC初始化
  505. ADCInit();
  506. SlwTrace(INF,"ModemInit...");
  507. if(ModemInit()){
  508. SlwTrace(INF," Fail\r\n");
  509. SlwTrace(INF,"will be reset the system!\r\n");
  510. OSTimeDlyHMSM(0, 0, 10, 0);
  511. SystemReset();
  512. }else{
  513. SlwTrace(INF," OK\r\n");
  514. }
  515. KeyInit();
  516. NetTaskCreate();//创建网络应用任务
  517. //创建消息队列,用于与UART1与PC通讯
  518. PcQ=OSQCreate(&PcMsg[0], PC_Q_NUM);
  519. OSQFlush(PcQ);
  520. //-begin-
  521. SlwTrace(INF,"Main task running...\r\n");
  522. while(1)
  523. {
  524. //喂狗
  525. IWDG_ReloadCounter();
  526. //检查关机键按下
  527. if(OnOffCheck()){
  528. //SlwTrace(INF,"Shutdown now!\r\n");
  529. SysShutDown();
  530. }
  531. //消息处理 每次大约等待20ms ,键盘扫描也是20ms
  532. msg = (char *)OSQPend(PcQ, 2, &err);
  533. if(err==OS_ERR_NONE){//收到PC发过来的消息,处理之
  534. //SlwTrace(DEBUG,"[PC_MSG]\r\n");
  535. PcMsgHandle(msg);
  536. continue;
  537. }
  538. //20ms timeout 处理其他
  539. //键盘扫描
  540. if(GetKey()){
  541. //printf("KeyValue=%02x\r\n",g_ucKeyValue);
  542. if(g_ucKeyValue==KEY_FUN){
  543. if(0==sucFunReportFlag){
  544. SlwTrace(INF,"Report Vbat\r\n");
  545. ReportVbat(g_iVbat);
  546. sucFunReportFlag=1;
  547. }else if(1==sucFunReportFlag){
  548. sucFunReportFlag=2;
  549. SlwTrace(INF,"Report CSQ\r\n");
  550. ReportCSQ(g_iCSQ);
  551. }else if(2==sucFunReportFlag){
  552. sucFunReportFlag=0;
  553. ReportGps();
  554. }
  555. }else if(g_ucKeyValue==KEY_FUN_DOWN && g_ucDKC>2){//FOTA升级
  556. g_ucDKC=0;
  557. SlwTrace(INF,"Set modem to FOTA!\r\n");
  558. g_ucNetTaskDisable=0xff;
  559. OSTimeDlyHMSM(0, 0, 2, 0);
  560. ModemSendAT("AT+POC=10000018\r\n");
  561. }else if(g_ucKeyValue==KEY_FUN_UP){//版本播报
  562. if(0==sucFunReportFlag){
  563. sucFunReportFlag=1;
  564. ReportModemVer(g_iModemVer);
  565. }else if(1==sucFunReportFlag){
  566. sucFunReportFlag=0;
  567. ReportMcuVer(g_iMcuVer);
  568. }
  569. }
  570. }
  571. //耳机插入监测
  572. if(g_ucEarDetLast!=g_ucEarDet){
  573. g_ucEarDetLast=g_ucEarDet;
  574. if(g_ucEarDet){
  575. SlwTrace(INF,"EarIn\r\n");
  576. ModemSendAT("AT+SPEAKER=0\r\n");//切换耳机通路
  577. }else {
  578. SlwTrace(INF,"EarOut\r\n");
  579. ModemSendAT("AT+SPEAKER=1\r\n");//切换外放通路
  580. }
  581. }
  582. //以下控制每秒执行一次
  583. if(++sucCt>99)sucCt=0;
  584. else continue;
  585. KeyCount();//键盘按下、释放计数控制
  586. //测量电池电压
  587. Vbat=GetVbat();
  588. if(Vbat>0)g_iVbat=Vbat;
  589. //判断电池电压是否过低关机
  590. CheckVbat(g_iVbat);
  591. }
  592. }
  593. /*********************************************************************
  594. *SKMBCrossTaskCreate
  595. **********************************************************************/
  596. void MainTaskCreate(void)
  597. {
  598. CPU_INT08U os_err;
  599. os_err = os_err; /* prevent warning... */
  600. os_err = OSTaskCreate((void (*)(void *)) MainTask,
  601. (void * ) 0,
  602. (OS_STK * )&AppMainTaskStk[APP_TASK_MAIN_STK_SIZE - 1],
  603. (INT8U ) APP_TASK_MAIN_PRIO );
  604. #if OS_TASK_NAME_EN > 0
  605. OSTaskNameSet(APP_TASK_MAIN_PRIO, "MainTask", &os_err);
  606. #endif
  607. }
  608. void ADCInit(void)
  609. {
  610. ADC_InitTypeDef ADC_InitStructure;
  611. GPIO_InitTypeDef GPIO_InitStructure;
  612. RCC_APB2PeriphClockCmd(RCC_APB2Periph_ADC1,ENABLE);
  613. RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB,ENABLE);
  614. GPIO_InitStructure.GPIO_Pin =GPIO_Pin_0;
  615. GPIO_InitStructure.GPIO_Mode =GPIO_Mode_AIN;
  616. GPIO_Init(GPIOA,&GPIO_InitStructure); //默认速度为两兆
  617. //配置ADC的运行:
  618. ADC_InitStructure.ADC_Mode = ADC_Mode_Independent; //独立模式
  619. ADC_InitStructure.ADC_ScanConvMode =DISABLE; //连续多通道模式
  620. ADC_InitStructure.ADC_ContinuousConvMode =DISABLE;//ENABLE; //连续转换
  621. ADC_InitStructure.ADC_ExternalTrigConv = ADC_ExternalTrigConv_None; //转换不受外界决定
  622. ADC_InitStructure.ADC_DataAlign =ADC_DataAlign_Right; //右对齐
  623. ADC_InitStructure.ADC_NbrOfChannel =1; //扫描通道数
  624. ADC_Init(ADC1,&ADC_InitStructure);
  625. ADC_RegularChannelConfig(ADC1,ADC_Channel_0, 1,ADC_SampleTime_1Cycles5); //通道X,采样时间为1.5周期,1代表规则通道第1个这个1是啥意思我不太清楚只有是1的时候我的ADC才正常。
  626. ADC_Cmd (ADC1,ENABLE); //使能或者失能指定的ADC
  627. ADC_SoftwareStartConvCmd(ADC1,ENABLE);//使能或者失能指定的ADC的软件转换启动功能
  628. SlwTrace(INF,"ADC Init!\r\n");
  629. }
  630. void GPIO_Config_ALL_AIN(void)
  631. {
  632. GPIO_InitTypeDef GPIO_InitStructure;
  633. /* Enable GPIOD and GPIOE clock */
  634. RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA | RCC_APB2Periph_GPIOB
  635. | RCC_APB2Periph_GPIOC | RCC_APB2Periph_GPIOD
  636. | RCC_APB2Periph_AFIO, ENABLE);
  637. /* Disable the Serial Wire Jtag Debug Port SWJ-DP */
  638. GPIO_PinRemapConfig(GPIO_Remap_SWJ_Disable, ENABLE);
  639. /* PA */
  640. GPIO_InitStructure.GPIO_Pin = GPIO_Pin_All;
  641. GPIO_InitStructure.GPIO_Speed = GPIO_Speed_2MHz;
  642. GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AIN;
  643. GPIO_Init(GPIOA, &GPIO_InitStructure);
  644. /* PB */
  645. GPIO_InitStructure.GPIO_Pin = GPIO_Pin_All;
  646. GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AIN;
  647. GPIO_Init(GPIOB, &GPIO_InitStructure);
  648. /* PC */
  649. GPIO_InitStructure.GPIO_Pin = GPIO_Pin_All;
  650. GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AIN;
  651. GPIO_Init(GPIOC, &GPIO_InitStructure);
  652. /* PD */
  653. GPIO_InitStructure.GPIO_Pin = GPIO_Pin_All;
  654. GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AIN;
  655. GPIO_Init(GPIOD, &GPIO_InitStructure);
  656. RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA
  657. | RCC_APB2Periph_GPIOC | RCC_APB2Periph_GPIOD
  658. , DISABLE);
  659. }
  660. /***********************************************************************
  661. *获取电池电压
  662. 返回值: -1为无效 ; 正数表示电池电压放大100倍,如 382表示3.82V
  663. ***********************************************************************/
  664. int GetVbat(void)
  665. {
  666. char buf[30];
  667. static int Ct=0;
  668. static int siVbat[10]={0,0,0,0,0,0,0,0,0,0};
  669. int iVbat[10];
  670. int max[5];
  671. int sum;
  672. int i,j,k;
  673. int adc;
  674. int Vbat;
  675. //采集ADC
  676. if(ADC_GetFlagStatus(ADC1,ADC_FLAG_EOC)!=RESET){//检查制定ADC标志位置1与否 ADC_FLAG_EOC 转换结束标志位 if(ADC_GetFlagStatus(ADC1,ADC_FLAG_EOC)!=RESET){
  677. adc=ADC_GetConversionValue(ADC1);
  678. ADC_SoftwareStartConvCmd(ADC1,ENABLE);
  679. if(adc<100 && adc>4095)return -1;
  680. }else{
  681. return -1;
  682. }
  683. //循环存储
  684. siVbat[Ct]=adc;
  685. if(++Ct>9)Ct=0;
  686. //printf("%d,%d,%d,%d,%d,%d,%d,%d,%d,%d\r\n",siVbat[0],siVbat[1],siVbat[2],siVbat[3],siVbat[4],siVbat[5],siVbat[6],siVbat[7],siVbat[8],siVbat[9]);
  687. //滤波处理,排列取3个最大值,3个最大中去掉第一大,其余求平均
  688. //拷贝
  689. for(i=0;i<10;i++){
  690. iVbat[i]=siVbat[i];
  691. }
  692. for(i=0;i<4;i++){
  693. max[i]=0;
  694. for(j=0;j<10;j++){
  695. if(iVbat[j]>max[i]){
  696. max[i]=iVbat[j];
  697. k=j;
  698. }
  699. }
  700. iVbat[k]=0;
  701. }
  702. // printf("%d,%d,%d\r\n",max[0],max[1],max[2]);
  703. sum=max[1]+max[2];
  704. if(max[2]<200)return -1;
  705. Vbat=sum*340/4096;
  706. if(g_ucUARTSel==COM_SEL_MCU){
  707. // sprintf(buf,"Vbat=%d\r\n",Vbat);
  708. // SlwTrace(DEBUG,buf);
  709. //printf("Vbat=%d\r\n",Vbat);
  710. }
  711. return Vbat;
  712. }
  713. /*******************************************************
  714. *CheckVbat
  715. *检查电池电压,控制低压报警,
  716. *低压关机已由硬件监测
  717. ******************************************************/
  718. void CheckVbat(int Vbat)
  719. {
  720. if(Vbat<355){
  721. LedSlecet(LED_SEL_RED);
  722. }else{
  723. LedSlecet(LED_SEL_BLUE);
  724. }
  725. //
  726. // if(Vbat>390){
  727. // //电量3级
  728. // // SetLedFlash(3,3);
  729. // }else if(Vbat>365){
  730. // //电量2级
  731. // // SetLedFlash(2,3);
  732. // }else if(Vbat>355){
  733. // //电量1级 3575CF913100A77E
  734. // // SetLedFlash(1,3);
  735. // }else if(Vbat>333){
  736. // //电量不足 3575CF910D4EB38D
  737. // // ModemSendAT("AT+ZTTS=1,\"3575CF910D4EB38D\"\r\n");
  738. // // SetLedFlash(1,5);
  739. // }else {
  740. //
  741. // }
  742. }
  743. /**************************************************************************
  744. *语音播报电量,用户按键查询电量时播报
  745. 信号较强 "E14FF753838F3A5F"
  746. 信号适中 "E14FF75302902D4E"
  747. 信号偏低 "E14FF7534F504E4F"
  748. 信号很弱 "E14FF753885F315F"
  749. **************************************************************************/
  750. void ReportVbat(int Vbat)
  751. {
  752. char buf[20];
  753. if(Vbat<100)return;
  754. //sprintf(buf,"Vbat=%d\r\n",Vbat);
  755. // SlwTrace(INF,buf);
  756. if(Vbat>390){
  757. //电量3级 "3575CF913300A77E" 电量充足 "3575CF914551B38D"
  758. ModemSendAT("AT+ZTTS=1,\"3575CF914551B38D\"\r\n");
  759. }else if(Vbat>365){
  760. //电量2级 "3575CF913200A77E" 电量适中 "3575CF9102902D4E"
  761. ModemSendAT("AT+ZTTS=1,\"3575CF9102902D4E\"\r\n");
  762. }else if(Vbat>355){
  763. //电量1级 "3575CF913100A77E" 电量偏低 "3575CF914F504E4F"
  764. ModemSendAT("AT+ZTTS=1,\"3575CF914F504E4F\"\r\n");
  765. }else{
  766. //电量不足 "3575CF910D4EB38D"
  767. ModemSendAT("AT+ZTTS=1,\"3575CF910D4EB38D\"\r\n");
  768. }
  769. }
  770. /**************************************************************************
  771. *语音播报信号强度
  772. 信号较强 "E14FF753838F3A5F"
  773. 信号适中 "E14FF75302902D4E"
  774. 信号偏低 "E14FF7534F504E4F"
  775. 信号很弱 "E14FF753885F315F"
  776. **************************************************************************/
  777. void ReportCSQ(int CSQ)
  778. {
  779. char buf[20];
  780. sprintf(buf,"CSQ=%d\r\n",(int)CSQ);
  781. SlwTrace(INF,buf);
  782. if(CSQ>31 || CSQ<1){
  783. //无网络信号 "E065517FDC7EE14FF753"
  784. ModemSendAT("AT+ZTTS=1,\"E065517FDC7EE14FF753\"\r\n");
  785. return;
  786. }
  787. if(CSQ>25){
  788. //信号较强 "E14FF753838F3A5F"
  789. ModemSendAT("AT+ZTTS=1,\"E14FF753838F3A5F\"\r\n");
  790. }else if(CSQ>17){
  791. //信号适中 "E14FF75302902D4E"
  792. ModemSendAT("AT+ZTTS=1,\"E14FF75302902D4E\"\r\n");
  793. }else if(CSQ>10){
  794. //信号偏低 "E14FF7534F504E4F"
  795. ModemSendAT("AT+ZTTS=1,\"E14FF7534F504E4F\"\r\n");
  796. }else{
  797. //信号很弱 "E14FF753885F315F"
  798. ModemSendAT("AT+ZTTS=1,\"E14FF753885F315F\"\r\n");
  799. }
  800. }
  801. void ReportModemVer(int ver)
  802. {
  803. char temp[10];
  804. char buf[50];
  805. int i,j,len;
  806. //106:310030003100
  807. sprintf(temp,"%d",ver);//0x31 0x30 0x36
  808. len=strlen(temp);
  809. j=0;
  810. for(i=0;i<len;i++){
  811. buf[j++]=0x30+temp[i]/16;
  812. buf[j++]=0x30+temp[i]%16;
  813. buf[j++]=0x30;
  814. buf[j++]=0x30;
  815. }
  816. buf[j]=0;
  817. strcat(buf,"\"\r\n");
  818. ModemSendAT("AT+ZTTS=1,\"F95BB28B48722C67"); //对讲版本 F95BB28B48722C67
  819. ModemSendAT(buf);
  820. }
  821. void ReportMcuVer(int ver)
  822. {
  823. char temp[10];
  824. char buf[50];
  825. int i,j,len;
  826. sprintf(temp,"%d",ver);//0x31 0x30 0x36
  827. len=strlen(temp);
  828. j=0;
  829. for(i=0;i<len;i++){
  830. buf[j++]=0x30+temp[i]/16;
  831. buf[j++]=0x30+temp[i]%16;
  832. buf[j++]=0x30;
  833. buf[j++]=0x30;
  834. }
  835. buf[j]=0;
  836. strcat(buf,"\"\r\n");
  837. ModemSendAT("AT+ZTTS=1,\"945E287548722C67"); //对讲版本 F95BB28B48722C67
  838. ModemSendAT(buf);
  839. }
  840. /*******************************************************************
  841. *GetParaFromStr
  842. *从Str中找到Para=后面至';'或非字符的字串并放入Value
  843. 返回Value的长度
  844. 举例:Str="GT+SMP=IP=192.168.1.1;Port=12345"
  845. 如果Para="Port" 则Value将被赋值为"12345",并返回5
  846. 如果Para="IP" 则Value将被赋值为"192.168.1.1",并返回11
  847. 要求Para长度不大于20字节
  848. ********************************************************************/
  849. int GetParaFromStr(char *Str,char *Para,char *Value)
  850. {
  851. int ValueLen=0,ParaLen=0;
  852. char ParaTemp[22];
  853. char *p;
  854. char d;
  855. int i=0;
  856. if(0==*Str || 0==*Para)return 0;
  857. while(0!=(d=*Para) && ParaLen<20){
  858. ParaTemp[i++]=d;
  859. if(d=='=' || d==';')return 0;
  860. Para++;
  861. ParaLen++;
  862. }
  863. ParaTemp[ParaLen++]='=';
  864. ParaTemp[ParaLen]=0;
  865. p=strstr(Str,ParaTemp);
  866. p+=ParaLen;
  867. //--
  868. while(*p>0x20 && ';'!=*p){
  869. *Value=*p;
  870. p++;
  871. Value++;
  872. ValueLen++;
  873. }
  874. *Value=0;
  875. return ValueLen;
  876. }
  877. /********************************************************************
  878. *SavePsnToFlash
  879. *********************************************************************/
  880. void SavePsnToFlash(unsigned long PSN)
  881. {
  882. unsigned short psn1,psn2;
  883. psn1=(unsigned short)((PSN>>16)&0xffff);
  884. psn2=(unsigned short)(PSN&0xffff);
  885. FLASH_Unlock();
  886. FLASH_ClearFlag(FLASH_FLAG_EOP|FLASH_FLAG_PGERR|FLASH_FLAG_WRPRTERR);
  887. FLASH_ErasePage(0x0801FC00); //
  888. FLASH_ProgramHalfWord(FLASH_PAGE_ADDR_PARA,psn1); //flash 为一个字节存储,16位数据必须地址加2
  889. FLASH_ProgramHalfWord(FLASH_PAGE_ADDR_PARA+2,psn2); //flash 为一个字节存储,16位数据必须地址加2
  890. FLASH_Lock();
  891. }
  892. /********************************************************************
  893. *ReadPsnFromFlash
  894. *********************************************************************/
  895. unsigned long ReadPsnFromFlash(void)
  896. {
  897. unsigned short psn1,psn2;
  898. unsigned long PSN;
  899. psn1=*(u16*)FLASH_PAGE_ADDR_PARA;
  900. psn2=*(u16*)(FLASH_PAGE_ADDR_PARA+2);
  901. PSN=(unsigned long)psn1;
  902. PSN<<=16;
  903. PSN+=(unsigned long)psn2;
  904. return PSN;
  905. }
  906. /********************************************************************
  907. *SaveParaToFlash
  908. 将sutNetPara重要参数保存到FLASH
  909. *********************************************************************/
  910. void SaveParaToFlash(void)
  911. {
  912. int i;
  913. unsigned short *pData=(unsigned short *)&sutNetPara;
  914. unsigned char rand=sutNetPara.Rand;
  915. //保存
  916. FLASH_Unlock();
  917. FLASH_ClearFlag(FLASH_FLAG_EOP|FLASH_FLAG_PGERR|FLASH_FLAG_WRPRTERR);
  918. FLASH_ErasePage(FLASH_PAGE_ADDR_PARA); //
  919. for(i=0;i<sizeof(SUT_NET_PARA)/2;i++){
  920. FLASH_ProgramHalfWord(FLASH_PAGE_ADDR_PARA+i*2,*pData);
  921. pData++;
  922. }
  923. FLASH_Lock();
  924. ReadParaFromFlash();
  925. }
  926. /********************************************************************
  927. *SaveParaToFlash
  928. 将sutNetPara重要参数保存到FLASH
  929. *********************************************************************/
  930. void ReadParaFromFlash(void)
  931. {
  932. int i;
  933. unsigned short *pData=(unsigned short*)&sutNetPara;
  934. for(i=0;i<sizeof(SUT_NET_PARA)/2;i++){
  935. *pData= *(u16*)(FLASH_PAGE_ADDR_PARA+i*2);
  936. pData++;
  937. }
  938. }
  939. void IWDG_Configuration(void)
  940. {
  941. // WWDG 时钟使能
  942. RCC_APB1PeriphClockCmd(RCC_APB1Periph_WWDG, ENABLE);
  943. if(RCC_GetFlagStatus(RCC_FLAG_IWDGRST) != RESET)RCC_ClearFlag();
  944. //写入0x5555,用于允许狗狗寄存器写入功能
  945. IWDG_WriteAccessCmd(IWDG_WriteAccess_Enable);
  946. //狗狗时钟分频,40K/256=156HZ(6.4ms)
  947. IWDG_SetPrescaler(IWDG_Prescaler_256);
  948. //喂狗时间 3.2s/6.4MS=500 .注意不能大于0xfff
  949. IWDG_SetReload(500);
  950. //喂狗
  951. IWDG_ReloadCounter();
  952. //使能狗狗
  953. IWDG_Enable();
  954. }