usart.c 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464
  1. /**
  2. *****************************************************************************
  3. * 系统串口设置相关的函数
  4. *
  5. * (C) Copyright 2000-2020, ***
  6. * All Rights Reserved
  7. *****************************************************************************
  8. *
  9. * @File : usart.c
  10. * @By : 陈桂东
  11. * @Version : V1.0
  12. * @Date : 2012 / 10 / 20
  13. *
  14. *****************************************************************************
  15. * Update
  16. * @Version : V1.0.1
  17. * @By : 陈桂东
  18. * @Date : 2014 / 05 / 24
  19. * @Brief : 增加对C++环境支持
  20. *
  21. * @Version : V1.1
  22. * @By : 陈桂东
  23. * @Date : 2015 / 10 / 03
  24. * @Brief : 增加103和407之间切换宏定义
  25. *
  26. * @Version : V1.2
  27. * @By : 陈桂东
  28. * @Date : 2016 / 04 / 27
  29. * @Brief : A、增加对STM32F0系列支持
  30. * B、增加对IAR环境支持
  31. *
  32. *****************************************************************************
  33. **/
  34. #include "usart.h"
  35. #if _SYSTEM_SUPPORT_ROTS == 1
  36. #if _RTOS_Type_Support == 1 // RAW-OS
  37. #include "raw_api.h"
  38. #else // uCOS
  39. #include "includes.h"
  40. #endif
  41. #endif
  42. #if Printf_Support_En == 0
  43. #include <stdarg.h>
  44. #endif
  45. /******************************************************************************
  46. 加入以下代码,支持printf函数,而不需要选择use MicroLIB
  47. ******************************************************************************/
  48. #if Printf_Support_En == 1
  49. #ifdef __ICCARM__ //IAR支持
  50. /**
  51. *****************************************************************************
  52. * @Name : 重定义out_char函数
  53. *
  54. * @Brief : none
  55. *
  56. * @Input : ch:发送字符
  57. *
  58. * @Output : none
  59. *
  60. * @Return : none
  61. *****************************************************************************
  62. **/
  63. int putchar ( int c )
  64. {
  65. uint16_t timeout = 0;
  66. USART_SendData ( USART1, ( uint16_t ) c ); //发送数据
  67. while ( USART_GetFlagStatus ( USART1, USART_FLAG_TC ) == RESET ) //循环发送,直到发送完毕
  68. {
  69. timeout++;
  70. if ( timeout > 800 )
  71. {
  72. timeout = 0;
  73. break;
  74. }
  75. }
  76. return c;
  77. }
  78. #else //MDK支持
  79. #pragma import(__use_no_semihosting)
  80. //
  81. //标准库需要的支持函数
  82. //
  83. struct __FILE
  84. {
  85. int handle;
  86. };
  87. /* FILE is typedef’ d in stdio.h. */
  88. FILE __stdout;
  89. //
  90. //定义_sys_exit()以避免使用半主机模式
  91. //
  92. _sys_exit ( int x )
  93. {
  94. x = x;
  95. }
  96. /**
  97. *****************************************************************************
  98. * @Name : 重定义fputc函数
  99. *
  100. * @Brief : none
  101. *
  102. * @Input : ch:发送字符
  103. * *f: FILE指针
  104. *
  105. * @Output : none
  106. *
  107. * @Return : none
  108. *****************************************************************************
  109. **/
  110. int fputc ( int ch, FILE *f )
  111. {
  112. uint16_t timeout = 0;
  113. while ( USART_GetFlagStatus ( USART1, USART_FLAG_TC ) == RESET ) //循环发送,直到发送完毕
  114. {
  115. timeout++;
  116. if ( timeout > 800 )
  117. {
  118. timeout = 0;
  119. break;
  120. }
  121. }
  122. USART_SendData ( USART1, ( uint16_t ) ch ); //发送数据
  123. return ch;
  124. }
  125. #endif
  126. #else
  127. /**
  128. *****************************************************************************
  129. * @Name : 串口发送一个字节
  130. *
  131. * @Brief : none
  132. *
  133. * @Input : byte:发送字符
  134. *
  135. * @Output : none
  136. *
  137. * @Return : none
  138. *****************************************************************************
  139. **/
  140. void uart_sendbyte ( uint8_t byte )
  141. {
  142. while ( USART_GetFlagStatus ( USART1, USART_FLAG_TC ) == RESET );
  143. USART_SendData ( USART1, byte );
  144. while ( USART_GetFlagStatus ( USART1, USART_FLAG_TC ) == RESET );
  145. }
  146. /**
  147. *****************************************************************************
  148. * @Name : 串口发送字符串
  149. *
  150. * @Brief : none
  151. *
  152. * @Input : *str:发送字符串
  153. *
  154. * @Output : none
  155. *
  156. * @Return : none
  157. *****************************************************************************
  158. **/
  159. void uart_senfstring ( uint8_t * str )
  160. {
  161. while ( USART_GetFlagStatus ( USART1, USART_FLAG_TC ) == RESET );
  162. while ( *str != '\0' )
  163. {
  164. USART_SendData ( USART1, * ( str++ ) );
  165. while ( USART_GetFlagStatus ( USART1, USART_FLAG_TC ) == RESET );
  166. }
  167. }
  168. /**
  169. *****************************************************************************
  170. * @Name : 串口格式化打印
  171. *
  172. * @Brief : none
  173. *
  174. * @Input : *format:格式化字符串
  175. * ...: 变长参数
  176. *
  177. * @Output : none
  178. *
  179. * @Return : none
  180. *****************************************************************************
  181. **/
  182. void uart_printf ( char *format, ... )
  183. {
  184. va_list ap;
  185. char string[512];
  186. va_start ( ap, format );
  187. vsprintf ( string, format, ap );
  188. va_end ( ap );
  189. uart_senfstring ( ( uint8_t * ) string );
  190. }
  191. #endif
  192. /************************************* end *******************************/
  193. /**
  194. *****************************************************************************
  195. * @Name : 初始化IO 串口
  196. *
  197. * @Brief : none
  198. *
  199. * @Input : bound:波特率
  200. *
  201. * @Output : none
  202. *
  203. * @Return : none
  204. *****************************************************************************
  205. **/
  206. void uart_init ( uint32_t bound )
  207. {
  208. GPIO_InitTypeDef GPIO_InitStructure;
  209. USART_InitTypeDef USART_InitStructure;
  210. NVIC_InitTypeDef NVIC_InitStructure;
  211. #if __CORTEX_M == 0x00 //Cortex-M0
  212. RCC_AHBPeriphClockCmd ( RCC_AHBPeriph_GPIOA, ENABLE );
  213. RCC_APB2PeriphClockCmd ( RCC_APB2Periph_USART1, ENABLE );
  214. //
  215. //管脚复用
  216. //
  217. GPIO_PinAFConfig ( GPIOA, GPIO_PinSource9, GPIO_AF_1 );
  218. #if EN_USART1_RX == 1 //使能接收
  219. GPIO_PinAFConfig ( GPIOA, GPIO_PinSource10, GPIO_AF_1 );
  220. #endif
  221. //
  222. //初始化管脚
  223. //
  224. #if EN_USART1_RX == 1 //使能接收
  225. GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9 | GPIO_Pin_10;
  226. #else
  227. GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9;
  228. #endif
  229. GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
  230. GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;
  231. GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
  232. GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP;
  233. GPIO_Init ( GPIOA, &GPIO_InitStructure );
  234. #elif __CORTEX_M == 0x03 //Cortex-M3
  235. //
  236. //打开时钟
  237. //
  238. RCC_APB2PeriphClockCmd ( RCC_APB2Periph_USART1 | RCC_APB2Periph_GPIOA, ENABLE );
  239. //
  240. //初始化管脚
  241. //
  242. GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9; //PA.9 TXD
  243. GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
  244. GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP; //复用推挽输出
  245. GPIO_Init ( GPIOA, &GPIO_InitStructure );
  246. #if EN_USART1_RX == 1 //使能接收
  247. GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10; //PA.10 RXD
  248. GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING; //浮空输入
  249. GPIO_Init ( GPIOA, &GPIO_InitStructure );
  250. #endif
  251. #elif __CORTEX_M == 0x04 //Cortex-M4
  252. //
  253. //打开时钟
  254. //
  255. RCC_AHB1PeriphClockCmd ( RCC_AHB1Periph_GPIOA, ENABLE ); //使能GPIOA时钟
  256. RCC_APB2PeriphClockCmd ( RCC_APB2Periph_USART1, ENABLE ); //使能USART1时钟
  257. //
  258. //管脚复用
  259. //
  260. GPIO_PinAFConfig ( GPIOA, GPIO_PinSource9, GPIO_AF_USART1 ); //TXD管脚
  261. #if EN_USART1_RX == 1 //使能接收
  262. GPIO_PinAFConfig ( GPIOA, GPIO_PinSource10, GPIO_AF_USART1 ); //RXD管脚
  263. #endif
  264. //
  265. //初始化管脚
  266. //
  267. #if EN_USART1_RX == 1 //使能接收
  268. GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9 | GPIO_Pin_10;
  269. #else
  270. GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9; //只初始化TXD管脚
  271. #endif
  272. GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
  273. GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF; //复用功能
  274. GPIO_InitStructure.GPIO_OType = GPIO_OType_PP; //推挽输出
  275. GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP; //上拉
  276. GPIO_Init ( GPIOA, &GPIO_InitStructure );
  277. #endif //end __CORTEX_M
  278. //
  279. //配置串口参数
  280. //
  281. USART_InitStructure.USART_BaudRate = bound; //波特率
  282. USART_InitStructure.USART_WordLength = USART_WordLength_8b; //数据长度8
  283. USART_InitStructure.USART_StopBits = USART_StopBits_1; //停止位1
  284. USART_InitStructure.USART_Parity = USART_Parity_No; //无奇偶校验
  285. USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None; //无数据流控制
  286. #if EN_USART1_RX == 1 //使能接收
  287. USART_InitStructure.USART_Mode = USART_Mode_Tx | USART_Mode_Rx;
  288. #else
  289. USART_InitStructure.USART_Mode = USART_Mode_Tx;
  290. #endif
  291. USART_Init ( USART1, &USART_InitStructure );
  292. //
  293. //使能串口
  294. //
  295. USART_Cmd ( USART1, ENABLE );
  296. USART_ClearFlag ( USART1, USART_FLAG_TC );
  297. //
  298. //初始化串口中断优先级
  299. //
  300. #if EN_USART1_RX == 1 //使能接收
  301. //
  302. //开启串口中断接收
  303. //
  304. USART_ITConfig ( USART1, USART_IT_RXNE, ENABLE );
  305. NVIC_InitStructure.NVIC_IRQChannel = USART1_IRQn; //中断号
  306. #if __CORTEX_M == 0x00 //Cortex-M0
  307. NVIC_InitStructure.NVIC_IRQChannelPriority = 3;
  308. #else
  309. NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 3; //抢先优先级
  310. NVIC_InitStructure.NVIC_IRQChannelSubPriority = 3; //响应优先级
  311. #endif
  312. NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
  313. NVIC_Init ( &NVIC_InitStructure );
  314. #endif
  315. }
  316. #if EN_USART1_RX == 1 //使能接收
  317. //注意,读取USARTx->SR能避免莫名其妙的错误
  318. uint8_t USART_RX_BUF[USART_REC_LEN]; //接收缓冲,最大USART_REC_LEN个字节
  319. //接收状态
  320. //bit15:接收完成标志
  321. //bit14:接收到0x0d
  322. //bit13~0:接收到的有效字节数目,最大512字节
  323. uint16_t USART_RX_STA = 0; //接收状态标记
  324. /**
  325. *****************************************************************************
  326. * @Name : 串口1接收中断服务程序
  327. *
  328. * @Brief : none
  329. *
  330. * @Input : none
  331. *
  332. * @Output : none
  333. *
  334. * @Return : none
  335. *****************************************************************************
  336. **/
  337. void USART1_IRQHandler ( void )
  338. {
  339. uint8_t res;
  340. #if _SYSTEM_SUPPORT_ROTS == 1
  341. #if _RTOS_Type_Support == 1 // RAW-OS
  342. raw_enter_interrupt();
  343. #else // uCOS
  344. OSIntEnter();
  345. #endif
  346. #endif
  347. if ( USART_GetITStatus ( USART1, USART_IT_RXNE ) != RESET ) //接收到数据
  348. {
  349. res = USART_ReceiveData ( USART1 ); //读取接收到的数据
  350. if ( ( USART_RX_STA & 0x8000 ) == 0 ) //接收未完成
  351. {
  352. if ( USART_RX_STA & 0x4000 ) //接收到了0x0d
  353. {
  354. /***********************************************
  355. 修改内容如下
  356. 当用户数据当中有0x0d的时候修正的错误的判断
  357. ***********************************************/
  358. if ( res != 0x0a )
  359. {
  360. USART_RX_BUF[USART_RX_STA & 0x3fff] = 0x0d; //补上丢失的0x0d数据
  361. USART_RX_STA++;
  362. USART_RX_BUF[USART_RX_STA & 0x3fff] = res; //继续接收数据
  363. USART_RX_STA++;
  364. USART_RX_STA &= 0xbfff; //清除0x0d标志
  365. }
  366. /***********************************************
  367. 修改完成
  368. ***********************************************/
  369. else USART_RX_STA |= 0x8000; //接收完成了
  370. }
  371. else //还没收到0x0d
  372. {
  373. if ( res == 0x0d ) USART_RX_STA |= 0x4000;
  374. else
  375. {
  376. USART_RX_BUF[USART_RX_STA & 0x3fff] = res;
  377. USART_RX_STA++;
  378. if ( USART_RX_STA > ( USART_REC_LEN - 1 ) ) USART_RX_STA = 0; //接收数据错误,重新开始接收
  379. }
  380. }
  381. } //end 接收未完成
  382. } //end 接收到数据
  383. #if _SYSTEM_SUPPORT_ROTS == 1
  384. #if _RTOS_Type_Support == 1 // RAW-OS
  385. raw_finish_int();
  386. #else // uCOS
  387. OSIntExit();
  388. #endif
  389. #endif
  390. }
  391. #endif //end EN_USART1_RX