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通用定时器原理
/************************************************************************************************ 转载 ...
随机推荐
- JZOJ2020年8月11日提高组T3 页
JZOJ2020年8月11日提高组T3 页 题目 Description 战神阿瑞斯听说2008年在中华大地上,将举行一届规模盛大的奥林匹克运动会,心中顿觉异常兴奋,他想让天马在广阔的天空上,举行一场 ...
- Abp(net core)+easyui+efcore实现仓储管理系统——出库管理之七(五十六)
abp(net core)+easyui+efcore实现仓储管理系统目录 abp(net core)+easyui+efcore实现仓储管理系统--ABP总体介绍(一) abp(net core)+ ...
- 第3.2节 Python列表简介
鉴于Python中列表(list)的强大功能,本节及后面至少有一节都是介绍列表相关的知识,本节先介绍基本的列表知识. 一. 列表的定义 列表是一种可以修改的序列,它有点类似于c语言中的数组,在Pyth ...
- moviepy音视频剪辑:视频剪辑基类VideoClip详解
☞ ░ 前往老猿Python博文目录 ░ 一.概述 在<moviepy音视频剪辑:moviepy中的剪辑基类Clip详解>和<moviepy音视频剪辑:moviepy中的剪辑基类Cl ...
- 第11.25节 Python正则表达式编译re.compile及正则对象使用
一. 引言 在<第11.2节 Python 正则表达式支持函数概览>介绍了re模块的主要函数,在<第11.3节 Python正则表达式搜索支持函数search.match.fullm ...
- PyQt(Python+Qt)学习随笔:实现toolButton与Action的关联
在Qt Designer中,如果创建的窗口为主窗口QMainWindow类型,可以通过<PyQt(Python+Qt)学习随笔:Qt Designer中怎么给toolBar添加按钮 >介绍 ...
- PHP代码审计分段讲解(5)
11 sql闭合绕过 源代码为 <?php if($_POST[user] && $_POST[pass]) { $conn = mysql_connect("**** ...
- PHP中双引号引起的命令执行漏洞(Kuwebs代码审计 )
在代码审计一书中提到Kuwebs的配置文件中可以利用PHP可变变量的特性执行代码 在PHP语言中,单引号和双引号都可以表示一个字符串,但是对于双引号来说,可能会对引号内的内容进行二次解释,这就可能会出 ...
- 总结下flask中的宏、Jinjia2语法
这几天学的东西比较多,时间又有点不够用,趁着快吃饭了,赶紧总结总结. 00x1 宏: 如果学过C语言的童鞋,可能知道宏在C语言里面是一个定义一个固定参数的变量.在flask里面,宏是相当于一个函数的作 ...
- 你知道Python基本数据类型是哪6个么
Python 是强类型语言,在学习 Python 时,有必要了解 Python 有哪些基本数据类型,一共 6 个:Number(数字).String(字符串).List(列表).Tuple(元组).S ...