#include
#include "system.h"
#include "tim.h"
void Gpio_Init(void);
int main(void)
{
u32 var=0,flag=0;
Rcc_Init(9); //系统时钟设置
// 相关TIM_x,CCR_x参数定义tim.h文件
Tim_Init(TIM_3,900,0); //初始化TIM3定时器,设定重装值和分频值
Tim_OC_Set(TIM_3,OC_2,7); //设定TIM3 通道1为PWM输出模式
Gpio_Init();
while(1){
delay(5000); //延时5ms
if(flag){
var--;
}else{
var++;
}
if(var>300) flag = 1;
if(var == 0) flag = 0;
Tim_CCR_Set(TIM_3,OC_2,var);
}
}
void Gpio_Init(void)
{
RCC->APB2ENR|=1<<2; //使能PORTA时钟
GPIOA->CRL&=0X0FFFFFFF;//PA7输出
GPIOA->CRL|=0XB0000000;//复用功能输出
}
#include
#include "tim.h"
//通用定时器初始化
//参数说明:TIM_x 为选择定时器 TIM_1为通用寄存器1又一次类推(定义于tim.h), arr为自动重装值 ;psc 为时钟预分频数
//要使用定时器的其他函数,必须先调用此函数,因为时钟在这个函数中开启
//TIM3用于PWM输出已测试
//待完善 目前只支持TIM2
//其他定时器只做了开启时钟处理
void Tim_Init(u8 TIM_x,u16 arr,u16 psc)
{
switch(TIM_x)
{
case 1 :{ RCC->APB2ENR |=1<<11; break; } //TIM1高级定时器设置
case 2 :{ //TIM2通用定时器设置
RCC->APB1ENR |=1<<0;
TIM2->ARR = arr; //设定自动重装值
TIM2->PSC = psc; //设定预分频值
TIM2->DIER |= 1<<0; //允许更新中断
TIM2->DIER |= 1<<6; //允许触发中断
TIM2->CR1 |= 0x81; //使能定时器,自动重装允许
break;
}
case 3 :{
RCC->APB1ENR |=1<<1;
TIM3->ARR = arr; //设定自动重装值
TIM3->PSC = psc; //设定预分频值
//TIM3->DIER |= 1<<0; //允许更新中断
//TIM3->DIER |= 1<<6; //允许触发中断
TIM3->CR1 |= 0x81; //使能定时器
break;
}
case 4 :{
RCC->APB1ENR |=1<<2;
TIM4->ARR = arr; //设定自动重装值
TIM4->PSC = psc; //设定预分频值
TIM4->DIER |= 1<<0; //允许更新中断
TIM4->DIER |= 1<<6; //允许触发中断
TIM4->CR1 |= 0x01; //使能定时器
break;
}
case 5 :{
RCC->APB1ENR |=1<<3;
TIM5->ARR = arr; //设定自动重装值
TIM5->PSC = psc; //设定预分频值
TIM5->DIER |= 1<<0; //允许更新中断
TIM5->DIER |= 1<<6; //允许触发中断
TIM5->CR1 |= 0x01; //使能定时器
break;
}
case 6 :{ RCC->APB1ENR |=1<<4; break; }
case 7 :{ RCC->APB1ENR |=1<<5; break; }
case 8 :{ RCC->APB2ENR |=1<<13; break; }
}
}
//捕获比较值设定函数
//参数说明:
// TIM_x 为选择定时器 TIM_1为通用寄存器1又一次类推(定义于tim.h)
// OC_x 为选择通道,以确定捕获/比较寄存器(1~4)(定义于tim.h)
// val 为要设定的捕获/比较寄存器的值
// TIM3,OC_2 用于PWM输出已测试
// 待完善,目前只支持TIM2
void Tim_CCR_Set(u8 TIM_x,u8 OC_x,u32 val)
{
switch(TIM_x)
{
case 1 :{ break;}
case 2 :{
TIM2->DIER |= 1 << OC_x; //开启相应允许捕获/比较中断
switch(OC_x){
case 1: {
TIM2 ->CCR1 = val; //设置捕获/比较1的值
break;
}
case 2: {
TIM2 ->CCR2 = val; //设置捕获/比较2的值
break;
}
case 3: {
TIM2 ->CCR3 = val; //设置捕获/比较3的值
break;
}
case 4: {
TIM2 ->CCR4 = val; //设置捕获/比较4的值
break;
}
}
break;
}
case 3 :{
//TIM3->DIER |= 1 << OC_x; //开启相应允许捕获/比较中断
switch(OC_x){
case 1: {
TIM3 ->CCR1 = val; //设置捕获/比较1的值
break;
}
case 2: {
TIM3 ->CCR2 = val; //设置捕获/比较2的值
break;
}
case 3: {
TIM3 ->CCR3 = val; //设置捕获/比较3的值
break;
}
case 4: {
TIM3 ->CCR4 = val; //设置捕获/比较4的值
break;
}
}
break;
}
case 4 :{ break;}
case 5 :{ break;}
case 6 :{ break;}
case 7 :{ break;}
case 8 :{ break;}
}
}
//定时器通道引脚输出模式设定函数
//参数说明:
// TIM_x 为选择定时器 TIM_1为通用寄存器1又一次类推(定义于tim.h)
// OC_x 为选择输出通道选择(1~4)(定义于tim.h)
// Mode 为选择通道对应引脚输出模式(0~7)
// TIM3,OC_2 用于PWM输出已测试
// 待完善,目前只支持TIM2
void Tim_OC_Set(u8 TIM_x,u8 OC_x,u8 Mode)
{
switch(TIM_x)
{
case 1 :{ break;}
case 2 :{
switch(OC_x){
case 1: {
TIM2 ->CCMR1 |= Mode <<4; //设定引脚输出模式
TIM2 ->CCMR1 |= 1<<3; //允许预装载
//TIM2 ->CCER |= 1<<2; //引脚输出低电平为有效
TIM2 ->CCER |= 1<<0; //OC1 输出使能
break;
}
case 2: {
TIM2 ->CCMR1 |= Mode <<12; //设定引脚输出模式
TIM2 ->CCMR1 |= 1<<11; //允许预装载
//TIM2 ->CCER |= 1<<5; //引脚输出低电平为有效
TIM2 ->CCER |= 1<<4; //OC2 输出使能
break;
}
case 3: {
TIM2 ->CCMR2 |= Mode <<4; //设定引脚输出模式
TIM2 ->CCMR2 |= 1<<3; //允许预装载
//TIM2 ->CCER |= 1<<9; //引脚输出低电平为有效
TIM2 ->CCER |= 1<<8; //OC3 输出使能
break;
}
case 4: {
TIM2 ->CCMR2 |= Mode <<12; //设定引脚输出模式
TIM2 ->CCMR2 |= 1<<11; //允许预装载
//TIM2 ->CCER |= 1<<5; //引脚输出低电平为有效
TIM2 ->CCER |= 1<<4; //OC1 输出使能
break;
}
}
break;
}
case 3 :{
switch(OC_x){
case 1: {
TIM3 ->CCMR1 |= Mode <<4; //设定引脚输出模式
TIM3 ->CCMR1 |= 1<<3; //允许预装载
//TIM3 ->CCER |= 1<<2; //引脚输出低电平为有效
TIM3 ->CCER |= 1<<0; //OC1 输出使能
break;
}
case 2: {
TIM3 ->CCMR1 |= Mode <<12; //设定引脚输出模式
TIM3 ->CCMR1 |= 1<<11; //允许预装载
TIM3 ->CCER |= 1<<5; //引脚输出低电平为有效
TIM3 ->CCER |= 1<<4; //OC2 输出使能
break;
}
case 3: {
TIM3 ->CCMR2 |= Mode <<4; //设定引脚输出模式
TIM3 ->CCMR2 |= 1<<3; //允许预装载
//TIM3 ->CCER |= 1<<9; //引脚输出低电平为有效
TIM3 ->CCER |= 1<<8; //OC3 输出使能
break;
}
case 4: {
TIM3 ->CCMR2 |= Mode <<12; //设定引脚输出模式
TIM3 ->CCMR2 |= 1<<11; //允许预装载
//TIM3 ->CCER |= 1<<5; //引脚输出低电平为有效
TIM3 ->CCER |= 1<<4; //OC1 输出使能
break;
}
}
break;
}
case 4 :{ break;}
case 5 :{ break;}
case 6 :{ break;}
case 7 :{ break;}
case 8 :{ break;}
}
}
#include
#define TIM_1 0x01
#define TIM_2 0x02
#define TIM_3 0x03
#define TIM_4 0x04
#define TIM_5 0x05
#define TIM_6 0x06
#define TIM_7 0x07
#define TIM_8 0x08
#define OC_1 0x01
#define OC_2 0x02
#define OC_3 0x03
#define OC_4 0x04
void Tim_Init(u8 TIM_x,u16 arr,u16 psc);
void Tim_CCR_Set(u8 TIM_x,u8 OC_x,u32 val);
void Tim_OC_Set(u8 TIM_x,u8 OC_x,u8 Mode);
#include "stm32f10x.h"
vu16 CCR1_Val = 60000;
vu16 CCR2_Val = 30000;
vu16 CCR3_Val = 15000;
vu16 CCR4_Val = 7500;
void RCC_Configuration(void);
void GPIO_Configuration(void);
void TIM_Configuration(void);
int main(void)
{
RCC_Configuration();
GPIO_Configuration();
TIM_Configuration();
while(1);
}
void TIM_Configuration(void)
{
TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure;
TIM_OCInitTypeDef TIM_OCInitStructure;
TIM_TimeBaseStructure.TIM_Period = 65535;
TIM_TimeBaseStructure.TIM_Prescaler = 7199;
TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;
TIM_TimeBaseInit(TIM2,&TIM_TimeBaseStructure);
//TIM_PrescalerConfig(TIM2,7199,TIM_PSCReloadMode_Immediate);
TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM1;
TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable; //使能TIM输出
TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_High;
TIM_OCInitStructure.TIM_Pulse = CCR1_Val;
TIM_OC1Init(TIM2,&TIM_OCInitStructure);
TIM_OCInitStructure.TIM_Pulse = CCR2_Val;
TIM_OC2Init(TIM2,&TIM_OCInitStructure);
TIM_OCInitStructure.TIM_Pulse = CCR3_Val;
TIM_OC3Init(TIM2,&TIM_OCInitStructure);
TIM_OCInitStructure.TIM_Pulse = CCR4_Val;
TIM_OC4Init(TIM2,&TIM_OCInitStructure);
TIM_OC1PreloadConfig(TIM2,TIM_OCPreload_Enable);
TIM_OC2PreloadConfig(TIM2,TIM_OCPreload_Enable);
TIM_OC3PreloadConfig(TIM2,TIM_OCPreload_Enable);
TIM_OC4PreloadConfig(TIM2,TIM_OCPreload_Enable);
//TIM_ITConfig(TIM2,TIM_IT_CC1|TIM_IT_CC2|TIM_IT_CC3|TIM_IT_CC4,ENABLE);
TIM_Cmd(TIM2,ENABLE);
}
void GPIO_Configuration(void)
{
GPIO_InitTypeDef GPIO_InitStructure;
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0 | GPIO_Pin_1 | GPIO_Pin_2 | GPIO_Pin_3;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP; //设置为复用推挽
GPIO_Init(GPIOA , &GPIO_InitStructure);
}
void RCC_Configuration(void)
{
/* 定义枚举类型变量 HSEStartUpStatus */
ErrorStatus HSEStartUpStatus;
/* 复位系统时钟设置*/
RCC_DeInit();
/* 开启HSE*/
RCC_HSEConfig(RCC_HSE_ON);
/* 等待HSE起振并稳定*/
HSEStartUpStatus = RCC_WaitForHSEStartUp();
/* 判断HSE起是否振成功,是则进入if()内部 */
if(HSEStartUpStatus == SUCCESS)
{
/* 选择HCLK(AHB)时钟源为SYSCLK 1分频 */
RCC_HCLKConfig(RCC_SYSCLK_Div1);
/* 选择PCLK2时钟源为 HCLK(AHB) 1分频 */
RCC_PCLK2Config(RCC_HCLK_Div1);
/* 选择PCLK1时钟源为 HCLK(AHB) 2分频 */
RCC_PCLK1Config(RCC_HCLK_Div2);
/* 设置FLASH延时周期数为2 */
FLASH_SetLatency(FLASH_Latency_2);
/* 使能FLASH预取缓存 */
FLASH_PrefetchBufferCmd(FLASH_PrefetchBuffer_Enable);
/* 选择锁相环(PLL)时钟源为HSE 1分频,倍频数为9,则PLL输出频率为 8MHz * 9 = 72MHz */
RCC_PLLConfig(RCC_PLLSource_HSE_Div1, RCC_PLLMul_9);
/* 使能PLL */
RCC_PLLCmd(ENABLE);
/* 等待PLL输出稳定 */
while(RCC_GetFlagStatus(RCC_FLAG_PLLRDY) == RESET);
/* 选择SYSCLK时钟源为PLL */
RCC_SYSCLKConfig(RCC_SYSCLKSource_PLLCLK);
/* 等待PLL成为SYSCLK时钟源 */
while(RCC_GetSYSCLKSource() != 0x08);
}
/* 打开APB2总线上的GPIOA时钟*/
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA , ENABLE);
RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2 , ENABLE);
}