搜档网
当前位置:搜档网 › stm32 串口中断总结

stm32 串口中断总结

stm32 串口中断总结
stm32 串口中断总结

本文以USART1为例,叙述串口中断的编程过程。

1、先来讲述一下在应用串口中断时涉及到的一些库文件。

首先对于STM32外设库文件的应用编程,misc.c和stm32f10x_rcc.c是肯定要添加到。

接下来就是我们要用到的相关外设了。毫无疑问,串口文件stm32f10x_usart.c是必须的。串口通信是对通用GPIO端口引脚的功能复用,所以还需要stm32f10x_gpio.c文件。另外,因为有中断的产生,所以中断文件stm32f10x_it.c也是必要的,当然这个文件一般和main.c 放在一个文件夹下(一般习惯为User文件夹),因为我们的中断响应函数是要在里面自己编写的。

当然还有其他的基本必须文件如系统配置文件等在这地方就不说了,这个是创建一个工程应该知道的。

2、初始化

对于串口通信的初始化,不仅仅只是对串口的初始化(这个地方是比较烦人的,不像别的芯片那样简洁明了)。

●?首先时钟使能配置。STM32内部的时钟有很多,感兴趣的自己看看参考手册。此处

以USART1为例说明。有USART1时钟、GPIOA时钟、GPIO复用(AFIO)时钟。由于

此处USART1和GPIOA、AFIO均在APB2上,所以可以一次配置完成。如下:

RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA|RCC_APB2Periph_AFIO|RCC_APB

2Periph_USART1 ,ENABLE);

●?其次中断配置。主要有优先级组设定、USART1中断使能、该中断的优先级,中断初

始化。程序如下:

void NVIC_Configuration(void)

{

NVIC_InitTypeDef NVIC_InitStructure;

NVIC_PriorityGroupConfig(NVIC_PriorityGroup_0);//选择分组方式0

/* 使能 USART1中断 */

NVIC_InitStructure.NVIC_IRQChannel = USART1_IRQn;

NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;

NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;

NVIC_Init(&NVIC_InitStructure);

}

●?然后GPIO复用功能配置。一般情况下我们使用原始的外设和GPIO端口引脚的映射

关系,如果要改变其映射的话,请另外查看参考手册上关于GPIO重映射部分。对

于GPIO的复用,其引脚的输入与输出模式都有要求,在参考手册上有详细说明。

void GPIO_Configuration(void)

