您的位置 首页 5G

SAM4E单片机之旅——11、UART之PDC收发

使用PDC进行数据的收发能减少CPU的开销。这次就使用PDC进行UART数据的接收与发送,同时,也利用TC也实现了PDC的接收超时。PDC是针对外设的DMA控制器。对比DMA控制器,它更为简便

  运用PDC进行数据的收发能削减CPU的开支。这次就运用PDC进行UART数据的接纳与发送,一起,也运用TC也完结了PDC的接纳超时。

  PDC是针对外设的DMA控制器。比照DMA控制器,它更为简洁,与相应外设的结合也更为严密。比如说,要装备PDC时,首先要启用相应的外设的时钟;一起PDC收发的状况是经过外设上的寄存器反映出来的;乃至中止也是经过相应外设发生的。

  运用PDC时,只需设置好传输时内存的地址,以及传输长度,就能够在外设和内存之前进行数据传输了。而SAM4的PDC乃至还供给了一个相似FIFO的功用:能够在进行本次传输的一起指定下次传输时的地址和长度,然后在本次传输结束时开端下一次传输。

  一、 完结思路

  本次会运用两组缓冲区,别离用来数据的接纳和发送。在接纳数据完结后,就让PDC把这个缓冲区的数据发送出去,而且运用另一个缓冲区进行数据接纳。

  运用PDC发送数据较为简略,只需设置好需求发送的数据的地址和长度即可。

  但是在运用PDC接纳数据的时,假如未接纳满足指定数目的数据,是不会发生中止的。在这儿运用TC来进行PDC接纳数据时的等候超时处理:

  UART的引脚在没有数据传输时,是一向坚持在高电平状况的。即只在有数据传输时,才会有电平的切换。而TC能够运用外部信号进行触发以重置计数器。这样一来,就能够让UART在接纳数据的一起,不断对TC的计数器进行重置。而在没有接纳数据时,就会使得TC顺畅步进到一个特定的值,然后发生一个中止。

  二、 UART的PDC装备

  UART和MCK的根本装备坚持不变:MCK为120 MHz,UART波特率为11520 Hz。

  在装备PDC时,需求保证现已敞开了相应UART的时钟,不然装备不收效。

  缓冲区和PDC的装备。装备完结,且启用UART的接纳后,就能够进行数据的接纳了。

  /* 缓冲区 */

  #define BUF_SIZE 8

  uint8_t BUF1[BUF_SIZE];

  uint8_t BUF2[BUF_SIZE];

  uint8_t* RX_BUF;

  /* 先设置好接纳的BUF */

  RX_BUF = BUF1;

  PDC_UART0->PERIPH_RPR = RX_BUF;

  PDC_UART0->PERIPH_RCR = BUF_SIZE;

  /* 使能输入输出*/

  PDC_UART0->PERIPH_PTCR = PERIPH_PTCR_RXTEN | PERIPH_PTCR_TXTEN;

  中止设置。PDC的中止是经过相应外设发生的,所以这儿需求对UART的中止进行装备。

  /* 启用缓冲区满中止*/

  UART0->UART_IER = UART_IER_RXBUFF;

  /* 在NVIC中启用中止,将优先级设置为1*/

  NVIC_DisableIRQ(UART0_IRQn);

  NVIC_ClearPendingIRQ(UART0_IRQn);

  NVIC_SetPriority(UART0_IRQn, 1);

  NVIC_EnableIRQ(UART0_IRQn);

  将接纳缓冲区的数据经过PDC发送出去,并开端下一次数据的接纳。

  /* 参数size: 表明接纳缓冲区中需求发送的数据的长度 */

  void TransferRxBufAndRec(int size)

  {

  /* 等候发送完结 */

  while(!(UART0->UART_SR & UART_SR_TXBUFE))

  ;

  /* 经过PDC发送 */

  PDC_UART0->PERIPH_TPR = RX_BUF;

  PDC_UART0->PERIPH_TCR = size;

  /* 运用另一个缓冲区持续接纳 */

  RX_BUF = (RX_BUF == BUF1) ? BUF2 : BUF1;

  PDC_UART0->PERIPH_RPR = RX_BUF;

  PDC_UART0->PERIPH_RCR = BUF_SIZE;

  }

  UART的中止处理函数。在中止时,只需调用上面的函数,将接纳缓冲区的内容从头发送出去即可。

  void UART0_Handler(void)

  {

  /*判别是否是由“接纳缓冲区满”引发的中止 */

  if (UART0->UART_SR & UART_SR_RXBUFF)

  {

  TransferRxBufAndRec(BUF_SIZE);

  }

  }

  这样装备完结后,删去上一节中UART收发数据的代码,即可完结数据的收发了。

  三、 TC的装备

  运用的通道为通道0:

  #define gUseTc TC0->TC_CHANNEL[0]

  使TC作业在波形输出形式下,将TIOB引脚(PA1)用做外部事情引脚,短接它和UART0接纳引脚,即短接PA1和PA9引脚。在装备完结后,若500ms内没有数据接纳,则强制开端数据的发送。

  使能TC时钟,及GPIO设置。

  PMC->PMC_PCER0 = (1 << ID_TC0);

  const uint32_t TIOB_PIN = PIO_PA1;

  PIOA->PIO_PDR = TIOB_PIN;

  PIOA->PIO_ABCDSR[0] |= TIOB_PIN;

  PIOA->PIO_ABCDSR[1] &= ~TIOB_PIN;

  TC形式设置。

  运用TC的RC比较时发生的中止进行超时提示,TIOB引脚电平的下降沿TC的触发。因为进行TC触发时也会敞开时钟,所以在RC比较时暂停时钟。

  因为超时时刻或许较长,且精度要求不高,让TC运用慢时钟SLCK就能够了。

  gUseTc.TC_CMR =

  TC_CMR_WAVE /* 波形形式 */

  | TC_CMR_TCCLKS_TIMER_CLOCK5 /* 时钟5: SLCK */

  | TC_CMR_WAVSEL_UP_RC /* 波形仅上升,且RC比较时触发 */

  | TC_CMR_CPCSTOP /* RC 比较时主动中止时钟 */

  | TC_CMR_EEVT_TIOB /* 设置为外部事情为TIOB */

  | TC_CMR_EEVTEDG_FALLING /* 外部事情下降沿触发 */

  | TC_CMR_ENETRG /* 使能外部事情 */

  ;

  RC设置,以及TC启用。在RC比较后,计数器将暂停作业。在下次UART数据的接纳时,TIOB引脚的信号会触发TC以从头开端计数。

  /* UART的PDC接纳时等候超时时刻 */

  #define UART_RX_WAIT_MS 500

  /* 设置RC */

  const uint32_t rc_v = CHIP_FREQ_SLCK_RC * UART_RX_WAIT_MS / 1000;

  gUseTc.TC_RC = TC_RC_RC(rc_v);

  /* 使能TC时钟,但不开端*/

  gUseTc.TC_CCR = TC_CCR_CLKEN;

  中止设置。TC中止的优先级比UART的要高。

  /* RC 比较时发生中止 */

  gUseTc.TC_IER = TC_IER_CPCS;

  /* NVIC , 优先级设置为0 */

  NVIC_DisableIRQ(TC0_IRQn);

  NVIC_ClearPendingIRQ(TC0_IRQn);

  NVIC_SetPriority(TC0_IRQn, 0);

  NVIC_EnableIRQ(TC0_IRQn);

  中止处理。中止处理中过程中禁用PDC数据的接纳,避免丢掉数据。

  void TC0_Handler(void)

  {

  uint32_t status = gUseTc.TC_SR;

  /* 判别中止是否为RC比较触发的 */

  if (status & TC_SR_CPCS)

  {

  PDC_UART0->PERIPH_PTCR = PERIPH_PTCR_RXTDIS;

  /* 核算PDC中接纳到的数据的巨细 */

  const int rec_size = BUF_SIZE – (PDC_UART0->PERIPH_RCR);

  if (rec_size != 0)

  {

  TransferRxBufAndRec(rec_size);

  }

  PDC_UART0->PERIPH_PTCR = PERIPH_PTCR_RXTEN;

  }

  }

声明:本文内容来自网络转载或用户投稿,文章版权归原作者和原出处所有。文中观点,不代表本站立场。若有侵权请联系本站删除(kf@86ic.com)https://www.86ic.net/yingyong/5g/204153.html

为您推荐

联系我们

联系我们

在线咨询: QQ交谈

邮箱: kf@86ic.com

关注微信
微信扫一扫关注我们

微信扫一扫关注我们

返回顶部