打印
[其他ST产品]

STM32入门基础

[复制链接]
楼主: 为你转身
手机看帖
扫描二维码
随时随地手机跟帖
21
为你转身|  楼主 | 2023-7-30 15:56 | 只看该作者 |只看大图 回帖奖励 |倒序浏览
服务函数结束后清除标志位

        EXTI_ClearITPendingBit(EXTI_Line0);//清除中断挂起标志位

使用特权

评论回复
22
为你转身|  楼主 | 2023-7-30 15:56 | 只看该作者
定时器

TIM(Timer)定时器

<1> 简介

· 定时器可以对输入的时钟进行计数,并在计数值达到设定值时触发中断

· 16位计数器、预分频、自动重装寄存器的时基单元,在72M计数时钟下可以实现最大59.65s的定时

· 不仅具备基本的定时器中断功能,而且还包含内外时钟源选择、输入捕获、输出比较、编码器接口、主从触发模式等多种功能

· 根据复杂度和应用场景分为了高级定时器、通用定时器、基本定时器三种类型

使用特权

评论回复
23
为你转身|  楼主 | 2023-7-30 15:56 | 只看该作者
对72MHz计72个数就是1MHz,也就是1us的时间,计72000个数,那就是1KHz也就是1ms的时间

59.65s =65536 · 65536 · 1/72M/(中断频率倒数),

· STM32的定时器支持级联的模式:一个定时器的输出当做另一个定时器的输入最大定时时间就是59.65s · 65536 · 65536

· STM32F103C8T6有TIM1/2/3/4四个定时器

使用特权

评论回复
24
为你转身|  楼主 | 2023-7-30 15:56 | 只看该作者
基本定时器有三个重要的定时器,这三个我们称一起为时基单元

下面是我们常选择的基本定时器

使用特权

评论回复
25
为你转身|  楼主 | 2023-7-30 15:57 | 只看该作者
这三个定时器连内部定时器,也就是ck_int

· 预分频器(PSC):对输入的基准频率提前进行一个分频的操作
实际分频系数 = 预分频器的值 + 1,最大可以写65535即65536分频


· 计数器(CNT):也是16位,值可以从0~65535,当计数器的值自增(自减)到目标值时,产生中断,完成定时


使用特权

评论回复
26
为你转身|  楼主 | 2023-7-30 15:57 | 只看该作者
自动重装寄存器():也是16位当计数值等于自动重装值时,就是计时的时间到了,就会产生一个中断信号,并且清零计数器,计数器自动开始下一次的计数计时,计数值等于自动重装值的中断一般叫做“更新中断”,此更新中断就会通往NVIC,再配置好NVIC的定时器通道,定时器上的更新中断就会得到CPU的响应了,对应的事件叫做“更新事件”,更新事件不会触发中断,但可以触发内部其他电路的工作

使用特权

评论回复
27
为你转身|  楼主 | 2023-7-30 15:57 | 只看该作者
我们在通用定时器内,不仅可选择内部时钟,也可以选择外部TIMX_ETR引脚上的外部时钟

基本结构

使用特权

评论回复
28
为你转身|  楼主 | 2023-7-30 15:57 | 只看该作者
定时器触发中断,我们可以选择RCC触发的内部时钟(定时器中断计数),也可以选择ETR引脚提供的外部时钟模式2.

也可以选择触发输入当作外部时钟(模式1),对应的为ETR外部时钟,ITRx其他1定时器,Tix输入捕获通道

编码器模式为编码器独有的模式

使用特权

评论回复
29
为你转身|  楼主 | 2023-7-30 15:58 | 只看该作者
预分频器时序

使用特权

评论回复
30
为你转身|  楼主 | 2023-7-30 15:58 | 只看该作者
计数器技术频率 : CK_CNT = CK_PSC / (PSC+1)

计数器时序

使用特权

评论回复
31
为你转身|  楼主 | 2023-7-30 15:58 | 只看该作者
· 计数器溢出频率 : CK_CNT_OV = CK_CNT / (ARR + 1)

通过设置ARPE,就可以选择有无预装的情况

使用特权

评论回复
32
为你转身|  楼主 | 2023-7-30 15:58 | 只看该作者
开启定时器步骤

第一步,RCC开启时钟
第二步,选择时基单元的时钟源
第三步,配置时基单元
第四步,配置输出中断控制,允许更新中断输出到NVIC
第五步,配置NVIC,在NVIC中打开定时器中断的通道,并分配一个优先级
第六步,运行控制
第七步,使能计数器

使用特权

