
用一句话讲明功能就是可以定时在什么时间干什么事

我们在对rcc进行初始化的时候,需要想好我们要去怎么去设置
=================基本定时器================================================


预分频器,比如说当你选择去设定为0时,也就是将基准时钟去除以(0+1),设定为1的时候,也就是将基准时钟去除以(1+1),其余的都是同理;当我们设定好定时后,我们的计数器会不断的计数去和我们的自动重装载寄存器去进行比较,倘若到了设定的标准,则会进行中断啊等等,也叫做更新中断
===========主模式触发DAC的功能=============================================


通过这个触发信号来控制其他的外设
============================================通用计时器=====================


图片讲解的很清楚,红色框图(和普通计时器不同的是,不仅支持向上计数模式,还支持向下和中央计数模式,什么是向上计数模式,就是比如说你设定了一个自动装载值为10,从0-1-2-3-···-10,然后再归零,而向下计数就是,从10不断减到0回到装载值触发中断,然后反复;然后对于中央计数呢,就是从0开始,从0到重装值触发中断,然后回到0再触发中断,不断反复

下面的部分

=======================高级计数器==========================================

只是多加了一部分,不需要去多讲
===============本项目所讲的工程的基本结构====================================

这四个即为我们的所有时钟,进行挑选就行,而这里的中断输出控制这一块,就是说当我们进行输出中断的时候,我们需要给出是否需要,只有需要的时候,才会有中断输出控制
=============执行逻辑======================================================


这就是我们的一个预分频器的时序逻辑
CK_PSC:即为系统时钟所输出的频率
CNT_EN:可以理解为使能端,只有这个开启,我们的时钟才会进行
CK_CNT:可以从图表上看出,只有当我们的使能端开启的时候,计数器才会接收我们的时钟
计数器寄存器:从图上可以看出到达FC,此时寄存器会重新计数,改到2的时候,计数器的频率降低
更新事件:发现只有当到达FC的时候才会更新事件
预分频控制寄存器:当你改换时钟计数器计数频率的时候,只有到达重装值时,才会重新开始更换计数器的计数频率
下面的意思相同
=========================================================================

和上面的同理,但是要记住当你达到重装值的时候,就会产生更新时间,然后我们的中断标志在我们的状态寄存器中就会置1,会一直执行中断,所以使用的时候,必须要想到要定时对其进行清楚



其实本质区别就是,当你改换了重装值的时候,一个是直接进行改换,一个是等到下一次重装值结束后进行更改
========================rcc时钟数==========================================

===============项目一 定时器================================================

①:RCC初始化,开启时钟②:选择时钟源③:配置时基单元④:配置中断输出控制⑤:配置NVIC⑥:运行控制⑦写一个中断函数
============要用到的函数===================================================

即对应为③


和之前有一个函数一样

③即为运行控制④即为中断输出控制


函数5,6,7,8即为我们的选择时钟部分,根据我们的时钟选择需要的函数,可以在我们之前的那个,高级定时器那边看到






最后四个就是之前的状态寄存器里的标志位,一个是在主函数中去使用,一个是在中断中去使用
============================================================定时器计数=====
Timer.h
#include "stm32f10x.h" // Device header
void Timerinit(void)
{
RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2,ENABLE);
//rcc初始化,为什么是TIM2,因为板子只有1-4
//下一步开始选择时钟
TIM_InternalClockConfig(TIM2);
//选择了内部时钟,下面开始时基单元初始化
TIM_TimeBaseInitTypeDef TimeBasestruct;
TimeBasestruct.TIM_ClockDivision=TIM_CKD_DIV1;//这个其实没啥说法,后面在看看
TimeBasestruct.TIM_CounterMode=TIM_CounterMode_Up;//这个就是向上计数,向下计数,中央计数啥的
TimeBasestruct.TIM_Period=999;//TIM_Period = 目标计数次数 - 1
TimeBasestruct.TIM_Prescaler=7199;//72MHz / 10kHz = 7200,TIM_Prescaler = 7200 - 1 = 7199
TimeBasestruct.TIM_RepetitionCounter=0;//高级计数器的时候才会使用
TIM_TimeBaseInit(TIM2,&TimeBasestruct);
TIM_ClearFlag(TIM2, TIM_FLAG_Update);//配置好后,会默认有一个中断,要去除
//下一步开始中断控制
TIM_ITConfig(TIM2,TIM_IT_Update,ENABLE);
//下一步进行NVIC优先级配置
NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);
NVIC_InitTypeDef TimeBasestruct1;
TimeBasestruct1.NVIC_IRQChannel=TIM2_IRQn;
//指定中断通道为 TIM2 的中断通道,使 NVIC 识别并管理 TIM2 的中断请求
TimeBasestruct1.NVIC_IRQChannelCmd=ENABLE;
//使能 TIM2 的中断通道,允许 NVIC 响应 TIM2 的中断请求
TimeBasestruct1.NVIC_IRQChannelPreemptionPriority=0;
TimeBasestruct1.NVIC_IRQChannelSubPriority=0;
NVIC_Init(&TimeBasestruct1);
//最后一步进行使能
TIM_Cmd(TIM2, ENABLE);
}
#ifndef __TIMER_H
#define __TIMER_H
void Timerinit(void);
#endif
#include "stm32f10x.h" // Device header
#include "OLED.h"
#include "Countsensor.h"
#include "Timer.h"
int16_t NUM;
int main(void)
{
OLED_Init(); //TIM_GetCounter(TIM2)就是计数器在不停的进行计数
Timerinit(); //计数器到达一个重装值的时候,此时就会进行中断
OLED_ShowString(1,1,"NUM:"); //然后我们的NUM就会加1
while(1)
{
OLED_ShowNum(1,5,NUM,5);
OLED_ShowNum(2,5,TIM_GetCounter(TIM2),5);
}
}
void TIM2_IRQHandler(void)
{
if (TIM_GetITStatus(TIM2, TIM_IT_Update) == SET) //判断是否是TIM2的更新事件触发的中断
{
NUM ++; //Num变量自增,用于测试定时中断
TIM_ClearITPendingBit(TIM2, TIM_IT_Update); //清除TIM2更新事件的中断标志位
//中断标志位必须清除 //否则中断将连续不断地触发,导致主程序卡死
}
}

