微波EDA网,见证研发工程师的成长!
首页 > 硬件设计 > 嵌入式设计 > STM32单片机简易定时器PWM输出

STM32单片机简易定时器PWM输出

时间:11-30 来源:互联网 点击:
由于RCC->CFGR时钟配置寄存器中 APB1设置为2分频,所以TIM3就是其倍频==72M


上次我发表的STM32单片机自带PWM输出实验大家可以参考学习:http://www.51hei.com/mcu/2123.html,这次是用定时器产生的pwm.

//----------------------------------定时器-----------time.c-----------
#include "time.h"

void time_init(u16 arr,u16 psc)

{

RCC->APB1ENR|=1<1; //TIM2定时器时钟使能

TIM3->ARR=arr; //设置重装载值

TIM3->PSC=psc; //设置分配系数

TIM3->DIER|=1<0; //允许更新

TIM3->DIER|=1<6; //触发中断使能

TIM3->CR1|=1<0; //使能定时器2

MY_NVIC_Init(2,2,TIM3_IRQChannel,2); //设置定时器2中断类别

}

//----------------time.h--------------

#ifndef _time_h

#define _time_h

#include "sys.h"

void time_init(u16 arr,u16 psc);

#endif
//----------------------按键-----key.c------------

#include "key.h"

void key_init(void)

{

RCC->APB2ENR|=1<2; //PORTA时钟使能

GPIOA->CRH&=0x0f0fffff;

GPIOA->CRH|=0x80800000; //设置为输入

GPIOA->ODR|=1<15;

GPIOA->ODR|=1<13;

}

//-------------------key.h----------------

#ifndef _key_h

#define _key_h

#include "sys.h"

#define key1 PAin(13)

#define key2 PAin(15)

void key_init(void);

#endif

//-------------------LED---------led.c-------------

#include "led.h"

void led_init(void)

{

RCC->APB2ENR|=1<2;

RCC->APB2ENR|=1<5; //使能PORTD时钟

GPIOA->CRH&=0xfffffff0;

GPIOA->CRH|=0x00000003; //PA8推挽输出

GPIOD->CRL&=0xfffff0ff;

GPIOD->CRL|=0x00000300; //PD2推挽输出

GPIOA->ODR|=1<8;

GPIOD->ODR|=1<2;

}

//------------------led.h---------------------
#ifndef _led_h

#define _led_h

#include "sys.h"

#define LED0 PAout(8)

#define LED1 PDout(2)


void led_init(void);

#endif

//------------------------主函数-----------test.c-----------

#include

#include "sys.h"

#include "delay.h"

#include "usart.h"

#include "led.h"

#include "key.h"

#include "time.h"

char pwm; //pwm增减量

char cnt; //pwm时间变量

//-----------------------pwm增量按键----------------

void key1_scan()

{

static u8 i,j;

if(key1==0)

{

if(i==0)

{

j++;

if(j>3)

{

i=1;j=0;

pwm+=5;

if(pwm>100)pwm=0;

}

}

}

else

{

i=j=0;

}

}

//--------------------pwm减量按键--------------------

void key2_scan()

{

static u8 i,j;

if(key2==0)

{

if(i==0)

{

j++;

if(j>3)

{

i=1;j=0;

pwm-=5;

if(pwm<10)pwm=0;

}

}

}

else

{

i=j=0;

}

}

void TIM3_IRQHandler(void) //定时器2中断函数

{

if(TIM3->SR&0x0001)

{

cnt++;

if(cnt>100)cnt=0;

if(cnt>pwm) //LED0作为pwm 输出指示

{

LED0=0;

}

else

{

LED0=1;

}

}

TIM3->SR&=~(1<0); //清除中断标志位

}

int main(void)

{

u16 i,t;

Stm32_Clock_Init(9);

delay_init(72);

uart_init(72,9600);

led_init();

key_init();

time_init(3600,1); //产生10K频率 pwm只是~~100HZ 由于100分频

while(1)

{

key1_scan();

key2_scan();

t++;

if(t>60000)

{

i++;

if(i>11)

{

LED1=!LED1; //系统运行指示约1秒闪烁一次

i=0;

}

t=0;

}

}

}

//--------------------------------关于定时器溢出时间计算--------------------------

1)TIM3时钟使能。

这里我们通过APB1ENR的第1位来设置TIM3的时钟,因为Stm32_Clock_Init函数里面把APB1的分频设置为2了,所以我们的TIM3时钟就是APB1时钟的2被,等于系统时钟。(72M)

Tout= (arr*(psc+1))/Tclk;

其中:

Tclk:TIM3的输入时钟频率(单位为Khz)。

Tout:TIM3溢出时间(单位为ms)。

Tout=(3600*(1+1))/72M=0.1ms

//------------------------------系统时钟初始化函数对于定时器TIM3时钟简易分析-----------------

void Stm32_Clock_Init(u8 PLL)

{

unsigned char temp=0;

MYRCC_DeInit(); //复位并配置向量表

RCC->CR|=0x00010000; //外部高速时钟使能HSEON

while(!(RCC->CR>>17));//等待外部时钟就绪

RCC->CFGR=0X00000400; //APB1=div2;APB2=div1;AHB=div1;

PLL-=2;//抵消2个单位

RCC->CFGR|=PLL<18; //设置PLL值 2~16

RCC->CFGR|=1<16; //PLLSRC ON

FLASH->ACR|=0x32; //FLASH 2个延时周期

RCC->CR|=0x01000000; //PLLON

while(!(RCC->CR>>25));//等待PLL锁定

RCC->CFGR|=0x00000002;//PLL作为系统时钟

while(temp!=0x02) //等待PLL作为系统时钟设置成功

{

temp=RCC->CFGR>>2;

temp&=0x03;

}

}


Copyright © 2017-2020 微波EDA网 版权所有

网站地图

Top