STM32库函数快速入门

stm32入门

  • 一、P口
  • 二、中断
    • 1.设置中断分组情况(通过SCB_AIRCR中写入对应的值,来设置中断分组)
    • 2.外部中断寄存器和工作原理
    • 3.外部中断设置(先配置EXTIx内部的相关参数,再配置中断中关于EXTIx的相关设置)
  • 三、串口通信
  • 四、DMA


一、P口

P口的初始化及其相关函数

void LED_Init(void)
{GPIO_InitTypeDef  GPIO_InitStructure;RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB|RCC_APB2Periph_GPIOE, ENABLE);	 //使能PB,PE端口时钟GPIO_InitStructure.GPIO_Pin = GPIO_Pin_5;				 //LED0-->PB.5 端口配置GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP; 		 //推挽输出GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;		 //IO口速度为50MHzGPIO_Init(GPIOB, &GPIO_InitStructure);					 //根据设定参数初始化GPIOB.5GPIO_SetBits(GPIOB,GPIO_Pin_5);						 //PB.5 输出高GPIO_InitStructure.GPIO_Pin = GPIO_Pin_5;	    		 //LED1-->PE.5 端口配置, 推挽输出GPIO_Init(GPIOE, &GPIO_InitStructure);	  				 //推挽输出 ,IO口速度为50MHzGPIO_SetBits(GPIOE,GPIO_Pin_5); 						 //PE.5 输出高 GPIO_ResetBits(GPIOE,GPIO_Pin_5); 						 //PE.5 输出低GPIO_write(GPIOE,portval);							    //PE写入一个16位的数
}

二、中断

1.设置中断分组情况(通过SCB_AIRCR中写入对应的值,来设置中断分组)

NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2); //设置NVIC中断分组2:2位抢占优先级,2位响应优先级

2.外部中断寄存器和工作原理

1.在EXTI_InitStructure.EXTI_Mode选择中断或事件:
(1)中断是指:当外部触发对应的p口,cpu会自动调用相关的中断服务程序。
(2)事件是指:当外部触发对应的p口,中断控制器会自动往某个引脚产生一个脉冲。
2.中断和事件有各自的屏蔽Register。
3.下降沿和上升沿触发Register时并行的,可以同时选择
4.软件中断事件Register设为1时,无论外部是否触发都会引起中断。
在这里插入图片描述

3.外部中断设置(先配置EXTIx内部的相关参数,再配置中断中关于EXTIx的相关设置)

1.RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO,ENABLE); //使能复用功能时钟, 通过在RCC_APB1ENR中设置参数来选择P口对应的复用时钟。
2.GPIO_EXTILineConfig(GPIO_PortSourceGPIOE,GPIO_PinSource2);//设置外部中断EXTI2选择PE口 3.EXTI_Init(&EXTI_InitStructure); //根据EXTI_InitStruct中指定的参数初始化外设EXTI寄存器
4.EXTI_ClearITPendingBit(EXTI_Line2); //清除LINE2上的中断标志位

