stm32外设库函数的功能

//RCC库函数(常用)
void RCC_AHBPeriphClockCmd(uint32_t RCC_AHBPeriph, FunctionalState NewState);	//使能或者失能外设时钟,参数1选择外设,参数二使能或者失能时钟控制的第一个参数可以使用按位或来选中多个外设。
void RCC_APB2PeriphClockCmd(uint32_t RCC_APB2Periph, FunctionalState NewState);	//以此类推
void RCC_APB1PeriphClockCmd(uint32_t RCC_APB1Periph, FunctionalState NewState);	//以此类推
GPIO库函数
GPIO输入模式的选择:我们一般看接在这个GPIO口的外部引脚的外部模块输出的默认电平,如果外部模块默认输出高电平,那我们就选择上拉输入模式,如果外部模块默认输出低电平,那我们就选择下拉输入模式,和外部模块默认输入电平保持一致,防止默认电平打架,但一般外部模块默认高电平居多,所以上拉输入模式用的也比较多。如果不确定外部默认输出模式又或者外部信号输出功率非常小,这是就尽量选择浮空输入,这样就不会因为上拉或者下拉电阻对去影响外部的信号,缺点就是当引脚悬空的时候,默认就是没有点电平了,容易受到外部噪声的影响。
    
void GPIO_DeInit(GPIO_TypeDef* GPIOx);	//调用此函数所指定的GPIO就会被复位
void GPIO_AFIODeInit(void);	//复位AFIO
void GPIO_Init(GPIO_TypeDef* GPIOx, GPIO_InitTypeDef* GPIO_InitStruct);	//用结构体的参数来初始化GPIO,先定义结构体,然后给结构体进行赋值,最后传入结构体参数
void GPIO_StructInit(GPIO_InitTypeDef* GPIO_InitStruct);	//把结构体变量赋一个默认值
//GPIO读取函数
uint8_t GPIO_ReadInputDataBit(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin);	//读取输入寄存器的某一位
uint16_t GPIO_ReadInputData(GPIO_TypeDef* GPIOx);					//读取整个输入寄存器
uint8_t GPIO_ReadOutputDataBit(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin);	//读取输出寄存器的某一位
uint16_t GPIO_ReadOutputData(GPIO_TypeDef* GPIOx);	//读取整个输出寄存器
//GPIO写入函数
void GPIO_SetBits(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin);	//指定端口设置为高电平,可以使用按位或来选中多个。
void GPIO_ResetBits(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin);//指定的端口设置为低电平,可以使用按位或来选中多个。
void GPIO_WriteBit(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin, BitAction BitVal);	//根据第三个参数的值来设置指定电平
void GPIO_Write(GPIO_TypeDef* GPIOx, uint16_t PortVal);	//可以同时对16个端口进行写入操作。

//GPIO8中工作模式
  GPIO_Mode_AIN = 0x0,	//模拟输入
  GPIO_Mode_IN_FLOATING = 0x04,	//浮空输入(当外部的输入功率很小的时候可以选择浮空输入,内部的上拉电阻可能会影响到这个输入信号的时候最好选用浮空输入)
  GPIO_Mode_IPD = 0x28,	//下拉输入
  GPIO_Mode_IPU = 0x48,	//上拉输入
  GPIO_Mode_Out_OD = 0x14,	//开漏输出
  GPIO_Mode_Out_PP = 0x10,	//推挽输出
  GPIO_Mode_AF_OD = 0x1C,	//复用开漏
  GPIO_Mode_AF_PP = 0x18	//复用推挽
//GPIO_Pin_ 可以实现按位或的操作,实现控制多个IO口,因为每一个引脚对应了一个二进制,按位或可以得出一个所有这些IO口都选中的一个二进制的值
//PA15   PB8  PBC默认是JTAG的调试端口不是普通IO口,如果要配置为普通IO口我们还需要在进行一些其他的配置。
GPIO配置好了之后默认就是低电平。
stm32的引脚上电之后,如果不初始化,默认是浮空输入模式,该模式下引脚不会输出电平
内核外设的手册要去 Cortex-M3编程手册去找,里面有内核和内核外设的详细介绍
外部中断EXTI,其库函数有三大类1初始化,2软件中断,3标志位控制
涉及的外设:RCC GPIO AFIO EXTI NVIC 
1.配置外部中断的步骤
2.第一步配置RCC把我们这里涉及的外设的时钟打开
3.第二步配置GPIO选择我们的端口为输入模式,外部中断我们选择浮空、上拉、下拉这几个输入模式的其中的一种。
4.第三步配置AFIO并选择GPIO口连接到EXTI 
5.第四步配置EXTI选择边沿触发模式比如上升沿,下降沿,双边沿。选择触发选择方式可以选择中断响应和事件响应(EXTI外设是一直打开的)
6.第五步配置NVIC给中断选择一个合适的优先级(NVIC外设是一直打开的,NVIC是内核的外设内核的外设都不需要开启时钟)
void EXTI_DeInit(void);	//将EXTI的配置都清除,恢复成上电默认的状态
void EXTI_Init(EXTI_InitTypeDef* EXTI_InitStruct);	//根据参数传入的结构体来配置EXTI外设使用方法和GPIO_Init()是一样的
void EXTI_StructInit(EXTI_InitTypeDef* EXTI_InitStruct);	//将参数传递的结构体变量赋一个默认值

