第十五章 DMA
单芯片处理计划,开启齐新体验——W55MH32 下功能以太网单片机
W55MH32是WIZnet重磅推出的下功能以太网单片机,它为用户带去史无前例的散成化体验。那颗芯片将弱小的组件散于一身,详细来讲,一颗W55MH32内置下功能Arm® Cortex-M3中心,其主频最下可达216MHz;装备1024KB FLASH取96KB SRAM,知足存储取数据处置需供;散成TOE引擎,包括WIZnet齐硬件TCP/IP和谈栈、内置MAC和PHY,具有自力的32KB以太网支收缓存,可供8个自力硬件socket运用。如斯设置装备摆设,实正完成了All-in-One处理计划,为开辟者供给极年夜便当。
正在启拆规格上,W55MH32 供给了两种挑选:QFN100战QFN68。
W55MH32L采取QFN100启拆版本,尺寸为12x12mm,其资本丰厚,专为各类庞大工控场景设想。它具有66个GPIO、3个ADC、12通讲DMA、17个按时器、2个I2C、5个串心、2个SPI接心(此中1个带I2S接心复用)、1个CAN、1个USB2.0和1个SDIO接心。如斯丰厚的中设资本,可以沉紧应对产业节制中多样化的衔接需供,不管是取各种传感器、履行器的通讯,仍是对庞大产业和谈的撑持,皆能熟能生巧,成为庞大工控范畴的抱负挑选。 同系列借有QFN68启拆的W55MH32Q版本,该版本体积更小,仅为8x8mm,本钱低,合适散成度下的网闭模组等场景,硬件运用办法分歧。更多疑息战材料请进进http://www.w5500.com/网站或许公疑获得。
另外,本W55MH32撑持硬件减稀算法单位,WIZnet借推出TOE+SSL使用,涵盖TCP SSL、HTTP SSL和 MQTT SSL等,为收集通讯平安再加保证。
为助力开辟者疾速上脚取深化开辟,基于W55MH32L那颗芯片,WIZnet粗心挨制了配套开辟板。开辟板散成WIZ-Link芯片,借助一根USB C心数据线,就可以沉紧完成调试、下载和串心挨印日记等功用。开辟板将一切中设全数引出,拓展功用也年夜幅晋升,便于开辟者片面评价芯片功能。
若您念获得芯片战开辟板的更多具体疑息,包罗产物特征、手艺参数和价钱等,欢送拜访民圆网页:http://www.w5500.com/,我们等待取您配合探究W55MH32的有限能够。
第十五章 DMA
本章参考材料:《W55MH32中文参考脚册》DMA节制器章节。
进修本章时,共同《W55MH32中文参考脚册》DMA节制器章节一同浏览,结果会更佳,特殊是触及到存放器阐明的局部。
1 DMA简介
DMA(Direct Memory Access)—间接存储器存与,是单片机的一个中设,它的次要功用是用去搬数据,可是没有需求占用CPU, 即正在传输数据的时分,CPU能够干其他的工作,仿佛是多线程一样。数据传输撑持从中设到存储器或许存储器到存储器, 那里的存储器能够是SRAM或许是FLASH。DMA节制器包括了DMA1战DMA2,此中DMA1有7个通讲,DMA2有5个通讲, 那里的通讲能够了解为传输数据的一种管讲。要留意的是DMA2只存正在于年夜容量产物战互联型产物中。
2 DMA功用框图
DMA节制器自力于内核,属于一个独自的中设,构造比拟复杂,从编程的角度去看,我们只需把握功用框图中的三局部内容便可, 详细睹下图,DMA框图 :DMA节制器的框图:
2.1 DMA恳求
假如中设要念经过DMA去传输数据,必需先给DMA节制器收收DMA恳求,DMA支到恳求旌旗灯号以后,节制器会给中设一个应对旌旗灯号, 当中设应对后且DMA节制器支到应对旌旗灯号以后,便会启动DMA的传输,曲到传输终了。
DMA有DMA1战DMA2两个节制器,DMA1有7个通讲,DMA2有5个通讲,分歧的DMA节制器的通讲对应着分歧的中设恳求, 那决议了我们正在硬件编程上该怎样设置,详细睹DMA恳求映像表:
中设 | 通讲 1 | 通讲 2 | 通讲 3 | 通讲 4 | 通讲 5 | 通讲 6 | 通讲 7 |
ADC1 | ADC1 | ||||||
SPI/I²S | SPI1_RX | SPI1_TX | SPI/I2S2_RX | SPI/I2S2_TX | |||
USART | USART3_TX | USART3_RX | USART1_TX | USART1_RX | USART2_RX | USART2_TX | |
I²C | I2C2_TX | I2C2_RX | I2C1_TX | I2C1_RX | |||
TIM1 | TIM1_CH1 | TIM1_CH2 |
TIM1_TX4 TIM1_TRIG TIM1_COM |
TIM1_UP | TIM1_CH3 | ||
TIM2 | TIM2_CH3 | TIM2_UP | TIM2_CH1 |
TIM2_CH2 TIM2_CH4 |
|||
TIM3 | TIM3_CH3 |
TIM3_CH4 TIM3_UP |
TIM3_CH1 TIM3_TRIG |
||||
TIM4 | TIM4_CH1 | TIM4_CH2 | TIM4_CH3 | TIM4_UP |
中设 | 通讲 1 | 通讲 2 | 通讲 3 | 通讲 4 | 通讲 5 |
ADC3⁽¹⁾ | ADC3 | ||||
SPI/I²S3 | SPI/I²S3_RX | SPI/I²S3_TX | |||
UART4 | UART4_RX | UART4_TX | |||
SDIO⁽¹⁾ | SDIO | ||||
TIM5 |
TIM5_CH4 TIM5_TRIG |
TIM5_CH3 TIM5_UP |
TIM5_CH2 | TIM5_CH1 | |
TIM6/DAC 通讲 1 |
TIM6_UP/ DAC 通讲 1 |
||||
TIM7/DAC 通讲 2 |
TIM7_UP/ DAC 通讲 2 |
||||
TIM8⁽¹⁾ |
TIM8_CH3 TIM8_UP |
TIM8_CH4 TIM8_TRIG TIM8_COM |
TIM8_CH1 | TIM8_CH2 |
此中ADC3、SDIO战TIM8的DMA恳求只正在年夜容量产物中存正在,那个正在详细项目时要留意。
2.2 通讲
DMA具有12个自力可编程的通讲,此中DMA1有7个通讲,DMA2有5个通讲,每一个通讲对应分歧的中设的DMA恳求。 固然每一个通讲能够接纳多个中设的恳求,可是统一工夫只能接纳一个,不克不及同时接纳多个。
2.3 仲裁器
当发作多个DMA通讲恳求时,便意味着有前后呼应处置的挨次成绩,那个便由仲裁器也治理。仲裁器治理DMA通讲恳求分为两个阶段。 第一阶段属于硬件阶段,能够正在DMA_CCRx存放器中设置,有4个品级:十分下、下、中战低四个劣先级。第两阶段属于硬件阶段, 假如两个或以上的DMA通讲恳求设置的劣先级一样,则他们劣先级与决于通讲编号,编号越低劣先权越下,比方通讲0下于通讲1。 正在年夜容量产物战互联型产物中, DMA1节制器具有下于DMA2节制器的劣先级。
3 DMA数据设置装备摆设
运用DMA,最中心便是设置装备摆设要传输的数据,包罗数据从那里去,要到那里来,传输的数据的单元是甚么,要传几多数据,是一次传输仍是轮回传输等等。
3.1DMA传输标的目的
我们晓得DMA传输数据的标的目的有三个:从中设到存储器,从存储器到中设,从存储器到存储器。 详细的标的目的DMA_CCR位4 DIR设置装备摆设:0暗示从中设到存储器,1暗示从存储器到中设。 那外面触及到的中设地点由DMA_CPAR设置装备摆设,存储器地点由DMA_CMAR设置装备摆设。
中设到存储器
当我们运用从中设到存储器传输时,以ADC收集为例。DMA中设存放器的地点对应的便是ADC数据存放器的地点, DMA存储器的地点便是我们自界说的变量(用去接纳存储AD收集的数据)的地点。标的目的我们设置中设为源地点。
存储器到中设
当我们运用从存储器到中设传输时,以串心背电脑端收收数据为例。DMA中设存放器的地点对应的便是串心数据存放器的地点, DMA存储器的地点便是我们自界说的变量(相称于一个缓冲区,用去存储经过串心收收到电脑的数据)的地点。标的目的我们设置中设为目的地点。
存储器到存储器
当我们运用从存储器到存储器传输时,之内部FLASH背外部SRAM复造数据为例。 DMA中设存放器的地点对应的便是外部FLASH(我们那里把外部FALSH看成一个中设去看)的地点, DMA存储器的地点便是我们自界说的变量(相称于一个缓冲区,用去存储去自外部FLASH的数据)的地点。 标的目的我们设置中设(即外部FLASH)为源地点。跟下面两个纷歧样的是,那里需求把DMA_CCR位14:MEM2MEM:存储器到存储器形式设置装备摆设为1,启动M2M形式。
3.2传输巨细及单元
当我们设置装备摆设好数据要从那里离开那里来以后,我们借需求晓得我们要传输的数据是几多,数据的单元是甚么。
以串心背电脑收收数据为例,我们能够一次性给电脑收收良多数据,详细几多由DMA_CNDTR设置装备摆设, 那是一个32位的存放器,一次最多只能传输65535个数据。
要念数据传输准确,源战目的地点存储的数据宽度借必需分歧,串心数据存放器是8位的, 以是我们界说的要收收的数据也必需是8位。中设的数据宽度由DMA_CCRx的PSIZE[1:0]设置装备摆设, 能够是8/16/32位,存储器的数据宽度由DMA_CCRx的MSIZE[1:0]设置装备摆设,能够是8/16/32位。
正在DMA节制器的节制下,数据要念杂乱无章的从一个中央搬到别的一个中央,借必需准确设置双方数据指针的删量形式。 中设的地点指针由DMA_CCRx的PINC设置装备摆设,存储器的地点指针由MINC设置装备摆设。以串心背电脑收收数据为例,要收收的数据良多, 每收收完一个,那末存储器的地点指针便应当减1,而串心数据存放器只要一个, 那末中设的地点指针便牢固稳定。详细的数据指针的删量形式由实践状况决议。
3.3 传输完成工夫
数据甚么时分传输完成,我们能够经过查询标记位或许经过中缀的体例去辨别。每一个DMA通讲正在DMA传输过半、 传输完成战传输毛病时城市有响应的标记位,假如使能了该范例的中缀后,则会发生中缀。有闭各个标记位的具体描绘请参考DMA中缀形态存放器DMA_ISR的具体描绘。
传输完成借分两种形式,是一次传输仍是轮回传输,一次传输很好了解,便是传输一次以后便中止,要念再传输的话, 必需闭断DMA使能后再从头设置装备摆设后才干持续传输。轮回传输则是一次传输完成以后又规复第一次传输时的设置装备摆设轮回传输, 不时的反复。详细的由DMA_CCRx存放器的CIRC 轮回形式位节制。
4 DMA初初化构造体详解
规范库函数对每一个中设皆树立了一个初初化构造体xxx_InitTypeDef(xxx为中设称号),构造体成员用于设置中设任务参数, 并由规范库函数xxx_Init()挪用那些设定参数进进设置中设响应的存放器,到达设置装备摆设中设任务情况的目标。
构造体xxx_InitTypeDef战库函数xxx_Init共同运用是规范库精华地点,了解了却构体xxx_InitTypeDef每一个成员意义根本上便可以对该中设应用自若。 构造体xxx_InitTypeDef界说正在W55MH32_xxx.h(前面xxx为中设称号)文件中,库函数xxx_Init界说正在W55MH32_xxx.c文件中, 编程时我们能够连系那两个文件内正文运用。
DMA_ InitTypeDef初初化构造体
typedef struct { uint32_t DMA_PeripheralBaseAddr; // 中设地点 uint32_t DMA_MemoryBaseAddr; // 存储器地点 uint32_t DMA_DIR; // 传输标的目的 uint32_t DMA_BufferSize; // 传输数量 uint32_t DMA_PeripheralInc; // 中设地点删量形式 uint32_t DMA_MemoryInc; // 存储器地点删量形式 uint32_t DMA_PeripheralDataSize; // 中设数据宽度 uint32_t DMA_MemoryDataSize; // 存储器数据宽度 uint32_t DMA_Mode; // 形式挑选 uint32_t DMA_Priority; // 通讲劣先级 uint32_t DMA_M2M; // 存储器到存储器形式 } DMA_InitTypeDef;
DMA_PeripheralBaseAddr: 中设地点,设定DMA_CPAR存放器的值;普通设置为中设的数据存放器地点,假如是存储器到存储器形式则设置为此中一个存储器地点。
DMA_Memory0BaseAddr: 存储器地点,设定DMA_CMAR存放器值;普通设置为我们自界说存储区的尾地点。
DMA_DIR: 传输标的目的挑选,可选中设到存储器、存储器到中设。它设定DMA_CCR存放器的DIR[1:0]位的值。那里并出有存储器到存储器的标的目的挑选,当运用存储器到存储器时,只需求把此中一个存储器看成中设运用便可。
DMA_BufferSize: 设定待传输数据数量,初初化设定DMA_CNDTR存放器的值。
DMA_PeripheralInc: 假如设置装备摆设为DMA_PeripheralInc_Enable,使能中设地点主动递删功用,它设定DMA_CCR存放器的PINC位的值;普通中设皆是只要一个数据存放器,以是普通没有会使能该位。
DMA_MemoryInc: 假如设置装备摆设为DMA_MemoryInc_Enable,使能存储器地点主动递删功用,它设定DMA_CCR存放器的MINC位的值;我们自界说的存储区普通皆是寄存多个数据的,以是要使能存储器地点主动递删功用。
DMA_PeripheralDataSize: 中设数据宽度,可选字节(8位)、半字(16位)战字(32位),它设定DMA_CCR存放器的PSIZE[1:0]位的值。
DMA_MemoryDataSize: 存储器数据宽度,可选字节(8位)、半字(16位)战字(32位),它设定DMA_CCR存放器的MSIZE[1:0]位的值。当中设战存储器之间传数据时,双方的数据宽度应当设置为分歧巨细。
DMA_Mode:DMA传输形式挑选,可选一次传输或许轮回传输,它设定DMA_CCR存放器的CIRC位的值。例程我们的ADC收集是继续轮回停止的,以是运用轮回传输形式。
DMA_Priority: 硬件设置通讲的劣先级,有4个可选劣先级辨别为十分下、下、中战低,它设定DMA_CCR存放器的PL[1:0]位的值。DMA通讲劣先级只要正在多个DMA通讲同时运用时才成心义,假如是单个通讲,劣先级能够随意设置。
DMA_M2M: 存储器到存储器形式,运用存储器到存储器时用到,设定DMA_CCR的位14 MEN2MEN便可启动存储器到存储器形式。
5 DMA存储器到中设形式尝试
5.1 代码剖析
USART初初化
代码浑单:DMA-5 USART初初化
void UART_Configuration(uint32_t bound) { GPIO_InitTypeDef GPIO_InitStructure; USART_InitTypeDef USART_InitStructure; RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1, ENABLE); RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE); GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9; GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP; GPIO_Init(GPIOA, &GPIO_InitStructure); GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING; GPIO_Init(GPIOA, &GPIO_InitStructure); USART_InitStructure.USART_BaudRate = bound; USART_InitStructure.USART_WordLength = USART_WordLength_8b; USART_InitStructure.USART_StopBits = USART_StopBits_1; USART_InitStructure.USART_Parity = USART_Parity_No; USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None; USART_InitStructure.USART_Mode = USART_Mode_Rx | USART_Mode_Tx; USART_Init(USART_TEST, &USART_InitStructure); USART_Cmd(USART_TEST, ENABLE); }
那段代码界说了UART_Configuration函数用于设置装备摆设 UART,它接纳波特率做为参数。函数先初初化 GPIO 战 USART 设置装备摆设构造体,接着使能 USART1 战 GPIOA 的时钟。然后将 PA9 设置装备摆设为复用推挽输入做为 TX 引足,PA10 设置装备摆设为浮空输出做为 RX 引足。以后设置 USART 的波特率、数据位、中止位、校验位、硬件流节制等参数,并使能接纳战收收形式。最初初初化并使能 USART
串心DMA传输设置装备摆设
代码浑单:DMA-6 USART1 收收恳求DMA设置
void DMA_RecvConfiguration(void) { DMA_InitTypeDef DMA_InitStructure; RCC_AHBPeriphClockCmd(RCC_AHBPeriph_DMA1, ENABLE); //USART1_RX DMA Config DMA_DeInit(DMA1_Channel5); DMA_InitStructure.DMA_PeripheralBaseAddr = (uint32_t)&USART1->DR; DMA_InitStructure.DMA_MemoryBaseAddr = (uint32_t)Buff; DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralSRC; DMA_InitStructure.DMA_BufferSize = BUFFSIZE; DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable; DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable; DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_Byte; DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_Byte; DMA_InitStructure.DMA_Mode = DMA_Mode_Normal; DMA_InitStructure.DMA_Priority = DMA_Priority_Medium; DMA_InitStructure.DMA_M2M = DMA_M2M_Disable; DMA_Init(DMA1_Channel5, &DMA_InitStructure); DMA_Cmd(DMA1_Channel5, ENABLE); } void DMA_SendConfiguration(void) { DMA_InitTypeDef DMA_InitStructure; RCC_AHBPeriphClockCmd(RCC_AHBPeriph_DMA1, ENABLE); //USART1_TX DMA Config DMA_DeInit(DMA1_Channel4); DMA_InitStructure.DMA_PeripheralBaseAddr = (uint32_t)&USART1->DR; DMA_InitStructure.DMA_MemoryBaseAddr = (uint32_t)Buff; DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralDST; DMA_InitStructure.DMA_BufferSize = BUFFSIZE; DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable; DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable; DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_Byte; DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_Byte; DMA_InitStructure.DMA_Mode = DMA_Mode_Normal; DMA_InitStructure.DMA_Priority = DMA_Priority_Medium; DMA_InitStructure.DMA_M2M = DMA_M2M_Disable; DMA_Init(DMA1_Channel4, &DMA_InitStructure); DMA_Cmd(DMA1_Channel4, ENABLE); }
代码界说了两个函数用于设置装备摆设 DMA(间接内存拜访)的接纳战收收功用。DMA_RecvConfiguration 函数设置装备摆设了 USART1 的 DMA 接纳功用,开启了 DMA1 的时钟,将 DMA1 通讲 5 初初化为从 USART1 的数据存放器接纳数据到内存缓冲区 Buff,并设置了数据标的目的、缓冲区巨细、数据删量形式、数据巨细、任务形式、劣先级等参数,最初使能该通讲。DMA_SendConfiguration 函数则设置装备摆设了 USART1 的 DMA 收收功用,异样开启 DMA1 时钟,将 DMA1 通讲 4 初初化为从内存缓冲区 Buff 收收数据到 USART1 的数据存放器,设置了类似的参数后使能该通讲。
主函数
代码浑单:DMA-7 存储器到中设形式主函数
int main(void) { uint32_t i; RCC_ClocksTypeDef clocks; delay_init(); UART_Configuration(115200); RCC_GetClocksFreq(&clocks); printf("n"); printf("SYSCLK: %3.1fMhz, HCLK: %3.1fMhz, PCLK1: %3.1fMhz, PCLK2: %3.1fMhz, ADCCLK: %3.1fMhzn", (float)clocks.SYSCLK_Frequency / 1000000, (float)clocks.HCLK_Frequency / 1000000, (float)clocks.PCLK1_Frequency / 1000000, (float)clocks.PCLK2_Frequency / 1000000, (float)clocks.ADCCLK_Frequency / 1000000); printf("USART Asyn DMA Test.n"); while (1) { DMA_Cmd(DMA1_Channel4, DISABLE); USART_DMACmd(USART1, USART_DMAReq_Rx, ENABLE); DMA_RecvConfiguration(); while (DMA_GetFlagStatus(DMA1_FLAG_TC5) == RESET); printf("USART Asyn DMA Recv Completen"); for (i = 0; i < BUFFSIZE; i++) { printf("%c ,", Buff[i]); } DMA_Cmd(DMA1_Channel5, DISABLE); USART_DMACmd(USART1, USART_DMAReq_Tx, ENABLE); DMA_SendConfiguration(); while (DMA_GetFlagStatus(DMA1_FLAG_TC4) == RESET); printf("USART Asyn DMA Send Completen"); } }
那段代码是一个 C 言语的 main 函数,次要完成了 USART(通用同步同步支收器)的同步 DMA(间接内存拜访)测试功用。详细步调以下:
界说变量 i 战 clocks,i 用于轮回计数,clocks 用于存储时钟频次疑息。
初初化延时函数,以 115200 的波特率设置装备摆设 UART,获得零碎时钟频次并存储正在 clocks 中。
挨印零碎各时钟频次疑息,包罗 SYSCLK、HCLK、PCLK1、PCLK2 战 ADCCLK,同时输入测试提醒疑息。
进进有限轮回,正在轮回中瓜代停止接纳战收收操纵:
接纳操纵:先禁用 DMA1 通讲 4,使能 USART1 的接纳 DMA 恳求,挪用 DMA_RecvConfiguration 函数设置装备摆设 DMA 接纳,等候接纳完成标记置位,挨印接纳完成疑息并逐一输入接纳到的数据。
收收操纵:禁用 DMA1 通讲 5,使能 USART1 的收收 DMA 恳求,挪用DMA_SendConfiguration 函数设置装备摆设 DMA 收收,等候收收完成标记置位,挨印收收完成疑息。
经过这类体例,不时停止数据的接纳战收收测试。
5.2 下载考证
包管开辟板相干硬件衔接准确,正在电脑端翻开串心调试助脚,把编译好的顺序下载到开辟板。
WIZnet 是一家无晶圆厂半导体公司,建立于 1998 年。产物包罗互联网处置器 iMCU™,它采取 TOE(TCP/IP 卸载引擎)手艺,基于共同的专利齐硬连线 TCP/IP。iMCU™ 里背各类使用中的嵌进式互联网装备。
WIZnet 正在齐球具有 70 多家分销商,正在喷鼻港、韩国、好国设有处事处,供给手艺撑持战产物营销。
喷鼻港处事处治理的地区包罗:澳年夜利亚、印度、土耳其、亚洲(韩国战日本除中)。