void EXTIX_Init(void)
{EXTI_InitTypeDef EXTI_InitStructure;NVIC_InitTypeDef NVIC_InitStructure;GPIO_InitTypeDef GPIO_InitStructure;//先配置外部中断中选用的p口进行初始化RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOE,ENABLE);//使能PORTA,PORTE时钟GPIO_InitStructure.GPIO_Pin  = GPIO_Pin_2|GPIO_Pin_3//KEY0-KEY2GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU; //设置成上拉输入GPIO_Init(GPIOE, &GPIO_InitStructure);//初始化GPIOE2,3,4RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO,ENABLE);	//使能复用功能时钟//GPIOE.2 中断线以及中断初始化配置   下降沿触发GPIO_EXTILineConfig(GPIO_PortSourceGPIOE,GPIO_PinSource2);//设置外部中断EXTI2选择PE口EXTI_InitStructure.EXTI_Line=EXTI_Line2;	//选择初始化外部中断EXTI0~15中的EXTI2EXTI_InitStructure.EXTI_Mode = EXTI_Mode_Interrupt;	//选择中断或事件EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Falling;//下降沿触发EXTI_InitStructure.EXTI_LineCmd = ENABLE;//使能EXTI_Init(&EXTI_InitStructure);	 	//根据EXTI_InitStruct中指定的参数初始化外设EXTI寄存器//GPIOE.3	  中断线以及中断初始化配置 下降沿触发 //KEY1GPIO_EXTILineConfig(GPIO_PortSourceGPIOE,GPIO_PinSource3);EXTI_InitStructure.EXTI_Line=EXTI_Line3;//选择初始化外部中断EXTI0~15中的EXTI3EXTI_Init(&EXTI_InitStructure);	  	//根据EXTI_InitStruct中指定的参数初始化外设EXTI寄存器//(先配置EXTIx内部的相关参数,再配置中断中关于EXTIx的相关设置) NVIC_InitStructure.NVIC_IRQChannel = EXTI2_IRQn;			//选择设置中断中EXTI2中断NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0x02;	//抢占优先级2, NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0x02;					//子优先级2NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;								//使能外部中断通道NVIC_Init(&NVIC_InitStructure);NVIC_InitStructure.NVIC_IRQChannel = EXTI3_IRQn;			//选择设置中断中EXTI2中断NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0x02;	//抢占优先级2 NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0x01;					//子优先级1 NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;								//使能外部中断通道NVIC_Init(&NVIC_InitStructure);  	  //根据NVIC_InitStruct中指定的参数初始化外设NVIC寄存器}//外部中断2服务程序
void EXTI2_IRQHandler(void)
{delay_ms(10);//消抖if(KEY2==0)	  //按键KEY2{LED0=!LED0;}		 EXTI_ClearITPendingBit(EXTI_Line2);  //清除LINE2上的中断标志位  
}
//外部中断3服务程序
void EXTI3_IRQHandler(void)
{delay_ms(10);//消抖if(KEY1==0)	 //按键KEY1{				 LED1=!LED1;}		 EXTI_ClearITPendingBit(EXTI_Line3);  //清除LINE3上的中断标志位  
}

三、串口通信

1.流程:先使能串口时钟,再配置串口对应的P口进行初始化,同时配置串口参数并初始化,然后配置串口的中断参数并初始化,然后设置哪些串口事件发生可以引起中断,最后写串口中断服务函数。
2.主要库函数:
RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1|RCC_APB2Periph_GPIOA, ENABLE); //使能USART1,外部中断GPIOA时钟
USART_Init(USART1, &USART_InitStructure); //初始化串口1
USART_ITConfig(USART1, USART_IT_RXNE, ENABLE);//开启串口接受中断
USART_Cmd(USART1, ENABLE); //使能串口1
NVIC_Init(&NVIC_InitStructure); //根据指定的参数初始化VIC寄存器
Res =USART_ReceiveData(USART1); //读取接收到的数据
USART_SendData(USART1, USART_RX_BUF[t]);//向串口1发送数据
USART_GetFlagStatus(USART1,USART_FLAG_TC)