void EXTI_GenerateSWInterrupt(uint32_t EXTI_Line);	//软件触发外部中断的,调用参数传一个指定的中断线,就能够软件触发一次该外部中断
//标志位函数(对状态寄存器进行读写)
FlagStatus EXTI_GetFlagStatus(uint32_t EXTI_Line);	//获取配置寄存器当中的指定标志位是不是被置1了(主程序当中使用)什么位都可以看
void EXTI_ClearFlag(uint32_t EXTI_Line);	//对置1的标志位进行清楚(主程序当中使用)什么位都可以看
ITStatus EXTI_GetITStatus(uint32_t EXTI_Line);	//获取中断标志位是不是被置1了(在中断函数当中的使用)只看中断位
void EXTI_ClearITPendingBit(uint32_t EXTI_Line);	//清楚中断挂起标志位(在中断函数当中使用)只看中断位
AFIO外设
void GPIO_AFIODeInit(void);  	//复位该外设,调用这个函数AFIO外设的配置会全部清除
void GPIO_PinLockConfig(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin);	//锁定GPIO配置,锁定某个引脚,防止被更改
//配置AFIO的事件输出功能的
void GPIO_EventOutputConfig(uint8_t GPIO_PortSource, uint8_t GPIO_PinSource);
void GPIO_EventOutputCmd(FunctionalState NewState);

void GPIO_PinRemapConfig(uint32_t GPIO_Remap, FunctionalState NewState);	//引脚重映射第一个参数是重映射的方式,第二个参数是新的状态
	GPIO_Remap_SWJ_NoJTRST //SWJ就是SWD和JTAG这两种调试方式,这个参数是解除NJTRST引脚的复用,PB14转变为正常的GPIO口
    GPIO_Remap_SWJ_JTAGDisable	//接触JTAG调试端口的复用 PA15,PB3,PB4三个端口变为GPIO
    GPIO_Remap_SWJ_Disable	//把SWJ和JTAG的所有调试端口全部解除,不要随便调用,一旦你调用这个函数并且下载程序之后,那么你的调试端口就没有了,STLink也就下载不进去东西了,最后只能够通过串口来进行下载程序了
void GPIO_EXTILineConfig(uint8_t GPIO_PortSource, uint8_t GPIO_PinSource);	//配置AFIO的数据选择器选择我们想要中断的引脚常和中断一起使用。
void GPIO_ETH_MediaInterfaceConfig(uint32_t GPIO_ETH_MediaInterface);	//和以太网有关系
NVIC中断内外设(先中断分组再初始化)
void NVIC_PriorityGroupConfig(uint32_t NVIC_PriorityGroup);	//中断分组参数是中断分组的方式,分组方式整个芯片只能够用一种,所以工程中只执行一次就可以了,但是如果是使用的模块化进行编程,要保证我们每个模块的分组方式选择的是同一个
void NVIC_Init(NVIC_InitTypeDef* NVIC_InitStruct);	//根据结构体里面指定的参数初始化NVIC
void NVIC_SetVectorTable(uint32_t NVIC_VectTab, uint32_t Offset);	//设置中断向量表不常用
void NVIC_SystemLPConfig(uint8_t LowPowerMode, FunctionalState NewState);	//系统低功耗设置不常用
pre-emption priority先占优先级(抢占优先级)
subpriority 从占优先级(响应优先级)
中断函数的结构:s
    if(EXTI_GetITStatus(EXTI_Linex)==1)//中断标志位判断
    {
        中断函数执行的内容;
        EXTI_ClearITPendingBit(EXTI_Linex);	//清除中断标志位
    }
    首先在启动文件当中找到对应中断函数的名字,然后进入中断我们要先进行一下中断标志位的判断,确保是我们想要的通道触发的中断
因为有断通道是公用一个中断函数的。
定时器中断(定时器上电后默认就是内部时钟)
第一步:RCC开启时钟打开时钟之后定时器的基准时钟和外设的工作时钟就会同时打开了
第二部:选择时基单元的时钟源,定时中断我们选择内部的时钟源
第三步:配置时基单元预分频器、自动重装器、计数模式
第四步:配置输出中断控制,允许更新中断输出到NVIC
第五步:配置NVIC,NVIC中打开定时器中断的通道,并分配一个优先级
第六步:运行控制使能一下计数器
定时器库函数
	void TIM_DeInit(TIM_TypeDef* TIMx);	//回复缺省配置

