单片机清零程序DMA传输完成后会把目标地址清零吗?急!!

DMA部分我用到的相对简单,当然,可能这是新东西,我暂时还用不到它的复杂功能吧。下面用问答的形式表达我的思路。
DMA有什么用?
&&&&&& 直接存储器存取用来提供在外设和存储器之间或者存储器和存储器之间的高速数据传输。无须CPU的干预,通过DMA数据可以快速地移动。这就节省了CPU的资源来做其他操作。
有多少个DMA资源?
&&&&&& 有两个DMA控制器,DMA1有7个通道,DMA2有5个通道。
数据从什么地方送到什么地方?
&&&&&& 外设到SRAM(I2C/UART等获取数据并送入SRAM);
&&&&&& SRAM的两个区域之间;
&&&&&& 外设到外设(ADC读取数据后送到TIM1控制其产生不同的PWM占空比);
&&&&&& SRAM到外设(SRAM中预先保存的数据送入DAC产生各种波形);
&&&&&& &&还有一些目前还搞不清楚的。
DMA可以传递多少数据?
&&&&&& 传统的DMA的概念是用于大批量数据的传输,但是我理解,在STM32中,它的概念被扩展了,也许更多的时候快速是其应用的重点。数据可以从1~65535个。
直接存储器存取(Direct Memory Access,DMA)是计算机科学中的一种内存访问技术。它允许某些电脑内部的硬体子系统(电脑外设),可以独立地直接读写系统存储器,而不需绕道 CPU。在同等程度的CPU负担下,DMA是一种快速的数据传送方式。它允许不同速度的硬件装置来沟通,而不需要依于 CPU的大量中断请求。【摘自Wikipedia】
现在越来越多的单片机采用DMA技术,提供外设和存储器之间或者存储器之间的高速数据传输。当 CPU 初始化这个传输动作,传输动作本身是由&DMA 控制器&来实行和完成。STM32就有一个DMA控制器,它有7个通道,每个通道专门用来管理一个或多个外设对存储器访问的请求,还有一个仲裁器来协调各个DMA请求的优先权。
DMA 控制器和Cortex-M3核共享系统数据总线执行直接存储器数据传输。当CPU和DMA同时访问相同的目标(RAM或外设)时,DMA请求可能会停止 CPU访问系统总线达若干个周期,总线仲裁器执行循环调度,以保证CPU至少可以得到一半的系统总线(存储器或外设)带宽。
在发生一个事件后,外设发送一个请求信号到DMA控制器。DMA控制器根据通道的优先权处理请求。当DMA控制器开始访问外设的时候,DMA控制器立即发送给外设一个应答信号。当从DMA控制器得到应答信号时,外设立即释放它的请求。一旦外设释放了这个请求,DMA控制器同时撤销应答信号。如果发生更多的请求时,外设可以启动下次处理。
总之,每个DMA传送由3个操作组成:
1. 从外设数据寄存器或者从DMA_CMARx寄存器指定地址的存储器单元执行加载操作。
2. 存数据到外设数据寄存器或者存数据到DMA_CMARx寄存器指定地址的存储器单元。
3. 执行一次DMA_CNDTRx寄存器的递减操作。该寄存器包含未完成的操作数目。
仲裁器根据通道请求的优先级来启动外设/存储器的访问。优先级分为两个等级:软件(4个等级:最高、高、中等、低)、硬件(有较低编号的通道比拥有较高编号的通道有较高的优先权)。
可以在DMA传输过半、传输完成和传输错误时产生中断。
STM32中DMA的不同中断(传输完成、半传输、传输完成)通过&线或&方式连接至NVIC,需要在中断例程中进行判断。
进行DMA配置前,不要忘了在RCC设置中使能DMA时钟。STM32的DMA控制器挂在AHB总线上。
DMA总共有7个通道,各个通道的DMA映射关系如下:
外设的事件连接至相应DMA通道,每个通道均可以通过软件触发实现存储器内部的DMA数据传输(M2M模式)
Tips:库2.0中函数RCC_AHBPeriphClockCmd的参数由&RCC_AHBPeriph_DMA&改成&RCC_AHBPeriph_DMA1&(如果是DMA1控制器的话)。
DMA的传输标志位(CHTIFx、CTCIFx、CGIFx)由硬件设置为&1&,但需要软件清零,在中断服务程序中清除。当CGIFx(全局中断标志位)清零后,CHTIFx 和 CTCIFx均清零。
过程:怎样启用DMA?首先,众所周知的是初始化,任何设备启用前都要对其进行初始化,要对模块初始化,还要先了解该模块相应的结构及其函数,以便正确的设置;由于DMA较为复杂,我就只谈谈DMA的基本结构和和常用函数,这些都是ST公司提供在库函数中的。
1、 下面代码是一个标准DMA设置,当然实际应用中可根据实际情况进行裁减:
DMA_DeInit(DMA_Channel1);
上面这句是给DMA配置通道,根据ST提供的资料,STM3210Fx中DMA包含7个通道(CH1~CH7),也就是说可以为外设或memory提供7座&桥梁&(请允许我使用桥梁一词,我觉得更容易理解,哈哈,别&拍砖&呀!);
DMA_InitStructure.DMA_PeripheralBaseAddr = ADC1_DR_A
上面语句中的DMA_InitStructure是一个DMA结构体,在库中有声明了,当然使用时就要先定义了;DMA_PeripheralBaseAddr是该结构体中一个数据成员,给DMA一个起始地址,好比是一个buffer起始地址,数据流程是:外设寄存器& DMA_PeripheralBaseAdd&memory中变量空间(或flash中数据空间等),ADC1_DR_Address是我定义的一个地址变量;
DMA_InitStructure.DMA_MemoryBaseAddr = (u32)ADC_ConvertedV
上面这句很显然是DMA要连接在Memory中变量的地址,ADC_ConvertedValue是我自己在memory中定义的一个变量;
DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralSRC;
上面的这句是设置DMA的传输方向,就如前面我所说的,DMA可以双向传输,也可以单向传输,这里设置的是单向传输,如果需要双向传输:把DMA_DIR_PeripheralSRC改成DMA_DIR_PeripheralDST即可。
DMA_InitStructure.DMA_BufferSize = 2;
上面的这句是设置DMA在传输时缓冲区的长度,前面有定义过了buffer的起始地址:ADC1_DR_Address ,为了安全性和可靠性,一般需要给buffer定义一个储存片区,这个参数的单位有三种类型:Byte、HalfWord、word,我设置的2个half-word(见下面的设置);32位的MCU中1个half-word占16 bits。
DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_D
上面的这句是设置DMA的外设递增模式,如果DMA选用的通道(CHx)有多个外设连接,需要使用外设递增模式:DMA_PeripheralInc_E我的例子里DMA只与ADC1建立了联系,所以选用DMA_PeripheralInc_Disable
DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_E
上面的这句是设置DMA的内存递增模式,DMA访问多个内存参数时,需要使用DMA_MemoryInc_Enable,当DMA只访问一个内存参数时,可设置成:DMA_MemoryInc_Disable。
DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_HalfW
上面的这句是设置DMA在访问时每次操作的数据长度。有三种数据长度类型,前面已经讲过了,这里不在叙述。
DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_HalfW
与上面雷同。在此不再说明。
DMA_InitStructure.DMA_Mode = DMA_Mode_C
上面的这句是设置DMA的传输模式:连续不断的循环模式,若只想访问一次后就不要访问了(或按指令操作来反问,也就是想要它访问的时候就访问,不要它访问的时候就停止),可以设置成通用模式:DMA_Mode_Normal
DMA_InitStructure.DMA_Priority = DMA_Priority_H
上面的这句是设置DMA的优先级别:可以分为4级:VeryHigh,High,Medium,Low.
DMA_InitStructure.DMA_M2M = DMA_M2M_D
上面的这句是设置DMA的2个memory中的变量互相访问的
DMA_Init(DMA_Channel1,&DMA_InitStructure);
前面那些都是对DMA结构体成员的设置,在次再统一对DMA整个模块做一次初始化,使得DMA各成员与上面的参数一致。
/*DMA Enable*/
DMA_Cmd(DMA_Channel1,ENABLE);
哈哈哈!这一句我想我就不罗嗦了,大家一看就明白。
至此,整个DMA总算设置好了,但是,DMA通道又是怎样与外设联系在一起的呢?哈哈,这也是我当初最想知道的一个事情,别急!容我想喝口茶~~~~~~哈哈哈!
要使DMA与外设建立有效连接,这不是DMA自身的事情,是各个外设的事情,每个外设都有 一个xxx_DMACmd(XXXx,Enable )函数,如果使DMA与ADC建立有效联系,就使用ADC_DMACmd(ADC1,Enable); (这里我启用了ADC中的ADC1模块)。
一个简单的例子 transfer& a word data buffer from FLASH memory to embedded SRAM memory.在V3.1.2库的位置STM32F10x_StdPeriph_Lib_V3.1.2\Project\STM32F10x_StdPeriph_Examples\DMA\FLASH_RAM/* DMA1 channel6 configuration */DMA_DeInit(DMA1_Channel6);& //peripheral base addressDMA_InitStructure.DMA_PeripheralBaseAddr = (uint32_t)SRC_Const_B& //memory base address&&&DMA_InitStructure.DMA_MemoryBaseAddr = (uint32_t)DST_B& //数据传输方向&&& Peripheral is source &&& &&& &&& &&DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralSRC;//缓冲区大小 Number of data to be transferred (0 up to 65535).数据传输数目&&& &DMA_InitStructure.DMA_BufferSize = BufferS&& // the Peripheral address register is incremented&&& &&&DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_E& //the memory address register is incrementedDMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_E//the Peripheral data width&&& &&&DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_W&DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_WDMA_InitStructure.DMA_Mode = DMA_Mode_NDMA_InitStructure.DMA_Priority = DMA_Priority_H//the DMAy Channelx will be used in memory-to-memory transfer//DMA通道的操作可以在没有外设请求的情况下进行,这种操作就是存储器到存储器模式。DMA_InitStructure.DMA_M2M = DMA_M2M_E&&&DMA_Init(DMA1_Channel6, &DMA_InitStructure);/* Enable DMA1 Channel6 Transfer Complete interrupt */DMA_ITConfig(DMA1_Channel6, DMA_IT_TC, ENABLE);/* Enable DMA1 Channel6 transfer */DMA_Cmd(DMA1_Channel6, ENABLE);=======================================================================外设的DMA请求映像要使DMA与外设建立有效连接,这不是DMA自身的事情,是各个外设的事情,每个外设都有 一个xxx_DMACmd(XXXx,Enable )函数,如果使DMA与ADC建立有效联系,就使用 ADC_DMACmd(ADC1,Enable); (这里我启用了ADC中的ADC1模块)。/* DMA1 channel1 configuration ----------------------------------------------*/DMA_DeInit(DMA1_Channel1);DMA_InitStructure.DMA_PeripheralBaseAddr = ADC1_DR_ADMA_InitStructure.DMA_MemoryBaseAddr = (uint32_t)&AD_V&&&//u16& AD_Value[2];&& 不加&应该也可以& 数组名 代表地址DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralSRC;DMA_InitStructure.DMA_BufferSize = 2;&&& & //############## 改了DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_DDMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_E& //##############&&& &改了DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_HalfWDMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_HalfWDMA_InitStructure.DMA_Mode = DMA_Mode_CDMA_InitStructure.DMA_Priority = DMA_Priority_HDMA_InitStructure.DMA_M2M = DMA_M2M_DDMA_Init(DMA1_Channel1, &DMA_InitStructure);/* Enable DMA1 channel 1 */DMA_Cmd(DMA1_Channel1, ENABLE);/* ADC1 configuration&------------------------------------------------------*/ADC_InitStructure.ADC_Mode = ADC_Mode_IADC_InitStructure.ADC_ScanConvMode = ENABLE;ADC_InitStructure.ADC_ContinuousConvMode = ENABLE;ADC_InitStructure.ADC_ExternalTrigConv = ADC_ExternalTrigConv_NADC_InitStructure.ADC_DataAlign = ADC_DataAlign_RADC_InitStructure.ADC_NbrOfChannel = 2;&&& & //##############&&& &改了ADC_Init(ADC1, &ADC_InitStructure);//内部温度传感器& 添加这一句&/* Enable the temperature sensor and vref internal channel */ADC_TempSensorVrefintCmd(ENABLE);//##############&&& &改了//################ Channel 10(电位器)ADC_RegularChannelConfig(ADC1, ADC_Channel_10, 1, ADC_SampleTime_13Cycles5);//###### 内部温度传感器& Channel 16 ###################ADC_RegularChannelConfig(ADC1, ADC_Channel_16, 2, ADC_SampleTime_55Cycles5);& /* Enable ADC1 DMA */使能ADC1的DMA请求映像& ADC_DMACmd(ADC1, ENABLE);/* Enable ADC1 */ADC_Cmd(ADC1, ENABLE);/* Enable ADC1 reset calibaration register */&& //使用之前一定要校准ADC_ResetCalibration(ADC1);/* Check the end of ADC1 reset calibration register */while(ADC_GetResetCalibrationStatus(ADC1));/* Start ADC1 calibaration */ADC_StartCalibration(ADC1);/* Check the end of ADC1 calibration */while(ADC_GetCalibrationStatus(ADC1));/* Start ADC1 Software Conversion */&ADC_SoftwareStartConvCmd(ADC1, ENABLE);
阅读(...) 评论()网站已改版,请使用新地址访问:
DMAtest 基于STM32单片机的DAM串口通信实验,传输成功后将 提示信息 ARM-PowerPC-ColdFire-MIPS 微处理器开发 238万源代码下载- www.pudn.com
&文件名称: DMAtest
& & & & &&]
&&所属分类:
&&开发工具: C-C++
&&文件大小: 70 KB
&&上传时间:
&&下载次数: 13
&&提 供 者:
&详细说明:基于STM32单片机的DAM串口通信实验,传输成功后将会有提示信息-STM32 MCU the DAM serial communication experiment, the transmission success will be followed by message
文件列表(点击判断是否您需要的文件,如果是垃圾请在下面评价投诉):
&&【21】DMA串口实验\HARDWARE\ADC\adc.c&&.................\........\...\adc.h&&.................\........\DMA\dma.c&&.................\........\...\dma.h&&.................\........\EXTI\exti.c&&.................\........\....\exti.h&&.................\........\KEY\key.c&&.................\........\...\key.h&&.................\........\LCD\FONT.H&&.................\........\...\ILI93xx.c&&.................\........\...\LCD.h&&.................\........\.ED\led.c&&.................\........\...\led.h&&.................\........\OLED\FONT.H&&.................\........\....\oled.c&&.................\........\....\oled.h&&.................\........\RTC\rtc.c&&.................\........\...\rtc.h&&.................\........\TIMER\timer.c&&.................\........\.....\timer.h&&.................\........\WDG\wdg.c&&.................\........\...\wdg.h&&.................\........\.KUP\wkup.c&&.................\........\....\wkup.h&&.................\SYSTEM\delay\delay.c&&.................\......\.....\delay.h&&.................\......\sys\sys.c&&.................\......\...\sys.h&&.................\......\usart\usart.c&&.................\......\.....\usart.h&&.................\USER\List\STM32F10x.lst&&.................\....\....\TEST.map&&.................\....\OBJ\TEST.plg&&.................\....\STM32F10x.s&&.................\....\test.c&&.................\....\TEST.plg&&.................\....\TEST.uvopt&&.................\....\TEST.uvproj&&.................\....\TEST_Target 1.dep&&.................\....\TEST_uvopt.bak&&.................\....\TEST_uvproj.bak&&.................\HARDWARE\ADC&&.................\........\DMA&&.................\........\EXTI&&.................\........\KEY&&.................\........\LCD&&.................\........\LED&&.................\........\OLED&&.................\........\RTC&&.................\........\TIMER&&.................\........\WDG&&.................\........\WKUP&&.................\SYSTEM\delay&&.................\......\sys&&.................\......\usart&&.................\USER\List&&.................\....\OBJ&&.................\HARDWARE&&.................\SYSTEM&&.................\USER&&【21】DMA串口实验
&相关搜索:
&输入关键字,在本站238万海量源码库中尽情搜索:
&[] - STM32 DAM配置例程,适用STM32各种芯片,详细的介绍了 DAM的配置过程。根据例子修改即可应用。
&[] - tic tac toe game, with server and clients. It also supports multiple pair of games at the same time, on the server.没有更多推荐了,
加入CSDN,享受更精准的内容推荐,与500万程序员共同成长!不用库函数自己动手配置STM32中的DMA
> 不用库函数自己动手配置STM32中的DMA
不用库函数自己动手配置STM32中的DMA
今天调试的STM32的DMA部分,第一次接触这部分,8位的单片机没有这部分的功能,一开始感觉这东西很神秘,所以怀着敬畏的心情来学习它。慢慢的发现这确实是个好东西,功能强大,可以分担CPU的任务。但它没有想象中那么棘手。DMA英文全称是Direct Memory Access,意思是直接存储器访问。他的作用就是不需要经过CUP进行数据传输,也就是替CPU分担点事情做,什么事情?数据传输方面的事情。也就是说,你只要使能并配置好了DMA,DMA就可以将一批数据从源地址搬运到目的地址去而不经过CPU的干预,这样可以为CPU节省好多精力去干更重要的事情很人性化。就像我们人一样,我们平常习惯性的动作是不用经过大脑思考的,比如说眨眼睛,呼吸等。DMA就是负责这些工作的,但它没人这么智能,需要将它设置好了它才会正常工作。本文引用地址:要进行数据传输就必须有两个条件:数据从哪传(源地址),数据传到哪里去(目的地址)。是的DMA的确有这两项设置,通过软件设置,设置好源地址和目的地址。在一个重要的条件就是触发源是什么,就是说什么时候进行DMA数据传输呢?这叫触发信号。也可以通过软件编程设置具体时间,具体条件来触发DMA数据传输。总之,要使用DMA就要将各种参数,条件配置好才可以用。就提的DMA寄存器说明见STM32的参考手册。下面举一简单的历程来说明DMA的用法,本历程将串口数据发送设置为DMA模式,串口1将持续从RAM中的一段连续的地址中取数据,然后发送出去。用串口调试助手可以监测DMA的工作和CPU互不冲突,串口发送就相当于后台运行的一段程序。具体配置如下:寄存器定义://*************************************************************************//// DMA-Register////*************************************************************************#define DMA_ISR(*((volatile unsigned long *)0x)) //中断状态寄存器#define DMA_IFCR(*((volatile unsigned long *)0x))//中断标志清零寄存器#define DMA_CCR1(*((volatile unsigned long *)0x))//通道1配置寄存器#define DMA_CCR2(*((volatile unsigned long *)0x4002001C))//通道2配置寄存器#define DMA_CCR3(*((volatile unsigned long *)0x))//通道3配置寄存器#define DMA_CCR4(*((volatile unsigned long *)0x))//通道4配置寄存器#define DMA_CCR5(*((volatile unsigned long *)0x))//通道5配置寄存器#define DMA_CCR6(*((volatile unsigned long *)0x4002006C))//通道6配置寄存器#define DMA_CCR7(*((volatile unsigned long *)0x))//通道7配置寄存器#define DMA_CNDTR1(*((volatile unsigned long *)0x4002000C))//通道1传输数量寄存器#define DMA_CNDTR2(*((volatile unsigned long *)0x))//通道2传输数量寄存器#define DMA_CNDTR3(*((volatile unsigned long *)0x))//通道3传输数量寄存器#define DMA_CNDTR4(*((volatile unsigned long *)0x))//通道4传输数量寄存器#define DMA_CNDTR5(*((volatile unsigned long *)0x4002005C))//通道5传输数量寄存器#define DMA_CNDTR6(*((volatile unsigned long *)0x))//通道6传输数量寄存器#define DMA_CNDTR7(*((volatile unsigned long *)0x))//通道7传输数量寄存器#define DMA_CPAR1(*((volatile unsigned long *)0x))//通道1外设地址寄存器#define DMA_CPAR2(*((volatile unsigned long *)0x))//通道2外设地址寄存器#define DMA_CPAR3(*((volatile unsigned long *)0x))//通道3外设地址寄存器#define DMA_CPAR4(*((volatile unsigned long *)0x4002004C))//通道4外设地址寄存器#define DMA_CPAR5(*((volatile unsigned long *)0x))//通道5外设地址寄存器#define DMA_CPAR6(*((volatile unsigned long *)0x))//通道6外设地址寄存器#define DMA_CPAR7(*((volatile unsigned long *)0x))//通道7外设地址寄存器#define DMA_CMAR1(*((volatile unsigned long *)0x))//通道1存储器地址寄存器#define DMA_CMAR2(*((volatile unsigned long *)0x))//通道2存储器地址寄存器#define DMA_CMAR3(*((volatile unsigned long *)0x4002003C))//通道3存储器地址寄存器#define DMA_CMAR4(*((volatile unsigned long *)0x))//通道4存储器地址寄存器#define DMA_CMAR5(*((volatile unsigned long *)0x))//通道5存储器地址寄存器#define DMA_CMAR6(*((volatile unsigned long *)0x))//通道6存储器地址寄存器#define DMA_CMAR7(*((volatile unsigned long *)0x4002008C))//通道7存储器地址寄存器配置DMA,手册上表示可以将串口UART1的发送Tx功能配置为DMA发送,在DMA通道4:void DMA_configration(void){//DMA设置://设置DMA源:内存地址&串口数据寄存器地址//方向:内存-->外设//每次传输位:8bit//传输大小:10字节//地址自增模式:外设地址不增,内存地址自增1//DMA模式:循环//优先级:高RCC_AHBENR|=0x; //位0 DMAEN DMA时钟使能DMA_CCR4&=0xFFFF800E;//0:通道禁用DMA_CPAR4=(unsigned long)&USART1_DR;DMA_CMAR4=(unsigned long)Data_BDMA_CNDTR4=10;DMA_CCR4=0x;DMA_CCR4|=0x;//DMA_CCR4|=0x;//DMA使能}Main函数:unsigned char Data_Buffer[10]={0x11,0x22,0x33,0x44,0x55};//将Data_Buffer设为全局变量。int main(){SystemInit0();//系统(时钟)初始化stm32_UsartSetup ();//串口初始化,前面的文章中有介绍DMA_configration();// DMA配置USART1_CR3|=0x; //将USART1模块发送数据Tx设置成DMA方式工作DMA_CCR4|=0x; //使能DMAwhile(1){//CPU可以不受打扰的做其他事情}}打开串口助手就可以看到Data_Buffer[]中的数据,其实这只是一个简单的演示实例,DMA的用处是很大的,先学会配置,以后会有它大显身手的时候。USART1_CR3|=0x; //将USART1模块发送数据Tx设置成DMA方式工作DMA_CCR4|=0x; //使能DMA上面这两句就是触发源,你可以把这两句放到定时器TIMx中,比如定时1S触发DMA,这些都是可以任意设置的,不难吧!
分享给小伙伴们:
我来说两句……
微信公众号二
微信公众号一您所在位置: &
&nbsp&&nbsp&nbsp&&nbsp
第8章MSP430单片机片内控制模块要点解读.pptx 46页
本文档一共被下载:
次 ,您可全文免费在线阅读后下载本文档。
下载提示
1.本站不保证该用户上传的文档完整性,不预览、不比对内容而直接下载产生的反悔问题本站不予受理。
2.该文档所得收入(下载+内容+预览三)归上传者、原创者。
3.登录后可充值,立即自动返金币,充值渠道很便利
你可能关注的文档:
·····
·······
合肥工业大学DSP及MSP430实验室;第八章 MSP430单片机片内控制模块;8.1 Flash控制器;;;(1)擦除周期
对需要擦除的段地址范围内执行一次空写操作(写入0)将启动一次擦除,擦除周期时序如图8.1.3所示。擦除开始时,Flash控制器需要产生适当的时序信号和正确的编程电压,然后由时序发生器控制整个擦除过程,擦除完毕,编程电压撤销。注意:在空写后(擦除开始后),BUSY标志位立即置位,并且在整个擦除周期内保持置位,当擦除完成后BUSY、MERAS和ERASE标志位自动清除。;(2)擦除各存储器方式
主存储器包含一个或多个扇区,每个扇区可以采用扇区擦除模式进行单独擦除,也可以通过块擦除模式擦除主存储器下的所有扇区。
信息存储段A~D及BSL引导装载程序段A~D只可采用段擦除模式擦除,若采用扇区擦除或块擦除模式,将不能擦除这些存储器。
(3)擦除操作编程步骤
MSP430单片机的Flash存储器的擦除操作可以从Flash中启动,也可以从RAM中启动(即擦除操作指令执行所在空间)。当从Flash中启动擦除操作时,被执行的代码不能存放在需要擦除的扇区中,在擦除期间,CPU会停止运行且状态保持不变,擦除完毕后,CPU才会恢复活动状态,继续执行程序代码。但是,从RAM中启动擦除工作时,CPU不会停止运行,能继续执行存储在RAM中的程序代码,BUSY忙标志位用于判断擦除周期是否结束。在CPU访问任何Flash地址时,必须保证擦除周期完成,即BUSY=0,否则对Flash的访问操作将是非法的,ACCVIFG(非法访问中断标志位)置位,且擦除结果是不确定的。MSP430单片机的程序存储空间可通过CCS工程文件下的CMD文件进行更改,默认情况下存放在Flash中,一般情况下在执行程序时直接从Flash中取指令。有时为了加快程序执行速度或进行目标段Flash擦写时,也可将程序从Flash中搬到RAM中执行。但是,在RAM中执行的指令掉电后会消失。 ;【例8.1.1】 编写擦除单段数据的函数。;2. Flash存储器写操作;【例8.1.2】 编写向目的地址写入1字节的函数。;【例8.1.3】 编写程序向Flash信息存储器D段写入一个长字。;(2)长字块写入模式
当有许多连续的字节或字需要编程写入时,长字块写入模式能够提高Flash的写入速度。长字块写入模式周期时序图如图8.1.5所示。长字块写入模式不能从Flash存储器中启动,只能从RAM中启动。在整个块写入的过程中,BUSY忙标志位置位。以一个长字(4字节)为单位地写入,每个长字之间必须检查WAIT标志位,当WAIT标志位置位时,表示已完成前一个长字的写入,可以写入后一个长字。在当前块数据写完之后,BLKWRT控制位必须清零,且在一个块的写入之前必须置位。当BUSY标志位清零后,表示当前块已完成写入操作,可以对下一块执行写入操作。;3. Flash控制器中断
Flash控制器有两个中断源:KEYV和ACCVIFG。
当产生非法访问时,ACCVIFG标志位置位。当Flash写入或擦除操作之后,使能ACCVIE控制位时,ACCVIFG标志位将产生中断请求,ACCVIE控制位位于特殊功能寄存器SFRIE1内,且ACCVIFG标志位来源于不可屏蔽中断(NMI)向量,所以当ACCVIFG请求中断时,GIE控制位无须置位。
当利用错误的密码配置Flash控制器寄存器时,将置位KEYV密钥错误标志位,此时将立即产生PUC复位信号,系统将会被复位。;4. Flash存储器编程方法
对MSP430 Flash型单片机有3种烧写程序的方法:通过JTAG接口编程、通过BSL引导加载程序编程和通过用户自定义方式编程,所有方式都支持在线编程。
MSP430单片机CPU对Flash存储器的在线和外部用户自定义写入方式如图8.1.6所示。用户可以选择通过UART、SPI等方式进行编程。用户可以自行开发软件用于接收数据或对Flash存储器进行编程。由于这种编程方式是由用户定义开发的,所以它完全能够用户化,从而符合用户编程、擦除或者更新Flash存储器的实际应用需求。
;;;//写信息段C函数
void write_SegC(char value)
{
;//将信息段C的内容复制到信息段D内
void copy_C2D(void)
{
char *Flash_ptrC;
char *Flash_ptrD;
Flash_ptrC = (char *) 0x1880;
// 初始化信息段C指针
Flash_ptrD = (char *) 0x1800;
// 初始化信息段D指针
FCTL3 = FWKE
正在加载中,请稍后...

我要回帖

更多关于 正在检查目标单片机 的文章

 

随机推荐