数字电路中分频比(计数模值)怎么计算

数字电路中分频比(计数模值)怎么计算,第1张

这个是看计数器的位数决定分频数的。
如4位计数器,可分频2的4次方,即16分频。
计数器Ⅰ的模为M,计数器Ⅱ的模为N
CO进位信号作为计数器2的触发信号,用乘法计算总分频器,即可实现MN次分频。

实例说明:

 假设时钟周期为4MHZ,每隔50MS点亮LED,每隔50MS灭掉LED。这样的程序要如何做到呢。

 这50ms如何做到

1,得到指令周期

  4MHz/4=1MHz

  1/1MHz=00000001s=1us

2,得到预分频

     定时器定时的最大时间要超过这50mS,所以预分频器要选择256

     预分频X256=最大的定时时间。256X256=65536us=65536ms 大于50ms

3,  计算定时器初始值

  (定时器最大值+1)- (定时时间/预分频)=定时器的初始值。

  255+1=256

  50000/256=1953125

  256-1953125=606875 四舍五入 定时器初始值为61

设置相关的寄存器。

OPTION_REG寄存器中我们一般需要设置三处。

PS<2:0>设置用来设置预分频预分频范围从2 ~256

PSA设置成0   讲预分频器分配给Timer0模块

TMR0CS设置成0 内部指令周期时钟。

实例程序:

/开发环境 MPLAB X IDE 型号PIC16LF1823/

#include<pich>  
__CONFIG(FOSC_INTOSC&WDTE_OFF&PWRTE_ON&MCLRE_OFF&CP_ON&CPD_OFF

                                                 &BOREN_ON&CLKOUTEN_OFF&IESO_ON&FCMEN_ON);
__CONFIG(PLLEN_OFF&LVP_OFF) ;
#define LED  LATA5/也可用 #define LED RA5,只是PIC16LF1823 输出电平的时候,直接控制LATA5执行速度更快,因为传给RA5的数据最终也是传给LATA5才执行的/
void init_fosc(void)
{
    OSCCON= 0x68;//时钟设置为4MHz
}
void init_gpio(void)
{
    PORTA = 0;
    LATA = 0;
    ANSELA = 0;
    TRISAbitsTRISA5=0; //RA5口设置成输出 用来控制LED
}
void init_timer0(void)
{
    OPTION_REG=0x87; //预分频为256
}
int main(int argc, char argv)
{
    init_fosc();
    init_gpio();
    init_timer0();
    TMR0IF=0;//清除TMR0中断标志位
    TMR0=61;//设置中断初始值61
    while(1)
    {
        if(TMR0IF==1)//定时时间到了吗??
        {
            LED = ~LED;//改变LED的状态
            TMR0IF=0;//清除TMR0中断标志位
            TMR0=61;//设置中断初始值61为下次50ms定时做准备
        }
    }
}

一般需要预分频的化,只需要对相关寄存器 *** 作就好。
TIM_TimeBaseStructureTIM_Period = arr; //设置自动重装载值
TIM_TimeBaseStructureTIM_Prescaler =psc; //设置预分频值
TIM_TimeBaseStructureTIM_ClockDivision = 0; //设置时钟分割:TDTS = Tck_tim
TIM_TimeBaseStructureTIM_CounterMode = TIM_CounterMode_Up; //向上计数模式
TIM_TimeBaseInit(TIM3, &TIM_TimeBaseStructure); //根据指定的参数初始化TIMx的
还有系统时钟的相关参数设定请参考资料手册:
给你个链接把:>获得合适的ADC时钟提供ADC使用。通常经过ADC预分频器能分频到最大的时钟只能是12M,ADC预分频器控制位为00时表示最低2分频,最高可设置8分频。adc预分频可以对大于100KHz的系统时钟进行分频,以获得合适的ADC时钟提供ADC使用。

