瑞萨单片机论坛
直播中

jf_1137202360

8年用户 1357经验值
擅长:嵌入式技术
私信 关注
[经验]

【RA4M2设计挑战赛】+串口驱动设计

前言
串口是最常用的通讯方式,简单方便,所以我们先实现该接口。我们需要实现一个比较好用的串口驱动,方便后面各种基于串口的模块使用。老规矩我们还是从手册开始一点一点进行驱动的实现。
过程串口模块介绍IO引脚
UART0
P410
P411
UART4
P205
P206
UART9
P109
P110
参考手册《27. Serial Communications Interface (SCI)
瑞萨的SCI与其他家有点不一样,瑞萨家的SCI是一个大集合,包括了UART,SPI,IIC等串行通讯接口,按照不同配置可以实现不同的接口。我们这里只关注UART
首先我们要从以下方向了解SCI模块
整体框图如下
时钟
SCI使用PLCKA
需要先使能外设时钟
MSTPCRBbit31 27 22分别对应SCI0 SCI4 SCI9,默认为1不使能,需要修改为0使能。
寄存器
l RSR:移位寄存器,收到数据后自动放入RDR, RDRHL或者接收FIFO,CPU也可以直接访问(虽然一半不会这么做)
l RDR:只读接收数据寄存器,RSR接收到一字节后复制到RDR,然后RSR可以继续接收。RDR必须有接收标志SCIn_RXI才能去读,如果没来得及读出RSR又有新的数据过来会溢出。
l RDRHL:类似于RDR只是是Non-Manchester模式9位串口模式使用,16,8位就是RDR的影子寄存器。79位模式不能访问。
l RDRHL_MAN:类似于RDRHL只是是Manchester模式使用,有一些其他同步信息。
l FRDRHL/FRDRH/FRDRL: FIFO模式下读数据和状态,读出的状态和SSR_FIFO一样,SSR_FIFO
寄存器的对应bit0清除状态(注意只需要清除的标志位写0其他位写1)。最好一起直接16位读FRDRHL,硬是要分开8位读,则先读FRDRH再读FRDRL
l TDR:发送寄存器,发送移位寄存器TSR空时,自动TDR移动到TSR进行发送。可读可写,只有发送空SCIn_TXI(TDR已经移动到TSR)才能进行下一次写。
l TDRHL:类似于TDR, Non-Manchester模式使用。
l TDRHL_MAN:类似于TDRHL Manchester模式使用,有一些其他同步信息。
l FTDRHL/FTDRH/FTDRL:类似于TDR,不过是FIFO模式使用。
l TSR:发送移位寄存器。TDR数据自动移动到TSR再按位发出,CPU不能直接访问。
l SMR: Non-Smart Card模式的串行模式选择,即选择串口的额时钟源,是否多机模式,停止校验,数据长度,模式是SPI,IIC还是UART
l SMR_SMCI:Smart Card接口使用我们这里不关心。
l SCR: Non-Smart Card模式串行接口控制,收发使能控制,收发多机处理中断使能控制,时钟输出控制
l  Non-Smart Card:Smart Card接口使用我们这里不关心。
l SSR状态寄存器: Non-Smart Card , Non-FIFO 模式使用。
l SSR_FIFO:状态寄存器FIFO模式,Non-Smart Card模式使用。
l SSR_SMCI:Smart Card接口使用我们这里不关心。
l SSR_MANC:Manchester模式使用我们这里不关心。
l SCMR:Smart Card模式使用我们这里不关心。
l BRR:波特率设置寄存器
l MDDR:波特率微调寄存器(调整小数部分)
l SEMR:调制参数配置,这里不使用不关心。
l SNFR:噪声过滤,串口模式只能设置为0
l SIMR1,SIMR2,SIMR3,SISR:IIC相关这里不关心
l SPMR:SPI相关这里不关心
l FCR:FIFO控制
l FDR:FIFO中收发数据个数。
l LSR:错误计数,溢出标志
l CDR,DCCR:多机通讯有地址匹配的才使用,这里不关心.
l SPTRL:端口配置电平翻转等。
l ACTR:时序调整配置
l MMR,TMPR,RMPR,MESR,MECR:Manchester模式使用这里不关心。
l ESMERExtended Serial Module控制这里不使用不关心。
l CR0,CR1,CR2,CR3
l PCR:端口极性控制。
l ICR:中断控制
l STR:状态
l STCR:状态清除
l CF0DR,CF0CR,CF0RR,PCF1DR,SCF1DR,CF1CR,CF1RR,不使用不关心
l TCR,TMR,TPRE,TCNT不使用不关心。
信号采样
串口是以16bit速率采样的,也就是一个bit的时间有16CLK,在第8CLK进行采样,也就是中间位置读输入引脚状态。
波特率计算
配置流程
引脚配置->
使能时钟->
参数配置->
串口中断配置->
NVIC中断配置->
使能
串口驱动实现
driverhal层实现,driver层只需要调用hal层的接口即可。
整体思想如下:
对于接收,串口接收中断将数据写入缓冲区,串口接收接口查询缓冲区读出即可,无数据则等待或者返回错误
对于发送,发送接口将数据写入缓冲区,串口发送中断中查询缓冲区有则继续发送,直到发送完,所以第一次如果未处于发送中则需要手动触发一次中断,后续就都是在发送完中断中处理。
核心代码
hal_uart.c
  1. #include "R7FA4M2AD.h"
  2. #include "hal_uart.h"
  3. #include "clk.h"


  4. // read FRDRHL  SSR_FIFO FDR


  5. /**
  6. *****************************************************************************
  7. * fn          int HAL_UART_Init(HAL_UART_ID_e id)
  8. * brief       初始化UART模块,完成模块相关必要的初始化配置.
  9. * note        使用UART前必须调用,所有UART按默认配置(BSP实现).
  10. * param[in]   id UARTid,依赖于BSP实现,ref HAL_UART_ID_e.
  11. * retval      0 初始化成功.
  12. * retval      -1 初始化失败.
  13. *****************************************************************************
  14. */
  15. int HAL_UART_Init(HAL_UART_ID_e id)
  16. {
  17.     return 0;
  18. }

  19. /**
  20. *****************************************************************************
  21. * fn          int HAL_UART_CheckSend(HAL_UART_ID_e id,unsigned char byte)
  22. * brief       查询的方式发送一个字节.
  23. * note        阻塞发送,直到发送完才会返回.  
  24. * param[in]   id UARTid,依赖于BSP实现,ref HAL_UART_ID_e.
  25. * param[in]   byte 需要发送的字节.
  26. * retval      0 发送成功.
  27. * retval      其他值 发送失败(实际上没有发送完会阻塞所以不会返回其他值).
  28. *****************************************************************************
  29. */
  30. int HAL_UART_CheckSend(HAL_UART_ID_e id,unsigned char value)
  31. {
  32.         int res = 0;
  33.         switch(id)
  34.   {
  35.           case 0:
  36.                         if(R_SCI0->SSR_FIFO_b.TDFE == 1)
  37.       {
  38.                                 R_SCI0->FTDRL = value;
  39.                                 res = 0;
  40.                         }
  41.                         else
  42.       {
  43.                                 res = -1;
  44.                         }
  45.                 break;
  46.           case HAL_UART_4:
  47.                         if(R_SCI4->SSR_FIFO_b.TDFE == 1)
  48.       {
  49.                                 R_SCI4->FTDRL = value;
  50.                                 res = 0;
  51.                         }
  52.                         else
  53.       {
  54.                                 res = -1;
  55.                         }
  56.                 break;
  57.           case HAL_UART_9:
  58.                         if(R_SCI9->SSR_FIFO_b.TDFE == 1)
  59.       {
  60.                                 R_SCI9->FTDRL = value;
  61.                                 res = 0;
  62.                         }
  63.                         else
  64.       {
  65.                                 res = -1;
  66.                         }
  67.                 break;
  68.                 default:
  69.                                 res = -1;
  70.                         break;
  71.         }
  72.         return res;
  73. }

  74. /**
  75. *****************************************************************************
  76. * fn          int HAL_UART_CheckRead(HAL_UART_ID_e id,unsigned char* byte);
  77. * brief       查询的方式读一个字节.
  78. * note        阻塞读,直到有数据才会返回.  
  79. * param[in]   id UARTid,依赖于BSP实现,ref HAL_UART_ID_e.
  80. * param[in]   byte 存储读到的字节.
  81. * retval      0 读成功.
  82. * retval      其他值 读失败(实际上读不到数据会阻塞所以不会返回其他值).
  83. *****************************************************************************
  84. */
  85. int HAL_UART_CheckRead(HAL_UART_ID_e id,unsigned char* byte)
  86. {
  87.     return 0;
  88. }

  89. /**
  90. *****************************************************************************
  91. * fn          int HAL_UART_Send(HAL_UART_ID_e id,unsigned char byte)
  92. * brief       直接发送一个字节.
  93. * note        直接发送,直接往硬件发送缓冲写字节立即返回.  
  94. * param[in]   id UARTid,依赖于BSP实现,ref HAL_UART_ID_e.
  95. * param[in]   byte 需要发送的字节.
  96. * retval      0 发送成功.
  97. * retval      其他值 发送失败(实际上不会返回其他值).
  98. *****************************************************************************
  99. */
  100. int HAL_UART_Send(HAL_UART_ID_e id,unsigned char byte)
  101. {
  102.     return 0;
  103. }

  104. /**
  105. *****************************************************************************
  106. * fn          int HAL_UART_Read(HAL_UART_ID_e id,unsigned char* byte);
  107. * brief       直接读一个字节.
  108. * note        直接读,直接读硬件缓冲立即返回.  
  109. * param[in]   id UARTid,依赖于BSP实现,ref HAL_UART_ID_e.
  110. * param[in]   byte 存储读到的字节.
  111. * retval      0 读成功.
  112. * retval      其他值 读失败(实际上不会返回其他值).
  113. *****************************************************************************
  114. */
  115. int HAL_UART_Read(HAL_UART_ID_e id,unsigned char* byte)
  116. {
  117.     return 0;
  118. }

  119. /**
  120. *****************************************************************************
  121. * fn          int HAL_UART_SetTxISRCallBack(HAL_UART_ID_e id,HAL_UART_ISRCallBack callbackfun)
  122. * brief       设置发送缓冲区空中断服务回调函数.
  123. * note        .  
  124. * param[in]   id UARTid,依赖于BSP实现,ref HAL_UART_ID_e.
  125. * param[in]   callbackfun 回调函数.
  126. * retval      0 设置成功.
  127. * retval      其他值 设置失败.
  128. *****************************************************************************
  129. */
  130. int HAL_UART_SetTxISRCallBack(HAL_UART_ID_e id,HAL_UART_ISRCallBack callbackfun)
  131. {
  132.     return 0;
  133. }

  134. /**
  135. *****************************************************************************
  136. * fn          int HAL_UART_SetTxCmpISRCallBack(HAL_UART_ID_e id,HAL_UART_ISRCallBack callbackfun)
  137. * brief       设置发送完中断服务回调函数.
  138. * note        .  
  139. * param[in]   id UARTid,依赖于BSP实现,ref HAL_UART_ID_e.
  140. * param[in]   callbackfun 回调函数.
  141. * retval      0 设置成功.
  142. * retval      其他值 设置失败.
  143. *****************************************************************************
  144. */
  145. int HAL_UART_SetTxCmpISRCallBack(HAL_UART_ID_e id,HAL_UART_ISRCallBack callbackfun)
  146. {
  147.     return 0;;
  148. }

  149. /**
  150. *****************************************************************************
  151. * fn          int HAL_UART_SetRxCallBack(HAL_UART_ID_e id,HAL_UART_ISRCallBack callbackfun)
  152. * brief       设置接收缓冲满中断服务回调函数.
  153. * note        .  
  154. * param[in]   id UARTid,依赖于BSP实现,ref HAL_UART_ID_e.
  155. * param[in]   callbackfun 回调函数.
  156. * retval      0 设置成功.
  157. * retval      其他值 设置失败.
  158. *****************************************************************************
  159. */
  160. int HAL_UART_SetRxCallBack(HAL_UART_ID_e id,HAL_UART_ISRCallBack callbackfun)
  161. {
  162.     return 0;
  163. }

  164. /**
  165. *****************************************************************************
  166. * fn          int HAL_UART_SetRxErrCallBack(HAL_UART_ID_e id,HAL_UART_ISRCallBack callbackfun)
  167. * brief       设置接收错误中断服务回调函数.
  168. * note        .  
  169. * param[in]   id UARTid,依赖于BSP实现,ref HAL_UART_ID_e.
  170. * param[in]   callbackfun 回调函数.
  171. * retval      0 设置成功.
  172. * retval      其他值 设置失败.
  173. *****************************************************************************
  174. */
  175. int HAL_UART_SetRxErrCallBack(HAL_UART_ID_e id,HAL_UART_ISRCallBack callbackfun)
  176. {
  177.     return 0;
  178. }

  179. /**
  180. *****************************************************************************
  181. * fn          int HAL_UART_SetCfg(HAL_UART_ID_e id,HAL_UART_CFG_t* cfg)
  182. * brief       配置UART参数.
  183. * note        .  
  184. * param[in]   id UARTid,依赖于BSP实现,ref HAL_UART_ID_e.
  185. * param[in]   cfg 指向配置参数结构体 ref HAL_UART_CFG_t.
  186. * retval      0 设置成功.
  187. * retval      其他值 设置失败.
  188. *****************************************************************************
  189. */
  190. int HAL_UART_SetCfg(HAL_UART_ID_e id,HAL_UART_CFG_t* cfg)
  191. {
  192.         int res = 0;
  193.         switch(id)
  194.   {
  195.           case HAL_UART_0:
  196.                           /* Enable CLK */
  197.                                 R_MSTP->MSTPCRB_b.MSTPB31 = 0;  /* SCI0 */
  198.                
  199.                     /* disable */
  200.                                 R_SCI0->SCR_b.RE = 0;
  201.                                 R_SCI0->SCR_b.TE = 0;
  202.                
  203.                    /*P410 RXD0 PSEL:4
  204.                     *P411 TXD0 PSEL:4
  205.                     */
  206.                                 R_PMISC->PWPR_b.B0WI = 0;
  207.                                 R_PMISC->PWPR_b.PFSWE = 1;
  208.                
  209.                           R_PFS->PORT[4].PIN[10].PmnPFS_b.PODR = 1;  /*0: Low output 1: High output */
  210.                           //R_PFS->PORT[4].PIN[10].PmnPFS_b.PIDR     /*0: Low level  1: High level  */
  211.                                 R_PFS->PORT[4].PIN[10].PmnPFS_b.PDR = 0;   /*0: Input (functions as an input pin) 1: Output (functions as an output pin) */
  212.                                 R_PFS->PORT[4].PIN[10].PmnPFS_b.PCR = 1;   /*0: Disable input pull-up 1: Enable input pull-up */
  213.                     //R_PFS->PORT[4].PIN[10].PmnPFS_b.PIM      /* This bit is read as 0. The write value should be 0. */
  214.                                 R_PFS->PORT[4].PIN[10].PmnPFS_b.NCODR = 0; /* 0: CMOS output  1: NMOS open-drain output */
  215.                           R_PFS->PORT[4].PIN[10].PmnPFS_b.DSCR = 3;  /* 00: Low drive  01: Middle drive 10: Setting prohibited 11: High drive */
  216.                     R_PFS->PORT[4].PIN[10].PmnPFS_b.EOFR = 0;  /* 00: Don't care 01: Detect rising edge 01: Detect rising edge 11: Detect both edges*/
  217.                     R_PFS->PORT[4].PIN[10].PmnPFS_b.ISEL = 0;  /* 0: Not used as an IRQn input pin 1: Used as an IRQn input pin */
  218.                                 R_PFS->PORT[4].PIN[10].PmnPFS_b.ASEL = 0;  /* 0: Not used as an analog pin 1: Used as an analog pin */
  219.               R_PFS->PORT[4].PIN[10].PmnPFS_b.PMR = 1;   /* 0: Used as a general I/O pin 1: Used as an I/O port for peripheral functions */
  220.                                 R_PFS->PORT[4].PIN[10].PmnPFS_b.PSEL = 4;  /* Peripheral Select */
  221.                                
  222.                           R_PFS->PORT[4].PIN[11].PmnPFS_b.PODR = 1;  /*0: Low output 1: High output */
  223.                           //R_PFS->PORT[4].PIN[11].PmnPFS_b.PIDR     /*0: Low level  1: High level  */
  224.                                 R_PFS->PORT[4].PIN[11].PmnPFS_b.PDR = 1;   /*0: Input (functions as an input pin) 1: Output (functions as an output pin) */
  225.                                 R_PFS->PORT[4].PIN[11].PmnPFS_b.PCR = 1;   /*0: Disable input pull-up 1: Enable input pull-up */
  226.                     //R_PFS->PORT[4].PIN[11].PmnPFS_b.PIM      /* This bit is read as 0. The write value should be 0. */
  227.                                 R_PFS->PORT[4].PIN[11].PmnPFS_b.NCODR = 0; /* 0: CMOS output  1: NMOS open-drain output */
  228.                           R_PFS->PORT[4].PIN[11].PmnPFS_b.DSCR = 3;  /* 00: Low drive  01: Middle drive 10: Setting prohibited 11: High drive */
  229.                     R_PFS->PORT[4].PIN[11].PmnPFS_b.EOFR = 0;  /* 00: Don't care 01: Detect rising edge 01: Detect rising edge 11: Detect both edges*/
  230.                     R_PFS->PORT[4].PIN[11].PmnPFS_b.ISEL = 0;  /* 0: Not used as an IRQn input pin 1: Used as an IRQn input pin */
  231.                                 R_PFS->PORT[4].PIN[11].PmnPFS_b.ASEL = 0;  /* 0: Not used as an analog pin 1: Used as an analog pin */
  232.               R_PFS->PORT[4].PIN[11].PmnPFS_b.PMR = 1;   /* 0: Used as a general I/O pin 1: Used as an I/O port for peripheral functions */
  233.                                 R_PFS->PORT[4].PIN[11].PmnPFS_b.PSEL = 4;  /* Peripheral Select */
  234.                                
  235.                                 R_PMISC->PWPR_b.PFSWE = 0;
  236.                                 R_PMISC->PWPR_b.B0WI = 1;
  237.                                
  238.                                 /*
  239.                                  *  set param
  240.                                  */
  241.                                  R_SCI0->SMR_b.CKS = 0; /* 00: PCLK clock (n = 0) 01: PCLK/4 clock 10: PCLK/16 clock 11: PCLK/64 clock  */
  242.                                  R_SCI0->SMR_b.MP = 0;  /*0: Disable multi-processor communications function 1: Enable multi-processor communications function */
  243.                                  R_SCI0->SMR_b.STOP = 0;  /*0: 1 stop bit 1: 2 stop bits */
  244.                                  R_SCI0->SMR_b.PM = 0;   /* 0: Even parity 1: Odd parity */
  245.                                  R_SCI0->SMR_b.PE = 0;   /* 0: Parity Disable 1: Parity Enable */
  246.                                  R_SCI0->SMR_b.CHR = 0;   /* SCMR.CHR1=0: 0-9bits 1-9bits  SCMR.CHR1=1: 0-8bits 1-7bits */
  247.                                  R_SCI0->SMR_b.CM = 0;    /* 0: Asynchronous mode or simple IIC mode 1: Clock synchronous mode or simple SPI mode*/
  248.                                  
  249.                                  R_SCI0->SCR_b.CKE = 0;   /*1 Clock Enable 0 Clock Disable*/
  250.                                  R_SCI0->SCR_b.TEIE = 0;  /* 0: Disable SCIn_TEI interrupt requests 1: Enable SCIn_TEI interrupt requests */
  251.                                  R_SCI0->SCR_b.MPIE = 0;
  252.                                  R_SCI0->SCR_b.RIE = 1;
  253.                                  R_SCI0->SCR_b.TIE = 0;
  254.                                  
  255.                                  R_SCI0->FCR_b.FM = 1;     /* 0: Non-FIFO mode. 1: FIFO mode. */
  256.                                  R_SCI0->FCR_b.RFRST = 1;  /* 0: Do not reset FRDRHL 1: Reset FRDRHL */
  257.                                  R_SCI0->FCR_b.RFRST = 0;
  258.                                  R_SCI0->FCR_b.TFRST = 1;  /* 0: Do not reset FTDRHL 1: Reset FTDRHL */
  259.                                  R_SCI0->FCR_b.TFRST = 0;
  260.                                  R_SCI0->FCR_b.DRES = 0;   /*Receive Data Ready Error Select Selects the interrupt requested when detecting receive data ready. 0: Receive data full interrupt (SCIn_RXI) 1: Receive error interrupt (SCIn_ERI) */
  261.                                  R_SCI0->FCR_b.TTRG = 1;   /* Transmit FIFO Data Trigger Number */
  262.          R_SCI0->FCR_b.RTRG = 1;   /* Receive FIFO Data Trigger Number */
  263.                                  R_SCI0->FCR_b.RSTRG = 0;  /* RTS Output Active Trigger Number Select */
  264.                                  
  265.                                  R_SCI0->SEMR_b.BRME =         1;
  266.                                  R_SCI0->SEMR_b.ABCS =         0;
  267.                                  R_SCI0->SEMR_b.BGDM =         0;
  268.                                  R_SCI0->SEMR_b.ABCSE =         0;
  269.                                 /*
  270.                                  * set baud
  271.                                  * PCLK/(64*2^(2*n-1))*(256/M)*B - 1 n=0  CKS[1:0]=0
  272.                                  */
  273.                                  R_SCI0->BRR = clk_get_pclka()/(32*cfg->baud) - 1;
  274.                                  R_SCI0->MDDR = 256;
  275.                                  /*
  276.                                   * enable
  277.                                   */
  278.                                  R_SCI0->SCR_b.RE = 1;
  279.                                  R_SCI0->SCR_b.TE = 1;
  280.                         break;
  281.                 case HAL_UART_4:
  282.                           /* Enable CLK */
  283.                                 R_MSTP->MSTPCRB_b.MSTPB27 = 0;  /* SCI4 */
  284.                
  285.                    /*P205 TXD4 PSEL:4
  286.                     *P206 RXD4 PSEL:4
  287.                     */
  288.                                 R_PMISC->PWPR_b.B0WI = 0;
  289.                                 R_PMISC->PWPR_b.PFSWE = 1;
  290.                
  291.                           R_PFS->PORT[2].PIN[6].PmnPFS_b.PODR = 1;  /*0: Low output 1: High output */
  292.                           //R_PFS->PORT[2].PIN[6].PmnPFS_b.PIDR     /*0: Low level  1: High level  */
  293.                                 R_PFS->PORT[2].PIN[6].PmnPFS_b.PDR = 0;   /*0: Input (functions as an input pin) 1: Output (functions as an output pin) */
  294.                                 R_PFS->PORT[2].PIN[6].PmnPFS_b.PCR = 1;   /*0: Disable input pull-up 1: Enable input pull-up */
  295.                     //R_PFS->PORT[2].PIN[6].PmnPFS_b.PIM      /* This bit is read as 0. The write value should be 0. */
  296.                                 R_PFS->PORT[2].PIN[6].PmnPFS_b.NCODR = 0; /* 0: CMOS output  1: NMOS open-drain output */
  297.                           R_PFS->PORT[2].PIN[6].PmnPFS_b.DSCR = 3;  /* 00: Low drive  01: Middle drive 10: Setting prohibited 11: High drive */
  298.                     R_PFS->PORT[2].PIN[6].PmnPFS_b.EOFR = 0;  /* 00: Don't care 01: Detect rising edge 01: Detect rising edge 11: Detect both edges*/
  299.                     R_PFS->PORT[2].PIN[6].PmnPFS_b.ISEL = 0;  /* 0: Not used as an IRQn input pin 1: Used as an IRQn input pin */
  300.                                 R_PFS->PORT[2].PIN[6].PmnPFS_b.ASEL = 0;  /* 0: Not used as an analog pin 1: Used as an analog pin */
  301.               R_PFS->PORT[2].PIN[6].PmnPFS_b.PMR = 1;   /* 0: Used as a general I/O pin 1: Used as an I/O port for peripheral functions */
  302.                                 R_PFS->PORT[2].PIN[6].PmnPFS_b.PSEL = 4;  /* Peripheral Select */
  303.                                
  304.                           R_PFS->PORT[2].PIN[5].PmnPFS_b.PODR = 1;  /*0: Low output 1: High output */
  305.                           //R_PFS->PORT[2].PIN[5].PmnPFS_b.PIDR     /*0: Low level  1: High level  */
  306.                                 R_PFS->PORT[2].PIN[5].PmnPFS_b.PDR = 1;   /*0: Input (functions as an input pin) 1: Output (functions as an output pin) */
  307.                                 R_PFS->PORT[2].PIN[5].PmnPFS_b.PCR = 1;   /*0: Disable input pull-up 1: Enable input pull-up */
  308.                     //R_PFS->PORT[2].PIN[5].PmnPFS_b.PIM      /* This bit is read as 0. The write value should be 0. */
  309.                                 R_PFS->PORT[2].PIN[5].PmnPFS_b.NCODR = 0; /* 0: CMOS output  1: NMOS open-drain output */
  310.                           R_PFS->PORT[2].PIN[5].PmnPFS_b.DSCR = 3;  /* 00: Low drive  01: Middle drive 10: Setting prohibited 11: High drive */
  311.                     R_PFS->PORT[2].PIN[5].PmnPFS_b.EOFR = 0;  /* 00: Don't care 01: Detect rising edge 01: Detect rising edge 11: Detect both edges*/
  312.                     R_PFS->PORT[2].PIN[5].PmnPFS_b.ISEL = 0;  /* 0: Not used as an IRQn input pin 1: Used as an IRQn input pin */
  313.                                 R_PFS->PORT[2].PIN[5].PmnPFS_b.ASEL = 0;  /* 0: Not used as an analog pin 1: Used as an analog pin */
  314.               R_PFS->PORT[2].PIN[5].PmnPFS_b.PMR = 1;   /* 0: Used as a general I/O pin 1: Used as an I/O port for peripheral functions */
  315.                                 R_PFS->PORT[2].PIN[5].PmnPFS_b.PSEL = 4;  /* Peripheral Select */
  316.                                
  317.                                 R_PMISC->PWPR_b.PFSWE = 0;
  318.                                 R_PMISC->PWPR_b.B0WI = 1;       
  319.                                
  320.                                 /*
  321.                                  *  set param
  322.                                  */
  323.                                  R_SCI4->SMR_b.CKS = 0; /* 00: PCLK clock (n = 0) 01: PCLK/4 clock 10: PCLK/16 clock 11: PCLK/64 clock  */
  324.                                  R_SCI4->SMR_b.MP = 0;  /*0: Disable multi-processor communications function 1: Enable multi-processor communications function */
  325.                                  R_SCI4->SMR_b.STOP = 0;  /*0: 1 stop bit 1: 2 stop bits */
  326.                                  R_SCI4->SMR_b.PM = 0;   /* 0: Even parity 1: Odd parity */
  327.                                  R_SCI4->SMR_b.PE = 0;   /* 0: Parity Disable 1: Parity Enable */
  328.                                  R_SCI4->SMR_b.CHR = 0;   /* SCMR.CHR1=0: 0-9bits 1-9bits  SCMR.CHR1=1: 0-8bits 1-7bits */
  329.                                  R_SCI4->SMR_b.CM = 0;    /* 0: Asynchronous mode or simple IIC mode 1: Clock synchronous mode or simple SPI mode*/
  330.                                  
  331.                                  R_SCI4->SCR_b.CKE = 0;   /*1 Clock Enable 0 Clock Disable*/
  332.                                  R_SCI4->SCR_b.TEIE = 0;  /* 0: Disable SCIn_TEI interrupt requests 1: Enable SCIn_TEI interrupt requests */
  333.                                  R_SCI4->SCR_b.MPIE = 0;
  334.                                  R_SCI4->SCR_b.RIE = 1;
  335.                                  R_SCI4->SCR_b.TIE = 0;
  336.                                  
  337.                                  R_SCI4->FCR_b.FM = 1;     /* 0: Non-FIFO mode. 1: FIFO mode. */
  338.                                  R_SCI4->FCR_b.RFRST = 1;  /* 0: Do not reset FRDRHL 1: Reset FRDRHL */
  339.                                  R_SCI4->FCR_b.RFRST = 0;
  340.                                  R_SCI4->FCR_b.TFRST = 1;  /* 0: Do not reset FTDRHL 1: Reset FTDRHL */
  341.                                  R_SCI4->FCR_b.TFRST = 0;
  342.                                  R_SCI4->FCR_b.DRES = 0;   /*Receive Data Ready Error Select Selects the interrupt requested when detecting receive data ready. 0: Receive data full interrupt (SCIn_RXI) 1: Receive error interrupt (SCIn_ERI) */
  343.                                  R_SCI4->FCR_b.TTRG = 1;   /* Transmit FIFO Data Trigger Number */
  344.          R_SCI4->FCR_b.RTRG = 1;   /* Receive FIFO Data Trigger Number */
  345.                                  R_SCI4->FCR_b.RSTRG = 0;  /* RTS Output Active Trigger Number Select */
  346.                                  
  347.                                  R_SCI4->SEMR_b.BRME =         1;
  348.                                  R_SCI4->SEMR_b.ABCS =         0;
  349.                                  R_SCI4->SEMR_b.BGDM =         0;
  350.                                  R_SCI4->SEMR_b.ABCSE =         0;
  351.                                 /*
  352.                                  * set baud
  353.                                  * PCLK/(64*2^(2*n-1))*(256/M)*B - 1 n=0  CKS[1:0]=0
  354.                                  */
  355.                                  R_SCI4->BRR = clk_get_pclka()/(32*cfg->baud) - 1;
  356.                                  R_SCI4->MDDR = 256;
  357.                                  /*
  358.                                   * enable
  359.                                   */
  360.                                  R_SCI4->SCR_b.RE = 1;
  361.                                  R_SCI4->SCR_b.TE = 1;
  362.                         break;
  363.                 case HAL_UART_9:
  364.                           /* Enable CLK */
  365.                                 R_MSTP->MSTPCRB_b.MSTPB22 = 0;  /* SCI9 */
  366.                
  367.                    /*P109 TXD9 PSEL:5
  368.                     *P110 RXD9 PSEL:5
  369.                     */
  370.                                 R_PMISC->PWPR_b.B0WI = 0;
  371.                                 R_PMISC->PWPR_b.PFSWE = 1;
  372.                
  373.                           R_PFS->PORT[1].PIN[10].PmnPFS_b.PODR = 1;  /*0: Low output 1: High output */
  374.                           //R_PFS->PORT[1].PIN[10].PmnPFS_b.PIDR     /*0: Low level  1: High level  */
  375.                                 R_PFS->PORT[1].PIN[10].PmnPFS_b.PDR = 0;   /*0: Input (functions as an input pin) 1: Output (functions as an output pin) */
  376.                                 R_PFS->PORT[1].PIN[10].PmnPFS_b.PCR = 1;   /*0: Disable input pull-up 1: Enable input pull-up */
  377.                     //R_PFS->PORT[1].PIN[10].PmnPFS_b.PIM      /* This bit is read as 0. The write value should be 0. */
  378.                                 R_PFS->PORT[1].PIN[10].PmnPFS_b.NCODR = 0; /* 0: CMOS output  1: NMOS open-drain output */
  379.                           R_PFS->PORT[1].PIN[10].PmnPFS_b.DSCR = 3;  /* 00: Low drive  01: Middle drive 10: Setting prohibited 11: High drive */
  380.                     R_PFS->PORT[1].PIN[10].PmnPFS_b.EOFR = 0;  /* 00: Don't care 01: Detect rising edge 01: Detect rising edge 11: Detect both edges*/
  381.                     R_PFS->PORT[1].PIN[10].PmnPFS_b.ISEL = 0;  /* 0: Not used as an IRQn input pin 1: Used as an IRQn input pin */
  382.                                 R_PFS->PORT[1].PIN[10].PmnPFS_b.ASEL = 0;  /* 0: Not used as an analog pin 1: Used as an analog pin */
  383.               R_PFS->PORT[1].PIN[10].PmnPFS_b.PMR = 1;   /* 0: Used as a general I/O pin 1: Used as an I/O port for peripheral functions */
  384.                                 R_PFS->PORT[1].PIN[10].PmnPFS_b.PSEL = 5;  /* Peripheral Select */
  385.                                
  386.                           R_PFS->PORT[1].PIN[9].PmnPFS_b.PODR = 1;  /*0: Low output 1: High output */
  387.                           //R_PFS->PORT[1].PIN[9].PmnPFS_b.PIDR     /*0: Low level  1: High level  */
  388.                                 R_PFS->PORT[1].PIN[9].PmnPFS_b.PDR = 1;   /*0: Input (functions as an input pin) 1: Output (functions as an output pin) */
  389.                                 R_PFS->PORT[1].PIN[9].PmnPFS_b.PCR = 1;   /*0: Disable input pull-up 1: Enable input pull-up */
  390.                     //R_PFS->PORT[1].PIN[9].PmnPFS_b.PIM      /* This bit is read as 0. The write value should be 0. */
  391.                                 R_PFS->PORT[1].PIN[9].PmnPFS_b.NCODR = 0; /* 0: CMOS output  1: NMOS open-drain output */
  392.                           R_PFS->PORT[1].PIN[9].PmnPFS_b.DSCR = 3;  /* 00: Low drive  01: Middle drive 10: Setting prohibited 11: High drive */
  393.                     R_PFS->PORT[1].PIN[9].PmnPFS_b.EOFR = 0;  /* 00: Don't care 01: Detect rising edge 01: Detect rising edge 11: Detect both edges*/
  394.                     R_PFS->PORT[1].PIN[9].PmnPFS_b.ISEL = 0;  /* 0: Not used as an IRQn input pin 1: Used as an IRQn input pin */
  395.                                 R_PFS->PORT[1].PIN[9].PmnPFS_b.ASEL = 0;  /* 0: Not used as an analog pin 1: Used as an analog pin */
  396.               R_PFS->PORT[1].PIN[9].PmnPFS_b.PMR = 1;   /* 0: Used as a general I/O pin 1: Used as an I/O port for peripheral functions */
  397.                                 R_PFS->PORT[1].PIN[9].PmnPFS_b.PSEL = 5;  /* Peripheral Select */
  398.                                
  399.                                 R_PMISC->PWPR_b.PFSWE = 0;
  400.                                 R_PMISC->PWPR_b.B0WI = 1;       
  401.                                
  402.                                 /*
  403.                                  *  set param
  404.                                  */
  405.                                  R_SCI9->SMR_b.CKS = 0; /* 00: PCLK clock (n = 0) 01: PCLK/4 clock 10: PCLK/16 clock 11: PCLK/64 clock  */
  406.                                  R_SCI9->SMR_b.MP = 0;  /*0: Disable multi-processor communications function 1: Enable multi-processor communications function */
  407.                                  R_SCI9->SMR_b.STOP = 0;  /*0: 1 stop bit 1: 2 stop bits */
  408.                                  R_SCI9->SMR_b.PM = 0;   /* 0: Even parity 1: Odd parity */
  409.                                  R_SCI9->SMR_b.PE = 0;   /* 0: Parity Disable 1: Parity Enable */
  410.                                  R_SCI9->SMR_b.CHR = 0;   /* SCMR.CHR1=0: 0-9bits 1-9bits  SCMR.CHR1=1: 0-8bits 1-7bits */
  411.                                  R_SCI9->SMR_b.CM = 0;    /* 0: Asynchronous mode or simple IIC mode 1: Clock synchronous mode or simple SPI mode*/
  412.                                  
  413.                                  R_SCI9->SCR_b.CKE = 0;   /*1 Clock Enable 0 Clock Disable*/
  414.                                  R_SCI9->SCR_b.TEIE = 0;  /* 0: Disable SCIn_TEI interrupt requests 1: Enable SCIn_TEI interrupt requests */
  415.                                  R_SCI9->SCR_b.MPIE = 0;
  416.                                  R_SCI9->SCR_b.RIE = 1;
  417.                                  R_SCI9->SCR_b.TIE = 0;
  418.                                  
  419.                                  R_SCI9->FCR_b.FM = 1;     /* 0: Non-FIFO mode. 1: FIFO mode. */
  420.                                  R_SCI9->FCR_b.RFRST = 1;  /* 0: Do not reset FRDRHL 1: Reset FRDRHL */
  421.                                  R_SCI9->FCR_b.RFRST = 0;
  422.                                  R_SCI9->FCR_b.TFRST = 1;  /* 0: Do not reset FTDRHL 1: Reset FTDRHL */
  423.                                  R_SCI9->FCR_b.TFRST = 0;
  424.                                  R_SCI9->FCR_b.DRES = 0;   /*Receive Data Ready Error Select Selects the interrupt requested when detecting receive data ready. 0: Receive data full interrupt (SCIn_RXI) 1: Receive error interrupt (SCIn_ERI) */
  425.                                  R_SCI9->FCR_b.TTRG = 1;   /* Transmit FIFO Data Trigger Number */
  426.          R_SCI9->FCR_b.RTRG = 1;   /* Receive FIFO Data Trigger Number */
  427.                                  R_SCI9->FCR_b.RSTRG = 0;  /* RTS Output Active Trigger Number Select */
  428.                                  
  429.                                  R_SCI9->SEMR_b.BRME =         1;
  430.                                  R_SCI9->SEMR_b.ABCS =         0;
  431.                                  R_SCI9->SEMR_b.BGDM =         0;
  432.                                  R_SCI9->SEMR_b.ABCSE =         0;
  433.                                 /*
  434.                                  * set baud
  435.                                  * PCLK/(64*2^(2*n-1))*(256/M)*B - 1 n=0  CKS[1:0]=0
  436.                                  */
  437.                                  R_SCI9->BRR = clk_get_pclka()/(32*cfg->baud) - 1;
  438.                                  R_SCI9->MDDR = 256;
  439.                                  /*
  440.                                   * enable
  441.                                   */
  442.                                  R_SCI9->SCR_b.RE = 1;
  443.                                  R_SCI9->SCR_b.TE = 1;
  444.                         break;
  445.                 default:
  446.                                 res = -1;
  447.                         break;
  448.         }
  449.         return res;
  450. }

  451. /**
  452. *****************************************************************************
  453. * fn          int HAL_UART_EnableTx(HAL_UART_ID_e id,HAL_UART_TYPE_e type,HAL_UART_ENABLE_e enable)
  454. * brief       发送使能.
  455. * note        .  
  456. * param[in]   id UARTid,依赖于BSP实现,ref HAL_UART_ID_e.
  457. * param[in]   type 处理方式 ref HAL_UART_TYPE_e.
  458. * param[in]   enable 使能或者禁能 ref HAL_UART_ENABLE_e.
  459. * retval      0 设置成功.
  460. * retval      其他值 设置失败.
  461. *****************************************************************************
  462. */
  463. int HAL_UART_EnableTx(HAL_UART_ID_e id,HAL_UART_TYPE_e type,HAL_UART_ENABLE_e enable)
  464. {
  465.     return 0;
  466. }

  467. /**
  468. *****************************************************************************
  469. * fn          int HAL_UART_EnableRx(HAL_UART_ID_e id,HAL_UART_TYPE_e type,HAL_UART_ENABLE_e enable)
  470. * brief       接收使能.
  471. * note        .  
  472. * param[in]   id UARTid,依赖于BSP实现,ref HAL_UART_ID_e.
  473. * param[in]   type 处理方式 ref HAL_UART_TYPE_e.
  474. * param[in]   enable 使能或者禁能 ref HAL_UART_ENABLE_e.
  475. * retval      0 设置成功.
  476. * retval      其他值 设置失败.
  477. *****************************************************************************
  478. */
  479. int HAL_UART_EnableRx(HAL_UART_ID_e id,HAL_UART_TYPE_e type,HAL_UART_ENABLE_e enable)
  480. {
  481.     return 0;
  482. }

  483. /**
  484. *****************************************************************************
  485. * fn          int HAL_UART_EnableRxErr(HAL_UART_ID_e id,HAL_UART_TYPE_e type,HAL_UART_ENABLE_e enable)
  486. * brief       接收错误中断使能.
  487. * note        .  
  488. * param[in]   id UARTid,依赖于BSP实现,ref HAL_UART_ID_e.
  489. * param[in]   type 处理方式 ref HAL_UART_TYPE_e.
  490. * param[in]   enable 使能或者禁能 ref HAL_UART_ENABLE_e.
  491. * retval      0 设置成功.
  492. * retval      其他值 设置失败.
  493. *****************************************************************************
  494. */
  495. int HAL_UART_EnableRxErr(HAL_UART_ID_e id,HAL_UART_TYPE_e type,HAL_UART_ENABLE_e enable)
  496. {
  497.     return 0;
  498. }

  499. /**
  500. *****************************************************************************
  501. * fn          int HAL_UART_DeInit(HAL_UART_ID_e id)
  502. * brief       解除UART模块,关闭模块.
  503. * note        .
  504. * param[in]   id UARTid,依赖于BSP实现,ref HAL_UART_ID_e.
  505. * retval      0 成功.
  506. * retval      -1 失败.
  507. *****************************************************************************
  508. */
  509. int HAL_UART_DeInit(HAL_UART_ID_e id)
  510. {
  511.     return 0;
  512. }
