HW_UART_ATY.c 9.9 KB

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