STM32自建库文件

    技术2022-07-10  143

    一、imut.c文件

    # include "imut.h" /*********************************************************************** //函数名称:STM32常用外设函数 //作用:包括LED初始化、按键初始化、串口初始化等。LED分0,1两个;按键分0,1,2三个;串口分1,2两个。 //示例:SysInit(); //作者:陈德强 //时间:2019年4月11日08:06:28 //修改者: //修改时间: //修改说明: ************************************************************************/ void LEDInit(u8 LED) { switch(LED) { case 0:GPIOInit(GPIOB,5,0);break; case 1:GPIOInit(GPIOE,5,0);break; } } void KeyInit(u8 KEY) { switch(KEY) { case 0:GPIOInit(GPIOE,4,1);break; case 1:GPIOInit(GPIOE,3,1);break; case 2:GPIOInit(GPIOA,0,-1);break; } } void USARTInit(u8 usart,int paudrate) { switch(usart) { case 1:uart_init(paudrate); case 2:USART2_Init(paudrate); } } /************************************************************************* //函数名称:IO口初始化函数封装 //作用:第一个参数是GPIO口,第二个参数是引脚号,第三个参数是输出输入模式选择,0是输出,1是上拉输入,-1是下拉输入。 //说明:输出是推挽输出50HZ,输入默认下拉输入。模拟输入和复用功能需单独设置。 //示例:GPIOInit(GPIOB,5,1) //作者:陈德强 //时间:2019年4月8日17:29:05 //修改者: //修改时间: //修改说明: ***************************************************************************/ void GPIOInit(GPIO_TypeDef * GPIOx,u8 Pin,int OutOrIN) { if(GPIOx==GPIOA)RCC->APB2ENR|=1<<2; if(GPIOx==GPIOB)RCC->APB2ENR|=1<<3; if(GPIOx==GPIOC)RCC->APB2ENR|=1<<4; if(GPIOx==GPIOD)RCC->APB2ENR|=1<<5; if(GPIOx==GPIOE)RCC->APB2ENR|=1<<6; if(GPIOx==GPIOF)RCC->APB2ENR|=1<<7; if(GPIOx==GPIOG)RCC->APB2ENR|=1<<8; if(OutOrIN==0) { switch (Pin) { case 0: GPIOx->CRL&=0XFFFFFFF0;GPIOx->CRL|=0X00000003;break; case 1: GPIOx->CRL&=0XFFFFFF0F;GPIOx->CRL|=0X00000030;break; case 2: GPIOx->CRL&=0XFFFFF0FF;GPIOx->CRL|=0X00000300;break; case 3: GPIOx->CRL&=0XFFFF0FFF;GPIOx->CRL|=0X00003000;break; case 4: GPIOx->CRL&=0XFFF0FFFF;GPIOx->CRL|=0X00030000;break; case 5: GPIOx->CRL&=0XFF0FFFFF;GPIOx->CRL|=0X00300000;break; case 6: GPIOx->CRL&=0XF0FFFFFF;GPIOx->CRL|=0X03000000;break; case 7: GPIOx->CRL&=0X0FFFFFFF;GPIOx->CRL|=0X30000000;break; case 8: GPIOx->CRH&=0XFFFFFFF0;GPIOx->CRH|=0X00000003;break; case 9: GPIOx->CRH&=0XFFFFFF0F;GPIOx->CRH|=0X00000030;break; case 10: GPIOx->CRH&=0XFFFFF0FF;GPIOx->CRH|=0X00000300;break; case 11: GPIOx->CRH&=0XFFFF0FFF;GPIOx->CRH|=0X00003000;break; case 12: GPIOx->CRH&=0XFFF0FFFF;GPIOx->CRH|=0X00030000;break; case 13: GPIOx->CRH&=0XFF0FFFFF;GPIOx->CRH|=0X00300000;break; case 14: GPIOx->CRH&=0XF0FFFFFF;GPIOx->CRH|=0X03000000;break; case 15: GPIOx->CRH&=0X0FFFFFFF;GPIOx->CRH|=0X30000000;break; default:break; } } if(OutOrIN==1) { switch (Pin) { case 0: GPIOx->CRL&=0XFFFFFFF0;GPIOx->CRL|=0X00000008;GPIOx->ODR|=1<<0;break; case 1: GPIOx->CRL&=0XFFFFFF0F;GPIOx->CRL|=0X00000080;GPIOx->ODR|=1<<1;break; case 2: GPIOx->CRL&=0XFFFFF0FF;GPIOx->CRL|=0X00000800;GPIOx->ODR|=1<<2;break; case 3: GPIOx->CRL&=0XFFFF0FFF;GPIOx->CRL|=0X00008000;GPIOx->ODR|=1<<3;break; case 4: GPIOx->CRL&=0XFFF0FFFF;GPIOx->CRL|=0X00080000;GPIOx->ODR|=1<<4;break; case 5: GPIOx->CRL&=0XFF0FFFFF;GPIOx->CRL|=0X00800000;GPIOx->ODR|=1<<5;break; case 6: GPIOx->CRL&=0XF0FFFFFF;GPIOx->CRL|=0X08000000;GPIOx->ODR|=1<<6;break; case 7: GPIOx->CRL&=0X0FFFFFFF;GPIOx->CRL|=0X80000000;GPIOx->ODR|=1<<7;break; case 8: GPIOx->CRH&=0XFFFFFFF0;GPIOx->CRH|=0X00000008;GPIOx->ODR|=1<<0;break; case 9: GPIOx->CRH&=0XFFFFFF0F;GPIOx->CRH|=0X00000080;GPIOx->ODR|=1<<1;break; case 10: GPIOx->CRH&=0XFFFFF0FF;GPIOx->CRH|=0X00000800;GPIOx->ODR|=1<<2;break; case 11: GPIOx->CRH&=0XFFFF0FFF;GPIOx->CRH|=0X00008000;GPIOx->ODR|=1<<3;break; case 12: GPIOx->CRH&=0XFFF0FFFF;GPIOx->CRH|=0X00080000;GPIOx->ODR|=1<<4;break; case 13: GPIOx->CRH&=0XFF0FFFFF;GPIOx->CRH|=0X00800000;GPIOx->ODR|=1<<5;break; case 14: GPIOx->CRH&=0XF0FFFFFF;GPIOx->CRH|=0X08000000;GPIOx->ODR|=1<<6;break;; case 15: GPIOx->CRH&=0X0FFFFFFF;GPIOx->CRH|=0X80000000;GPIOx->ODR|=1<<7;break; default:break; } } if(OutOrIN==-1) { switch (Pin) { case 0: GPIOx->CRL&=0XFFFFFFF0;GPIOx->CRL|=0X00000008;break; case 1: GPIOx->CRL&=0XFFFFFF0F;GPIOx->CRL|=0X00000080;break; case 2: GPIOx->CRL&=0XFFFFF0FF;GPIOx->CRL|=0X00000800;break; case 3: GPIOx->CRL&=0XFFFF0FFF;GPIOx->CRL|=0X00008000;break; case 4: GPIOx->CRL&=0XFFF0FFFF;GPIOx->CRL|=0X00080000;break; case 5: GPIOx->CRL&=0XFF0FFFFF;GPIOx->CRL|=0X00800000;break; case 6: GPIOx->CRL&=0XF0FFFFFF;GPIOx->CRL|=0X08000000;break; case 7: GPIOx->CRL&=0X0FFFFFFF;GPIOx->CRL|=0X80000000;break; case 8: GPIOx->CRH&=0XFFFFFFF0;GPIOx->CRH|=0X00000008;break; case 9: GPIOx->CRH&=0XFFFFFF0F;GPIOx->CRH|=0X00000080;break; case 10: GPIOx->CRH&=0XFFFFF0FF;GPIOx->CRH|=0X00000800;break; case 11: GPIOx->CRH&=0XFFFF0FFF;GPIOx->CRH|=0X00008000;break; case 12: GPIOx->CRH&=0XFFF0FFFF;GPIOx->CRH|=0X00080000;break; case 13: GPIOx->CRH&=0XFF0FFFFF;GPIOx->CRH|=0X00800000;break; case 14: GPIOx->CRH&=0XF0FFFFFF;GPIOx->CRH|=0X08000000;break;; case 15: GPIOx->CRH&=0X0FFFFFFF;GPIOx->CRH|=0X80000000;break; default:break; } } } /************************************************************************** //函数名称:单个按键扫描程序 //作用:直连按键扫描程序,包括KE0(PE4)。//mode=1,支持连按。 //示例:KEY_Scan(0) //作者:陈德强 //时间:2019年4月8日17:29:05 //修改者: //修改时间: //修改说明: ***************************************************************************/ u8 KEY_Scan(u8 mode) { static u8 key_up=1;//按键按松开标志 if(mode)key_up=1; //支持连按 if(key_up&&(KEY0==0||KEY1==0||WakeUP==1)) { delay_ms(10);//去抖动 key_up=0; if(KEY0==0)return 1; else if(KEY1==0)return 2; else if(WakeUP==1)return 3; }else if(KEY0==1&&KEY1==1&&WakeUP==0)key_up=1; return 0;// 无按键按下 } /****************************************************************************** //函数名称:UART2初始化函数及中断函数 //作用:UART2初始化函数。注:使用时用杜邦线将PA2和P9下的RXD连接,将PA3和TXD连接。 //示例:USART2_Init(115200); //作者:陈德强 //时间:2019年4月10日17:16:36 //修改者: //修改时间: //修改说明: *******************************************************************************/ void USART2_Init(int BaudRate) { GPIO_InitTypeDef GPIO_InitStrue; USART_InitTypeDef USART_InitStrue; //使能引脚A RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA,ENABLE); //使能串口复用功能 RCC_APB1PeriphClockCmd(RCC_APB1Periph_USART2,ENABLE); /*----------------------配置引脚PA2和PA3为复用功能----------------*/ GPIO_InitStrue.GPIO_Mode=GPIO_Mode_AF_PP; GPIO_InitStrue.GPIO_Pin=GPIO_Pin_2; GPIO_InitStrue.GPIO_Speed=GPIO_Speed_10MHz; GPIO_Init(GPIOA,&GPIO_InitStrue); GPIO_InitStrue.GPIO_Mode=GPIO_Mode_IN_FLOATING; GPIO_InitStrue.GPIO_Pin=GPIO_Pin_3; GPIO_InitStrue.GPIO_Speed=GPIO_Speed_10MHz; GPIO_Init(GPIOA,&GPIO_InitStrue); /*----------------------------------------------------------------*/ /*-------------------------配置USART2-----------------------------*/ USART_InitStrue.USART_BaudRate=BaudRate; USART_InitStrue.USART_HardwareFlowControl=USART_HardwareFlowControl_None; USART_InitStrue.USART_Mode=USART_Mode_Tx|USART_Mode_Rx; USART_InitStrue.USART_Parity=USART_Parity_No; USART_InitStrue.USART_StopBits=USART_StopBits_1; USART_InitStrue.USART_WordLength=USART_WordLength_8b; USART_Init(USART2,&USART_InitStrue);//③ /*----------------------------------------------------------------*/ //使能串口1 USART_Cmd(USART2,ENABLE); //开启接收中断 USART_ITConfig(USART2,USART_IT_RXNE,ENABLE); } /*----------------------------串口2中断服务函数--------------------------------*/ void USART2_IRQHandler(void) { u8 res; static int num; if(USART_GetITStatus(USART2,USART_IT_RXNE)) //当接收寄存器接收到数据时 { res= USART_ReceiveData(USART2); //将数据放在res变量中 USART_SendData(USART2,res); //将数据发送到串口,这时电脑串口接收到数据,并在串口调试助手显示出来。 num++; if(num==5) { num=0; LED0 =1; } } } /*----------------------------------------------------------------------------*/ /****************************************************************************** //函数名称:外部中断初始化函数及中断函数 //作用:外部中断初始化函数。带注释的地方需要改。1上升沿,0上升沿。 //示例:EXTIX_Init(GPIOE,3,0); //说明:PE3引脚,下降沿 //作者:陈德强 //时间:2019年4月11日00:56:11 //修改者: //修改时间: //修改说明: *******************************************************************************/ void ExtiInit(GPIO_TypeDef * GPIOx,u8 BITx,u8 UpOrDown) { u8 EXTADDR; u8 EXTOFFSET; u8 gpiox; if(GPIOx==GPIOA)gpiox=0; if(GPIOx==GPIOB)gpiox=1; if(GPIOx==GPIOC)gpiox=2; if(GPIOx==GPIOD)gpiox=3; if(GPIOx==GPIOE)gpiox=4; if(GPIOx==GPIOF)gpiox=5; if(GPIOx==GPIOG)gpiox=6; EXTADDR=BITx/4; EXTOFFSET=(BITx%4)*4; RCC->APB2ENR|=0x01; AFIO->EXTICR[EXTADDR]&=~(0x000F<<EXTOFFSET); AFIO->EXTICR[EXTADDR]|=gpiox<<EXTOFFSET; EXTI->IMR|=1<<BITx; if(UpOrDown==0)EXTI->FTSR|=1<<BITx; if(UpOrDown==1)EXTI->RTSR|=1<<BITx; } /*----------------------外部中断3服务程序中断服务函数--------------------------*/ void EXTI3_IRQHandler(void) { delay_ms(10);//消抖 if(KEY1==0) //按键KEY1 { LED0=!LED0; LED1=!LED1; } EXTI_ClearITPendingBit(EXTI_Line3); //清除LINE3上的中断标志位 } /****************************************************************************** //函数名称:NVIC设置函数 //作用:设置NVIC。数值越小,优先级越高。 //示例:NVICInit(2,1,EXTI3_IRQn,2); //说明:设置抢占优先级为2,子优先级为1,中断类型为EXTI3_IRQn,中断分组方式为组2. //作者:陈德强 //时间:2019年4月11日00:52:32 //修改者: //修改时间: //修改说明: *******************************************************************************/ void NVICPriorityGroupConfig(u8 NVIC_Group) { u32 temp,temp1; temp1=(~NVIC_Group)&0x07; temp1<<=8; temp=SCB->AIRCR; temp&=0X0000F8FF; temp|=0X05FA0000; temp|=temp1; SCB->AIRCR=temp; } void NVICInit(u8 NVIC_PreemptionPriority,u8 NVIC_SubPriority,u8 NVIC_Channel,u8 NVIC_Group) { u32 temp; NVICPriorityGroupConfig(NVIC_Group); temp=NVIC_PreemptionPriority<<(4-NVIC_Group); temp|=NVIC_SubPriority&(0x0f>>NVIC_Group); temp&=0xf; NVIC->ISER[NVIC_Channel/32]|=(1<<NVIC_Channel2); NVIC->IP[NVIC_Channel]|=temp<<4; } /****************************************************************************** //函数名称:独立看门狗初始化 //作用:程序卡死时自动复位。 //示例:IWDG_Init(4,625);//约为1s //说明:时间计算(大概):Tout=((4*2^prer)*rlr)/40 (ms). //作者:陈德强 //时间:2019年4月11日08:20:43 //修改者: //修改时间: //修改说明: *******************************************************************************/ void IWDG_Init(u8 prer,u16 rlr) { IWDG_WriteAccessCmd(IWDG_WriteAccess_Enable); IWDG_SetPrescaler(prer); IWDG_SetReload(rlr); IWDG_ReloadCounter(); IWDG_Enable(); } /****************************************************************************** //函数名称:通用定时器初始化函数 //作用:初始化通用定时器,即定时器2、3、4、5。 //示例:TIMInit(TIM3,500); //说明:500ms更新一次,arr和psc随便设置,不超过2^16-1就行。. //作者:陈德强 //时间:2019年4月11日09:12:40 //修改者: //修改时间: //修改说明: *******************************************************************************/ void TIMInit(TIM_TypeDef* TIMx,u16 uptime) { u8 addr; if(TIMx==TIM2)addr=1; if(TIMx==TIM3)addr=2; if(TIMx==TIM4)addr=3; if(TIMx==TIM5)addr=4; RCC->APB1ENR|=1<<addr; TIMx->ARR=uptime*10-1; TIMx->PSC=7200-1; TIMx->DIER|=1<<0; TIMx->CR1|=0x01; } /*---------------------------定时器3中断服务程序------------------------------*/ void TIM3_IRQHandler(void) { if (TIM_GetITStatus(TIM3, TIM_IT_Update) != RESET) { TIM_ClearITPendingBit(TIM3, TIM_IT_Update ); LED1=!LED1; } } /****************************************************************************** //函数名称:PWM初始化函数 //作用:初始化PWM。TIM2-TIM5,每个定时器4个通道。每个通道有固定引脚。 // 目前仅写了PWMInit(TIM2,2,900);和PWMInit(TIM3,1,900);和PWMInit(TIM3,2,900); //示例:PWMInit(TIM2,1,900);//启用定时器2的CH1通道,自动装载值为0-899。 //说明:PWM频率=72000000/900=80Khz。 //PWM的调用函数:TIM_SetCompare2(TIM2,100); //第二个参数要在自动装载值的范围内,即0-899 //作者:陈德强 //时间:2019年4月11日12:23:19 //修改者: //修改时间: //修改说明: *******************************************************************************/ void PWMInit(TIM_TypeDef *TIMx,u8 CHx,u16 arr) { u8 addr; if(TIMx==TIM2)addr=1; if(TIMx==TIM3)addr=2; if(TIMx==TIM4)addr=3; if(TIMx==TIM5)addr=4; RCC->APB1ENR|=1<<addr; if((TIMx==TIM2)&&(CHx==2))//TIM2的CH2通道PA1 { RCC->APB1ENR|=1<<0; //TIM2时钟使能 RCC->APB2ENR|=1<<1; //使能PORTA时钟 GPIOA->CRL&=0XFFFFFF0F; //PA1输出 GPIOA->CRL|=0X000000B0; //复用功能输出 RCC->APB2ENR|=0x01; TIMx->ARR=arr-1; TIMx->PSC=0; TIMx->CCMR1|=7<<12; TIMx->CCMR1|=1<<11; TIMx->CCER|=1<<4; TIMx->CR1=0x0080; TIMx->CR1|=0x01; } if((TIMx==TIM3)&&(CHx==1))//TIM3的CH1通道PB5 { RCC->APB1ENR|=1<<1; RCC->APB2ENR|=1<<3; GPIOB->CRL&=0XFF0FFFFF; GPIOB->CRL|=0X00B00000; RCC->APB2ENR|=1<<0; AFIO->MAPR&=0XFFFFF3FF; AFIO->MAPR|=1<<11; TIM3->ARR=arr; TIM3->PSC=0; TIM3->CCMR1|=7<<12; TIM3->CCMR1|=1<<11; TIM3->CCER|=1<<4; TIM3->CR1=0x0080; TIM3->CR1|=0x01; } if((TIMx==TIM3)&&(CHx==2))//TIM3的CH2通道PA7 { RCC->APB1ENR|=1<<1; RCC->APB2ENR|=1<<1; GPIOA->CRL&=0X0FFFFFFF; GPIOA->CRL|=0XB0000000; RCC->APB2ENR|=0x01; TIMx->ARR=arr-1; TIMx->PSC=0; TIMx->CCMR1|=7<<12; TIMx->CCMR1|=1<<11; TIMx->CCER|=1<<4; TIMx->CR1=0x0080; TIMx->CR1|=0x01; } } /****************************************************************************** //函数名称:输入捕获初始化函数 //作用:捕获PA0的上升沿,并输出结果。 //示例:CapInit(0XFFFF,72-1); //说明: //PWM的调用函数:由定时器中断处理。 //作者:陈德强 //时间:2019年4月11日16:56:00 //修改者: //修改时间: //修改说明: *******************************************************************************/ void CapInit(u16 arr,u16 psc) { RCC->APB1ENR|=1<<3; //TIM5 时钟使能 RCC->APB2ENR|=1<<2; //使能PORTA时钟 GPIOA->CRL&=0XFFFFFFF0; //PA0 清除之前设置 GPIOA->CRL|=0X00000008; //PA0 输入 GPIOA->ODR|=0<<0; //PA0 下拉 TIM5->ARR=arr; //设定计数器自动重装值 TIM5->PSC=psc; //预分频器 TIM5->CCMR1|=1<<0; //CC1S=01 选择输入端 IC1映射到TI1上 TIM5->CCMR1|=0<<4; //IC1F=0000 配置输入滤波器 不滤波 TIM5->CCMR1|=0<<10; //IC2PS=00 配置输入分频,不分频 TIM5->CCER|=0<<1; //CC1P=0 上升沿捕获 TIM5->CCER|=1<<0; //CC1E=1 允许捕获计数器的值到捕获寄存器中 TIM5->DIER|=1<<1; //允许捕获中断 TIM5->DIER|=1<<0; //允许更新中断 TIM5->CR1|=0x01; //使能定时器2 } void TIM5_IRQHandler(void) { if (TIM_GetITStatus(TIM5, TIM_IT_Update) != RESET) { if (TIM_GetITStatus(TIM5, TIM_IT_CC1) != RESET) { printf("捕获到一次上升沿输入!\r\n"); LED0=!LED0; } TIM_ClearITPendingBit(TIM5, TIM_IT_CC1|TIM_IT_Update); //清除中断标志位 } }

    二、imut.h文件

    #ifndef __IMUT_H__ #define __IMUT_H__ #include "stm32f10x.h" #include "sys.h" #include "delay.h" #include "usart.h" #define KEY0 PEin(4) #define LED0 PBout(5) #define LED1 PEout(5) #define KEY0 PEin(4) #define KEY1 PEin(3) #define WakeUP PAin(0) #define BEEP PBout(8) void SysInit(void); void GPIOInit(GPIO_TypeDef * GPIOx,u8 Pin,int OutOrIN); u8 KEY_Scan(u8 mode); void NVICPriorityGroupConfig(u8 NVIC_Group); void NVICInit(u8 NVIC_PreemptionPriority,u8 NVIC_SubPriority,u8 NVIC_Channel,u8 NVIC_Group); void USART2_Init(int BaudRate); void ExtiInit(GPIO_TypeDef * GPIOx,u8 BITx,u8 UpOrDown); void LEDInit(u8 LED); void KeyInit(u8 KEY); void USARTInit(u8 usart,int paudrate); void IWDG_Init(u8 prer,u16 rlr); void TIMInit(TIM_TypeDef* TIMx,u16 uptime); void PWMInit(TIM_TypeDef* TIMx,u8 CHx,u16 arr); void CapInit(u16 arr,u16 psc); #endif
    Processed: 0.015, SQL: 12