hal_uart.h
  1. #ifndef __HAL_UART_H
  2. #define __HAL_UART_H

  3. #ifdef __cplusplus
  4. extern "C" {
  5. #endif

  6.      
  7. /** addtogroup HAL
  8. *  {
  9. */   
  10.      
  11. /** addtogroup HAL_UART 硬件抽象层(HAL)串口模块(UART)
  12. *  {
  13. */
  14. /*****************************************************************************   
  15. *                                                                           *
  16. *                             数据结构描述                                  *
  17. *                                                                          *
  18. ****************************************************************************/
  19.    

  20. /** defgroup HAL_UART_data 硬件抽象层(HAL)串口模块(UART)数据结构
  21.   * {
  22.   */
  23.      
  24.                
  25. /**
  26. * enum hal_uart_txstate
  27. * UART 发送状态.
  28. */
  29. enum hal_uart_txstate
  30. {
  31.     HAL_UART_TXIDLE=0,      /**< UART 发送空闲 */
  32.     HAL_UART_TXBUSY=1,      /**< UART 正在发送 */
  33. };

  34. typedef enum  hal_uart_txstate HAL_UART_TXSTATE_e; /**< UART 发送状态枚举定义  */

  35.    
  36. /**
  37. * enum hal_uart_enable
  38. * UART 使能枚举定义.
  39. */
  40. enum hal_uart_enable
  41. {
  42.     HAL_UART_DISABLE=0,     /**< UART 不使能 */
  43.     HAL_UART_ENABLE=1,      /**< UART 使能 */
  44. };

  45. typedef enum  hal_uart_enable HAL_UART_ENABLE_e; /**< UART 使能枚举定义  */
  46.   

  47.                
  48. /**
  49. * enum hal_uart_type
  50. * UART 处理方式枚举定义.
  51. */
  52. enum hal_uart_type
  53. {
  54.     HAL_UART_INTERRUPT=0,     /**< UART 中断方式 */
  55.     HAL_UART_CHECK=1,         /**< UART 查询方式 */
  56. };

  57. typedef enum  hal_uart_type HAL_UART_TYPE_e; /**< UART 处理方式枚举定义  */

  58.      
  59.              
  60. /**
  61. * enum hal_uart_id
  62. * UART ID枚举定义.
  63. * note id从0开始连续递增,HAL预留足够多的id号n
  64. *       实际用到的id号由BSP硬件资源实现决定.
  65. */
  66. enum hal_uart_id
  67. {
  68.     HAL_UART_0=0,           /**< UART ID0 */
  69.     HAL_UART_1=1,           /**< UART ID1 */
  70.     HAL_UART_2=2,           /**< UART ID2 */
  71.     HAL_UART_3=3,           /**< UART ID3 */
  72.     HAL_UART_4=4,           /**< UART ID4 */
  73.     HAL_UART_5=5,           /**< UART ID5 */
  74.     HAL_UART_6=6,           /**< UART ID6 */
  75.     HAL_UART_7=7,           /**< UART ID7 */
  76.     HAL_UART_8=8,           /**< UART ID8 */
  77.     HAL_UART_9=8,           /**< UART ID9 */
  78.     HAL_UART_MAX=8,         /**< UART 个数 */
  79.     HAL_UART_INV=0xFF,      /**< 无效ID */
  80. };

  81. typedef enum  hal_uart_id HAL_UART_ID_e; /**< UART ID枚举定义  */
  82.    
  83.                
  84. /**
  85. * enum hal_uart_parity
  86. * UART数据奇偶校验枚举定义.
  87. * note HAL描述了所有标准校验方式,n
  88. *       实际用到的校验由BSP硬件资源实现决定.
  89. */
  90. enum hal_uart_parity
  91. {
  92.     HAL_UART_PARITY_NONE=0,       /**< UART无检验 */
  93.     HAL_UART_PARITY_EVEN=1,       /**< UART偶校验 */
  94.     HAL_UART_PARITY_ODD=2,        /**< UART奇校验 */
  95.     HAL_UART_PARITY_HIG=3,        /**< UART校验固定1  */
  96.     HAL_UART_PARITY_LOW=4,        /**< UART校验固定0  */
  97. };

  98. typedef enum  hal_uart_parity HAL_UART_PARITY_e; /**< UART数据奇偶校验枚举定义  */

  99.       
  100. /**
  101. * enum hal_uart_datalen
  102. * UART数据长度枚举定义.
  103. * note HAL描述了所有标准数据长度,n
  104. *       实际用到的数据长度由BSP硬件资源实现决定.
  105. */
  106. enum hal_uart_datalen
  107. {
  108.     HAL_UART_DATA_9=9,       /**< UART 9位数据 */
  109.     HAL_UART_DATA_8=8,       /**< UART 8位数据 */
  110.     HAL_UART_DATA_7=7,       /**< UART 7位数据 */
  111.     HAL_UART_DATA_6=6,       /**< UART 6位数据 */
  112.     HAL_UART_DATA_5=5,       /**< UART 5位数据 */
  113. };

  114. typedef enum  hal_uart_datalen HAL_UART_DATALEN_e; /**< UART数据长度枚举定义  */
  115.           

  116.              
  117. /**
  118. * enum hal_uart_stopb
  119. * UART停止位枚举定义.
  120. * note HAL描述了所有标准停止位长度,n
  121. *       实际用到的停止位长度由BSP硬件资源实现决定.
  122. */
  123. enum hal_uart_stopb
  124. {
  125.     HAL_UART_STOPB_1P5=0,       /**< UART 1.5位停止位 */
  126.     HAL_UART_STOPB_1=1,         /**< UART 1位停止位 */
  127.     HAL_UART_STOPB_2=2,         /**< UART 2位停止位 */
  128. };

  129. typedef enum  hal_uart_stopb HAL_UART_STOPB_e; /**< UART停止位枚举定义  */
  130.    
  131.              
  132. /**
  133. * enum hal_uart_baud
  134. * UART波特率枚举定义.
  135. * note HAL描述了常见波特率,n
  136. *       实际支持的波特率由BSP硬件资源实现决定.
  137. */
  138. enum hal_uart_baud
  139. {
  140.     HAL_UART_BAUD_600=600,        /**< UART波特率600 */
  141.     HAL_UART_BAUD_1200=1200,      /**< UART波特率1200 */
  142.     HAL_UART_BAUD_2400=2400,      /**< UART波特率2400 */
  143.     HAL_UART_BAUD_4800=4800,      /**< UART波特率4800 */
  144.     HAL_UART_BAUD_9600=9600,      /**< UART波特率9600 */
  145.     HAL_UART_BAUD_19200=19200,    /**< UART波特率19200 */
  146.     HAL_UART_BAUD_38400=38400,    /**< UART波特率38400 */
  147.     HAL_UART_BAUD_57600=57600,    /**< UART波特率38400 */
  148.     HAL_UART_BAUD_115200=115200,  /**< UART波特率115200 */
  149.     HAL_UART_BAUD_256000=256000,  /**< UART波特率256000 */
  150. };

  151. typedef enum  hal_uart_baud HAL_UART_BAUD_e; /**< UART波特率枚举定义  */
  152.   
  153. typedef struct hal_uart_cfg HAL_UART_CFG_t;  /**< UART配置结构体  */

  154. /**
  155. * struct hal_uart_cfg
  156. * UART配置结构体.
  157. */
  158. struct hal_uart_cfg
  159. {
  160.     HAL_UART_ID_e       id;         /**< UART id    */
  161.     HAL_UART_DATALEN_e  datalen;    /**< UART数据长度*/  
  162.     HAL_UART_PARITY_e   parity;     /**< UART校验    */
  163.     HAL_UART_STOPB_e    stopb;      /**< UART停止位  */
  164.     HAL_UART_BAUD_e     baud;       /**< UART波特率  */   
  165. };

  166.              
  167. /**
  168. * enum hal_uart_err
  169. * UART错误类型枚举定义.
  170. */
  171. enum hal_uart_err
  172. {
  173.     HAL_UART_ERR_NONE=0,           /**< UART无错误 */
  174.     HAL_UART_ERR_PER=1,            /**< UART校验错误 */
  175.     HAL_UART_ERR_FER=2,            /**< UART帧错误 */
  176.     HAL_UART_ERR_ORER=4,           /**< UART溢出错误 */
  177. };

  178. typedef enum  hal_uart_err HAL_UART_ERR_e; /**< UART错误类型枚举定义  */
  179.    

  180. /**
  181. * typedef HAL_UART_ISRCallBack
  182. * 中断服务回调函数.
  183. * - rxerrfun输入错误回调函数时,param指向错误码字节数据,不需要返回值.
  184. * - rxfun输入缓冲满回调函数时,param指向读到的字节数据,不需要返回值.
  185. * - txfun发送缓冲空回调函数,需要往param写需要发送的字节,返回值0表示还有数据需要发送 返回其他值标志本次为最后一字节数据.
  186. * - txcmpfun发送完回调函数,需要往param写需要发送的字节,返回值0表示还有数据需要发送 返回其他值标志本次为最后一字节数据.
  187. */
  188. typedef int (*HAL_UART_ISRCallBack)(unsigned char* param) ; /**< 中断服务回调函数        */   

  189. typedef struct hal_uart_isrcallback HAL_UART_ISRCALLBACK_t;  /**< 中断服务回调函数结构体  */

  190. /**
  191. * struct hal_uart_isrcallback
  192. * UART回调函数结构体.
  193. */
  194. struct hal_uart_isrcallback
  195. {
  196.     HAL_UART_ID_e        id;         /**< UART id             */
  197.     HAL_UART_ISRCallBack rxerrfun;   /**< 输入错误回调函数     */
  198.     HAL_UART_ISRCallBack rxfun;      /**< 输入缓冲满回调函数   */
  199.     HAL_UART_ISRCallBack txfun;      /**< 发送缓冲空回调函数   */
  200.     HAL_UART_ISRCallBack txcmpfun;   /**< 发送完回调函数       */
  201. };

  202. /**
  203.   * }
  204.   */
  205. /*****************************************************************************   
  206. *                                                                           
  207. *                             接口函数描述                                   
  208. *                                                                           
  209. ****************************************************************************/

  210. /** defgroup HAL_UART_if 硬件抽象层(HAL)串口模块(UART)接口
  211.   * {
  212.   */

  213. /**
  214. *****************************************************************************
  215. * fn          int HAL_UART_Init(HAL_UART_ID_e id)
  216. * brief       初始化UART模块,完成模块相关必要的初始化配置.
  217. * note        使用UART前必须调用,所有UART按默认配置(BSP实现).
  218. * param[in]   id UARTid,依赖于BSP实现,ref HAL_UART_ID_e.
  219. * retval      0 初始化成功.
  220. * retval      -1 初始化失败.
  221. *****************************************************************************
  222. */
  223. int HAL_UART_Init(HAL_UART_ID_e id);

  224. /**
  225. *****************************************************************************
  226. * fn          int HAL_UART_CheckSend(HAL_UART_ID_e id,unsigned char byte)
  227. * brief       查询的方式发送一个字节.
  228. * note        阻塞发送,直到发送完才会返回.  
  229. * param[in]   id UARTid,依赖于BSP实现,ref HAL_UART_ID_e.
  230. * param[in]   byte 需要发送的字节.
  231. * retval      0 发送成功.
  232. * retval      其他值 发送失败(实际上没有发送完会阻塞所以不会返回其他值).
  233. *****************************************************************************
  234. */
  235. int HAL_UART_CheckSend(HAL_UART_ID_e id,unsigned char byte);

  236. /**
  237. *****************************************************************************
  238. * fn          int HAL_UART_CheckRead(HAL_UART_ID_e id,unsigned char* byte);
  239. * brief       查询的方式读一个字节.
  240. * note        阻塞读,直到有数据才会返回.  
  241. * param[in]   id UARTid,依赖于BSP实现,ref HAL_UART_ID_e.
  242. * param[in]   byte 存储读到的字节.
  243. * retval      0 读成功.
  244. * retval      其他值 读失败(实际上读不到数据会阻塞所以不会返回其他值).
  245. *****************************************************************************
  246. */
  247. int HAL_UART_CheckRead(HAL_UART_ID_e id,unsigned char* byte);

  248. /**
  249. *****************************************************************************
  250. * fn          int HAL_UART_Send(HAL_UART_ID_e id,unsigned char byte)
  251. * brief       直接发送一个字节.
  252. * note        直接发送,直接往硬件发送缓冲写字节立即返回.  
  253. * param[in]   id UARTid,依赖于BSP实现,ref HAL_UART_ID_e.
  254. * param[in]   byte 需要发送的字节.
  255. * retval      0 发送成功.
  256. * retval      其他值 发送失败(实际上不会返回其他值).
  257. *****************************************************************************
  258. */
  259. int HAL_UART_Send(HAL_UART_ID_e id,unsigned char byte);

  260. /**
  261. *****************************************************************************
  262. * fn          int HAL_UART_Read(HAL_UART_ID_e id,unsigned char* byte);
  263. * brief       直接读一个字节.
  264. * note        直接读,直接读硬件缓冲立即返回.  
  265. * param[in]   id UARTid,依赖于BSP实现,ref HAL_UART_ID_e.
  266. * param[in]   byte 存储读到的字节.
  267. * retval      0 读成功.
  268. * retval      其他值 读失败(实际上不会返回其他值).
  269. *****************************************************************************
  270. */
  271. int HAL_UART_Read(HAL_UART_ID_e id,unsigned char* byte);

  272. /**
  273. *****************************************************************************
  274. * fn          int HAL_UART_SetTxISRCallBack(HAL_UART_ID_e id,HAL_UART_ISRCallBack callbackfun)
  275. * brief       设置发送缓冲区空中断服务回调函数.
  276. * note        .  
  277. * param[in]   id UARTid,依赖于BSP实现,ref HAL_UART_ID_e.
  278. * param[in]   callbackfun 回调函数.
  279. * retval      0 设置成功.
  280. * retval      其他值 设置失败.
  281. *****************************************************************************
  282. */
  283. int HAL_UART_SetTxISRCallBack(HAL_UART_ID_e id,HAL_UART_ISRCallBack callbackfun);

  284. /**
  285. *****************************************************************************
  286. * fn          int HAL_UART_SetTxCmpISRCallBack(HAL_UART_ID_e id,HAL_UART_ISRCallBack callbackfun)
  287. * brief       设置发送完中断服务回调函数.
  288. * note        .  
  289. * param[in]   id UARTid,依赖于BSP实现,ref HAL_UART_ID_e.
  290. * param[in]   callbackfun 回调函数.
  291. * retval      0 设置成功.
  292. * retval      其他值 设置失败.
  293. *****************************************************************************
  294. */
  295. int HAL_UART_SetTxCmpISRCallBack(HAL_UART_ID_e id,HAL_UART_ISRCallBack callbackfun);

  296. /**
  297. *****************************************************************************
  298. * fn          int HAL_UART_SetRxCallBack(HAL_UART_ID_e id,HAL_UART_ISRCallBack callbackfun)
  299. * brief       设置接收缓冲满中断服务回调函数.
  300. * note        .  
  301. * param[in]   id UARTid,依赖于BSP实现,ref HAL_UART_ID_e.
  302. * param[in]   callbackfun 回调函数.
  303. * retval      0 设置成功.
  304. * retval      其他值 设置失败.
  305. *****************************************************************************
  306. */
  307. int HAL_UART_SetRxCallBack(HAL_UART_ID_e id,HAL_UART_ISRCallBack callbackfun);

  308. /**
  309. *****************************************************************************
  310. * fn          int HAL_UART_SetRxErrCallBack(HAL_UART_ID_e id,HAL_UART_ISRCallBack callbackfun)
  311. * brief       设置接收错误中断服务回调函数.
  312. * note        .  
  313. * param[in]   id UARTid,依赖于BSP实现,ref HAL_UART_ID_e.
  314. * param[in]   callbackfun 回调函数.
  315. * retval      0 设置成功.
  316. * retval      其他值 设置失败.
  317. *****************************************************************************
  318. */
  319. int HAL_UART_SetRxErrCallBack(HAL_UART_ID_e id,HAL_UART_ISRCallBack callbackfun);

  320. /**
  321. *****************************************************************************
  322. * fn          int HAL_UART_SetCfg(HAL_UART_ID_e id,HAL_UART_CFG_t* cfg)
  323. * brief       配置UART参数.
  324. * note        .  
  325. * param[in]   id UARTid,依赖于BSP实现,ref HAL_UART_ID_e.
  326. * param[in]   cfg 指向配置参数结构体 ref HAL_UART_CFG_t.
  327. * retval      0 设置成功.
  328. * retval      其他值 设置失败.
  329. *****************************************************************************
  330. */
  331. int HAL_UART_SetCfg(HAL_UART_ID_e id,HAL_UART_CFG_t* cfg);

  332. /**
  333. *****************************************************************************
  334. * fn          int HAL_UART_EnableTx(HAL_UART_ID_e id,HAL_UART_TYPE_e type,HAL_UART_ENABLE_e enable)
  335. * brief       发送使能.
  336. * note        .  
  337. * param[in]   id UARTid,依赖于BSP实现,ref HAL_UART_ID_e.
  338. * param[in]   type 处理方式 ref HAL_UART_TYPE_e.
  339. * param[in]   enable 使能或者禁能 ref HAL_UART_ENABLE_e.
  340. * retval      0 设置成功.
  341. * retval      其他值 设置失败.
  342. *****************************************************************************
  343. */
  344. int HAL_UART_EnableTx(HAL_UART_ID_e id,HAL_UART_TYPE_e type,HAL_UART_ENABLE_e enable);

  345. /**
  346. *****************************************************************************
  347. * fn          int HAL_UART_EnableRx(HAL_UART_ID_e id,HAL_UART_TYPE_e type,HAL_UART_ENABLE_e enable)
  348. * brief       接收使能.
  349. * note        .  
  350. * param[in]   id UARTid,依赖于BSP实现,ref HAL_UART_ID_e.
  351. * param[in]   type 处理方式 ref HAL_UART_TYPE_e.
  352. * param[in]   enable 使能或者禁能 ref HAL_UART_ENABLE_e.
  353. * retval      0 设置成功.
  354. * retval      其他值 设置失败.
  355. *****************************************************************************
  356. */
  357. int HAL_UART_EnableRx(HAL_UART_ID_e id,HAL_UART_TYPE_e type,HAL_UART_ENABLE_e enable);

  358. /**
  359. *****************************************************************************
  360. * fn          int HAL_UART_EnableRxErr(HAL_UART_ID_e id,HAL_UART_TYPE_e type,HAL_UART_ENABLE_e enable)
  361. * brief       接收错误中断使能.
  362. * note        .  
  363. * param[in]   id UARTid,依赖于BSP实现,ref HAL_UART_ID_e.
  364. * param[in]   type 处理方式 ref HAL_UART_TYPE_e.
  365. * param[in]   enable 使能或者禁能 ref HAL_UART_ENABLE_e.
  366. * retval      0 设置成功.
  367. * retval      其他值 设置失败.
  368. *****************************************************************************
  369. */
  370. int HAL_UART_EnableRxErr(HAL_UART_ID_e id,HAL_UART_TYPE_e type,HAL_UART_ENABLE_e enable);

  371. /**
  372. *****************************************************************************
  373. * fn          int HAL_UART_DeInit(HAL_UART_ID_e id)
  374. * brief       解除UART模块,关闭模块.
  375. * note        .
  376. * param[in]   id UARTid,依赖于BSP实现,ref HAL_UART_ID_e.
  377. * retval      0 成功.
  378. * retval      -1 失败.
  379. *****************************************************************************
  380. */
  381. int HAL_UART_DeInit(HAL_UART_ID_e id);

  382. /**
  383.   * }
  384.   */

  385. /**
  386.   * }
  387.   */


  388. /**
  389.   * }
  390.   */

  391. /**
  392.   * }
  393.   */

  394. #ifdef __cplusplus
  395. }
  396. #endif

  397. #endif

