您的位置 首页 分销

STM32 串口功用 库函数 详解和DMA 串口府第运用(转载)

数据传输时要从支持那些相关的标准?传输的速度?什么时候开始?什么时候结束?传输的内容?怎样防止通信出错?数据量大的时候怎么弄?硬件…

数据传输时要从支撑那些相关的标准?传输的速度?什么时分开端?什么时分完毕?传输的内容?怎样避免通讯犯错?数据量大的时分怎样弄?硬件怎样衔接动身,当然关于stm32还要了解库函数的功用

具起来rs232和485电平的差异硬件外围芯片,波特率(反映传一位的时刻),开端位和中止位,数据宽度,校验,硬件流操控,相应衔接电脑时的接口怎样样的。装备,运用函数,中止,查询并结合通讯协议才算了解了串口运用。

以上是根底,当然stm许多相关复用功用,支撑同步单向通讯和半双工单线通讯,支撑部分互联网、智能卡协议和红外数据安排相关标准,以及调制解调器操作,运转多处理器通讯。一起能够运用DMA办法进行高速数据通讯。留意Print函数时刻问题,测验经过DMA处理。

特征:全双工,异步,分数波特率发生器优点是速度快,位数8或9为,可装备1或2中止位,Lin协议,可供给同步时钟功用。

硬件上

一般2个脚,RX和TX;同步方法需求SCLK时钟脚,红外IRDA需求irDA_RDI脚作为数据输入和irDA_TDO输出。

奇偶校验经过usart_cr1pce位装备校验(发送生成奇偶位,承受时进行校验)

LIN局域互联网方法:经过设置USART_CR2中LINEN位装备,运用的时分需求外加专门的收发器才能够

同步方法:经过设置USART_CR2中CLKEN位装备

智能卡方法:经过设置USART_CR3中SCEN位装备

DMA、硬件流操控作专门研究。

中止有哪些作业?

发送数据寄存器空发送完结承受数据可读奇偶校验错数据溢出CTS标志 闲暇标志 断开标志 噪声标志

惋惜是没有留有承受缓冲区,用查询简单数据丢掉

。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。

流程是时钟装备管脚装备(如重映射,管脚方法)-串口装备-中止装备–相应中止–翻开串口

上面是一些根底知识点,下面从实践运用来了解串口功用

比较简单些的运用吧:对usart进行初始化的作业

void COM1_Init( void)
{

//首先要初始化结构体:少不了关于的引脚,忘不了usart,更牵挂着中止的装备结构体,界说空间来被涂鸦

GPIO_InitTypeDef GPIO_InitStructure;
USART_InitTypeDef USART_InitStructure;
NVIC_InitTypeDef NVIC_InitStructure;

//下面是对GPIO进行涂鸦

RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA RCC_APB2Periph_AFIO, ENABLE);
RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1, ENABLE);

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

GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10;//挑选管脚位
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;//方法为输入
GPIO_Init(GPIOA, &GPIO_InitStructure);

USART_InitStructure.USART_BaudRate = 115200;//波特率
USART_InitStructure.USART_WordLength = USART_WordLength_8b;//8数据位
USART_InitStructure.USART_StopBits = USART_StopBits_1;//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);

//使能串口中止,并设置优先级
NVIC_InitStructure.NVIC_IRQChannel = USART1_IRQn;
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = USART1_IRQn_Priority;
NVIC_InitStructure.NVIC_IRQChannelSubPriority=0;
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
NVIC_Init(&NVIC_InitStructure);//将结构体丢到装备函数,即写入到对应寄存器中

//USART_ITConfig(USART1, USART_IT_RXNE, ENABLE);

//一切的作业都做好了,最终别忘了翻开串口
USART_Cmd(USART1, ENABLE);
}

//USART_ITConfig(USART1, USART_IT_RXNE, ENABLE);下面是中止源

