查看: 3652|回复: 1

串口收发数据

[复制链接]

该用户从未签到

发表于 2017-5-26 14:06:29 | 显示全部楼层 |阅读模式
分享到:
串口收发数据

评估板自带了USB转串口,这个用起来方便多了,可以直接打印数据到电脑端。

下面上配置程序和收发处理。
用到资源UART2和TIMER6。准备之后连接modbus-RTU的所以占用一个定时器来判定接收报文结束

程序清单:
com_hal.h
  1. #ifndef _COM_HAL_H_
  2. #define        _COM_HAL_H_

  3. #include "mytype.h"
  4. #include "stdint.h"

  5. #ifdef   _COM_HAL_MODULE_
  6. #define  COM_EXT
  7. #else
  8. #define  COM_EXT  extern
  9. #endif      

  10. #define COM                       USART2
  11. #define ComTIMER                  TIMER6

  12. typedef enum {
  13.     COM_RX_IDLE, //!< Receiver is in idle state.
  14.     COM_RX_RCV, //!< Frame is beeing received.
  15.     COM_RX_RCVEND, //!< Port Receive complete ,3.5T timer
  16.     COM_RX_TIMEOUT //!< Time out ,Send a command and no data return after 500ms( --> system timer)

  17. } ComRcvState_t;

  18. typedef enum {
  19.     COM_TX_IDLE, /*!< Transmitter is in idle state. */
  20.     COM_TX_XMIT /*!< Transmitter is in transfer state. */
  21. } ComSndState_t;

  22. typedef enum {
  23.     COM_PAR_NONE, /*!< No parity. */
  24.     COM_PAR_ODD, /*!< Odd parity. */
  25.     COM_PAR_EVEN /*!< Even parity. */
  26. } ComParity_t;

  27. typedef union {
  28.     uint8_t St;

  29.     struct {
  30.         uint8_t PortSt : 1;
  31.         uint8_t Connect : 1;
  32.     } bits;
  33. } COM_ST_Type;

  34. #define COM_BUFF_SIZE             1024

  35. COM_EXT uint8_t ComBuff[COM_BUFF_SIZE];
  36. COM_EXT COM_ST_Type ComSt;

  37. COM_EXT uint8_t *pComSndCur;
  38. COM_EXT uint16_t ComSndCnt;
  39. COM_EXT uint16_t ComRcvCnt;

  40. COM_EXT volatile uint8_t ComErrSt;
  41. COM_EXT volatile ComSndState_t ComSndSt;
  42. COM_EXT volatile ComRcvState_t ComRcvSt;

  43. void ComInit(uint32_t ulBaudRate, ComParity_t eParity);
  44. void ComParity(ComParity_t eParity);
  45. void ComStringSend(uint8_t * pData);
  46. void ComDataSend(uint8_t * pData, uint16_t Len);
  47. uint8_t ComStCheck(void); //端口空闲状态检查

  48. #undef COM_EXT

  49. #endif        /* _COM_HAL_H_ */
