单片机的运行需要一个脉冲信号,作为自己执行指令的触发信号。可以理解为,单片机收到一个脉冲,就执行一次或多次指令。
而这个脉冲是由单片机控制器中的时序电路发出,组成该电路最关键的器件晶振,是一种高精度,高稳定度的振荡器,街上一定的外界电路可以生成频率和峰值稳定的正弦波。这就给单片机提供了脉冲。
所以时钟就是给的单片机提供脉冲,从而使它执行指令。
51单片机和stm32
51不需要配置时钟,因为一个时钟开启所有功能都可以用。就相当只有一个总开关,且默认为开启状态。
32默认为关闭,不同的功能使用不同的时钟,因此需要用哪个就开启哪个时钟。
普通方法:
设置定时器触发中断,每隔一段事件在程序中调用代码手动触发一次DAC转换,然后DAC输出 。但会影响主程序运行和其他中断的响应。
改进,定时器设计了主模式
因此定时器设计了主模式,使用它可以把这个更新事件映射到触发输出TRGO口上,触发TRGO直接接到DAC的触发转换引脚上,从而定时器的更新不需要触发中断来触发FAC转换了。
编码器接口:读取正交编码器的输出波形
捕获比较寄存器:输入捕获和比较电路共用
计数器无预装时序(没有缓冲寄存器)
计数器有预装时序 (有缓冲寄存器)
缓冲寄存器的功能:
实现每隔几个周期再更新一次。
之前是,每个周期都更新,对更新信号再分频
作用:
缓冲寄存器才是真正起作用的寄存器,比如再某个时刻把预分频器寄存器由0该1,如果此时立刻改变分频系数,就会导致前半段和后半段分频不一致,缓存计数器的作用就是,改变后不会立刻生效,等待本次计数结束,产生更新时间,预分频的值才会传进去,下一轮计数才生效。
包含有缓冲寄存器的有:
通过设置ARPE位
无预装:自动加载寄存器突然更改,将FF改为36
计数的目标值就从FF变为36,因此计数寄存器增加到目标值36就自动更新,重新计数
有预装:自动加载寄存器突然更改,当F5突然改为36,计数寄存器仍然
累计到F5,完成本次计数,才更新计算下一轮计数。
主函数执行之前会先运行一个systemInit函数:用来配置时钟树
1.选择内部8MHZ给系统时钟(绿色路线),系统暂时以8MZH运行。2.在开启外部时钟(红色路线)进入PLL锁相环进行倍频,8MHZ倍频9倍,得到72MHZ,等到锁相环输出稳定,选择锁相环输出为系统时钟,这样就将系统时钟从8MHZ切换到72MHZ。
程序的时钟慢了10倍。定时器设定为1S,结果10秒后才有中断。
因为没有了外部时钟,内部那就是以8MHZ运行,相比于72MHZ满了10倍。
(外部晶振引脚焊短路)
CSS:用来切换时钟。检测外部时钟的运行状态,如果外部出问题了,那就该时钟为内部,保证程序运行。
即便APB1选择的是,但是有分支判断它的分频系数,最终输出仍然是72MHZ,因此可以的出,不论是基本,通用还是高级定时器,内部基准时钟都是72MHZ。
//时基单元
void TIM_DeInit(TIM_TypeDef* TIMx);
//定时器时基单元初始化,就是配置自动重装器,预分频器,计数器,第一个参数:选择某个定时器,
void TIM_TimeBaseInit(TIM_TypeDef* TIMx, TIM_TimeBaseInitTypeDef* TIM_TimeBaseInitStruct);
//可以把结构体变量赋默认值
void TIM_TimeBaseStructInit(TIM_TimeBaseInitTypeDef* TIM_TimeBaseInitStruct);
//运行控制:启动时基单元
void TIM_Cmd(TIM_TypeDef* TIMx, FunctionalState NewState);
//使能中断控制 第二个参数:哪个中断函数
void TIM_ITConfig(TIM_TypeDef* TIMx, uint16_t TIM_IT, FunctionalState NewState);
//时钟源的选择
//下面6个函数指的就是最左边的绿色那三个,选择时钟
void TIM_InternalClockConfig(TIM_TypeDef* TIMx);
//第二个参数,选择输入捕获通道
void TIM_ITRxExternalClockConfig(TIM_TypeDef* TIMx, uint16_t TIM_InputTriggerSource);
//第二个参数:选择TIX具体的某个引脚,第三个:输入的极性 第四个:输入的滤波器(对于外部引脚,都会有极性选择和滤波器)
void TIM_TIxExternalClockConfig(TIM_TypeDef* TIMx, uint16_t TIM_TIxExternalCLKSource,
uint16_t TIM_ICPolarity, uint16_t ICFilter);
//外部触发预分频器
void TIM_ETRClockMode1Config(TIM_TypeDef* TIMx, uint16_t TIM_ExtTRGPrescaler, uint16_t TIM_ExtTRGPolarity,
uint16_t ExtTRGFilter);
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);
//单独设置预分频值的函数 第二个参数:选择写入模式,预分频器有缓冲寄存器,写入的值只有在更新事件后才有效。
//所以这里的写入模式可以选择听从安排,在更新事件后生效,或写入后,手动产生一个更新事件,让这个值立刻生效。
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_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);