{

GPIO_InitTypeDef GPIO_InitStructure;

/* 配置 USART1 Rx 作为浮空输入 */

GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10;

GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;

GPIO_Init(USARTy_GPIO, &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(USARTy_GPIO, &GPIO_InitStructure);

}

串口初始化配置。主要有串口基本参数配置(如波特率、数据位、工作方式等),串口中断使能,串口使能。

(1) 基本参数配置

USART_InitTypeDef USART_InitStructure;

USART_https://www.sodocs.net/doc/3e6039902.html,ART_BaudRate = 9600;//波特率

USART_https://www.sodocs.net/doc/3e6039902.html,ART_WordLength = USART_WordLength_8b;//数据长度

USART_https://www.sodocs.net/doc/3e6039902.html,ART_StopBits = USART_StopBits_1;//停止位

USART_https://www.sodocs.net/doc/3e6039902.html,ART_Parity = USART_Parity_No;//校验

USART_https://www.sodocs.net/doc/3e6039902.html,ART_HardwareFlowControl

=USART_HardwareFlowControl_None;//硬件流控制无

USART_https://www.sodocs.net/doc/3e6039902.html,ART_Mode = USART_Mode_Rx | USART_Mode_Tx;//发

送与接受两种方式

USART_Init(USART1, &USART_InitStructure);//用配置的参数惊喜串口初始化

(2) 串口中断使能

USART_ITConfig(USARTy, USART_IT_RXNE, ENABLE);//使能接受中断,在接受移位寄存器中有数据是产生

USART_ITConfig(USARTy, USART_IT_TXE, ENABLE);//使能发送中断,在发送完数据后产生。

一般情况下,如果与PC通信的话,我们只用接受中断即可。

(3) 串口使能

USART_Cmd(USART1, ENABLE);//USART1使能

好了,经过以上不走之后呢,我们就可以进行数据的收发了。

3、发送数据

使用函数USART_SendData(USART1, char data),一次只能发送一个字符。当然我们可以用如下函数发送字符串。

void USART1_Puts(char * str)

{

while(*str)

{

USART_SendData(USART1, *str++); //发送一个字符

while(USART_GetFlagStatus(USART1, USART_FLAG_TXE) == RESET); //等待发送完毕

}

}

当然我们也可以循环发送字符串数组

for(i = 0; TxBuf1 != '\0'; i++) // TxBuf1为定义好的字符串数组

{

USART_SendData(USART2 , TxBuf1);

while(USART_GetFlagStatus(USART2, USART_FLAG_TC)==RESET);

}

4、接收数据

由于我们使用的是接受中断,所以当有数据需要接收时,会执相应的中断函数。此处我们USART1的中断函数在stm32f10x_it.c文件中。找到函数void USART1_IRQHandler(void),如果没有的话就自己加上吧,别忘了头文件中需要声明一下。当然你也可以在其他文件中写下该中断函数。当产生中断进入该函数之后,我们就可以进行自己的操作了。

void USARTy_IRQHandler(void)

{

if(USART_GetITStatus(USARTy, USART_IT_RXNE) != RESET)//如果寄存器中有数据

{

/* Read one byte from the receive data register */

RxBuffer1[RxCounter1++] = USART_ReceiveData(USART1);

}

/*************************************************************

if(USART_GetITStatus(USARTy, USART_IT_TXE) != RESET)

{

USART_SendData(USARTy, TxBuffer1[TxCounter1++]);

}

//这个地方那个之所以把这个写出来主要是想说发送中断和接受中断其实是共用一个//中断函数的,到底是那个中断发生了呢,这就需要我们读取中断状态标志来识别了。

*****************************************************************/

}

别忘了在接受完数据进行别的操作之前为了防止数据被覆盖最好先禁止一下接受中断/* 禁止 USART1接收中断 */

USART_ITConfig(USART1, USART_IT_RXNE, DISABLE);

/* 禁止 USART1发送中断 */

USART_ITConfig(USART1, USART_IT_TXE, DISABLE);

5、main函数

int main(void)//这个地方和特别,我们知道一般main函数是没有返回值的,但在STM32//的编程中其返回类型为int。

{

RCC_Configuration();

NVIC_Configuration();

GPIO_Configuration();

USART_https://www.sodocs.net/doc/3e6039902.html,ART_BaudRate = 9600;

USART_https://www.sodocs.net/doc/3e6039902.html,ART_WordLength = USART_WordLength_8b;

USART_https://www.sodocs.net/doc/3e6039902.html,ART_StopBits = USART_StopBits_1;

USART_https://www.sodocs.net/doc/3e6039902.html,ART_Parity = USART_Parity_No;

USART_https://www.sodocs.net/doc/3e6039902.html,ART_HardwareFlowControl= USART_HardwareFlowControl_None;

USART_https://www.sodocs.net/doc/3e6039902.html,ART_Mode = USART_Mode_Rx | USART_Mode_Tx;

USART_Init(USART1, &USART_InitStructure);

USART_ITConfig(USART1, USART_IT_RXNE, ENABLE);

//USART_ITConfig(USART1, USART_IT_TXE, ENABLE);

USART_Cmd(USART1, ENABLE);

while (1)//等待中断

{

}

}

当然你也可以在main()中添加一些发送指令之类的东西。

以上内容为个人总结,转载请注明出处。若有错误,本人概不负任何责任。

STM32 外部中断配

NVIC_Configuration 函数实现配置嵌套向量中断中断优先级并使能中断。其中的NVIC_PriorityGroupConfig 函数配置中断优先级的组织方式,STM32 的嵌套向量中断控制器可以配置16 个可编程的优先等级,使用了4 位表示中断优先级(2 的 4 此方就是16),16 个可编程的优先等级又可以分为主优先级和次优先级,例如参数NVIC_PriorityGroup_1表示1bit 主优先级(pre-emption priority)3 bits 次优先级(subpriority )。

一、配置中断

1、分配中断向量表:

/* Set the Vector Table base location at 0x20000000 */

NVIC_SetVectorTable(NVIC_VectTab_RAM, 0x0);

2、设置中断优先级:

NVIC_PriorityGroupConfig(NVIC_PriorityGroup_0); //设置中断优先级

3、初始化外部中断:

/*允许EXTI4中断*/

NVIC_InitStructure.NVIC_IRQChannel = EXTI4_IRQChannel; //中断通道NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority= PreemptionPriorityValue; //占先优先级

NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0; //响应(次级)优先级NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; //通道中断使能

NVIC_Init(&NVIC_InitStructure); //初始化中断

注意:如果我们配置的外部针脚为PA4,或PB4,或PC4,PD4等,那么采用的外部

中断也必须是EXTI4,同样,如果外部中断针脚是PA1,PB1,PC1,PD1 那么中断就要用EXTI1,其他类推。

二、配置GPIO针脚作为外部中断的触发事件

1、选择IO针脚

GPIO_InitStructure.GPIO_Pin = GPIO_Pin_4;

注意,如果的针脚是端口的4号针脚,配置的中断一定是EXTI4

2、配置针脚为输入

GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;

3、初始化针脚

GPIO_Init(GPIOD,&GPIO_InitStructure);

3配置EXTI线,使中断线和IO针脚线连接上

1、将EXTI线连接到IO端口上

将EXTI线4连接到端口GPIOD的第4个针脚上

GPIO_EXTILineConfig(GPIO_PortSourceGPIOD,GPIO_PinSource4);

注意:如果配置的针脚是4号,那么参数必须是GPIO_PinSource4

如果配置的针脚是3号,那么参数必须是GPIO_PinSource3

2、配置中断边沿

/*配置EXTI线4上出现下降沿,则产生中断*/

EXTI_InitStructure.EXTI_Line = EXTI_Line4;

注意:如果配置的4号针脚,那么EXTI_Line4是必须的

EXTI_InitStructure.EXTI_Mode = EXTI_Mode_Interrupt;

EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Falling; //下降沿触发

EXTI_InitStructure.EXTI_LineCmd = ENABLE; //中断线使能

EXTI_Init(&EXTI_InitStructure); //初始化中断

EXTI_GenerateSWInterrupt(EXTI_Line4); //EXTI_Line4中断允许

到此中断配置完成,可以写中断处理函数。

举例:

配置函数

/************************************************************* ************

* 函数名NVIC_Configration

* 描述配置各个中断寄存器

************************************************************** **************/

void NVIC_Configration(void)

{

NVIC_InitTypeDef NVIC_InitStructure;

//#ifdef VECT_TAB_RAM

/* Set the Vector Table base location at 0x20000000 */

NVIC_SetVectorTable(NVIC_VectTab_RAM, 0x0);

//#else /* VECT_TAB_FLASH */

/* Set the Vector Table base location at 0x08000000 */

//NVIC_SetVectorTable(NVIC_VectTab_FLASH, 0x0);

//#endif

NVIC_PriorityGroupConfig(NVIC_PriorityGroup_0); //设置中断优先级

/*允许EXTI4中断*/

NVIC_InitStructure.NVIC_IRQChannel = EXTI4_IRQChannel;

NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = PreemptionPriorityValue;

NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;

NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;

NVIC_Init(&NVIC_InitStructure);

/*允许EXTI9中断*/

NVIC_InitStructure.NVIC_IRQChannel = EXTI9_5_IRQChannel;

NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;

NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1;

NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;

NVIC_Init(&NVIC_InitStructure);

/*配置SysTick处理优先级:优先级以及子优先级*/

}

/************************************************************* ***********

* 函数名GPIO_Configuration(void)

* 描述配置TIM2针脚

************************************************************** **********/

void GPIO_Configuration(void){

/* GPIO_InitTypeDef GPIO_InitStructure;

GPIO_InitStructure.GPIO_Pin=

GPIO_Pin_0|GPIO_Pin_1|GPIO_Pin_2|GPIO_Pin_3;

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

GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;

GPIO_InitStructure.GPIO_Speed = GPIO_Speed_2MHz;

GPIO_Init(GPIOC,&GPIO_InitStructure);

/*配置GPIOD的第一个管角为浮动输入*/

GPIO_InitStructure.GPIO_Pin = GPIO_Pin_4;

GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;

GPIO_Init(GPIOD,&GPIO_InitStructure);

/*配置GPIOB的第9个管脚为浮动输入*/

GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9;

GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;

GPIO_Init(GPIOB,&GPIO_InitStructure);

}

/************************************************************* *

* 函数SysTick_Configuration

* 描述设置SysTick

************************************************************** */

void SysTick_Configuration(void)

{

/*配置HCLK 时钟做为SysTick 时钟源*/

SysTick_CLKSourceConfig(SysTick_CLKSource_HCLK_Div8); //系统时钟8分频72MHz

NVIC_SystemHandlerPriorityConfig(SystemHandler_SysTick, 8,2);

/*SysTick Interrupt each 1000Hz with HCLK equal to 72MHz*/

SysTick_SetReload(9000);//中断周期1ms

/*Enable the SysTick Interrupt */

SysTick_ITConfig(ENABLE);//打开中断

SysTick_CounterCmd(SysTick_Counter_Enable);

SysTick_CounterCmd(SysTick_Counter_Clear);

}

/************************************************************* *****************

* 函数名EXTI_Configuration

* 描述配置EXTI线

************************************************************** ****************/

void EXTI_Configuration(void){

/*将EXTI线4连接到PD4*/

GPIO_EXTILineConfig(GPIO_PortSourceGPIOD,GPIO_PinSource4);

/*配置EXTI线4上出现下降沿,则产生中断*/

EXTI_InitStructure.EXTI_Line = EXTI_Line4;

EXTI_InitStructure.EXTI_Mode = EXTI_Mode_Interrupt;

EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Falling;

EXTI_InitStructure.EXTI_LineCmd = ENABLE;

EXTI_Init(&EXTI_InitStructure);

EXTI_GenerateSWInterrupt(EXTI_Line4);

/*将EXTI线9连接到PB9上*/

GPIO_EXTILineConfig(GPIO_PortSourceGPIOB,GPIO_PinSource9);

/*将EXTI线9上出现下降沿产生中断*/

EXTI_InitStructure.EXTI_Line = EXTI_Line9;

EXTI_InitStructure.EXTI_Mode = EXTI_Mode_Interrupt;

EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Falling;

EXTI_InitStructure.EXTI_LineCmd = ENABLE;

EXTI_Init(&EXTI_InitStructure);

EXTI_GenerateSWInterrupt(EXTI_Line9);

}

中断函数:

void EXTI4_IRQHandler(void)

{

if(EXTI_GetITStatus(EXTI_Line4)!= RESET)

{

if(Ledflag == 0)

{

Ledflag = 1;

GPIOC->ODR |= 0X00000080;

}

else

{

Ledflag = 0;

GPIOC->ODR &= 0XFFFFFF7F;

}

EXTI_ClearITPendingBit(EXTI_Line4); //清除EXTI0线路挂起位

}

注:时钟设置的时候最好加上这句:

RCCRCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO, ENABLE); // 使能AFIO时钟

================================================ /************************************************************* ************************************************************** 例程名称:外部中断实验

实验硬件:DP-miniSTM32

硬件连接:指示灯连接PA1

按钮连接PA3

功能描述:本例程实现外部中断的输入试验,按下按钮,指示灯闪烁一下

************************************************************** ******/

#include // STM32F10x Library Definitions

#include "STM32_Init.h" // STM32 Initialization

/************************************************************* *********

* 名称:Delay()

*************************************************************/ void Delay(vu16 cnt) {

uint16 i,j;

for (i=0;i

{ for (j=0;j<1000;j++)

{ }

}

}

/*************************************************************

* 名称:RCC_Configuration()

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

RCC_PLLConfig(RCC_PLLSource_HSE_Div1, RCC_PLLMul_4);

//启动PLL

RCC_PLLCmd(ENABLE);

//等待PLL稳定

while(RCC_GetFlagStatus(RCC_FLAG_PLLRDY) == RESET);

//系统时钟SYSCLK来自PLL输出

RCC_SYSCLKConfig(RCC_SYSCLKSource_PLLCLK);

//切换时钟后等待系统时钟稳定

while(RCC_GetSYSCLKSource()!=0x08);

}

/* RCC system reset(for debug purpose) */

RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA|RCC_APB2Periph_AFI O , ENABLE); //给GPIOA和重映射提供时钟,注意:一定要设置RCC_APB2Periph_AFIO

}