/*配置时基单元*/
	void TIM_TimeBaseInit(TIM_TypeDef* TIMx, TIM_TimeBaseInitTypeDef* TIM_TimeBaseInitStruct);	//时基单元初始化配置时基单元,第一个参数选择定时器,第二个参数结构体(滤波器频率采样频率越低,采样点数越多,滤波效果越好,但是相应的延迟越大。滤波器是通过采样看看n个点的电平是不是相同的,如果是相同的那么就可以证明信号是稳定的,直接输出,如果不相同那么我们就证明信号不稳定,那么就保持上一次的信号输出或者直接输出低电平就可以了。采样频率从内部的始终来,或者内部时钟分频来,分频多少就是我们结构体第一个参数的功能)
	void TIM_TimeBaseStructInit(TIM_TimeBaseInitTypeDef* TIM_TimeBaseInitStruct);	//可以把结构体变量赋一个默认值


/*运行控制*/
	void TIM_Cmd(TIM_TypeDef* TIMx, FunctionalState NewState);	//使能计数器也就是我们ppt当中的运行控制,第一个参数选择定时器、第二个参数新的状态也是使能与使能这两个(启动定时器)


/*中断输出控制*/
	void TIM_ITConfig(TIM_TypeDef* TIMx, uint16_t TIM_IT, FunctionalState NewState);	//使能中断输出信号的,也就是我们的中断输出控制,第一个参数选择定时器、第二个参数要选择配置哪个中断输出、第三个参数状态使能或者使能(使能外设的中断输出)


/*时基单元的时钟选择部分*/
	void TIM_InternalClockConfig(TIM_TypeDef* TIMx);	//选择内部时钟
	void TIM_ITRxExternalClockConfig(TIM_TypeDef* TIMx, uint16_t TIM_InputTriggerSource);	//选择ITRX其他定时器时钟,第一个参数,需要配置的定时器。第二个参数,选择要接入哪个其他的定时器
	void TIM_TIxExternalClockConfig(TIM_TypeDef* TIMx, uint16_t TIM_TIxExternalCLKSource,
                                uint16_t TIM_ICPolarity, uint16_t ICFilter);	//选择TIx捕获通道的时钟,第二个参数,选择TIx某个具体的引脚,第三个参数,输入的极性,第四个参数,选择滤波器
	void TIM_ETRClockMode1Config(TIM_TypeDef* TIMx, uint16_t TIM_ExtTRGPrescaler, uint16_t TIM_ExtTRGPolarity,
                             uint16_t ExtTRGFilter);	//选择ETR通过外部时钟模式1输入的时钟 TIM_ExtTRGPrescaler:外部触发预分频器,可以对ETR的外部时钟再提前做一个分频  TIM_ExtTRGPolarity:极性 ExtTRGFilter:滤波器
	void TIM_ETRClockMode2Config(TIM_TypeDef* TIMx, uint16_t TIM_ExtTRGPrescaler, 
                             uint16_t TIM_ExtTRGPolarity, uint16_t ExtTRGFilter);	//选择ETR通过外部时钟2模式输入的时钟
	void TIM_ETRConfig(TIM_TypeDef* TIMx, uint16_t TIM_ExtTRGPrescaler, uint16_t TIM_ExtTRGPolarity,
                   uint16_t ExtTRGFilter);	//单独用来配置ETR的引脚的预分频器、极性、滤波器这些参数
	