l4d支持 第3人称,只需要在控制台输入 thirdpersonshoulder 回车即可,好像第3人称准星不太正确,如果想改回第1人称 在控制台输入 firstperson。
打开控制台方法:
1、首先在选项里找 鼠标设置;
2、然后里面有一个 控制台 选择启用;
3、之后按“`” 就是数字1左边的那个键。

STM32F10XXX系列包含TIM6、TIM7两个基本定时器,计数器为16位,其功能比较简单,仅支持向上计数,且只能计时,没有外部I/O口。
一、基本定时器的功能框图
1、时钟源TIMxCLK:定时器的时钟源来自系统内部时钟,准确来说由APB1预分频器分频提供,因为TIM6、7都是挂载在APB1上的外设。如果APB1的预分频系数等于1,则频率不变,其他情况,频率乘以2,库函数中APB1的分频系数为2,故定时器的时钟TIMxCLK=362=72MHz。
2、计数器时钟CK_CNT:CK_PSC可看成直接由CK_INT经触发控制器引入,PSC预分频器为16位寄存器,可对TIMxCLK进行1~65536分频,计算公式为:CK_CNT=TIMxCLK/(PSC+1)。
3、计数器CNT:计数器CNT为16位寄存器,只能向上计数,最大值为65535,当计数器有0加到65535并溢出时,可以产生一个更新中断/更新事件。
4、自动重装寄存器ARR:16位寄存器,里面的数值为计数器能达到的最大数值。
5、产生一次中断的时间计算:time=(ARR+1)/(TIMxCLK/(PSC+1))
在实际中,预分频器起分频作用的是其影子寄存器或称为缓冲器。由下图的时序图可见:
ARR的值为FC-1,最开始预分频控制寄存器的值为0,此时预分频系数为1,即计数器时钟为72MHz。当计数器计数到F8时,我们将预分频控制寄存器的值写为1,此时,预分频器缓冲寄存器的值并没有立即更新为1,定时器的时钟依然为72MHz,计数器计数到FC,产生一个更新事件后,才将预分频器缓冲器的值更新为1,此时定时器的时钟变为原来的一半,即36MHz,保证了计数的准确性。
二、时基单元
typedef struct
{
uint16_t TIM_Prescaler; /!< Specifies the prescaler value used to divide the TIM clock
This parameter can be a number between 0x0000 and 0xFFFF /
uint16_t TIM_CounterMode; /!< Specifies the counter mode
This parameter can be a value of @ref TIM_Counter_Mode /
uint16_t TIM_Period; /!< Specifies the period value to be loaded into the active
Auto-Reload Register at the next update event
This parameter must be a number between 0x0000 and 0xFFFF /
uint16_t TIM_ClockDivision; /!< Specifies the clock division
This parameter can be a value of @ref TIM_Clock_Division_CKD /
uint8_t TIM_RepetitionCounter; /!< Specifies the repetition counter value Each time the RCR downcounter
reaches zero, an update event is generated and counting restarts
from the RCR value (N)
This means in PWM mode that (N+1) corresponds to:
- the number of PWM periods in edge-aligned mode
- the number of half PWM period in center-aligned mode
This parameter must be a number between 0x00 and 0xFF
@note This parameter is valid only for TIM1 and TIM8 /
} TIM_TimeBaseInitTypeDef;
1、TIM_Prescaler:定时器预分频器设置
2 、TIM_CounterMode:计数器有向上计数、向下计数、中心对齐计数3中模式,基本定时器仅支持向上计算,这里不用设置
3、TIM_Period:定时器周期,实际就是设置自动重装寄存器ARR的值
4 、TIM_ClockDivision:时钟分频,设置定时器时钟CK_INT频率与数字滤波器采样时钟频率的分频比,基本定时器不用设置
5 、TIM_RepetitionCounter:重复计数器,属于高级定时器的功能,不用设置
三、代码
使用定时器实现1S定时,因为STM32F103C8T6只有TIM1、TIM2、TIM3、TIM4这几个定时器,这里使用TIM2代替TIM6。
Timerc文件
#include "stm32f10xh" // Device header
void Timer_Init(void)
{
//第一步:开启APB1上的TIM2外设时钟
RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2, ENABLE);
//第二步:时钟源选择内部时钟
TIM_InternalClockConfig(TIM2);
//第三步:初始化TIM2时基单元
TIM_TimeBaseInitTypeDef TIM_TimeBaseInitStructure;
TIM_TimeBaseInitStructureTIM_ClockDivision = TIM_CKD_DIV1;
TIM_TimeBaseInitStructureTIM_CounterMode = TIM_CounterMode_Up;
TIM_TimeBaseInitStructureTIM_Period = 10000 - 1;
TIM_TimeBaseInitStructureTIM_Prescaler = 7200 - 1;
TIM_TimeBaseInitStructureTIM_RepetitionCounter = 0;
TIM_TimeBaseInit(TIM2, &TIM_TimeBaseInitStructure);
//第四步:手动清除计数器中断标志位
TIM_ClearFlag(TIM2, TIM_FLAG_Update);
//第五步:开启计数器中断
TIM_ITConfig(TIM2, TIM_IT_Update, ENABLE);
//第六步:配置NVIC
NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);

NVIC_InitTypeDef NVIC_InitStructure;
NVIC_InitStructureNVIC_IRQChannel = TIM2_IRQn;
NVIC_InitStructureNVIC_IRQChannelCmd = ENABLE;
NVIC_InitStructureNVIC_IRQChannelPreemptionPriority = 2;
NVIC_InitStructureNVIC_IRQChannelSubPriority = 1;
NVIC_Init(&NVIC_InitStructure);
//第七步:计数器使能
TIM_Cmd(TIM2, ENABLE);
}
mainc文件
#include "stm32f10xh" // Device header
#include "Delayh"
#include "OLEDh"
#include "Timerh"
uint16_t Num;
int main(void)
{
OLED_Init();
Timer_Init();

OLED_ShowString(1, 1, "Num:");

while (1)
{
OLED_ShowNum(1, 5, Num, 5);
}
}
/TIM2中断处理程序/
void TIM2_IRQHandler(void)
{
if (TIM_GetITStatus(TIM2, TIM_IT_Update) == SET)
{
Num ++;
TIM_ClearITPendingBit(TIM2, TIM_IT_Update);
}
}


欢迎分享,转载请注明来源:内存溢出

原文地址: https://www.outofmemory.cn/yw/13321698.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2023-07-14
下一篇 2023-07-14

发表评论

登录后才能评论

评论列表(0条)

保存