复制代码
com_hal.c
  1. /* ------------------------------------------------------------------------*
  2. *
  3. * ------------------------------------------------------------------------*/
  4. #include "osObjects.h"  

  5. #define _COM_HAL_MODULE_
  6. #include "com_hal.h"
  7. #include "comtask.h"

  8. //RS485 Dir-Pin
  9. #define ComRxEnable()
  10. #define ComTxEnable()
  11. #define ComDE(x)  


  12. static void ComEnable(uint8_t xRxEnable, uint8_t xTxEnable);
  13. void ComTimerEnable(void);
  14. void ComTimerDisable(void);

  15. /*****************************************************************************//*!
  16. * @brief UART2 TX interrupt routine.
  17. * @brief   Uart interrupt.
  18. *            
  19. * @param   none
  20. *
  21. * @return  none
  22. *
  23. * @ Pass/ Fail criteria: none
  24. *****************************************************************************/

  25. void USART2_IRQHandler() {
  26.     uint32_t IntSt;
  27.     uint8_t Data;

  28.     IntSt = USART_STAT0(USART2);

  29.     if (IntSt & USART_STAT0_RBNE) {
  30.         ComTimerEnable();

  31.         Data = USART_DATA(USART2);

  32.         if (COM_RX_RCVEND == ComRcvSt)
  33.             return;

  34.         if (ComRcvCnt > (COM_BUFF_SIZE - 1))
  35.             return; //指针越界检查

  36.         ComRcvSt = COM_RX_RCV; //指示正在接收数据

  37.         if ((IntSt & USART_STAT0_ORERR) != 0) { //溢出 //只读,由硬件管理

  38.         }


  39.         if ((IntSt & (USART_STAT0_FERR | USART_STAT0_PERR)) != 0) { //帧错误 //只读,由硬件管理
  40.             return;
  41.         }

  42.         if (ComRcvCnt < COM_BUFF_SIZE)
  43.             ComBuff[ComRcvCnt++] = Data;
  44.         else {
  45.             //receive overflow
  46.         }

  47.     } else if (IntSt & USART_STAT0_TBE) {
  48.         if ((0 == ComSndCnt) && (IntSt & USART_STAT0_TC)) {
  49.             ComSndSt = COM_TX_IDLE; //发送结束
  50.             ComEnable(ENABLE, DISABLE);
  51.         } else if (ComSndCnt) {
  52.             USART_DATA(COM) = *(pComSndCur++);
  53.             ComSndCnt--;
  54.             if (0 == ComSndCnt) //写缓冲区结束
  55.             {
  56.                 USART_CTL0(COM) &= ~(uint32_t) (USART_CTL0_TBEIE);
  57.                 USART_CTL0(COM) |= (uint32_t) (USART_CTL0_TCIE);
  58.             }
  59.         } else {

  60.         }
  61.     }
  62. }

  63. /*****************************************************************************//*!
  64. *
  65. * @brief   com end timer.
  66. *            
  67. * @param   none
  68. *
  69. * @return  none
  70. *
  71. * @ Pass/ Fail criteria: none
  72. *****************************************************************************/

  73. void TIMER6_IRQHandler() {
  74.     //关闭定时器
  75.     ComTimerDisable();
  76.     //清除更新中断标志
  77.     TIMER_INTF(ComTIMER) &= ~((uint32_t) TIMER_INTF_UPIF);
  78.     //
  79.     if (COM_RX_RCV == ComRcvSt) {
  80.         //端口接收结束,告诉数据处理单元可以处理数据
  81.         ComRcvSt = COM_RX_RCVEND;

  82.         /* Set bit 0 and bit 4 in xEventGroup. */
  83.         xSemaphoreGiveFromISR(xSemCom, NULL);

  84.     }
  85. }

  86. /*****************************************************************************//*!
  87. *
  88. * @brief   RTU timer enable.
  89. *            
  90. * @param   none
  91. *
  92. * @return  none
  93. *
  94. * @ Pass/ Fail criteria: none
  95. *****************************************************************************/

  96. void ComTimerEnable(void) {
  97.     TIMER_CNT(ComTIMER) = 0;
  98.     TIMER_CTL0(ComTIMER) |= ((uint32_t) TIMER_CTL0_CEN);
  99. }

  100. /*****************************************************************************//*!
  101. *
  102. * @brief   RTU timer disable.
  103. *            
  104. * @param   none
  105. *
  106. * @return  none
  107. *
  108. * @ Pass/ Fail criteria: none
  109. *****************************************************************************/

  110. void ComTimerDisable(void) {
  111.     //停止计数
  112.     TIMER_CTL0(ComTIMER) &= ~((uint32_t) TIMER_CTL0_CEN);
  113. }

  114. /*****************************************************************************//*!
  115. *
  116. * @brief   timer init.
  117. *            
  118. * @param   none
  119. *
  120. * @return  TURE
  121. *
  122. * @ Pass/ Fail criteria: none
  123. *****************************************************************************/

  124. uint8_t ComTimerInit(uint32_t ts50us) {
  125.     uint32_t TimerClk;

  126.     rcu_periph_clock_enable(RCU_TIMER6);
  127.     rcu_periph_reset_enable(RCU_TIMER6RST);
  128.     rcu_periph_reset_disable(RCU_TIMER6RST);

  129.     TimerClk = rcu_clock_freq_get(CK_APB1);
  130.     // 向上计数,仅溢出产生更新事件,单脉冲模式
  131.     TIMER_CTL0(ComTIMER) = (uint32_t) (TIMER_CTL0_SPM | TIMER_CTL0_UPS);
  132.     //预分频
  133.     TIMER_PSC(ComTIMER) = TimerClk / 1000000 - 1;
  134.     //装载值
  135.     TIMER_CNT(ComTIMER) = 0;
  136.     //周期
  137.     TIMER_CAR(ComTIMER) = ts50us * 50 - 1; //auto reload value
  138.     //禁止所有通道
  139.     TIMER_CHCTL2(ComTIMER) = 0;
  140.     //产生一次软件更新事件
  141.     TIMER_SWEVG(ComTIMER) = TIMER_SWEVG_UPG; //update
  142.     //清除更新中断标志
  143.     TIMER_INTF(ComTIMER) &= ~((uint32_t) TIMER_INTF_UPIF);
  144.     //更新事件产生中断
  145.     TIMER_DMAINTEN(ComTIMER) = TIMER_DMAINTEN_UPIE;
  146.     NVIC_SetPriority(TIMER6_IRQn, 0xFF);
  147.     NVIC_ClearPendingIRQ(TIMER6_IRQn);
  148.     NVIC_EnableIRQ(TIMER6_IRQn);

  149.     return 1;
  150. }

  151. /*****************************************************************************//*!
  152. * @brief           com modle init .
  153. *               
  154. * @param   none
  155. *
  156. * @return  none
  157. *
  158. * @ Pass/ Fail criteria: none
  159. *****************************************************************************/

  160. void ComInit(uint32_t ulBaudRate, ComParity_t eParity) {
  161.     uint32_t usTimerT35_50us;

  162.     // Enable USART APB clock
  163.     rcu_periph_clock_enable(RCU_USART2);
  164.     rcu_periph_reset_enable(RCU_USART2RST);
  165.     rcu_periph_reset_disable(RCU_USART2RST);

  166.     gpio_af_set(GPIOD, GPIO_AF_7, GPIO_PIN_8 | GPIO_PIN_9);
  167.     gpio_mode_set(GPIOD, GPIO_MODE_AF, GPIO_PUPD_PULLUP, GPIO_PIN_8);
  168.     gpio_output_options_set(GPIOD, GPIO_OTYPE_PP, GPIO_OSPEED_50MHZ, GPIO_PIN_8);
  169.     gpio_mode_set(GPIOD, GPIO_MODE_AF, GPIO_PUPD_PULLUP, GPIO_PIN_9);
  170.     gpio_output_options_set(GPIOD, GPIO_OTYPE_PP, GPIO_OSPEED_50MHZ, GPIO_PIN_9);

  171.     usart_baudrate_set(COM, ulBaudRate);
  172.     ComParity(eParity);

  173.     //Timer init
  174.     {
  175.         if (ulBaudRate > 19200) {
  176.             usTimerT35_50us = 35; /* 1800us. */
  177.         } else {
  178.             usTimerT35_50us = (7UL * 220000UL) / (2UL * ulBaudRate);
  179.         }
  180.         ComTimerInit(usTimerT35_50us);
  181.     }

  182.     ComSndSt = COM_TX_IDLE;
  183.     ComRcvSt = COM_RX_IDLE;

  184.     NVIC_SetPriority(USART2_IRQn, 0xFF);
  185.     NVIC_ClearPendingIRQ(USART2_IRQn);
  186.     NVIC_EnableIRQ(USART2_IRQn);

  187.     ComEnable(ENABLE, DISABLE);
  188. }


  189. /*****************************************************************************//*!
  190. * @brief           com parity set.
  191. *               
  192. * @param   none
  193. *
  194. * @return  none
  195. *
  196. * @ Pass/ Fail criteria: none
  197. *****************************************************************************/

  198. void ComParity(ComParity_t eParity) {
  199.     USART_CTL0(COM) &= ~((uint32_t) USART_CTL0_UEN);
  200.     switch (eParity) {
  201.         case COM_PAR_NONE:
  202.             USART_CTL0(COM) &= ~((uint32_t) (USART_CTL0_PCEN | USART_CTL0_PM | USART_CTL0_WL));
  203.             USART_CTL1(COM) &= ~((uint32_t) USART_CTL1_STB);
  204.             USART_CTL1(COM) |= (uint32_t) BIT(13);
  205.             break;
  206.         case COM_PAR_ODD:
  207.             USART_CTL0(COM) &= ~((uint32_t) (USART_CTL0_PCEN | USART_CTL0_PM | USART_CTL0_WL));
  208.             USART_CTL1(COM) &= ~((uint32_t) USART_CTL1_STB);
  209.             USART_CTL0(COM) |= (uint32_t) (USART_CTL0_PCEN | USART_CTL0_PM | USART_CTL0_WL);
  210.             break;
  211.         case COM_PAR_EVEN:
  212.             USART_CTL0(COM) &= ~((uint32_t) (USART_CTL0_PCEN | USART_CTL0_PM | USART_CTL0_WL));
  213.             USART_CTL1(COM) &= ~((uint32_t) USART_CTL1_STB);
  214.             USART_CTL0(COM) |= (uint32_t) (USART_CTL0_PCEN | USART_CTL0_WL);
  215.             break;
  216.         default:
  217.             break;
  218.     }
  219.     USART_CTL0(COM) |= ((uint32_t) USART_CTL0_UEN);
  220. }

  221. /*****************************************************************************//*!
  222. *
  223. * @brief   Uart En or Dis.
  224. *            
  225. * @param   none
  226. *
  227. * @return  none
  228. *
  229. * @ Pass/ Fail criteria: none
  230. *****************************************************************************/

  231. static void ComEnable(uint8_t xRxEnable, uint8_t xTxEnable) {
  232.     volatile uint8_t u8Temp;
  233.     volatile uint32_t u32Temp;

  234.     if (xRxEnable) {
  235.         USART_CTL0(COM) &= ~((uint32_t) USART_CTL0_TCIE);
  236.         USART_CTL0(COM) &= ~((uint32_t) USART_CTL0_TBEIE);

  237.         ComRxEnable();

  238.         USART_CTL0(COM) &= ~((uint32_t) USART_CTL0_TEN);
  239.         USART_CTL0(COM) |= (uint32_t) USART_CTL0_REN;

  240.         u8Temp = USART_DATA(COM);
  241.         u32Temp = USART_STAT0(COM);
  242.         while ((USART_STAT0(COM) & (USART_STAT0_RBNE | USART_STAT0_ORERR)) != 0) {
  243.             u32Temp = USART_STAT0(COM);
  244.             u8Temp = USART_DATA(COM);
  245.         }

  246.         USART_CTL0(COM) |= USART_CTL0_RBNEIE;

  247.     } else if (xTxEnable) {
  248.         USART_CTL0(COM) &= ~((uint32_t) USART_CTL0_RBNEIE);

  249.         USART_CTL0(COM) &= ~((uint32_t) USART_CTL0_REN);
  250.         USART_CTL0(COM) |= (uint32_t) USART_CTL0_TEN;
  251.         ComTxEnable();

  252.         ComSndCnt--;
  253.         USART_DATA(COM) = *(pComSndCur++);
  254.         USART_CTL0(COM) |= (uint32_t) (USART_CTL0_TBEIE);
  255.     } else {

  256.     }
  257. }

  258. /*****************************************************************************//*!
  259. *
  260. * @brief   Send a string.
  261. *            
  262. * @param   none
  263. *
  264. * @return  none
  265. *
  266. * @ Pass/ Fail criteria: none
  267. *****************************************************************************/

  268. void ComStringSend(uint8_t * pData) {
  269.     if (COM_TX_IDLE == ComSndSt) {
  270.         pComSndCur = pData;
  271.         ComSndCnt = 0;
  272.         while (*pData++)
  273.             ComSndCnt++;
  274.         ComSndSt = COM_TX_XMIT;
  275.         ComEnable(DISABLE, ENABLE);
  276.     } else {

  277.     }
  278. }

  279. /*****************************************************************************//*!
  280. *
  281. * @brief   Send data.
  282. *            
  283. * @param   none
  284. *
  285. * @return  none
  286. *
  287. * @ Pass/ Fail criteria: none
  288. *****************************************************************************/

  289. void ComDataSend(uint8_t * pData, uint16_t Len) {
  290.     if (ComStCheck()) {
  291.         ComSndCnt = Len;
  292.         ComSndSt = COM_TX_XMIT;
  293.         pComSndCur = pData;
  294.         ComEnable(DISABLE, ENABLE);
  295.     } else {

  296.     }
  297. }

  298. /*****************************************************************************//*!
  299. *
  300. * @brief   Port state check.
  301. *            
  302. * @param   none
  303. *
  304. * @return  none
  305. *
  306. * @ Pass/ Fail criteria: none
  307. *****************************************************************************/

  308. uint8_t ComStCheck(void) {
  309.     if (ComSndSt != COM_TX_IDLE)
  310.         return 0;
  311.     if (ComRcvSt != COM_RX_IDLE)
  312.         return 0;
  313.     return 1;
  314. }
