|
在配置STM32外設的時候,任何時候都要先使能該外設的時鐘!
第一個例程,首先,考慮一個延時程序,要實現這一功能,共四步步驟(實際使用中兩步就夠了,第一步任何例程都必須做,):
Stm32_Clock_Init(9); //系統時鐘設置,系統時鐘設置為9倍頻,即8Mhz*9=72Mhz
delay_init(72); //延時初始化,按總線時鐘72Mhz延時
//LED_Init(); //初始化與LED連接的硬件接口,這個不算第三步,使用它以便演示流水燈
delay_ms(300);
第一步,看第一個程序:
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;
}
}
第二步,延時功能初始化,看第二個程序
void delay_init(u8 SYSCLK)
{
SysTick->CTRL&=0xfffffffb;//bit2清空,選擇外部時鐘 HCLK/8
fac_us=SYSCLK/8;
fac_ms=(u16)fac_us*1000;
}
第三部,調用延時程序:
void delay_ms(u16 nms)
{
u32 temp;
SysTick->LOAD=(u32)nms*fac_ms;//時間加載(SysTick->LOAD為24bit)
SysTick->VAL =0x00; //清空計數器
SysTick->CTRL=0x01 ; //開始倒數
do
{
temp=SysTick->CTRL;
}
while(temp&0x01&&!(temp&(1<<16)));//等待時間到達,先將
SysTick->CTRL=0x00; //關閉計數器
SysTick->VAL =0X00; //清空計數器
}
//延時nus
//nus為要延時的us數.
void delay_us(u32 nus)
{
u32 temp;
SysTick->LOAD=nus*fac_us; //時間加載
SysTick->VAL=0x00; //清空計數器
SysTick->CTRL=0x01 ; //開始倒數
do
{
temp=SysTick->CTRL;
}
while(temp&0x01&&!(temp&(1<<16)));//等待時間到達
SysTick->CTRL=0x00; //關閉計數器
SysTick->VAL =0X00; //清空計數器
}
------------------------------------
不得不說,《21天學通ARM嵌入式開發》是一本不折不扣的爛書,只是把官方手冊照搬上去,再把庫函數加些注釋就變成一本書了,誰買誰上當,視頻教程也沒什么技術含量可言,千萬不要買這本書。
STM32的定時器功能比單片機復雜,切不可照搬,首先給出一些基本定義:
ARR:auto reload register:自動重載寄存器,ARR也有定時器重載值的含義,STM32中的定時器是自動重載的,(不像單片機中的定時器有自動重載模式和手動軟件重載模式,而且手動重載用得較多);
TIMx_CR:定時器控制寄存器;
更新事件:更新不等于觸發中斷,更新是指計數器上溢或下溢時,內部產生一個更新信號,根據此時相關寄存器的設置執行一些相應操作,比如重載ARR,具體在下文中會介紹。
觸發事件:主要用于信號計數,可以使內部信號(定時器的輸出也可以作為觸發信號),也可以是外部引腳信號
接下來關注下面寄存器TIMx_CR中的兩個位
ARPE:自動重裝載預裝載允許位
TIMx_CR中的UDIS:update disable 禁止更新
ARPE為0時,若改變ARR值,影子寄存器中的值立即被改變;ARPE=1時,影子寄存器中的值將等到計數值到達上一次設定的溢出值(即發生更新事件后)時,才會裝載被修改過的ARR值;
UDIS:禁止更新,1有效
產生更新事件的條件:
①當計數器上溢或下溢時,并觸發中斷;
②當循環計數器計數值為0時(僅適用于TIM1),觸發中斷;
③通過軟件設置UG(Update Generation)位,這種情況下不會觸發定時中斷。
|
|