STM32学习——入门到放弃篇_1

1、单片机启动

        启动过程,先运行启动文件,启动文件里面有一段汇编代码,先执行汇编代码,接着配置时钟,随即进入主函数。

        查看单片机主频

        

2、自己配置时钟树

stm32的RCC系统时钟配置 以及RCC_PLLConfig(uint32_t RCC_PLLSource, uint32_t PLLM, uint32_t PLLN, uint32_t PLLP, uint32_t PLLQ)的配置 - chaina_家长 - 博客园 (cnblogs.com)

void RCC_Init(void)
{RCC_ClocksTypeDef RCC_Clocks;ErrorStatus 			HSEStartUpStaus;RCC_DeInit();			// 把RCC外设初始化成复位状态,这句是必须的RCC_ClockSecuritySystemCmd(ENABLE);			//使能系统安全RCC_HSEConfig(RCC_HSE_ON);							//打开HSE,外部高速时钟HSEStartUpStaus = RCC_WaitForHSEStartUp();	//等待HSE开启if (SUCCESS == HSEStartUpStaus)		//成功开始分频{
//----------------------------------------------------------------------//// 使能FLASH 预存取缓冲区FLASH_PrefetchBufferCmd(ENABLE);// SYSCLK周期与闪存访问时间的比例设置,这里统一设置成2// 设置成2的时候,SYSCLK低于48M也可以工作,如果设置成0或者1的时候,// 如果配置的SYSCLK超出了范围的话,则会进入硬件错误,程序就死了// 0:0 < SYSCLK <= 24M// 1:24< SYSCLK <= 48M// 2:48< SYSCLK <= 72MFLASH_SetLatency(FLASH_Latency_2);
//----------------------------------------------------------------------//// AHB预分频因子设置为1分频,HCLK = SYSCLK RCC_HCLKConfig(RCC_SYSCLK_Div1);		// APB1预分频因子设置为2分频,PCLK1 = HCLK/2RCC_PCLK1Config(RCC_SYSCLK_Div2);		// APB2预分频因子设置为1分频,PCLK2 = HCLKRCC_PCLK2Config(RCC_SYSCLK_Div1);			//-----------------设置各种频率主要就是在这里设置-------------------//// 设置PLL时钟来源为HSE,HSE=8MHz
//      PLLM:PLL_VCO input clock =(HSE or HSI /PLLM)
//    	PLLN:PLL_VCO output clock =(PLL_VCP input clock)*PLLN
//    	PLLP:System Clock =PLL_VCO output clock/PLLP
//    	PLLQ:配置SD卡读写,USB等功能,暂时不用RCC_PLLConfig(RCC_PLLSource_PREDIV1, RCC_PLLMul_9);
//------------------------------------------------------------------//// 开启PLL RCC_PLLCmd(ENABLE);// 等待 PLL稳定while (RCC_GetFlagStatus(RCC_FLAG_PLLRDY) == RESET){}// 当PLL稳定之后,把PLL时钟切换为系统时钟SYSCLKRCC_SYSCLKConfig(RCC_SYSCLKSource_PLLCLK);// 读取时钟切换状态位,确保PLLCLK被选为系统时钟while (RCC_GetSYSCLKSource() != 0x08){}}else{ // 如果HSE开启失败,那么程序就会来到这里,用户可在这里添加出错的代码处理// 当HSE开启失败或者故障的时候,单片机会自动把HSI设置为系统时钟,// HSI是内部的高速时钟,8MHZwhile (1){}}}

3、GPIO口使用

        3.1、输出模式

// 1、配置GPIO外设时钟RCC_AHBPeriphClockCmd(RCC_AHBPeriph_GPIOA | RCC_AHBPeriph_GPIOB | RCC_AHBPeriph_GPIOC | RCC_AHBPeriph_GPIOD | RCC_AHBPeriph_GPIOF |  RCC_AHBPeriph_DMA1, ENABLE);GPIO_InitTypeDef GPIO_InitStructure;    //配置结构体GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0|GPIO_Pin_1|GPIO_Pin_2|GPIO_Pin_3|GPIO_Pin_4|GPIO_Pin_5|GPIO_Pin_6|GPIO_Pin_7; //配置的引脚                           GPIO_InitStructure.GPIO_Mode = GPIO_Mode_OUT;                      //配置模式,OUTPUT/INPUTGPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;                 //速度50MHzGPIO_InitStructure.GPIO_OType = GPIO_OType_PP;                   	//输出模式GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP;                 			//是否需要上拉GPIO_Init(GPIOA, &GPIO_InitStructure);														//配置A组引脚	GPIO_SetBits(GPIOA,GPIO_Pin_0|GPIO_Pin_1|GPIO_Pin_2|GPIO_Pin_3|GPIO_Pin_4|GPIO_Pin_5|GPIO_Pin_6|GPIO_Pin_7);//引脚设置高电平
//GPIO_ResetBits(GPIOA,GPIO_Pin_0);        //A组GPIO引脚0设置低电平
void GPIO_ResetBits(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin)    //置低电平
void GPIO_setBits(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin)    //置高电平

         3.2、输入模式

// 1、配置GPIO外设时钟RCC_AHBPeriphClockCmd(RCC_AHBPeriph_GPIOA | RCC_AHBPeriph_GPIOB | RCC_AHBPeriph_GPIOC | RCC_AHBPeriph_GPIOD | RCC_AHBPeriph_GPIOF |  RCC_AHBPeriph_DMA1, ENABLE);GPIO_InitTypeDef GPIO_InitStructure;GPIO_InitStructure.GPIO_Pin = GPIO_Pin_8|GPIO_Pin_11|GPIO_Pin_15;GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN;GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL;    //根据电路图和芯片配置是否下拉GPIO_Init(GPIOA, &GPIO_InitStructure);
	if(GPIO_ReadInputDataBit(GPIOA, GPIO_Pin_0) == 0)    //读取电平

        3.3、转换功能

        通讯类的IIC、ADC等功能

4、NVIC配置 (嵌套中断控制器)

中断-NVIC与EXTI外设详解(超全面)-CSDN博客

void Hardware_NVIC_Init(void)		//设置中断优先级
{NVIC_InitTypeDef NVIC_InitStructure;//配置GPIA_Pin_0口中断优先级NVIC_InitStructure.NVIC_IRQChannel = EXTI0_IRQn ;						//中断源	PA0中断NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1;		//抢占优先级NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;						//优先级NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;							//是否启用中断NVIC_Init(&NVIC_InitStructure);//配置GPIA_Pin_1口中断优先级NVIC_InitStructure.NVIC_IRQChannel = EXTI1_IRQn ;						//中断源	PA0中断NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;		//抢占优先级NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;						//优先级NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;							//是否启用中断NVIC_Init(&NVIC_InitStructure);
}

5、EXTI        外部中断

void EXTI0_Config(void)
{GPIO_InitTypeDef 		GPIO_InitStructure;   		 					//配置结构体EXTI_InitTypeDef 		EXTI_InitStructure;NVIC_InitTypeDef NVIC_InitStructure;RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA ,ENABLE);		//打开GPIOA时钟RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO, ENABLE);		//开启AFIO的时钟//配置EXTI中断相应的引脚GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0;GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;		//浮空输入GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;  			//速度50MHzGPIO_Init(GPIOA, &GPIO_InitStructure);//配置AFIO//连接PA0作为EXTI使用,相同的GPIO_Pin_x不能同时触发中断GPIO_EXTILineConfig(GPIO_PortSourceGPIOA, GPIO_PinSource0 );//配置EXTI中断				//PA0 是EXTI_0EXTI_InitStructure.EXTI_Line = EXTI_Line0;							//中断线 PA0,PB0,PC0引脚共用EXTI_Line0中断线EXTI_InitStructure.EXTI_Mode = EXTI_Mode_Interrupt;			//中断模式EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Falling;	//下降沿触发EXTI_InitStructure.EXTI_LineCmd = ENABLE;								//启用中断线EXTI_Init(&EXTI_InitStructure);EXTI_ClearFlag(EXTI_Line0 );								//清理中断标志位//配置GPIOA_Pin_0口中断优先级NVIC_InitStructure.NVIC_IRQChannel = EXTI0_IRQn ;						//中断源,来自中断线EXTI_Line0NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1;		//抢占优先级NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1;						//优先级NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;							//是否启用中断NVIC_Init(&NVIC_InitStructure);
}void EXTI0_IRQHandler(void)											//触发EXTI0_IRQ中断源的服务函数
{static int status = 1;if ( SET == EXTI_GetITStatus(EXTI_Line0) )	  //检测中断来自哪条中断线,//因为有的中断线共用一个中断处理函数{if (status == 1){GPIO_ResetBits(GPIOB ,GPIO_Pin_9);GPIO_ResetBits(GPIOB ,GPIO_Pin_8);status = 0;}else{GPIO_SetBits(GPIOB ,GPIO_Pin_9);GPIO_SetBits(GPIOB ,GPIO_Pin_8);status = 1;}EXTI_ClearFlag( EXTI_Line0 );									//清理中断标志位}
}

6、串口USART

STM32中配置重映射的情况主要出现在需要对GPIO端口的功能进行改变或重新分配时。每个GPIO都有一组重映射寄存器,用于配置该GPIO端口的重映射方式。当默认引脚不满足某些特定配置要求,如电压、频率等时,可能需要通过重映射来改变引脚的物理位置或功能。

配置重映射的步骤如下:

  1. 使能AFIO时钟:在使用重映射功能之前,需要先配置AFIO的时钟以使其可用。
  2. 配置GPIO端口:将源GPIO端口配置为相应的复用功能,以便可以重映射到目标GPIO端口上。
  3. 配置重映射寄存器:设置重映射寄存器的值,以选择要映射的复用功能和目标GPIO端口。
  4. 配置目标GPIO端口:将目标GPIO端口配置为相应的复用功能以使用已重映射的信号。

请注意,在进行重映射配置时,必须使能AFIO时钟。另外,虽然有时即使不开启重映射功能也能成功启用重映射引脚并使外设功能正常,但当重映射引脚和默认引脚都使能之后,外设会优先启用默认引脚。

因此,当需要改变GPIO端口的功能或当默认引脚不满足特定配置要求时,STM32就需要配置重映射。具体的配置步骤和注意事项可能因不同的STM32型号和具体应用场景而有所差异,建议查阅相关的STM32参考手册或技术文档以获取更详细和准确的信息。

stm32——串口配置一般步骤_stm32串口配置步骤-CSDN博客

//STM32F051C8TC芯片的RS485通讯
void RS485_initializes(void)
{USART_InitTypeDef USART_InitStructure;GPIO_InitTypeDef  GPIO_InitStructure;RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1, ENABLE);       //打开时钟//重映射GPIO_PinAFConfig(GPIOA, GPIO_PinSource9, GPIO_AF_1);        //配置引脚为转换功能GPIO_PinAFConfig(GPIOA, GPIO_PinSource10, GPIO_AF_1);GPIO_PinAFConfig(GPIOA, GPIO_PinSource12, GPIO_AF_1);GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9 | GPIO_Pin_10 | GPIO_Pin_12;GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP;GPIO_Init(GPIOA, &GPIO_InitStructure);USART_OverSampling8Cmd(USART1,ENABLE);USART_InitStructure.USART_BaudRate = 6000000;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_DECmd(USART1,ENABLE);														//485方向使能USART_SetDEAssertionTime(USART1,0x1F);				    //发数据时DE需要提前Tx为高电平,保证数据发送USART_DEPolarityConfig(USART1,USART_DEPolarity_High);	//DE极性设置,发送数据为高电平/*********************************************/USART_ITConfig(USART1, USART_IT_RXNE, ENABLE);			//开启串口寄存器非空中断USART_Cmd(USART1, ENABLE);													//启动USART1USART_ClearFlag(USART1,USART_FLAG_TC);							//清楚发送完全标志位置//发数据unsigned short data = 0x20;USART_SendData(USART1 ,data);

        6.2、STM32F103C8T6芯片

        1、配置USART

void Hardware_USART_Init(void)
{GPIO_InitTypeDef 		GPIO_InitStructure;    							//GPIO配置结构体USART_InitTypeDef 	USART_InitStructure;								//USART配置结构体NVIC_InitTypeDef 		NVIC_InitStructure;									//USART中断优先级配置结构体//1、串口时钟使能,GPIO时钟使能RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1 | RCC_APB2Periph_GPIOA ,ENABLE);	//打开GPIO时钟,打开USART时钟//2、串口复位USART_DeInit(USART1);	
/*****************************************************************//重映射(AFIO)RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB | RCC_APB2Periph_AFIO ,ENABLE);GPIO_PinRemapConfig(GPIO_Remap_USART1 ,ENABLE);//USART1_TX   原GPIOA.9是Tx   重映射PB6GPIO_InitStructure.GPIO_Pin = GPIO_Pin_6; 						GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;				//复用推挽输出GPIO_Init(GPIOB, &GPIO_InitStructure);								//初始化//USART1_RX	  原GPIOA.10Rx		重映射PB7GPIO_InitStructure.GPIO_Pin = GPIO_Pin_7;						GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;	//浮空输入GPIO_Init(GPIOB, &GPIO_InitStructure);								//初始化
******************************************************************/	//3、配置GPIO为转换功能//USART1_TX   原GPIOA.9是Tx   GPIO_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.10Rx		GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10;						//PA10GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;	//浮空输入GPIO_Init(GPIOA, &GPIO_InitStructure);								//初始化GPIOA.10//4、串口参数初始化USART_OverSampling8Cmd(USART1 ,ENABLE);									//启用8倍过采样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);											//串口初始化//5、开启中断并初始化NVIC(需要开启中断才需要)NVIC_InitStructure.NVIC_IRQChannel = USART1_IRQn;							//中断源NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;			//抢占优先级NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;						//优先级NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;								//启用中断NVIC_Init(&NVIC_InitStructure);																//NVIC初始化//6、使能串口USART_ITConfig(USART1, USART_IT_RXNE, ENABLE);				//开启串口寄存器非空中断USART_Cmd(USART1 ,ENABLE);																		//启动串口USART_ClearFlag(USART1,USART_FLAG_TC);												//清除发送完全标志位置
}

        2、发送数据