//单独修改某个参数函数
void TIM_PrescalerConfig(TIM_TypeDef* TIMx, uint16_t Prescaler, uint16_t TIM_PSCReloadMode);	//单独写预分频值 Prescaler:要写入的预分频值 TIM_PSCReloadMode:要写入的模式(缓冲器有无发生作用)
void TIM_CounterModeConfig(TIM_TypeDef* TIMx, uint16_t TIM_CounterMode);	//用来改变计数器的计数模式 TIM_CounterMode选择新的计数器模式
void TIM_ARRPreloadConfig(TIM_TypeDef* TIMx, FunctionalState NewState);	//自动重装器预装功能配置
void TIM_SetCounter(TIM_TypeDef* TIMx, uint16_t Counter);	//给计数器写入一个值
void TIM_SetAutoreload(TIM_TypeDef* TIMx, uint16_t Autoreload);	//给自动重装器写一个值
uint16_t TIM_GetCounter(TIM_TypeDef* TIMx);	//获取当前计数器的值
uint16_t TIM_GetPrescaler(TIM_TypeDef* TIMx);	//获取当前预分频器的值,可以看预分频值
FlagStatus TIM_GetFlagStatus(TIM_TypeDef* TIMx, uint16_t TIM_FLAG);	//获取标志位(主函数调用)
void TIM_ClearFlag(TIM_TypeDef* TIMx, uint16_t TIM_FLAG);	//清除标志位(主函数调用)
ITStatus TIM_GetITStatus(TIM_TypeDef* TIMx, uint16_t TIM_IT);	//获取中断标志位(中断程序当中调用)
void TIM_ClearITPendingBit(TIM_TypeDef* TIMx, uint16_t TIM_IT);	//清除中断标志位(中断程序当中调用)
定时器外设的输出比较(输出PWM波形)
第一步:RCC开启我们需要的TIM外设和GPIO外设
第二部:配置时基单元包括前面的时钟源选择
第三步:配置输出比较单元
第四步:配置GPIO初始化为复用推挽输出的配置
第五步:运行控制
定时器输出比较库函数
同一个定时器不同的通道输出PWM的特点,因为所有的通道是公用一个计数器的,所以他们的频率是一样的,但是它们的占空比是由各自的CCR决定的,它们的相位,由于计数器更新,所有的PWM同时跳变,所以相位是同步的。
//配置输出比较模块的库函数OC(output Compare),因为有四个输出单元所以对应有四个函数,一个函数配置一个单元。
//第一个参数:选择定时器;第二个参数:结构体就是输出比较的那些参数了可以设置极性(我们还有单独设置极性的函数),不同的GPIO口对应的通道也不一样,根据选择的GPIO口来选择通道初始化函数(很重要)
void TIM_OC1Init(TIM_TypeDef* TIMx, TIM_OCInitTypeDef* TIM_OCInitStruct);
void TIM_OC2Init(TIM_TypeDef* TIMx, TIM_OCInitTypeDef* TIM_OCInitStruct);
void TIM_OC3Init(TIM_TypeDef* TIMx, TIM_OCInitTypeDef* TIM_OCInitStruct);
void TIM_OC4Init(TIM_TypeDef* TIMx, TIM_OCInitTypeDef* TIM_OCInitStruct);
//用来给输出比较函数的结构体参数赋一个默认值的
void TIM_OCStructInit(TIM_OCInitTypeDef* TIM_OCInitStruct);
	这个结构体里面的模式参数
        TIM_OCMode_Timing //冻结模式
        TIM_OCMode_Active //相等时置有效电平
        TIM_OCMode_Inactive //相等时置无效电平
        TIM_OCMode_Toggle	//相等时电平翻转
        TIM_OCMode_PWM1		//PWM模式1
        TIM_OCMode_PWM2	//PWM模式2
    输出比较的极性
        TIM_OCPolarity_High	//高极性,极性不翻转REF波形直接输出
        TIM_OCPolarity_Low	//低极性,REF电平取反
        