/************************************************************* *********

* 名称:GPIO_Configuration()

*************************************************************/ void GPIO_Configuration(void)

{

GPIO_InitTypeDef GPIO_InitStructure;

/*设置PA3为输入*/

GPIO_InitStructure.GPIO_Pin = GPIO_Pin_3;

GPIO_InitStructure.GPIO_Speed = GPIO_Speed_10MHz;

GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;

GPIO_Init(GPIOA,&GPIO_InitStructure);

/*设置PA1为输出*/

GPIO_InitStructure.GPIO_Pin = GPIO_Pin_1;

GPIO_InitStructure.GPIO_Speed = GPIO_Speed_10MHz;

GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;

GPIO_Init(GPIOA, &GPIO_InitStructure);

}

/************************************************************* *********

* 名称:EXTI_Configuration()

************************************************************** *********/

void EXTI_Configuration(void)

{

EXTI_InitTypeDef EXTI_InitStructure;

/* Configure EXTI Line3 to generate an interrupt on falling edge */

EXTI_InitStructure.EXTI_Line = EXTI_Line3; //外部中断通道3 EXTI_InitStructure.EXTI_Mode = EXTI_Mode_Interrupt;

EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Falling; //下降沿触发EXTI_InitStructure.EXTI_LineCmd = ENABLE; //使能

EXTI_Init(&EXTI_InitStructure);

GPIO_EXTILineConfig(GPIO_PortSourceGPIOA, GPIO_PinSource3); //将PA3连接到外部中断通道3

}

/************************************************************* *********

* 名称:NVIC_Configuration()

*************************************************************/ 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/* VECT_TAB_FLASH */

/* Set the Vector Table base location at 0x08000000 */

NVIC_SetVectorTable(NVIC_VectTab_FLASH, 0x0);

#endif

NVIC_PriorityGroupConfig(NVIC_PriorityGroup_0); //抢占式优先级别设置为无抢占优先级

NVIC_InitStructure.NVIC_IRQChannel = EXTI3_IRQChannel; //指定中断源NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1; //指定响应优先级别1

NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; //使能外部中断通道3

NVIC_Init(&NVIC_InitStructure);

}

int main (void)

{

RCC_Configuration(); //配置时钟

GPIO_Configuration(); //配置IO口

NVIC_Configuration(); //中断配置

EXTI_Configuration(); //外部中断配置

while(1)

{

}

}

/************************************************************ **********

* 说明:将LED灯的连接到PA1

*************************************************************/

void EXTI3_IRQHandler (void)

{

if(EXTI_GetITStatus(EXTI_Line3) != RESET)

{

//添加中断处理程序

GPIO_WriteBit(GPIOA, GPIO_Pin_1,(BitAction)0);

Delay(1000);

GPIO_WriteBit(GPIOA, GPIO_Pin_1,(BitAction)1);

Delay(1000);

EXTI_ClearFlag(EXTI_Line3); //清除中断标志(必须)

EXTI_ClearITPendingBit(EXTI_Line3);

// 以上两条语句作用相同

}

}

================================================

在使用EXTI的时候,因为没有开启时钟没有开启RCC_APB2Periph_AFIO时钟,让我调试吃了不少苦头,看来还要好好看看stm32的时钟啊

现在给出我的exti8的配置

首先一定要记得配置

RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO, ENABLE); // 使能AFIO时钟

//GPIOB8作为中断脚,配置为浮空输入

void GPIO_Configuration(void)

{

GPIO_InitTypeDef GPIO_InitStructure;

/* Configure PB8 as input floating */

GPIO_InitStructure.GPIO_Pin = GPIO_Pin_8;

GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;

GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;

GPIO_Init(GPIOB,&GPIO_InitStructure);

}

继续配置NVIC

void NVIC_Configuration(void)

{

NVIC_InitTypeDef NVIC_InitStructure;

NVIC_InitStructure.NVIC_IRQChannel = EXTI9_5_IRQn;

NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;

NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;

NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;

NVIC_Init(&NVIC_InitStructure);

/* Configure the NVIC Preemption Priority Bits*/

NVIC_PriorityGroupConfig(NVIC_PriorityGroup_0);

/* Set the Vector Table base location at 0x08000000 */

NVIC_SetVectorTable(NVIC_VectTab_FLASH, 0x0);

}

然后配置EXTI ,把PB8连接到EXTI

void EXTI_Configuration(void)