//发送数据
void USART_Print(uint8_t *s)  //发送字符串函数
{while(*s){//查USART1模块的发送数据寄存器是否还未准备好(即是否不为空),RESET未准备好while(USART_GetFlagStatus(USART1,USART_FLAG_TXE) == RESET);USART_SendData(USART1,*s);s++;}
}

        3、中断方式接收数据

void USART1_IRQHandler(void)                	//串口1中断服务程序
{volatile unsigned short temp;//1、读数据temp = USART_ReceiveData(USART1);					//收//USART_SendData(USART1,temp);							//发出去//2、清理FLAGUSART_ClearITPendingBit(USART1,USART_IT_RXNE);
} 

7、DMA

STM32 | 串口DMA很难?其实就是如此简单!(超详细、附代码)_stm32串口dma很难?-CSDN博客

#include "hardware_usart.h"#define USART1_MAX_TX_LEN 32		//发送缓存大小,最大USART1_MAX_TX_LEN
#define USART1_MAX_RX_LEN 32unsigned int USART1_TX_BUF[USART1_MAX_TX_LEN];		//发送数据缓存区
unsigned int usart1_rx_buf[USART1_MAX_RX_LEN];	  //接收数据缓存区
unsigned int recv_msg[USART1_MAX_RX_LEN];					//复制接收数据去处理void DMA_Config_Tx(void);
void DMA_Config_Rx(void);void Hardware_USART_Init(void)
{GPIO_InitTypeDef 		GPIO_InitStructure;    							//GPIO配置结构体USART_InitTypeDef 	USART_InitStructure;								//USART配置结构体NVIC_InitTypeDef 		NVIC_InitStructure;									//USART中断优先级配置结构体//1、串口时钟使能,GPIO时钟使能RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1 ,ENABLE);	//打开USART时钟RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA | RCC_APB2Periph_AFIO ,ENABLE);		//打开GPIO时钟,AFIO时钟//2、串口复位USART_DeInit(USART1);//3、配置GPIO为转换功能//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//4、串口参数初始化USART_OverSampling8Cmd(USART1 ,ENABLE);												//启用8倍过采样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);											//串口初始化//5、开启中断并初始化NVIC(需要开启中断才需要)NVIC_InitStructure.NVIC_IRQChannel = USART1_IRQn;							//中断源NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 8;			//抢占优先级NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;						//优先级NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;								//启用中断NVIC_Init(&NVIC_InitStructure);																//NVIC初始化//6、使能串口USART_ITConfig(USART1, USART_IT_IDLE, ENABLE);								//开启串口空闲中断USART_ClearFlag(USART1,USART_FLAG_TC);												//清除发送完成标志位置USART_Cmd(USART1 ,ENABLE);																		//启动串口//配置DMADMA_Config_Tx();DMA_Config_Rx();USART_DMACmd(USART1 ,USART_DMAReq_Tx | USART_DMAReq_Rx ,ENABLE);		//启动串口DMA发送和接收}void DMA_Config_Tx(void)
{DMA_InitTypeDef  DMA_InitStructure;															//DMA配置结构体RCC_AHBPeriphClockCmd(RCC_AHBPeriph_DMA1, ENABLE);							//打开DMA时钟DMA_DeInit( DMA1_Channel4 );																		//DMA通道4(USART1_Tx)复位DMA_InitStructure.DMA_PeripheralBaseAddr = (uint32_t)&USART1->DR;				//外设地址DMA_InitStructure.DMA_MemoryBaseAddr = (uint32_t)USART1_TX_BUF;					//内存地址DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralDST;							//指定数据传输方向,内存到外设DMA_InitStructure.DMA_BufferSize = USART1_MAX_TX_LEN;						//缓存区的大小 32字节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;						//指定内存数据宽度DMA_InitStructure.DMA_Mode = DMA_Mode_Normal;										//工作模式正常,搬完一次数据停在那需要手动再启动DMA_InitStructure.DMA_Priority = DMA_Priority_VeryHigh;						//DMA通道x软件优先级最高DMA_InitStructure.DMA_M2M = DMA_M2M_Disable;										//DMA通道x不设置内存到内存传输DMA_ClearFlag(DMA1_FLAG_TC4);																		//清理DMA传输完成标志DMA_Init(DMA1_Channel4 ,&DMA_InitStructure);										//DMA通道x初始化DMA_Cmd(DMA1_Channel4 ,DISABLE);																//关闭DMA串口的发送通道
}void DMA_Config_Rx(void)
{DMA_InitTypeDef  DMA_InitStructure;															//DMA配置结构体RCC_AHBPeriphClockCmd(RCC_AHBPeriph_DMA1, ENABLE);							//打开DMA时钟DMA_DeInit( DMA1_Channel5 );																		//DMA通道5(USART1_Rx)复位DMA_InitStructure.DMA_PeripheralBaseAddr = (uint32_t)&USART1->DR;			//外设地址DMA_InitStructure.DMA_MemoryBaseAddr = (uint32_t)usart1_rx_buf;				//内存地址DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralSRC;							//数据传输方向,外设到内存DMA_InitStructure.DMA_BufferSize = USART1_MAX_RX_LEN;						//DMA通道缓存区的大小  32字节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_VeryHigh;					//DMA通道x软件优先级最高DMA_InitStructure.DMA_M2M = DMA_M2M_Disable;										//DMA通道x不设置内存到内存传输DMA_ClearFlag(DMA1_FLAG_TC5);																		//清理DMA传输完成标志DMA_Init(DMA1_Channel5 ,&DMA_InitStructure);										//DMA通道x初始化DMA_Cmd(DMA1_Channel5 ,ENABLE);																	//开启DMA1的5通道
}//USART使用DMA发送数据
void USART_DMA_Tx_Data(unsigned char *buffer)
{	//1、清理标志位TC//DMA_ClearFlag( DMA1_FLAG_TC4 );				//先清理DMA通道4的传输完成标志位//2、关闭DMA1的4通道DMA_Cmd(DMA1_Channel4 ,DISABLE);			//因为传输数量寄存器配置需要通道关闭才能配置//3、配置需要发送的数据DMA1_Channel4->CMAR = (uint32_t)buffer;//4、重新设置长度DMA1_Channel4->CCR &= ~(1<<0);								//关闭通道DMA1_Channel4->CNDTR = USART1_MAX_TX_LEN;			//重新配置传输数量寄存器DMA1_Channel4->CCR |= 1<<0;										//开启通道//5、检测DMA传输完成标志位while( SET != DMA_GetFlagStatus(DMA1_FLAG_TC4));		//等待DMA传输完成USART_ClearFlag(USART1 ,USART_FLAG_TC);							//清理串口发送完成标志位DMA_ClearFlag(DMA1_FLAG_TC4);												//清理DMA传输完成标志}//接收数据
void USART1_IRQHandler(void)                	//串口1中断服务程序
{uint8_t temp;if ( SET != USART_GetITStatus(USART1 ,USART_FLAG_IDLE))			//触发串口空闲中断,发生返回RESET{//1、关闭通道、拷贝数据DMA_Cmd(DMA1_Channel5 ,DISABLE);													//关闭DMA通道//2、重新设置DMA长度DMA1_Channel5->CCR &= ~(1<<0);								//关闭通道DMA1_Channel5->CNDTR = USART1_MAX_RX_LEN;			//重新配置传输数量寄存器DMA1_Channel5->CCR |= 1<<0;										//开启通道//3、清除DMA传输完成标志和串口空闲中断标志temp = USART1->SR;temp = USART1->DR;DMA_ClearFlag( DMA1_FLAG_TC5 );USART_DMA_Tx_Data((unsigned char *)usart1_rx_buf);		//接收的数据发送出去}
} 

8、TIM

STM32高级定时器TIM1生成互补PWM_stm32 tim1 互补pwm-CSDN博客
STM32之定时器配置-CSDN博客
        8.1、TIM+更新中断

void TIMER_INIT(void)
{TIM_TimeBaseInitTypeDef  TIM_TimeBaseStructure;NVIC_InitTypeDef 				 NVIC_InitStructure;TIM_DeInit(TIM3);													//复位定时器/*1、使能TIM2时钟*/RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM3, ENABLE);/*配置定时2参数  溢出时间 = [ ( TIM_Period + 1 ) * ( TIM_Prescaler + 1 ) / ( SystemCoreClock ) ] ( s )*/TIM_TimeBaseStructure.TIM_Prescaler = 71;/*PSC预分频器,72分频,1MHz*/TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Down;/*向上计数模式*/TIM_TimeBaseStructure.TIM_Period = 499;/*设定计数器的计数值(周期),计数1000次,0.5ms*/TIM_TimeBaseStructure.TIM_ClockDivision = TIM_CKD_DIV1;/*时钟分频因子*/TIM_TimeBaseStructure.TIM_RepetitionCounter = 0;/*重载周期,高级定时器特有*/TIM_TimeBaseInit(TIM3 ,&TIM_TimeBaseStructure);						/*初始化定时器*/TIM_ITConfig(TIM3 ,TIM_IT_Update ,ENABLE);								/*启动定时器更新中断*/NVIC_InitStructure.NVIC_IRQChannel = TIM3_IRQn;NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1;NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1;NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;NVIC_Init(&NVIC_InitStructure);//TIM_Cmd(TIM3 ,ENABLE);										/*开启定时器*/TIM1->CR1 |= 1<<0 ;
}void TIM3_IRQHandler(void)
{static unsigned  char flag = 0;if ( RESET == TIM_GetITStatus( TIM3 ,TIM_IT_Update) ) {if (flag == 40){flag = 0;}flag++;if (flag <= 5){GPIO_SetBits(GPIOB ,GPIO_Pin_8);		/*输出高电平*/}else{GPIO_ResetBits(GPIOB ,GPIO_Pin_8);		/*输出低电平*/}TIM_ClearITPendingBit( TIM3 ,TIM_IT_Update);}
}

        8.2、        TIM+PWM
 

void TIMER_INIT(void)
{TIM_TimeBaseInitTypeDef  TIM_TimeBaseStructure;GPIO_InitTypeDef 				 GPIO_InitStructure;TIM_OCInitTypeDef  			 TIM_OCInitStructure;//TIM_DeInit(TIM1);													//复位定时器/*1、使能TIM1时钟  GPIOA时钟(TIM1_CH2对应PA9)*/RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA | RCC_APB2Periph_TIM1 | RCC_APB2Periph_GPIOB ,ENABLE);RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO ,ENABLE);/*2、配置GPIOA_Pin_9*/GPIO_InitStructure.GPIO_Pin =  GPIO_Pin_9 ; 							//配置的引脚                           GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;   			//配置模式,复用推挽输出GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;  			//速度50MHzGPIO_Init(GPIOA, &GPIO_InitStructure);									//配置A组引脚/*配置TIM1_CH2N*/GPIO_InitStructure.GPIO_Pin = GPIO_Pin_14 ; 							//配置的引脚                           GPIO_Init(GPIOB, &GPIO_InitStructure);									//配置B组引脚/*3、配置定时1参数(定时)  溢出时间 = [ ( TIM_Period + 1 ) * ( TIM_Prescaler + 1 ) / ( SystemCoreClock ) ] ( s )*/TIM_TimeBaseStructure.TIM_Prescaler = 71;/*PSC预分频器,72分频,1MHz*/TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;/*向上计数模式*/TIM_TimeBaseStructure.TIM_Period = 19999;/*设定计数器的计数值(周期),计数1000次,1ms*/TIM_TimeBaseStructure.TIM_ClockDivision = TIM_CKD_DIV1;/*时钟分频因子*/TIM_TimeBaseStructure.TIM_RepetitionCounter = 0;/*重载周期,高级定时器特有*/TIM_TimeBaseInit(TIM1 ,&TIM_TimeBaseStructure);						/*初始化定时器*//*4、PWM输出定时器1配置,(通道2)*/TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM1;				/*从0递增,小于CCR值为有效.(PWM2于之相反)*/TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable;			/*使能PWM输出    PA9引脚*/TIM_OCInitStructure.TIM_OutputNState = TIM_OutputNState_Disable;		/*开起互补PWM输出  PB14引脚*/TIM_OCInitStructure.TIM_Pulse = 1999;  /*配置2ms/20ms = 10%=(CCR+1/ARR+1),  CCR=?,ARR=周期*/TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_High;					/*输出极性,高电平*/TIM_OCInitStructure.TIM_OCNPolarity = TIM_OCNPolarity_Low;					/*互补输出,有效时为低电平*/TIM_OCInitStructure.TIM_OCIdleState = TIM_OCIdleState_Reset;				/*输出比较空闲时电平(低电平)*/TIM_OCInitStructure.TIM_OCNIdleState = TIM_OCNIdleState_Reset;			TIM_OC2Init(TIM1 ,&TIM_OCInitStructure);													/*初始化配置的PWM*/     TIM_Cmd(TIM1 ,ENABLE);										/*开启定时器*///TIM1->CR1 |= 1<<0 ;/**/TIM_CtrlPWMOutputs( TIM1 ,ENABLE);					/*开启PWM输出*/
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.hqwc.cn/news/564423.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

代码随想录|Day26|贪心01|455.分发饼干、376.摆动序列、53.最大子数组和

455.分发饼干 大尺寸的饼干既可以满足胃口大的孩子也可以满足胃口小的孩子。 局部最优&#xff1a;尽量确保每块饼干被充分利用 全局最优&#xff1a;手上的饼干可以满足尽可能多的孩子 思路&#xff1a;大饼干 尽量分给 大胃口孩子 将小孩和饼干数组排序&#xff0c;我们从大到…

ABAP笔记:定义指针,动态指针分配:ASSIGN COMPONENT <N> OF STRUCTURE <结构> TO <指针>.

参考大佬文章学习&#xff0c;总结了下没有提到的点&#xff1a;SAP ABAP指针的6种用法。_abap 指针-CSDN博客 定义指针&#xff1a;其实指针这玩意&#xff0c;就是类似你给个地方&#xff0c;把东西临时放进去&#xff0c;然后指针就是这个东西的替身了&#xff0c;写代码的…

洛谷day3

B2053 求一元二次方程 - 洛谷 掌握printf用法&#xff1b; #include <iostream> #include <cmath> using namespace std; double a,b,c; double delta; double x1,x2;int main() {cin>>a>>b>>c;delta b*b-4*a*c;if(delta>0){x1 (-bsqrt…

Linux查看磁盘空间

查看磁盘空间 df -h 查看目录所占空间 du -sh [目录] 查看当前目录下, 所有目录所占空间 (一级目录) find . -maxdepth 1 -type d -exec du -sh {} \;-maxdepth 1 查看的目录深度是1级, 2则是2级

从抛硬币试验看概率论的基本内容及统计方法

一般说到概率&#xff0c;就喜欢拿抛硬币做例子。大多数时候&#xff0c;会简单认为硬币正背面的概率各为二分之一&#xff0c;其实事情远没有这么简单。这篇文章会以抛硬币试验为例子并贯穿全文&#xff0c;引出一系列概率论和数理统计的基本内容。这篇文章会涉及的有古典概型…

注意力机制篇 | YOLOv8改进之添加CBAM注意力机制

前言:Hello大家好,我是小哥谈。CBAM是一种用于图像分类的注意力机制,全称为Convolutional Block Attention Module。它可以自适应地学习每个通道和空间位置的重要性,从而提高模型的性能。CBAM由两个部分组成:通道注意力模块和空间注意力模块。通道注意力模块通过学习每个通…

生物信息学文章中常见的图应该怎么看?

目录 火山图 热图 箱线图 森林图 LASSO回归可视化图&#xff08;套索图&#xff09; 交叉验证图 PCA图 ROC曲线图 这篇文章只介绍这些图应该怎么解读&#xff0c;具体怎么绘制&#xff0c;需要什么参数&#xff0c;怎么处理数据&#xff0c;会在下一篇文章里面给出 火山…

【】(综合练习)博客系统

在之前的学些中&#xff0c;我们掌握了Spring框架和MyBatis的基本使用&#xff0c;接下来 我们就要结合之前我们所学的知识&#xff0c;做出一个项目出来 1.前期准备 当我们接触到一个项目时&#xff0c;我们需要对其作出准备&#xff0c;那么正规的准备是怎么样的呢 1.了解需求…

基于Java中的SSM框架实现快餐店线上点餐系统项目【项目源码+论文说明】计算机毕业设计

基于Java中的SSM框架实现快餐店线上点餐系统演示 摘要 随着计算机互联网的高速发展。餐饮业的发展也加入了电子商务团队。各种网上点餐系统纷纷涌现&#xff0c;不仅增加了商户的销售量和营业额&#xff0c;而且为买家提供了极大的方便&#xff0c;足不出户&#xff0c;就能订…

代码随想录算法训练营第三十二天 | 122. 买卖股票的最佳时机 II、55. 跳跃游戏、45. 跳跃游戏 II

代码随想录算法训练营第三十二天 | 122. 买卖股票的最佳时机 II、55. 跳跃游戏、45. 跳跃游戏 II 122. 买卖股票的最佳时机 II题目解法 55. 跳跃游戏题目解法 45. 跳跃游戏 II题目解法 感悟 122. 买卖股票的最佳时机 II 题目 解法 贪心&#xff1a;局部最优&#xff1a;收集每…

计算机二级 公共基础知识点大全

计算机二级 公共基础知识点 第一章 数据结构与算法 1.1 算法 算法的定义&#xff1a;是指解题方案的准确而完整的描述。&#xff08;算法不等于程序&#xff0c;程序的设计不可能优于算法的设计&#xff09;算法的基本特征&#xff1a;可行性、确定性、有穷性、足够的情报。…

【算法每日一练]-动态规划(保姆级教程 篇17 状态压缩)#POJ1185:炮兵阵地 #互不侵犯

目录 今日知识点&#xff1a; 把状态压缩成j,dp每行i的布置状态&#xff0c;从i-1和i-2行进行不断转移 把状态压缩成j,dp每行i的布置状态&#xff0c;从i-1行进行状态匹配&#xff0c;然后枚举国王数转移 POJ1185&#xff1a;炮兵阵地 思路&#xff1a; 题目&#xff1a;互…