首页 > 其他分享 >CMS32L051定时器时钟选择

CMS32L051定时器时钟选择

时间:2024-09-18 10:20:10浏览次数:3  
标签:定时器 Ckm TIM InitStruct CMS32L051 Type reg Channel 时钟

文章目录

概要

  1. CMS32L051的定时器搭载两个通用定时器单元,每个单元含有4个通道。每个通用定时器单元有4个16位定时器。各16位定时器称为“通道”,既能分别用作独立的定时器,也能组合多个通道用作高级的定时器功能。
  2. 定时器时钟选择寄存器m(TPSm)是16位寄存器,选择提供给各通道的2种或者4种公共运行时钟(CKm0、CKm1、CKm2、CKm3)。通过TPSm寄存器的bit3~0选择CKm0,通过TPSm寄存器的bit7~4选择CKm1。另外,只有通道1和通道3才能选择CKm2和CKm3,通过TPSm寄存器的bit9~8选择CKm2,通过TPSm寄存器的bit13和bit12选择CKm3。
  3. 官方提供的标准库函数全是使用CKm0作为运行时钟,这将导致使用通一个定时器单元下的通道时,时钟分频必须保持一直,否则将会使用最后一个分频系数,导致时钟错乱。
  4. 修改标准库函数中的定时器初始化,根据分频系数确定选择的运行时钟。
  5. 各通道的寄存器使用或的关系赋值,不能相互影响。

代码

  1. int TIM_Init(TIM_InitTypeDef *TIM_InitStruct)
/**
  * @brief  Initializes the TIEMR peripheral according to the specified
  *         parameters in the TIM_InitStruct .
  * @param  TIM_InitStruct: pointer to a TIM_InitTypeDef structure that contains
  *         the configuration information for the specified TIEMR peripheral.
  * @retval initial result
  */
