CC2530-DMA传输(2)串口发送

DMA数组之间拷贝在CC2530-DMA传输(1)已经记录过了,这次主要是解决当时提到串口发送问题,现在串口发送已解决。具体代码如下,仅供参考交流。

1.Dma

1.1.bspDma.h

#ifndef __BSP_DMA_H__
#define __BSP_DMA_H__

#include "hal_types.h"// Define basic data types:
typedef unsigned char BYTE;
typedef unsigned short WORD;
typedef unsigned char UINT8;
// Define data
#pragma bitfields = reversed
typedef struct {
  uint8 SRCADDRH;       //源地址高字节
  uint8 SRCADDRL;       //源地址低字节
  uint8 DESTADDRH;       //目的地址高字节
  uint8 DESTADDRL;       //目的地址低字节
  uint8 VLEN:3;         //变成传输模式
  uint8 LENH:5;         //传输长度高字节
  uint8 LENL:8;         //传输长度低字节
  uint8 WORDSIZE:1;     //字节传输或字传输
  uint8 TMODE:2;        //传输模式
  uint8 TRIG:5;         //触发时间选择
  uint8 SRCINC:2;       //源地址增量方式选择
  uint8 DESTINC:2;      //目的地址增量方式选择
  uint8 IRQMASK:1;      //中断屏蔽位
  uint8 M8:1;           //字节传输模式时用,8或7bit传输,仅仅适合在字节传输模式下
  uint8 PRIORITY:2;     //优先级选择
}DMA_DESC;
#pragma bitfields = default

#define DMA_IRQ_CH0  1<<0
#define DMA_IRQ_CH1  1<<1
#define DMA_IRQ_CH2  1<<2
#define DMA_IRQ_CH3  1<<3
#define DMA_IRQ_CH4  1<<4

#define DMA_AMOUNT             4
#define DMA_CH0                1<<0
#define DMA_CH1                1<<1
#define DMA_CH2                1<<2
#define DMA_CH3                1<<3
#define DMA_CH4                1<<4


#define DMA_VLEN_USE_LEN             0x00 // Use LEN for transfer count
#define DMA_VLEN_USE_LEN1            0x01 // Transfer number of bytes commanded by LEN + 1
 
#define DMA_WORDSIZE_BYTE            0x00 // Transfer a byte at a time
#define DMA_WORDSIZE_WORD            0x01 // Transfer a 16-bit word at a time
 
#define DMA_TMODE_SINGLE             0x00 // Transfer a single byte/word after each DMA trigger           单个传输模式
#define DMA_TMODE_BLOCK              0x01 // Transfer block of data (length len) after each DMA trigger   块传输模式
#define DMA_TMODE_SINGLE_REPEATED    0x02 // Transfer single byte/word (after len transfers, rearm DMA)   重复单个传输模式
#define DMA_TMODE_BLOCK_REPEATED     0x03 // Transfer block of data (after len transfers, rearm DMA)      重复块传输模式
 
#define DMA_TRIG_NONE                0    // No trigger, setting DMAREQ.DMAREQx bit starts transfer       无触发
#define DMA_TRIG_URX0                0x10   /* USART0 RX complete. */
#define DMA_TRIG_UTX0                0x0F   /* USART0 TX complete. */
#define DMA_TRIG_URX1                0x10   /* USART1 RX complete. */
#define DMA_TRIG_UTX1                0x11   /* USART1 TX complete. */
#define DMA_SRCINC_0                 0x00 // Increment source pointer by 0 bytes/words after each transfer源地址递增0字节/字
#define DMA_SRCINC_1                 0x01 // Increment source pointer by 1 bytes/words after each transfer源地址递增1字节/字
#define DMA_DESTINC_0                0x00 // Increment source pointer by 0 bytes/words after each transfer源地址递增0字节/字
#define DMA_DESTINC_1                0x01 // Increment destination pointer by 1 bytes/words after each transfer目标地址递增1字节/字
 
#define DMA_IRQMASK_DISABLE          0x00 // Disable interrupt generation                                 通道的中断屏蔽
#define DMA_IRQMASK_ENABLE           0x01 // Enable interrupt generation upon DMA channel done            通道的中断使能
 
#define DMA_M8_USE_8_BITS            0x00 // Use all 8 bits for transfer count                            采用所有8位作为传输长度
#define DMA_M8_USE_7_BITS            0x01 // Use 7 LSB for transfer count                                 采用字节地7位作为传输长度
 
