武汉理工大学自动化学院 唐穗欣
一、引言 由于在C8051F060单片机中采用了双16位模数转换器(ADC),采集速度较之前面产品有了大幅度提高,CPU既要控制 ADC信号采集,又要队ADC的转换数据进行存储控制。这样一来,CPU对于实时采集的信号不能加以迅速处理,甚至发生在数据缓冲器里数据重叠并丢失的现象,造成整个系统的性能下降,因而,采取了DMA存储技术,以缓解CPU的工作压力。
二、 C8051F060简介 C8051F060(简称060)是美国德州Cygnal公司推出的一种混合信号SOC型8位单片机,它属于 C8051F系列中的F06x子系列,其性价比在目前应用领域极具竞争力。其模拟外设包括:两个由DMA控制的16位1Msps 的ADC、一个10位逐次逼近型(SAR)ADC,可多达8个外部输入,可编程为单端输入或差分输入、两个12位DAC、内部高精度基准电源、一个温度传感器、三个模拟比较器以及精确的VDD监视器和欠压检测器。数字外设包括:8个8位的I/O端口、五个16位定时/计数器、两个可同时使用硬件SMBus (I2C兼容)、SPI及两个增强型UART串口、可编程的16位计数器/定时器阵列(PCA)、六个捕捉/比较模块、专用的看门狗定时器。此外,高速 8051位控制器内核,流水线式指令结构使其速度可达25MIPS,存储器部分为片内4352字节数据RAM和64KB Flash程序存储器可作非易失性存储,此外外部可扩展64KB数据存储器接口。 三、C8051F060中的DMA介绍 1、DMA原理 DMA 是一种新型的存储技术,在DMA传送方式下,数据的传送不经过CPU,由DMA控制器来实现内存和外设,外设和外设之间的直接快速传送。它多用于需要高速大批量数据传送的系统中,以提高数据的吞吐率。但是,DMA传送方式的优点是以增加系统硬件的复杂性和成本为代价的。 2、DMA接口技术 C8051F060 单片机种的DMA是配合着两个模数转换器ADC0 和ADC1 来使用,它把ADC0和ADC1转换结果直接存到XRAM的一个专门的区域。DMA接口是由特殊功能寄存器(SFR)来配置使用的。在DMA中,有一个指令缓冲器,可编入多达64条DMA指令来对DMA 产生一连串的操作。这个指令缓冲器可有DMA控制逻辑来访问。这些DMA指令会告诉DMA控制逻辑将要存储那一个ADC的转换结果。值得注意的是,在开始 DMA接口前,务必把ADC的参考电压、逐次比较的时钟频率要设置好。 3、如何向指令缓冲器写指令 指令缓冲器是一个64字节的存储区域,能够写一些指令在里面,这些指令就成为DMA指令。如何向其中写指令是由特殊功能寄存器DMA0IPT和DMA0IDT控制。DMA0IPT寄存器控制的是地址,DMA0IDT控制的是数据,当在DMA0IDT区中读出或写入一条指令时,DMA0IPT寄存器指针将自动指向下一个指令区域。 4、数据存储的选择 DMA要存储的数据来自于AD转换的结果,分为ADC0的转换结果、ADC1的转换结果以及它们转换结果的差分输出。如何设定请见下列宏定义中所示: #define DMA0_END_OF_OP 0x00 // 不存储 #define DMA0_END_OF_OP_C 0x80 // 不存储并继续转换 #define DMA0_GET_ADC0 0x10 // 存储ADC0的转换结果 #define DMA0_GET_ADC1 0x20 // 存储ADC1的转换结果 #define DMA0_GET_ADC01 0x30 // 存储ADC0 和ADC1的结果 #define DMA0_GET_DIFF 0x40 // 存储差分输出结果 #define DMA0_GET_DIFF1 0x60 // 存储差分输出和ADC1结果5、数据存储器的编址与设置 DMA接口可设置为即可以访问内部数据存储器也可以访问外部存储器。但是,只有CPU不使用片内数据存储器时,DMA才可以对片内存储器进行访问,这样就保证了DMA和CPU在时序上不会冲突。 片外数据存储器的访问权由DMA0CF寄存器中的DMA0HLT为控制。当DMA0HLT=0时,片外数据存储器完全由DMA访问;当DMA0HLT=1 时,CPU访问片外数据存储器。当DMA和CPU都要求访问片外数据存储器时,DMA0HLT位由软件控制置‘1’或置‘0'。软件应检查DMA0XBY 位,它为‘0'时,DMA没有在访问片外数据存储器,为‘1'时,表明DMA正在访问片外数据存储器。当DMA0HLT=‘0'时,CPU不能访问外部数据存储器。这时,CPU好像仍然继续访问片外数据存储器,但是,数据却不能从片外数据存储器读出或写入。当CPU访问完片外数据存储器后,要把 DMA0HLT设为‘0',以便DMA接口能访问外部数据存储器。DMA控制逻辑将总是等到DMA0HLT=‘0'时,才存数据到片外数据存储器。如果在新的数据到来时DMA接口上的数据还没有被写入片外数据寄存器,那么,新来的数据将丢失。 DMA将数据写在片外数据存储器的哪个地方是由数据地址指针寄存器DMA0DSH和DMA0DSL来决定,DMA0DSH和DMA0DSL组成16位地址。在写数据之前,DMA0DSH和DMA0DSL被初始化为DMA0DAH和DMA0DAL。当写入一个数据后,数据地址寄存器将自动加‘1'。
6、中断源 DMA有多个中断源,并且一些中断源在需要时可单独使用,DMA控制寄存器(DMA0CN)和配置寄存器(DMA0CF)包含了DMA的中断位。DMA中断如下表所示:
四、DMA寄存器 1、 DMA控制寄存器(DMA0CN) MSB LSB DMA0EN:DMA允许位 当写数据时:0:禁用DMA 1:启动DMA 当读数据时:0:DMA口是空闲的 1:正在使用 DMA0INT:DMA操作完成标志位 0:DMA还没有完成所有操作 1:DMA完成所有操作 DMA0MD:DMA模式选择位 0:模式0 1:模式1 DMA0DE1:ADC1数据溢出错误标志位 0:数据未溢出 1:数据溢出,ADC1的转换结果丢失,软件清此位 DMA0DE0:ADC0数据溢出错误标志位 0:数据未溢出 1:数据溢出,ADC0的转换结果丢失,软件清此位 DMA0DOE:数据溢出警告中断使能位 0:禁止数据溢出警告中断 1:允许数据溢出警告中断 DMA0DO1:ADC1数据溢出警告标志位 0:ADC1没有数据溢出警告 1:ADC1有数据溢出警告,软件置0 DMA0DO0:ADC0数据溢出警告标志位 0:ADC0没有数据溢出警告 1:ADC0有数据溢出警告,软件置0 2、DMA配置寄存器(DMA0CF) MSB LSB DMA0HLT:阻止DMA访问片外数据存储器 0:DMA已经完成对片外数据存储器的访问 1:CPU已经完成对片外数据存储器的访问 DMA0XBY:片外数据寄存器忙标志 0:DMA没有正在使用片外数据存储器 1:DMA0正在访问片外数据存储器 位5-4:保留,置0 DMA0CIE:指令计数器溢出中断允许位 0:禁止指令计数器溢出中断 1:允许指令计数器溢出中断 DMA0CI:指令计数器溢出标志位 0:指令计数器还未溢出 1:指令计数器已经溢出,软件清0 DMA0EOE:操作结束中断使能位 0:禁止操作结束中断 1:允许操作结束中断 DMA0EO:操作结束标志位 0:操作结束指令还未收到 1:操作结束指令已经收到,软件清0此位 3、DMA指令写数据寄存器(DMA0IDT) MSB LSB CCNV:连续转换位 0:禁止连续转换位 1:允许连续转换,指令计数器忽略,转换继续 DIFFSEL:等差分输出数据位 0:不收集差分输出数据 1:等待差分输出数据并储存至片外数据存储器 ADC1EN:等ADC1的数据 0:不收集ADC1数据 1:等待ADC1数据并储存至片外数据存储器 ADC0EN:等ADC0的数据 0:不收集ADC0数据 1:等待ADC0数据并储存至片外数据存储器 位3-0:保留 ,置0 五:软件编程 1、DMA初始化程序 void DMA0_Init (unsigned int XRAM_START_ADD,unsigned int NUM_SAMPLES) { char old_SFRPAGE = SFRPAGE; //储存当前寄存器页 SFRPAGE = DMA0_PAGE; // 切换到DMA0特殊功能寄存器页 DMA0CN = 0x00; // 禁止DMA接口 DMA0DA = XRAM_START_ADD; // 设置数据存储器开始值 DMA0CT = NUM_SAMPLES; // 获取采样点 DMA0IPT = 0x00; // 设置向指令缓冲器中写指令的开始区域为0 DMA0IDT = DMA0_GET_ADC01; // DMA 存ADC0的转换数据 DMA0IDT = DMA0_END_OF_OP; DMA0BND = 0x00; // 设置指令开始执行地址为0 DMA0CN = 0x80; //设置为模式0, 开始执行指令 SFRPAGE = old_SFRPAGE; // 恢复刚才的特殊功能寄存器页 } 2、DMA调用方法: EMIF_Init (); // 外部数据存储器接口初始化 SFRPAGE = CONFIG_PAGE; // 置DMA配置寄存器页为当前页 ADC0_Init (); // ADC0初始化 ADC1_Init (); // ADC0初始化 Timer3_Init (SYSCLK/SAMP_RATE); // 定时器3初始化设出采样率 EA=0; // 关中断 for(x=0;x<4096;x++)XBYTE[x]=0xff; //清内部数据寄存器 SFRPAGE = DMA0_PAGE; // 置DMA0寄存器页为当前页 DMA0_Init (0x0000,512); //DMA0初始化 while (!(DMA0CN & 0x40)); //开DMA接口,准备储存数据 结束语 C8051F060内部DMA技术的开发利用大大提高了CPU的数据采集速率,解决了以往CPU不能对实时采集的信号加以迅速处理、数据缓冲器里发生数据重叠并丢失、系统性能下降等现象。为高速大批量数据传送的系统提供了方便。
参考文献: [1]潘琢金,施国君。C8051FXXX高速SOC单片机原理及应用[M].北京航空航天大学出版社,2002 [2]许爱均,彭秀华。单片机高级语言C51应用程序设计 北京:电子工业出版社 2002
|