串口DMA发送+中断接收的例程

lpc5500的sdk中提供了非常丰富的串口例程(如下图所示):
但是,偏偏没有串口dma发送+中断接收这种组合。
实话说小编觉得这种组合才是大部分mcu场景中最常用的。尤其是对一些rx数据量不大(比如只是解析一些命令)但是tx数据量大的应用(比如定时,高频发送数据)再合适不过,该架构模型简单,非常容易理解。
本篇文章就手把手教大家分分钟撸一个dma发送+中断接收的例程:
我们复制一个dma_transfer例程作为模板,重命名为dma_tx_int_rx(名字无所谓,自己起即可)。打开,编译下载运行一下,确保原版demo在自己的板子上可以顺利的运行,咱们把前期工作都铺垫好。
下面我们开始改代码:dma_transfer原版代码是tx和rx都是dma传输,我们只需要将rx改为中断接收数据即可。
首先将usart_transfercreatehandledma函数修改下,将所有rx dma有关的东西去掉,handler填null就可以。这样usart_dmadriver就不会处理rx dma有关的操作了:
usart_transfercreatehandledma(demo_usart, &g_uartdmahandle, usart_usercallback, null,&g_uarttxdmahandle, null);
2. 开启usart rx中断,没啥可说的,常规操作:
/* enable rx interrupt. */ usart_enableinterrupts(demo_usart, kusart_rxlevelinterruptenable | kusart_rxerrorinterruptenable); enableirq(demo_usart_irqn);
3. 在app层定义(接管)串口硬件中断,并在中断中处理串口rx接收到的数据: #define demo_usart_irqhandler flexcomm0_irqhandler #define demo_usart_irqn     flexcomm0_irqn
void demo_usart_irqhandler(void) {   uint8_t data;   /* if new data arrived. */   if ((kusart_rxfifonotemptyflag | kusart_rxerror | kusart_rxfifofullflag) & usart_getstatusflags(demo_usart))   {       data = usart_readbyte(demo_usart);       printf(usart rx interrupt:%c , data);       if(data == 's')
      {
         /* send g_tipstring out. */
         xfer.data     = g_tipstring;
         xfer.datasize = sizeof(g_tipstring) - 1;
         g_uartdmahandle.txstate = kusart_txidle;
         usart_transfersenddma(demo_usart, &g_uartdmahandle, &xfer);
     }
  }
  if ((0u != (demo_usart->intenset &  usart_intenset_txidleen_mask)) && (0u != (demo_usart->intstat & usart_intstat_txidle_mask)))
  {
     usart_transferdmahandleirq(demo_usart, &g_uartdmahandle);
  }
}
注意,这里需要在硬件串口中断里判断txidle中断,并调用usart_transferdmahandleirq。这是仿照fsl_usart_dma.c中的写法(fsl_usart_dma中开启了txidle中断,并使用txidle中断来调用dma handle用户回调函数,现在硬件串口中断已经被app层接管,所以我们同样要实现这部分功能)。 4. 测试:改好代码,下载运行:当串口敲入任意键时候,程序都会回显接收到数据,当按键”s”时,会调用usart_transfersenddma函数使用dma发送一串数据,并进入dma发送完成回调函数。
代码清单
以下是完整代码清单(可以直接复制到usart_dma_transfer.c里运行):
/* * copyright (c) 2016, freescale semiconductor, inc.
* copyright 2016-2017 nxp
* all rights reserved.
*
* spdx-license-identifier:  bsd-3-clause
*/
#include pin_mux.h
#include board.h
#include fsl_usart.h
#include fsl_usart_dma.h
#include fsl_dma.h
#include fsl_debug_console.h
#include
#include fsl_power.h
#define demo_usart                usart0
#define demo_usart_clk_src        kclock_flexcomm0
#define demo_usart_clk_freq       clock_getflexcommclkfreq(0u)
#define usart_rx_dma_channel      4
#define usart_tx_dma_channel      5
#define example_uart_dma_baseaddr dma0
#define demo_usart_irqhandler flexcomm0_irqhandler
#define demo_usart_irqn       flexcomm0_irqn
#define echo_buffer_length 8
usart_transfer_t xfer;
usart_dma_handle_t g_uartdmahandle;
dma_handle_t g_uarttxdmahandle;
uint8_t g_tipstring[]                  = this string is send from uart_dma ;
#define kusart_txidle 0
void usart_usercallback(usart_type *base, usart_dma_handle_t *handle, status_t status, void *userdata)
{
  userdata = userdata;
  if (kstatus_usart_txidle == status)
  {
      printf(usart_usercallback, status:0x%x , status);
  }
}
void demo_usart_irqhandler(void) {   uint8_t data;   /* if new data arrived. */   if ((kusart_rxfifonotemptyflag | kusart_rxerror | kusart_rxfifofullflag) & usart_getstatusflags(demo_usart))   {       data = usart_readbyte(demo_usart);       printf(usart rx interrupt:%c , data);       if(data == 's')
      {
         /* send g_tipstring out. */
         xfer.data     = g_tipstring;
         xfer.datasize = sizeof(g_tipstring) - 1;
         g_uartdmahandle.txstate = kusart_txidle;
         usart_transfersenddma(demo_usart, &g_uartdmahandle, &xfer);
     }
  }
  if ((0u != (demo_usart->intenset &  usart_intenset_txidleen_mask)) && (0u != (demo_usart->intstat & usart_intstat_txidle_mask)))
  {
     usart_transferdmahandleirq(demo_usart, &g_uartdmahandle);
  }
}
int main(void)
{
  usart_config_t   config;
/* set bod vbat level to 1.65v */
  power_setbodvbatlevel(kpower_bodvbatlevel1650mv, kpower_bodhystlevel50mv, false);
  /* attach 12 mhz clock to flexcomm0 (debug console) */
  clock_attachclk(kfro12m_to_flexcomm0);
board_initbootpins();
  board_initbootclocks();
  board_initdebugconsole();
printf(usart: tx dma, rx interrupt );
  printf(press 's' for dma tx tranmsit );
usart_getdefaultconfig(&config);
  config.baudrate_bps = board_debug_uart_baudrate;
  config.enabletx     = true;
  config.enablerx     = true;
usart_init(demo_usart, &config, demo_usart_clk_freq);
/* configure dma. */
  dma_init(example_uart_dma_baseaddr);
  dma_enablechannel(example_uart_dma_baseaddr, usart_tx_dma_channel);
  dma_enablechannel(example_uart_dma_baseaddr, usart_rx_dma_channel);
  dma_createhandle(&g_uarttxdmahandle, example_uart_dma_baseaddr, usart_tx_dma_channel);
  usart_transfercreatehandledma(demo_usart, &g_uartdmahandle, usart_usercallback, null, &g_uarttxdmahandle, null);
/* send g_tipstring out. */
  xfer.data     = g_tipstring;
  xfer.datasize = sizeof(g_tipstring) - 1;
  usart_transfersenddma(demo_usart, &g_uartdmahandle, &xfer);
/* enable rx interrupt. */
  usart_enableinterrupts(demo_usart, kusart_rxlevelinterruptenable | kusart_rxerrorinterruptenable);
  enableirq(demo_usart_irqn);
  while (1);
}


变压器变比测试仪的作用_变压器变比测试仪的设计
戴姆勒通过架构重组计划 预计2020年完成
英飞凌携手SensiML为智能家居、健身和工业应用提供传感器数据并训练机器学习模型
投资400亿 国内首个柔性半导体服务基地“落地”西咸新区
UWB赛道快速崛起:推进技术发展,拓展落地应用
串口DMA发送+中断接收的例程
广电运通AI+安防,助力区域产业园区智慧升级
HTC U11怎么样?苹果iPhone7又迎来降价潮,面对年度旗舰HTC U11的强强压迫,你会怎么选?
SpaceX将继续开展 Q/V/Ka 等频段的通信性能测试
艾德克斯可为医疗电子设备提供专业的测试解决方案
水质检测实验室常规配置的仪器设备清单
dfrobotCheapduino控制器介绍
关于推导全差分放大器传递公式
汽车必备的5款小配件
船用主配电板和应急配电板的通电试验操作
再智能的驾驶,也离不开安全
铁路应用连接器
Altius探针卡的主要特征是什么
可穿戴式智能手机—努比亚α 即将量产,预计4月将在中国市场首销
浅析UWB技术在物联网中的应用价值