{

EXTI_InitTypeDef EXTI_InitStructure;

/*connect PB8 to EXTI*/

GPIO_EXTILineConfig(GPIO_PortSourceGPIOB,GPIO_PinSource8);

/*Config EXTI8*/

EXTI_InitStructure.EXTI_Line = EXTI_Line8;

EXTI_InitStructure.EXTI_Mode = EXTI_Mode_Interrupt;

EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Falling;

EXTI_InitStructure.EXTI_LineCmd = ENABLE;

EXTI_Init(&EXTI_InitStructure);

//EXTI_GenerateSWInterrupt(EXTI_Line8);

}

这样就可以中断了,

在中断函数里面记得清除标志位

void EXTI9_5_IRQHandler(void)

{

if(EXTI_GetITStatus(EXTI_Line8)!= RESET)

{

EXTI_ClearITPendingBit(EXTI_Line8);

}

}

关于STM32串口空闲中断IDEL的问题

关于STM32串口空闲中断IDEL的问题 1.空闲中断是接受数据后出现一个byte 的高电平(空闲)状态,就会触发空闲 中断.并不是空闲就会一直中断,准确的说应该是上升沿(停止位)后一个 byte,如果一直是低电平是不会触发空闲中断的(会触发break 中断)。 2.关于第二点有要铺垫的三个情况,datasheet 中”当一空闲帧被检测到时,其处 理步骤和接收到普通数据帧一样,但如果IDLEIE 位被设置将产生一个中断”“空 闲符号被视为完全由'1'组成的一个完整的数据帧,后面跟着包含了数 据的下一帧的开始位'1'的位数也包括了停止位的位数”空闲符号的 配图后面跟这一个低电平.有人理解为只有收到下一个数据的起始位才会触发中 断,这样理解是不对的,应该是数据后有空闲了一帧就会触发. 3.清中断的方式感觉奇怪,使用函数USART_ClearITPendingBit( USART1, USART_IT_IDLE )清除不了中断的.我用的是3.5 的库,查看函数说明,里面的 @param 参数并没有IDLE,后面的@note 中,这样说:”PE(Parity error),FE(Framing error),NE(Noise error),ORE(OverRun error) and IDLE(Idle line detected) pending bits are cleared by software sequence: a read operation to USART_SR register (USART_GetITStatus()) followed by a read operation to USART_DR register (USART_ReceiveData()).”我是通过语句”USART1->DR;”来清除IDLE 中断的. 现在有很多数据处理都要用到不定长数据,而单片机串口的RXNE 中断一次 只能接收一个字节的数据,没有缓冲区,无法接收一帧多个数据,现提供两种 利用串口IDLE 空闲中断的方式接收一帧数据,方法如下: 方法1:实现思路:采用STM32F103 的串口1,并配置成空闲中断IDLE 模 式且使能DMA 接收,并同时设置接收缓冲区和初始化DMA。那么初始化完成 之后,当外部给单片机发送数据的时候,假设这帧数据长度是200 个字节,那

TMS320F28335外部中断总结

TMS320F28335外部中断总结 作者:Free 文章来源:Free 点击数:93 更新时间:2010-8-26 在这里我们要十分清楚DSP的中断系统。C28XX一共有16个中断源,其中有2个不可屏蔽的中断RESET和NMI、定时器1和定时器2分别使用中断13 和14。这样还有12个中断都直接连接到外设中断扩展模块PIE上。说的简单一点就是PIE 通过12根线与28335核的12个中断线相连。而PIE的另外 一侧有12*8根线分别连接到外设,如AD、SPI、EXINT等等。这样PIE共管理12*8=96个外部中断。这12组大中断由28335核的中断寄存器IER来控 制,即IER确定每个中断到底属于哪一组大中断(如IER |= M_INT12;说明我们要用第12组的中断,但是第12组里面的什么中断CPU并不知道需 要再由PIEIER确定)。接下来再由PIE模块中的寄存器PIEIER中的低8确定该中断是这一组的第几个中断,这些配置都要告诉CPU(我们不难想 象到PIEIER共有12总即从PIEIER1-PIEIER12)。另外,PIE模块还有中断标志寄存器PIEIFR,同样它的低8位是来自外部中断的8个标志位,同 样CPU的IFR寄存器是中断组的标志寄存器。由此看来,CPU的所有中断寄存器控制12组的中断,PIE的所有中断寄存器控制每组内8个的中断。 除此之外,我们用到哪一个外部中断,相应的还有外部中断的寄存器,需要注意的就是外部中断的标志要自己通过软件来清零。而PIE和CPU的 中断标志寄存器由硬件来清零。 EALLOW; // This is needed to write to EALLOW protected registers PieVectTable.XINT2 = &ISRExint; //告诉中断入口地址 EDIS; // This is needed to disable write to EALLOW protected registers PieCtrlRegs.PIECTRL.bit.ENPIE = 1; // Enable the PIE block使能PIE PieCtrlRegs.PIEIER1.bit.INTx5= 1; //使能第一组中的中断5 IER |= M_INT1; // Enable CPU 第一组中断

最新stm32学习之串口usart复习进程

STM32学习之串口USART STM32 的串口是相当丰富的。最多可提供5路串口,有分数波特率发生器、支持单线光通信和半双工单线通讯、支持LIN、智能卡协议和IrDA SIR ENDEC 规范(仅串口3 支持)、具有DMA 等。串口最基本的设置,就是波特率的设置。STM32 的串口使用起来还是蛮简单的,只要你开启了串口时钟,并设置相应IO口的模式,然后配置一下波特率,数据位长度,奇偶校验位等信息,就可以使用了。 1、串口时钟使能。串口作为STM32 的一个外设,其时钟由外设始终使能寄存器控制,这里我们使用的串口1是在APB2ENR 寄存器的第14 位。除了串口1 的时钟使能在APB2ENR寄存器,其他串口的时钟使能位都在APB1ENR。 1、串口的作用:用在STM32板子和PC机通信的。我们调试的时候,无法知道是否正确,就可以用STM32的cpu,给串口输出一些信息给PC,我们通过屏幕(实际上是终端串口软件),可以看到这些信息,从而知道当前程序的错误可能出现的位置。当然,也可以在PC的键盘敲打命令,让串口帮传递给STM32板子,来执行这些命令。 2、串口的工作模式一般有两种方式:查询和中断 (1)查询:串口程序不断地循环查询,看看当前有没有数据要它传,如果有,就帮助传送(可以从PC到STM32板子,也可以从STM32 板子到PC)。 (2)中断:平时串口只要打开中断即可。如果发现有一个中断来,则意味着要它帮助传输数据——它就马上进行数据的传送。同样,可以从PC到STM32板子,也可以从STM32板子到PC 。 步骤一从硬件开始学习。大家先打开芯达STM32开发板附带的原理图。找到串口部分。笔者把它截图如下。我们发现,串口模块的电路是这样的:STM32的CPU引脚,通过两个PA端口的引脚PA10和PA9(此两个引脚复用USART),连接到一个SP3232芯片,或者MAX232芯片。然后再连接到DB9串口座上。由于232芯片可以允许走两路信号,因此,我们扩展了一个串口COM2,请注意,如无特别说明,我们都将使用COM1。

STM32串口中断接收方式详细比较

