stm32之定时器彻底研究
分类: C/C++
void TIM2_Configuration(void)
{
TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure;
TIM_OCInitTypeDef TIM_OCInitStructure;
u16 CCR1_Val = 4000;
u16 CCR2_Val = 2000;
u16 CCR3_Val = 1000;
u16 CCR4_Val = 500;
/* TIM2 clock enable */
RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2, ENABLE);
TIM_TimeBaseStructure.TIM_Period = 10000; //计满值
TIM_TimeBaseStructure.TIM_Prescaler = 7200-1; //预分频,此值+1为分频的除数
TIM_TimeBaseStructure.TIM_ClockDivision = 0x0; //
TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up; //向上计数
TIM_TimeBaseInit(TIM2, &TIM_TimeBaseStructure);
/* 比较通道1*/
TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_Inactive; //输出比较非主动模式
TIM_OCInitStructure.TIM_Pulse = CCR1_Val;
TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_High; //极性为正
TIM_OC1Init(TIM2, &TIM_OCInitStructure);
TIM_OC1PreloadConfig(TIM2, TIM_OCPreload_Disable); //禁止OC1重装载,其实可以省掉这句,因为默认是4路都不重装的.
/*比较通道2 */
TIM_OCInitStructure.TIM_Pulse = CCR2_Val;
TIM_OC2Init(TIM2, &TIM_OCInitStructure);
TIM_OC2PreloadConfig(TIM2, TIM_OCPreload_Disable);
/* 比较通道3 */
TIM_OCInitStructure.TIM_Pulse = CCR3_Val;
TIM_OC3Init(TIM2, &TIM_OCInitStructure);
TIM_OC3PreloadConfig(TIM2, TIM_OCPreload_Disable);
/* 比较通道4 */
TIM_OCInitStructure.TIM_Pulse = CCR4_Val;
TIM_OC4Init(TIM2, &TIM_OCInitStructure);
TIM_OC4PreloadConfig(TIM2, TIM_OCPreload_Disable);
/*使能预装载*/
TIM_ARRPreloadConfig(TIM2, ENABLE);
/*预先清除所有中断位*/
TIM_ClearITPendingBit(TIM2, TIM_IT_CC1 | TIM_IT_CC2 | TIM_IT_CC3 | TIM_IT_CC4|TIM_IT_Update);
TIM_ITConfig(TIM2, TIM_IT_CC1 | TIM_IT_CC2 | TIM_IT_CC3 | TIM_IT_CC4|TIM_IT_Update, ENABLE);
/* 允许TIM2开始计数 */
TIM_Cmd(TIM2, ENABLE);
}
void TIM3_Configuration(u16 p,u16 psc)
{
RCC->APB1ENR|=1<<1;//TIM3时钟使能
//自动装载寄存器
TIM3->ARR=p; //设定定时器自动重装值
//PSC预分频寄存器
TIM3->PSC=psc; //设定定时器的分频系数
TIM3->DIER|=1<<6; //允许触发中断
TIM3->CR1|=0X01; //使能定时器3(这里面包括计数方向为向上计数)
}
#if 0
void TIM4_Configuration(void)
{
TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure;
TIM_OCInitTypeDef TIM_OCInitStructure;
RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM4, ENABLE);
/* 基础设置*/
TIM_TimeBaseStructure.TIM_Period = 10000; //计满值
TIM_TimeBaseStructure.TIM_Prescaler = 7200-1; //预分频,此值+1为分频的除数
TIM_TimeBaseStructure.TIM_ClockDivision = 0x0; //
TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up; //向上计数
TIM_TimeBaseInit(TIM4, &TIM_TimeBaseStructure);
/*使能预装载*/
TIM_ARRPreloadConfig(TIM4, ENABLE);
/*预先清除所有中断位*/
TIM_ClearITPendingBit(TIM4, TIM_IT_Update);
TIM_ITConfig(TIM4, TIM_IT_Update, ENABLE);
/* 允许TIM2开始计数 */
TIM_Cmd(TIM4, ENABLE);
}
#else
void TIM_Configuration(u16 p,u16 psc)
{
RCC->APB1ENR|=1<<2;//TIM4时钟使能
//自动装载寄存器
TIM4->ARR=p; //设定定时器自动重装值
//PSC预分频寄存器
TIM4->PSC=psc; //设定定时器的分频系数
TIM4->DIER|=1<<6; //允许触发中断
TIM4->CR1|=0X01; //使能定时器3(这里面包括计数方向为向上计数)
}
#endif
* Function Name : TIM2_IRQHandler TIM2中断
* Description : This function handles TIM2 global interrupt request.
* Input : None
* Output : None
* Return : None
*******************************************************************************/
unsigned int flag=0;
void TIM2_IRQHandler(void)
{
if (TIM_GetITStatus(TIM2, TIM_IT_CC1) != RESET)
{
/*必须清空标志位*/
TIM_ClearITPendingBit(TIM2, TIM_IT_CC1);
//可添加功能块......
}
else if (TIM_GetITStatus(TIM2, TIM_IT_CC2) != RESET)
{
TIM_ClearITPendingBit(TIM2, TIM_IT_CC2);
//可添加功能块......
}
else if (TIM_GetITStatus(TIM2, TIM_IT_CC3) != RESET)
{
TIM_ClearITPendingBit(TIM2, TIM_IT_CC3);
//可添加功能块......
}
else if (TIM_GetITStatus(TIM2, TIM_IT_CC4) != RESET)
{
TIM_ClearITPendingBit(TIM2, TIM_IT_CC4);
//可添加功能块......
}
if (TIM_GetITStatus(TIM2, TIM_IT_Update) != RESET)
{
TIM_ClearITPendingBit(TIM2, TIM_IT_Update);
//flag=1;//计时满标志位置位
//cnt++;//每TIM_Period计时满变量加一
}
}
* Function Name : TIM3_IRQHandler
* Description : This function handles TIM3 global interrupt request.
* Input : None
* Output : None
* Return : None
*******************************************************************************/
void TIM3_IRQHandler(void)
{
if(TIM3->SR&0X0001)
{
cnt++;
flag=1;
}
TIM3->SR&=~(1<<0);
}
* Function Name : TIM4_IRQHandler
* Description : This function handles TIM4 global interrupt request.
* Input : None
* Output : None
* Return : None
*******************************************************************************/
void TIM4_IRQHandler(void)
{
if(TIM_GetITStatus(TIM4, TIM_IT_Update) != RESET)
{
TIM_ClearITPendingBit(TIM4, TIM_IT_Update);
cnt++;
flag=1;
}
}
//设置所有的中断允许
{
NVIC_InitTypeDef NVIC_InitStructure;
NVIC_PriorityGroupConfig(NVIC_PriorityGroup_4);
NVIC_InitStructure.NVIC_IRQChannel = TIM2_IRQn;
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 4;
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
NVIC_Init(&NVIC_InitStructure);
#if 1
/* Configure one bit for preemption priority */
/* Timer3中断*/
NVIC_InitStructure.NVIC_IRQChannel = TIM3_IRQn;
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 3;
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
NVIC_Init(&NVIC_InitStructure);
NVIC_InitStructure.NVIC_IRQChannel = TIM4_IRQn;
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 2;
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
NVIC_Init(&NVIC_InitStructure);
NVIC_InitStructure.NVIC_IRQChannel = USART1_IRQn;
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1;
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
NVIC_Init(&NVIC_InitStructure);
}
#include "hal.h"
#include "stdio.h"
#include "string.h"
extern unsigned int cnt;
extern unsigned int flag;
{
//USART_SendData(USART1, (u8) ch);
USART1->DR = (u8) ch;
/* Loop until the end of transmission */
while(USART_GetFlagStatus(USART1, USART_FLAG_TXE) == RESET)
{
}
return ch;
}
{
CanTxMsg msg;
msg.StdId=0x11;
msg.DLC=8;
msg.IDE=CAN_ID_STD;
msg.RTR=CAN_RTR_DATA;
memset(msg.Data,0x11,8);
ChipHalInit(); //片内硬件初始化
ChipOutHalInit(); //片外硬件初始化
for(;;)
{
can_send(&msg);
if(flag)
{
flag=0;
printf("cnt is %d\n",cnt);
}
}
}
#include "hal.h"
#include <string.h>
void CAN_Configuration(void)
{
GPIO_InitTypeDef GPIO_InitStructure;
//RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA | RCC_APB2Periph_AFIO,ENABLE);
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);
/* PA11-CAN RX */
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_11;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU;
GPIO_Init(GPIOA, &GPIO_InitStructure);
/*PA12-CAN TX */
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_12;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
GPIO_Init(GPIOA, &GPIO_InitStructure);
RCC_APB1PeriphClockCmd(RCC_APB1Periph_CAN1, ENABLE);
// RCC_APB1PeriphClockCmd(RCC_APB1Periph_CAN1, ENABLE);
}
/*******************************************************************************
**CAN中断测试
*******************************************************************************/
void CAN_Interrupt(void)
{
CAN_InitTypeDef CAN_InitStructure;
CAN_FilterInitTypeDef CAN_FilterInitStructure;
// CanTxMsg TxMessage;
/* CAN register init */
CAN_DeInit(CAN1);
CAN_StructInit(&CAN_InitStructure);
/* CAN cell init */
/* CAN cell init */
CAN_InitStructure.CAN_TTCM=DISABLE; //时间触发
CAN_InitStructure.CAN_ABOM=DISABLE; //自动离线管理
CAN_InitStructure.CAN_AWUM=DISABLE; //自动唤醒
CAN_InitStructure.CAN_NART=DISABLE; //ENABLE:错误不自动重传 DISABLE:重传
CAN_InitStructure.CAN_RFLM=DISABLE;
CAN_InitStructure.CAN_TXFP=DISABLE;
CAN_InitStructure.CAN_Mode=CAN_Mode_Normal; //CAN_Mode_LoopBack,CAN_Mode_Normal
CAN_InitStructure.CAN_SJW=CAN_SJW_1tq; //1-4
CAN_InitStructure.CAN_BS1=CAN_BS1_5tq; //1-16
CAN_InitStructure.CAN_BS2=CAN_BS2_3tq; //1-8
CAN_InitStructure.CAN_Prescaler=4; //波特率为 36/(4*(1+5+3))=1000k
CAN_Init(CAN1,&CAN_InitStructure);
/* CAN 过滤器设置 */
CAN_FilterInitStructure.CAN_FilterNumber=0;
CAN_FilterInitStructure.CAN_FilterMode=CAN_FilterMode_IdMask;
CAN_FilterInitStructure.CAN_FilterScale=CAN_FilterScale_32bit;
CAN_FilterInitStructure.CAN_FilterIdHigh=0x0000;
CAN_FilterInitStructure.CAN_FilterIdLow=0x0000;
CAN_FilterInitStructure.CAN_FilterMaskIdHigh=0x0000;
CAN_FilterInitStructure.CAN_FilterMaskIdLow=0x0000;
CAN_FilterInitStructure.CAN_FilterFIFOAssignment=CAN_FIFO0;
CAN_FilterInitStructure.CAN_FilterActivation=ENABLE;
CAN_FilterInit(&CAN_FilterInitStructure);
/* 允许FMP0中断*/
CAN_ITConfig(CAN1,CAN_IT_FMP0, ENABLE);
}/*
typedef struct
{
uint32_t StdId;
uint32_t ExtId;
uint8_t IDE;
uint8_t RTR;
uint8_t DLC;
uint8_t Data[8];
} CanTxMsg;
*/
//发送一个2字节的数据
void SendCan(u16 dat)
{
CanTxMsg TxMessage;
TxMessage.ExtId=0x01;
TxMessage.IDE=CAN_ID_EXT;
TxMessage.RTR=CAN_RTR_DATA;
TxMessage.DLC=2;
TxMessage.Data[0]=dat&0xff;
TxMessage.Data[1]=dat>>8;
CAN_Transmit(CAN1,&TxMessage);
}
#if 1
int can_send(CanTxMsg *pTransmitBuf)
{
u8 TransmitMailbox=0;
CanTxMsg TxMessage;
if(pTransmitBuf -> DLC > 8)
{
return 1;
}
/* transmit */
TxMessage.StdId=pTransmitBuf ->StdId;//用来设定标准标识符(0-0x7ff,11位)
//TxMessage.ExtId=pTransmitBuf ->ExtId;
TxMessage.RTR= pTransmitBuf ->RTR;//设置RTR位为数据帧
TxMessage.IDE= pTransmitBuf ->IDE;//标识符扩展位,为标准帧
TxMessage.DLC= pTransmitBuf ->DLC;//设置数据长度
//根据DLC字段的值,将有效数据拷贝到发送数据寄存器
memcpy(TxMessage.Data, pTransmitBuf ->Data,pTransmitBuf ->DLC);
TransmitMailbox = CAN_Transmit(CAN1,&TxMessage);
TransmitMailbox=TransmitMailbox;//加上这句话就是防止编译器产生警告
return 1;
}
#endif
**HAL.c
**主要用于芯片硬件的内部外围和外部外围的初始化,两大INIT函数
**在MAIN中调用,使MAIN函数中尽量与硬件库无关
***************************************************/
//STM32F103RBT6有三个通用定时器,定时器2、3、4;操作基本一致
#include "STM32Lib\\stm32f10x.h"
//各个内部硬件模块的配置函数
extern void GPIO_Configuration(void); //GPIO
extern void RCC_Configuration(void); //RCC
extern void USART_Configuration(void); //串口
extern void NVIC_Configuration(void); //NVIC
extern void TIM3_Configuration(u16 p,u16 psc);
extern void TIM4_Configuration(void);
extern void TIM_Configuration(u16 p,u16 psc);
extern void CAN_Interrupt(void);
**函数名:ChipHalInit()
**功能:片内硬件初始化
*******************************/
void ChipHalInit(void)
{
//初始化时钟源
RCC_Configuration();
//初始化GPIO
GPIO_Configuration();
//初始化中断源
NVIC_Configuration();
USART_Configuration();
//初始化定时器
//TIM2_Configuration();
//
//TIM3_Configuration(10000,7199);
//TIM4_Configuration();
TIM_Configuration(10000,7199);
//初始化CAN总线
CAN_Configuration();
//初始化CAN总线接收中断
CAN_Interrupt();
**函数名:ChipOutHalInit()
**功能:片外硬件初始化
*********************************/
void ChipOutHalInit(void)
{
}
stm32之定时器彻底研究的更多相关文章
- STM32——通用定时器基本定时功能
STM32——————通用定时器基本定时功能 1. ...
- STM32通用定时器(转载)
STM32的定时器功能很强大,学习起来也很费劲儿. 其实手册讲的还是挺全面的,只是无奈TIMER的功能太复杂,所以显得手册很难懂,我就是通过这样看手册:while(!SUCCESS){看手册-}才搞明 ...
- Stm32高级定时器(四)
Stm32高级定时器(四) 1 编码器接口模式 1.1 编码器原理 什么是正交?如果两个信号相位相差90度,则这两个信号称为正交.由于两个信号相差90度,因此可以根据两个信号哪个先哪个后来判断方向.根 ...
- Stm32高级定时器(三)
Stm32高级定时器(三) 1 互补输出和死区插入 1.1 死区:某个处于相对无效状态的时间或空间 本来OCX信号与OCXREF时序同相同步,OCXN信号与OCXREF时序反相同步.但为了安全考虑,以 ...
- Stm32高级定时器(二)
Stm32高级定时器(二) 1 主从模式:主?从? 谈论主从,可知至少有两个以上的触发或者驱动信号,stm32内部有多个定时器,可以相互之间驱动或者控制. 主模式:定时器使能只受驱动时钟控制或者输出控 ...
- Stm32高级定时器(一)
Stm32高级定时器(一) 1 定时器的用途 2 高级定时器框图 3 时基单元 4 通道 1 定时器的用途 已知一个波形求另一个未知波形(信号长度和占空比) 已知波形的信号长度和占空比产生一个相应的波 ...
- STM32普通定时器(TIM2-7)的时钟源
STM32普通定时器(TIM2-7)的时钟源
- STM32 基于定时器的PWM发生器
脉冲宽度调制(PWM),是英文"Pulse Width Modulation" 的缩写,简称脉宽调制,是利用微处理器的数字输出来对模拟电路进行控制的一种非常有效的技术.简单一点,就 ...
- STM32通用定时器原理
/************************************************************************************************ 转载 ...
随机推荐
- Fist—— 团队展示
作业要求 软件工程1班 团队名称 Fist 这个作业的目标 团队合作开发项目,加强团队合作,进一步了解相应岗位. 作业正文 https://www.cnblogs.com/team4/p/137730 ...
- Python中数字按位取反的方法
老猿Python博文目录 专栏:使用PyQt开发图形界面Python应用 老猿Python博客地址 Python中有个按位取反运算符:,但这个运算符并不是真正的按位取反,而是效果相当于原值乘以负一再减 ...
- 推荐系统实践 0x0c FM系列
逻辑回归(LR) 在介绍FM系列之前,我想首先简单介绍一下逻辑回归.通常来说,逻辑回归模型能够综合利用更多的信息,如用户.物品.上下文等多种不同的特征,生成更为全面的结果.另外,逻辑回归将推荐问题看成 ...
- 赶紧收藏!王者级别的Java多线程技术笔记,我java小菜鸡愿奉你为地表最强!
Java多线程技术概述 介绍多线程之前要介绍线程,介绍线程则离不开进程. 首先 , 进程 :是一个正在执行中的程序,每一个进程执行都有一个执行顺序,该顺序是一个执行路径,或者叫一个控制单元: 线程:就 ...
- 算法——和为K的连续子数组
给定一个整数数组和一个整数 k,你需要找到该数组中和为 k 的连续的子数组的个数. 输入:nums = [1,1,1], k = 2 输出: 2 , [1,1] 与 [1,1] 为两种不同的情况. 链 ...
- js实现转盘抽奖
大转盘抽奖,主要通过css3的"transform:rotate(0deg)"属性来控制元素的旋转角度来实现. 通常,抽奖的过程需要渐进的效果,所以直接通过旋转属性写比较繁琐. 这 ...
- Spring Boot 启动事件和监听器,太强大了!
大家都知道,在 Spring 框架中事件和监听无处不在,打通了 Spring 框架的任督二脉,事件和监听也是 Spring 框架必学的核心知识之一. 一般来说,我们很少会使用到应用程序事件,但我们也不 ...
- Object.assign 之后 点对象 找不到
export function CopyObject(val) { return JSON.parse(JSON.stringify(val)); }
- ss命令结合zabbix对socket做监控
本文为博客园作者所写: 一寸HUI,个人博客地址:https://www.cnblogs.com/zsql/ 最近天冷了,socket也出问题了,一直没有做监控,现在就把监控加起来,目前我们使用的有z ...
- Maven笔记之核心概念及常用命令
Maven的核心概念 Maven是一款服务于java平台的自动化构建工具. 自动化构建工具还有:make->ant->maven->gradle 1.约定的目录 2.P ...