由于RCC->CFGR時鐘配置寄存器中 APB1設置為2分頻,所以TIM3就是其倍頻==72M


上次我發表的STM32單片機自帶PWM輸出實驗大家可以參考學習: http://www.zg4o1577.cn/mcu/2123.html ,這次是用定時器產生的pwm.


上次我發表的STM32單片機自帶PWM輸出實驗大家可以參考學習: http://www.zg4o1577.cn/mcu/2123.html ,這次是用定時器產生的pwm.
//----------------------------------定時器-----------time.c-----------
#include "time.h"
#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--------------
//------------------------主函數-----------test.c-----------
//----------------time.h--------------
#ifndef _time_h
#define _time_h
#include "sys.h"
void time_init(u16 arr,u16 psc);
#endif
//----------------------按鍵-----key.c------------
//-------------------key.h----------------
#ifndef _led_h
//----------------------按鍵-----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;
}
#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 <stm32f10x_lib.h>
#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=(3600*(1+1))/72M=0.1ms
//------------------------------系統時鐘初始化函數對于定時器TIM3 時鐘簡易分析-----------------
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;
}
}