赞
踩
学习江协科技stm32基于库函数开发记录一下
代码压缩包地址:code
中断初始化
1.开启时钟
2.GPIO初始化
3.AFIO选择引脚
4.EXTI初始化
5.NVIC分组
6.NVIC配置
#ifndef __COUNTSENSOR_H
#define __COUNTSENSOR_H
void CountSeneor_Init(void);//中断初始化
uint16_t CountSensor_Get(void);//次数获取
#endif
#include "stm32f10x.h" // Device header uint16_t CountSensor_Count; /* 中断初始化 1.开启时钟 2.GPIO初始化 3.AFIO选择引脚 4.EXTI初始化 5.NVIC分组 6.NVIC配置 */ void CountSeneor_Init(void) { //开启时钟 RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE);//开启gpiob时钟 RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO,ENABLE);//开启afio时钟,外部中断必须开启afio时钟 //GPIO初始化 GPIO_InitTypeDef GPIO_InitStruct; GPIO_InitStruct.GPIO_Mode = GPIO_Mode_IPU; GPIO_InitStruct.GPIO_Pin = GPIO_Pin_14; GPIO_InitStruct.GPIO_Speed = GPIO_Speed_50MHz; GPIO_Init(GPIOB,&GPIO_InitStruct);//将PB14脚初始化为上拉输入 GPIO_EXTILineConfig(GPIO_PortSourceGPIOB, GPIO_PinSource14);//选择用作EXTI线的GPIO引脚 //中断线选择,将外部中断的14号线映射到GPIOB,即选择PB14为外部中断引脚 EXTI_InitTypeDef EXTI_InitStruct; EXTI_InitStruct.EXTI_Line = EXTI_Line14;//配置外部中断线 EXTI_InitStruct.EXTI_LineCmd = ENABLE;//外部中断线使能 EXTI_InitStruct.EXTI_Mode = EXTI_Mode_Interrupt;//指定外部中断线为中断模式 EXTI_InitStruct.EXTI_Trigger = EXTI_Trigger_Rising;//外部中断线上升沿触发 EXTI_Init(&EXTI_InitStruct); NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);//配置nvic分组,目前为分组2,抢占优先级与响应优先级均为0~3 //nvic配置 NVIC_InitTypeDef NVIC_InitStruct;//结构体定义 NVIC_InitStruct.NVIC_IRQChannel = EXTI15_10_IRQn;//选择配置nvic的EXTI15_10 NVIC_InitStruct.NVIC_IRQChannelCmd = ENABLE;//使能 NVIC_InitStruct.NVIC_IRQChannelPreemptionPriority = 1;//抢占优先级 NVIC_InitStruct.NVIC_IRQChannelSubPriority = 1;//响应优先级 NVIC_Init(&NVIC_InitStruct); } void EXTI15_10_IRQHandler(void)//服务中断函数 { if(EXTI_GetITStatus(EXTI_Line14)== SET) { if(GPIO_ReadInputDataBit(GPIOB, GPIO_Pin_14) == 0) { CountSensor_Count ++; } EXTI_ClearITPendingBit(EXTI_Line14);//结束清除标志位 } } uint16_t CountSensor_Get(void) { return CountSensor_Count; }
#include "stm32f10x.h" // Device header
#include "Delay.h"
#include "oled.h"
#include "countsensor.h"
int main()
{
OLED_Init();//oled初始化
CountSeneor_Init();
OLED_ShowString(1,1,"count:");//第一行第一列展示字符串count:
while(1)
{
OLED_ShowNum(1,7,CountSensor_Get(),5);
}
}
#ifndef __ENCODER_H
#define __ENCODER_H
void Encoder_Init(void);
int16_t Encoder_Get(void);
#endif
#include "stm32f10x.h" // Device header uint16_t Encoder_Count; /* 中断初始化 1.开启时钟 2.GPIO初始化 3.AFIO选择引脚 4.EXTI初始化 5.NVIC分组 6.NVIC配置 */ void Encoder_Init(void) { //开启时钟 RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE);//开启gpiob时钟 RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO,ENABLE);//开启afio时钟,外部中断必须开启afio时钟 //GPIO初始化 GPIO_InitTypeDef GPIO_InitStruct; GPIO_InitStruct.GPIO_Mode = GPIO_Mode_IPU; GPIO_InitStruct.GPIO_Pin = GPIO_Pin_0 | GPIO_Pin_0; GPIO_InitStruct.GPIO_Speed = GPIO_Speed_50MHz; GPIO_Init(GPIOB,&GPIO_InitStruct);//将PB14脚初始化为上拉输入 GPIO_EXTILineConfig(GPIO_PortSourceGPIOB, GPIO_PinSource0);//选择用作EXTI线的GPIO引脚 GPIO_EXTILineConfig(GPIO_PortSourceGPIOB, GPIO_PinSource1); EXTI_InitTypeDef EXTI_InitStruct; EXTI_InitStruct.EXTI_Line = EXTI_Line0 | EXTI_Line1;//配置外部中断线 EXTI_InitStruct.EXTI_LineCmd = ENABLE;//外部中断线使能 EXTI_InitStruct.EXTI_Mode = EXTI_Mode_Interrupt;//指定外部中断线为中断模式 EXTI_InitStruct.EXTI_Trigger = EXTI_Trigger_Falling;//外部中断线下降沿触发 EXTI_Init(&EXTI_InitStruct); NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);//配置nvic分组,目前为分组2,抢占优先级与响应优先级均为0~3 //nvic配置 NVIC_InitTypeDef NVIC_InitStruct;//结构体定义 NVIC_InitStruct.NVIC_IRQChannel = EXTI0_IRQn;//选择配置nvic的EXTI0 NVIC_InitStruct.NVIC_IRQChannelCmd = ENABLE;//使能 NVIC_InitStruct.NVIC_IRQChannelPreemptionPriority = 1;//抢占优先级 NVIC_InitStruct.NVIC_IRQChannelSubPriority = 1;//响应优先级 NVIC_Init(&NVIC_InitStruct); NVIC_InitStruct.NVIC_IRQChannel = EXTI1_IRQn;//选择配置nvic的EXTI0 NVIC_InitStruct.NVIC_IRQChannelCmd = ENABLE;//使能 NVIC_InitStruct.NVIC_IRQChannelPreemptionPriority = 1;//抢占优先级 NVIC_InitStruct.NVIC_IRQChannelSubPriority = 2;//响应优先级 NVIC_Init(&NVIC_InitStruct); } void EXTI0_IRQHandler(void)//服务中断函数 { if(EXTI_GetITStatus(EXTI_Line0)== SET) { if(GPIO_ReadInputDataBit(GPIOB, GPIO_Pin_0) == 0) { if(GPIO_ReadInputDataBit(GPIOB, GPIO_Pin_1) == 0) { Encoder_Count ++; } } EXTI_ClearITPendingBit(EXTI_Line0);//结束清除标志位 } } void EXTI1_IRQHandler(void)//服务中断函数 { if(EXTI_GetITStatus(EXTI_Line1)== SET) { if(GPIO_ReadInputDataBit(GPIOB, GPIO_Pin_1) == 0) { if(GPIO_ReadInputDataBit(GPIOB, GPIO_Pin_1) == 0) { Encoder_Count --; } } EXTI_ClearITPendingBit(EXTI_Line1);//结束清除标志位 } } int16_t Encoder_Get(void) { int16_t Temp; Temp = Encoder_Count; Encoder_Count = 0; return Temp; }//返回后数据清零
1.开启时钟
2.配置时钟源
3.时基单元初始化
4.中断输出配置
5.nvic中断分组
6.nvic配置
7.tim使能
#ifndef __TIMER_H
#define __TIMER_H
void Timer_Init(void);
#endif
#include "stm32f10x.h" // Device header /* 1.开启时钟 2.配置时钟源 3.时基单元初始化 4.中断输出配置 5.nvic中断分组 6.nvic配置 7.tim使能 */ /* 51 32 usart/iic/spi/freertos ~ 通信+系统 树莓派 ~linux编程 */ void Timer_Init(void) { //开启时钟 RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2, ENABLE); //选择时钟源~~选择tim2为内部时钟 TIM_InternalClockConfig(TIM2); //配置时基单元 TIM_TimeBaseInitTypeDef TIM_TimeBaseInitStruct; TIM_TimeBaseInitStruct.TIM_ClockDivision = TIM_CKD_DIV1;//时钟分频 TIM_TimeBaseInitStruct.TIM_CounterMode = TIM_CounterMode_Up;//计数模式~向上计数 TIM_TimeBaseInitStruct.TIM_Period = 10000 - 1;//计数周期 TIM_TimeBaseInitStruct.TIM_Prescaler = 7200 - 1;//预分频器72M = 7200 0000 /10000 /7200 = 1 TIM_TimeBaseInitStruct.TIM_RepetitionCounter = 0; TIM_TimeBaseInit(TIM2, &TIM_TimeBaseInitStruct); //中断输出配置 TIM_ITConfig(TIM2,TIM_IT_Update,ENABLE);//开启nvic中断 //nvic中断分组 NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);//ncic中断分组2 //nvic初始化 NVIC_InitTypeDef NVIC_InitStruct; NVIC_InitStruct.NVIC_IRQChannel = TIM2_IRQn; NVIC_InitStruct.NVIC_IRQChannelCmd = ENABLE; NVIC_InitStruct.NVIC_IRQChannelPreemptionPriority = 2; NVIC_InitStruct.NVIC_IRQChannelSubPriority = 1; NVIC_Init(&NVIC_InitStruct); //定时器使能 TIM_Cmd(TIM2, ENABLE); } //void TIM2_IRQHandler(void) //{ // if(TIM_GetITStatus(TIM2,TIM_IT_Update) == SET) // { // TIM_ClearITPendingBit(TIM2,TIM_IT_Update);//清除标志位 // } //}
#include "stm32f10x.h" // Device header #include "Delay.h" #include "oled.h" #include "Timer.h"//.h文件多打了一个空格 int16_t Num; int main() { OLED_Init();//oled初始化 Timer_Init(); OLED_ShowString(1,1,"Num:"); while(1) { OLED_ShowNum(1,5,Num,5); } } void TIM2_IRQHandler(void) { if(TIM_GetITStatus(TIM2,TIM_IT_Update) == SET) { Num ++ ; TIM_ClearITPendingBit(TIM2,TIM_IT_Update);//清除标志位 } }
1.开启时钟
2.配置时钟源
3.时基单元初始化
4.中断输出配置
5.nvic中断分组
6.nvic配置
7.tim使能
#ifndef __TIMER_H
#define __TIMER_H
void Timer_Init(void);
uint16_t Timer_GetCount(void);
#endif
#include "stm32f10x.h" // Device header void Timer_Init(void) { //开启时钟 RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2, ENABLE); // RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);//开启gpioa时钟 // // GPIO_InitTypeDef GPIO_InitStruct; GPIO_InitStruct.GPIO_Mode = GPIO_Mode_IPU; GPIO_InitStruct.GPIO_Pin = GPIO_Pin_0; GPIO_InitStruct.GPIO_Speed = GPIO_Speed_50MHz; GPIO_Init(GPIOA, &GPIO_InitStruct);//gpioa初始化~上拉输入 // // TIM_ETRClockMode2Config(TIM2,TIM_ExtTRGPSC_OFF,TIM_ExtTRGPolarity_NonInverted,0x0f); //配置外部时钟模式2,外设tim2,外部触发关闭,外部触发极性上升沿,滤波最大~0x0f // // //选择时钟源~~选择tim2为内部时钟 // TIM_InternalClockConfig(TIM2); //配置时基单元 TIM_TimeBaseInitTypeDef TIM_TimeBaseInitStruct; TIM_TimeBaseInitStruct.TIM_ClockDivision = TIM_CKD_DIV1;//时钟分频 TIM_TimeBaseInitStruct.TIM_CounterMode = TIM_CounterMode_Up;//计数模式~向上计数 TIM_TimeBaseInitStruct.TIM_Period = 10 - 1;//计数周期 arr TIM_TimeBaseInitStruct.TIM_Prescaler = 1 - 1;//预分频器psc TIM_TimeBaseInitStruct.TIM_RepetitionCounter = 0;//重复计数器 TIM_TimeBaseInit(TIM2, &TIM_TimeBaseInitStruct); TIM_ClearFlag(TIM2, TIM_FLAG_Update);//清除中断触发标志位 //中断输出配置 TIM_ITConfig(TIM2,TIM_IT_Update,ENABLE);//开启nvic中断 //启用或禁用指定中断,tim2,tim更新中断源,使能 //nvic中断分组 NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);//ncic中断分组2 //nvic初始化 NVIC_InitTypeDef NVIC_InitStruct; NVIC_InitStruct.NVIC_IRQChannel = TIM2_IRQn; NVIC_InitStruct.NVIC_IRQChannelCmd = ENABLE; NVIC_InitStruct.NVIC_IRQChannelPreemptionPriority = 2; NVIC_InitStruct.NVIC_IRQChannelSubPriority = 1; NVIC_Init(&NVIC_InitStruct); //定时器使能 TIM_Cmd(TIM2, ENABLE); } uint16_t Timer_GetCount(void) { return TIM_GetCounter(TIM2);//返回tim2的cnt值 } //void TIM2_IRQHandler(void) //{ // if(TIM_GetITStatus(TIM2,TIM_IT_Update) == SET) // { // TIM_ClearITPendingBit(TIM2,TIM_IT_Update);//清除标志位 // } //}
#include "stm32f10x.h" // Device header #include "Delay.h" #include "oled.h" #include "Timer.h"//.h文件多打了一个空格 int16_t Num; int main() { OLED_Init();//oled初始化 Timer_Init(); OLED_ShowString(1,1,"Num:"); OLED_ShowString(2,1,"CNT:"); while(1) { OLED_ShowNum(1,5,Num,5); OLED_ShowNum(2,5,Timer_GetCount(),5); } } void TIM2_IRQHandler(void) { if(TIM_GetITStatus(TIM2,TIM_IT_Update) == SET) { Num ++ ; TIM_ClearITPendingBit(TIM2,TIM_IT_Update);//清除标志位 } }
1.rcc开启时钟(tim/gpio)
2.配置时基单元
3.配置输出比较单元(ccr/输出比较模式/极性选择/输出使能)
4.配置GPIO口为复用推挽
5.启动计数器
#ifndef __PWM_H
#define __PWM_H
void PWM_Init(void);//pwm初始化
void PWM_SetComparel(uint16_t Compare);//设置ccr1的值用于调节占空比
#endif
#include "stm32f10x.h" // Device header /* 1.rcc开启时钟(tim/gpio) 2.配置时基单元 3.配置输出比较单元(ccr/输出比较模式/极性选择/输出使能) 4.配置GPIO口为复用推挽 5.启动计数器 */ void PWM_Init(void) { RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2, ENABLE); //tim2时钟开启 RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE); //gpioa初始化 GPIO_InitTypeDef GPIO_InitStruct; GPIO_InitStruct.GPIO_Mode = GPIO_Mode_AF_PP;//复用推挽输出 GPIO_InitStruct.GPIO_Pin = GPIO_Pin_0; GPIO_InitStruct.GPIO_Speed = GPIO_Speed_50MHz; GPIO_Init(GPIOA,&GPIO_InitStruct); //gpio_a0脚初始化 TIM_InternalClockConfig(TIM2); //内部时钟源选择 TIM_TimeBaseInitTypeDef TIM_TimeBaseInitStruct; TIM_TimeBaseInitStruct.TIM_ClockDivision = TIM_CKD_DIV1; TIM_TimeBaseInitStruct.TIM_CounterMode = TIM_CounterMode_Up; TIM_TimeBaseInitStruct.TIM_Period = 100 - 1;//计数周期 TIM_TimeBaseInitStruct.TIM_Prescaler = 720 - 1;//预分频器 TIM_TimeBaseInitStruct.TIM_RepetitionCounter = 0;//重复计数器 TIM_TimeBaseInit(TIM2,&TIM_TimeBaseInitStruct); //时基单元初始化 TIM_OCInitTypeDef TIM_OCInitStruct; TIM_OCStructInit(&TIM_OCInitStruct);//结构体初始化,结构体未完全赋值先进行初始化赋值 TIM_OCInitStruct.TIM_OCMode = TIM_OCMode_PWM1;//输出比较模式 TIM_OCInitStruct.TIM_OCPolarity = TIM_OCPolarity_High;//输出比较极性~high原样输出/low反向输出 TIM_OCInitStruct.TIM_OutputState = ENABLE;//使能 TIM_OCInitStruct.TIM_Pulse = 0;//CCR初始值 TIM_OC1Init(TIM2,&TIM_OCInitStruct); //输出比较初始化 TIM_Cmd(TIM2, ENABLE);//使能,定时器开始运行 } void PWM_SetComparel(uint16_t Compare) { TIM_SetCompare1(TIM2, Compare);//设置ccr1的值 }
#include "stm32f10x.h" // Device header #include "Delay.h" #include "oled.h" #include "pwm.h" uint8_t i; int main() { OLED_Init();//oled初始化 PWM_Init();//pwm初始化 while(1) { for(i = 0;i<=100;i++) { PWM_SetComparel(i); Delay_ms(10); } for(i = 0;i<=100;i++) { PWM_SetComparel(100 - i); Delay_ms(10); } } }
#ifndef __SERVO_H
#define __SERVO_H
void Servo_Init(void);
void Servo_SetAngle(float Angle);
#endif
#include "stm32f10x.h" // Device header
#include "stm32f10x.h" // Device header
#include "pwm.h"
void Servo_Init(void)
{
PWM_Init();//初始化舵机底层pwm
}
void Servo_SetAngle(float Angle)
{
PWM_SetCompare2(Angle / 180 * 2000 + 500);//设置占空比
}
#include "stm32f10x.h" // Device header #include "Delay.h" #include "oled.h" #include "Servo.h" #include "Key.h" uint8_t KeyNum; float Angle; int main() { OLED_Init();//oled初始化 Servo_Init();//舵机初始化 Key_Init();//按键初始化 OLED_ShowString(1,1,"Angle:");//显示静态字符"Angle:" while(1) { KeyNum = Key_GetNum();//得到键码返回值 if(KeyNum == 1) { Angle += 30;//角度增加30 if(Angle > 180) { Angle = 0; } } Servo_SetAngle(Angle); OLED_ShowNum(1,7,Angle,3); } }
#ifndef __MOTOR_H
#define __MOTOR_H
void Motor_Init(void);//舵机初始化
void Motor_SetSpeed(int8_t Speed);//速度设置
#endif
#include "stm32f10x.h" // Device header #include "pwm.h" void Motor_Init(void) { RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE); GPIO_InitTypeDef GPIO_InitStruct; GPIO_InitStruct.GPIO_Mode = GPIO_Mode_Out_PP; GPIO_InitStruct.GPIO_Pin = GPIO_Pin_4 | GPIO_Pin_5; GPIO_InitStruct.GPIO_Speed = GPIO_Speed_50MHz; GPIO_Init(GPIOA ,&GPIO_InitStruct);//PA4与PA5脚进行初始化,用作控制脚 PWM_Init();//PA2脚用作输出pwm } void Motor_SetSpeed(int8_t Speed) { if(Speed >= 0) { GPIO_SetBits(GPIOA, GPIO_Pin_4); GPIO_ResetBits(GPIOA, GPIO_Pin_5); PWM_SetCompare3(Speed); } else { GPIO_ResetBits(GPIOA,GPIO_Pin_4); GPIO_SetBits(GPIOA,GPIO_Pin_5); PWM_SetCompare3(-Speed);//反向旋转 } }
#include "stm32f10x.h" // Device header #include "Delay.h" #include "oled.h" #include "Motor.h" #include "Key.h" uint8_t KeyNum; int8_t Speed; int main() { OLED_Init();//oled初始化 Motor_Init();//舵机初始化 Key_Init();//按键初始化 OLED_ShowString(1,1,"speed:"); while(1) { KeyNum = Key_GetNum(); if(KeyNum == 1) { Speed += 20; if(Speed > 100) { Speed = -100; } } Motor_SetSpeed(Speed);//占空比传递 OLED_ShowSignedNum(1,7,Speed,3); } }
1.rcc开启时钟(gpio/tim)
2.gpio初始化(gpio~输入模式)~上拉 or 浮空
3.配置时基单元,让cnt计数器在内部时钟的驱动下自增
4.配置输入捕获单元(滤波器、极性、直连通道 or 交叉通道、分频器)
5.选择从模式的触发源ti1fp1
6.选择触发后进行的操作reset
7.tim开启定时器
#ifndef __IC_H
#define __IC_H
void Ic_Init(void);//输入捕获初始化
uint32_t Ic_GetFreq(void);//获取频率
#endif
#include "stm32f10x.h" // Device header /* 1.rcc开启时钟(gpio/tim) 2.gpio初始化(gpio~输入模式)~上拉 or 浮空 3.配置时基单元,让cnt计数器在内部时钟的驱动下自增 4.配置输入捕获单元(滤波器、极性、直连通道 or 交叉通道、分频器) 5.选择从模式的触发源ti1fp1 6.选择触发后进行的操作reset 7.tim开启定时器 */ void Ic_Init(void) { //rcc开启时钟 RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM3, ENABLE); //tim2时钟开启 RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE); //gpioa初始化 //gpio初始化 GPIO_InitTypeDef GPIO_InitStruct; GPIO_InitStruct.GPIO_Mode = GPIO_Mode_IPU;//复用推挽输出 GPIO_InitStruct.GPIO_Pin = GPIO_Pin_6; GPIO_InitStruct.GPIO_Speed = GPIO_Speed_50MHz; GPIO_Init(GPIOA,&GPIO_InitStruct); //gpio_a0脚初始化 //时钟源选择 TIM_InternalClockConfig(TIM3); //内部时钟源选择 //时基单元初始化 TIM_TimeBaseInitTypeDef TIM_TimeBaseInitStruct; TIM_TimeBaseInitStruct.TIM_ClockDivision = TIM_CKD_DIV1; TIM_TimeBaseInitStruct.TIM_CounterMode = TIM_CounterMode_Up; TIM_TimeBaseInitStruct.TIM_Period = 65536 - 1;//计数周期 TIM_TimeBaseInitStruct.TIM_Prescaler = 72 - 1;//预分频器 TIM_TimeBaseInitStruct.TIM_RepetitionCounter = 0;//重复计数器 TIM_TimeBaseInit(TIM3,&TIM_TimeBaseInitStruct); //输入捕获初始化 TIM_ICInitTypeDef TIM_ICInitStruct; TIM_ICInitStruct.TIM_Channel = TIM_Channel_1;//模式3通道1 TIM_ICInitStruct.TIM_ICFilter = 0xF;//滤波 TIM_ICInitStruct.TIM_ICPolarity = TIM_ICPolarity_Rising;//极性,不反转 TIM_ICInitStruct.TIM_ICPrescaler = TIM_ICPSC_DIV1;//预分频,不分频 TIM_ICInitStruct.TIM_ICSelection = TIM_ICSelection_DirectTI;//直接选择 TIM_ICInit(TIM3,&TIM_ICInitStruct); //<===================== //选择触发源及从模式 TIM_SelectInputTrigger(TIM3,TIM_TS_TI1FP1);//触发源选择~TI1FP1 //<===================== TIM_SelectSlaveMode(TIM3,TIM_SlaveMode_Reset);//选择从模式 //<===================== TIM_Cmd(TIM3,ENABLE);//使能tim3,定时器开始运行 } uint32_t Ic_GetFreq(void) { return 1000000 / (TIM_GetCapture1(TIM3) + 1); }
#include "stm32f10x.h" // Device header #include "Delay.h" #include "oled.h" #include "pwm.h" #include "ic.h" int main() { OLED_Init();//oled初始化 PWM_Init();//pwm初始化 Ic_Init();//输入捕获初始化 OLED_ShowString(1,1,"Freq:00000Hz"); PWM_SetPrescaler(720 - 1);//设置频率 freq = 72M / (psc + 1)/100 PWM_SetCompare3(50);//设置占空比 duty = ccr / 100 while(1) { OLED_ShowNum(1,6,Ic_GetFreq(),5);//频率展示 } }
#ifndef __IC_H
#define __IC_H
void Ic_Init(void);//输入捕获初始化
uint32_t Ic_GetFreq(void);//获取频率
uint32_t Ic_GetDuty(void);//获取占空比
#endif
#include "stm32f10x.h" // Device header /* 1.rcc开启时钟(gpio/tim) 2.gpio初始化(gpio~输入模式)~上拉 or 浮空 3.配置时基单元,让cnt计数器在内部时钟的驱动下自增 4.配置输入捕获单元(滤波器、极性、直连通道 or 交叉通道、分频器) 5.选择从模式的触发源ti1fp1 6.选择触发后进行的操作reset 7.tim开启定时器 */ void Ic_Init(void) { //rcc开启时钟 RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM3, ENABLE); //tim2时钟开启 RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE); //gpioa初始化 //gpio初始化 GPIO_InitTypeDef GPIO_InitStruct; GPIO_InitStruct.GPIO_Mode = GPIO_Mode_IPU;//复用推挽输出 GPIO_InitStruct.GPIO_Pin = GPIO_Pin_6; GPIO_InitStruct.GPIO_Speed = GPIO_Speed_50MHz; GPIO_Init(GPIOA,&GPIO_InitStruct); //gpio_a0脚初始化 //时钟源选择 TIM_InternalClockConfig(TIM3); //内部时钟源选择 //时基单元初始化 TIM_TimeBaseInitTypeDef TIM_TimeBaseInitStruct; TIM_TimeBaseInitStruct.TIM_ClockDivision = TIM_CKD_DIV1; TIM_TimeBaseInitStruct.TIM_CounterMode = TIM_CounterMode_Up; TIM_TimeBaseInitStruct.TIM_Period = 65536 - 1;//计数周期 TIM_TimeBaseInitStruct.TIM_Prescaler = 72 - 1;//预分频器 TIM_TimeBaseInitStruct.TIM_RepetitionCounter = 0;//重复计数器 TIM_TimeBaseInit(TIM3,&TIM_TimeBaseInitStruct); //输入捕获初始化(pwmi) TIM_ICInitTypeDef TIM_ICInitStruct; TIM_ICInitStruct.TIM_Channel = TIM_Channel_1;//模式3通道1 TIM_ICInitStruct.TIM_ICFilter = 0xF;//滤波 TIM_ICInitStruct.TIM_ICPolarity = TIM_ICPolarity_Rising;//极性,不反转 TIM_ICInitStruct.TIM_ICPrescaler = TIM_ICPSC_DIV1;//预分频,不分频 TIM_ICInitStruct.TIM_ICSelection = TIM_ICSelection_DirectTI;//直接选择 //TIM_ICInit(TIM3,&TIM_ICInitStruct); TIM_PWMIConfig(TIM3,&TIM_ICInitStruct);//将结构体变量交给TIM_PWMIConfig,配置tim3的输入捕获通道 //同时此函数会把另一个通道配置为相反模式//<===================== //选择触发源及从模式 TIM_SelectInputTrigger(TIM3,TIM_TS_TI1FP1);//触发源选择~TI1FP1 TIM_SelectSlaveMode(TIM3,TIM_SlaveMode_Reset);//选择从模式 TIM_Cmd(TIM3,ENABLE);//使能tim3,定时器开始运行 } uint32_t Ic_GetFreq(void) { return 1000000 / (TIM_GetCapture1(TIM3) + 1); } uint32_t Ic_GetDuty(void) { return (TIM_GetCapture2(TIM3) + 1) * 100 / (TIM_GetCapture1(TIM3) + 1);//计算占空比 }
#include "stm32f10x.h" // Device header #include "Delay.h" #include "oled.h" #include "pwm.h" #include "ic.h" int main() { OLED_Init();//oled初始化 PWM_Init();//pwm初始化 Ic_Init();//输入捕获初始化 OLED_ShowString(1,1,"Freq:00000Hz"); OLED_ShowString(2,1,"Duty:00%"); PWM_SetPrescaler(720 - 1);//设置频率 freq = 72M / (psc + 1)/100 PWM_SetCompare3(50);//设置占空比 duty = ccr / 100 while(1) { OLED_ShowNum(1,6,Ic_GetFreq(),5);//频率展示 OLED_ShowNum(2,6,Ic_GetDuty(),2);//占空比显示 } }
#ifndef __ENCODERTWO_H
#define __ENCODERTWO_H
void EncoderTwo_Init(void);//编码器测速初始化
int16_t Encoder_Get(void);//获取编码器测速值
#endif
#include "stm32f10x.h" // Device header void EncoderTwo_Init(void) { /*开启时钟*/ RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM3, ENABLE); //开启TIM3的时钟 RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE); //开启GPIOA的时钟 /*GPIO初始化*/ GPIO_InitTypeDef GPIO_InitStructure; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU; GPIO_InitStructure.GPIO_Pin = GPIO_Pin_6 | GPIO_Pin_7; GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; GPIO_Init(GPIOA, &GPIO_InitStructure); //将PA6和PA7引脚初始化为上拉输入 /*时基单元初始化*/ TIM_TimeBaseInitTypeDef TIM_TimeBaseInitStructure; //定义结构体变量 TIM_TimeBaseInitStructure.TIM_ClockDivision = TIM_CKD_DIV1; //时钟分频,选择不分频,此参数用于配置滤波器时钟,不影响时基单元功能 TIM_TimeBaseInitStructure.TIM_CounterMode = TIM_CounterMode_Up; //计数器模式,选择向上计数 TIM_TimeBaseInitStructure.TIM_Period = 65536 - 1; //计数周期,即ARR的值 TIM_TimeBaseInitStructure.TIM_Prescaler = 1 - 1; //预分频器,即PSC的值 TIM_TimeBaseInitStructure.TIM_RepetitionCounter = 0; //重复计数器,高级定时器才会用到 TIM_TimeBaseInit(TIM3, &TIM_TimeBaseInitStructure); //将结构体变量交给TIM_TimeBaseInit,配置TIM3的时基单元 //输入捕获初始化 TIM_ICInitTypeDef TIM_ICInitStruct; TIM_ICStructInit(&TIM_ICInitStruct);//不完全赋值先进行初始化//<====================== TIM_ICInitStruct.TIM_Channel = TIM_Channel_1;//选择定时器通道 TIM_ICInitStruct.TIM_ICFilter = 0xf;//滤波器 TIM_ICInit(TIM3,&TIM_ICInitStruct); TIM_ICInitStruct.TIM_Channel = TIM_Channel_2;//选择定时器通道 TIM_ICInitStruct.TIM_ICFilter = 0xf;//滤波器 TIM_ICInit(TIM3,&TIM_ICInitStruct); TIM_EncoderInterfaceConfig(TIM3,TIM_EncoderMode_TI12,TIM_ICPolarity_Rising,TIM_ICPolarity_Rising); //配置编码器模式以及两个输入通道是否反相 TIM_Cmd(TIM3, ENABLE); } int16_t Encoder_Get(void) { int16_t Temp; Temp = TIM_GetCounter(TIM3);//获取计数器计数值 TIM_SetCounter(TIM3 , 0);//设置计数器值 return Temp; }
#include "stm32f10x.h" // Device header #include "Delay.h" #include "oled.h" #include "timer.h" #include "encodertwo.h" int16_t Speed; int main() { OLED_Init();//oled初始化 Timer_Init();//定时器初始化 EncoderTwo_Init();//编码器接口初始化 OLED_ShowString(1,1,"Speed:"); while(1) { OLED_ShowSignedNum(1,7,Speed,5); } } void TIM2_IRQHandler(void) { if(TIM_GetITStatus(TIM2,TIM_IT_Update) == SET) { Speed = Encoder_Get();//将寄存器中数值保存到中间变量Speed中 TIM_ClearITPendingBit(TIM2,TIM_IT_Update);//清除标志位 } }
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。