CC2530-DMA传输(3)串口接收

CC2530串口DMA研究,本次测试代码主要涉及串口初始化,串口DMA发送,串口DMA接收,串口发送,串口中断接收。

所用串口为:

// uart1 
// p0_4 - TX, p0_5 - RX

具体代码如下,仅供参考。

1.dma.c

#include "hal_types.h"
#include "bspDma.h"
#include "ioCC2530.h"
#include "hal_dma.h"
#include "uart.h"

DMA_DESC __xdata dmaConfig;

bool sDataReceived=0;
bool mDataTransmitted=0;

void NOPn(uint8 temp)
{
  for(uint8 i=0;i<temp;i++)
  {
    NOP();
  }
}

void DMA_Transmission(uint8 channel)
{
  //DMA进入工作模式通道0
  DMAARM |= (1<<channel);//为了任何DMA传输能够在该通道上发生,该位必须置1,对于非重复传输模式,一旦完成传送,该位自动清0
  //一个通道准备工作(即获得配置数据)的时间需要9个系统时钟
  NOPn(9);
  
  DMAIRQ = 0;              //清中断标志    
  
  //DMA通道0传送请求,即触发DMA传送
  DMAREQ |= (1<<channel);//设置为1,激活DMA通道0(与一个触发事件具有相同的效果),当DMA传输开始清除该位
  
  //等待DMA通道0传送完毕
  //for (; !(DMAIRQ & DMAIRQ_DMAIF0););//当DMA通道0传送完成,DMAIRQ:DMAIF1位置1,与上DMAIRQ_DMAIF1(0x01),取非后为0退出循环
  while(!(DMAIRQ&(1<<channel)));    //等待DMA通道0传输结束
  //清除中断标志
  DMAIRQ = ~(1<<channel);  
}

void DMA_Copy_Init(uint8* sourceaddr, uint8* distanationaddr, uint8 len)
{
  //测试DMA通道,无源触发,data数据复制到copy,测试成功,DMA传输无误
  SET_WORD(dmaConfig.SRCADDRH, dmaConfig.SRCADDRL, sourceaddr);//load address of the dma source
  SET_WORD(dmaConfig.DESTADDRH, dmaConfig.DESTADDRL, distanationaddr);//load address of the dma distanation
  SET_WORD(dmaConfig.LENH, dmaConfig.LENL, len); //LEN = nmax
  dmaConfig.VLEN = DMA_VLEN_USE_LEN; // Transfer number of bytes commanded by n
  dmaConfig.WORDSIZE = DMA_WORDSIZE_BYTE; // Each transfer is 8 bits
  dmaConfig.TRIG = DMA_TRIG_NONE;//dmaConfig.TRIG = DMA_TRIG_URX1;
  dmaConfig.TMODE = DMA_TMODE_BLOCK;// Transfer block of data (length len) after each DMA trigger
  dmaConfig.SRCINC = DMA_SRCINC_1; // Increase source addr. by 1 between transfers
  dmaConfig.DESTINC = DMA_DESTINC_1; // Keep the same dest. addr. for all transfers
  dmaConfig.IRQMASK = DMA_IRQMASK_DISABLE;
  dmaConfig.M8 = DMA_M8_USE_8_BITS; // Use all 8 bits of first byte in source data to determine the transfer count
  dmaConfig.PRIORITY = DMA_PRI_HIGH; // DMA memory access has high priority
  SET_WORD(DMA0CFGH, DMA0CFGL, &dmaConfig);
  DMAARM = ABORT;              //停止DMA所有通道进行传输
  DMA_Transmission(0);         //DMA进入工作模式通道0
}