#define USART_IT_PE((uint16_t)0x0028)
#define USART_IT_TXE((uint16_t)0x0727)
#define USART_IT_TC((uint16_t)0x0626)
#define USART_IT_RXNE((uint16_t)0x0525)
#define USART_IT_IDLE((uint16_t)0x0424)
#define USART_IT_LBD((uint16_t)0x0846)
#define USART_IT_CTS((uint16_t)0x096A)
#define USART_IT_ERR((uint16_t)0x0060)
#define USART_IT_ORE((uint16_t)0x0360)
#define USART_IT_NE((uint16_t)0x0260)
#define USART_IT_FE((uint16_t)0x0160)

以上是初始化装备,下面还要构成最小的运用,就举例输出函数吧

void PrintUart1(const u8 *Str)
{
while(*Str)
{
USART_SendData(USART1, (unsigned char)*Str++);
while (USART_GetFlagStatus(USART1, USART_FLAG_TXE) == RESET);
}
}

发送字符是经过查询字符串的状况来来不断的发送下一个数据。

承受数据是经过中止来完结的,把承受的数据放入缓冲区,来完结。有包括协议今后细讲。

想玩电脑串口传输数据,经过printf()来直接在电脑窗口显现是不是很爽?在usart.c函数中参加

//不运用半主机方法
#if 1 //假如没有这段,则需求在target选项中挑选运用USE microLIB
#pragma import(__use_no_semihosting)
struct __FILE
{
int handle;
};
FILE __stdout;

_sys_exit(int x)
{
x = x;
}
#endif

int fputc(int ch, FILE *f)
{
USART_SendData(USART1, (unsigned char)ch);
while (USART_GetFlagStatus(USART1, USART_FLAG_TXE) == RESET);
return ch;
}

上面数据来历能够经过串口,经过usb,经过无线等等。。。

printf函数有个缺点,便是花费的时刻太多了(毫秒级),总不至于让CPU等几个毫秒就来显现串口吧,那再好的CPU也就费了,那肿么办?能够用DMA!!直接让其它硬件来传这些粗糙的作业。CPU玩要点的其它的活!

先接着讲好串口承受,再说这个DMA,在固件库晒干有个文件是专门用来放中止处理函数的

晒干有个函数
void USART1_IRQHandler(void)
{
static u8 UartBuf[UART_BUF_LEN];//串口缓冲
if(USART_GetITStatus(USART1, USART_IT_RXNE) != RESET)
{
temp=USART_ReceiveData(USART1);

…………..下面便是一些处理,能够用状况机方法来玩,直到填充好串口缓冲数据,并校验正确,不多说

}
}

上面是典型的中止处理函数,结合状况机功用就强壮了。讲到操作体系还要进一步的学会运用。

经过上面的学习信任对根本的串口操作有了比较深化的了解了,前面说到printf太慢,这儿需求一些改善。

考虑到真实碑文串口输出(用DMA其实在几毫秒后完结)比碑文完pruntf(当即完结)这个时刻点晚个几毫秒对实践运用来说没有任何影响,因而CPU能够在嘀嗒中止中指挥DMA模块完结串口输出的使命。(其实对体系仍是有些影响的微观讲,串口输出的数据其实很少,在大河中放入一杯水,简直能够忽略不计的)
再处理怎样分配:
界说两个大局缓存区
其间一个缓存区以循环行列的方法安排,每次碑文fputc时向其队尾参加一个元素。
另一个缓存区直接以数组的方法安排,作为DMA的源地址。
在嘀嗒中止中按下列次序完结对DMA的操作
(1)判别循环行列是否为空,假如为空阐明当时没有字符串需求经过串口输出直接跳至(6)
(2)判别DMA是否正在作业,假如DMA正在作业阐明前次分配的任何没干完直接跳至(6)
(3)从循环行列出队N个字符到数组缓存
(4)告知DMA本次需传输的字节数N
(5)指令DMA开端传输
(6)完毕操作
弥补:
1.N的确认办法:若循环行列中元素的个数大于或等于数组缓存区的长度(固定值),则将数组缓存区的
长度赋给N,若循环行列中元素的个数小于数组缓存区的长度则将循环行列元素的个数赋给N
2.循环行列拓荒得越大,能缓存的字符串就越多,因而是越大越好.
3.数组缓存区并不是拓荒的越大越好,这个值能够做如下的核算得出,假定波特率为115200嘀嗒中止
的周期为2毫秒则在这2毫秒时刻内理论上最多可传115200*0.002/10=23个字节。因而把数组缓存区
的巨细定到比23稍小一点即可,比方定为20.
代码可正常运转。经测验运用新计划printf一个包括了二十个字符的字符串只需求25微秒的CPU耗时,
而老计划则需求1.76毫秒的CPU耗时。然后能够定心的运用printf调试一些时序要求较高的函数了,
别的由于碑文时刻段然后printf被重入的概率大大减小。假如需求完全避免printf被重入的话,可在调用printf之前关中止,在printf碑文完之后开中止,价值也仅是可能发生的几十微秒的中止延时罢了。