#define DMA_PRI_LOW                  0x00 // Low, CPU has priority                                        低优先级,CPU优先
#define DMA_PRI_GUARANTEED           0x01 // Guaranteed, DMA at least every second try                    保证级,DMA至少在每秒一次的尝试中优先
#define DMA_PRI_HIGH                 0x02 // High, DMA has priority                                       高优先级,DMA优先
#define DMA_PRI_ABSOLUTE             0x03 // Highest, DMA has priority. Reserved for DMA port access.     

#define ABORT 0x80 // Bit mask for DMA abort bit (DMAARM)
#define DMAARM_DMAARM0               0x01// Bit mask for DMA arm channel 0 bit (DMAARM)
#define DMAARM_DMAARM1               0x02
#define DMAREQ_DMAREQ0               0x01 
#define DMAREQ_DMAREQ1               0x02 
#define DMAIRQ_DMAIF0                0x01// Bit mask for DMA channel 0 interrupt flag (DMAIRQ)
#define DMAIRQ_DMAIF1                0x02

#define NOP()  asm("NOP")
// Define macro for splitting 16 bits in 2 x 8 bits:
#define HIBYTE(a) (BYTE) ((WORD)(a) >> 8)
#define LOBYTE(a) (BYTE) (WORD)(a)
#define SET_WORD(regH, regL, word) \
 do { \
 (regH) = HIBYTE( word ); \
 (regL) = LOBYTE( word ); \
 } while(0) 
   

void DMA_Transmission(uint8 channel);
void UART_DMA_TX_Init(uint8* sourceaddr, uint8 len);
void DMA_Copy_Init(uint8* sourceaddr, uint8* distanationaddr, uint8 len);
#endif

1.2.bspDma.c

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

DMA_DESC __xdata dmaConfig;
DMA_DESC __xdata dmaConfigTx;// DMA进入工作模式通道1
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_TX_Init(uint8* sourceaddr, uint8 len)
{
  //测试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
}

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
#define FLASH_SIZE 120 //FLASH 大小为8M字节
uint16 IDTYPE = 0;//W25QXX器件ID
uint8 string[] =  "uart DMA test!";
//此数据是用来复制到内存的其他区域
uint8 data[] = "W25Q64 R&W test!";
//数据长度
#define DATA_AMOUNT sizeof(data)
//用来保存复制来的数据区域
uint8 copy[DATA_AMOUNT];
//DMA_DESC __xdata dmaConfig0;
void InitClockTo32M(void)
{   
  CLKCONCMD &= ~0x40;              //设置系统时钟源为 32MHZ晶振
  while(!(CLKCONSTA & 0x40));      //等待晶振稳定
  CLKCONCMD &= ~0x47;              //设置系统主时钟频率为 32MHZ
}

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

void main(void)
{
  InitClockTo32M();
  
  InitLed();
  
  UART_Init();
  EA=1;
  Uart_Send_String(string,sizeof(string));
  
  //W25QXX_Init();
  //IDTYPE = W25QXX_ReadID();//IDTYPE = 0xEF16
  while(1)
  {
    //DMA通道1串口发送,数据从data放到串口缓冲区,可以通过电脑串口助手查看串口打印出来的数据
    UART_DMA_TX_Init(string, sizeof(string));

/*
    //DMA通道0数组拷贝测试,无源触发,数据从data复制到copy,可以通过电脑串口助手查看串口打印出来的数据
    DMA_Copy_Init(data, copy, sizeof(data));
    Uart_Send_String(copy,sizeof(copy));
*/
/*
    //W25Q64读写测试,数据从data写入flash地址,等亮,从flash读取数据放到copy,可以通过电脑串口助手查看串口打印出来的数据
    W25QXX_Write_Page(data,FLASH_SIZE,DATA_AMOUNT);//W25QXX_Read_Byte
    LED = ~LED;
    halMcuWaitMs(1000);
    W25QXX_Read(copy,FLASH_SIZE,DATA_AMOUNT);//W25QXX_Read_Byte
    Uart_Send_String(copy,sizeof(copy));
    memset(copy,0,DATA_AMOUNT);
*/
    LED = ~LED;
    halMcuWaitMs(1000);
  }
}

3. 通过电脑串口助手查看串口打印出来的数据

 

4.待解决

串口DMA接收

 

  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值