STM32的DMA演示,USART

发布者:Whisper123最新更新时间:2017-11-08 来源: eefocus关键字:STM32  USART 手机看文章 扫描二维码
随时随地手机看文章

#include "stm32f10x_lib.h"
#include "stdio.h"


#define USART1_DR_Base  0x40013804


#define SENDBUFF_SIZE   10240
vu8 SendBuff[SENDBUFF_SIZE];
vu8 RecvBuff[10];
vu8 recv_ptr;

void RCC_Configuration(void);
void GPIO_Configuration(void);
void NVIC_Configuration(void);
void DMA_Configuration(void);
void USART1_Configuration(void);
int fputc(int ch, FILE *f);
void Delay(void);


int main(void)
{
u16 i;
#ifdef DEBUG
debug();
#endif
recv_ptr = 0;
RCC_Configuration();
GPIO_Configuration();
NVIC_Configuration();
DMA_Configuration();
USART1_Configuration();
printf("\r\nSystem Start...\r\n");
printf("Initialling SendBuff... \r\n");
for(i=0;i{
SendBuff[i] = i&0xff;
}
printf("Initial success!\r\nWaiting for transmission...\r\n");
//发送去数据已经准备好,按下按键即开始传输
while(GPIO_ReadInputDataBit(GPIOD, GPIO_Pin_3));
printf("Start DMA transmission!\r\n");
//这里是开始DMA传输前的一些准备工作,将USART1模块设置成DMA方式工作
USART_DMACmd(USART1, USART_DMAReq_Tx, ENABLE);
//开始一次DMA传输!
DMA_Cmd(DMA1_Channel4, ENABLE);
//等待DMA传输完成,此时我们来做另外一些事,点灯
//实际应用中,传输数据期间,可以执行另外的任务
while(DMA_GetFlagStatus(DMA1_FLAG_TC4) == RESET)
{
LED_1_REV;      //LED翻转
Delay();        //浪费时间
}
//DMA传输结束后,自动关闭了DMA通道,而无需手动关闭
//下面的语句被注释
//DMA_Cmd(DMA1_Channel4, DISABLE);
printf("\r\nDMA transmission successful!\r\n");

while (1)
{
}
}

int fputc(int ch, FILE *f)
{
//USART_SendData(USART1, (u8) ch);
USART1->DR = (u8) ch;

while(USART_GetFlagStatus(USART1, USART_FLAG_TXE) == RESET)
{
}
return ch;
}

void Delay(void)
{
u32 i;
for(i=0;i<0xF0000;i++);
return;
}

void RCC_Configuration(void)
{
ErrorStatus HSEStartUpStatus;
//使能外部晶振
RCC_HSEConfig(RCC_HSE_ON);
//等待外部晶振稳定
HSEStartUpStatus = RCC_WaitForHSEStartUp();
//如果外部晶振启动成功,则进行下一步操作
if(HSEStartUpStatus==SUCCESS)
{
//设置HCLK(AHB时钟)=SYSCLK
RCC_HCLKConfig(RCC_SYSCLK_Div1);
//PCLK1(APB1) = HCLK/2
RCC_PCLK1Config(RCC_HCLK_Div2);
//PCLK2(APB2) = HCLK
RCC_PCLK2Config(RCC_HCLK_Div1);
//FLASH时序控制
//推荐值:SYSCLK = 0~24MHz   Latency=0
//        SYSCLK = 24~48MHz  Latency=1
//        SYSCLK = 48~72MHz  Latency=2
FLASH_SetLatency(FLASH_Latency_2);
//开启FLASH预取指功能
FLASH_PrefetchBufferCmd(FLASH_PrefetchBuffer_Enable);
//PLL设置 SYSCLK/1 * 9 = 8*1*9 = 72MHz
RCC_PLLConfig(RCC_PLLSource_HSE_Div1, RCC_PLLMul_9);
//启动PLL
RCC_PLLCmd(ENABLE);
//等待PLL稳定
while(RCC_GetFlagStatus(RCC_FLAG_PLLRDY) == RESET);
//系统时钟SYSCLK来自PLL输出
RCC_SYSCLKConfig(RCC_SYSCLKSource_PLLCLK);
//切换时钟后等待系统时钟稳定
while(RCC_GetSYSCLKSource()!=0x08);

}
//下面是给各模块开启时钟
//启动GPIO
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA | RCC_APB2Periph_GPIOB | \
RCC_APB2Periph_GPIOC | RCC_APB2Periph_GPIOD,\
ENABLE);
//启动AFIO
RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO, ENABLE);
//启动USART1
RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1, ENABLE);
//启动DMA时钟
RCC_AHBPeriphClockCmd(RCC_AHBPeriph_DMA1, ENABLE);
}