……………………………………………………………………………..

下面讲一讲我对DMA的了解

stm32DMA有8通道,07

已然DMA传输的是数据,当然有数据的宽度了,这需求装备。别的还要有地址吧,从哪个地址开端传,还有传到哪个地址,需求装备。还有传输一般的就直接传完就好了,假如要高速不断循环传输,这也能够装备。还有从ROM直接快速的加载到RAM(反过来不能够)也能够的。

之上便是一些根本需求装备的作业

DMA_DeInit(DMA1_Channel4);

上面这句是给DMA装备通道,依据ST供给的材料,STM3210Fx中DMA包括7个通道

DMA_InitStructure.DMA_PeripheralBaseAddr = (uint32_t)(&((USART_TypeDef *)USART1)->DR);
上面是设置外设地址

DMA_InitStructure.DMA_MemoryBaseAddr = (uint32_t) USART_DMA_BUF;

上面这句很显然是DMA要衔接在Memory中变量的地址,上面设置存储器地址;

DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralSRC;

上面的这句是设置DMA的传输方向,就如前面我所说的,从存储器到外设,也能够从外设到存储器,:把DMA_DIR_PeripheralSRC改成DMA_DIR_PeripheralDST即可。

DMA_InitStructure.DMA_BufferSize = 0;

上面的这句是设置DMA在传输时缓冲区的长度,前面有界说过了buffer的开端地址:为了安全性和可靠性,一般需求给buffer界说一个贮存片区,这个参数的单位有三种类型:Byte、HalfWord、word,我设置的2个half-word(见下面的设置);32位的MCU中1个half-word占16 bits。

DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable;

上面的这句是设置DMA的外设递加方法,假如DMA选用的通道(CHx)有多个外设衔接,需求运用外设递加方法:DMA_PeripheralInc_Enable;我的比如选用DMA_PeripheralInc_Disable

DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable;

上面的这句是设置DMA的内存递加方法,DMA拜访多个内存参数时,需求运用DMA_MemoryInc_Enable,当DMA只拜访一个内存参数时,可设置成:DMA_MemoryInc_Disable。

DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_Byte;

上面的这句是设置DMA在拜访时每次操作的数据长度。有三种数据长度类型,前面现已讲过了,这儿不在叙说。

DMA_InitStructure.DMA_MemoryDataSize = DMA_PeripheralDataSize_Byte;

与上面相同。在此不再阐明。

DMA_InitStructure.DMA_Mode = DMA_Mode_Normal;

上面的这句是设置DMA的传输方法:接二连三的循环方法,若只想拜访一次后就不要拜访了(或按指令操作来反诘,也便是想要它拜访的时分就拜访,不要它拜访的时分就中止),能够设置成通用方法:DMA_Mode_Normal

DMA_InitStructure.DMA_Priority = DMA_Priority_Low;

上面的这句是设置DMA的优先等级:能够分为4级:VeryHigh,High,Medium,Low.

DMA_InitStructure.DMA_M2M = DMA_M2M_Disable;

上面的这句是设置DMA的2个memory中的变量相互拜访的