复制代码
cominfo.h
  1. #ifndef _COM_INFO_H_
  2. #define        _COM_INFO_H_

  3. #include "stdint.h"

  4. extern uint8_t const ComInfo[][64];

  5. #define   COM_INFO_TEST                    0
  6. #define   COM_INFO_VER                     (COM_INFO_TEST + 1)
  7. #define   COM_INFO_NOCMD                   (COM_INFO_VER + 1)

  8. #endif        /* _COM_INFO_H_ */
复制代码
cominfo.c
  1. /* ------------------------------------------------------------------------*
  2. *
  3. * ------------------------------------------------------------------------*/
  4. #include "stdint.h"
  5. uint8_t const ComInfo[][64] =
  6. {
  7.         "Communicate OK !\r\n\0",
  8.         "System version : 0.01.\r\n\0",
  9.         "No Command Received.\r\n\0"
  10. };
复制代码
comtask.h
  1. ifndef _COM_TASK_H_
  2. #define        _COM_TASK_H_

  3. #include "mytype.h"
  4. #include "stdint.h"

  5. #define   COM_EVENT_RCVEND                    (0x01UL)
  6. #define   COM_EVENT_TIMOUT                    (0x02UL)

  7. #define   COMDLYTIMEOUT                        3000

  8. #define   CMD_START                           (':')

  9. #endif        /* _COM_TASK_H_ */