void UART_DMA_RX_Init(uint8* distanationaddr, uint8 len)
{/*
  SET_WORD(dmaConfig.SRCADDRH, dmaConfig.SRCADDRL, &X_U1DBUF);//load address of the dma source
  SET_WORD(dmaConfig.DESTADDRH, dmaConfig.DESTADDRL, distanationaddr);//load address of the dma distanation
  SET_WORD(dmaConfig.LENH, dmaConfig.LENL, len); //LEN = nmax
  dmaConfig.VLEN = DMA_VLEN_USE_LEN; // Transfer number of bytes commanded by n
  dmaConfig.WORDSIZE = DMA_WORDSIZE_BYTE; // Each transfer is 8 bits
  dmaConfig.TRIG = DMA_TRIG_URX1;//DMA_TRIG_URX1;DMA_TRIG_NONE;
  dmaConfig.TMODE = DMA_TMODE_SINGLE;// Transfer block of data (length len) after each DMA trigger//DMA_TMODE_SINGLE,DMA_TMODE_BLOCK
  dmaConfig.SRCINC = DMA_SRCINC_0; // Keep the same source addr. addr. for all transfers
  dmaConfig.DESTINC = DMA_DESTINC_1; // Increase dest. by 1 between transfers
  dmaConfig.IRQMASK = DMA_IRQMASK_ENABLE;//DMA_IRQMASK_ENABLE;DMA_IRQMASK_DISABLE
  dmaConfig.M8 = DMA_M8_USE_8_BITS; // Use all 8 bits of first byte in source data to determine the transfer count
  dmaConfig.PRIORITY = DMA_PRI_HIGH; // DMA memory access has high priority
  SET_WORD(DMA0CFGH, DMA0CFGL, &dmaConfig);

  DMAIF = 0;
  DMAIRQ &= ~DMAARM_DMAARM0;
  DMAIE = 1;
  EA = 1;
  DMAARM |= DMAARM_DMAARM0;
  DMAREQ |= DMAREQ_DMAREQ0;
*/ 
  SET_WORD(dmaConfig.SRCADDRH, dmaConfig.SRCADDRL, &X_U1DBUF);//load address of the dma source
  SET_WORD(dmaConfig.DESTADDRH, dmaConfig.DESTADDRL, distanationaddr);//load address of the dma distanation
  SET_WORD(dmaConfig.LENH, dmaConfig.LENL, len); //LEN = nmax
  dmaConfig.VLEN = DMA_VLEN_USE_LEN; // Transfer number of bytes commanded by n
  dmaConfig.WORDSIZE = DMA_WORDSIZE_BYTE; // Each transfer is 8 bits
  dmaConfig.TRIG = DMA_TRIG_URX1;//DMA_TRIG_URX1;DMA_TRIG_NONE;
  dmaConfig.TMODE = DMA_TMODE_SINGLE;// Transfer block of data (length len) after each DMA trigger//DMA_TMODE_SINGLE,DMA_TMODE_BLOCK
  dmaConfig.SRCINC = DMA_SRCINC_0; // Increase source addr. by 1 between transfers
  dmaConfig.DESTINC = DMA_DESTINC_1; // Keep the same dest. addr. for all transfers
  dmaConfig.IRQMASK = DMA_IRQMASK_ENABLE;//DMA_IRQMASK_ENABLE;DMA_IRQMASK_DISABLE
  dmaConfig.M8 = DMA_M8_USE_8_BITS; // Use all 8 bits of first byte in source data to determine the transfer count
  dmaConfig.PRIORITY = DMA_PRI_HIGH; // DMA memory access has high priority
  SET_WORD(DMA0CFGH, DMA0CFGL, &dmaConfig);
  DMAARM = ABORT;              //停止DMA所有通道进行传输
  DMA_Transmission(0);
}