void GPIO_Configuration(void)
{
GPIO_InitTypeDef GPIO_InitStructure;
//PC口4567脚设置GPIO输出,推挽 2M
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_4 | GPIO_Pin_5 | GPIO_Pin_6 | GPIO_Pin_7;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_2MHz;
GPIO_Init(GPIOC, &GPIO_InitStructure);
//KEY2 KEY3 JOYKEY
//位于PD口的3 4 11-15脚,使能设置为输入
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_3 | GPIO_Pin_4 | GPIO_Pin_11 | GPIO_Pin_12 |\
GPIO_Pin_13 | GPIO_Pin_14 | GPIO_Pin_15;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;
GPIO_Init(GPIOD, &GPIO_InitStructure);
//USART1_TX
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);
//USART1_RX
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;
GPIO_Init(GPIOA, &GPIO_InitStructure);
}

void NVIC_Configuration(void)
{
NVIC_InitTypeDef NVIC_InitStructure;
#ifdef  VECT_TAB_RAM
// Set the Vector Table base location at 0x20000000
NVIC_SetVectorTable(NVIC_VectTab_RAM, 0x0);
#else 
// Set the Vector Table base location at 0x08000000
NVIC_SetVectorTable(NVIC_VectTab_FLASH, 0x0);
#endif
//设置NVIC优先级分组为Group2:0-3抢占式优先级,0-3的响应式优先级
NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);
//串口接收中断打开   
NVIC_InitStructure.NVIC_IRQChannel = USART1_IRQChannel;
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1;
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
NVIC_Init(&NVIC_InitStructure);
}

void USART1_Configuration(void)
{
USART_InitTypeDef USART_InitStructure;
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_Tx | USART_Mode_Rx;
USART_Init(USART1, &USART_InitStructure);
USART_ITConfig(USART1, USART_IT_RXNE, ENABLE);
USART_Cmd(USART1, ENABLE);
}
void DMA_Configuration(void)
{
DMA_InitTypeDef DMA_InitStructure;
//DMA设置:
//设置DMA源:内存地址&串口数据寄存器地址
//方向:内存-->外设
//每次传输位:8bit
//传输大小DMA_BufferSize=SENDBUFF_SIZE
//地址自增模式:外设地址不增,内存地址自增1
//DMA模式:一次传输,非循环
//优先级:中
DMA_DeInit(DMA1_Channel4);
DMA_InitStructure.DMA_PeripheralBaseAddr = USART1_DR_Base;
DMA_InitStructure.DMA_MemoryBaseAddr = (u32)SendBuff;
DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralDST;
DMA_InitStructure.DMA_BufferSize = SENDBUFF_SIZE;
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);
}

关键字:STM32  USART 引用地址:STM32的DMA演示,USART

上一篇:Cortex-M3 USB的“JoyStickMouse”例程结构分析(二)
下一篇:STC89C52上的读写MMA7455程序

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