复制代码
comtask.c
  1. /* ------------------------------------------------------------------------*
  2. *
  3. * ------------------------------------------------------------------------*/
  4. #include "com_hal.h"
  5. #include "comtask.h"
  6. #include "osObjects.h"   
  7. #include "cominfo.h"
  8. #include "dataproc.h"


  9. void CmdProc(void);
  10. void WifiCmd(void);
  11. void Cifsr(void);
  12. void ComStringHandle(void);


  13. /*****************************************************************************//*!
  14. * @brief           com task init .
  15. *               
  16. * @param   none
  17. *
  18. * @return  none
  19. *
  20. * @ Pass/ Fail criteria: none
  21. *****************************************************************************/

  22. void ComTask(void *argument) {

  23.     ComInit(9600, COM_PAR_EVEN);

  24.     for(;;){
  25.         vTaskDelay(10);

  26.         if (pdFALSE == xSemaphoreTake(xSemCom, 3000)) {
  27.             TimeToAscii(&TimeCur, ComBuff);
  28.             ComBuff[19] = '\r';
  29.             ComBuff[20] = '\n';
  30.             ComBuff[21] = 0;
  31.             ComStringSend(ComBuff);
  32.         } else {
  33.             ComStringHandle();
  34.         }
  35.     }
  36. }

  37. /*****************************************************************************//*!
  38. * @brief           String Handle .
  39. *               
  40. * @param   none
  41. *
  42. * @return  none
  43. *
  44. * @ Pass/ Fail criteria: none
  45. *****************************************************************************/

  46. void ComStringHandle(void) {
  47.     switch (ComBuff[0]) {
  48.             //case 'A': WifiCmd();break;
  49.         case ':': CmdProc();
  50.             break;
  51.         default: break;
  52.     }

  53.     ComRcvSt = COM_RX_IDLE;
  54.     ComRcvCnt = 0;
  55. }

  56. /*****************************************************************************//*!
  57. * @brief           Data Handle .
  58. *               
  59. * @param   none
  60. *
  61. * @return  none
  62. *
  63. * @ Pass/ Fail criteria: none
  64. *****************************************************************************/

  65. void ComDataHandle(void) {

  66. }

  67. /*****************************************************************************//*!
  68. * @brief   Command Proc .
  69. *               
  70. * @param   none
  71. *
  72. * @return  none
  73. *
  74. * @ Pass/ Fail criteria: none
  75. *****************************************************************************/

  76. void CmdProc() {
  77.     uint8_t Cnt;

  78.     if (CMD_START != ComBuff[0])
  79.         return;

  80.     switch (ComBuff[1]) {
  81.         case 'T': Cnt = 0;
  82.             while (ComInfo[COM_INFO_TEST][Cnt]) {
  83.                 ComBuff[Cnt] = ComInfo[COM_INFO_TEST][Cnt];
  84.                 Cnt++;
  85.             }
  86.             ComBuff[Cnt] = 0;
  87.             ComStringSend(ComBuff);
  88.             break;
  89.         case 'V': Cnt = 0;
  90.             while (ComInfo[COM_INFO_VER][Cnt]) {
  91.                 ComBuff[Cnt] = ComInfo[COM_INFO_VER][Cnt];
  92.                 Cnt++;
  93.             }
  94.             ComBuff[Cnt] = 0;
  95.             ComStringSend(ComBuff);
  96.             break;
  97.         default: break;
  98.     }
  99. }

复制代码
工程使用了freertos系统,串口收发需要创建一个任务和用于同步的信号量
创建任务
if(pdPASS != xTaskCreate( ComTask, "Com", COM_TASK_STACK_SIZE, NULL, COM_TASK_PRIORITY, NULL )) while(1);
创建信号量
vSemaphoreCreateBinary( xSemCom );
if(NULL == xSemCom) while(1);













回复

使用道具 举报

  • TA的每日心情
    难过
    2021-2-27 22:16
  • 签到天数: 1568 天

    连续签到: 1 天

    [LV.Master]伴坛终老

    发表于 2017-5-26 20:41:00 | 显示全部楼层
    0.png
    回复 支持 反对

    使用道具 举报

    您需要登录后才可以回帖 注册/登录

    本版积分规则

    关闭

    站长推荐上一条 /5 下一条



    手机版|小黑屋|与非网

    GMT+8, 2024-12-24 07:58 , Processed in 0.126432 second(s), 18 queries , MemCache On.

    ICP经营许可证 苏B2-20140176  苏ICP备14012660号-2   苏州灵动帧格网络科技有限公司 版权所有.

    苏公网安备 32059002001037号

    Powered by Discuz! X3.4

    Copyright © 2001-2024, Tencent Cloud.