int TIM_Init(TIM_InitTypeDef *TIM_InitStruct)
{
	int ret = TIM_SUCC;
	uint8_t i=0,j=0;
	uint8_t chanPos =0,chanNum=0,pos=0,currentChan[8]={0};
	uint8_t masterPos =0,masterNum=0,posm=0,currentMChan[4]={0};
	uint16_t Ckm_Type = 0;
	
	assert_param(IS_TIM(TIM_InitStruct->TIM));	
	assert_param(IS_TIM_CHANNEL(TIM_InitStruct->TIM_Channel));
	
	Ckm_Type = TIM_InitStruct->TIM_ClkDivision;
	
	if (Ckm_Type & 0x000f) {
		Ckm_Type = _0000_TM_CLOCK_SELECT_CKM0;
	} else if (Ckm_Type & 0x00f0) {
		Ckm_Type = _8000_TM_CLOCK_SELECT_CKM1;
	} else if (Ckm_Type & 0x0f00) {
		Ckm_Type = _4000_TM_CLOCK_SELECT_CKM2;
	} else if (Ckm_Type & 0xf000) {
		Ckm_Type = _C000_TM_CLOCK_SELECT_CKM3;
	} else if (Ckm_Type == 0){
		Ckm_Type = _0000_TM_CLOCK_SELECT_CKM0;
	}
	
	if(TIM_InitStruct->TIM == TIM40)
	{
		CGC_PER0PeriphClockCmd(CGC_PER0Periph_TIM40,ENABLE);
	}
	else if(TIM_InitStruct->TIM == TIM41)
	{
		CGC_PER0PeriphClockCmd(CGC_PER0Periph_TIM41,ENABLE);		
	}

	Tim_RegSetting(TIM_InitStruct->TIM);
	
#if 0
	*TIM_reg.TPS = TIM_InitStruct->TIM_ClkDivision;	
#else
	*TIM_reg.TPS |= TIM_InitStruct->TIM_ClkDivision;	
#endif
	if(1==IS_TTM_Master_Chan(TIM_InitStruct->TIM_Selection_Master))//multi-tim combination
	{
		for(masterPos = 0; masterPos < 8; masterPos++)
		{
			posm = ((char)0x01) << masterPos;
			masterNum = TIM_InitStruct->TIM_Selection_Master & posm;
			if(masterNum == posm)
			{
				currentMChan[j]=masterPos;
	
				if(masterPos == 0)
				{
					*TIM_reg.TMR[currentMChan[j]] = Ckm_Type | TIM_InitStruct->TIM_Trigger | TIM_InitStruct->TIM_Pulse_Edge | TIM_InitStruct->TIM_Mode | TIM_InitStruct->TIM_StartInt;//								
				}
				else
				{
					*TIM_reg.TMR[masterPos] = Ckm_Type |0x0800|TIM_InitStruct->TIM_Trigger | TIM_InitStruct->TIM_Pulse_Edge | TIM_InitStruct->TIM_Mode | TIM_InitStruct->TIM_StartInt;								
				}
				*TIM_reg.TDR[currentMChan[j]] = TIM_InitStruct->TIM_Period[currentMChan[j]] -1;				 
				*TIM_reg.TO &= ~(1 << masterPos);
				*TIM_reg.TOE &= ~(1 << masterPos);	
				MISC->NFEN1 |=  (1<<currentMChan[j]);	 //后加			
				j++;
			}			
		}
		for(chanPos = 0; chanPos < 8; chanPos++)   //从属通道配置
		{
			pos = ((uint8_t)0x01) << chanPos;
			chanNum = TIM_InitStruct->TIM_Channel & pos;
			if(chanNum == pos)
			{
			  //currentChan[i]=chanPos;
			  //i++;
			    *TIM_reg.TMR[chanPos] = Ckm_Type |TIM_Trigger_UseMaster_Int |TIM_Mode_PWM_Slave| TIM_InitStruct->TIM_Mode |TIM_InitStruct->TIM_StartInt;// | TIM_InitStruct->TIM_Mode 
				*TIM_reg.TDR[chanPos] = TIM_InitStruct->TIM_Period[chanPos];
				*TIM_reg.TO &= ~(1 << chanPos);
				*TIM_reg.TOE |= (1 << chanPos);
				*TIM_reg.TOM |= (1 << chanPos);
				*TIM_reg.TOL &= ~(1 << chanPos);
			}
		}
		*TIM_reg.TS |= TIM_InitStruct->TIM_Channel |TIM_InitStruct->TIM_Selection_Master;   //TIM Start

	}
	else
	{
		for(chanPos = 0; chanPos < 8; chanPos++)
		{
			pos = ((uint8_t)0x01) << chanPos;
			chanNum = TIM_InitStruct->TIM_Channel & pos;
			if(chanNum == pos)
			{
			  currentChan[i]=chanPos;
			  i++;
			}
		}
		if(i == 1)
		{
			*TIM_reg.TDR[currentChan[0]] = TIM_InitStruct->TIM_Period[currentChan[0]] -1;
			*TIM_reg.TT |=  TIM_InitStruct->TIM_Channel;   //TIM stop

			*TIM_reg.TMR[currentChan[0]] = Ckm_Type | TIM_InitStruct->TIM_Trigger | TIM_InitStruct->TIM_Pulse_Edge | TIM_InitStruct->TIM_Mode | TIM_InitStruct->TIM_StartInt;

			*TIM_reg.TO &= ~ TIM_InitStruct->TIM_Channel;
			if(TIM_InitStruct->TIM_Mode == 0x0000)    //tim output
			{
				*TIM_reg.TOE |= TIM_InitStruct->TIM_Channel;
			}
			else   //input event for tim 
			{
				*TIM_reg.TOE &= ~ TIM_InitStruct->TIM_Channel;
				if(TIM_InitStruct->TIM_Mode == TIM_Mode_EventCount)
				{
					*TIM_reg.TMR[currentChan[0]] |= 0x1000;		
				}
				if(TIM_InitStruct->TIM == TIM40)
				{
					 MISC->NFEN1 |=  TIM_InitStruct->TIM_Channel;
				}
				if(TIM_InitStruct->TIM == TIM41)
				{
					 MISC->NFEN2 |=  TIM_InitStruct->TIM_Channel;
				}						
				if((TIM_InitStruct->TIM_Channel == 0x01 || TIM_InitStruct->TIM_Channel == 0x02) && (TIM_InitStruct->TIM == TIM40))
				{
					MISC->TIOS0 |=  TIM_InitStruct->TIM4_Input;
					if(TIM_InitStruct->TIM4_Input)
					{
						MISC->NFEN1 &=  ~(TIM_InitStruct->TIM_Channel);					
					}	
				}		
			}				
			*TIM_reg.TS |=  TIM_InitStruct->TIM_Channel;   //TIM Start
		}
		else
		{
			return TIM_ERR;
		}
	}
	
	return ret;
}

小结

  1. 当配置TIM41_CH1作为PWM输出时,再使用TIM41_CH0作为定时器时,PWM输出会受到影响,因此不能再使用TIM41_CH0,可以使用TIM41_CH2或者TIM41_CH3。

