Serial.c 38 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123
  1. /*******************************************************************************************
  2. * File Name: Serial.c
  3. * Function Describe:device for serial
  4. * Relate Module:
  5. * Explain:
  6. 接收采用中断方式
  7. UART1: 连接尾插,用于与PC相连 另外,printf映射到UART1
  8. UART2: 连接GPS
  9. UART3: 连接Modem
  10. 全局变量g_ucUARTSel 调试选择控制,决定了3个串口的转发关系,其值通过以下3个宏控分别代表:
  11. COM_SEL_MCU 正常使用不转发,尾插用于MCU打印LOG或 MCU软件升级
  12. COM_SEL_GPS UART1<-->UART2,尾插用于GPS LOG打印
  13. COM_SEL_MODEM UART1<-->UART3,尾插用于MODEM AT momand 或模块软件升级
  14. * Writer: ShiLiangWen
  15. * Date: 2015.1.20
  16. ********************************************************************************************/
  17. #define THIS_FILE_ID 4
  18. /* Includes ------------------------------------------------------------------*/
  19. #include "includes.h"
  20. #define USART1_DR_Base 0x40013804
  21. #define USART2_DR_Base 0x40004404
  22. #define USART3_DR_Base (u32)&USART3->DR
  23. unsigned char g_ucUARTSel=COM_SEL_MCU;//0--MCU 1--Modem 2--GPS
  24. unsigned short g_usUSART_WordLength = 0x0000;//用于串口初始化,无校验位时为0x0000,有校验位时为0x1000
  25. unsigned char g_ucDebugLog=0;//0--不打印DEBUG信息 1--打印DEBUG信息
  26. //UART1 对外接口
  27. unsigned char RxBuffer1[UART1_RX_BUFFER_SIZE];
  28. unsigned char TxBuffer1[UART1_TX_BUFFER_SIZE];
  29. unsigned char ModbusBuf[UART1_RX_BUFFER_SIZE];
  30. static unsigned short rx1_ct;
  31. static unsigned char rx1_ct_max=0;
  32. unsigned char g_ucUart1Sending;
  33. unsigned char g_usUart1RecvLen=0;
  34. //UART3 用于与MODEM通讯
  35. unsigned char RxBuffer3[UART3_RX_BUFFER_SIZE];
  36. unsigned char TxBuffer3[UART3_TX_BUFFER_SIZE];
  37. static unsigned short susRx3In=0;
  38. static unsigned short susRx3Len=0;
  39. static unsigned short susRx3Out=0;
  40. //UART2 用于与GPS通讯
  41. unsigned char RxBuffer2[UART2_RX_BUFFER_SIZE];
  42. static unsigned short rx2_ct;
  43. unsigned short g_usRx2Len;
  44. /********************************************************************
  45. *Uart1DMAInit
  46. *串口1 DMA设置
  47. *串口1 发送必须用通道4,接收必须用通道5
  48. *********************************************************************/
  49. void Uart1DMAInit(void)
  50. {
  51. NVIC_InitTypeDef NVIC_InitStructure;
  52. DMA_InitTypeDef DMA_InitStructure;
  53. //启动DMA时钟
  54. RCC_AHBPeriphClockCmd(RCC_AHBPeriph_DMA1, ENABLE);
  55. #if UART1_TX_USE_DMA!=0
  56. //DMA 通道4用于UART1 TX
  57. DMA_DeInit(DMA1_Channel4);
  58. DMA_InitStructure.DMA_PeripheralBaseAddr = (u32)(&USART1->DR);//外设地址
  59. DMA_InitStructure.DMA_MemoryBaseAddr = (uint32_t)TxBuffer1;//内存地址
  60. DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralDST;//DMA传输方向单向
  61. DMA_InitStructure.DMA_BufferSize = UART1_TX_BUFFER_SIZE; //设置DMA在传输时缓冲区的长度
  62. DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable; //设置DMA的外设递增模式
  63. DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable; //设置DMA的内存递增模式
  64. DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_Byte;//外设数据字长
  65. DMA_InitStructure.DMA_MemoryDataSize = DMA_PeripheralDataSize_Byte;//内存数据字长
  66. DMA_InitStructure.DMA_Mode = DMA_Mode_Normal; //设置DMA的传输模式
  67. DMA_InitStructure.DMA_Priority = DMA_Priority_Low; //设置DMA的优先级别
  68. DMA_InitStructure.DMA_M2M = DMA_M2M_Disable;//设置DMA的2个memory中的变量互相访问
  69. DMA_Init(DMA1_Channel4,&DMA_InitStructure);
  70. // //DMA中断设置
  71. // NVIC_InitStructure.NVIC_IRQChannel = DMA1_Channel4_IRQn;
  72. // NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1;
  73. // NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1;
  74. // NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
  75. // NVIC_Init(&NVIC_InitStructure);
  76. DMA_ITConfig(DMA1_Channel4,DMA_IT_TC,ENABLE);//中断设置
  77. DMA_Cmd(DMA1_Channel4, DISABLE); //等到需要发送的时候再使能
  78. #endif
  79. //DMA 通道5用于UART1 RX
  80. DMA_DeInit(DMA1_Channel5);
  81. DMA_InitStructure.DMA_PeripheralBaseAddr = (u32)(&USART1->DR);//外设地址
  82. DMA_InitStructure.DMA_MemoryBaseAddr = (uint32_t)RxBuffer1;//内存地址
  83. DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralSRC;//DMA传输方向单向
  84. DMA_InitStructure.DMA_BufferSize = UART1_RX_BUFFER_SIZE; //设置DMA在传输时缓冲区的长度
  85. DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable; //设置DMA的外设递增模式
  86. DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable; //设置DMA的内存递增模式
  87. DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_Byte;//外设数据字长
  88. DMA_InitStructure.DMA_MemoryDataSize = DMA_PeripheralDataSize_Byte;//内存数据字长
  89. DMA_InitStructure.DMA_Mode = DMA_Mode_Normal; //设置DMA的传输模式
  90. DMA_InitStructure.DMA_Priority = DMA_Priority_High; //设置DMA的优先级别
  91. DMA_InitStructure.DMA_M2M = DMA_M2M_Disable;//设置DMA的2个memory中的变量互相访问
  92. DMA_Init(DMA1_Channel5,&DMA_InitStructure);
  93. DMA_Cmd(DMA1_Channel5, ENABLE); //使能通道
  94. }
  95. /********************************************************************
  96. *Uart3DMAInit
  97. *串口3 DMA设置
  98. *串口3 发送必须用通道2,接收必须用通道3
  99. *********************************************************************/
  100. /*
  101. void Uart3DMAInit(void)
  102. {
  103. NVIC_InitTypeDef NVIC_InitStructure;
  104. DMA_InitTypeDef DMA_InitStructure;
  105. //启动DMA时钟
  106. RCC_AHBPeriphClockCmd(RCC_AHBPeriph_DMA1, ENABLE);
  107. //DMA 通道2用于UART3 TX
  108. DMA_DeInit(DMA1_Channel2);
  109. DMA_InitStructure.DMA_PeripheralBaseAddr = (u32)(&USART3->DR);//外设地址
  110. DMA_InitStructure.DMA_MemoryBaseAddr = (uint32_t)TxBuffer3;//内存地址
  111. DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralDST;//DMA传输方向单向
  112. DMA_InitStructure.DMA_BufferSize = UART3_TX_BUFFER_SIZE; //设置DMA在传输时缓冲区的长度
  113. DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable; //设置DMA的外设递增模式
  114. DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable; //设置DMA的内存递增模式
  115. DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_Byte;//外设数据字长
  116. DMA_InitStructure.DMA_MemoryDataSize = DMA_PeripheralDataSize_Byte;//内存数据字长
  117. DMA_InitStructure.DMA_Mode = DMA_Mode_Normal; //设置DMA的传输模式
  118. DMA_InitStructure.DMA_Priority = DMA_Priority_High; //设置DMA的优先级别
  119. DMA_InitStructure.DMA_M2M = DMA_M2M_Disable;//设置DMA的2个memory中的变量互相访问
  120. DMA_Init(DMA1_Channel2,&DMA_InitStructure);
  121. //DMA中断设置
  122. // NVIC_InitStructure.NVIC_IRQChannel = DMA1_Channel2_IRQn;
  123. // NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 3;
  124. // NVIC_InitStructure.NVIC_IRQChannelSubPriority = 2;
  125. // NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
  126. // NVIC_Init(&NVIC_InitStructure);
  127. DMA_ITConfig(DMA1_Channel2,DMA_IT_TC,ENABLE);//中断设置
  128. DMA_Cmd(DMA1_Channel2, DISABLE); //等到需要发送的时候再使能
  129. //DMA 通道3用于UART3 RX
  130. DMA_DeInit(DMA1_Channel3);
  131. DMA_InitStructure.DMA_PeripheralBaseAddr = (u32)(&USART3->DR);//外设地址
  132. DMA_InitStructure.DMA_MemoryBaseAddr = (uint32_t)RxBuffer3;//内存地址
  133. DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralSRC;//DMA传输方向单向
  134. DMA_InitStructure.DMA_BufferSize = UART3_RX_BUFFER_SIZE; //设置DMA在传输时缓冲区的长度
  135. DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable; //设置DMA的外设递增模式
  136. DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable; //设置DMA的内存递增模式
  137. DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_Byte;//外设数据字长
  138. DMA_InitStructure.DMA_MemoryDataSize = DMA_PeripheralDataSize_Byte;//内存数据字长
  139. DMA_InitStructure.DMA_Mode = DMA_Mode_Normal; //设置DMA的传输模式
  140. DMA_InitStructure.DMA_Priority = DMA_Priority_VeryHigh; //设置DMA的优先级别
  141. DMA_InitStructure.DMA_M2M = DMA_M2M_Disable;//设置DMA的2个memory中的变量互相访问
  142. DMA_Init(DMA1_Channel3,&DMA_InitStructure);
  143. DMA_Cmd(DMA1_Channel3, DISABLE); //使能通道
  144. }
  145. */
  146. extern unsigned short atous(char *pMsg);
  147. static unsigned char uart_data_last=0;
  148. /*
  149. Use for Modem
  150. */
  151. void UART3RxTxISRHandler(void)
  152. {
  153. __IO unsigned char uart_data;
  154. unsigned short len;
  155. static unsigned char GSAFlag=0;
  156. if(USART_GetITStatus(USART3, USART_IT_RXNE) != RESET)
  157. {
  158. uart_data = USART_ReceiveData(USART3); // Read one byte from the receive data register
  159. if(g_ucUARTSel==COM_SEL_MODEM){
  160. USART_SendData(USART1,uart_data);
  161. }else{
  162. if(susRx3Len<UART3_RX_BUFFER_SIZE){
  163. RxBuffer3[susRx3In]=uart_data;
  164. if(++susRx3In>=UART3_RX_BUFFER_SIZE)susRx3In=0;
  165. susRx3Len++;
  166. }
  167. isr_sem_send(&ModemUartSem);
  168. }
  169. USART_ClearITPendingBit(USART3, USART_IT_RXNE);
  170. }
  171. //---
  172. if(USART_GetFlagStatus(USART3,USART_FLAG_ORE)==SET)
  173. {
  174. USART_ReceiveData(USART3); //
  175. USART_ClearFlag(USART3,USART_FLAG_ORE); //
  176. }
  177. }
  178. static unsigned short susTcpRecvDataLen=0;//如果是$MYNETREAD: 0,8的AT响应,则应该记录其长度并存放在susTcpRecvDataLen中,然后其后的与长度相匹配数据也一起打包成应用层的消息
  179. /**********************************************************************
  180. Uart3RecvProcess
  181. 从UART3接收缓冲区RxBuffer3中提取消息,放入环形消息队列Uart3MsgQueue中
  182. RxBuffer3也是环形缓冲区。
  183. 需要处理以下几种消息:
  184. (1)长度为1的'>' 消息。
  185. (2)非+QIURC: "recv"开头,以\r\n结尾的消息
  186. (3)以+QIURC: "recv"开头,以\r\n结尾的消息,这种消息需要处理中间接收数据中可能存在\r\n,避免分包需要一并处理
  187. +QIURC: "recv",0,20
  188. ************************************************************************/
  189. void Uart3RecvProcess(void)
  190. {
  191. char data;
  192. unsigned short RxLen,out;
  193. char preData[10];
  194. char lastData1,lastData2;
  195. unsigned short i,j;
  196. static const char RECVHEAD[]={'+','Q','I','U','R','C',':',' ','\"','r','e','c','v','\"',','};//+QIURC: "recv",
  197. RunMake(THIS_FILE_ID);
  198. //处理只有'>'的消息
  199. if(susRx3Len==1){
  200. USART_ITConfig(USART3, USART_IT_RXNE, DISABLE); //关闭串口接收中断
  201. i=susRx3In;
  202. RxLen=susRx3Len;
  203. USART_ITConfig(USART3, USART_IT_RXNE, ENABLE); //打开串口接收中断
  204. if(i>0)i--;
  205. else i=UART3_RX_BUFFER_SIZE-1;
  206. lastData1=RxBuffer3[i];
  207. if(lastData1=='>'){
  208. MsgQueuePostLoopBuf(&ModemMsgQueue,(char *)RxBuffer3,UART3_RX_BUFFER_SIZE,susRx3Out,RxLen);
  209. susRx3Out=(susRx3Out+RxLen)%UART3_RX_BUFFER_SIZE;
  210. USART_ITConfig(USART3, USART_IT_RXNE, DISABLE); //关闭串口接收中断
  211. susRx3Len=susRx3Len-RxLen;
  212. USART_ITConfig(USART3, USART_IT_RXNE, ENABLE); //打开串口接收中断
  213. return;
  214. }
  215. }
  216. //处理其他消息,其他消息必须以\r\n作为结束符,因此至少2字节长度,
  217. if(susRx3Len<2){
  218. return;
  219. }
  220. //如果长度溢出,清空并重置缓冲区。
  221. if(susRx3Len>(UART3_RX_BUFFER_SIZE-2)){
  222. USART_ITConfig(USART3, USART_IT_RXNE, DISABLE); //关闭串口接收中断
  223. susRx3In=0;
  224. susRx3Out=0;
  225. susRx3Len=0;
  226. USART_ITConfig(USART3, USART_IT_RXNE, ENABLE); //打开串口接收中断
  227. SlwTrace(DEBUG,"[Rx3Buf Over]\r\n");
  228. RunMake(THIS_FILE_ID);
  229. return;
  230. }
  231. //获取当前缓冲区中最后的两个字节并存放在lastData1和lastData2中,并记录下当前长度放在RxLen中
  232. USART_ITConfig(USART3, USART_IT_RXNE, DISABLE); //关闭串口接收中断
  233. i=susRx3In;
  234. RxLen=susRx3Len;
  235. USART_ITConfig(USART3, USART_IT_RXNE, ENABLE); //打开串口接收中断
  236. if(i>0)i--;
  237. else i=UART3_RX_BUFFER_SIZE-1;
  238. lastData1=RxBuffer3[i];
  239. if(i>0)i--;
  240. else i=UART3_RX_BUFFER_SIZE-1;
  241. lastData2=RxBuffer3[i];
  242. if(lastData2!='\r' || lastData1!='\n')return;
  243. if(RxLen==2){//只有\r\n的消息抛弃掉
  244. //更新环形缓冲区读指针和数据长度
  245. susRx3Out=(susRx3Out+RxLen)%UART3_RX_BUFFER_SIZE;
  246. USART_ITConfig(USART3, USART_IT_RXNE, DISABLE); //关闭串口接收中断
  247. susRx3Len=susRx3Len-RxLen;
  248. USART_ITConfig(USART3, USART_IT_RXNE, ENABLE); //打开串口接收中断
  249. return;
  250. }
  251. //+QIURC: "recv",x,y\r\n
  252. if(susTcpRecvDataLen==0){
  253. if(RxLen>19){//如果缓冲区里的数据大于19字节,则先需要判断是否为+QIURC: "recv",x,y\r\n 如果是则需要和后续的数据合并
  254. //预读15个字节,然后判断是否等于+QIURC: "recv",
  255. out=susRx3Out;
  256. for(i=0;i<sizeof(RECVHEAD);i++){
  257. data=RxBuffer3[out];
  258. if(++out>UART3_RX_BUFFER_SIZE)out=0;
  259. if(data!=RECVHEAD[i])break;
  260. }
  261. if(i==sizeof(RECVHEAD)){//等于RECVHEAD 则需要和后续的数据进行合并
  262. //因此继续读后面的数据,取RECVHEAD,x,y中的y 并转为整数存在susTcpRecvDataLen中
  263. if(++out>UART3_RX_BUFFER_SIZE)out=0;//,
  264. if(++out>UART3_RX_BUFFER_SIZE)out=0;//y
  265. for(i=0;i<4;i++){//1234
  266. preData[i]=RxBuffer3[out];
  267. if(++out>UART3_RX_BUFFER_SIZE)out=0;
  268. }
  269. preData[i]=0;
  270. susTcpRecvDataLen=atoi(preData);
  271. //printf("L=%d\r\n",susTcpRecvDataLen);
  272. //在此要判断一下susTcpRecvDataLen的值,如果是0,则将此包立刻输出应用层消息,否则会进入死循环
  273. if(susTcpRecvDataLen == 0){
  274. MsgQueuePostLoopBuf(&ModemMsgQueue,(char *)RxBuffer3,UART3_RX_BUFFER_SIZE,susRx3Out,RxLen);
  275. //更新环形缓冲区读指针和数据长度
  276. susRx3Out=(susRx3Out+RxLen)%UART3_RX_BUFFER_SIZE;
  277. USART_ITConfig(USART3, USART_IT_RXNE, DISABLE); //关闭串口接收中断
  278. susRx3Len=susRx3Len-RxLen;
  279. USART_ITConfig(USART3, USART_IT_RXNE, ENABLE); //打开串口接收中断
  280. }
  281. }else{//非RECVHEAD 开头的,则认为已是完整的消息,直接产生应用层消息。
  282. MsgQueuePostLoopBuf(&ModemMsgQueue,(char *)RxBuffer3,UART3_RX_BUFFER_SIZE,susRx3Out,RxLen);
  283. //更新环形缓冲区读指针和数据长度
  284. susRx3Out=(susRx3Out+RxLen)%UART3_RX_BUFFER_SIZE;
  285. USART_ITConfig(USART3, USART_IT_RXNE, DISABLE); //关闭串口接收中断
  286. susRx3Len=susRx3Len-RxLen;
  287. USART_ITConfig(USART3, USART_IT_RXNE, ENABLE); //打开串口接收中断
  288. }
  289. }else{//长度小于19字节,当然是非RECVHEAD消息了,那就认为已是完整的消息,直接产生应用层消息。
  290. MsgQueuePostLoopBuf(&ModemMsgQueue,(char *)RxBuffer3,UART3_RX_BUFFER_SIZE,susRx3Out,RxLen);
  291. //更新环形缓冲区读指针和数据长度
  292. susRx3Out=(susRx3Out+RxLen)%UART3_RX_BUFFER_SIZE;
  293. USART_ITConfig(USART3, USART_IT_RXNE, DISABLE); //关闭串口接收中断
  294. susRx3Len=susRx3Len-RxLen;
  295. USART_ITConfig(USART3, USART_IT_RXNE, ENABLE); //打开串口接收中断
  296. }
  297. }else{
  298. //比如:+QIURC: "recv",0,20\r\n.....
  299. //则sTcpRecvDataLen=20, 总长度=19+2+20
  300. //如果susTcpRecvDataLen是1位数,那么RxLen=susTcpRecvDataLen+20
  301. //如果susTcpRecvDataLen是2位数,那么RxLen=susTcpRecvDataLen+21
  302. //如果susTcpRecvDataLen是3位数,那么RxLen=susTcpRecvDataLen+22
  303. //如果susTcpRecvDataLen是4位数,那么RxLen=susTcpRecvDataLen+23
  304. if(susTcpRecvDataLen<10)i=susTcpRecvDataLen+20;
  305. else if(susTcpRecvDataLen<100)i=susTcpRecvDataLen+21;
  306. else if(susTcpRecvDataLen<1000)i=susTcpRecvDataLen+22;
  307. else i=susTcpRecvDataLen+23;
  308. if(RxLen>=i){//长度够了,完整的数据包,产生应用层消息
  309. MsgQueuePostLoopBuf(&ModemMsgQueue,(char *)RxBuffer3,UART3_RX_BUFFER_SIZE,susRx3Out,RxLen);
  310. //更新环形缓冲区读指针和数据长度
  311. susRx3Out=(susRx3Out+RxLen)%UART3_RX_BUFFER_SIZE;
  312. USART_ITConfig(USART3, USART_IT_RXNE, DISABLE); //关闭串口接收中断
  313. susRx3Len=susRx3Len-RxLen;
  314. USART_ITConfig(USART3, USART_IT_RXNE, ENABLE); //打开串口接收中断
  315. susTcpRecvDataLen=0;
  316. }
  317. }
  318. }
  319. /********************************************************************************
  320. *Uart1Send
  321. *串口1启动发送
  322. *********************************************************************************/
  323. /*
  324. void Uart1Send(char *txbuf,int len)
  325. {
  326. int i;
  327. unsigned char data;
  328. unsigned char last_data=~UART_TRANSFORM;
  329. //Send Head
  330. USART_SendData(USART1, UART_HEAD);
  331. while (USART_GetFlagStatus(USART1, USART_FLAG_TC) == RESET);
  332. for(i=0;i<len;i++){
  333. data= txbuf[i];
  334. if(UART_TRANSFORM == data){
  335. USART_SendData(USART1,UART_TRANSFORM );
  336. while (USART_GetFlagStatus(USART1, USART_FLAG_TC) == RESET);
  337. USART_SendData(USART1,0x01 );
  338. while (USART_GetFlagStatus(USART1, USART_FLAG_TC) == RESET);
  339. }else if(UART_HEAD == data){
  340. USART_SendData(USART1,UART_TRANSFORM);
  341. while (USART_GetFlagStatus(USART1, USART_FLAG_TC) == RESET);
  342. USART_SendData(USART1,0x02 );
  343. while (USART_GetFlagStatus(USART1, USART_FLAG_TC) == RESET);
  344. }else if(UART_END == data){
  345. USART_SendData(USART1,UART_TRANSFORM);
  346. while (USART_GetFlagStatus(USART1, USART_FLAG_TC) == RESET);
  347. USART_SendData(USART1,0x03 );
  348. while (USART_GetFlagStatus(USART1, USART_FLAG_TC) == RESET);
  349. }else{
  350. USART_SendData(USART1,data);
  351. while (USART_GetFlagStatus(USART1, USART_FLAG_TC) == RESET);
  352. }
  353. }
  354. //Send End
  355. USART_SendData(USART1, UART_END);
  356. while (USART_GetFlagStatus(USART1, USART_FLAG_TC) == RESET);
  357. }
  358. */
  359. void Uart1Send(char *txbuf,int len)
  360. {
  361. int i;
  362. RS485_DIR_HIGH;
  363. for(i=0;i<len;i++){
  364. USART_SendData(USART1,txbuf[i]);
  365. while (USART_GetFlagStatus(USART1, USART_FLAG_TC) == RESET);
  366. }
  367. RS485_DIR_LOW;
  368. }
  369. void Uart2Send(char *txbuf,int len)
  370. {
  371. int i;
  372. for(i=0;i<len;i++){
  373. USART_SendData(USART2,txbuf[i]);
  374. while (USART_GetFlagStatus(USART2, USART_FLAG_TC) == RESET);
  375. }
  376. }
  377. void Uart3Send(char *txbuf,int len)
  378. {
  379. int i;
  380. for(i=0;i<len;i++){
  381. USART_SendData(USART3,txbuf[i]);
  382. while (USART_GetFlagStatus(USART3, USART_FLAG_TC) == RESET);
  383. }
  384. }
  385. /*************************************************************************************
  386. * 函数名:USART1_Send
  387. * 描述 :串口1发送数据函数 通过DMA实现
  388. * 输入 :要发送数据的首地址,发送数据的个数。发送数据的地址任意,并不用固定为Txd1Buffer
  389. * 输出 : 无
  390. * 举例 :Usart1_Send("Hello word!",11); Usart1_Send(Txd1Buffer,11);
  391. **************************************************************************************/
  392. void USART1_Send(char *pbuffer, unsigned short size)
  393. {
  394. #if UART1_TX_USE_DMA==1
  395. char buf[20];
  396. unsigned short i;
  397. unsigned short len;
  398. char *pData;
  399. if(size==0)return;
  400. //等待上一次发送完成
  401. while(g_ucUart1Sending!=0){
  402. os_dly_wait(1);
  403. }
  404. #if 0 //增加时间戳
  405. sprintf((char *)TxBuffer1,"%010u: ",os_time_get());
  406. if(size>(UART1_TX_BUFFER_SIZE-12))len=UART1_TX_BUFFER_SIZE-12;
  407. else len=size;
  408. len+=12;
  409. pData=(char *)&TxBuffer1[12];
  410. #else
  411. if(size>UART1_TX_BUFFER_SIZE)len=UART1_TX_BUFFER_SIZE;
  412. else len=size;
  413. pData=(char *)&TxBuffer1[0];
  414. #endif
  415. for(i=0;i<len;i++)pData[i]=pbuffer[i];
  416. DMA_Cmd (DMA1_Channel4,DISABLE);
  417. DMA1_Channel4->CMAR = (u32)TxBuffer1;
  418. DMA1_Channel4->CNDTR = len;
  419. g_ucUart1Sending=1;
  420. DMA_Cmd (DMA1_Channel4,ENABLE); //使能DMA,开始发送
  421. #else
  422. Uart1Send(pbuffer,size);
  423. #endif
  424. }
  425. void USART1_SendWaitCompleted(void)
  426. {
  427. #if UART1_TX_USE_DMA==1
  428. while(g_ucUart1Sending!=0){
  429. os_dly_wait(1);
  430. }
  431. #endif
  432. }
  433. //void USART2_SendWaitCompleted(void)
  434. //{
  435. //#if UART2_TX_USE_DMA==1
  436. // while(g_ucUart2Sending!=0){
  437. // os_dly_wait(1);
  438. // }
  439. //#endif
  440. //}
  441. void USART3_SendWaitCompleted(void)
  442. {
  443. #if UART3_TX_USE_DMA==1
  444. while(g_ucUart3Sending!=0){
  445. os_dly_wait(1);
  446. }
  447. #endif
  448. }
  449. /*************************************************************************************
  450. * 函数名:USART2_Send
  451. * 描述 :串口2发送数据函数
  452. * 输入 :要发送数据的首地址,发送数据的个数。发送数据的地址任意,并不用固定为Txd1Buffer
  453. * 输出 : 无
  454. * 举例 :Usart2_Send("Hello word!",11); Usart1_Send(Txd1Buffer,11);
  455. **************************************************************************************/
  456. //void USART2_Send(char *pbuffer, unsigned short size)
  457. //{
  458. //#if UART2_TX_USE_DMA==1
  459. // unsigned short i;
  460. // unsigned short len;
  461. // if(size==0)return;
  462. // //等待上一次发送完成
  463. // while(g_ucUart2Sending!=0){}
  464. //
  465. // if(size>UART2_TX_BUFFER_SIZE)len=UART2_TX_BUFFER_SIZE;
  466. // else len=size;
  467. // for(i=0;i<len;i++)DMATxBuffer2[i]=pbuffer[i];
  468. // DMA_Cmd (DMA1_Channel7,DISABLE);
  469. // DMA1_Channel7->CMAR = (u32)DMATxBuffer2;
  470. // DMA1_Channel7->CNDTR = len;
  471. // g_ucUart2Sending=1;
  472. // DMA_Cmd (DMA1_Channel7,ENABLE); //使能DMA,开始发送 //数据发送中 //灯亮
  473. // RunMake(THIS_FILE_ID);
  474. //#else
  475. // Uart2Send(pbuffer,size);
  476. //#endif
  477. //}
  478. /*************************************************************************************
  479. * 函数名:USART3_Send
  480. * 描述 :串口1发送数据函数 通过DMA实现
  481. * 输入 :要发送数据的首地址,发送数据的个数。发送数据的地址任意,并不用固定为Txd1Buffer
  482. * 输出 : 无
  483. * 举例 :Usart3_Send("Hello word!",11); Usart3_Send(Txd3Buffer,11);
  484. **************************************************************************************/
  485. void USART3_Send(char *pbuffer, unsigned short size)
  486. {
  487. #if UART3_TX_USE_DMA==1
  488. unsigned short i;
  489. if(size==0 || size>UART3_TX_BUFFER_SIZE)return;
  490. //等待上一次发送完成
  491. while(g_ucUart3Sending!=0){
  492. os_dly_wait(1);
  493. }
  494. for(i=0;i<size;i++){
  495. TxBuffer3[i]=pbuffer[i];
  496. }
  497. DMA_Cmd (DMA1_Channel2,DISABLE);
  498. DMA1_Channel2->CMAR = (u32)TxBuffer3;
  499. DMA1_Channel2->CNDTR = size;
  500. g_ucUart3Sending=1;
  501. DMA_Cmd (DMA1_Channel2,ENABLE); //使能DMA,开始发送 //数据发送中
  502. //灯亮
  503. #else
  504. Uart3Send(pbuffer,size);
  505. #endif
  506. }
  507. /*********************************************************************************************
  508. *UART1RxTxISRHandler
  509. *串口1中断处理函数
  510. 通讯协议
  511. RxBuffer1接收缓冲区
  512. sutMsg.Uart1Recv为1表明接受到一包数据,需要应用层处理数据后将其清零以便接受新的数据包
  513. 每包数据均以UART_HEAD开头,UART_END结尾。如解决数据包内容刚好有与UART_HEAD或UART_END相等的值,则需要转义
  514. 转义字符为UART_TRANSFORM,当收到UART_TRANSFORM开头时将根据紧挨其后的字符决定转义
  515. 如UART_HEAD=0x7a UART_END=0x7b UART_TRANSFORM=0x7c
  516. 如拟发送数据为: 01 02 7a 03 04 7b 05 06 7c 08 09 经过转换后的数据包为:
  517. 01 02 7c 02 03 04 7c 03 05 06 7c 01 08 09
  518. 加上包头包尾后:
  519. 7a 01 02 7c 02 03 04 7c 03 05 06 7c 01 08 09 7b
  520. **********************************************************************************************
  521. void UART1RxTxISRHandler(void)
  522. {
  523. __IO unsigned char uart_data;
  524. __IO static unsigned char last_data;
  525. //----接收中断--------
  526. if(USART_GetITStatus(USART1, USART_IT_RXNE) != RESET)
  527. {
  528. uart_data = USART_ReceiveData(USART1);
  529. if(sutMsg.Uart1Recv){//上一批没处理,不接受新数据
  530. USART_ClearITPendingBit(USART1, USART_IT_RXNE); //清除中断标志
  531. rx1_ct=0;
  532. return;
  533. }
  534. if(uart_data==UART_HEAD){//包头
  535. RxBuffer1[0]=UART_HEAD;
  536. rx1_ct=1;
  537. }else if(rx1_ct>=(UART1_RX_BUFFER_SIZE-1)){//超出接受缓冲区,丢掉此包数据,复位重新接收
  538. rx1_ct=0;
  539. }else if(rx1_ct>0){
  540. if(uart_data==UART_END){//包尾
  541. RxBuffer1[rx1_ct++]=uart_data;
  542. rx1_len=rx1_ct;
  543. rx1_ct=0;
  544. sutMsg.Uart1Recv=1;
  545. }else if(uart_data==UART_TRANSFORM){//转义字符,忽略
  546. }else{
  547. if(last_data==UART_TRANSFORM){
  548. if(0x01==uart_data)RxBuffer1[rx1_ct++]=UART_TRANSFORM;
  549. else if(0x02==uart_data)RxBuffer1[rx1_ct++]=UART_HEAD;
  550. else if(0x03==uart_data)RxBuffer1[rx1_ct++]=UART_END;
  551. }else{
  552. RxBuffer1[rx1_ct++]=uart_data;
  553. }
  554. }
  555. }
  556. last_data=uart_data;
  557. USART_ClearITPendingBit(USART1, USART_IT_RXNE); //清除中断标志
  558. }
  559. }
  560. */
  561. unsigned char max_len=0;
  562. /*********************************************************************************************
  563. *UART1RxTxISRHandler
  564. *串口1中断处理函数
  565. **********************************************************************************************/
  566. void UART1RxTxISRHandler(void)
  567. {
  568. __IO unsigned char uart_data;
  569. __IO static unsigned char uart_last_data;
  570. static unsigned short len,cnt=0;
  571. //----接收中断--------
  572. if(USART_GetITStatus(USART1, USART_IT_IDLE) != RESET)
  573. {
  574. len = USART1->SR;//先读SR,再读DR
  575. len = USART1->DR;//方可清USART_IT_IDLE标志
  576. // len = UART1_RX_BUFFER_SIZE - DMA1_Channel5->CNDTR;
  577. // DMA_Cmd(DMA1_Channel5,DISABLE);
  578. //// if(g_usUart1RecvLen==0){
  579. //// memcpy(ModbusBuf,RxBuffer1,len);
  580. //// g_usUart1RecvLen=len;
  581. //// }
  582. // DMA1_Channel5->CNDTR = UART1_RX_BUFFER_SIZE;
  583. // DMA_Cmd(DMA1_Channel5,ENABLE);
  584. }
  585. if(USART_GetITStatus(USART1, USART_IT_RXNE) != RESET)
  586. {
  587. uart_data = USART_ReceiveData(USART1);
  588. USART_ClearITPendingBit(USART1, USART_IT_RXNE); //清除中断标志
  589. if(g_ucUARTSel==COM_SEL_MODEM){
  590. USART_SendData(USART3,uart_data);
  591. }else{
  592. if(g_usUart1RecvLen!=0){//上一包数据未处理完,不处理新来的数据,直接扔掉!
  593. cnt=0;
  594. return;
  595. }
  596. RxBuffer1[cnt++]=uart_data;
  597. #if 1
  598. if(RxBuffer1[0] == 'R'){//检测RT+TM指令
  599. if((cnt >= 2 && RxBuffer1[1] != 'T') ||
  600. (cnt >= 3 && RxBuffer1[2] != '+')){
  601. cnt=0;
  602. }else if(uart_last_data=='\r' && uart_data=='\n'){
  603. g_usUart1RecvLen=cnt;
  604. cnt=0;
  605. }
  606. }else if(RxBuffer1[0] == PRO_HEADER){
  607. if(cnt >= 3){
  608. len=RxBuffer1[2]+3;//总接收长度
  609. if(cnt>=len){//收够一包长度了
  610. g_usUart1RecvLen=cnt;
  611. cnt=0;
  612. }
  613. }
  614. }else{//命令不认可
  615. cnt=0;
  616. RxBuffer1[0]=0;
  617. }
  618. #else
  619. if(rx1_ct>2){
  620. if( RxBuffer1[0]==0xAA && RxBuffer1[1]==0xBB){
  621. if(rx1_ct==3)max_len=uart_data;
  622. else if(rx1_ct>max_len){
  623. rx1_ct=0;
  624. max_len=0;
  625. RxBuffer1[0]=0;
  626. return;
  627. }
  628. if(uart_last_data==0xDD && uart_data==0x55){
  629. g_usUart1RecvLen=rx1_ct;
  630. RxBuffer1[rx1_ct]=0;//末尾补0,方便应用层调试直接打印消息内容。
  631. rx1_ct=0;
  632. }
  633. }else if((RxBuffer1[0]=='R'|| RxBuffer1[0]=='A') && RxBuffer1[1]=='T'){
  634. if(uart_last_data=='\r' && uart_data=='\n'){
  635. g_usUart1RecvLen=rx1_ct;
  636. RxBuffer1[rx1_ct]=0;//末尾补0,方便应用层调试直接打印消息内容。
  637. rx1_ct=0;
  638. max_len=0;
  639. }
  640. }else{
  641. rx1_ct=0;
  642. max_len=0;
  643. RxBuffer1[0]=0;
  644. }
  645. }else if(rx1_ct==1 && uart_data!=0xAA && uart_data!='R' && uart_data!='A'){
  646. rx1_ct=0;
  647. max_len=0;
  648. RxBuffer1[0]=0;
  649. }else if(rx1_ct==2 && uart_data!=0xBB && uart_data!='T'){
  650. rx1_ct=0;
  651. max_len=0;
  652. RxBuffer1[0]=0;
  653. }
  654. #endif
  655. if(rx1_ct>=(UART1_RX_BUFFER_SIZE-1)){//数据超过缓冲区的数据,过滤不处理
  656. rx1_ct=0;
  657. max_len=0;
  658. g_usUart1RecvLen=0;
  659. }
  660. uart_last_data=uart_data;
  661. }
  662. }
  663. //---异常中断---
  664. if(USART_GetFlagStatus(USART1,USART_FLAG_ORE)==SET)
  665. {
  666. USART_ReceiveData(USART1); //
  667. USART_ClearFlag(USART1,USART_FLAG_ORE); //
  668. }
  669. }
  670. /*******************************************************************************
  671. Uart1Init
  672. 对外接口
  673. mode=0 正常模式 采用Idel中断 波特率 9600
  674. mode=1 GPS透传模式 采用RXEN中断 波特率 9600
  675. mode=2 Modem透传模式 采用RXEN中断 波特率 115200
  676. *******************************************************************************/
  677. void Uart1Init(int mode)
  678. {
  679. NVIC_InitTypeDef NVIC_InitStructure;
  680. GPIO_InitTypeDef GPIO_InitStructure;
  681. USART_InitTypeDef USART_InitStructure;
  682. RCC_APB2PeriphClockCmd( RCC_APB2Periph_GPIOA | RCC_APB2Periph_USART1,ENABLE);
  683. /*
  684. * USART1_TX -> PA9 , USART1_RX -> PA10 , RS485_DIR -> PA8
  685. */
  686. GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9;
  687. GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
  688. GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
  689. GPIO_Init(GPIOA, &GPIO_InitStructure);
  690. GPIO_InitStructure.GPIO_Pin = GPIO_Pin_8;
  691. GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
  692. GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
  693. GPIO_Init(GPIOA, &GPIO_InitStructure);
  694. GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10;
  695. GPIO_InitStructure.GPIO_Mode =GPIO_Mode_IPU;// GPIO_Mode_IPU;//GPIO_Mode_IN_FLOATING;
  696. GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
  697. GPIO_Init(GPIOA, &GPIO_InitStructure);
  698. if(mode<2){
  699. USART_InitStructure.USART_BaudRate =115200;//9600;
  700. }else{
  701. USART_InitStructure.USART_BaudRate = 115200;
  702. }
  703. USART_InitStructure.USART_WordLength = USART_WordLength_8b;
  704. USART_InitStructure.USART_StopBits = USART_StopBits_1;
  705. USART_InitStructure.USART_Parity = USART_Parity_No;
  706. USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None;
  707. USART_InitStructure.USART_Mode = USART_Mode_Rx | USART_Mode_Tx;//
  708. USART_Init(USART1, &USART_InitStructure);
  709. USART_Cmd(USART1, ENABLE);
  710. USART_ClearFlag(USART1,USART_FLAG_TC);
  711. USART_ITConfig(USART1, USART_IT_TXE, DISABLE); //ENABLE DISABLE
  712. if(mode==0){
  713. USART_ITConfig(USART1, USART_IT_RXNE, ENABLE); //ENABLE DISABLE
  714. USART_ITConfig(USART1, USART_IT_IDLE, DISABLE); //USART_IT_IDLE USART_IT_RXNE
  715. //USART_DMACmd(USART1,USART_DMAReq_Rx,ENABLE); //使能USART1的接收DMA请求ENABLE
  716. //USART_DMACmd(USART1,USART_DMAReq_Tx,DISABLE); //使能USART1的发送DMA请求
  717. Uart1DMAInit();
  718. }else{
  719. USART_ITConfig(USART1, USART_IT_RXNE, ENABLE); //ENABLE DISABLE
  720. USART_ITConfig(USART1, USART_IT_IDLE, DISABLE); //USART_IT_IDLE USART_IT_RXNE
  721. USART_DMACmd(USART1,USART_DMAReq_Rx,DISABLE); //使能USART1的接收DMA请求ENABLE
  722. USART_DMACmd(USART1,USART_DMAReq_Tx,DISABLE); //使能USART1的发送DMA请求
  723. DMA_Cmd(DMA1_Channel5, DISABLE); //使能通道
  724. }
  725. rx1_ct=0;
  726. g_usUart1RecvLen=0;
  727. g_ucUart1Sending=0;
  728. RS485_DIR_LOW;
  729. }
  730. /********************************************************************
  731. *Uart2DMAInit
  732. *串口2 DMA设置
  733. *串口2 发送必须用通道7,接收必须用通道6
  734. *********************************************************************/
  735. //void Uart2DMAInit(void)
  736. //{
  737. // NVIC_InitTypeDef NVIC_InitStructure;
  738. // DMA_InitTypeDef DMA_InitStructure;
  739. // //启动DMA时钟
  740. // RCC_AHBPeriphClockCmd(RCC_AHBPeriph_DMA1, ENABLE);
  741. // //DMA 通道7用于UART2 TX
  742. // DMA_DeInit(DMA1_Channel7);
  743. // DMA_InitStructure.DMA_PeripheralBaseAddr = (u32)(&USART2->DR);//外设地址
  744. // DMA_InitStructure.DMA_MemoryBaseAddr = (uint32_t)TxBuffer2;//内存地址
  745. // DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralDST;//DMA传输方向单向
  746. // DMA_InitStructure.DMA_BufferSize = UART2_TX_BUFFER_SIZE; //设置DMA在传输时缓冲区的长度
  747. // DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable; //设置DMA的外设递增模式
  748. // DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable; //设置DMA的内存递增模式
  749. // DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_Byte;//外设数据字长
  750. // DMA_InitStructure.DMA_MemoryDataSize = DMA_PeripheralDataSize_Byte;//内存数据字长
  751. // DMA_InitStructure.DMA_Mode = DMA_Mode_Normal; //设置DMA的传输模式
  752. // DMA_InitStructure.DMA_Priority = DMA_Priority_Low; //设置DMA的优先级别
  753. // DMA_InitStructure.DMA_M2M = DMA_M2M_Disable;//设置DMA的2个memory中的变量互相访问
  754. // DMA_Init(DMA1_Channel7,&DMA_InitStructure);
  755. // DMA_ITConfig(DMA1_Channel7,DMA_IT_TC,ENABLE);//中断设置
  756. // DMA_Cmd(DMA1_Channel7, DISABLE); //等到需要发送的时候再使能
  757. ///*
  758. // //DMA 通道6用于UART2 RX
  759. // DMA_DeInit(DMA1_Channel6);
  760. // DMA_InitStructure.DMA_PeripheralBaseAddr = (u32)(&USART2->DR);//外设地址
  761. // DMA_InitStructure.DMA_MemoryBaseAddr = (uint32_t)RxBuffer2;//内存地址
  762. // DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralSRC;//DMA传输方向单向
  763. // DMA_InitStructure.DMA_BufferSize = UART2_RX_BUFFER_SIZE; //设置DMA在传输时缓冲区的长度
  764. // DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable; //设置DMA的外设递增模式
  765. // DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable; //设置DMA的内存递增模式
  766. // DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_Byte;//外设数据字长
  767. // DMA_InitStructure.DMA_MemoryDataSize = DMA_PeripheralDataSize_Byte;//内存数据字长
  768. // DMA_InitStructure.DMA_Mode = DMA_Mode_Normal; //设置DMA的传输模式
  769. // DMA_InitStructure.DMA_Priority = DMA_Priority_High; //设置DMA的优先级别
  770. // DMA_InitStructure.DMA_M2M = DMA_M2M_Disable;//设置DMA的2个memory中的变量互相访问
  771. // DMA_Init(DMA1_Channel6,&DMA_InitStructure);
  772. //
  773. // DMA_ITConfig(DMA1_Channel6,DMA_IT_TC,DISABLE);//中断设置 RX DMA不需要中断
  774. // DMA_Cmd(DMA1_Channel6, ENABLE);
  775. //*/
  776. //}
  777. /***************************************************************************
  778. Uart2Init
  779. Use for GPS
  780. ****************************************************************************/
  781. void Uart2Init(void)
  782. {
  783. GPIO_InitTypeDef GPIO_InitStructure;
  784. USART_InitTypeDef USART_InitStructure;
  785. memset(RxBuffer2,0,sizeof(RxBuffer2));
  786. /*使能串口2使用的GPIO时钟*/
  787. RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);
  788. /*使能串口2时钟*/
  789. RCC_APB1PeriphClockCmd(RCC_APB1Periph_USART2, ENABLE);
  790. /*串口2 RX管脚配置*/
  791. /* Configure USART2 Rx as input floating */
  792. GPIO_InitStructure.GPIO_Pin = GPIO_Pin_3;
  793. GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU;//GPIO_Mode_IN_FLOATING;
  794. GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
  795. GPIO_Init(GPIOA, &GPIO_InitStructure);
  796. /*串口2 TX管脚配置*/
  797. /* Configure USART2 Tx as alternate function push-pull */
  798. GPIO_InitStructure.GPIO_Pin = GPIO_Pin_2;
  799. GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
  800. GPIO_Init(GPIOA, &GPIO_InitStructure);
  801. USART_InitStructure.USART_BaudRate = 9600;
  802. USART_InitStructure.USART_WordLength = USART_WordLength_8b;
  803. USART_InitStructure.USART_StopBits = USART_StopBits_1;
  804. USART_InitStructure.USART_Parity = USART_Parity_No;
  805. USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None;
  806. USART_InitStructure.USART_Mode = USART_Mode_Rx | USART_Mode_Tx;
  807. USART_Init(USART2, &USART_InitStructure);
  808. USART_ClearFlag(USART2,USART_FLAG_TC);
  809. USART_ITConfig(USART2, USART_IT_RXNE, ENABLE); //ENABLE DISABLE
  810. USART_ITConfig(USART2, USART_IT_IDLE, DISABLE); //USART_IT_IDLE USART_IT_RXNE
  811. USART_DMACmd(USART2,USART_DMAReq_Tx,DISABLE);
  812. USART_DMACmd(USART2,USART_DMAReq_Rx,DISABLE);
  813. USART_Cmd(USART2, ENABLE);
  814. g_usRx2Len=0;
  815. rx2_ct=0;
  816. //USART_DMACmd(USART2,USART_DMAReq_Rx,ENABLE); //使能USART1的接收DMA请求
  817. //Uart2DMAInit();
  818. }
  819. /*
  820. Use for GPS
  821. */
  822. void UART2RxTxISRHandler(void)
  823. {
  824. __IO unsigned char uart_data;
  825. __IO static unsigned char last_uart_data=0;
  826. if(USART_GetITStatus(USART2, USART_IT_RXNE) != RESET){
  827. uart_data = USART_ReceiveData(USART2);
  828. if(g_ucUARTSel==COM_SEL_GPS){
  829. USART_ClearITPendingBit(USART2,USART_IT_RXNE);
  830. USART_SendData(USART1,uart_data);
  831. return;
  832. }
  833. if(g_usRx2Len==0){
  834. RxBuffer2[rx2_ct]=uart_data;
  835. if(rx2_ct<(UART2_RX_BUFFER_SIZE-1))rx2_ct++;
  836. //$GNRMC,
  837. //$BDGSV,
  838. //$GNRMC,062056.000,A,2237.2459,N,11402.1144,E,0.00,147.89,110319,,,A*77
  839. if(last_uart_data=='\r' && uart_data=='\n'){
  840. if(RxBuffer2[0]=='$' && RxBuffer2[3]=='R' && RxBuffer2[4]=='M' && RxBuffer2[5]=='C'){
  841. g_usRx2Len=rx2_ct;
  842. sutGpsInfo.isGpsWork=1;
  843. sutGpsInfo.GpsCheckWorkCt=0;
  844. sutGpsInfo.BDCheckWorkCt=0;
  845. RxBuffer2[rx2_ct]=0;
  846. }
  847. rx2_ct=0;
  848. }
  849. }else{
  850. rx2_ct=0;
  851. }
  852. last_uart_data=uart_data;
  853. USART_ClearITPendingBit(USART2, USART_IT_RXNE);
  854. }
  855. if(USART_GetFlagStatus(USART2,USART_FLAG_ORE)==SET)
  856. {
  857. USART_ReceiveData(USART2); //
  858. USART_ClearFlag(USART2,USART_FLAG_ORE); //
  859. }
  860. }
  861. /***************************************************************************
  862. Uart3Init
  863. ****************************************************************************/
  864. void Uart3Init(void)
  865. {
  866. NVIC_InitTypeDef NVIC_InitStructure;
  867. GPIO_InitTypeDef GPIO_InitStructure;
  868. USART_InitTypeDef USART_InitStructure;
  869. susRx3In=0;
  870. susRx3Len=0;
  871. susRx3Out=0;
  872. //初始化接收消息队列
  873. MsgQueueInit(&ModemMsgQueue,ModemMsgQueueDataBuffer,MODEM_MSG_DATA_BUF_LEN);
  874. //使能串口3使用的GPIO时钟
  875. RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE);
  876. //使能串口3时钟
  877. RCC_APB1PeriphClockCmd(RCC_APB1Periph_USART3, ENABLE);
  878. //串口3 RX管脚配置
  879. GPIO_InitStructure.GPIO_Pin = GPIO_Pin_11;
  880. GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU;//GPIO_Mode_IPU;//GPIO_Mode_IN_FLOATING;
  881. GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
  882. GPIO_Init(GPIOB, &GPIO_InitStructure);
  883. //串口3 TX管脚配置
  884. GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10;
  885. GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;//GPIO_Mode_AF_PP;
  886. GPIO_Init(GPIOB, &GPIO_InitStructure);
  887. USART_InitStructure.USART_BaudRate = 115200;
  888. USART_InitStructure.USART_WordLength = USART_WordLength_8b;
  889. USART_InitStructure.USART_StopBits = USART_StopBits_1;
  890. USART_InitStructure.USART_Parity = USART_Parity_No;;
  891. USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None;
  892. USART_InitStructure.USART_Mode = USART_Mode_Rx | USART_Mode_Tx;
  893. USART_Init(USART3, &USART_InitStructure);
  894. USART_ClearFlag(USART3,USART_FLAG_TC);
  895. USART_ITConfig(USART3, USART_IT_TXE, DISABLE);
  896. USART_ITConfig(USART3, USART_IT_RXNE, ENABLE);
  897. USART_ITConfig(USART3, USART_IT_IDLE, DISABLE);
  898. USART_Cmd(USART3, ENABLE);
  899. }
  900. /*
  901. void IapTrace(char* format, ...)
  902. {
  903. static char TraceBuffer[512];
  904. va_list argptr;
  905. int cnt;
  906. va_start(argptr, format);
  907. cnt = vsprintf(TraceBuffer, format, argptr);
  908. va_end(argptr);
  909. if(cnt>152){
  910. printf("TraceBuffer Error!\r\n");
  911. return;
  912. }
  913. DelayTick(10);
  914. printf("[IAP]");
  915. printf(TraceBuffer);
  916. DelayTick(10);
  917. }
  918. */
  919. /***********************************************************************************
  920. *
  921. ************************************************************************************/
  922. void SlwTrace(TRACE_TYPE type,char *buf)
  923. {
  924. int len;
  925. #ifndef SLW_DEBUG
  926. if(type==DEBUG)return;
  927. #endif
  928. if(sutDeviceConfig.DebugPrintEn == 0)
  929. if(type==DEBUG)return;
  930. if(g_ucUARTSel!=COM_SEL_MCU)return;
  931. RS485_DIR_HIGH;
  932. #if UART1_TX_USE_DMA==0
  933. len=strlen(buf);
  934. if(len>256)len=256;
  935. Uart1Send(buf,len);
  936. #else
  937. len=strlen(buf);
  938. if(len>512)len=512;
  939. if(len>UART1_TX_BUFFER_SIZE)len=UART1_TX_BUFFER_SIZE;
  940. USART1_Send(buf,len);
  941. #endif
  942. }
  943. /*******************************************************************************
  944. ComSelect
  945. 调试口选择
  946. #define COM_SEL_MCU 0
  947. #define COM_SEL_GPS 1
  948. #define COM_SEL_MODEM 2
  949. *******************************************************************************/
  950. void ComSelect(unsigned char sel)
  951. {
  952. switch(sel)
  953. {
  954. case COM_SEL_GPS:
  955. SlwTrace(INF,"Debug COM selcet to GPS!\r\n");
  956. g_ucUARTSel=sel;
  957. os_tsk_delete(idModemTask);
  958. Uart1Init(1);
  959. RS485_DIR_HIGH;
  960. break;
  961. case COM_SEL_MODEM:
  962. SlwTrace(INF,"Debug COM selcet to Modem!\r\n");
  963. g_ucUARTSel=sel;
  964. os_tsk_delete(idModemTask);
  965. Uart1Init(2);
  966. break;
  967. }
  968. }
  969. /**************************************************************************
  970. * USART1_SendOK_IQ
  971. * 串口1发送数据完毕后,会调用的中断函数,将发送标志置0
  972. * 此函数需在stm32f10x_it.c 的 DMA1_Channel4_IRQHandler()中被调用
  973. ***************************************************************************/
  974. void USART1_SendOK_IQ(void)
  975. {
  976. //判断是否为DMA发送完成中断
  977. if(DMA_GetFlagStatus(DMA1_FLAG_TC4)==SET)
  978. {
  979. DMA_ClearITPendingBit(DMA1_IT_GL4);
  980. DMA_ClearFlag(DMA1_FLAG_TC4);
  981. DMA_Cmd (DMA1_Channel4,DISABLE);
  982. g_ucUart1Sending = 0; //数据发送完毕
  983. }
  984. //printf("USART1_SendOK_IQ\r\n");
  985. }
  986. /**************************************************************************
  987. * USART1_SendOK_IQ
  988. * 串口1发送数据完毕后,会调用的中断函数,将发送标志置0
  989. * 此函数需在stm32f10x_it.c 的 DMA1_Channel2_IRQHandler()中被调用
  990. ***************************************************************************/
  991. //void USART2_SendOK_IQ(void)
  992. //{
  993. //
  994. // //判断是否为DMA发送完成中断
  995. // if(DMA_GetFlagStatus(DMA1_FLAG_TC7)==SET)
  996. // {
  997. // DMA_ClearITPendingBit(DMA1_IT_GL7);
  998. // DMA_ClearFlag(DMA1_FLAG_TC7);
  999. // DMA_Cmd (DMA1_Channel7,DISABLE);
  1000. // g_ucUart2Sending = 0; //数据发送完毕
  1001. // }
  1002. //}
  1003. /**************************************************************************
  1004. * USART3_SendOK_IQ
  1005. * 串口3发送数据完毕后,会调用的中断函数,将发送标志置0
  1006. * 此函数需在stm32f10x_it.c 的 DMA1_Channel2_IRQHandler()中被调用
  1007. ***************************************************************************/
  1008. //void USART3_SendOK_IQ(void)
  1009. //{
  1010. // //判断是否为DMA发送完成中断
  1011. // if(DMA_GetFlagStatus(DMA1_FLAG_TC2)==SET)
  1012. // {
  1013. // DMA_ClearITPendingBit(DMA1_IT_GL2);
  1014. // DMA_ClearFlag(DMA1_FLAG_TC2);
  1015. // DMA_Cmd (DMA1_Channel2,DISABLE);
  1016. // g_ucUart3Sending = 0; //数据发送完毕
  1017. // }
  1018. // //printf("USART3_SendOK_IQ\r\n");
  1019. //}
  1020. #ifdef __GNUC__
  1021. /* With GCC/RAISONANCE, small printf (option LD Linker->Libraries->Small printf
  1022. set to 'Yes') calls __io_putchar() */
  1023. #define PUTCHAR_PROTOTYPE int __io_putchar(int ch)
  1024. #else
  1025. #define PUTCHAR_PROTOTYPE int fputc(int ch, FILE *f)
  1026. #endif /* __GNUC__ */
  1027. /**
  1028. * @brief Retargets the C library printf function to the USART.
  1029. * @param None
  1030. * @retval None
  1031. */
  1032. PUTCHAR_PROTOTYPE
  1033. {
  1034. RS485_DIR_HIGH;
  1035. /* Place your implementation of fputc here */
  1036. /* e.g. write a character to the USART */
  1037. USART_SendData(USART1, (uint8_t) ch);
  1038. /* Loop until the end of transmission */
  1039. while (USART_GetFlagStatus(USART1, USART_FLAG_TC) == RESET)
  1040. {}
  1041. RS485_DIR_LOW;
  1042. return ch;
  1043. }