STM32F10x DMA介绍以及 dma usart数据收发

发布者:skyhcg最新更新时间:2019-01-04 来源: eefocus关键字:STM32F10x  DMA  dma  usart  数据收发 手机看文章 扫描二维码
随时随地手机看文章

DMA方式

1. DMA 介绍 

Direct memory access (DMA) is used in order to provide high-speed data transfer between 

peripherals and memory and between memory and memory. Data can be quickly moved by 

DMA without any CPU action. This keeps CPU resources free for other operations. 

The DMA controller combines a powerful dual AHB master bus architecture with 

independent FIFO to optimize the bandwidth of the system, based on a complex bus matrix 

architecture. 

The two DMA controllers have 16 streams in total (8 for each controller), each dedicated to 

managing memory access requests from one or more peripherals. Each stream can have 

up to 8 channels (requests) in total. And each has an arbiter for handling the priority 

between DMA requests. 

2. DMA main features 

The main DMA features are: 

● Dual AHB master bus architecture, one dedicated to memory accesses and one 

dedicated to peripheral accesses 

● AHB slave programming interface supporting only 32-bit accesses 

● 8 streams for each DMA controller, up to 8 channels (requests) per stream 

● Four separate 32 first-in, first-out memory buffers (FIFOs) per stream, that can be used 

in FIFO mode or direct mode: 

– FIFO mode: with threshold level software selectable between 1/4, 1/2 or 3/4 of the 

FIFO size 

– Direct mode 

Each DMA request immediately initiates a transfer from/to the memory. When it is 

configured in direct mode (FIFO disabled), to transfer data in memory-to-peripheral mode, the DMA preloads only one data from the memory to the internal FIFO to ensure an immediate data transfer as soon as a DMA request is triggered 

by a peripheral. 

● Each stream can be configured by hardware to be: 

– a regular channel that supports peripheral-to-memory, memory-to-peripheral and 

memory-to-memory transfers 

– a double buffer channel that also supports double buffering on the memory side 

● Each of the 8 streams are connected to dedicated hardware DMA channels (requests) 

● Priorities between DMA stream requests are software-programmable (4 levels 

consisting of very high, high, medium, low) or hardware in case of equality (request 0 

has priority over request 1, etc.) 

● Each stream also supports software trigger for memory-to-memory transfers (only 

available for the DMA2 controller) 

● Each stream request can be selected among up to 8 possible channel requests. This 

selection is software-configurable and allo ws several peripherals to initiate DMA 

requests 

● The number of data items to be transferred can be managed either by the DMA 

controller or by the peripheral: 

– DMA flow controller: the number of data items to be transferred is software-programmable from 1 to 65535 

– Peripheral flow controller: the number of data items to be transferred is unknown 

and controlled by the source or the destination peripheral that signals the end of 

the transfer by hardware 

● Independent source and destination transfer width (byte, half-word, word): when the 

data widths of the source and destination are not equal, the DMA automatically 

packs/unpacks the necessary transfers to optimize the bandwidth. This feature is only 

available in FIFO mode 

● Incrementing or nonincrementing addressing for source and destination 

● Supports incremental burst transfers of 4, 8 or 16 beats. The size of the burst is 

software-configurable, usually equal to half the FIFO size of the peripheral 

● Each stream supports circular buffer management 

● 5 event flags (DMA Half Transfer, DMA Transfer complete, DMA Transfer Error, DMA 

FIFO Error, Direct Mode Error) logically ORed together in a single interrupt request for 

each stream


3.DMA设置以及uart输入输出 

uart DMA的输入输出有两种方式,一种是polling方式,一种是中断方式。 

(1) polling方式 

首先是DMA的初始化,这个是一个DMA Polling方式初始化例子。


/* Private functions ---------------------------------------------------------*/


/**

  * @brief  Main program

  * @param  None

  * @retval None

  */

int main(void)

