HW_UART_ATY.c 9.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403
  1. /**
  2. * @file HW_UART_ATY.c
  3. *
  4. * @param Project DEVICE_GENERAL_ATY_LIB
  5. *
  6. * @author ATY
  7. *
  8. * @copyright
  9. * - Copyright 2017 - 2023 MZ-ATY
  10. * - This code follows:
  11. * - MZ-ATY Various Contents Joint Statement -
  12. * <a href="https://mengze.top/MZ-ATY_VCJS">
  13. * https://mengze.top/MZ-ATY_VCJS</a>
  14. * - CC 4.0 BY-NC-SA -
  15. * <a href="https://creativecommons.org/licenses/by-nc-sa/4.0/">
  16. * https://creativecommons.org/licenses/by-nc-sa/4.0/</a>
  17. * - Your use will be deemed to have accepted the terms of this statement.
  18. *
  19. * @brief Familiar functions of uart for STC51
  20. *
  21. * @version
  22. * - 1_01_221231 > ATY
  23. * -# Preliminary version, first Release
  24. * -Undone: over with "\r\n" type
  25. ********************************************************************************
  26. */
  27. #ifndef __HW_UART_ATY_C
  28. #define __HW_UART_ATY_C
  29. #include "HW_UART_ATY.h"
  30. struct _uartMsgStruct uartMsgStruct_t = {0};
  31. /******************************* For user *************************************/
  32. #if defined(__STC51_ATY)
  33. #define BRT (uint32_t)(65536 - (uint32_t)FOSC / BAUD_RATE / 4)
  34. #define FOSC 24000000UL // 24MHz MCU frequency
  35. #define BAUD_RATE 115200
  36. /**
  37. * @brief uart hardware init
  38. * @note put at main init
  39. */
  40. void UartInit(void)
  41. {
  42. SCON = 0x50; // 8bit data, variable baud rate
  43. AUXR |= 0x40; // timer clk 1T mode
  44. AUXR &= 0xFE; // user timer 1 as uart1 baud generate
  45. TMOD &= 0x0F; // set timer mode
  46. TL1 = BRT; // set timer origin value
  47. TH1 = BRT >> 8; // set timer origin value
  48. ET1 = 0; // disable timer IT
  49. TR1 = 1; // start timer 1
  50. // TI = 1;
  51. uartMsgStruct_t.rxCount = 0x00;
  52. uartMsgStruct_t.txCount = 0x00;
  53. uartMsgStruct_t.busyFlag = 0;
  54. ES = 1; // UART interrupt enable
  55. EA = 1; // Global interrupt enable
  56. }
  57. /**
  58. * @brief uart IT callback function
  59. */
  60. void UartIsr(void) INTERRUPT(4)
  61. {
  62. if(TI)
  63. {
  64. TI = 0;
  65. uartMsgStruct_t.busyFlag = 0;
  66. }
  67. if(RI)
  68. {
  69. RI = 0;
  70. if(uartMsgStruct_t.rxCount < UART_RX_MAX_LEN)
  71. {
  72. uartMsgStruct_t.overCount = 0;
  73. uartMsgStruct_t.rx[uartMsgStruct_t.rxCount++] = SBUF;
  74. }
  75. }
  76. }
  77. /**
  78. * @brief uart send byte
  79. * @param byte byte to send
  80. */
  81. void UartSendByte(uint8_t byte)
  82. {
  83. uint8_t errCount = 0;
  84. while(uartMsgStruct_t.busyFlag == 1)
  85. {
  86. errCount++;
  87. if(errCount > 200)
  88. break;
  89. }
  90. uartMsgStruct_t.busyFlag = 1;
  91. SBUF = byte;
  92. }
  93. #elif defined(__STM32_HAL_ATY)
  94. #include "usart.h"
  95. void UartSendByte(uint8_t byte)
  96. {
  97. uint8_t i = 0;
  98. for(i = 0; i < uartMsgStruct_t.rxCount; i++)
  99. uartMsgStruct_t.rx[i] = 0;
  100. uartMsgStruct_t.rxCount = 0;
  101. #ifdef LL
  102. LL_USART_TransmitData8(PRINTF_UART, byte);
  103. while(!LL_USART_IsActiveFlag_TC(PRINTF_UART)){}
  104. #else
  105. HAL_UART_Transmit(&PRINTF_UART, (uint8_t*)&byte, 1, 0xFFFF);
  106. #endif
  107. }
  108. /**
  109. * @brief uart hardware init
  110. * @note put at main init
  111. * use DMA IDEL type, open uart IT and add rx dma, mode in Normal(not Circular!), data with byte
  112. */
  113. void UartInit(void)
  114. {
  115. // __HAL_UART_ENABLE_IT(&PRINTF_UART, UART_IT_IDLE);
  116. HAL_UARTEx_ReceiveToIdle_DMA(&PRINTF_UART, uartMsgStruct_t.rx, UART_RX_MAX_LEN);
  117. __HAL_DMA_DISABLE_IT(&PRINTF_DMA, DMA_IT_HT);
  118. uartMsgStruct_t.rxCount = 0x00;
  119. uartMsgStruct_t.txCount = 0x00;
  120. uartMsgStruct_t.busyFlag = 0;
  121. }
  122. void HAL_UARTEx_RxEventCallback(UART_HandleTypeDef* huart, uint16_t Size)
  123. {
  124. if(huart->Instance == USART1){
  125. HAL_UART_DMAStop(&PRINTF_UART);
  126. uartMsgStruct_t.overCount = 0;
  127. uartMsgStruct_t.rxCount = UART_RX_MAX_LEN - __HAL_DMA_GET_COUNTER(&PRINTF_DMA);
  128. HAL_UARTEx_ReceiveToIdle_DMA(&PRINTF_UART, uartMsgStruct_t.rx, UART_RX_MAX_LEN);
  129. __HAL_DMA_DISABLE_IT(&PRINTF_DMA, DMA_IT_HT);
  130. }
  131. /* if process is not too long, process function can be used at this call back;
  132. otherwise put process at other cycle like while or timer cycle */
  133. // PrintfReceiveProcess();
  134. }
  135. #ifndef __MICROLIB
  136. // for standart lib(not use MicroLIB)
  137. #pragma import(__use_no_semihosting)
  138. // define _sys_exit to avoid semi-host mode
  139. void _sys_exit(int x)
  140. {
  141. x = x;
  142. }
  143. struct __FILE
  144. {
  145. int handle;
  146. };
  147. FILE __stdout;
  148. #endif /* __MICROLIB */
  149. /* In gcc, using printf() output, if there is no "\n" in output data, no data
  150. will be printed on the screen until "\n" is encountered or the buffer overflows
  151. Another way to refresh the output data is to run "fflush(stdout)" after
  152. sending the data to force a refresh of the output stream
  153. */
  154. #ifdef __GNUC__
  155. #define PUTCHAR_PROTOTYPE int __io_putchar(int ch)
  156. #define GETCHAR_PROTOTYPE int __io_getchar(void)
  157. #else
  158. #define PUTCHAR_PROTOTYPE int fputc(int ch, FILE *f)
  159. #define GETCHAR_PROTOTYPE int fgetc(FILE *f)
  160. #endif /* __GNUC__ */
  161. PUTCHAR_PROTOTYPE \
  162. {
  163. #ifdef LL
  164. LL_USART_TransmitData8(PRINTF_UART, ch);
  165. while(!LL_USART_IsActiveFlag_TC(PRINTF_UART)){}
  166. #else
  167. HAL_UART_Transmit(&PRINTF_UART, (uint8_t*)&ch, 1, 0xFFFF);
  168. #endif
  169. return ch;
  170. }
  171. GETCHAR_PROTOTYPE \
  172. {
  173. uint8_t ch = 0;
  174. HAL_UART_Receive(&PRINTF_UART, &ch, 1, 0xFFFF);
  175. return ch;
  176. }
  177. #ifdef DEBUG_PRINTF_RECEIVE
  178. uint8_t uartPrintfRxBuf[PRINTF_RX_MAX_LEN];
  179. struct _uartMsgStruct uartPrintfMsgStruct = {*uartPrintfRxBuf,0};
  180. /**
  181. * @brief init uart IT and DMA etc.
  182. */
  183. void PrintfReceiveInit(void)
  184. {
  185. HAL_UARTEx_ReceiveToIdle_DMA(&PRINTF_UART, uartPrintfMsgStruct.rx, PRINTF_RX_MAX_LEN);
  186. __HAL_DMA_DISABLE_IT(&PRINTF_DMA, DMA_IT_HT);
  187. }
  188. /**
  189. * @brief uart receive data analysis
  190. * @note put at main while
  191. */
  192. __WEAK_ATY void PrintfReceiveProcess(void)
  193. {
  194. struct _uartMsgStruct* ptr = &uartPrintfMsgStruct;
  195. if(ptr->rcvOverFlag)
  196. {
  197. ptr->rcvOverFlag = 0;
  198. PrintfReceiveProcess_User(ptr);
  199. PrintfReceiveInit();
  200. }
  201. }
  202. __WEAK_ATY void PrintfReceiveProcess_User(struct _uartMsgStruct* ptr)
  203. {
  204. // if(memcmp("DSTART", (char*)ptr->rx, strlen("DSTART")) == 0)
  205. // {
  206. // printf("\r\nDebug START!");
  207. // }
  208. // else if(memcmp("temp", (char*)ptr->rx, strlen("temp")) == 0)
  209. // {
  210. // printf("\r\ntemp %c%c%c",
  211. // ptr->rx[strlen("temp_")],
  212. // ptr->rx[strlen("temp_") + 1],
  213. // ptr->rx[strlen("temp_") + 2]);
  214. // }
  215. }
  216. void HAL_UARTEx_RxEventCallback(UART_HandleTypeDef* huart, uint16_t Size)
  217. {
  218. HAL_UART_DMAStop(&PRINTF_UART);
  219. uartPrintfMsgStruct.rxCount = PRINTF_RX_MAX_LEN - __HAL_DMA_GET_COUNTER(&PRINTF_DMA);
  220. uartPrintfMsgStruct.rcvOverFlag = 1;
  221. /* if process is not too long, process function can be used at this call back;
  222. otherwise put process at other cycle like while or timer cycle */
  223. // PrintfReceiveProcess();
  224. }
  225. #endif /* DEBUG_PRINTF_RECEIVE */
  226. #endif /* PLATFORM */
  227. /******************************************************************************/
  228. /**
  229. * @brief uart send bytes
  230. * @param bytes bytes to send
  231. * @param len bytes to send
  232. */
  233. void UartSendBytes(uint8_t* bytes, uint16_t len)
  234. {
  235. while(len--)
  236. UartSendByte(*bytes++);
  237. }
  238. /**
  239. * @brief uart send string
  240. * @param str data to send
  241. */
  242. void UartSendStr(uint8_t* str)
  243. {
  244. while(*str)
  245. UartSendByte(*str++);
  246. }
  247. /**
  248. * @brief uart send float data
  249. * @param dataFloat float number
  250. */
  251. void UartSendFloat(float dataFloat)
  252. {
  253. union result
  254. {
  255. float temp_f;
  256. uint8_t temp_uint8[4];
  257. }resultA, resultB;
  258. resultA.temp_f = dataFloat;
  259. resultB.temp_uint8[0] = resultA.temp_uint8[0];
  260. resultB.temp_uint8[1] = resultA.temp_uint8[1];
  261. resultB.temp_uint8[2] = resultA.temp_uint8[2];
  262. resultB.temp_uint8[3] = resultA.temp_uint8[3];
  263. UartSendByte(resultB.temp_uint8[3]);
  264. UartSendByte(resultB.temp_uint8[2]);
  265. UartSendByte(resultB.temp_uint8[1]);
  266. UartSendByte(resultB.temp_uint8[0]);
  267. }
  268. /**
  269. * @brief uart send float data in ASCII character type
  270. * @param dataFloat number to send, use double to get better
  271. * @note float and double is the same in C51
  272. */
  273. // void UartSendFloatStr(double dataFloat)
  274. void UartSendFloatStr(float dataFloat)
  275. {
  276. #define DECIMALS_NUM 4
  277. uint8_t i = 0, j = 0;
  278. uint8_t dataStr[10]; // ulongint 4294967295, 6.4f
  279. unsigned long int tempSaveData = 0;
  280. for(i = 0; i < 10; i++)
  281. dataStr[i] = 0;
  282. if(dataFloat < 0)
  283. {
  284. dataFloat = -dataFloat;
  285. UartSendByte('-');
  286. }
  287. tempSaveData = (dataFloat * 10000) + 0.5;
  288. for(i = 0; tempSaveData != 0; i++)
  289. {
  290. dataStr[10 - 1 - i] = tempSaveData % 10;
  291. tempSaveData /= 10;
  292. }
  293. // UartSendByte(i + 48);
  294. if(i < 5)
  295. i = 5;
  296. while(i--)
  297. {
  298. UartSendByte(dataStr[10 - 1 - i] + 48);
  299. if(i == DECIMALS_NUM)
  300. UartSendByte('.');
  301. }
  302. UartSendByte(' ');
  303. }
  304. /**
  305. * @brief uart receive data process
  306. * @note put at main while
  307. */
  308. __WEAK_ATY void UartReceiveProcess(void)
  309. {
  310. // if(uartMsgStruct_t.overCount >= 10000)
  311. if(uartMsgStruct_t.overCount > 2000)
  312. {
  313. uartMsgStruct_t.overCount = 0;
  314. if(uartMsgStruct_t.rxCount != 0)
  315. {
  316. // UartSendStr(&uartMsgStruct_t.rxCount);
  317. UartReceiveProcess_User(&uartMsgStruct_t);
  318. while(uartMsgStruct_t.rxCount){
  319. uartMsgStruct_t.rx[uartMsgStruct_t.rxCount--] = 0;
  320. }
  321. }
  322. }
  323. else
  324. uartMsgStruct_t.overCount++;
  325. }
  326. // /**
  327. // * @brief uart receive data analysis in user define self
  328. // */
  329. // void UartReceiveProcess_User(struct _uartMsgStruct* ptr)
  330. // {
  331. // if(ptr->rx[0] == 'O' && ptr->rx[1] == 'K')
  332. // UartSendStr("\r\nRC OK!\r\n");
  333. // // UartSendStr(ptr->rx);
  334. // }
  335. // void main()
  336. // {
  337. // UartInit();
  338. // UartSendStr("Uart Test !\r\n");
  339. // while (1)
  340. // {
  341. // UartReceiveProcess();
  342. // }
  343. // }
  344. #endif /* __HW_UART_ATY_C */
  345. /******************************** End Of File *********************************/