评论回复
33
为你转身|  楼主 | 2023-7-30 15:58 | 只看该作者
输出比较说明

· OC——输出比较

· 输出比较可以通过CNT和CRR寄存器值的关系,来对输出电平进行 1, 0 ,翻转

· 每个通用定时器/高级都有4个输出比较通道

使用特权

评论回复
34
为你转身|  楼主 | 2023-7-30 15:58 | 只看该作者
PWM

· 可通过一系列脉冲的宽度进行调制

使用特权

评论回复
35
为你转身|  楼主 | 2023-7-30 15:58 | 只看该作者

使用特权

评论回复
36
为你转身|  楼主 | 2023-7-30 15:59 | 只看该作者
输出比较模式

使用特权

评论回复
37
为你转身|  楼主 | 2023-7-30 15:59 | 只看该作者
TIM库函数


// 恢复配置
void TIM_DeInit(TIM_TypeDef* TIMx);

/********时基单元**********************
// 时基单元的配置,第一个选择TIMX的某个定时器,第二个结构体,包含了配置时基单元的一些参数
void TIM_TimeBaseInit(TIM_TypeDef* TIMx, TIM_TimeBaseInitTypeDef* TIM_TimeBaseInitStruct);
********************end***************/

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_ICInit(TIM_TypeDef* TIMx, TIM_ICInitTypeDef* TIM_ICInitStruct);
void TIM_PWMIConfig(TIM_TypeDef* TIMx, TIM_ICInitTypeDef* TIM_ICInitStruct);
void TIM_BDTRConfig(TIM_TypeDef* TIMx, TIM_BDTRInitTypeDef *TIM_BDTRInitStruct);

//结构体变量赋一个默认值
void TIM_TimeBaseStructInit(TIM_TimeBaseInitTypeDef* TIM_TimeBaseInitStruct);

void TIM_OCStructInit(TIM_OCInitTypeDef* TIM_OCInitStruct);
void TIM_ICStructInit(TIM_ICInitTypeDef* TIM_ICInitStruct);
void TIM_BDTRStructInit(TIM_BDTRInitTypeDef* TIM_BDTRInitStruct);

//使能计数器,对应图中运行控制(运行控制)
void TIM_Cmd(TIM_TypeDef* TIMx, FunctionalState NewState);


void TIM_CtrlPWMOutputs(TIM_TypeDef* TIMx, FunctionalState NewState);

//输出中断控制 使能中断输出信号,1.选择定时器 2.配置哪个中断输出, 3.状态为使能/失能
void TIM_ITConfig(TIM_TypeDef* TIMx, uint16_t TIM_IT, FunctionalState NewState);

void TIM_GenerateEvent(TIM_TypeDef* TIMx, uint16_t TIM_EventSource);
void TIM_DMAConfig(TIM_TypeDef* TIMx, uint16_t TIM_DMABase, uint16_t TIM_DMABurstLength);
void TIM_DMACmd(TIM_TypeDef* TIMx, uint16_t TIM_DMASource, FunctionalState NewState);


//下面四个对应时基单元的时钟选择部分

/****************时钟源选择********************
//选择内部时钟,选择定时器即可
void TIM_InternalClockConfig(TIM_TypeDef* TIMx);
//选择ITRX其他定时器时钟,1.选择定时器 2.选择接入哪个其他定时器
void TIM_ITRxExternalClockConfig(TIM_TypeDef* TIMx, uint16_t TIM_InputTriggerSource);
//选择TIX捕获通道的函数 2.选择具体引脚 3.输入极性与滤波器
void TIM_TIxExternalClockConfig(TIM_TypeDef* TIMx, uint16_t TIM_TIxExternalCLKSource,
                                uint16_t TIM_ICPolarity, uint16_t ICFilter);
//选择ETR通过外部时钟模式1输入时钟
void TIM_ETRClockMode1Config(TIM_TypeDef* TIMx, uint16_t TIM_ExtTRGPrescaler, uint16_t TIM_ExtTRGPolarity, uint16_t ExtTRGFilter);
//选择ETR通过外部时钟模式2输入时钟
void TIM_ETRClockMode2Config(TIM_TypeDef* TIMx, uint16_t TIM_ExtTRGPrescaler,
                             uint16_t TIM_ExtTRGPolarity, uint16_t ExtTRGFilter);、
//配置引脚预分频等等
void TIM_ETRConfig(TIM_TypeDef* TIMx, uint16_t TIM_ExtTRGPrescaler, uint16_t TIM_ExtTRGPolarity, uint16_t ExtTRGFilter);
*****************end file**********************************************/