{


    /* 初始化DMA和usart,gpio相关的clock*/

    RCC_Configuration();


    ...

    /* Configure the DMA */

    DMA_Configuration();//DMA配置

    ...

    /*USART初始化*/

    USART_InitStructure.USART_BaudRate = 230400;

    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;

    /* Configure USARTy */

    USART_Init(USARTy, &USART_InitStructure);

    ....

    /* Enable USARTy DMA Rx and TX request

    这里设置CR3寄存器支持DMA输入输出 */

    USART_DMACmd(USARTy, USART_DMAReq_Rx | USART_DMAReq_Tx, ENABLE);

    ...

    /*使能相应的输入输出DMA channel*/

    /* Enable USARTy TX DMA1 Channel */

    DMA_Cmd(USARTy_Tx_DMA_Channel, ENABLE);

    /* Enable USARTy RX DMA1 Channel */

    DMA_Cmd(USARTy_Rx_DMA_Channel, ENABLE);

    ...

    /* Enable the USARTy */

    USART_Cmd(USARTy, ENABLE);


  /*这一句完了之后,下面DMA_Configuration()函数里边设置的TxBuffer1数据应该就会

    被输出,可以按如下方式等待发送完毕,然后再等待接收后比较输入输出的buffer*/

  /* Wait until USARTy TX DMA1 Channel Transfer Complete */

  while (DMA_GetFlagStatus(USARTy_Tx_DMA_FLAG) == RESET)

  {

  }

  /* Wait until USARTy RX DMA1 Channel Transfer Complete */

  while (DMA_GetFlagStatus(USARTy_Rx_DMA_FLAG) == RESET)

  {

  }

  TransferStatus1 = Buffercmp(TxBuffer2, RxBuffer1, TxBufferSize2);

  //CNTR表示每次要传输的数据大小,如果循环方式的话,传输完一次之后就会停止,想继续传输下一次,需要重新设置CNTR。看下面的例子

}


void DMA_Configuration(void)

{

  DMA_InitTypeDef DMA_InitStructure;


  /* USARTy TX DMA1 Channel (triggered by USARTy Tx event) Config */

  DMA_DeInit(USARTy_Tx_DMA_Channel);  

  DMA_InitStructure.DMA_PeripheralBaseAddr = USARTy_DR_Base;

  DMA_InitStructure.DMA_MemoryBaseAddr = (uint32_t)TxBuffer1;

  DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralDST;//memory的数据通过DMA放到usart dr寄存器中

  DMA_InitStructure.DMA_BufferSize = TxBufferSize1;

  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_VeryHigh;

  DMA_InitStructure.DMA_M2M = DMA_M2M_Disable;

  DMA_Init(USARTy_Tx_DMA_Channel, &DMA_InitStructure);


  /* USARTy RX DMA1 Channel (triggered by USARTy Rx event) Config */

  DMA_DeInit(USARTy_Rx_DMA_Channel);  

  DMA_InitStructure.DMA_PeripheralBaseAddr = USARTy_DR_Base;

  DMA_InitStructure.DMA_MemoryBaseAddr = (uint32_t)RxBuffer1;

  DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralSRC;

  DMA_InitStructure.DMA_BufferSize = TxBufferSize2;

  DMA_Init(USARTy_Rx_DMA_Channel, &DMA_InitStructure);

}



void DMA_Init(DMA_Channel_TypeDef* DMAy_Channelx, DMA_InitTypeDef* DMA_InitStruct)