void UART_DMA_TX_Init(uint8* sourceaddr, uint8 len)
{ 
  //测试DMA通道,DMA_TRIG_UTX1触发,data数据复制到X_U1DBUF,启用DMA中断,测试成功,DMA传输无误
  SET_WORD(dmaConfig.SRCADDRH, dmaConfig.SRCADDRL, sourceaddr);//load address of the dma source
  SET_WORD(dmaConfig.DESTADDRH, dmaConfig.DESTADDRL, &X_U1DBUF);//load address of the dma distanation
  SET_WORD(dmaConfig.LENH, dmaConfig.LENL, len); //LEN = nmax
  dmaConfig.VLEN = DMA_VLEN_USE_LEN; // Transfer number of bytes commanded by n
  dmaConfig.WORDSIZE = DMA_WORDSIZE_BYTE; // Each transfer is 8 bits
  dmaConfig.TRIG = DMA_TRIG_UTX1;//DMA_TRIG_UTX1;DMA_TRIG_NONE
  dmaConfig.TMODE = DMA_TMODE_SINGLE;// Transfer block of data (length len) after each DMA trigger//DMA_TMODE_SINGLE,DMA_TMODE_BLOCK
  dmaConfig.SRCINC = DMA_SRCINC_1; // Increase source addr. by 1 between transfers
  dmaConfig.DESTINC = DMA_DESTINC_0; // Keep the same dest. addr. for all transfers
  dmaConfig.IRQMASK = DMA_IRQMASK_ENABLE;
  dmaConfig.M8 = DMA_M8_USE_8_BITS; // Use all 8 bits of first byte in source data to determine the transfer count
  dmaConfig.PRIORITY = DMA_PRI_HIGH; // DMA memory access has high priority
  SET_WORD(DMA1CFGH, DMA1CFGL, &dmaConfig);
  DMAIF = 0;
  DMAIRQ &= ~DMAARM_DMAARM1;
  DMAIE = 1;
  EA = 1;
  DMAARM |= DMAARM_DMAARM1;
  DMAREQ |= DMAREQ_DMAREQ1;
/*
  //测试DMA通道,DMA_TRIG_UTX1触发,data数据复制到X_U1DBUF,测试成功,DMA传输无误
  SET_WORD(dmaConfig.SRCADDRH, dmaConfig.SRCADDRL, sourceaddr);//load address of the dma source
  SET_WORD(dmaConfig.DESTADDRH, dmaConfig.DESTADDRL, &X_U1DBUF);//load address of the dma distanation
  SET_WORD(dmaConfig.LENH, dmaConfig.LENL, len); //LEN = nmax
  dmaConfig.VLEN = DMA_VLEN_USE_LEN; // Transfer number of bytes commanded by n
  dmaConfig.WORDSIZE = DMA_WORDSIZE_BYTE; // Each transfer is 8 bits
  dmaConfig.TRIG = DMA_TRIG_UTX1;//DMA_TRIG_UTX1;DMA_TRIG_NONE
  dmaConfig.TMODE = DMA_TMODE_SINGLE;// Transfer block of data (length len) after each DMA trigger//DMA_TMODE_SINGLE,DMA_TMODE_BLOCK
  dmaConfig.SRCINC = DMA_SRCINC_1; // Increase source addr. by 1 between transfers
  dmaConfig.DESTINC = DMA_DESTINC_0; // Keep the same dest. addr. for all transfers
  dmaConfig.IRQMASK = DMA_IRQMASK_DISABLE;
  dmaConfig.M8 = DMA_M8_USE_8_BITS; // Use all 8 bits of first byte in source data to determine the transfer count
  dmaConfig.PRIORITY = DMA_PRI_HIGH; // DMA memory access has high priority
  SET_WORD(DMA1CFGH, DMA1CFGL, &dmaConfig);
  DMAARM = ABORT;              //停止DMA所有通道进行传输
  DMA_Transmission(1);         //DMA进入工作模式通道1
*/
}

#pragma vector=DMA_VECTOR
__interrupt void dma_IRQ(void)
{
  DMAIF = 0;
  
  DMAIRQ &= ~DMAIRQ_DMAIF0;
  sDataReceived = TRUE; 
  
  DMAIRQ &= ~DMAIRQ_DMAIF1;
  while(U1ACTIVE);
  mDataTransmitted = TRUE;
}

2.main.c

#include <iocc2530.h>
#include "hal_types.h"
#include "hal_board.h"
#include "hal_mcu.h"
#include "string.h"
#include "W25Qxx.h"
#include "uart.h"
#include "bspDma.h"