DMA_Init(DMA_Channel1,&DMA_InitStructure);

前面那些都是对DMA结构体成员的设置,在次再共同对DMA整个模块做一次初始化,使得DMA各成员与上面的参数共同。

DMA_Cmd(DMA_Channel1,ENABLE);

ok上面的装备作业完结了,相当于设定了一根管道经过DMA把缓冲区中要发送的数据发送到串口中。当然要使得DMA与usart1相衔接,在usart1中还要把usart的DMA功用翻开:USART_DMACmd(USART1, USART_DMAReq_Tx, ENABLE);接着在程序中只需求监控,数据发送的状况,并当令的翻开或封闭DMA,藏着下一次的串口发送用。

函数重载的printf()函数如下

int fputc(int ch, FILE *f)
{
while(En_Usart_Queue(ch)==-1);
return ch;
}

开端便是往环形缓冲区中添加要串口打印的数据,这个动作是比较快的。由于cpu直接移动数据很快,而经过cpu来操作串口,等候收成反映,有个while(..)是比较慢得,故有几个毫秒的延时。现在好了,cpu ,经过printf只是移动数据到了缓冲区,缓冲区在必定的时分,cpu指挥dma来开端接下来的操作,然后dma操作,cpu接着做其他的作业,只是只需在下次闲暇的时分来查一下dma有木有传输完结,或许有没有传输过错,并改动环形行列首位的方位,以及更改相应的状况就能够了。这样能够大大的节约许多的时刻哦。
环形行列的结构,咱们能够看一些算法,不是很难的。

下面是运转过程中,cpu操作查询的函数。

void DMA_USART_Handler(void){
u16 num=0;
s16 read;
if(DMA_GetCurrDataCounter(DMA1_Channel4)==0){ //查看DMA是否完结传输使命
DMA_Cmd(DMA1_Channel4, DISABLE);
while((read=De_Usart_Queue())!=-1){
USART_DMA_BUF[num]=read;
num++;
if(num==USART_DMA_BUF_SIZE)
break;
}
if(num>0){
((DMA_Channel_TypeDef *)DMA1_Channel4)->CNDTR = num;//数量寄存器清零
DMA_Cmd(DMA1_Channel4, ENABLE);
}
}
}

一.DMA原理:

DMA(Direct Memory Access,直接内存存取) 是一切现代电脑的重要特征,它答应不同速度的硬件设备来交流,而不需求依于 CPU 的很多 中止 负载。不然,CPU 需求从 来历 把每一片段的材料到 暂存器,然后把它们再次写回到新的当地。在这个时刻中,CPU 关于其他的作业来说就无法运用。

DMA 传输将数据从一个地址空间到别的一个地址空间。当 CPU 初始化这个传输动作,传输动作自身是由 DMA 操控器 来实施和完结。典型的比如便是移动一个外部内存的区块到芯片内部更快的内存区。像是这样的操作并没有让处理器作业延迟,反而能够被从头排程去处理其他的作业。

二.STM32运用DMA

1.DMA的设置:

要装备的有DMA传输通道挑选,传输的成员和方向、一般方法仍是循环方法等等。

