HW_UART_ATY.c 9.7 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 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. #ifndef __MICROLIB
  110. // for standart lib(not use MicroLIB)
  111. #pragma import(__use_no_semihosting)
  112. // define _sys_exit to avoid semi-host mode
  113. void _sys_exit(int x)
  114. {
  115. x = x;
  116. }
  117. struct __FILE
  118. {
  119. int handle;
  120. };
  121. FILE __stdout;
  122. #endif /* __MICROLIB */
  123. /* In gcc, using printf() output, if there is no "\n" in output data, no data
  124. will be printed on the screen until "\n" is encountered or the buffer overflows
  125. Another way to refresh the output data is to run "fflush(stdout)" after
  126. sending the data to force a refresh of the output stream
  127. */
  128. #ifdef __GNUC__
  129. #define PUTCHAR_PROTOTYPE int __io_putchar(int ch)
  130. #define GETCHAR_PROTOTYPE int __io_getchar(void)
  131. #else
  132. #define PUTCHAR_PROTOTYPE int fputc(int ch, FILE *f)
  133. #define GETCHAR_PROTOTYPE int fgetc(FILE *f)
  134. #endif /* __GNUC__ */
  135. PUTCHAR_PROTOTYPE \
  136. {
  137. #ifdef LL
  138. LL_USART_TransmitData8(PRINTF_UART, ch);
  139. while(!LL_USART_IsActiveFlag_TC(PRINTF_UART)){}
  140. #else
  141. HAL_UART_Transmit(&PRINTF_UART, (uint8_t*)&ch, 1, 0xFFFF);
  142. #endif
  143. return ch;
  144. }
  145. GETCHAR_PROTOTYPE \
  146. {
  147. uint8_t ch = 0;
  148. HAL_UART_Receive(&PRINTF_UART, &ch, 1, 0xFFFF);
  149. return ch;
  150. }
  151. #ifdef DEBUG_PRINTF_RECEIVE
  152. uint8_t uartPrintfRxBuf[PRINTF_RX_MAX_LEN];
  153. /**
  154. * @brief uart hardware init
  155. * @note put at main init
  156. * use DMA IDEL type, open uart IT and add rx dma, mode in Normal(not Circular!), data with byte
  157. */
  158. void UartInit(void)
  159. {
  160. // __HAL_UART_ENABLE_IT(&PRINTF_UART, UART_IT_IDLE);
  161. HAL_UARTEx_ReceiveToIdle_DMA(&PRINTF_UART, uartMsgStruct_t.rx, UART_RX_MAX_LEN);
  162. __HAL_DMA_DISABLE_IT(&PRINTF_DMA, DMA_IT_HT);
  163. *(uartMsgStruct_t.rx) = *uartPrintfRxBuf;
  164. uartMsgStruct_t.rxCount = 0x00;
  165. uartMsgStruct_t.txCount = 0x00;
  166. uartMsgStruct_t.busyFlag = 0;
  167. }
  168. void HAL_UARTEx_RxEventCallback(UART_HandleTypeDef* huart, uint16_t Size)
  169. {
  170. if(huart == &PRINTF_UART){
  171. HAL_UART_DMAStop(&PRINTF_UART);
  172. uartMsgStruct_t.overCount = 0;
  173. uartMsgStruct_t.rxCount = UART_RX_MAX_LEN - __HAL_DMA_GET_COUNTER(&PRINTF_DMA);
  174. uartMsgStruct_t.rcvOverFlag = 1;
  175. // HAL_UARTEx_ReceiveToIdle_DMA(&PRINTF_UART, uartMsgStruct_t.rx, UART_RX_MAX_LEN);
  176. // __HAL_DMA_DISABLE_IT(&PRINTF_DMA, DMA_IT_HT);
  177. }
  178. /* if process is not too long, process function can be used at this call back;
  179. otherwise put process at other cycle like while or timer cycle */
  180. // PrintfReceiveProcess();
  181. }
  182. /**
  183. * @brief init uart IT and DMA etc.
  184. */
  185. void PrintfReceiveInit(void)
  186. {
  187. HAL_UARTEx_ReceiveToIdle_DMA(&PRINTF_UART, uartMsgStruct_t.rx, PRINTF_RX_MAX_LEN);
  188. __HAL_DMA_DISABLE_IT(&PRINTF_DMA, DMA_IT_HT);
  189. }
  190. /**
  191. * @brief uart receive data analysis
  192. * @note put at main while
  193. */
  194. __WEAK_ATY void PrintfReceiveProcess(void)
  195. {
  196. struct _uartMsgStruct* ptr = &uartMsgStruct_t;
  197. if(ptr->rcvOverFlag)
  198. {
  199. ptr->rcvOverFlag = 0;
  200. // ptr->rxCount = 0;
  201. UartReceiveProcess_User(ptr);
  202. PrintfReceiveInit();
  203. }
  204. }
  205. #endif /* DEBUG_PRINTF_RECEIVE */
  206. #endif /* PLATFORM */
  207. /******************************************************************************/
  208. /**
  209. * @brief uart send bytes
  210. * @param bytes bytes to send
  211. * @param len bytes to send
  212. */
  213. void UartSendBytes(uint8_t* bytes, uint16_t len)
  214. {
  215. while(len--)
  216. UartSendByte(*bytes++);
  217. }
  218. /**
  219. * @brief uart send string
  220. * @param str data to send
  221. */
  222. void UartSendStr(uint8_t* str)
  223. {
  224. while(*str)
  225. UartSendByte(*str++);
  226. }
  227. /**
  228. * @brief uart send float data in little endian
  229. * @param dataFloat float number
  230. */
  231. void UartSendFloat(float dataFloat)
  232. {
  233. union result
  234. {
  235. float temp_f;
  236. uint8_t temp_uint8[4];
  237. }resultA, resultB;
  238. resultA.temp_f = dataFloat;
  239. resultB.temp_uint8[0] = resultA.temp_uint8[0];
  240. resultB.temp_uint8[1] = resultA.temp_uint8[1];
  241. resultB.temp_uint8[2] = resultA.temp_uint8[2];
  242. resultB.temp_uint8[3] = resultA.temp_uint8[3];
  243. UartSendByte(resultB.temp_uint8[3]);
  244. UartSendByte(resultB.temp_uint8[2]);
  245. UartSendByte(resultB.temp_uint8[1]);
  246. UartSendByte(resultB.temp_uint8[0]);
  247. }
  248. /**
  249. * @brief uart send float data in ASCII character type
  250. * @param dataFloat number to send, use double to get better
  251. * @note float and double is the same in C51
  252. */
  253. // void UartSendFloatStr(double dataFloat)
  254. void UartSendFloatStr(float dataFloat)
  255. {
  256. #define DECIMALS_NUM 4
  257. uint8_t i = 0, j = 0;
  258. uint8_t dataStr[10]; // ulongint 4294967295, 6.4f
  259. unsigned long int tempSaveData = 0;
  260. for(i = 0; i < 10; i++)
  261. dataStr[i] = 0;
  262. if(dataFloat < 0)
  263. {
  264. dataFloat = -dataFloat;
  265. UartSendByte('-');
  266. }
  267. tempSaveData = (dataFloat * 10000) + 0.5;
  268. for(i = 0; tempSaveData != 0; i++)
  269. {
  270. dataStr[10 - 1 - i] = tempSaveData % 10;
  271. tempSaveData /= 10;
  272. }
  273. // UartSendByte(i + 48);
  274. if(i < 5)
  275. i = 5;
  276. while(i--)
  277. {
  278. UartSendByte(dataStr[10 - 1 - i] + 48);
  279. if(i == DECIMALS_NUM)
  280. UartSendByte('.');
  281. }
  282. UartSendByte(' ');
  283. }
  284. /**
  285. * @brief uart receive data process
  286. * @note put at main while
  287. */
  288. __WEAK_ATY void UartReceiveProcess(void)
  289. {
  290. #ifdef DEBUG_PRINTF_RECEIVE
  291. PrintfReceiveProcess();
  292. #else
  293. // if(uartMsgStruct_t.overCount >= 10000)
  294. if(uartMsgStruct_t.overCount > 2000)
  295. {
  296. uartMsgStruct_t.overCount = 0;
  297. if(uartMsgStruct_t.rxCount != 0)
  298. {
  299. // UartSendStr(&uartMsgStruct_t.rxCount);
  300. UartReceiveProcess_User(&uartMsgStruct_t);
  301. while(uartMsgStruct_t.rxCount){
  302. uartMsgStruct_t.rx[uartMsgStruct_t.rxCount--] = 0;
  303. }
  304. }
  305. }
  306. else
  307. uartMsgStruct_t.overCount++;
  308. #endif
  309. }
  310. // /**
  311. // * @brief uart receive data analysis in user define self
  312. // */
  313. // void UartReceiveProcess_User(struct _uartMsgStruct* ptr)
  314. // {
  315. // if(ptr->rx[0] == 'O' && ptr->rx[1] == 'K')
  316. // UartSendStr("\r\nRC OK!\r\n");
  317. // // UartSendStr(ptr->rx);
  318. // if(memcmp("DSTART", (char*)ptr->rx, strlen("DSTART")) == 0)
  319. // {
  320. // printf("\r\nDebug START!");
  321. // }
  322. // else if(memcmp("temp", (char*)ptr->rx, strlen("temp")) == 0)
  323. // {
  324. // printf("\r\ntemp %c%c%c",
  325. // ptr->rx[strlen("temp_")],
  326. // ptr->rx[strlen("temp_") + 1],
  327. // ptr->rx[strlen("temp_") + 2]);
  328. // }
  329. // if((ptr->rx[0] == 'O'
  330. // && ptr->rx[1] == 'K'
  331. // && ptr->rx[2] == '?'))
  332. // UartSendStr("OK!");
  333. // Modbus_Process(ptr->rx, ptr->rxCount);
  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 *********************************/