{

  uint32_t tmpreg = 0;


  /* Check the parameters */

  assert_param(IS_DMA_ALL_PERIPH(DMAy_Channelx));

  assert_param(IS_DMA_DIR(DMA_InitStruct->DMA_DIR));

  assert_param(IS_DMA_BUFFER_SIZE(DMA_InitStruct->DMA_BufferSize));

  assert_param(IS_DMA_PERIPHERAL_INC_STATE(DMA_InitStruct->DMA_PeripheralInc));

  assert_param(IS_DMA_MEMORY_INC_STATE(DMA_InitStruct->DMA_MemoryInc));   

  assert_param(IS_DMA_PERIPHERAL_DATA_SIZE(DMA_InitStruct->DMA_PeripheralDataSize));

  assert_param(IS_DMA_MEMORY_DATA_SIZE(DMA_InitStruct->DMA_MemoryDataSize));

  assert_param(IS_DMA_MODE(DMA_InitStruct->DMA_Mode));

  assert_param(IS_DMA_PRIORITY(DMA_InitStruct->DMA_Priority));

  assert_param(IS_DMA_M2M_STATE(DMA_InitStruct->DMA_M2M));


/*--------------------------- DMAy Channelx CCR Configuration -----------------*/

  /* Get the DMAy_Channelx CCR value */

  tmpreg = DMAy_Channelx->CCR;

  /* Clear MEM2MEM, PL, MSIZE, PSIZE, MINC, PINC, CIRC and DIR bits */

  tmpreg &= CCR_CLEAR_Mask;

  /* Configure DMAy Channelx: data transfer, data size, priority level and mode */

  /* Set DIR bit according to DMA_DIR value */

  /* Set CIRC bit according to DMA_Mode value */

  /* Set PINC bit according to DMA_PeripheralInc value */

  /* Set MINC bit according to DMA_MemoryInc value */

  /* Set PSIZE bits according to DMA_PeripheralDataSize value */

  /* Set MSIZE bits according to DMA_MemoryDataSize value */

  /* Set PL bits according to DMA_Priority value */

  /* Set the MEM2MEM bit according to DMA_M2M value */

  tmpreg |= DMA_InitStruct->DMA_DIR | DMA_InitStruct->DMA_Mode |

            DMA_InitStruct->DMA_PeripheralInc | DMA_InitStruct->DMA_MemoryInc |

            DMA_InitStruct->DMA_PeripheralDataSize | DMA_InitStruct->DMA_MemoryDataSize |

            DMA_InitStruct->DMA_Priority | DMA_InitStruct->DMA_M2M;


  /* Write to DMAy Channelx CCR */

  DMAy_Channelx->CCR = tmpreg;


/*--------------------------- DMAy Channelx CNDTR Configuration ---------------*/

  /* Write to DMAy Channelx CNDTR */

  DMAy_Channelx->CNDTR = DMA_InitStruct->DMA_BufferSize;


/*--------------------------- DMAy Channelx CPAR Configuration ----------------*/

  /* Write to DMAy Channelx CPAR */

  DMAy_Channelx->CPAR = DMA_InitStruct->DMA_PeripheralBaseAddr;


/*--------------------------- DMAy Channelx CMAR Configuration ----------------*/

  /* Write to DMAy Channelx CMAR */

  DMAy_Channelx->CMAR = DMA_InitStruct->DMA_MemoryBaseAddr;

}



当通道配置为非循环模式时,传输结束后(即传输计数变为0)将不再产生DMA操作。要开始新的DMA传输,需要在关闭DMA通道的情况下,在DMA_CNDTRx寄存器中重新写入传输数目。 

例子:


void DMA_Init(DMA_Channel_TypeDef* DMAy_Channelx, DMA_InitTypeDef* DMA_InitStruct)