//用来配置强制输出模式,用的不多,因为强制输出高电平和占空比100%是一样的,强制输出低电平和占空比0%也是一样的。了解即可
void TIM_ForcedOC1Config(TIM_TypeDef* TIMx, uint16_t TIM_ForcedAction);
void TIM_ForcedOC2Config(TIM_TypeDef* TIMx, uint16_t TIM_ForcedAction);
void TIM_ForcedOC3Config(TIM_TypeDef* TIMx, uint16_t TIM_ForcedAction);
void TIM_ForcedOC4Config(TIM_TypeDef* TIMx, uint16_t TIM_ForcedAction);
//用来配置CC R寄存器的预装功能的,影子寄存器,缓冲,你写入的值不会立即生效而是在下一次更新事件的时候才会生效,了解即可
void TIM_OC1PreloadConfig(TIM_TypeDef* TIMx, uint16_t TIM_OCPreload);
void TIM_OC2PreloadConfig(TIM_TypeDef* TIMx, uint16_t TIM_OCPreload);
void TIM_OC3PreloadConfig(TIM_TypeDef* TIMx, uint16_t TIM_OCPreload);
void TIM_OC4PreloadConfig(TIM_TypeDef* TIMx, uint16_t TIM_OCPreload);
//用来配置快速使能用的不多了解即可
void TIM_OC1FastConfig(TIM_TypeDef* TIMx, uint16_t TIM_OCFast);
void TIM_OC2FastConfig(TIM_TypeDef* TIMx, uint16_t TIM_OCFast);
void TIM_OC3FastConfig(TIM_TypeDef* TIMx, uint16_t TIM_OCFast);
void TIM_OC4FastConfig(TIM_TypeDef* TIMx, uint16_t TIM_OCFast);
//外部事件时清除REF信号了解就可
void TIM_ClearOC1Ref(TIM_TypeDef* TIMx, uint16_t TIM_OCClear);
void TIM_ClearOC2Ref(TIM_TypeDef* TIMx, uint16_t TIM_OCClear);
void TIM_ClearOC3Ref(TIM_TypeDef* TIMx, uint16_t TIM_OCClear);
void TIM_ClearOC4Ref(TIM_TypeDef* TIMx, uint16_t TIM_OCClear);
//单独设置输出比较的极性的带N的就是高级定时器里面互补通道的配置OC4没有互补函数,所以就没有OC4N的互补函数(我们初始化的结构体也可以设置极性,一般来说结构体里面的参数都会有一个单独的函数进行修改)
void TIM_OC1PolarityConfig(TIM_TypeDef* TIMx, uint16_t TIM_OCPolarity);
void TIM_OC1NPolarityConfig(TIM_TypeDef* TIMx, uint16_t TIM_OCNPolarity);
void TIM_OC2PolarityConfig(TIM_TypeDef* TIMx, uint16_t TIM_OCPolarity);
void TIM_OC2NPolarityConfig(TIM_TypeDef* TIMx, uint16_t TIM_OCNPolarity);
void TIM_OC3PolarityConfig(TIM_TypeDef* TIMx, uint16_t TIM_OCPolarity);
void TIM_OC3NPolarityConfig(TIM_TypeDef* TIMx, uint16_t TIM_OCNPolarity);
void TIM_OC4PolarityConfig(TIM_TypeDef* TIMx, uint16_t TIM_OCPolarity);
//单独修改输出使能参数的
void TIM_CCxCmd(TIM_TypeDef* TIMx, uint16_t TIM_Channel, uint16_t TIM_CCx);
void TIM_CCxNCmd(TIM_TypeDef* TIMx, uint16_t TIM_Channel, uint16_t TIM_CCxN);
//选择输出比较模式,用来单独更改输出比较模式的函数
void TIM_SelectOCxM(TIM_TypeDef* TIMx, uint16_t TIM_Channel, uint16_t TIM_OCMode);
//用来单独更改CCR寄存器值的函数在运行的时候更改占空比需要用到的函数(important)
void TIM_SetCompare1(TIM_TypeDef* TIMx, uint16_t Compare1);
void TIM_SetCompare2(TIM_TypeDef* TIMx, uint16_t Compare2);
void TIM_SetCompare3(TIM_TypeDef* TIMx, uint16_t Compare3);
void TIM_SetCompare4(TIM_TypeDef* TIMx, uint16_t Compare4);
//这个函数仅高级定时器使用,在使用高级定时器输出PWM波形时需要调用这个函数,否则PWM不能够正常输出
void TIM_CtrlPWMOutputs(TIM_TypeDef* TIMx, FunctionalState NewState);
定时器的输入捕获
第一步:RCC开启时钟,把GPIO和TIM的时钟打开
第二步:GPIO初始化,把GPIO配置成输入模式,一般选择上拉输入或者浮空输入
第三步:配置时基单元,让CNT计数器在内部时钟的驱动下自增运行。
第四步:配置输入配置输入捕获单元包括滤波器、极性、直连通道还是交叉通道、分频器这些参数。使用一个结构体就可以进行配置了。
第五步:选择从模式的触发源,触发源选择TI1FP1,调用一个库函数,给一个参数就可以了。
第六步:选择TIM_Cmd,开启定时器。
void TIM_ICInit(TIM_TypeDef* TIMx, TIM_ICInitTypeDef* TIM_ICInitStruct);	//结构体配置输入捕获单元的函数,输入捕获和输出比较都有4个通道,OCInit输出比较函数每个通道有各自的函数,而ICInt中输入捕获的在这四个通道是公用一个函数的,在该函数的结构体当中,有一个参数可以用来选择具体是配置哪个通道。,因为可能有交叉通道的配置,所以函数合在一起比较方便。
void TIM_PWMIConfig(TIM_TypeDef* TIMx, TIM_ICInitTypeDef* TIM_ICInitStruct);	//也是用于初始化输入捕获单元的,但是上一个函数只是单一地配置一个通道,而这个函数可以快速地配置两个通道。因此可以将外设配置为PWI模式,这个函数可以快速地将剩下的那个通道初始化成相反的配置,当然只能初始化一个通道啦。(如果我们传入通道1,智联。上升沿,那函数里面会顺带配置通道2,交叉,下降沿;如果传入通道2,直连,上升沿,函数就会顺带配置通道1,交叉,下降沿)
void TIM_ICStructInit(TIM_ICInitTypeDef* TIM_ICInitStruct);	//可以给输入捕获结构体赋一个初始值
void TIM_SelectInputTrigger(TIM_TypeDef* TIMx, uint16_t TIM_InputTriggerSource);	//选择输入触发源TRGI,就是触发源选择地TRGI,调用这个函数就能够选择从模式地触发源了。
void TIM_SelectOutputTrigger(TIM_TypeDef* TIMx, uint16_t TIM_TRGOSource);	//选择输出从触发源TRGO,也就是主模式地TRGO 
void TIM_SelectSlaveMode(TIM_TypeDef* TIMx, uint16_t TIM_SlaveMode);	//选择从模式
//分别单独配置这四个通道1、2、3、4的分频器,这个也可以通过初始化的结构体来进行配置
void TIM_SetIC1Prescaler(TIM_TypeDef* TIMx, uint16_t TIM_ICPSC);
void TIM_SetIC2Prescaler(TIM_TypeDef* TIMx, uint16_t TIM_ICPSC);
void TIM_SetIC3Prescaler(TIM_TypeDef* TIMx, uint16_t TIM_ICPSC);
void TIM_SetIC4Prescaler(TIM_TypeDef* TIMx, uint16_t TIM_ICPSC);
//分别读取四个通道的CCR,输出比较模式下,CCR是只写的,要用SetCapture写入,输入捕获模式下,CCR是只读的,要用GetCapture读出
uint16_t TIM_GetCapture1(TIM_TypeDef* TIMx);
uint16_t TIM_GetCapture2(TIM_TypeDef* TIMx);
uint16_t TIM_GetCapture3(TIM_TypeDef* TIMx);
uint16_t TIM_GetCapture4(TIM_TypeDef* TIMx);
定时器:编码器接口测速。
    //第一步:RCC开启时钟,开启GPIO和定时器的时钟
	//第二步:配置GPIO,这里需要将PA6和PA7配置成输入模式
	//第三步:配置时基单元,这里的预分频器我们一般选择不分频,自动重装一般给最大65535,只需要一个CNT执行计数就可以了。
	//第四步:配置输入捕获单元,不过这里的输入捕获单元只有滤波器和极性选择这两个参数有作用
	//第五步:配置编码器接口的模式,直接调用一个库函数就可以了
	//第六步:调用TIM_Cmd,启动定时器就可以了。
    void TIM_EncoderInterfaceConfig(TIM_TypeDef* TIMx, uint16_t TIM_EncoderMode,
                                uint16_t TIM_IC1Polarity, uint16_t TIM_IC2Polarity);	//定时器编码器接口配置第一个参数,选择定时器,第二个参数选择编码器模式,后面两个参数分别选择通道1通道2的电平极性