STM32 EXTI中断设置五步曲
首依实际系统选择需要多少个中断优先级即 NVIC_PriorityGroupConfig(NVIC_PriorityGroup_0); 然后按下列5步 1 AFIO及GPIO时钟设置 2 要中断的脚设为IN_PU或浮空输入 3 绑定exti中断引脚如 GPIO_EXTILineConfig(GPIO_PortSourceGPIOA,GPIO_PinSource0); 4 配置边沿触发 即设置 EXTI_InitTypeDef EXTI_InitStructure; 5 配置中断向量 即设置 NVIC_InitTypeDef NVIC_InitStructure; 另外 不要忘了在中断程序中补充相应的中断函数
[单片机]
STM32 DMA->内存到内存
基于STM32 F401 Discovery板: DMA2在AHB1总线上 步骤一:使能DMA #define DMA_STREAM_CLOCK RCC_AHB1Periph_DMA2 RCC_AHB1PeriphClockCmd(DMA_STREAM_CLOCK, ENABLE); 步骤二:reset DMA Stream register: /* Reset DMA Stream registers (for debug purpose) */ DMA_DeInit(DMA_STREAM); 步骤三: /* Check if the DMA Stream is disab
[单片机]
<font color='red'>STM32</font> DMA->内存到内存
基于stm32处理器的PWM 异步驱动蜂鸣器
这两天应工作需求研究了一下M3处理器的PWM(脉宽调制)实现对蜂鸣器的异步控制。鉴于阻塞式对蜂鸣器的控制比较耗时,影响用户体验,因此对原有阻塞式控制方案进行了改善,提出了异步控制蜂鸣器的实现方法。以下主要对实现中需要注意的重点知识以及所遇到的问题进行了讨论。 PWM波利用M3的定时器产生,出于对平台资源的有效利用,选择定时器1用来输出脉宽调制信号。这就引出了本文的重点,M3定时器的应用。 M3的定时器资源一共有11个,其中两个高级定时器(Timer1和Timer8)、4个通用定时器(Timer2-Timer5)、2个普通定时器(Timer6-Timer7)、2个看门狗定时器以及一个SysTick定时器。相对于普通定时器来说,高
[单片机]
基于<font color='red'>stm32</font>处理器的PWM 异步驱动蜂鸣器
关于使用STM32 SPI3的一些总结
总结一下spi3的问题,因为spi3的nss口与JTAG有共用引脚,所以配置错误会导致SPI3无法使用。需要注意以下三点就可以了:  1.将PA15配置为普通IO口,GPIO_Mode_Out_PP  2.开启AFIO时钟RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO, ENABLE);  3.关闭JTAG功能,使能SWD  GPIO_PinRemapConfig(GPIO_Remap_SWJ_JTAGDisable,ENABLE) ; 其他的SPI口正常配置,因为板子重启后默认为JTAG模式,虽然在调试时使用了SWD,但PA15依然不是普通的IO口,当把它重新配置时,一定要开启AFIO时钟,
[单片机]
STM32的位操作的方法
STM32 之位带操作 Cortex-M3 支持了位操作后,可以使用普通的加载/存储指令来对单一的比特进行读写。   在 CM3 支持的位带中,有两个区中实现了位带。   其中一个是 SRAM 区的最低 1MB 范围, 0x20000000 ‐ 0x200FFFFF(SRAM 区中的最低 1MB);   第二个则是片内外设区的最低 1MB范围, 0x40000000 ‐ 0x400FFFFF(片上外设区中的最低 1MB)。   这两个区中的地址除了可以像普通的 RAM 一样使用外,它们还都有自己的“位带别名区”,位带别名区把每个比特膨胀成一个 32 位的字。当你通过位带别名区访问这些字时,就可以达到访问原始比特的目的。   C
[单片机]
<font color='red'>STM32</font>的位操作的方法
stm32专题三十:12864 IIC驱动
1 IIC发送数据 / 命令时序 2 12864 图形显示(显存) RAM的大小是128×64位,RAM分为8页,从PAGE0到PAGE7,用于单色128x64点阵显示。 3 行列设置 1 设置起始行坐标(设置页) 命令 0XB0 ~ 0XB7 用于设置分页,所以我们显示的分页要 + 偏移(0XB0) 2 设置起始列坐标 4 制作字模 1 字模软件设置方式: 2 生成的字模的批处理: 生成的字模如图所示,我们要转成 0X00 这种格式: 使用 sublime 这个软件,可以进行批处理(先全选,然后再 快捷键 Ctrl + Shift + L): 字模生成完毕。 驱动程序如下所示
[单片机]
<font color='red'>stm32</font>专题三十:12864 IIC驱动
STM32 堆栈大小详解 以及变量存储位置
栈增长和大端/小端问题是和CPU相关的两个问题. 1,首先来看:栈(STACK)的问题. 函数的局部变量,都是存放在 栈 里面,栈的英文是:STACK.STACK的大小,我们可以在stm32的启动文件里面设置,以 战舰 stm32 开发板 为例,在startup_stm32f10x_hd.s里面,开头就有: Stack_Size EQU 0x00000800 表示栈大小是0X800,也就是2048字节.这样,CPU处理任务的时候,函数局部变量做多可占用的大小就是:2048字节,注意:是所有在处理的函数,包括函数嵌套,递归,等等,都是从这个 栈 里面,来分配的. 所以,如果一个函数的局部变量过多,比如在函数里面定义一个u8
[单片机]
<font color='red'>STM32</font> 堆栈大小详解 以及变量存储位置
小广播
添点儿料...
无论热点新闻、行业分析、技术干货……
设计资源 培训 开发板 精华推荐

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

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

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