打印
[STM32F1]

stm32(F103c8t6)自学笔记

[复制链接]
楼主: t60yz
手机看帖
扫描二维码
随时随地手机跟帖
101
t60yz|  楼主 | 2023-11-22 11:39 | 只看该作者 |只看大图 回帖奖励 |倒序浏览
1.5 高级定时器框图

使用特权

评论回复
102
t60yz|  楼主 | 2023-11-22 11:39 | 只看该作者
1.6 定时中断基本结构

使用特权

评论回复
103
t60yz|  楼主 | 2023-11-22 11:39 | 只看该作者
1.7 时序图(详细解释)
计数流程:选择时钟源-->确定滤波的几分频-->确定预分频PSC-->确定重装载值ARR-->溢出触发中断

分频过程:外部输入规律的高低电平脉冲信号,经过选择分频模式后,信号转化输入预分频器开始计数,每到达预分频器设置的阈值溢出时就产生一个脉冲给计数器,计数器+1,最后当计数器计数值等于自动装载器设置的阈值时产生溢出,触发中断,因此在一分频模式下:

定时频率(时间)=(预分频值/初始时钟频率)*预装载值

如定时1s,则1 s=(7200)/72Mhz * 10000                     (取值范围 0~65535)

这就像是两个定时器级联一样,增大了计数范围

最新理解:

已知公式 t=1/f

那么内部时钟经过预分频后每记一次的时间就为:t1=1/(72Mhz/PSC+1)

那么分频器每隔t1时间就产生信号给计数器,直到计数器经过t2=t1*(ARR+1)的时间或者说累加到等于ARR时,产生中断同时计数器清零。

所以整个过程花费时间(每次中断的间隔时间)为:t2=1/(72Mhz/PSC+1)*(ARR+1)

比如要计时 1s :1 s = 1 / ( 72Mhz / 7200)* 10000

使用特权

评论回复
104
t60yz|  楼主 | 2023-11-22 11:39 | 只看该作者

使用特权

评论回复
105
t60yz|  楼主 | 2023-11-22 11:40 | 只看该作者

使用特权

评论回复
106
t60yz|  楼主 | 2023-11-22 11:40 | 只看该作者

使用特权

评论回复
107
t60yz|  楼主 | 2023-11-22 11:40 | 只看该作者

使用特权

评论回复
108
t60yz|  楼主 | 2023-11-22 11:40 | 只看该作者

使用特权

评论回复
109
t60yz|  楼主 | 2023-11-22 11:40 | 只看该作者
2.定时器中断计数(代码)
[code]#include "stm32f10x.h"                  // Device header
#include "OLED.h"
#include "timer2.h"

/***************************************************/定时器2
#include "stm32f10x.h"
#include "timer2.h"

extern int num;
void timer2_init(void)
{
        //**1.打开总的RCC
        RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2,ENABLE);//因为定时器2是通用定时器,在APB1总线上
        //**2.选定定时器接入的时钟
        TIM_InternalClockConfig(TIM2);//设置定时器2使用内部时钟,可不写,上电默认
        //**3.配置时基单元
        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;//设置预分频值
        TIM_TimeBaseInitStruct.TIM_RepetitionCounter=0;//高级计数器功能,重复计数器
        TIM_TimeBaseInit(TIM2, &TIM_TimeBaseInitStruct);//初始化时基单元
        TIM_ClearFlag(TIM2,TIM_FLAG_Update);//初始化时会产生标志位,需要清除
        //**4.使能时基单元的中断
        TIM_ITConfig(TIM2,TIM_IT_Update,ENABLE);
        //**5.配置NVIC
        NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);//分组
       
        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);
        //**6.开始计数
        TIM_Cmd(TIM2,ENABLE);

}

//**配置中断函数
void TIM2_IRQHandler(void)
{
        if(TIM_GetITStatus(TIM2,TIM_IT_Update)==SET)
        {
                num++;
        }
        TIM_ClearITPendingBit(TIM2, TIM_IT_Update);//一定要清除标志位
}

/***************************************************/主函数

int num;
int main(void)
{
        OLED_Init();
        timer2_init();
        OLED_ShowString(1,1,"Hello,my honey");
//        OLED_ShowString(2,1,"Hello WangFang");
//        OLED_ShowString(3,1,"Hello Tomorrow");
//        OLED_ShowString(4,1,"I miss you");
        while(1)
        {
                OLED_ShowString(2,1,"NUM:");
                OLED_ShowNum(2,5,num,5);
               
                OLED_ShowString(3,1,"Prescaler:");
                OLED_ShowNum(3,11,TIM_GetPrescaler(TIM2),5);
               
                OLED_ShowString(4,1,"Counter:");
                OLED_ShowNum(4,9,TIM_GetCounter(TIM2),5);
        }
}

使用特权

评论回复
110
t60yz|  楼主 | 2023-11-22 11:40 | 只看该作者
3.外部时钟的定时器中断(代码)
相对于2的使用内部时钟,此方法不同之处仅在于使用函数:

TIM_ETRClockMode2Config(TIM2, TIM_ExtTRGPSC_OFF, TIM_ExtTRGPolarity_NonInverted, 0x00);//第二个设置分频,第三个设置触发方式,第四个设置采样频率(滤波器)

