打印
[PIC®/AVR®/dsPIC®产品]

使用MCC学习PIC单片机 – DMA 直接存储器访问

[复制链接]
3010|5
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
本帖最后由 oxygenzz 于 2019-4-17 17:52 编辑


PIC18芯片家族中,K42和K83等系列芯片配备有DMA外设。这使得存储器与外设之间的数据传输可以不经过CPU干预来进行,能显著的提高数据传输的吞吐率。

MCC配置界面:






DMA功能框图如下,图中画出了两个DMA通道。




传输方向/源地址/目的地址

DMA数据传输方向是固定的,即从源地址到目的地址。具体的说,DMA能将数据从源地址读出,然后写入目的地址。
源地址(读操作):flash,EEPROM,GPR(SRAM), SFR(外设寄存器)
目的地址(写操作):GPR (SRAM),SFR(外设寄存器)
源地址起始地址寄存器,为24位,DMAxSSAU-DMAxSSAH-DMAxSSAL
目的地址起始地址寄存器,为16位, DMAxDSAH-DMAxSSAL

传输数据长度

传输数据长度由源端数据长度和目的端数据长度决定。这两个数据长度可以设置不同。当设置不同时,每次传输的长度由较小的一端决定。

典型的传输形式举例:
N:1 - 将N字节长度数据通过串口/SPI口传输出去
N:N – 将数据块在存储器不同地址间搬移
1:N – 将ADC采集到数据依次写入到一块预定的存储器空间
1:1 – 两个通信口桥接

DMA 启动/停止控制

DMA数据搬移启动可以由软件操作,也可以由其他外设进行触发。
同样的,停止操作也是可以由软件操作或硬件触发。

DMA与CPU资源使用仲裁

可以设为DMA高优先级或CPU高优先级。
当DMA高优先级时,DMA操作时,CPU执行暂停;当CPU高优先级时,DMA利用
CPU空闲时间进行DMA传输。


MCC生成代码

初始化函数。注意函数中嵌入了一段汇编代码。
void DMA1_Initialize(void)
{
DMA1SSA = 0x000000; //set source start address
    DMA1DSA = 0x1000; //set destination start address
    DMA1CON1 = 0x00; //set control register1
    DMA1SSZ = 0x0000; //set source size
    DMA1DSZ = 0x0000; //set destination size
    DMA1SIRQ = 0x01; //set DMA Transfer Trigger Source
    DMA1AIRQ = 0x01; //set DMA Transfer abort Source   
    PIR2bits.DMA1DCNTIF =0; // clear Destination Count Interrupt Flag bit
    PIR2bits.DMA1SCNTIF =0; // clear Source Count Interrupt Flag bit
    PIR2bits.DMA1AIF =0; // clear abort Interrupt Flag bit
    PIR2bits.DMA1ORIF =0; // clear overrun Interrupt Flag bit

    PIE2bits.DMA1DCNTIE =1; // enable Destination Count 0 Interrupt
    PIE2bits.DMA1SCNTIE =1; // enable Source Count Interrupt
    PIE2bits.DMA1AIE =1; // enable abort Interrupt
    PIE2bits.DMA1ORIE =1; // enable overrun Interrupt
        
   //给与外设访问存储器的权限
   asm("BCF INTCON0,7");
        
   asm ("BANKSEL PRLOCK");
    asm ("MOVLW 0x55");
    asm ("MOVWF PRLOCK");
    asm ("MOVLW 0xAA");
    asm ("MOVWF PRLOCK");
    asm ("BSF PRLOCK, 0");
        
        asm("BSF INTCON0,7");

    DMA1CON0 = 0x00; //set control register0
}
源端传输完成中断
void DMA1_DMASCNT_ISR(void)
{
    PIR2bits.DMA1SCNTIF=0;// clear Source Count Interrupt Flag
    // add your DMA channel 1 source count 0 interrupt custom code
}
目的端传输完成中断
void DMA1_DMADCNT_ISR(void)
{
    PIR2bits.DMA1DCNTIF=0; // clear Destination Count Interrupt Flag
    // add your DMA channel 1 destination count 0 interrupt custom code
}
中止产生中断
void DMA1_DMAA_ISR(void)
{
    PIR2bits.DMA1AIF=0;// clear abort Interrupt Flag
    // add your DMA channel 1 abort interrupt custom code
}
过载产生中断
void DMA1_DMAOR_ISR(void)
{
    PIR2bits.DMA1ORIF=0;// clear overrun Interrupt Flag
    // add your DMA channel 1 overrun interrupt custom code
}




使用特权

评论回复
评论
forgot 2024-4-17 08:45 回复TA
可以提高数据传输的吞吐率 
沙发
CoolSilicon| | 2019-4-18 08:56 | 只看该作者
加油加油!!还有13个MCC外设模块呢!!

使用特权

评论回复
板凳
wanduzi| | 2024-4-16 22:57 | 只看该作者
这个貌似已经不符合现在的MCC了,MCC好像改版了。

使用特权

评论回复
地板
天灵灵地灵灵| | 2024-4-29 22:17 | 只看该作者
DMA实在是太好用了。

使用特权

评论回复
5
Libby@| | 2024-5-7 11:06 | 只看该作者
DMA是个好东西

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

46

主题

190

帖子

11

粉丝