标签:定时器,Ckm,TIM,InitStruct,CMS32L051,Type,reg,Channel,时钟
From: https://blog.csdn.net/wwfsdffinf/article/details/142325537

相关文章

  • 51定时器(1)
                                51定时器定时器/计数器任何一个时刻使用,只能使用其中一种功能51单片机提供的定时器分别为T0、T1(T0定时器四种工作方式都有,而T1仅有模式0与2)启动定时器后,每个机器周期到来,初值寄存器自动加1,直到记满溢出以方式......
  • 51单片机-DS1302(实时时钟+可调时钟)(可参考主页上一节内容介绍)
    作者:王开心时间:2024.9.10目的:手撕51main.c#include<REGX52.H>#include"LCD1602.h"#include"DS1302.h"#include"Key.h"#include"Delay.h"#include"Timer0.h"unsignedcharKeyNum,MODE,TimeSetSelect,TimeS......
  • 必趣CB1核心板、H616主控linux验证IO模拟I2C驱动DS1307时钟芯片
    使用了#include<gpiod.h>内部库作为IO驱动`#ifndef __DS1307_Hdefine__DS1307_HdefineNUM_LEDS21//控制4个GPIO引脚defineCHIPNAME"gpiochip0"//GPIO芯片的名称defineWRITE_CMD 0x00defineREAD_CMD 0x01defineDEV_ADDR0xD0//......
  • stm32 时钟
    1、时钟从时钟源的角度,分为两类外部时钟(E)和内部时钟(I)。从时钟速率的角度,分为两类高速时钟(HS)和低速时钟(LS)。而把它们组合起来就有四种时钟:HSE、HIS、LSE、LSI, LSE一般用于RTC和看门狗,LSE接引脚OSC32_IN、OSC32_OUT,  接32.768kHzHSE一般用于主频,接引脚OSC_OUT、......
  • [linux 驱动]内核定时器详解与实战
    目录1描述2结构体2.1timer_list3相关函数3.1DEFINE_TIMER3.2add_timer3.3del_timer3.4msecs_to_jiffies3.5usecs_to_jiffies5示例4延迟工作队列delayed_work4.1结构体4.1.1delayed_work4.2相关函数4.2.1DECLARE_DELAYED_WORK4.2.2INIT_DELAYE......
  • STM32定时器
    定时器简介定时器,核心就是计数器。STM32的定时器不仅具有基本定时器中断功能,还具备捕获脉冲宽度,PWM输出,互补输出以及编码器计数等功能。F103中共有8个定时器,TIM1-TIM8,不同定时器功能不一样,可分为三类定时器类型主要功能基本定时器TIM6和TIM7,没有输入输出通道,常用作......
  • QT使用定时器事件驱动完成定时播报效果
    widget.h#ifndefWIDGET_H#defineWIDGET_H#include<QWidget>#include<QObject>#include<QPushButton>#include<QLineEdit>#include<QLabel>#include<QTimer>#include<QString>#include<QTime>#include......
  • MySQL主从节点运用chrony实现时钟同步
    在数据库主从复制环境中,保持主从节点之间的时间同步是非常重要的,因为数据库的复制操作通常依赖于时间戳。如果主从节点的时钟不同步,可能会导致复制延迟或者数据不一致的情况。使用chrony来同步主从数据库节点的时钟,确保它们的时间保持一致。主节点安装chronyyuminsta......
  • 从STM32的定时器到Linux上的时间相关服务
    难题:在baremetal上实现按钮点击、长按事件起因是因为我想用stm32加几个按钮只做一个我自己的控制器,我可以通过按钮执行一些功能。硬件是如何和CPU通信的呢?CPU上支出几个GPIO引脚,这些引脚可以配置为输入模式和输出模式,并且都有两种状态——高电平和低电平。硬件连接这些引脚,你编......
  • 硬件基础知识和典型应用-关于STM32休眠唤醒引脚PA0使用说明(PA0问题,PA0一直连接高电
     说明PA0本身是下降沿唤醒,PA0在休眠时不能连接高电平,因为会导致休眠失败!所以在STM32使用PA0做中断唤醒时,学习到的教程全部是外部连接按键进行唤醒,平时PA0悬空,按键按一下PA0接到低电平,然后唤醒单片机; 如何解决(A0本身是下降沿唤醒,PA0在休眠时不能连接高电平,因......