driver_uart.c
  1. #define DRIVER_UART_GLOBALS /**< 包含driver_uart.h中的数据将会编译*/

  2. #include "driver_uart.h"
  3. #include "osapi.h"
  4.    
  5. /*****************************************************************************   
  6. *                                                                           
  7. *                             内部数据                                   
  8. *                                                                           
  9. ****************************************************************************/


  10. /*****************************************************************************   
  11. *                                                                           
  12. *                             内部接口函数实现                                   
  13. *                                                                           
  14. ****************************************************************************/

  15. /*485方向控制回调函数:
  16.   按照一般需求最多8路串口这里实现8路,如果有更多路需求再添加即可
  17. */
  18. #if UART0_ENABLE
  19. static void uart0_txhook(void)
  20. {
  21.        /*无效电平发送*/
  22. }

  23. static void uart0_rxhook(void)
  24. {
  25.       /*有效电平接收*/
  26. }
  27. #endif


  28. #if UART4_ENABLE
  29. static void uart4_txhook(void)
  30. {
  31.      /*无效电平发送*/
  32. }

  33. static void uart4_rxhook(void)
  34. {
  35.      /*有效电平接收 */
  36. }
  37. #endif

  38. #if UART9_ENABLE
  39. static void uart9_txhook(void)
  40. {
  41.       /*无效电平发送*/
  42. }

  43. static void uart9_rxhook(void)
  44. {
  45.       /*有效电平接收 */
  46. }
  47. #endif

  48. /**
  49. *****************************************************************************
  50. * fn          static int rx_fifo_in(driver_uart_t *p, unsigned char data)
  51. * brief       写数据到接收缓冲区.
  52. * note        接收中断服务函数调用该函数写数据到接收缓冲区,缓冲区满不写入.
  53. * param[in]   p 指向uart结构体实例的指针 ref driver_uart_t
  54. * param[in]   data 指向要写到缓冲区的数据
  55. *****************************************************************************
  56. */
  57. static int rx_fifo_in(driver_uart_t *p, unsigned char data)
  58. {
  59.     if(p==0)
  60.     {
  61.         return 0;
  62.     }
  63.     /*缓冲区未满写入数据*/
  64.     if (p->rx_len < (p->rxbuf_len/sizeof(p->rx_buf[0])))
  65.     {   
  66.         p->rx_buf[p->rx_in++] = data;                   /*写入数据,写入指针递增*/
  67.         p->rx_in %= p->rxbuf_len/sizeof(p->rx_buf[0]); /*边界处理,实现圆形缓冲区*/
  68.         p->rx_len++;                                    /*数据个数递增*/
  69.         return 0;
  70.     }
  71.     else
  72.     {
  73.         return -1;
  74.     }
  75. }


  76. /**
  77. *****************************************************************************
  78. * fn          static unsigned char rx_fifo_out(driver_uart_t *p, unsigned int timeout, unsigned char *perro)
  79. * brief       从接收缓冲区读数据.
  80. * note        应用函数调用该函数从接收缓冲区读数据,可以指定超时时间.
  81. * param[in]   p 指向uart结构体实例的指针 ref driver_uart_t
  82. * param[in]   timeout 指定超时时间 0表示一直等待
  83. * param[in]   perro 错误码0表示读到了数据 1表示没有读到数据
  84. * retval      unsigned char 读到的字节数据.
  85. *****************************************************************************
  86. */
  87. static unsigned char rx_fifo_out(driver_uart_t *p, unsigned int timeout, int *perro)
  88. {
  89.     unsigned char data = 0;
  90.     if(p==0)
  91.     {
  92.         *perro = 1;
  93.         return 0;
  94.     }
  95.     OSCriticalAlloc();
  96.     /*timeout==0 表示一直等待直到有数据*/
  97.     if (timeout == 0)
  98.     {
  99.         while(p->rx_len == 0)
  100.         {
  101.             OsTimeDelay(DRIVER_UART_DELAY_CHECK);  /*延时*/
  102.         }
  103.     }
  104.     else /*timeout!=0 表示等待指定超时时间*/
  105.     {
  106.         while (timeout != 0)
  107.         {
  108.             if (p->rx_len == 0)
  109.             {
  110.                 /*如果无数据,延时指定时间间隔*/
  111.                 if (timeout >= DRIVER_UART_DELAY_CHECK)
  112.                 {
  113.                     timeout -= DRIVER_UART_DELAY_CHECK;
  114.                     OsTimeDelay(DRIVER_UART_DELAY_CHECK);
  115.                 }
  116.                 else
  117.                 {
  118.                      /*不足一个时间间隔延时剩余时间*/
  119.                     OsTimeDelay(timeout);
  120.                     timeout = 0;
  121.                 }
  122.             }
  123.             else
  124.             {
  125.                 break;
  126.             }
  127.         }
  128.     }
  129.     /*临界段处理 防止此时中断在操作缓冲区*/
  130.     OSCriticalEnter();
  131.     if (p->rx_len != 0)
  132.     {
  133.         /*从缓冲区读出数据*/
  134.         p->rx_len--;
  135.         data = p->rx_buf[p->rx_out++];
  136.         p->rx_out %= p->rxbuf_len/sizeof(p->rx_buf[0]);
  137.         *perro = 0;
  138.     }
  139.     else
  140.     {
  141.         *perro = 1;
  142.     }
  143.     OSCriticalExit();
  144.     return data;
  145. }


  146. /**
  147. *****************************************************************************
  148. * fn          static int tx_fifo_in(driver_uart_t *p, unsigned int timeout, unsigned char data,unsigned char *perro)
  149. * brief       写数据到发送缓冲区.
  150. * note        应用调用该函数调写数据到发送缓冲区,缓冲区满等待.
  151. * param[in]   p 指向uart结构体实例的指针 ref driver_uart_t
  152. * param[in]   timeout 设定超时时间 0表示一直等待
  153. * param[in]   data 指向要写到缓冲区的数据
  154. * retval      0 写成功
  155. * retval      1 写失败
  156. *****************************************************************************
  157. */
  158. static int tx_fifo_in(driver_uart_t *p, unsigned char data, unsigned int timeout)
  159. {
  160.     /*注意确保p缓冲区的读写处于临界段保护 */
  161.     int ret=0;
  162.     if(p==0)
  163.     {
  164.         return 1;
  165.     }
  166.     OSCriticalAlloc();
  167.     if (timeout == 0)
  168.     {
  169.       
  170.         while(1)
  171.         {
  172.             OSCriticalEnter();
  173.             if(p->tx_len < (p->txbuf_len/sizeof(p->tx_buf[0])))
  174.             {
  175.                 /*没有满则写入数据*/
  176.                 p->tx_buf[p->tx_in++] = data;
  177.                 p->tx_in %= p->txbuf_len/sizeof(p->tx_buf[0]);
  178.                 p->tx_len++;
  179.                 OSCriticalExit();
  180.                 break;
  181.             }
  182.             else
  183.             {
  184.                 /*满则等待*/
  185.                 OSCriticalExit();
  186.                 OsTimeDelay(DRIVER_UART_DELAY_CHECK);  /*延时*/
  187.             }
  188.         }
  189.     }
  190.     while (timeout != 0)
  191.     {
  192.         OSCriticalEnter();
  193.         if (p->tx_len < (p->txbuf_len/sizeof(p->tx_buf[0])))
  194.         {   
  195.             /*没有满则写入数据*/
  196.             p->tx_buf[p->tx_in++] = data;
  197.             p->tx_in %= p->txbuf_len/sizeof(p->tx_buf[0]);
  198.             p->tx_len++;
  199.             OSCriticalExit();
  200.             ret = 0; /*设置正确返回值*/
  201.             break;
  202.         }
  203.         else
  204.         {
  205.             OSCriticalExit();
  206.             /*如果无数据,延时指定时间间隔*/
  207.             if (timeout >= DRIVER_UART_DELAY_CHECK)
  208.             {
  209.                 timeout -= DRIVER_UART_DELAY_CHECK;
  210.                 OsTimeDelay(DRIVER_UART_DELAY_CHECK);
  211.                 ret = 1; /*设置超时错误 之前这里没设置ret=1 在timeout为DRIVER_UART_DELAY_CHECK的整数倍时总是会返回0*/
  212.             }
  213.             else
  214.             {
  215.                 /*不足一个时间间隔延时剩余时间*/
  216.                 OsTimeDelay(timeout);
  217.                 timeout = 0;
  218.                 ret = 1; /*设置超时错误*/
  219.             }
  220.         }
  221.     }
  222.     return ret;
  223. }


  224. /**
  225. *****************************************************************************
  226. * fn          static unsigned char tx_fifo_out(driver_uart_t *p, unsigned char *perro)
  227. * brief       从发送缓冲区读数据.
  228. * note        发送中断服务函数调用该函数获取发送缓冲区数据,用于发送.
  229. * param[in]   p 指向uart结构体实例的指针 ref driver_uart_t
  230. * param[out]  perro 错误码 0表示读到数据 1表示没有数据
  231. * return      unsigned char perro=0时表示读到的数据  
  232. *****************************************************************************
  233. */
  234. static unsigned char tx_fifo_out(driver_uart_t *p, int *perro)
  235. {
  236.     unsigned char data = 0;
  237.     if(p==0)
  238.     {
  239.         *perro = 1;
  240.         return 0;
  241.     }
  242.     if (p->tx_len != 0)
  243.     {
  244.         if(p->tx_hook != 0)
  245.         {
  246.             (*(p->tx_hook))();
  247.         }
  248.         p->tx_len--;
  249.         data = p->tx_buf[p->tx_out++];
  250.         p->tx_out %= p->txbuf_len/sizeof(p->tx_buf[0]);
  251.         *perro = 0;
  252.     }
  253.     else
  254.     {
  255.         *perro = 1;
  256.     }
  257.     return data;
  258. }



  259. /**
  260. *****************************************************************************
  261. * fn          static int driver_uart0_send_isr(unsigned char *pdata)
  262. * brief       发送处理.
  263. * note        发送中断服务函数调用该函数,如果缓冲区空则停止发送并调用回调函数.
  264. * param[out]  pdata 回写需要发送的数据
  265. * retval      0 pdata指向的数据有效(需要发送) 1无后续发送数据
  266. *****************************************************************************
  267. */
  268. #if UART0_ENABLE
  269. static int driver_uart0_send_isr(unsigned char *pdata)
  270. {
  271.     int erro=0;
  272.     unsigned char data;
  273.     if(driver_uart_tab[0]==0)
  274.     {
  275.         return 1;
  276.     }
  277.     data = tx_fifo_out(driver_uart_tab[0], &erro);
  278.     if (erro != 0)
  279.     {  
  280.         /*没有获取到数据,停止发送*/
  281.         HAL_UART_EnableTx(driver_uart_tab[0]->id,HAL_UART_INTERRUPT,HAL_UART_DISABLE);
  282.         driver_uart_tab[0]->state = HAL_UART_TXIDLE;
  283.         if(driver_uart_tab[0]->rx_hook != 0)
  284.         {
  285.             driver_uart_tab[0]->rx_hook();
  286.         }   
  287.         return 1;
  288.     }
  289.     else
  290.     {
  291.         *pdata = data;
  292.         return 0;
  293.     }  
  294. }
  295. #endif


  296. /**
  297. *****************************************************************************
  298. * fn          static int driver_uart4_send_isr(unsigned char *pdata)
  299. * brief       发送处理.
  300. * note        发送中断服务函数调用该函数,如果缓冲区空则停止发送并调用回调函数.
  301. * param[out]  pdata 回写需要发送的数据
  302. * retval      0 pdata指向的数据有效(需要发送) 1无后续发送数据
  303. *****************************************************************************
  304. */
  305. #if UART4_ENABLE
  306. static int driver_uart4_send_isr(unsigned char *pdata)
  307. {
  308.     int erro=0;
  309.     unsigned char data;
  310.     if(driver_uart_tab[4]==0)
  311.     {
  312.         return 1;
  313.     }
  314.     data = tx_fifo_out(driver_uart_tab[4], &erro);
  315.     if (erro != 0)
  316.     {  
  317.         /*没有获取到数据,停止发送*/
  318.         HAL_UART_EnableTx(driver_uart_tab[4]->id,HAL_UART_INTERRUPT,HAL_UART_DISABLE);
  319.         driver_uart_tab[4]->state = HAL_UART_TXIDLE;
  320.         if(driver_uart_tab[4]->rx_hook != 0)
  321.         {
  322.             driver_uart_tab[4]->rx_hook();
  323.         }  
  324.         return 1;
  325.     }
  326.     else
  327.     {
  328.       *pdata = data;
  329.       return 0;
  330.     }  
  331. }
  332. #endif

  333. /**
  334. *****************************************************************************
  335. * fn          static int driver_uart9_send_isr(unsigned char *pdata)
  336. * brief       发送处理.
  337. * note        发送中断服务函数调用该函数,如果缓冲区空则停止发送并调用回调函数.
  338. * param[out]  pdata 回写需要发送的数据
  339. * retval      0 pdata指向的数据有效(需要发送) 1无后续发送数据
  340. *****************************************************************************
  341. */
  342. #if UART9_ENABLE
  343. static int driver_uart9_send_isr(unsigned char *pdata)
  344. {
  345.     int erro=0;
  346.     unsigned char data;
  347.     if(driver_uart_tab[9]==0)
  348.     {
  349.         return 1;
  350.     }
  351.     data = tx_fifo_out(driver_uart_tab[9], &erro);
  352.     if (erro != 0)
  353.     {  
  354.         /*没有获取到数据,停止发送*/
  355.         HAL_UART_EnableTx(driver_uart_tab[9]->id,HAL_UART_INTERRUPT,HAL_UART_DISABLE);
  356.         driver_uart_tab[9]->state = HAL_UART_TXIDLE;
  357.         if(driver_uart_tab[9]->rx_hook != 0)
  358.         {
  359.             driver_uart_tab[9]->rx_hook();
  360.         }   
  361.         return 1;
  362.     }
  363.     else
  364.     {
  365.         *pdata = data;
  366.         return 0;
  367.     }  
  368. }
  369. #endif


  370. /**
  371. *****************************************************************************
  372. * fn          static int driver_uart0_recv_isr(unsigned char* data)
  373. * brief       接收处理.
  374. * note        接收中断服务函数调用该函数,如果缓冲区满则丢弃新的数据.
  375. * param[out]  pdata 新的数据.
  376. * retval      总是返回0
  377. *****************************************************************************
  378. */
  379. #if UART0_ENABLE
  380. static int driver_uart0_recv_isr(unsigned char* data)
  381. {
  382.     if(driver_uart_tab[0]==0)
  383.     {
  384.         return 0;
  385.     }
  386.     driver_uart_tab[0]->rxhavedata =1;
  387.     return rx_fifo_in(driver_uart_tab[0], *data);
  388. }
  389. #endif


  390. /**
  391. *****************************************************************************
  392. * fn          static int driver_uart4_recv_isr(unsigned char* data)
  393. * brief       接收处理.
  394. * note        接收中断服务函数调用该函数,如果缓冲区满则丢弃新的数据.
  395. * param[out]  pdata 新的数据.
  396. * retval      总是返回0
  397. *****************************************************************************
  398. */
  399. #if UART4_ENABLE
  400. static int driver_uart4_recv_isr(unsigned char* data)
  401. {
  402.     if(driver_uart_tab[4]==0)
  403.     {
  404.         return 0;
  405.     }
  406.     driver_uart_tab[4]->rxhavedata =1;
  407.     return rx_fifo_in(driver_uart_tab[4], *data);
  408. }
  409. #endif

  410. /**
  411. *****************************************************************************
  412. * fn          static int driver_uart9_recv_isr(unsigned char* data)
  413. * brief       接收处理.
  414. * note        接收中断服务函数调用该函数,如果缓冲区满则丢弃新的数据.
  415. * param[out]  pdata 新的数据.
  416. * retval      总是返回0
  417. *****************************************************************************
  418. */
  419. #if UART9_ENABLE
  420. static int driver_uart9_recv_isr(unsigned char* data)
  421. {
  422.     if(driver_uart_tab[9]==0)
  423.     {
  424.         return 0;
  425.     }
  426.     driver_uart_tab[9]->rxhavedata =1;
  427.     return rx_fifo_in(driver_uart_tab[9], *data);
  428. }
  429. #endif



  430. /**
  431. *****************************************************************************
  432. * fn          static int driver_uart_rxerr_isr(HAL_UART_ID_e id,unsigned char *pdata)
  433. * brief       接收错误处理.
  434. * note        接收错误中断服务函数调用该函数.
  435. * param[in]   pdata 错误码
  436. * retval      0 总是返回0
  437. *****************************************************************************
  438. */
  439. static int driver_uart_rxerr_isr(HAL_UART_ID_e id,unsigned char *pdata)
  440. {
  441.     if(driver_uart_tab[id]==0)
  442.     {
  443.         return 0;
  444.     }
  445.     if(*pdata & HAL_UART_ERR_PER)
  446.     {
  447.         if((driver_uart_tab[id]->err & 0x000000FF) != 0x000000FF)
  448.         {
  449.             driver_uart_tab[id]->err = driver_uart_tab[id]->err + 1;
  450.         }
  451.         else
  452.         {
  453.             HAL_UART_EnableRxErr(id,HAL_UART_INTERRUPT,HAL_UART_DISABLE);
  454.             HAL_UART_EnableRx(id,HAL_UART_INTERRUPT,HAL_UART_DISABLE);
  455.         }
  456.     }
  457.     if(*pdata & HAL_UART_ERR_FER)
  458.     {
  459.         if((driver_uart_tab[id]->err & 0x0000FF00) != 0x0000FF00)
  460.         {
  461.             driver_uart_tab[id]->err = driver_uart_tab[id]->err + 0x100;
  462.         }
  463.         else
  464.         {
  465.             HAL_UART_EnableRxErr(id,HAL_UART_INTERRUPT,HAL_UART_DISABLE);
  466.             HAL_UART_EnableRx(id,HAL_UART_INTERRUPT,HAL_UART_DISABLE);
  467.         }
  468.     }
  469.     if(*pdata & HAL_UART_ERR_ORER)
  470.     {
  471.         if((driver_uart_tab[id]->err & 0x00FF0000) != 0x00FF0000)
  472.         {
  473.             driver_uart_tab[id]->err = driver_uart_tab[id]->err + 0x10000;
  474.         }
  475.         else
  476.         {
  477.             HAL_UART_EnableRxErr(id,HAL_UART_INTERRUPT,HAL_UART_DISABLE);
  478.             HAL_UART_EnableRx(id,HAL_UART_INTERRUPT,HAL_UART_DISABLE);
  479.         }
  480.     }
  481.     return 0;
  482. }

  483. /**
  484. *****************************************************************************
  485. * fn          static int driver_uart0_rxerr_isr(unsigned char *pdata)
  486. * brief       接收错误处理.
  487. * note        接收错误中断服务函数调用该函数.
  488. * param[in]   pdata 错误码
  489. * retval      0 总是返回0
  490. *****************************************************************************
  491. */
  492. #if UART0_ENABLE
  493. static int driver_uart0_rxerr_isr(unsigned char *pdata)
  494. {
  495.     return driver_uart_rxerr_isr(HAL_UART_0,pdata);
  496. }
  497. #endif

  498. /**
  499. *****************************************************************************
  500. * fn          static int driver_uart4_rxerr_isr(unsigned char *pdata)
  501. * brief       接收错误处理.
  502. * note        接收错误中断服务函数调用该函数.
  503. * param[in]   pdata 错误码
  504. * retval      0 总是返回0
  505. *****************************************************************************
  506. */
  507. #if UART4_ENABLE
  508. static int driver_uart4_rxerr_isr(unsigned char *pdata)
  509. {
  510.     return driver_uart_rxerr_isr(HAL_UART_4,pdata);
  511. }
  512. #endif

  513. /**
  514. *****************************************************************************
  515. * fn          static int driver_uart9_rxerr_isr(unsigned char *pdata)
  516. * brief       接收错误处理.
  517. * note        接收错误中断服务函数调用该函数.
  518. * param[in]   pdata 错误码
  519. * retval      0 总是返回0
  520. *****************************************************************************
  521. */
  522. #if UART9_ENABLE
  523. static int driver_uart9_rxerr_isr(unsigned char *pdata)
  524. {
  525.     return driver_uart_rxerr_isr(HAL_UART_9,pdata);
  526. }
  527. #endif


  528. /*****************************************************************************   
  529. *                                                                           
  530. *                             对外接口函数实现                                   
  531. *                                                                           
  532. ****************************************************************************/

  533. /**
  534. *****************************************************************************
  535. * fn          static int driver_uart_init(HAL_UART_ID_e id)
  536. * brief       初始化串口.
  537. * note        .
  538. * param[in]   id 串口id ref HAL_UART_ID_e
  539. * retval      0 设置成功
  540. * retval      -1参数错误
  541. *****************************************************************************
  542. */
  543. static int driver_uart_init(HAL_UART_ID_e id)
  544. {       
  545.     /*初始化端口和默认参数*/
  546.     HAL_UART_Init(id);
  547.     /*设置回调函数*/
  548.     switch(id)
  549.     {
  550. #if UART0_ENABLE
  551.     case HAL_UART_0:
  552.         HAL_UART_SetTxCmpISRCallBack(HAL_UART_0,driver_uart0_send_isr);
  553.         HAL_UART_SetRxCallBack(HAL_UART_0,driver_uart0_recv_isr);
  554.         HAL_UART_SetRxErrCallBack(HAL_UART_0,driver_uart0_rxerr_isr);
  555.         break;
  556. #endif
  557. #if UART4_ENABLE
  558.     case HAL_UART_4:
  559.         HAL_UART_SetTxCmpISRCallBack(HAL_UART_4,driver_uart4_send_isr);
  560.         HAL_UART_SetRxCallBack(HAL_UART_4,driver_uart4_recv_isr);
  561.         HAL_UART_SetRxErrCallBack(HAL_UART_4,driver_uart4_rxerr_isr);
  562.         break;
  563. #endif
  564. #if UART9_ENABLE
  565.     case HAL_UART_9:
  566.         HAL_UART_SetTxCmpISRCallBack(HAL_UART_9,driver_uart9_send_isr);
  567.         HAL_UART_SetRxCallBack(HAL_UART_9,driver_uart9_recv_isr);
  568.         HAL_UART_SetRxErrCallBack(HAL_UART_9,driver_uart9_rxerr_isr);
  569.         break;
  570. #endif
  571.     default:
  572.         return -1;
  573.         break;
  574.     }
  575.     return 0;
  576. }

  577. /**
  578. *****************************************************************************
  579. * fn          unsigned int driver_uart_getrxlen(HAL_UART_ID_e id)
  580. * brief       获取接收缓冲区有效数据长度.
  581. * note        .
  582. * param[in]   id 串口id ref HAL_UART_ID_e
  583. * return      unsigned int 接收缓冲区长度
  584. *****************************************************************************
  585. */
  586. unsigned int driver_uart_getrxlen(HAL_UART_ID_e id)
  587. {
  588.     if(driver_uart_tab[id]==0)
  589.     {
  590.         return 0;
  591.     }
  592.     return driver_uart_tab[id]->rx_len;
  593. }


  594. /**
  595. *****************************************************************************
  596. * fn          unsigned int driver_uart_flush(HAL_UART_ID_e id)
  597. * brief       清除缓冲区.
  598. * note        .
  599. * param[in]   id 串口id ref HAL_UART_ID_e
  600. * return      int 总是返回0
  601. *****************************************************************************
  602. */
  603. unsigned int driver_uart_flush(HAL_UART_ID_e id)
  604. {
  605.     if(driver_uart_tab[id]!=0)
  606.     {
  607.         driver_uart_tab[id]->rx_in  = 0;
  608.         driver_uart_tab[id]->rx_out = 0;
  609.         driver_uart_tab[id]->rx_len = 0;
  610.         driver_uart_tab[id]->tx_in  = 0;
  611.         driver_uart_tab[id]->tx_out = 0;
  612.         driver_uart_tab[id]->tx_len = 0;
  613.         driver_uart_tab[id]->err = 0x00;
  614.     }
  615.     return 0;
  616. }

  617. /**
  618. *****************************************************************************
  619. * fn          int driver_uart_set(HAL_UART_CFG_t* cfg)
  620. * brief       配置串口参数.
  621. * note        .
  622. * param[in]   cfg 配置参数
  623. * return      int ref HAL_UART_SetCfg 的返回值
  624. *****************************************************************************
  625. */
  626. int driver_uart_set(HAL_UART_CFG_t* cfg)
  627. {
  628.     int ret;
  629.     if(driver_uart_tab[cfg->id]==0)
  630.     {
  631.         return 0;
  632.     }
  633.     driver_uart_init(cfg->id);
  634.     ret = HAL_UART_SetCfg(cfg->id,cfg);
  635.     HAL_UART_EnableRx(cfg->id,HAL_UART_INTERRUPT,HAL_UART_ENABLE);
  636.     driver_uart_flush(cfg->id);
  637.     return ret;
  638. }

  639. /**
  640. *****************************************************************************
  641. * fn          unsigned int driver_uart_recv(HAL_UART_ID_e id, unsigned char *pdata, unsigned int len, unsigned int timeout, int *perro)
  642. * brief       串口接收指定长度数据,可以设置超时时间.
  643. * note        应用调用该函数接收数据,如果缓冲区无数据就等待.
  644. * param[in]   id 指定的串口id.
  645. * param[in]   pdata 需存储接收数据的缓冲区.
  646. * param[in]   len   接收的数据长度.
  647. * param[in]   timeout 设置为0表示一直等到接收到指定长度数据,设置为其他值表示等待指定超时时间(单位mS)
  648. * param[out]  perro 错误码 0表示成功 -1表示参数错误 1表示超时
  649. * return      int 返回实际读到的数据长度
  650. *****************************************************************************
  651. */
  652. unsigned int driver_uart_recv(HAL_UART_ID_e id, unsigned char *pdata, unsigned int len, unsigned int timeout, int *erro)
  653. {
  654.     unsigned char data=0;
  655.     unsigned int readlen=0;
  656.     unsigned int tmptimeout=0;
  657.     if (id >= HAL_UART_MAX)
  658.     {
  659.         *erro = -1;
  660.         return 0;
  661.     }
  662.     if(driver_uart_tab[id]==0)
  663.     {
  664.         *erro = -1;
  665.         return 0;
  666.     }
  667.     if(len ==0)
  668.     {
  669.         *erro = -1;
  670.         return 0;
  671.     }
  672.     tmptimeout = timeout;
  673.     while(len !=0)
  674.     {
  675.         data = rx_fifo_out(driver_uart_tab[id], tmptimeout, erro);
  676.         if (*erro == 0)
  677.         {      
  678.             tmptimeout = DRIVER_UART_DELAY_FRAME;
  679.             *pdata++ = data;   
  680.             len--;
  681.             readlen++;
  682.         }
  683.         else
  684.         {
  685.             *erro = 1;
  686.             break;
  687.         }
  688.     }
  689.     return readlen;
  690. }

  691. /**
  692. *****************************************************************************
  693. * fn          int driver_uart_send(HAL_UART_ID_e id, unsigned char *pdata, unsigned int len,unsigned int timeout,int *perro)
  694. * brief       串口发送指定长度数据,可以设置超时时间.
  695. * note        应用调用该函数发送数据,如果缓冲区满就等待.
  696. * param[in]   id 指定的串口id.
  697. * param[in]   pdata 需要发送的数据缓冲区.
  698. * param[in]   len   需要发送的数据长度.
  699. * param[in]   timeout 设置为0表示一直等到全部写入缓冲区,设置为其他值表示等待指定超时时间(单位mS)
  700. * param[out]  perro 错误码 0表示成功 -1表示参数错误 1表示超时
  701. * return      int 返回实际发送的数据
  702. *****************************************************************************
  703. */
  704. int driver_uart_send(HAL_UART_ID_e id, unsigned char *pdata, unsigned int len,unsigned int timeout,int *erro)
  705. {
  706.     unsigned char full=0;
  707.     driver_uart_t *p=0;
  708.     unsigned char data=0;
  709.     unsigned int sendlen=0;
  710.     OSCriticalAlloc();
  711.     if (id >= HAL_UART_MAX)
  712.     {
  713.         *erro = -1;
  714.         return 0;
  715.     }
  716.     if(driver_uart_tab[id]==0)
  717.     {
  718.         *erro = -1;
  719.         return 0;
  720.     }
  721.     if(len ==0)
  722.     {
  723.          *erro = -1;
  724.         return 0;
  725.     }
  726.     p = (driver_uart_t *)driver_uart_tab[id];
  727.     if(p->tx_hook !=0)
  728.     {
  729.         p->tx_hook();   /*调用准备发送回调函数*/
  730.     }
  731.     driver_uart_tab[id]->txhavedata =1;
  732.     if(timeout == 0)
  733.     {
  734.         while(len !=0)
  735.         {
  736.             full = tx_fifo_in(p,*pdata,DRIVER_UART_DELAY_CHECK);
  737.             if (full == 0)
  738.             {
  739.                 pdata++;
  740.                 len--;
  741.                 sendlen++;
  742.             }
  743.             else
  744.             {
  745.                 OSCriticalEnter();
  746.                 /*如果缓冲区满而且当前串口没有处于发送状态要先发送一个字节触发发送中断流*/
  747.                 if(p->state == HAL_UART_TXIDLE)
  748.                 {
  749.                     data = tx_fifo_out(p, erro);
  750.                     if(*erro == 0)
  751.                     {
  752.                         if(p->tx_hook !=0)
  753.                         {
  754.                             p->tx_hook();   /*调用准备发送回调函数*/
  755.                         }
  756.                         p->state = HAL_UART_TXBUSY; /*注意:p->state的读写需要临界保护*/
  757.                         HAL_UART_Send(p->id,data);  /*注意:必须放在使能TX前,写TDR会清除TEND标志,否则使能TE会马上产生发送完中断*/
  758.                         HAL_UART_EnableTx(id,HAL_UART_INTERRUPT,HAL_UART_ENABLE);      
  759.                     }
  760.                 }
  761.                 OSCriticalExit();
  762.                 OsTimeDelay(DRIVER_UART_DELAY_CHECK);
  763.             }
  764.         }
  765.         *erro = 0;
  766.     }
  767.     else
  768.     {
  769.         while ((len != 0) && (timeout!=0))
  770.         {
  771.             full = tx_fifo_in(p,*pdata,DRIVER_UART_DELAY_CHECK);
  772.             if (full == 0)
  773.             {
  774.                 pdata++;
  775.                 len--;
  776.                 sendlen++;
  777.             }
  778.             else
  779.             {
  780.                 OSCriticalEnter();
  781.                 /*如果缓冲区满而且当前串口没有处于发送状态要先发送一个字节触发发送中断流*/
  782.                 if(p->state == HAL_UART_TXIDLE)
  783.                 {
  784.                     data = tx_fifo_out(p, erro);
  785.                     if(*erro == 0)
  786.                     {
  787.                         if(p->tx_hook !=0)
  788.                         {
  789.                             p->tx_hook();   /*调用准备发送回调函数*/
  790.                         }
  791.                         p->state = HAL_UART_TXBUSY; /*注意:p->state的读写需要临界保护*/
  792.                         HAL_UART_Send(p->id,data);  /*注意:必须放在使能TX前,写TDR会清除TEND标志,否则使能TE会马上产生发送完中断*/
  793.                         HAL_UART_EnableTx(id,HAL_UART_INTERRUPT,HAL_UART_ENABLE);      
  794.                     }
  795.                     OSCriticalExit();
  796.                 }
  797.                 else /*如果当前处于发送状态*/
  798.                 {
  799.                     OSCriticalExit();
  800.                     /*如果缓冲区满而且串口处于发送状态则延时指定时间间隔等待中断发送完*/
  801.                     if (timeout >= DRIVER_UART_DELAY_CHECK)
  802.                     {
  803.                         timeout -= DRIVER_UART_DELAY_CHECK;
  804.                         OsTimeDelay(DRIVER_UART_DELAY_CHECK);
  805.                     }
  806.                     else
  807.                     {
  808.                         /*不足一个时间间隔延时剩余时间*/
  809.                         OsTimeDelay(timeout);
  810.                         timeout = 0;
  811.                     }
  812.                 }
  813.             }
  814.         }
  815.         /*如果没发送完设置超时错误码*/
  816.         if(len != 0)
  817.         {
  818.             *erro = 1;
  819.         }
  820.     }
  821.    

  822.     OSCriticalEnter();
  823.     /*如果缓冲区有数据而且当前串口没有处于发送状态要先发送一个字节触发发送中断流*/
  824.     if((p->state == HAL_UART_TXIDLE) && (p->tx_len!=0))
  825.     {
  826.         data = tx_fifo_out(p, erro);
  827.         if(*erro == 0)
  828.         {
  829.             if(p->tx_hook !=0)
  830.             {
  831.                 p->tx_hook();   /*调用准备发送回调函数*/
  832.             }
  833.             p->state = HAL_UART_TXBUSY; /*注意:p->state的读写需要临界保护*/
  834. #ifdef FM33A
  835.             HAL_UART_EnableTx(id,HAL_UART_INTERRUPT,HAL_UART_ENABLE);
  836.             HAL_UART_Send(p->id,data);   /*注意:必须放在使能TX后,否则使能TE会马上清除刚写如的数据,不产生中断 这里与k20等芯片不同*/
  837. #else
  838.             HAL_UART_Send(p->id,data);  /*注意:必须放在使能TX前,写TDR会清除TEND标志,否则使能TE会马上产生发送完中断*/
  839.             HAL_UART_EnableTx(id,HAL_UART_INTERRUPT,HAL_UART_ENABLE);      
  840. #endif
  841.         }
  842.     }
  843.     OSCriticalExit();
  844.     return sendlen;
  845. }

  846. /**
  847. *****************************************************************************
  848. * fn          int driver_uart_haverxdata(HAL_UART_ID_e id)
  849. * brief       读串口是否曾经接收到过数据.
  850. * note        应用调用该函数用于判断是否点亮接收指示灯.读会清除状态.
  851. * param[in]   id 指定的串口id.
  852. * retval      1 串口曾经有接收数据
  853. * retval      0 串口没有接收数据
  854. *****************************************************************************
  855. */
  856. int driver_uart_haverxdata(HAL_UART_ID_e id)
  857. {
  858.     unsigned char havedata=0;
  859.     if(driver_uart_tab[id]==0)
  860.     {
  861.         return 0;
  862.     }
  863.     havedata = driver_uart_tab[id]->rxhavedata;
  864.     driver_uart_tab[id]->rxhavedata =0;
  865.     return havedata;
  866. }

  867. /**
  868. *****************************************************************************
  869. * fn          int driver_uart_havetxdata(HAL_UART_ID_e id)
  870. * brief       读串口是否曾经发送过数据.
  871. * note        应用调用该函数用于判断是否点亮发送指示灯.读会清除状态.
  872. * param[in]   id 指定的串口id.
  873. * retval      1 串口曾经有发送数据
  874. * retval      0 串口没有发送数据
  875. *****************************************************************************
  876. */
  877. int driver_uart_havetxdata(HAL_UART_ID_e id)
  878. {
  879.     unsigned char havedata=0;
  880.     if(driver_uart_tab[id]==0)
  881.     {
  882.         return 0;
  883.     }
  884.     havedata = driver_uart_tab[id]->txhavedata;
  885.     driver_uart_tab[id]->txhavedata =0;
  886.     return havedata;
  887. }

  888. /**
  889. *****************************************************************************
  890. * fn          int driver_uart_geterr(HAL_UART_ID_e id,unsigned int* err)
  891. * brief       读串口错误状态字.
  892. * note        应用调用该函数用于判断串口是否异常,如果err的低三个字节有任意个字节为FF则表示异常需要处理.
  893. * param[in]   id 指定的串口id ref HAL_UART_ID_e .
  894. * param[out]  err 存储错误字
  895.                 0xxxxxxxFF表示校验错误  
  896.                 0xxxxxFFxx表示帧错误   
  897.                 0xxxFF00xx表示溢出错误  
  898. * retval      0 总是返回0
  899. *****************************************************************************
  900. */
  901. int driver_uart_geterr(HAL_UART_ID_e id,unsigned int* err)
  902. {
  903.     if(driver_uart_tab[id]==0)
  904.     {
  905.         return 0;
  906.     }
  907.     *err = driver_uart_tab[id]->err;
  908.     return 0;
  909. }