void DMA_Configuration(void)
{
DMA_InitTypeDef DMA_InitStructure;
//DMA设置:
//设置DMA源:内存地址&串口数据寄存器地址
//方向:内存–>外设
//每次传输位:8bit
//传输巨细DMA_BufferSize=SENDBUFF_SIZE
//地址自增方法:外设地址不增,内存地址自增1
//DMA方法:一次传输,非循环
//优先级:中
DMA_DeInit(DMA1_Channel4);//串口1的DMA传输通道是通道4
DMA_InitStructure.DMA_PeripheralBaseAddr = USART1_DR_Base;
DMA_InitStructure.DMA_MemoryBaseAddr =(u32)SendBuff;//DMA拜访的数据地址
DMA_InitStructure.DMA_DIR =DMA_DIR_PeripheralDST;//外设作为DMA的意图端
DMA_InitStructure.DMA_BufferSize = SENDBUFF_SIZE;//传输数据巨细
DMA_InitStructure.DMA_PeripheralInc =DMA_PeripheralInc_Disable;//外设地址不添加
DMA_InitStructure.DMA_MemoryInc =DMA_MemoryInc_Enable;//内存地址自增1
DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_Byte;
DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_Byte;
DMA_InitStructure.DMA_Mode =DMA_Mode_Circular;
//DMA_Mode_Normal(只传送一次),DMA_Mode_Circular (循环传送)
DMA_InitStructure.DMA_Priority = DMA_Priority_Medium;//(DMA传送优先级为中等)
DMA_InitStructure.DMA_M2M = DMA_M2M_Disable;
DMA_Init(DMA1_Channel4, &DMA_InitStructure);
}
注:
1、传输通道:经过查表,串口1的发送对应的是DMA的通道4,所以此处挑选通道4.
2、DMA传输办法:
(1) DMA_Mode_Normal,正常方法,当一次DMA数据传输完后,中止DMA传送,关于上例而言,便是DMA_PeripheralDataSize_Byte个字节的传送完结后,就中止传送。
(2)DMA_Mode_Circular
循环方法,当传输完一次后,从头接着传送,永不暂停。
2、外设的DMA办法设置
将串口1设置成DMA方法:
USART_DMACmd(USART1, USART_DMAReq_Tx, ENABLE);
3、待传输数据的界说和初始化
#define SENDBUFF_SIZE10240
vu8 SendBuff[SENDBUFF_SIZE];
for(i=0;i{
SendBuff[i] = i+0;
}
4、开端DMA传输(使能对应的DMA通道)
DMA_Cmd(DMA1_Channel4, ENABLE);
5、DMA传输的完结
while(DMA_GetFlagStatus(DMA1_FLAG_TC4) == RESET)
{
LED_1_REV;//LED改动亮灭
Delay();//浪费时刻
}
当传输完结后,就会跳出上面的死循环。
下面是九九的一个例程,测验过,能够运转!
#include “stm32f10x_lib.h”
#include “stdio.h”

#define USART1_DR_Base0x40013804

#define SENDBUFF_SIZE10240
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+0;
}
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)
{
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<0xF0;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~24MHzLatency=0
//SYSCLK = 24~48MHzLatency=1
//SYSCLK = 48~72MHzLatency=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;
#ifdefVECT_TAB_RAM
// Set the Vector Table base location at 0x20
NVIC_SetVectorTable(NVIC_VectTab_RAM, 0x0);
#else
// Set the Vector Table base location at 0x08
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);//串口1的DMA传输通道是通道4
DMA_InitStructure.DMA_PeripheralBaseAddr = USART1_DR_Base;
DMA_InitStructure.DMA_MemoryBaseAddr = (u32)SendBuff;
DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralDST;//外设作为DMA的意图端
DMA_InitStructure.DMA_BufferSize = SENDBUFF_SIZE;//传输巨细
DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable;//外设地址不添加
DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable;//内存地址自增1
DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_Byte;
DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_Byte;
DMA_InitStructure.DMA_Mode = DMA_Mode_Circular;//DMA_Mode_Normal(只传送一次),DMA_Mode_Circular (不停地传送)
DMA_InitStructure.DMA_Priority = DMA_Priority_Medium;//(DMA传送优先级为中等)
DMA_InitStructure.DMA_M2M = DMA_M2M_Disable;
DMA_Init(DMA1_Channel4, &DMA_InitStructure);
}

声明:本文内容来自网络转载或用户投稿,文章版权归原作者和原出处所有。文中观点,不代表本站立场。若有侵权请联系本站删除(kf@86ic.com)https://www.86ic.net/bandaoti/fenxiao/264798.html

为您推荐

联系我们

联系我们

在线咨询: QQ交谈

邮箱: kf@86ic.com

关注微信
微信扫一扫关注我们

微信扫一扫关注我们

返回顶部