即日起在codingBlog上分享您的技术经验即可获得积分,积分可兑换现金哦。

STM32:DMA实例之串口(USART)通信

编程语言 sinat_36184075 91℃ 0评论

硬件平台:stm32f10xZET6


开发环境:keil MDK uVision v4.10


开发语言:C、ST_lib_3.5固件库




/* 代码演示 main.c */
#include "stm32f10x.h"
#include "bsp_usart1.h"
#include "bsp_led.h"

extern uint8_t SendBuff[SENDBUFF_SIZE];
static void Delay(__IO u32 nCount); 

/**
  * @brief  主函数
  */
int main(void)
{
  /* USART1 config 115200 8-N-1 */
  USART1_Config();
 
  USART1_DMA_Config();
 
  LED_GPIO_Config();
 
  printf ("\r\n usart1 DMA TX test... \r\n");
 
  {
   uint16_t i;
   /*填充将要发送的数据*/
   for(i=0;i
/* 中断处理函数 stm32f10x_it.c line:157 */
void DMA1_Channel4_IRQHandler(void)
{
 //判断是否为 DMA 发送完成中断
 if (DMA_GetFlagStatus(DMA1_FLAG_TC4)==SET)
 {
  //LED 关闭
  LED1(OFF);


  DMA_ClearFlag(DMA1_FLAG_TC4);
 }
}
/* 代码演示 bsp_usart1模块 */
#ifndef __USART1_H
#define __USART1_H


#include "stm32f10x.h"
#include 


#define USART1_DR_Base  0x40013804  // 0x40013800 + 0x04 = 0x40013804
#define SENDBUFF_SIZE   5000


void USART1_Config(void);
void USART1_DMA_Config(void);


#endif /* __USART1_H */
// ------------------------------------------------------
#include "bsp_usart1.h"


uint8_t SendBuff[SENDBUFF_SIZE];


/**
  * @brief  USART1 GPIO 配置,工作模式配置。115200 8-N-1
  * @param  无
  * @retval 无
  */
void USART1_Config(void)
{
  GPIO_InitTypeDef GPIO_InitStructure;
  USART_InitTypeDef USART_InitStructure;
  
  /* config USART1 clock */
  RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1 | RCC_APB2Periph_GPIOA, ENABLE);
  
  /* USART1 GPIO config */
  /* Configure USART1 Tx (PA.09) as alternate function push-pull */
  GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9;
  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
  GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
  GPIO_Init(GPIOA, &GPIO_InitStructure);    
  /* Configure USART1 Rx (PA.10) as input floating */
  GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10;
  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;
  GPIO_Init(GPIOA, &GPIO_InitStructure);
   
  /* USART1 mode config */
  USART_InitStructure.USART_BaudRate = 115200;
  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(USART1, &USART_InitStructure); 
  USART_Cmd(USART1, ENABLE);
}


/**
  * @brief  USART1 TX DMA 配置,内存到外设(USART1->DR)
  * @param  无
  * @retval 无
  */
void USART1_DMA_Config(void)
{
  DMA_InitTypeDef DMA_InitStructure;
 
  /*开启DMA时钟*/
  RCC_AHBPeriphClockCmd (RCC_AHBPeriph_DMA1, ENABLE);


  /*传输大小DMA_BufferSize=SENDBUFF_SIZE*/ 
  DMA_InitStructure.DMA_BufferSize = SENDBUFF_SIZE;  // 此处是发送的buffer的配置
  /*方向:从内存到外设*/  
  DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralDST;
  /*禁止内存到内存的传输 */
  DMA_InitStructure.DMA_M2M = DMA_M2M_Disable;


  /*内存地址(要传输的变量的指针)*/
  DMA_InitStructure.DMA_MemoryBaseAddr = (u32)SendBuff;
  /*内存数据单位 8bit*/
  DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_Byte;
  /*内存地址自增*/
  DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable;


  /*DMA模式:不断循环*/
  DMA_InitStructure.DMA_Mode = DMA_Mode_Circular;  
       
  /* 设置DMA源:串口数据寄存器地址 */
  DMA_InitStructure.DMA_PeripheralBaseAddr = USART1_DR_Base;
  /* 外设数据单位:字节 */ 
  DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_Byte;      
   /* 外设地址不增 */     
  DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable; 


  /*优先级:中*/ 
  DMA_InitStructure.DMA_Priority = DMA_Priority_Medium;  


  /*配置DMA1的4通道*/     
  DMA_Init(DMA1_Channel4, &DMA_InitStructure);     
  
  /*使能DMA*/
  DMA_Cmd (DMA1_Channel4,ENABLE);     
  //DMA_ITConfig(DMA1_Channel4, DMA_IT_TC,ENABLE);  // 配置DMA发送完成后产生中断
}


/// 重定向c库函数printf到USART1
int fputc(int ch, FILE *f)
{
  /* 发送一个字节数据到USART1 */
  USART_SendData(USART1, (uint8_t) ch);
  
  /* 等待发送完毕 */
  while (USART_GetFlagStatus(USART1, USART_FLAG_TXE) == RESET);  
 
  return (ch);
}


/// 重定向c库函数scanf到USART1
int fgetc(FILE *f)
{
  /* 等待串口1输入数据 */
  while (USART_GetFlagStatus(USART1, USART_FLAG_RXNE) == RESET);


  return (int)USART_ReceiveData(USART1);
}
/* 代码演示 bsp_led模块 */
#ifndef __LED_H
#define __LED_H


#include "stm32f10x.h"


/** the macro definition to trigger the led on or off 
  * 1 - off
  *0 - on
  */
#define ON  0
#define OFF 1


/* 带参宏,可以像内联函数一样使用 */
#define LED1(a) if (a) \
     GPIO_SetBits(GPIOB,GPIO_Pin_0);\
     else  \
     GPIO_ResetBits(GPIOB,GPIO_Pin_0)

#define LED2(a) if (a) \
     GPIO_SetBits(GPIOF,GPIO_Pin_7);\
     else  \
     GPIO_ResetBits(GPIOF,GPIO_Pin_7)

#define LED3(a) if (a) \
     GPIO_SetBits(GPIOF,GPIO_Pin_8);\
     else  \
     GPIO_ResetBits(GPIOF,GPIO_Pin_8)

void LED_GPIO_Config(void);

#endif /* __LED_H */
//---------------------------------------------------------
#include "bsp_led.h"   


 /**
  * @brief  初始化控制LED的IO
  * @param  无
  * @retval 无
  */
void LED_GPIO_Config(void)
{  
  /*定义一个GPIO_InitTypeDef类型的结构体*/
  GPIO_InitTypeDef GPIO_InitStructure;


  /*开启GPIOB和GPIOF的外设时钟*/
  RCC_APB2PeriphClockCmd( RCC_APB2Periph_GPIOB|RCC_APB2Periph_GPIOF, ENABLE); 


  /*选择要控制的GPIOB引脚*/                  
  GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0; 


  /*设置引脚模式为通用推挽输出*/
  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;   


  /*设置引脚速率为50MHz */   
  GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; 


  /*调用库函数,初始化GPIOB0*/
  GPIO_Init(GPIOB, &GPIO_InitStructure); 
  
  /*选择要控制的GPIOF引脚*/                  
  GPIO_InitStructure.GPIO_Pin = GPIO_Pin_7;


  /*调用库函数,初始化GPIOF7*/
  GPIO_Init(GPIOF, &GPIO_InitStructure);
  
  /*选择要控制的GPIOF引脚*/                  
  GPIO_InitStructure.GPIO_Pin = GPIO_Pin_8;


  /*调用库函数,初始化GPIOF7*/
  GPIO_Init(GPIOF, &GPIO_InitStructure);     


  /* 关闭所有led灯 */
  GPIO_SetBits(GPIOB, GPIO_Pin_0);
  
  /* 关闭所有led灯 */
  GPIO_SetBits(GPIOF, GPIO_Pin_7|GPIO_Pin_8);  
}

*注:LED灯的管脚Pin根据开发板的不同,实际去调整即可。




转载请注明:CodingBlog » STM32:DMA实例之串口(USART)通信

喜欢 (0)or分享 (0)
发表我的评论
取消评论

*

表情