driver_uart.h
  1. #ifndef __DRIVER_UART_H
  2. #define __DRIVER_UART_H

  3. #ifdef __cplusplus
  4. extern "C" {
  5. #endif

  6. #include "hal_uart.h"
  7. /** addtogroup DRIVER 驱动层(DRIVER)
  8. *  {
  9. */
  10.          
  11. /** addtogroup DRIVER_UART 驱动层(DRIVER)串口模块(UART)
  12. *  {
  13. */
  14. /*****************************************************************************   
  15. *                                                                           *
  16. *                             数据结构描述                                  *
  17. *                                                                          *
  18. ****************************************************************************/
  19. /** defgroup DRIVER_UART_data 驱动层(DRIVER)串口模块(UART)数据结构
  20.   * {
  21.   */
  22.   
  23. #define UART0_ENABLE          1  /**< 通道0 使能 */
  24. #define UART4_ENABLE          1  /**< 通道4 使能 */
  25. #define UART9_ENABLE          1  /**< 通道9 使能 */

  26. #define DRIVER_UART0_TXBUF_SIZE 64       /**< UART0发送缓冲区大小  */   
  27. #define DRIVER_UART0_RXBUF_SIZE 128       /**< UART0接收缓冲区大小  */
  28. #define DRIVER_UART4_TXBUF_SIZE 64       /**< UART4发送缓冲区大小  */   
  29. #define DRIVER_UART4_RXBUF_SIZE 128       /**< UART4接收缓冲区大小  */
  30. #define DRIVER_UART9_TXBUF_SIZE 64       /**< UART9发送缓冲区大小  */   
  31. #define DRIVER_UART9_RXBUF_SIZE 128       /**< UART9接收缓冲区大小  */

  32. #define DRIVER_UART_DELAY_FIFO    (5)    /**< 缓冲区操作延时时间       */   
  33. #define DRIVER_UART_DELAY_CHECK   (1)      /**< 缓冲区延时查询时间间隔   */
  34. #define DRIVER_UART_DELAY_FRAME   (5)    /**< 字节间距大于该值认为帧结束   */
  35.          
  36. typedef void (*driver_uart_hook)(void);      /**< 发送/接收回调函数   */   

  37. /**
  38. * struct driver_uart_t
  39. * UART驱动配置结构体.
  40. */
  41. typedef struct
  42. {
  43.     HAL_UART_ID_e id;                 /**< UART id   */   
  44.     unsigned int rx_in;              /**< 接收缓冲区写入指针       */
  45.     unsigned int rx_out;             /**< 接收缓冲区读出指针       */
  46.     unsigned int rx_len;             /**< 接收缓冲区有效数据大小   */
  47.     unsigned int tx_in;              /**< 发送缓冲区写入指针       */
  48.     unsigned int tx_out;             /**< 发送缓冲区读出指针      */
  49.     unsigned int tx_len;             /**< 发送缓冲区有效数据大小   */
  50.     unsigned short rxbuf_len;        /**< 接收缓冲区大小           */   
  51.     unsigned short txbuf_len;        /**< 发送缓冲区大小          */
  52.     driver_uart_hook tx_hook;         /**< 准备发送回调函数          */
  53.     driver_uart_hook rx_hook;         /**< 发送完转接收回调函数          */
  54.     unsigned char *rx_buf;           /**< 接收缓冲区              */
  55.     unsigned char *tx_buf;           /**< 发送缓冲区                */
  56.     unsigned int bit_len;            /**< 用于发送完延时(有发送完中断不需要)    */
  57.     HAL_UART_TXSTATE_e state;         /**< 发送状态标志是否在发送                */
  58.     unsigned char rxhavedata;        /**< 是否有接收到数据                */
  59.     unsigned char txhavedata;        /**< 是否有发送数据                */
  60.     unsigned int err;                /**< 错误码计数器               */
  61. }driver_uart_t;


  62. /*****************************************************************************   
  63. *                                                                           *
  64. *                             模块数据定义                                  *
  65. *                                                                          *
  66. ****************************************************************************/

  67. #ifdef   DRIVER_UART_GLOBALS

  68. /*485方向控制回调函数:
  69.   按照一般需求最多8路串口这里实现8路,如果有更多路需求再添加即可
  70. */
  71. static void uart9_txhook(void);
  72. static void uart9_rxhook(void);
  73. static void uart4_txhook(void);
  74. static void uart4_rxhook(void);
  75. static void uart0_txhook(void);
  76. static void uart0_rxhook(void);

  77. static unsigned char driver_uart0_rxbuf[DRIVER_UART0_RXBUF_SIZE];
  78. static unsigned char driver_uart0_txbuf[DRIVER_UART0_TXBUF_SIZE];
  79. static unsigned char driver_uart4_rxbuf[DRIVER_UART4_RXBUF_SIZE];
  80. static unsigned char driver_uart4_txbuf[DRIVER_UART4_TXBUF_SIZE];
  81. static unsigned char driver_uart9_rxbuf[DRIVER_UART4_RXBUF_SIZE];
  82. static unsigned char driver_uart9_txbuf[DRIVER_UART4_TXBUF_SIZE];

  83. static driver_uart_t driver_uart0 = {HAL_UART_0, 0,0,0, 0,0,0, sizeof(driver_uart0_rxbuf), sizeof(driver_uart0_txbuf),uart0_txhook,uart0_rxhook,driver_uart0_rxbuf, driver_uart0_txbuf, 0,HAL_UART_TXIDLE,0,0};
  84. static driver_uart_t driver_uart4 = {HAL_UART_0, 0,0,0, 0,0,0, sizeof(driver_uart4_rxbuf), sizeof(driver_uart4_txbuf),uart4_txhook,uart4_rxhook,driver_uart4_rxbuf, driver_uart4_txbuf, 0,HAL_UART_TXIDLE,0,0};
  85. static driver_uart_t driver_uart9 = {HAL_UART_0, 0,0,0, 0,0,0, sizeof(driver_uart9_rxbuf), sizeof(driver_uart9_txbuf),uart9_txhook,uart9_rxhook,driver_uart9_rxbuf, driver_uart9_txbuf, 0,HAL_UART_TXIDLE,0,0};


  86. static driver_uart_t *driver_uart_tab[] = {&driver_uart0, 0, 0, 0, &driver_uart4, 0, 0, 0, 0, &driver_uart9};


  87. #endif

  88. /**
  89.   * }
  90.   */
  91. /*****************************************************************************   
  92. *                                                                           
  93. *                             接口函数描述                                   
  94. *                                                                           
  95. ****************************************************************************/

  96. /** defgroup DRIVER_UART_if 驱动层(DRIVER)串口模块(UART)接口
  97.   * {
  98.   */
  99.       
  100. /**
  101. *****************************************************************************
  102. * fn          unsigned int driver_uart_getrxlen(HAL_UART_ID_e id)
  103. * brief       获取接收缓冲区有效数据长度.
  104. * note        .
  105. * param[in]   id 串口id ref HAL_UART_ID_e
  106. * return      unsigned int 接收缓冲区长度
  107. *****************************************************************************
  108. */
  109. unsigned int driver_uart_getrxlen(HAL_UART_ID_e id);

  110. /**
  111. *****************************************************************************
  112. * fn          unsigned int driver_uart_flush(HAL_UART_ID_e id)
  113. * brief       清除缓冲区.
  114. * note        .
  115. * param[in]   id 串口id ref HAL_UART_ID_e
  116. * return      int 总是返回0
  117. *****************************************************************************
  118. */
  119. unsigned int driver_uart_flush(HAL_UART_ID_e id);

  120. /**
  121. *****************************************************************************
  122. * fn          int driver_uart_set(HAL_UART_CFG_t* cfg)
  123. * brief       配置串口参数.
  124. * note        .
  125. * param[in]   cfg 配置参数
  126. * return      int ref HAL_HWT_SetCfg() 的返回值
  127. *****************************************************************************
  128. */
  129. int driver_uart_set(HAL_UART_CFG_t* cfg);

  130. /**
  131. *****************************************************************************
  132. * fn          int driver_uart_recv(HAL_UART_ID_e id, unsigned char *pdata, unsigned int len, unsigned int timeout, int *perro)
  133. * brief       串口接收指定长度数据,可以设置超时时间.
  134. * note        应用调用该函数接收数据,如果缓冲区无数据就等待.
  135. * param[in]   id 指定的串口id.
  136. * param[in]   pdata 需存储接收数据的缓冲区.
  137. * param[in]   len   接收的数据长度.
  138. * param[in]   timeout 设置为0表示一直等到接收到指定长度数据,设置为其他值表示等待指定超时时间(单位mS)
  139. * param[out]  perro 错误码 0表示成功 -1表示参数错误 1表示超时
  140. * return      int 返回实际读到的数据长度
  141. *****************************************************************************
  142. */
  143. unsigned int driver_uart_recv(HAL_UART_ID_e id, unsigned char *pdata, unsigned int len, unsigned int timeout, int *erro);

  144. /**
  145. *****************************************************************************
  146. * fn          int driver_uart_send(HAL_UART_ID_e id, unsigned char *pdata, unsigned int len,unsigned int timeout,int *perro)
  147. * brief       串口发送指定长度数据,可以设置超时时间.
  148. * note        应用调用该函数发送数据,如果缓冲区满就等待.
  149. * param[in]   id 指定的串口id.
  150. * param[in]   pdata 需要发送的数据缓冲区.
  151. * param[in]   len   需要发送的数据长度.
  152. * param[in]   timeout 设置为0表示一直等到全部写入缓冲区,设置为其他值表示等待指定超时时间(单位mS)
  153. * param[out]  perro 错误码 0表示成功 -1表示参数错误 1表示超时
  154. * return      int 返回实际发送的数据
  155. *****************************************************************************
  156. */
  157. int driver_uart_send(HAL_UART_ID_e id, unsigned char *pdata, unsigned int len,unsigned int timeout,int *erro);

  158. /**
  159. *****************************************************************************
  160. * fn          int driver_uart_haverxdata(HAL_UART_ID_e id)
  161. * brief       读串口是否曾经接收到过数据.
  162. * note        应用周期调用该函数用于判断是否点亮接收指示灯.读会清除状态.
  163. * param[in]   id 指定的串口id.
  164. * retval      1 串口曾经有接收数据
  165. * retval      0 串口没有接收数据
  166. *****************************************************************************
  167. */
  168. int driver_uart_haverxdata(HAL_UART_ID_e id);

  169. /**
  170. *****************************************************************************
  171. * fn          int driver_uart_havetxdata(HAL_UART_ID_e id)
  172. * brief       读串口是否曾经发送过数据.
  173. * note        应用周期调用该函数用于判断是否点亮发送指示灯.读会清除状态.
  174. * param[in]   id 指定的串口id.
  175. * retval      1 串口曾经有发送数据
  176. * retval      0 串口没有发送数据
  177. *****************************************************************************
  178. */
  179. int driver_uart_havetxdata(HAL_UART_ID_e id);

  180. /**
  181. *****************************************************************************
  182. * fn          int driver_uart_geterr(HAL_UART_ID_e id,unsigned int* err)
  183. * brief       读串口错误状态字.
  184. * note        应用调用该函数用于判断串口是否异常,如果err的低三个字节有任意个字节为FF则表示异常需要处理.
  185. * param[in]   id 指定的串口id ref HAL_UART_ID_e .
  186. * param[out]  err 存储错误字
  187.                 0xxxxxxxFF表示校验错误  
  188.                 0xxxxxFFxx表示帧错误   
  189.                 0xxxFF00xx表示溢出错误  
  190. * retval      0 总是返回0
  191. *****************************************************************************
  192. */
  193. int driver_uart_geterr(HAL_UART_ID_e id,unsigned int* err);
  194. /**
  195.   * }
  196.   */

  197. /**
  198.   * }
  199.   */

  200. /**
  201.   * }
  202.   */

  203. /**
  204.   * }
  205.   */

  206. #ifdef __cplusplus
  207. }
  208. #endif

  209. #endif



测试
上位机发送串口数据,板子收到后原样返回,测试是否完全一致。通过调整缓冲区大小和查询缓冲区的间隔,测试性能可以达到波特率对应的理想速度。
总结
以上介绍了串口模块,实现了比较健壮好用的串口驱动,为后续的开发打下了基础。

附件: 您需要登录才可以下载或查看附件。没有帐号?注册

更多回帖

发帖
×
20
完善资料,
赚取积分