//单独写入预分频值 3.写入模式
void TIM_PrescalerConfig(TIM_TypeDef* TIMx, uint16_t Prescaler, uint16_t TIM_PSCReloadMode);


void TIM_CounterModeConfig(TIM_TypeDef* TIMx, uint16_t TIM_CounterMode);
void TIM_SelectInputTrigger(TIM_TypeDef* TIMx, uint16_t TIM_InputTriggerSource);
void TIM_EncoderInterfaceConfig(TIM_TypeDef* TIMx, uint16_t TIM_EncoderMode,
                                uint16_t TIM_IC1Polarity, uint16_t TIM_IC2Polarity);
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);
void TIM_ARRPreloadConfig(TIM_TypeDef* TIMx, FunctionalState NewState);
void TIM_SelectCOM(TIM_TypeDef* TIMx, FunctionalState NewState);
void TIM_SelectCCDMA(TIM_TypeDef* TIMx, FunctionalState NewState);
void TIM_CCPreloadControl(TIM_TypeDef* TIMx, FunctionalState NewState);
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);
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);
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);
void TIM_UpdateDisableConfig(TIM_TypeDef* TIMx, FunctionalState NewState);
void TIM_UpdateRequestConfig(TIM_TypeDef* TIMx, uint16_t TIM_UpdateSource);
void TIM_SelectHallSensor(TIM_TypeDef* TIMx, FunctionalState NewState);
void TIM_SelectOnePulseMode(TIM_TypeDef* TIMx, uint16_t TIM_OPMode);
void TIM_SelectOutputTrigger(TIM_TypeDef* TIMx, uint16_t TIM_TRGOSource);
void TIM_SelectSlaveMode(TIM_TypeDef* TIMx, uint16_t TIM_SlaveMode);
void TIM_SelectMasterSlaveMode(TIM_TypeDef* TIMx, uint16_t TIM_MasterSlaveMode);

//给计数器写入一个值函数
void TIM_SetCounter(TIM_TypeDef* TIMx, uint16_t Counter);

//给自动重装器写入一个值函数
void TIM_SetAutoreload(TIM_TypeDef* TIMx, uint16_t Autoreload);
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);
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);
void TIM_SetClockDivision(TIM_TypeDef* TIMx, uint16_t TIM_CKD);
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);

//获取当前计数器的值函数
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);

使用特权

评论回复
38
为你转身|  楼主 | 2023-7-30 15:59 | 只看该作者
定时器初始化示例:
void Timer_Init(void)
{
        RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2, ENABLE);//开启TIM2时钟
       
//因为如果不写默认的就是使用内部时钟,所以我们可以选择不写这个
        TIM_InternalClockConfig(TIM2);//使用内部时钟
       
        TIM_TimeBaseInitTypeDef TIM_TimeBaseInitStructure;//定义时基单元结构体
        TIM_TimeBaseInitStructure.TIM_ClockDivision = TIM_CKD_DIV1;//设置不分频
        TIM_TimeBaseInitStructure.TIM_CounterMode = TIM_CounterMode_Up;//设置向上计数
        TIM_TimeBaseInitStructure.TIM_Period = 10000 - 1;//ARR自动重装值
        TIM_TimeBaseInitStructure.TIM_Prescaler = 7200 - 1;//PSC不分频
        TIM_TimeBaseInitStructure.TIM_RepetitionCounter = 0;//重复计数器的值,高级定时器特有
        TIM_TimeBaseInit(TIM2, &TIM_TimeBaseInitStructure);//写入参数
       
        TIM_ClearFlag(TIM2, TIM_FLAG_Update);//清除更新标志位
        TIM_ITConfig(TIM2, TIM_IT_Update, ENABLE);//中断输出
       
        NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);//中断优先级分组
       
        NVIC_InitTypeDef NVIC_InitStructure;//NVIC结构体
        NVIC_InitStructure.NVIC_IRQChannel = TIM2_IRQn;//定时器通道
        NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;//使能
        NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 2;//抢占优先级
        NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1;//响应优先级
        NVIC_Init(&NVIC_InitStructure);//写入参数
       
        TIM_Cmd(TIM2, ENABLE);//开启定时器
}

使用特权

评论回复
39
周半梅| | 2023-12-29 08:19 | 只看该作者

共模电感的电感值可以用电桥来测量

使用特权

评论回复
40
Pulitzer| | 2023-12-29 09:22 | 只看该作者

单层板不具有固定孔

使用特权

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

本版积分规则