{

  uint32_t tmpreg = 0;


  /* Check the parameters */

  assert_param(IS_DMA_ALL_PERIPH(DMAy_Channelx));

  assert_param(IS_DMA_DIR(DMA_InitStruct->DMA_DIR));

  assert_param(IS_DMA_BUFFER_SIZE(DMA_InitStruct->DMA_BufferSize));

  assert_param(IS_DMA_PERIPHERAL_INC_STATE(DMA_InitStruct->DMA_PeripheralInc));

  assert_param(IS_DMA_MEMORY_INC_STATE(DMA_InitStruct->DMA_MemoryInc));   

  assert_param(IS_DMA_PERIPHERAL_DATA_SIZE(DMA_InitStruct->DMA_PeripheralDataSize));

  assert_param(IS_DMA_MEMORY_DATA_SIZE(DMA_InitStruct->DMA_MemoryDataSize));

  assert_param(IS_DMA_MODE(DMA_InitStruct->DMA_Mode));

  assert_param(IS_DMA_PRIORITY(DMA_InitStruct->DMA_Priority));

  assert_param(IS_DMA_M2M_STATE(DMA_InitStruct->DMA_M2M));


/*--------------------------- DMAy Channelx CCR Configuration -----------------*/

  /* Get the DMAy_Channelx CCR value */

  tmpreg = DMAy_Channelx->CCR;

  /* Clear MEM2MEM, PL, MSIZE, PSIZE, MINC, PINC, CIRC and DIR bits */

  tmpreg &= CCR_CLEAR_Mask;

  /* Configure DMAy Channelx: data transfer, data size, priority level and mode */

  /* Set DIR bit according to DMA_DIR value */

  /* Set CIRC bit according to DMA_Mode value */

  /* Set PINC bit according to DMA_PeripheralInc value */

  /* Set MINC bit according to DMA_MemoryInc value */

  /* Set PSIZE bits according to DMA_PeripheralDataSize value */

  /* Set MSIZE bits according to DMA_MemoryDataSize value */

  /* Set PL bits according to DMA_Priority value */

  /* Set the MEM2MEM bit according to DMA_M2M value */

  tmpreg |= DMA_InitStruct->DMA_DIR | DMA_InitStruct->DMA_Mode |

            DMA_InitStruct->DMA_PeripheralInc | DMA_InitStruct->DMA_MemoryInc |

            DMA_InitStruct->DMA_PeripheralDataSize | DMA_InitStruct->DMA_MemoryDataSize |

            DMA_InitStruct->DMA_Priority | DMA_InitStruct->DMA_M2M;


  /* Write to DMAy Channelx CCR */

  DMAy_Channelx->CCR = tmpreg;


/*--------------------------- DMAy Channelx CNDTR Configuration ---------------*/

  /* Write to DMAy Channelx CNDTR */

  DMAy_Channelx->CNDTR = DMA_InitStruct->DMA_BufferSize;


/*--------------------------- DMAy Channelx CPAR Configuration ----------------*/

  /* Write to DMAy Channelx CPAR */

  DMAy_Channelx->CPAR = DMA_InitStruct->DMA_PeripheralBaseAddr;


/*--------------------------- DMAy Channelx CMAR Configuration ----------------*/

  /* Write to DMAy Channelx CMAR */

  DMAy_Channelx->CMAR = DMA_InitStruct->DMA_MemoryBaseAddr;

}


(2) 中断方式 

下面再说说如何在DMA传输完成之后产生中断。当传输一半的数据后,半传输标志(HTIF)被置1,当设置了允许半传输中断位(HTIE)时,将产生一个中断请求。在数据传输结束后,传输完成标志(TCIF)被置1,当设置了允许传输完成中断位(TCIE)时,将产生一个中断请求。 

DMA 的CCR 寄存器中有1位TCIE (Transfer complete interrupt enable) 

该位由软件设置和清除。 

0:禁止TC中断 

1:允许TC中断 

所以为了使用DMA中断,我们需要下面的代码: 

[cpp] view plaincopy 

DMA1_Channel7->CCR |= DMA_IT_TC; //Transfer complete interrupt enable 

另外能否响应中断,还要NVIC说了算,所以下面的代码也不能少: 

[cpp] view plaincopy 

NVIC_InitStructure.NVIC_IRQChannel = DMA1_Channel7_IRQn; 

NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 5; 

NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0; 

NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; 

NVIC_Init(&NVIC_InitStructure); 

下面还是给个简单的示例程序,示例程序中还用到了uCOS的信号量,中断处理函数通过信号量通知Task 完成了DMA传输:


#include "stm32f10x.h"  

#include "uart.h"  

#include "led.h"  

#include "COMMRTOS.H"  

#include "ucos_ii.h"  


#define  TASK_STK_SIZE 128  

OS_STK TaskStartStk[TASK_STK_SIZE];  