u16 USART_RX_STA=0;       //接收状态标记	  void uart_init(u32 bound)
{//GPIO端口设置GPIO_InitTypeDef GPIO_InitStructure;USART_InitTypeDef USART_InitStructure;NVIC_InitTypeDef NVIC_InitStructure;RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1|RCC_APB2Periph_GPIOA, ENABLE);	//使能USART1,外部中断GPIOA时钟//PA.9,PA.10是串口对应的输入输出引脚,所以得先配置PA.9和PA.10的参数。//USART1_TX   GPIOA.9GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9; //PA.9GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;	//复用推挽输出GPIO_Init(GPIOA, &GPIO_InitStructure);//初始化GPIOA.9//USART1_RX	  GPIOA.10初始化GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10;//PA10GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;//浮空输入GPIO_Init(GPIOA, &GPIO_InitStructure);//初始化GPIOA.10  //Usart1 NVIC 配置NVIC_InitStructure.NVIC_IRQChannel = USART1_IRQn;NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority=3 ;//抢占优先级3NVIC_InitStructure.NVIC_IRQChannelSubPriority = 3;		//子优先级3NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;			//IRQ通道使能NVIC_Init(&NVIC_InitStructure);	//根据指定的参数初始化VIC寄存器//USART 初始化设置USART_InitStructure.USART_BaudRate = bound;//串口波特率USART_InitStructure.USART_WordLength = USART_WordLength_8b;//字长为8位数据格式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); //初始化串口1USART_ITConfig(USART1, USART_IT_RXNE, ENABLE);//开启串口接受中断USART_Cmd(USART1, ENABLE);                    //使能串口1 }void USART1_IRQHandler(void)                	//串口1中断服务程序
{u8 Res;
#if SYSTEM_SUPPORT_OS 		//如果SYSTEM_SUPPORT_OS为真,则需要支持OS.OSIntEnter();    
#endifif(USART_GetITStatus(USART1, USART_IT_RXNE) != RESET)  //接收中断(接收到的数据必须是0x0d 0x0a结尾){Res =USART_ReceiveData(USART1);	//读取接收到的数据if((USART_RX_STA&0x8000)==0)//接收未完成{if(USART_RX_STA&0x4000)//接收到了0x0d{if(Res!=0x0a)USART_RX_STA=0;//接收错误,重新开始else USART_RX_STA|=0x8000;	//接收完成了 }else //还没收到0X0D{	if(Res==0x0d)USART_RX_STA|=0x4000;else{USART_RX_BUF[USART_RX_STA&0X3FFF]=Res ;USART_RX_STA++;if(USART_RX_STA>(USART_REC_LEN-1))USART_RX_STA=0;//接收数据错误,重新开始接收	  }		 }}   		 } 

四、DMA

1.DMA原理框图:
每个DMA有6个通道,每个通道都可以触发DMA通信,所以STM32有4个优先级对每个通道的请求进行设置。
每个通道又有3~8个通道请求,使用X通道时,需要打开X通道的某个通道请求,也就是设置某个通道请求为DMA方式。

在这里插入图片描述
2.主要库函数:
RCC_AHBPeriphClockCmd(RCC_AHBPeriph_DMA1, ENABLE); //使能DMA传输
DMA_DeInit(DMA_CHx); //将DMA的通道1寄存器重设为缺省值
DMA_Init(DMA_CHx, &DMA_InitStructure); //根据DMA_InitStruct中指定的参数初始化
DMA_SetCurrDataCounter(DMA_CHx,DMA1_MEM_LEN);//每次进行一次DMA传输的次数,函数会覆盖之前再初始化时设置的传输次数设定
DMA_Cmd(DMA_CHx, ENABLE); //使能USART1 TX DMA1 所指示的通道
DMA_ClearFlag(DMA1_FLAG_TC4);//清除通道4传输完成标志
DMA_GetFlagStatus(DMA1_FLAG_TC4)
USART_DMACmd(USART1,USART_DMAReq_Tx,ENABLE); //使能串口1的DMA发送,USART_CR3中可以选择是否使能DMA方式进行串口发送。此函数就决定了使用DMA第x通道的USART发送请求作为通道DMA的外设请求端口。


u16 DMA1_MEM_LEN;//保存DMA每次数据传送的长度 	    
//DMA1的各通道配置
//这里的传输形式是固定的,这点要根据不同的情况来修改
//从存储器->外设模式/8位数据宽度/存储器增量模式
//DMA_CHx:DMA通道CHx
//cpar:外设地址
//cmar:存储器地址
//cndtr:数据传输量 void MYDMA_Config(DMA_Channel_TypeDef* DMA_CHx,u32 cpar,u32 cmar,u16 cndtr)
{RCC_AHBPeriphClockCmd(RCC_AHBPeriph_DMA1, ENABLE);	//使能DMA传输DMA_DeInit(DMA_CHx);   //将DMA的通道1寄存器重设为缺省值DMA_InitStructure.DMA_PeripheralBaseAddr = cpar;  //DMA外设基地址DMA_InitStructure.DMA_MemoryBaseAddr = cmar;  //DMA内存基地址DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralDST;  //数据传输方向,从内存读取发送到外设DMA_InitStructure.DMA_BufferSize = cndtr;  //DMA通道的DMA缓存的大小DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable;  //外设地址寄存器不变DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable;  //内存地址寄存器递增DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_Byte;  //数据宽度为8位DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_Byte; //数据宽度为8位DMA_InitStructure.DMA_Mode = DMA_Mode_Normal;  //工作在正常模式DMA_InitStructure.DMA_Priority = DMA_Priority_Medium; //DMA通道 x拥有中优先级 DMA_InitStructure.DMA_M2M = DMA_M2M_Disable;  //DMA通道x没有设置为内存到内存传输DMA_Init(DMA_CHx, &DMA_InitStructure);  //根据DMA_InitStruct中指定的参数初始化DMA的通道USART1_Tx_DMA_Channel所标识的寄存器}USART_DMACmd(USART1,USART_DMAReq_Tx,ENABLE); 使能串口1的DMA发送,USART_CR3中可以选择是否使能DMA方式进行串口通信。void MYDMA_Enable(DMA_Channel_TypeDef*DMA_CHx)
{ DMA_Cmd(DMA_CHx, DISABLE );  //关闭USART1 TX DMA1 所指示的通道      DMA_SetCurrDataCounter(DMA_CHx,DMA1_MEM_LEN);//DMA通道的DMA缓存的大小DMA_Cmd(DMA_CHx, ENABLE);  //使能USART1 TX DMA1 所指示的通道 
}	  


本文来自互联网用户投稿,文章观点仅代表作者本人,不代表本站立场,不承担相关法律责任。如若转载,请注明出处。 如若内容造成侵权/违法违规/事实不符,请点击【内容举报】进行投诉反馈!

相关文章

立即
投稿

微信公众账号

微信扫一扫加关注

返回
顶部