ADC数模转换器
    第一步:开启RCC时钟,包括GPIO和ADC的时钟。同时ADCCLK的分频器也需要配置一下。
    第二步:配置GPIO,把需要的GPIO配置成模拟输入的模式。
    第三步:配置这里的多路开关。,把左边的通道接入到右边的规则组列表里。
    第四步:配置ADC转换器。库函数当中是用结构体来进行配置的
    第五步:调用一下ADC_cmd函数这样就可以开启ADC了,开启之后我们还可以对ADC进行一下校准,这样可以减小误差。如果在ADC工作的时候想要软件来触发,那么就可以使用函数来进行触发。如果想读取转换结果,那么也会有相应的函数进行读取。

void RCC_ADCCLKConfig(uint32_t RCC_PCLK2);	//用来配置ADCCLK预分频器的,它可以对APB2的72MHZ时钟选择2、4、6、8分频输入到ADCCLK。
void ADC_DeInit(ADC_TypeDef* ADCx);//恢复缺省配置。
void ADC_Init(ADC_TypeDef* ADCx, ADC_InitTypeDef* ADC_InitStruct);//初始化。
void ADC_StructInit(ADC_InitTypeDef* ADC_InitStruct);//结构体初始化
void ADC_Cmd(ADC_TypeDef* ADCx, FunctionalState NewState);//用来给ADC上电的。也就是前面步骤当中提到的开关控制。
void ADC_DMACmd(ADC_TypeDef* ADCx, FunctionalState NewState);//用于开启DMA输出信号的。如果使用DMA转运数据,就得调用这个函数。 
void ADC_ITConfig(ADC_TypeDef* ADCx, uint16_t ADC_IT, FunctionalState NewState);//中断输出控制,用于控制某个终端看看能不能通往NVIC

//用于控制校准的函数。在ADC初始化完成之后一次调用就i可以了。
void ADC_ResetCalibration(ADC_TypeDef* ADCx);//复位校准
FlagStatus ADC_GetResetCalibrationStatus(ADC_TypeDef* ADCx);//获取复位校准的状态。
void ADC_StartCalibration(ADC_TypeDef* ADCx);//开始校准
FlagStatus ADC_GetCalibrationStatus(ADC_TypeDef* ADCx);//获取开始校准的状态。
void ADC_SoftwareStartConvCmd(ADC_TypeDef* ADCx, FunctionalState NewState);//软件开始转换控制,这个就是用于软件触发的函数了。也就是触发控制。
FlagStatus ADC_GetSoftwareStartConvStatus(ADC_TypeDef* ADCx);//ADC获取软件开始转换状态。这个函数与转换是否结束毫无关系(我们一般不用)。
FlagStatus ADC_GetFlagStatus(ADC_TypeDef* ADCx, uint8_t ADC_FLAG);//将后一个参数给EOC标志位是不是置1了如果转换结束那么EOC标志位置1,这样就可以正确的判断转换是否结束的方法。