void USART2_Init(void)  

{  

    GPIO_InitTypeDef GPIO_InitStructure;  

    USART_InitTypeDef USART_InitStructure;  

    NVIC_InitTypeDef NVIC_InitStructure;  


    RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOD | RCC_APB2Periph_AFIO, ENABLE);  


    /* Configure USART Tx as alternate function push-pull */  

    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;  

    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_5;  

    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;  

    GPIO_Init(GPIOD, &GPIO_InitStructure);  


    /* Configure USART Rx as input floating */  

    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;  

    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_6;  

    GPIO_Init(GPIOD, &GPIO_InitStructure);  


    GPIO_PinRemapConfig(GPIO_Remap_USART2, ENABLE);  

    RCC_APB1PeriphClockCmd(RCC_APB1Periph_USART2, ENABLE);  


    USART_InitStructure.USART_BaudRate = 9600;  

    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(USART2, &USART_InitStructure);  


    USART_Cmd(USART2, ENABLE);  


    NVIC_InitStructure.NVIC_IRQChannel = USART2_IRQn;  

    NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1;  

    NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1;  

    NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;  

    NVIC_Init(&NVIC_InitStructure);  

}  


void UART2_TX_DMA_Init(uint8_t *p_str, uint16_t cnt)  

{  

//    DMA_InitTypeDef    DMA_InitStructure;  

//    DMA_InitStructure.DMA_PeripheralBaseAddr = (uint32_t) &(USART2->DR);      

//    DMA_InitStructure.DMA_MemoryBaseAddr = (uint32_t) str;  

//    DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralDST;  

//    DMA_InitStructure.DMA_BufferSize = 14;  

//    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_Low;  

//    DMA_InitStructure.DMA_M2M = DMA_M2M_Disable;  


    RCC_AHBPeriphClockCmd(RCC_AHBPeriph_DMA1, ENABLE);  

//    DMA_Init(DMA1_Channel7, &DMA_InitStructure);  


    DMA1_Channel7->CPAR = (uint32_t) &(USART2->DR);  

    DMA1_Channel7->CMAR = (uint32_t) p_str;  

    DMA1_Channel7->CNDTR = cnt;  

    DMA1_Channel7->CCR = DMA_DIR_PeripheralDST | DMA_Priority_Low |   

                DMA_Mode_Normal | DMA_PeripheralInc_Disable    |  

                DMA_MemoryInc_Enable | DMA_PeripheralDataSize_Byte |  

                DMA_MemoryDataSize_Byte    | DMA_M2M_Disable;  

}  


OS_EVENT  *UART2_DMA_TX_Sem;  

uint8_t str[] = "Hello World!!!";  

void TaskStart(void *pdata)  

{  

    unsigned char err;  

    SysTick_Config(SystemCoreClock/10);  


    USART2_Init();  

    USART_DMACmd(USART2, USART_DMAReq_Tx, ENABLE);  

    UART2_TX_DMA_Init(str);  

    UART2_DMA_TX_Sem = OSSemCreate(1);      

    for(;;)  

    {  

        LED_Spark();  

        OSSemPend(UART2_DMA_TX_Sem, 0, &err);   

        //DMA_Cmd(DMA1_Channel7, DISABLE);  

        DMA1_Channel7->CCR &= (uint16_t)(~DMA_CCR1_EN);   

        //DMA_Init(DMA1_Channel7, &DMA_InitStructure);  

        DMA1_Channel7->CNDTR = 14;  

        //DMA_Cmd(DMA1_Channel7, ENABLE);  

        DMA1_Channel7->CCR |= DMA_CCR1_EN;  

        //USART_DMACmd(USART2, USART_DMAReq_Tx, ENABLE);  

        OSTimeDly(10);  

    }  

}  


int main(void)  

{  

    SystemInit();  

    LED_Init();  

    OSInit();  

    OSTaskCreate(TaskStart, (void *)0, &(TaskStartStk[TASK_STK_SIZE-1]), 1);  

    OSStart();  

    for(;;)  

    {  


    }      

}  