照着这个思路写的
=============================外接时钟中断计数===============================
其实就是换了一个函数,使用了外部时钟源,然后多配置一个gpio接口就行
#include "stm32f10x.h" // Device header
void Timerinit(void)
{
RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2,ENABLE);
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA,ENABLE);
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);
//rcc初始化,为什么是TIM2,因为板子只有1-4
//下一步开始选择时钟
TIM_ETRClockMode2Config(TIM2,TIM_ExtTRGPSC_OFF,TIM_ExtTRGPolarity_NonInverted,6);
//选择了外部时钟,下面开始时基单元初始化
TIM_TimeBaseInitTypeDef TimeBasestruct;
TimeBasestruct.TIM_ClockDivision=TIM_CKD_DIV1;//这个其实没啥说法,后面在看看
TimeBasestruct.TIM_CounterMode=TIM_CounterMode_Up;//这个就是向上计数,向下计数,中央计数啥的
TimeBasestruct.TIM_Period=10-1;//TIM_Period = 目标计数次数 - 1
TimeBasestruct.TIM_Prescaler=1-1;//72MHz / 10kHz = 7200,TIM_Prescaler = 7200 - 1 = 7199-
TimeBasestruct.TIM_RepetitionCounter=0;//高级计数器的时候才会使用
TIM_TimeBaseInit(TIM2,&TimeBasestruct);
TIM_ClearFlag(TIM2, TIM_FLAG_Update);//配置好后,会默认有一个中断,要去除
//下一步开始中断控制
TIM_ITConfig(TIM2,TIM_IT_Update,ENABLE);
//下一步进行NVIC优先级配置
NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);
NVIC_InitTypeDef TimeBasestruct1;
TimeBasestruct1.NVIC_IRQChannel=TIM2_IRQn;
//指定中断通道为 TIM2 的中断通道,使 NVIC 识别并管理 TIM2 的中断请求
TimeBasestruct1.NVIC_IRQChannelCmd=ENABLE;
//使能 TIM2 的中断通道,允许 NVIC 响应 TIM2 的中断请求
TimeBasestruct1.NVIC_IRQChannelPreemptionPriority=0;
TimeBasestruct1.NVIC_IRQChannelSubPriority=0;
NVIC_Init(&TimeBasestruct1);
//最后一步进行使能
TIM_Cmd(TIM2, ENABLE);
}
#include "stm32f10x.h" // Device header
#include "OLED.h"
#include "Countsensor.h"
#include "Timer.h"
int16_t NUM;
int main(void)
{
OLED_Init(); //TIM_GetCounter(TIM2)就是计数器在不停的进行计数
Timerinit(); //计数器到达一个重装值的时候,此时就会进行中断
OLED_ShowString(1,1,"NUM:");
OLED_ShowString(2,1,"CNT:"); //然后我们的NUM就会加1
while(1)
{
OLED_ShowNum(1,5,NUM,5);
OLED_ShowNum(2,5,TIM_GetCounter(TIM2),5);
}
}
void TIM2_IRQHandler(void)
{
if (TIM_GetITStatus(TIM2, TIM_IT_Update) == SET) //判断是否是TIM2的更新事件触发的中断
{
NUM++; //Num变量自增,用于测试定时中断
TIM_ClearITPendingBit(TIM2, TIM_IT_Update); //清除TIM2更新事件的中断标志位
//中断标志位必须清除 //否则中断将连续不断地触发,导致主程序卡死
}
}
305

被折叠的 条评论
为什么被折叠?