使用特权

评论回复
111
t60yz|  楼主 | 2023-11-22 11:41 | 只看该作者
#include "stm32f10x.h"                  // Device header
#include "OLED.h"
#include "timer2.h"

/***************************************************/定时器2
#include "stm32f10x.h"
#include "timer2.h"

extern int num;
void timer2_init(void)
{
        //**1.打开总的RCC,要配置GPIO从而传入外部时钟
        RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2,ENABLE);//因为定时器2是通用定时器,在APB1总线上
        RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB,ENABLE);
        //**2.配置定时器接入外部时钟 同时配置外部时钟输入的引脚
        //TIM_InternalClockConfig(TIM2);//设置定时器2使用内部时钟,可不写,上电默认
       
        GPIO_InitTypeDef GPIO_InitStruct;
       
        GPIO_InitStruct.GPIO_Mode=GPIO_Mode_IPU;
        GPIO_InitStruct.GPIO_Pin=GPIO_Pin_12;
        GPIO_InitStruct.GPIO_Speed=GPIO_Speed_50MHz;
        GPIO_Init(GPIOB,&GPIO_InitStruct);
       
        TIM_ETRClockMode2Config(TIM2, TIM_ExtTRGPSC_OFF, TIM_ExtTRGPolarity_NonInverted, 0x00);//第二个设置分频,第三个设置触发方式,第四个设置采样频率(滤波器)
        //**3.配置时基单元
        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;//设置预分频值
        TIM_TimeBaseInitStruct.TIM_Period=10-1;//设置预装载值
        TIM_TimeBaseInitStruct.TIM_Prescaler=2-1;//设置预分频值
        TIM_TimeBaseInitStruct.TIM_RepetitionCounter=0;//高级计数器功能,重复计数器
        TIM_TimeBaseInit(TIM2, &TIM_TimeBaseInitStruct);//初始化时基单元
        TIM_ClearFlag(TIM2,TIM_FLAG_Update);//初始化时会产生标志位,需要清除
        //**4.使能时基单元的中断
        TIM_ITConfig(TIM2,TIM_IT_Update,ENABLE);
        //**5.配置NVIC
        NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);//分组
       
        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);
        //**6.开始计数
        TIM_Cmd(TIM2,ENABLE);

}

//**配置中断函数
void TIM2_IRQHandler(void)
{
        if(TIM_GetITStatus(TIM2,TIM_IT_Update)==SET)
        {
                num++;
        }
        TIM_ClearITPendingBit(TIM2, TIM_IT_Update);

}


/***************************************************/主函数

int num;
int main(void)
{
        OLED_Init();
        timer2_init();
        OLED_ShowString(1,1,"Hello,my honey");
//        OLED_ShowString(2,1,"Hello WangFang");
//        OLED_ShowString(3,1,"Hello Tomorrow");
//        OLED_ShowString(4,1,"I miss you");
        while(1)
        {
                OLED_ShowString(2,1,"NUM:");
                OLED_ShowNum(2,5,num,5);
               
                OLED_ShowString(3,1,"Prescaler:");
                OLED_ShowNum(3,11,TIM_GetPrescaler(TIM2),5);
               
                OLED_ShowString(4,1,"Counter:");
                OLED_ShowNum(4,9,TIM_GetCounter(TIM2),5);
        }
}

使用特权

评论回复
112
t60yz|  楼主 | 2023-11-22 11:41 | 只看该作者
4.TIM(OC)比较输出(PWM)!!!
4.1 结构原理介绍(模式)

使用特权

评论回复
113
t60yz|  楼主 | 2023-11-22 11:41 | 只看该作者

使用特权

评论回复
114
t60yz|  楼主 | 2023-11-22 11:41 | 只看该作者

使用特权

评论回复
115
t60yz|  楼主 | 2023-11-22 11:41 | 只看该作者

使用特权

评论回复
116
t60yz|  楼主 | 2023-11-22 11:42 | 只看该作者
8种模式

TIM_OCMode                        函数库描述                             解释


TIM_OCMode_Timing       TIM输出比较                      冻结,输出比较不起作用
TIM_OOCMode_Active     TIM输出比较主动模式        当比较发生时,强制输出高电平
TIM_OCMode_Inactiive    TIM输出比较非主动模式     当比较发生时,强制输出低电平
TIM_OCMode_Toggle       TIM输出比较触发模式        当比较发生时,输出翻转
TIM_OCMode_PWM1        TIM脉冲宽度调制模式1      PWM1
TIM_OCMode_PWM2        TIM脉冲宽度调制模式2      PWM2

使用特权

评论回复
117
t60yz|  楼主 | 2023-11-22 11:42 | 只看该作者

使用特权

评论回复
118
t60yz|  楼主 | 2023-11-22 11:42 | 只看该作者

使用特权

评论回复
119
t60yz|  楼主 | 2023-11-22 11:42 | 只看该作者

使用特权

评论回复
120
t60yz|  楼主 | 2023-11-22 11:42 | 只看该作者
4.2 输出设备(舵机,直流电机)

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则