void DMA1_Channel7_IRQHandler(void)  

{  

    OS_CPU_SR  cpu_sr;  


    OS_ENTER_CRITICAL();        /* Tell uC/OS-II that we are starting an ISR  */  

    OSIntNesting++;  

    OS_EXIT_CRITICAL();  

    OSSemPost(UART2_DMA_TX_Sem);  

    //UART_PutChar(USART2, '+');  

    DMA1->IFCR = DMA1_FLAG_TC7;          

    OSIntExit();  

}  


关键字:STM32F10x  DMA  dma  usart  数据收发 引用地址:STM32F10x DMA介绍以及 dma usart数据收发

上一篇:stm32 DMA 的 buffersize 意义与设置
下一篇:STM32之DMA的认识和使用

推荐阅读最新更新时间:2024-03-16 16:21

STM32的usart2串口调试
先是参考 http://wenku.baidu.com/view/78f6b1350b4c2e3f572763e9.html 调通了usart1 然后将程序进行修改,对Usart2进行配置,配置完了之后,程序还是没有正确,然后在void GPIO_cfg();函数中添加一句 GPIO_PinRemapConfig(GPIO_Remap_USART2, ENABLE); 最后程序如下, #include stm32f10x_lib.h FlagStatus RX_status; FlagStatus Tx_status; void RCC_cfg(void); v
[单片机]
stm32 USART_IT_IDLE中断 一帧数据
USART_IT_IDLE中断,是串口收到一帧数据后,发生的中断。也可以叫做一包数据 USART_IT_IDLE和USART_IT_RXNE区别 当接收到1个字节,会产生USART_IT_RXNE中断 当接收到一帧数据,就会产生USART_IT_IDLE中断 清中断方法 //USART_IT_RXNE USART_ClearITPendingBit(USART1, USART_IT_RXNE); //USART_IT_IDLE USART1- SR; //先读SR寄存器 USART1- DR; //再读DR寄存器 使用举例 u8 count; u8 flag; void uart_init(u32
[单片机]
stm32 <font color='red'>USART</font>_IT_IDLE中断 一帧<font color='red'>数据</font>
STM32F4学习笔记7——USART Part2
硬件流控制 使用 nCTS 输入和 nRTS 输出可以控制 2 个器件间的串行数据流。如图显示了在这种模式 下如何连接 2 个器件: 分别向 USART_CR3 寄存器中的 RTSE 位和 CTSE 位写入 1,可以分别使能 RTS 和 CTS 流 控制。 RTS 流控制 如果使能 RTS 流控制 (RTSE=1),只要 USART 接收器准备好接收新数据,便会将 nRTS 变 为有效(连接到低电平)。当接收寄存器已满时,会将 nRTS 变为无效,表明发送过程会在 当前帧结束后停止。下图图显示了在使能 RTS 流控制的情况下进行通信的示例。 CTS 流控制 如果使能 CTS 流控制 (CTSE=1),则发送器会在发送下一帧
[单片机]
STM32F4学习笔记7——<font color='red'>USART</font> Part2
STM32F1的DMA使用
在前面我们提到过 DMA,这一章我们就来学习 STM32F1 的DMA 使 用。要实现的功能是:通过 K_UP 按键控制 DMA 串口 1 数据的传送,在传送过程中让 D2 指示灯不断闪烁,直到数据传送完成。D1 指示灯闪烁提示系统正常运行。学习时可以参考《STM32F10x 中文参考手册》-10 DMA 控制器(DMA)章节。 DMA 简介 DMA,全称是 Direct Memory Access,中文意思为直接存储器访问。DMA 可用于实现外设与存储器之间或者存储器与存储器之间数据传输的高效性。之所以称为高效, 是因为 DMA 传输数据移动过程无需 CPU 直接操作, 这样节省的 CPU 资源就可供其它操作使用。
[单片机]
STM32F1的<font color='red'>DMA</font>使用
STM32F10x _RTC秒中断
Ⅰ、概述 RTC(Real Time Clock)是实时时钟的意思,它其实和TIM有点类似,也是利用计数的原理,选择RTC时钟源,再进行分频,到达计数的目的。 该文主要讲述关于RTC的秒中断功能,这个功能类似SysTick系统滴答的功能。RTC秒中断功能其实是每计数一次就中断一次。注意,这里所说的秒中断并非一定是一秒的时间,它是由RTC时钟源和分频值决定的“秒”的时间,当然也是可以做到1秒钟中断一次。 本文章提供的实例工程,其实验效果是: 主函数间隔0.5秒LED变化一次; 秒中断一次打印数据 RTC Sec... ; 也就是LED变化一次,串口打印一次数据 RTC Sec... 扩展部分的功能RTC计数:可以实现RTC
[单片机]
<font color='red'>STM32F10x</font> _RTC秒中断
MSP430串口数据收发的讨论
简介:在做串口通信看 沈建华编著 一书中感到书中有些控制字没有列出,编写程序时容易忘记写.出现不必要的错误. ME2 IE2 IFG2 (或ME1 IE1 IFG1)下面的本程序用的是USART1.要从.H的头文件里找上面三个特殊功能寄存器的用法. #define IE2_ (0x0001) /* Interrupt Enable 2 */ DEFC( IE2 , IE2_) #define U1IE IE2 /* UART1 Interrupt Enable Register */ #define URXIE1 (0x10) #define UTXIE1 (0x20) #define IFG2_ (0x0
[单片机]
USART——串口通讯
开发平台 野火F429开发板 标准库 通讯基本概念 同步通讯和异步通讯 同步通讯和异步通讯的区别在于有没有时钟信号线 全双工、半双工、单工通讯 全双工可以收发同时进行 半双工可以收发但不可同时进行 单工只能收或发 USART 三大时序:USART、I2C、SPI,USART是其中之一了 USART时序:起始位为低电平、然后发送数据8位数据是没有校验位的,9位数据是有校验位的、停止位为高电平。时序如下图:(字长为8) 现在我使用串口一般都是打印调试信息或者蓝牙通讯 ,只会用到TX和RX,不需要用到时钟信号线,所以是异步半双工 如果想要操作寄存器,那就要看功能框图了 1.TX发送数据引脚、RX接受数据引脚,所以要把引脚配置为串
[单片机]
<font color='red'>USART</font>——串口通讯
事件系统和DMA实现超快响应时间和极低功耗
在多数情况下,一个外设上的信号除了要让另一个外设知道它有事要做外,两个外设间的联络却需要大量中断处理时间。CPU便会随之中断,并关断马达驱动电路的PWM输出。这个过程需要耗费数十个时钟周期,并需要另外的20~100个时钟周期来恢复关联。微控制器并没真正被用于任何需要其处理能力的事情,只是从模拟比较器向PWM输出传递了一个消息而已。   如果这些外设能够无需中断CPU而直接相互通信,每秒钟就可轻易节省数百万个时钟周期。8位微控制器不再适用于8位应用的一个原因,就是应用涉及的数据处理和中断处理太多,CPU的MIPS大都耗费在这些活动上。而外设和内存之间的传输数据更进一步地增加了MCU的负担。一个350kps的数据传输就要耗费22~25个
[模拟电子]
事件系统和<font color='red'>DMA</font>实现超快响应时间和极低功耗
小广播
添点儿料...
无论热点新闻、行业分析、技术干货……
设计资源 培训 开发板 精华推荐

最新单片机文章
何立民专栏 单片机及嵌入式宝典

北京航空航天大学教授,20余年来致力于单片机与嵌入式系统推广工作。

换一换 更多 相关热搜器件
电子工程世界版权所有 京B2-20211791 京ICP备10001474号-1 电信业务审批[2006]字第258号函 京公网安备 11010802033920号 Copyright © 2005-2024 EEWORLD.com.cn, Inc. All rights reserved