#define LED P2_0

uint8 string[] =  "uart DMA test!";//http://en.core.cn
//此数据是用来复制到内存的其他区域
uint8 data[] = "W25Q64 R&W test!";
//数据长度
#define DATA_AMOUNT sizeof(data)
//用来保存复制来的数据区域
uint8 copy[DATA_AMOUNT];
extern bool sDataReceived;
extern bool mDataTransmitted;
void InitClockTo32M(void)
{   
  CLKCONCMD &= ~0x40;              //设置系统时钟源为 32MHZ晶振
  while(!(CLKCONSTA & 0x40));      //等待晶振稳定
  CLKCONCMD &= ~0x47;              //设置系统主时钟频率为 32MHZ
}

void InitLed(void)
{
  P2DIR |= 0x01;
  P2_0   = 0;
}


void UART1_Init(void)
{
  // uart1 init config
  PERCFG &= ~1<<1;        //bit1 = 0, uart1 -- postion 1 p0_4, p0_5, bit1 = 1, postion 2 p1_6, p1_7 
  P0SEL  |= (1<<4 | 1<<5);//uart1 p0_4, p0_5:bit4,5 = 1   

  P2DIR  &= ~1<<7;        //bit[7-6] = 01, at P0 port, uart1 get a higher priority than uart0
  P2DIR  |= 1<<6;
  
  U1CSR  |= 1<<7;         //bit7=0 uartMode;1 spiMode
  
  U1GCR  |= 11;           //U0GCR and U0BAUD set baud rate.     
  U1BAUD |= 216;          //115200 
  
  UTX1IF = 0;             //clear uart0 TX interrupt flag. //we does not use it.
  URX1IF = 0;             //clear uart0 RX interrupt flag.
  
  URX1IE = 1;             //Enable rx interrupt 
  U1CSR |= 0X40;          //Enable rx
  EA=1;
}

void main(void)
{
  InitClockTo32M();
  
  InitLed();
  
  UART1_Init();

  Uart_Send_String(string,sizeof(string));
  
  while(1)
  {
 
    UART_DMA_RX_Init(copy,DATA_AMOUNT);
    if (copy[0]!=0)
    {
      Uart_Send_String(copy,sizeof(copy));
      memset(copy,0,sizeof(copy));
    }
/*
    //DMA通道0串口接收,数据从串口缓冲区放到copy,可以通过电脑串口助手查看串口打印出来的数据
    //UART_DMA_RX(copy, DATA_AMOUNT);
    if (sDataReceived)
    {
      sDataReceived = FALSE;
      Uart_Send_String(copy,sizeof(copy));
      memset(copy,0,sizeof(copy));
    }
*/
/*
    //DMA通道1串口发送,数据从data放到串口缓冲区,可以通过电脑串口助手查看串口打印出来的数据
    UART_DMA_TX_Init(string, sizeof(string));
    if (mDataTransmitted)
    { 
      mDataTransmitted=0;
    }
*/
/*
    //DMA通道0数组拷贝测试,无源触发,数据从data复制到copy,可以通过电脑串口助手查看串口打印出来的数据
    DMA_Copy_Init(data, copy, sizeof(data));
    Uart_Send_String(copy,sizeof(copy));
*/
/*
    //串口中断接收测试
    if(copy[0] != 0)
    {
      Uart_Send_String(copy,DATA_AMOUNT);
      memset(copy,0,DATA_AMOUNT);
    }
*/
    LED = ~LED;
    halMcuWaitMs(1000);
  }
}

#pragma vector = URX1_VECTOR
__interrupt void UART1_ISR(void)
{
  static uint8 i=0;
  URX1IF = 0;
  if(i < DATA_AMOUNT-1)
  {
    copy[i] = U1DBUF;
    i++;
  }
  else
  {
    i = 0;
  }
}

3.仿真调试

4.串口打印

 

 

  • 1
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值