本例程通过PC机的串口调试助手将数据发送至STM32,接收数据后将所接收的数据又发送至PC机,具体下面详谈。。。 实例一: void USART1_IRQHandler(u8 GetData) { u8 BackData; if(USART_GetITStatus(USART1, USART_IT_RXNE) != RESET) //中断产生 { USART_ClearITPendingBit(USART1,USART_IT_RXNE); //清除中断标志. GetData = UART1_GetByte(BackData); //也行GetData=USART1->DR; USART1_SendByte(GetData); //发送数据 GPIO_SetBits(GPIOE, GPIO_Pin_8 ); //LED闪烁,接收成功发送完成 delay(1000); GPIO_ResetBits(GPIOE, GPIO_Pin_8 ); } } 这是最基本的,将数据接收完成后又发送出去,接收和发送在中断函数里执行,main函数里无其他要处理的。 优点:简单,适合很少量数据传输。 缺点:无缓存区,并且对数据的正确性没有判断,数据量稍大可能导致数据丢失。 实例二: void USART2_IRQHandler() { if(USART_GetITStatus(USART2,USART_IT_RXNE) != RESET) //中断产生 { USART_ClearITPendingBit(USART2,USART_IT_RXNE); //清除中断标志 Uart2_Buffer[Uart2_Rx_Num] = USART_ReceiveData(USART2); Uart2_Rx_Num++; } if((Uart2_Buffer[0] == 0x5A)&&(Uart2_Buffer[Uart2_Rx_Num-1] == 0xA5)) //判断最后接收的数据是否为设定值,确定数据正确性 Uart2_Sta=1; if(USART_GetFlagStatus(USART2,USART_FLAG_ORE) == SET) //溢出 { USART_ClearFlag(USART2,USART_FLAG_ORE); //读SR USART_ReceiveData(USART2); //读DR } } if( Uart2_Sta ) { for(Uart2_Tx_Num=0;Uart2_Tx_Num < Uart2_Rx_Num;Uart2_Tx_Num++)

STM32 无中断串口代码

STM32 无中断串口代码2010-05-14 16:09 串口,是我们日常使用最多的一部分,刚开始做电子工程师的,基本都是从这个开始的,下面的代码是我使用STM32库编写的串口输出和读取的代码。 1、串口初始化函数:void USART_Ini(USART_TypeDef* USARTx,u16 buad) 2、串口中断开启和关闭:USART_IT(USART_TypeDef* USARTx,FunctionalState NewState) 3、串口接收:u16 Getch(USART_TypeDef* USARTx) 4、串口单个字符输出:void Putch(USART_TypeDef* USARTx,u16 ch) 5、串口输出字符串:void PutStr(USART_TypeDef* USARTx,u16 *SendBuf,u16 Length) #include "stm32f10x_lib.h" u16 RecDateBuffer[100]; u16 RecLen; u8 SendDateBuffer[100]; /************************************************************* ****************** * Function Name : Uart_Ini * Description : 串口初始化 * Input : * Output : None * Return : ************************************************************** *****************/ void USART_Ini(USART_TypeDef* USARTx,u16 buad) { USART_InitTypeDef USART_InitStructure; USART_ClockInitTypeDef USART_ClockIni; GPIO_InitTypeDef GPIO_InitStructure; /* Configure USART1 Tx (PA.09) as alternate function push-pull */ GPIO_InitStructure.GPIO_Pin = GPIO_Pin_5; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP; GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; GPIO_Init(GPIOD, &GPIO_InitStructure); /* Configure USART1 Rx (PA.10) as input floating */ GPIO_InitStructure.GPIO_Pin = GPIO_Pin_6;

stm32 串口中断总结

本文以USART1为例,叙述串口中断的编程过程。 1、先来讲述一下在应用串口中断时涉及到的一些库文件。 首先对于STM32外设库文件的应用编程,misc.c和stm32f10x_rcc.c是肯定要添加到。 接下来就是我们要用到的相关外设了。毫无疑问,串口文件stm32f10x_usart.c是必须的。串口通信是对通用GPIO端口引脚的功能复用,所以还需要stm32f10x_gpio.c文件。另外,因为有中断的产生,所以中断文件stm32f10x_it.c也是必要的,当然这个文件一般和main.c 放在一个文件夹下(一般习惯为User文件夹),因为我们的中断响应函数是要在里面自己编写的。 当然还有其他的基本必须文件如系统配置文件等在这地方就不说了,这个是创建一个工程应该知道的。 2、初始化 对于串口通信的初始化,不仅仅只是对串口的初始化(这个地方是比较烦人的,不像别的芯片那样简洁明了)。 ●?首先时钟使能配置。STM32内部的时钟有很多,感兴趣的自己看看参考手册。此处 以USART1为例说明。有USART1时钟、GPIOA时钟、GPIO复用(AFIO)时钟。由于 此处USART1和GPIOA、AFIO均在APB2上,所以可以一次配置完成。如下: RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA|RCC_APB2Periph_AFIO|RCC_APB 2Periph_USART1 ,ENABLE); ●?其次中断配置。主要有优先级组设定、USART1中断使能、该中断的优先级,中断初 始化。程序如下: void NVIC_Configuration(void) { NVIC_InitTypeDef NVIC_InitStructure; NVIC_PriorityGroupConfig(NVIC_PriorityGroup_0);//选择分组方式0 /* 使能 USART1中断 */ NVIC_InitStructure.NVIC_IRQChannel = USART1_IRQn; NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0; NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; NVIC_Init(&NVIC_InitStructure); } ●?然后GPIO复用功能配置。一般情况下我们使用原始的外设和GPIO端口引脚的映射 关系,如果要改变其映射的话,请另外查看参考手册上关于GPIO重映射部分。对 于GPIO的复用,其引脚的输入与输出模式都有要求,在参考手册上有详细说明。 void GPIO_Configuration(void) { GPIO_InitTypeDef GPIO_InitStructure; /* 配置 USART1 Rx 作为浮空输入 */ GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING; GPIO_Init(USARTy_GPIO, &GPIO_InitStructure); /* 配置 USART1 Tx 作为推挽输出 */ GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9; GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;

STM32个人总结

基础入门编 1.搭建开发环境 详情看光盘资料,主要是软件安装和设置。 2.新建工程 可以直接用模板,了解每个文件的含义,会使用chm帮助。 3.STM32库 库的含义。 4.GPIO流水灯 认识RCC,GPIO的各种模式,寄存器的种类和作用。 5.POLLING按键 主要介绍了各种模式,实验通过不断读取GPIO的状态以达到判断按键的目的。 6.EXTI按键 使用了GPIO的EXTI中断来判断按键,记住EXTI要开AFIO(重映射也要开),另外SYSTICK不归NVIC管。注意NVIC_IRQChannelSubPriority(),最多可以判断16种优先级,即16种中断,同一个中断入口的引脚引发的中断也算是同一种中断,同种种中断不能相互嵌套。(响应优先级是在抢占优先级相同时,同时发生才有用,其中一个发生后无用)。 7.SYSTICK 关键是SYSTICK的初始化函数,了解那几个寄存器的作用和特殊的宏定义(就是选择自己想选择的位),根据配置可以延时不同的时间,详情看代码。 8.串口通信 开启相应RCC,做好Iint,配置好中断(可选,主要用于接收),然后弄好fputc(),可以直接用printf()直接输出。 9.DMA 不经CPU处理直接相互传输,开启相应的DMA,配置好from..to..,字节大小等,用cmd 命令后可以开启传输。 10.ADC(DMA) 主要就是初始化好ADC,什么通道模式之类的,详情看代码,由于使用了DMA模式,要配置好DMA,有ADC_DMACmd()开始传输。 11..FSMC显示英文 用FSMC直接写入液晶的控制芯片的显存,注意使用的是16位的颜色,线的接法要注意(RGB为5:6:5)。 由于用的是模拟的方法,输入数据时用的都是宏,该地址线用来作为C/D,16位是往前移了一位的,因此要乘以2. 值得注意的是开窗的显示手法,在显示字符前先“开”一个窗,当一行数据写完时,自动换到下一行继续写。 在写数据的函数那里可以更换字的背景色,也可以修改该函数的.h的BACKGROUND 的宏定义。 FSMC的初始化暂时不清楚,应该是关于NOR FLASH的。控制代码是配好的,具体的设置看参考文档(有关定位坐标和扫描方式都与此有关)。 (NOR-FLASH 有4个bank,NE[3:0],区分不同的bank,实验用NE1;DataAddress_Mux 数据域地址线复用;8位地址线25:0->24:0 16位地址线25:1->24:0,宏定义是16位的地址线,对应的机内地址*2左移1位) 12.IIC-EEPROM

STM32 Uart串口中断响应、发送接收详细程序

程序实现功能:可以直接接收USART1的数据,并通过串口调试输出显示 #include"stm32f10x_lib.h" void NVIC_Configuration(void); void RCC_Configuration(void); void GPIO_Configuration(void); ErrorStatus HSEStartUpStatus; USART_InitTypeDef USART_InitStructure; USART_ClockInitTypeDef USART_ClockInitStructure; int main() { #ifdef DEBUG debug #endif RCC_Configuration(); NVIC_Configuration(); GPIO_Configuration(); /*串口传输速率的大小必须与RCC所设定的时钟相对应起来*/ USART_https://www.sodocs.net/doc/3e6039902.html,ART_BaudRate = 9600; //设置USART的传输速率/*设定数据的接收发送模式*/ USART_https://www.sodocs.net/doc/3e6039902.html,ART_WordLength = USART_WordLength_8b;//在一帧中传输或接受8位数据位 USART_https://www.sodocs.net/doc/3e6039902.html,ART_StopBits = USART_StopBits_1; //定义在帧的结尾传输一个停止位 USART_https://www.sodocs.net/doc/3e6039902.html,ART_Parity = USART_Parity_No; //奇偶失能 USART_https://www.sodocs.net/doc/3e6039902.html,ART_HardwareFlowControl = USART_HardwareFlowControl_None; //指定硬件流控制模式RTS和CTS使能 USART_https://www.sodocs.net/doc/3e6039902.html,ART_Mode = USART_Mode_Rx | USART_Mode_Tx; //指定使能或失能发送和接受模式Tx发送使能和Rx接收使能 USART_Clock https://www.sodocs.net/doc/3e6039902.html,ART_Clock = USART_Clock_Disable; //提升USART时钟时使能还是失能,钟低电平活动 USART_https://www.sodocs.net/doc/3e6039902.html,ART_CPOL = USART_CPOL_Low; //指定SLCK引脚上时钟的极性 USART_https://www.sodocs.net/doc/3e6039902.html,ART_CPHA = USART_CPHA_2Edge; //时钟第二个边缘进行数据捕获 USART_https://www.sodocs.net/doc/3e6039902.html,ART_LastBit = USART_LastBit_Disable; //在SCLK引脚上输出最后发送的那个数据字的脉冲不从SCLK输出 USART_ClockInit(USART1, &USART_ClockInitStructure); USART_Init(USART1, &USART_InitStructure); /*输入输出的中断使能*/ // USART_ITConfig(USART1, USART_IT_TXE, ENABLE); USART_ITConfig(USART1, USART_IT_RXNE, ENABLE);

STM32串口中断接收方式详细比较

串口中断接收方式详细比较 串口调试,以前也调过,只是没这么深入的琢磨过,最近又在弄,感觉串口很基本,也很有学问,要是出现BUG可能导致系统奔溃。。。现在贴出来,欢迎拍砖指正!!! 本例程通过PC机的串口调试助手将数据发送至STM32,STM32通过SP3232芯片采用中断接收方式完成,然后接收数据后将所接收的数据又发送至PC机,具体下面详谈。。。 实例一: void USART1_IRQHandler(u8 GetData) { u8 BackData; if(USART_GetITStatus(USART1, USART_IT_RXNE) != RESET) //中断产生 { USART_ClearITPendingBit(USART1,USART_IT_RXNE); //清除中断标志. GetData = UART1_GetByte(BackData); //也行GetData=USART1->DR; USART1_SendByte(GetData); //发送数据 GPIO_SetBits(GPIOE, GPIO_Pin_8 ); //LED闪烁,接收成功发送完成 delay(1000); GPIO_ResetBits(GPIOE, GPIO_Pin_8 ); } } 这是最基本的,将数据接收完成后又发送出去,接收和发送在中断函数里执行,main 函数里无其他要处理的。 优点:简单,适合很少量数据传输。 缺点:无缓存区,并且对数据的正确性没有判断,数据量稍大可能导致数据丢失。 实例二: void USART2_IRQHandler() { if(USART_GetITStatus(USART2,USART_IT_RXNE) != RESET) //中断产生 { USART_ClearITPendingBit(USART2,USART_IT_RXNE); //清除中断标志 Uart2_Buffer[Uart2_Rx_Num] = USART_ReceiveData(USART2); Uart2_Rx_Num++; } if((Uart2_Buffer[0] == 0x5A)&&(Uart2_Buffer[Uart2_Rx_Num-1] == 0xA5)) //判断最后接收的数据是否为设定值,确定数据正确性 Uart2_Sta=1; if(USART_GetFlagStatus(USART2,USART_FLAG_ORE) == SET) //溢出

stm32学习总结

学习总结 单片机学习经历总结 自从大二寒假接受了一次初始培训开始,我便开始了单片机的学习,一开始借了一块 MSP430G2553的板子,于是便从MSP开始学习单片机。一开始的我对于单片机一窍不通,只能对照着数据手册学习,逐渐开始了解什么是IO口,中断,定时器,AD转换等。开学来了以后接受了四次培训,期间又重新认识这些模块并在学长指导下开始写了一些程序作为练习。后续的学习中我在串口通讯这里遇到了很大阻碍,不太能理解其中的含义,网上的解释又不太看得懂,便找了一些STM32的视频来学习串口,期间发现51和MSP已经不是主流的板子了,现在的厂商更多的是用STM32这样的板子,于是后来的学习重心开始放到了STM32上,因为有了前面的基础,这次从头的学习就更加容易理解STM32的原理与使用了。 MSP430G2553一些模块的总结 (一).IO口模块, 1.我们实用的MSP430G2553有两组IO口,是P1和P 2. 2.IO口的寄存器有:方向选择寄存器PxDIR,输出寄存器PxOUT,输入寄存器PxIN,IO口内部上拉或下拉电阻使能寄存器PxREN, IO口功能选择寄存器PxSEL和PxSEL2,IO口中断使能寄存器PxIE,中断沿选择寄存器PxIES,IO口中断标志寄存器PxIFG。 3.所有的IO都带有中断,其中所有的P1口公用一个中断向量,所有的P2口公用一个中断向量。所以在使用中断时,当进入中断后,还要判断到底是哪一个IO口产生的中断,判断方法可以是判断各个IO口的电平。 4.中断标志PxIFG需要软件清除,也可以用软件置位,从而用软件触发一个中断。 5.PxOUT:如果引脚选择了内部的上拉或下拉电阻使能,则PxOUT设定电阻是上拉还是下拉,0:下拉,1:上拉 (二).时钟系统 1.MSP430的时钟源有: (1).外接低频晶振LFXT1CLK:低频模式32768Hz,高频模式450KHz~8MHz (2).外接高速晶振XT2CLK:8MHz; (3).内部数字控制振荡器DCO: (4).超低功耗低频振荡器VLO: 2.时钟模块:430的时钟模块有MCLK SMCLK ACLK : (1).主系统时钟MCLK:提供给MSP430的CPU时钟。可以来自LFXT1CLK XT2CLK DCO VLO 可选,默认为DCO。

STM32串口典型配置

usart.h : 头文件 /*------------------------------------------------------------------------------------------------------------------*/ #ifndef __USART_H #define __USART_H /* Include -------------------------------------------------------------------*/ #include "stm32f10x.h" #include #include //#include /* Define & Typedef ----------------------------------------------------------*/ /* Macro Switch ---------------------------------------------*/ /*注:以下宏供移植时选择和修改*/ #define USE_RS485 2 //使用RS485 #define USE_USART1 //使用串口1 #define USE_USART2 //使用串口2 #define USE_USART3 //使用串口3 //#define USE_UART4 //使用串口4 //#define USE_UART5 //使用串口5 #define MAX_LEN 256 //打印函数字符串输入最大字节数 #define PUTX fputc //fputc重定向函数 #ifdef USE_RS485 #define RS485 0 #define RS232 1 #define RS24_CONFIG RS24_Configration //RS485-232选择控制端口配置函数 #define RSCHOOSEFLAG SeM.Bit.RSChooseFlag //RS485-232选择标志 #define RS485_T GPIO_SetBits(GPIOA,GPIO_Pin_1) //RS485进入发送状态 #define RS485_R GPIO_ResetBits(GPIOA,GPIO_Pin_1) //RS485进入接收状态

STM32 串口简介

串口作为MCU的重要外部接口,同时也是软件开发重要的调试手段,其重要性不言而喻。STM32的串口资源相当丰富的,功能也相当强劲。ALIENTEK战舰STM32开发板所使用的STM32F103ZET6最多可提供5路串口,有分数波特率发生器、支持同步单线通信和半双工单线通讯、支持LIN、支持调制解调器操作、智能卡协议和IrDASIRENDEC规范、具有DMA等。用过单片机的人肯定都接触过串口,设置串口无非就是设置波特率、数据位、停止位、奇偶校验位。发送接收也就三种基本方式,轮询、中断和DMA。STM32F10x 的USART 模块也不过如此。所以我重点讲讲我在调试代码时犯得各种错误,那些很容易得到的代码就不详细的讲解了。 串口设置的一般步骤可以总结为如下几个步骤: 1)串口时钟使能,GPIO时钟使能 2)串口复位 3)GPIO端口模式设置 4)串口参数初始化 5)开启中断并且初始化NVIC(如果需要开启中断才需要这个步骤) 6)使能串口 7)编写中断处理函数 与串口基本配置直接相关的几个固件库函数。这些函数和定义主要分布在 stm32f10x_usart.h和stm32f10x_usart.c文件中。 1.串口时钟使能。串口是挂载在APB2下面的外设,所以使能函数为: RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1); 2.串口复位。当外设出现异常的时候可以通过复位设置,实现该外设的复位,然后重新配置这个外设达到让其重新工作的目的。一般在系统刚开始配置外设的时候,都会先执行复位该外设的操作。复位的是在函数USART_DeInit()中完成: void USART_DeInit(USART_TypeDef*USARTx);//串口复位 比如我们要复位串口1,方法为: USART_DeInit(USART1);//复位串口1 3:GPIO端口设置,首先要是能gpio时钟,然后将用到的串口占用的io口设置一下属性。 4.串口参数初始化。串口初始化是通过USART_Init()函数实现的, void USART_Init(USART_TypeDef*USARTx,USART_InitTypeDef*USART_InitStruct); 这个函数的第一个入口参数是指定初始化的串口标号,这里选择USART1。