//用来配置间断模式的
void ADC_DiscModeChannelCountConfig(ADC_TypeDef* ADCx, uint8_t Number);//每隔几个通道间断一次。
void ADC_DiscModeCmd(ADC_TypeDef* ADCx, FunctionalState NewState);//是不是开启中断模式。
void ADC_RegularChannelConfig(ADC_TypeDef* ADCx, uint8_t ADC_Channel, uint8_t Rank, uint8_t ADC_SampleTime);//ADC规则组通道配置,给序列的每个位置填写指定的通道。第一个参数是ADCX,第二个参数是你想要指定的通道,第三个Rank就是序列几的位置,第四个参数就是用来指定通道的采样时间。
void ADC_ExternalTrigConvCmd(ADC_TypeDef* ADCx, FunctionalState NewState);//ADC外部触发转换控制,是否允许外部中断触发转换。
uint16_t ADC_GetConversionValue(ADC_TypeDef* ADCx);//ADC获取转换值
uint32_t ADC_GetDualModeConversionValue(void);//获取ADC双模式转换值。双ADC读取转换结果的模式,我们暂时不用。

//用来对ADC注入组进行配置的函数
void ADC_AutoInjectedConvCmd(ADC_TypeDef* ADCx, FunctionalState NewState);
void ADC_InjectedDiscModeCmd(ADC_TypeDef* ADCx, FunctionalState NewState);
void ADC_ExternalTrigInjectedConvConfig(ADC_TypeDef* ADCx, uint32_t ADC_ExternalTrigInjecConv);
void ADC_ExternalTrigInjectedConvCmd(ADC_TypeDef* ADCx, FunctionalState NewState);
void ADC_SoftwareStartInjectedConvCmd(ADC_TypeDef* ADCx, FunctionalState NewState);
FlagStatus ADC_GetSoftwareStartInjectedConvCmdStatus(ADC_TypeDef* ADCx);
void ADC_InjectedChannelConfig(ADC_TypeDef* ADCx, uint8_t ADC_Channel, uint8_t Rank, uint8_t ADC_SampleTime);
void ADC_InjectedSequencerLengthConfig(ADC_TypeDef* ADCx, uint8_t Length);
void ADC_SetInjectedOffset(ADC_TypeDef* ADCx, uint8_t ADC_InjectedChannel, uint16_t Offset);
uint16_t ADC_GetInjectedConversionValue(ADC_TypeDef* ADCx, uint8_t ADC_InjectedChannel);
//对模拟看门狗进行配置的
void ADC_AnalogWatchdogCmd(ADC_TypeDef* ADCx, uint32_t ADC_AnalogWatchdog);//是否启动模拟看门狗
void ADC_AnalogWatchdogThresholdsConfig(ADC_TypeDef* ADCx, uint16_t HighThreshold, uint16_t LowThreshold);//配置高低阈值。
void ADC_AnalogWatchdogSingleChannelConfig(ADC_TypeDef* ADCx, uint8_t ADC_Channel);//配置看门的通道。

void ADC_TempSensorVrefintCmd(FunctionalState NewState);//ADC温度传感器内部参考电压控制。用来开启内部的两个通道。
//
FlagStatus ADC_GetFlagStatus(ADC_TypeDef* ADCx, uint8_t ADC_FLAG);//获取标志位
void ADC_ClearFlag(ADC_TypeDef* ADCx, uint8_t ADC_FLAG);//清除标志位
ITStatus ADC_GetITStatus(ADC_TypeDef* ADCx, uint16_t ADC_IT);//获取中断状态。
void ADC_ClearITPendingBit(ADC_TypeDef* ADCx, uint16_t ADC_IT);//清除中断挂起位。
DMA
void DMA_DeInit(DMA_Channel_TypeDef* DMAy_Channelx);	//恢复缺省设置
void DMA_Init(DMA_Channel_TypeDef* DMAy_Channelx, DMA_InitTypeDef* DMA_InitStruct);	//初始化
void DMA_StructInit(DMA_InitTypeDef* DMA_InitStruct);	//结构体初始化。
void DMA_Cmd(DMA_Channel_TypeDef* DMAy_Channelx, FunctionalState NewState);	//使能
void DMA_ITConfig(DMA_Channel_TypeDef* DMAy_Channelx, uint32_t DMA_IT, FunctionalState NewState);	//中断输出使能
void DMA_SetCurrDataCounter(DMA_Channel_TypeDef* DMAy_Channelx, uint16_t DataNumber); 	//DMA设置当前数据寄存器就是给传输寄存器写数据用的。
uint16_t DMA_GetCurrDataCounter(DMA_Channel_TypeDef* DMAy_Channelx);	//DMA获取当前数据寄存器,返回传输寄存器的值
FlagStatus DMA_GetFlagStatus(uint32_t DMAy_FLAG);	//获取标志位状态
void DMA_ClearFlag(uint32_t DMAy_FLAG);	//清除标志位
ITStatus DMA_GetITStatus(uint32_t DMAy_IT);	//获取中断状态
void DMA_ClearITPendingBit(uint32_t DMAy_IT);	//清除中断挂起位。
串口
    第一步:开启时钟,需要将USART和GPIO的时钟打开
    第二步:GPIO初始化,TX设置成复用输出,RX配置成输入
    第三步:配置USART,直接使用一个结构体。
    第四步:如果只需要进行发送的功能,那么直接开启USART这样初始化就结束了。如果需要接收的功能,那么还需要配置中断。那么就在开启USART之前加上ITConfig和NVIC的代码就可以了。
    库函数:
void USART_DeInit(USART_TypeDef* USARTx);
void USART_Init(USART_TypeDef* USARTx, USART_InitTypeDef* USART_InitStruct);
void USART_StructInit(USART_InitTypeDef* USART_InitStruct);
//用户来配置串口外设的同步时钟输出的,包括时钟是不是要输出,时钟的极性相位等参数。
void USART_ClockInit(USART_TypeDef* USARTx, USART_ClockInitTypeDef* USART_ClockInitStruct);
void USART_ClockStructInit(USART_ClockInitTypeDef* USART_ClockInitStruct);

void USART_Cmd(USART_TypeDef* USARTx, FunctionalState NewState);
void USART_ITConfig(USART_TypeDef* USARTx, uint16_t USART_IT, FunctionalState NewState);

//开启USART到DMA的触发通道
void USART_DMACmd(USART_TypeDef* USARTx, uint16_t USART_DMAReq, FunctionalState NewState);

void USART_SendData(USART_TypeDef* USARTx, uint16_t Data);		//接收数据
uint16_t USART_ReceiveData(USART_TypeDef* USARTx);			   //发送数据

//标志位函数
void USART_IrDACmd(USART_TypeDef* USARTx, FunctionalState NewState);
FlagStatus USART_GetFlagStatus(USART_TypeDef* USARTx, uint16_t USART_FLAG);
void USART_ClearFlag(USART_TypeDef* USARTx, uint16_t USART_FLAG);
ITStatus USART_GetITStatus(USART_TypeDef* USARTx, uint16_t USART_IT);
void USART_ClearITPendingBit(USART_TypeDef* USARTx, uint16_t USART_IT);
I2C外设
硬件代码思路
第一步:配置I2C外设,对I2C2外设进行初始化,来替换软件的MyI2CInit()
第二步:控制外设电路实现指定地址写的时序来替换WriteReg()
第三步:控制外设电路,实现指定地址读的时序,来替换ReadReg()
配置I2C外设的步骤
第一步:开启I2C外设和对应GPIO口的时钟
第二步:将I2C外设对应的GPIO口的初始化为复用开漏模式
第三步:使用结构体,对整个I2C进行配置
第四步:I2C_Cmd 使能I2C
I2C库函数
void I2C_DeInit(I2C_TypeDef* I2Cx);
void I2C_Init(I2C_TypeDef* I2Cx, I2C_InitTypeDef* I2C_InitStruct);
void I2C_StructInit(I2C_InitTypeDef* I2C_InitStruct);
void I2C_Cmd(I2C_TypeDef* I2Cx, FunctionalState NewState);
//生成起始条件
void I2C_GenerateSTART(I2C_TypeDef* I2Cx, FunctionalState NewState);
//生成终止条件
void I2C_GenerateSTOP(I2C_TypeDef* I2Cx, FunctionalState NewState);
//配置应答位
void I2C_AcknowledgeConfig(I2C_TypeDef* I2Cx, FunctionalState NewState);
//写数据到数据寄存器DR,这样我们的硬件就会自己产生I2C时序将我们的一个字节数据发送出去了
void I2C_SendData(I2C_TypeDef* I2Cx, uint8_t Data);
//读取DR的数据作为返回值
uint8_t I2C_ReceiveData(I2C_TypeDef* I2Cx);
//发送七位地址专用的函数。这个发送地址的函数是可以使用上面的发送数据的寄存器来完成的。
void I2C_Send7bitAddress(I2C_TypeDef* I2Cx, uint8_t Address, uint8_t I2C_Direction);

—————————————————————持续更新——————————————————

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值