STM32串口1中断实验

串口1中断实验 一、实验要求 开发板加电后,先向串口输出一串测试数据,然后在PC端的串口助手类软件上输入结束符为0x0d 0x0a的一串数据,发送到开发板,开发板接收到该字符串后将该字串回传给PC端串口助手软件,传送和接收过程中LED灯闪烁。 二、硬件电路设计 如下图所示,只需要将开发板配套的RS232串口线连接开发板9针串口到PC的串口上,如果电脑上没有串口,可以用USB转串口设备取代标准串口。 三、软件设计思路 根据任务要求,程序内容主要包括: 1. 初始化串口1,使能串口接收中断,通过串口输出相关信息到PC 2. 通过串口中断服务程序检测串口输入信息 3. 将收到的字符发送回PC,然后回到步骤2继续等待 四、程序分析 1.工程结构: 整个工程包含4类源文件,把它们安排在4个组当中:

1)RVMDK组: 仅包含一个启动用汇编源文件startup_stm32f10x_hd.s 。由于奋斗板采用STM32F103大存储器芯片(512k片上FLASH),因此采用STM32标准库中自带的大存储器芯片启动代码.这个文件已经配置好了初始状态,以及中断向量表,可以直接在工程里使用。 如果你在以后的应用中采用了中存储器或者小存储器的STM32芯片,可以将启动代码替换为startup_stm32f10x_md.s (中容量)或者 startup_stm32f10x_ld.s(小容量)。 2)StdPeriph_Driver组: stm32f10x_gpio.c:ST公司的标准库,包含了关于对通用IO口设置的函数。 stm32f10x_rcc.c :ST公司的标准库,包含了关于对系统时钟设置的函数。 stm32f10x_USART.c:ST公司的标准库,包含了关于对USART设置的函数。 Misc.c:ST公司的标准库,包含了关于中断设置的函数。 3)CMSYS组: 是关于整个Cortex-M3平台的系统函数及定义,由ARM公司给出。 4)USER组: main.c:例程的主函数。 stm32f10x_it.c:中断服务函数,此程序只需要增加串口1中断的代码。 2.编译与链接: 编译工程,完成后会提示如下:

STM32使用DMA加串口空闲中断接收数据

STM32使用DMA加串口空闲中断接收数据 STM32中,需要用串口接收数据,是使用串口中断来接收数据。但是用这种方法的话,就要频繁进入串口中断,然后处理,效率就比较低。于是就想到用DMA来接收串口数据,这个STM32也是支持的。但是关键的一点,怎么知道数据接收完毕了呢?如果接收的数据长度固定,那就好办,直接设置DMA的接收数据个数就行了。但是如果长度不固定了,那应该怎么办了? 这个时候,就要用到STM32在串口中提供的另一个好用的东西了,就是串口空闲中断。在STM32的串口控制器中,设置了有串口空闲中断,即如果串口空闲,又开启了串口空闲中断的话,就触发串口空闲中断,然后程序就会跳到串口中断去执行。有了这个,是不是可以判断什么时候串口数据接收完毕了呢?因为串口数据接收完毕后,串口总线肯定是会空闲的嘛,那这个中断肯定是会触发的了。 还有一个问题,这串口空闲中断是只要串口空闲就会产生吗?其实不是的,串口空闲中断要触发的话,是要RXNE位被置位后,串口总线空闲才会触发的。所以我们不用担心,串口数据发送完毕后,会不会触发串口空闲中断了。

下面用代码来说明。 1、配置串口。包括设置串口的引脚配置,串口的配置,串口中断的配置,串口的 接收DMA的配置 void USART_init(void) { GPIO_InitTypeDef GPIO_InitStructure; USART_InitTypeDef USART_InitStructure; NVIC_InitTypeDef NVIC_InitStructure; //开启时钟 RCC_APB2PeriphClockCmd(USART_RCC,ENABLE); //配置TX端口 GPIO_InitStructure.GPIO_Pin = GPIO_USART_TX; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP; GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; GPIO_Init(GPIO_USART_TYPE,&GPIO_InitStructure); //配置RX端口

stm32串口接收字符串经验

stm32串口接收字符串经验 https://www.sodocs.net/doc/3e6039902.html,/jishu_578041_1_1.html2016 分享一个stm32的串口就收字符串以十六进制数解析的程序。好多朋友在用stm32写串口接收的时候说用串口发送数据的时候有丢失的现象,或者发送的数据与接收的数据不一样,比如发送01 串口接收到的是40。还有好多好多的不明现象。今天就和大家讨论一下这些问题是怎么出现的。 在调试串口通信的时候首先要确定硬件是好用的,大家应该都用的是开发板所以硬件部分应该是没问题的。如果是最小系统的话要缺定外接串口模块是不是好的也就是rs3232,如果串口不好使,程序在对也是没用的,再有就是关于电平的问题,在这里说几个芯片就是rs3232芯片和ch340芯片这两个芯片大家都很熟悉了专业性的知识咱就不复i述了,为什么要说这两个芯片呢。因为有的童鞋的板子上没有板载 rs3232的芯片,所以直接将九针串口线的的2、3、5引脚直接接到单片机上了,所以出现可上述发送01收到的是40的情况,这种接是错误的要将串口线接到rs3232的串口上才能开始调试。硬件部分就这些,注意一下就行,下面说说软件部分的在写串口程序是首先要配置串口的初始化 我直接贴出程序再说,#include "pbdata.h"uint8_t TxBuffer1[] = "USART Interrupt Example: This isUSART1 DEMO";

uint8_t RxBuffer1[],rec_f,tx_flag;volatile uint8_t TxCounter1 = 0x00;volatile uint8_t RxCounter1 = 0x00; uint32_t Rec_Len;int main(void){ u8 a=0; RCC_Configuration(); NVIC_Configuration(); GPIO_Configuration(); USART_Config(USART1); while(1) { if(rec_f==1) { rec_f=0; USART_OUT(USART1,&TxBuffer1[0]); if(a==0){GPIO_SetBits(GPIOA, GPIO_Pin_2); a=1;} else{GPIO_ResetBits(GPIOA, GPIO_Pin_2);a=0; } } }}这是主函数部分,在主函数中只有几个函数的初始化,还有就是定义的数组和标志位。在一般的串口历程中大家会看到的就是定义一个缓冲区,将接收到的串口数据通过串口中断存放到缓冲区中然后在发送到串口中,但是在接收字符串的时候就要用到逐位发送,新手自己有些不了程序,所以只能一直处于蒙着的状态。其实个人感觉整点原子的程序写的真的挺好的,建议新手开始学习的时候看他的程序,有的人就是不喜欢他写程序的风格,这个因人而异,在这里只是建议一下。原子的串口就给出了字符串就收的历程,但是用

STM32的串口中断配置

STM32的串口中断配置,也是很简单的. 首先是配置UART的GPIO口 /****************************************************************************** * * Name : UART1_GPIO_Configuration * Deion : Configures the uart1 GPIO ports. * Input : None * Output : None * Return : None ******************************************************************************* / void UART1_GPIO_Configuration(void) { GPIO_InitTypeDef GPIO_InitStructure; // Configure USART1_Tx as alternate push-pull 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); // Configure USART1_Rx as input floating GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING; GPIO_Init(GPIOA, &GPIO_InitStructure); } 然后是配置串口参数 /****************************************************************************** * * Name : UART1_Configuration * Deion : Configures the uart1 * Input : None * Output : None * Return : None ******************************************************************************* / void USART_Configuration(void) { USART_InitTypeDef USART_InitStructure; USART_ClockInitTypeDef USART_ClockInitStructure; Uart1_GPIO_Configuration(); USART_https://www.sodocs.net/doc/3e6039902.html,ART_Clock = USART_Clock_Disable; USART_https://www.sodocs.net/doc/3e6039902.html,ART_CPOL = USART_CPOL_Low; USART_https://www.sodocs.net/doc/3e6039902.html,ART_CPHA = USART_CPHA_2Edge;

STM32串口初始化

#include"stm32f10x.h" void USART_Config(void) { USART_InitTypeDef USART_InitStructure; USART_https://www.sodocs.net/doc/3e6039902.html,ART_BaudRate = 9600; //波特率为9600Hz USART_https://www.sodocs.net/doc/3e6039902.html,ART_WordLength = USART_WordLength_8b; //8位数据 USART_https://www.sodocs.net/doc/3e6039902.html,ART_StopBits = USART_StopBits_1; //在帧结尾传输1 个停止位 USART_https://www.sodocs.net/doc/3e6039902.html,ART_Parity = USART_Parity_No; //奇偶失能 USART_https://www.sodocs.net/doc/3e6039902.html,ART_HardwareFlowControl =USART_HardwareFlowControl_None; //硬件流控制失能 USART_https://www.sodocs.net/doc/3e6039902.html,ART_Mode = USART_Mode_Tx | USART_Mode_Rx; //发送使能,接收使能 USART_Init(USART1, &USART_InitStructure); USART_ITConfig(USART1, USART_IT_RXNE, ENABLE); //USART_ITConfig:使能或者失能指定的USART中断USART_IT_RXNE, ENABLE:接收中断 USART_Cmd(USART1, ENABLE); //使能USART 外设 USART_ClearFlag(USART1,USART_FLAG_TC); //清除USARTx 的待处理标志位USART_FLAG_TC:发送完成标志位 }

相关主题