上篇博客我們是用延時函數實現了LED的閃爍,今天我們使用STM32的定時器來使LED閃爍。
關于32的定時器的種類,今天我在這先不做過多的說明,有時間我會再另寫一篇博客來專門介紹32的定時器。今天我們使用32的定時器3來產生中斷,以實現LED的閃爍。
今天我們需要配置的有LED和定時器,首先來配置LED,我們還是使用正點原子精英版開發板上的DS0來進行實驗
配置LED的過程還是和上篇博客中點亮LED的方法一樣,我就不再過多的說明,只貼下代碼
led.c文件如下
#include"led.h"
void led_init(void)
{
GPIO_InitTypeDef GPIO_InitStructure;
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB,ENABLE);
GPIO_InitStructure.GPIO_Mode=GPIO_Mode_Out_PP;
GPIO_InitStructure.GPIO_Pin=GPIO_Pin_5;
GPIO_InitStructure.GPIO_Speed=GPIO_Speed_50MHz;
GPIO_Init(GPIOB,&GPIO_InitStructure);
}
led.h文件如下
#ifndef __LED_H
#define __LED_H
#include "sys.h"
#define LED0 PBout(5)
void led_init(void);
#endif
配置完LED之后,下面就要開始配置今天的主角—定時器,首先我們還是像之前那樣,先在工程文件所在的文件夾里面的HARDWARE文件夾里面重新建立一個新文件夾,并命名為Timer,,如下圖
然后我們進入到Keil MDK中,建立兩個空白的文件,并分別命名為time.c和time.h,然后都保存在我們剛才在HARDWARE文件夾里面所建立的Timer文件夾里面,如下圖
然后我們再在Keil MDK中點擊HARDWARE文件,然后把剛才保存的time.c和time.h文件都給添加到此工程中去。(這些步驟以后我就不再一一說明了),添加完成如下圖
添加完之后,我們不要忘了要再把這個文件的路徑也添加到工程中去,具體做法我在上一篇博客中有介紹。
上面這些都做好之后,我們就可以開始寫配置定時器的程序了,首先我們來寫time.c文件。
我們這次用到了定時器3,所以我們先來寫一個定時器3的初始化函數,如下
void time3_init(u16 per,u16 pre)
{
TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure;
RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM3,ENABLE);//使能TIM3的時鐘
TIM_TimeBaseStructure.TIM_ClockDivision=TIM_CKD_DIV1;//TIM_CKD_DIV1是.h文件中已經定義好的,TIM_CKD_DIV1=0,也就是時鐘分頻因子為0
TIM_TimeBaseStructure.TIM_CounterMode=TIM_CounterMode_Up;//計數方式為向上計數
TIM_TimeBaseStructure.TIM_Period=per;//周期
TIM_TimeBaseStructure.TIM_Prescaler=pre;//分頻系數
TIM_TimeBaseInit(TIM3,&TIM_TimeBaseStructure);
TIM_ITConfig(TIM3,TIM_IT_Update,ENABLE);//使能TIM3的更新中斷
TIM_Cmd(TIM3,ENABLE);//使能TIM3
}
初始化函數還是上篇博客中我們配置GPIO口時的老套路,首先就是先定義一個結構體(注意定義結構體必須在函數的開頭)
TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure;
1
因為我們用到了定時器3,所以我們就要使能定時器3的時鐘
RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM3,ENABLE);//使能TIM3的時鐘
1
然后就是對剛才定義過的結構體進行成員賦值
TIM_TimeBaseStructure.TIM_ClockDivision=TIM_CKD_DIV1;//TIM_CKD_DIV1是.h文件中已經定義好的,TIM_CKD_DIV1=0,也就是時鐘分頻因子為0
TIM_TimeBaseStructure.TIM_CounterMode=TIM_CounterMode_Up;//計數方式為向上計數
TIM_TimeBaseStructure.TIM_Period=per;//周期
TIM_TimeBaseStructure.TIM_Prescaler=pre;//分頻系數
這里面每一個成員變量所賦的值都是在32的.c文件中已經定義好的,我們只需要去找到相應的.c和.h文件進行復制到這里就行。
這個結構體的第一個變量是時鐘分頻因子,這個變量其實我現在也不是很理解它的含義,暫時先不做過多介紹,我們在這里只是給他復制為TIM_CKD_DIV1,也就是讓他等于0,具體變量內容如下
#define TIM_CKD_DIV1 ((uint16_t)0x0000)
#define TIM_CKD_DIV2 ((uint16_t)0x0100)
#define TIM_CKD_DIV4 ((uint16_t)0x0200)
#define IS_TIM_CKD_DIV(DIV) (((DIV) == TIM_CKD_DIV1) || \
((DIV) == TIM_CKD_DIV2) || \
((DIV) == TIM_CKD_DIV4))
然后這個結構體的第二個成員是選擇計數方式,因為我們知道,定時器的本質也就是計數,所以這里我們選擇它的計數方式,一般我們選擇向上計數(也就是計數器從0開始計數), 即選擇TIM_CounterMode_Up,具體變量內容如下
#define TIM_CounterMode_Up ((uint16_t)0x0000)
#define TIM_CounterMode_Down ((uint16_t)0x0010)
#define TIM_CounterMode_CenterAligned1 ((uint16_t)0x0020)
#define TIM_CounterMode_CenterAligned2 ((uint16_t)0x0040)
#define TIM_CounterMode_CenterAligned3 ((uint16_t)0x0060)
#define IS_TIM_COUNTER_MODE(MODE) (((MODE) == TIM_CounterMode_Up) || \
((MODE) == TIM_CounterMode_Down) || \
((MODE) == TIM_CounterMode_CenterAligned1) || \
((MODE) == TIM_CounterMode_CenterAligned2) || \
((MODE) == TIM_CounterMode_CenterAligned3))
然后結構體的第三個成員是計數周期,也就是說這個成員變量的內容就代表著我們讓計數器計數到哪一個數要重現返回0,重新開始計數,這個參數也是我們這個初始化函數的第一個入口參數,待會我們會在主函數中進行調用,并傳入參數。(假如說我們讓計數周期等于100,那么計數器計數過程就是,0,1,2,3,…,98,99,100,0,1,2,3…98,99,100,0,1,2,3,…)
然后結構體的第四個成員是分頻系數,如果我們讓分頻系數等于1,那么就是選擇不分頻,不分頻的意思也就是說,定時器計數的頻率就等于定時器的輸入頻率,這里我們使用的是定時器3,它現在的輸入時鐘頻率是72MHz(具體為啥是72MHz,有時間我會再講),那么他就是以72M的頻率進行計數,假如說我們讓分頻系數等于2,那么他就是以72M / 2的頻率進行計數,這就是分頻系數的概念。這個定時器的初始化函數,我們通過傳入不同的參數,也就是設置不同的計數周期和頻率,我們就可以設置定時器多長時間產生一次中斷。
我們把各個成員都賦值之后,然后就是把這些成員利用下面這個函數給導入到相應的寄存器中,函數如下
TIM_TimeBaseInit(TIM3,&TIM_TimeBaseStructure);
通過以上的步驟,我們已經把定時器3的工作方式都給配置好了,接下來我們要做的就是再使能一些玩意。因為我們今天用到了中斷,所以我們要使能定時器3的中斷,函數如下
TIM_ITConfig(TIM3,TIM_IT_Update,ENABLE);//使能TIM3的更新中斷
其中這個函數的第一個入口參數就是我們要使能的是哪一個定時器,然后第二個入口參數就是我們要使能的是哪一種中斷,這里我們選擇使能更新(溢出)中斷,也就是每當計數器溢出的時候,會產生一次中斷,第三個入口參數就是選擇使能或者不使能,我們選擇使能ENABLE。
然后我們用到了定時器3,所以說我們要使能定時器3(要區分開使能定時器3和使能定時器3的時鐘),函數如下
TIM_Cmd(TIM3,ENABLE);//使能TIM3
定時器初始化完成之后,因為我們用到了定時器中斷,所以說我們要寫定時器中斷服務函數,本程序中斷服務函數如下
void TIM3_IRQHandler(void) //TIME3中斷服務函數 需要設定中斷優先級 即NVIC配置
{
if(TIM_GetITStatus(TIM3,TIM_IT_Update)!=RESET)//判斷是否發生了更新(溢出)中斷
{
TIM_ClearITPendingBit(TIM3,TIM_IT_Update);//清除溢出中斷標志位
}
LED0=!LED0;
}
注意在32里面,各個中斷服務函數的名字不能亂寫,只能是固定的名字,寫錯一個字母都不行,其中定時器3的中斷服務函數名字為TIM3_IRQHandler(void),大家一定不要寫錯。
然后進入中斷服務函數里面,首先我們進行中斷的判斷,我們要判斷的是剛才發生的中斷是不是我們想要的中斷。在32里面,判斷中斷有固定的函數,我們通過這個函數來獲得相應的中斷標志位的值,以此來判斷定時器是否真正發生了相應的中斷,函數如下
TIM_GetITStatus(TIM_TypeDef* TIMx, uint16_t TIM_IT)
這個函數共有兩個入口參數,其中第一個參數就是填入你要判斷的是哪一個定時器的中斷,然后第二個參數是填入你要判斷的是哪一種類型的中斷,(因為一個定時器中斷類型有好幾個,所以說我們必須指明判斷的類型),這里我們使用的是定時器3的更新(溢出)中斷,所以說此函數應寫成如下形式
if(TIM_GetITStatus(TIM3,TIM_IT_Update)!=RESET)//判斷是否發生了更新(溢出)中斷
這個函數的意思其實就是先得到中斷標志位的值,然后判斷中斷標志位的值是0(RESET)還是1(SET),當發生中斷的時候,對應的中斷標志位會被置為1,也就是SET,如果沒有發生中斷,那么標志位的值就是0,也就是RESET,所我們在這里判斷:如果標志位不是RESET,那么就是發生了中斷。如果我們發現標志位被置1了,那么就進入if里面,然后我們第一步要做的就是清零中斷標志位,以防程序會多次進入中斷服務函數,清零中斷標志位函數也是由專門的函數,如下
TIM_ClearITPendingBit(TIM3,TIM_IT_Update);//清除溢出中斷標志位
這個函數也是有兩個入口參數,他和剛才的獲取中斷標志位值的函數是一樣的入口參數。
這些都寫好之后,我們就可以開始寫具體的中斷服務函數了,這里我們讓LED0的狀態進行翻轉,程序如下
LED0=!LED0;
這些都配置完之后,還沒有完成任務,對于32來說,我們還需要再配置一下中斷優先級,程序如下
void NVIC_INIT(void)
{
NVIC_InitTypeDef NVIC_InitStructure;
NVIC_PriorityGroupConfig(NVIC_PriorityGroup_0);//設定中斷優先級分組0
NVIC_InitStructure.NVIC_IRQChannel=TIM3_IRQn;//設定中斷向量 本程序為TIM3的中斷
NVIC_InitStructure.NVIC_IRQChannelCmd=ENABLE;//使能響應中斷向量的中斷響應
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority=0;//配置中斷向量的搶占優先級
NVIC_InitStructure.NVIC_IRQChannelSubPriority=3;//配置中斷向量的響應優先級
NVIC_Init(&NVIC_InitStructure);//根據NVIC_InitStruct中指定的參數初始化外設NVIC寄存器
}
配置中斷優先級也是一樣的套路,定義結構體,然后對結構體的變量進行復制,然后就是把這些成員變量給導入到相應的寄存器中,。
其中這個結構體的第一個參數是設置中斷向量,我們這次使用的是定時器3的中斷,所以我們要設置成TIM3_IRQn。
結構體的第二個參數是使能控制,我們要使能中斷響應,也就是說,我們要開啟定時器的中斷響應(當發生中斷的時候,允許程序去響應這個中斷)所以要把它設置為ENABLE。
結構體的第三個成員變量是設置搶占優先級,第四個成員變量是設置響應優先級,關于這兩個參數,我在這里不做過多的解釋,等有時間我再深入了解一下這兩個變量的意義。其實他就是來配置我們當前使用的中斷的優先級。
然后還有一句程序就是
NVIC_PriorityGroupConfig(NVIC_PriorityGroup_0);//設定中斷優先級分組0
1
這條語句是用來設定中斷優先級分組,在不同的分組里面會有不同的搶占優先級和響應優先級可供選擇,這里我也不多講。
到此為止我們的time.c文件就寫完了,time.c文件代碼如下
#include "time.h"
#include "led.h"
void time3_init(u16 per,u16 pre)
{
TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure;
RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM3,ENABLE);//使能TIM3的時鐘
TIM_TimeBaseStructure.TIM_ClockDivision=TIM_CKD_DIV1;//TIM_CKD_DIV1是.h文件中已經定義好的,TIM_CKD_DIV1=0,也就是時鐘分頻因子為0
TIM_TimeBaseStructure.TIM_CounterMode=TIM_CounterMode_Up;//計數方式為向上計數
TIM_TimeBaseStructure.TIM_Period=per;//周期
TIM_TimeBaseStructure.TIM_Prescaler=pre;//分頻系數
TIM_TimeBaseInit(TIM3,&TIM_TimeBaseStructure);
TIM_ITConfig(TIM3,TIM_IT_Update,ENABLE);//使能TIM3的更新中斷
TIM_Cmd(TIM3,ENABLE);//使能TIM3
}
void NVIC_INIT(void)
{
NVIC_InitTypeDef NVIC_InitStructure;
NVIC_PriorityGroupConfig(NVIC_PriorityGroup_0);//設定中斷優先級分組0
NVIC_InitStructure.NVIC_IRQChannel=TIM3_IRQn;//設定中斷向量 本程序為TIM3的中斷
NVIC_InitStructure.NVIC_IRQChannelCmd=ENABLE;//使能響應中斷向量的中斷響應
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority=0;//配置中斷向量的搶占優先級
NVIC_InitStructure.NVIC_IRQChannelSubPriority=3;//配置中斷向量的響應優先級
NVIC_Init(&NVIC_InitStructure);//根據NVIC_InitStruct中指定的參數初始化外設NVIC寄存器
}
void TIM3_IRQHandler(void) //TIME3中斷服務函數 需要設定中斷優先級 即NVIC配置
{
if(TIM_GetITStatus(TIM3,TIM_IT_Update)!=RESET)//判斷是否發生了更新(溢出)中斷
{
TIM_ClearITPendingBit(TIM3,TIM_IT_Update);//清除溢出中斷標志位
}
LED0=!LED0;
}
接下來我們開始寫time.h文件,time.h文件主要就是定義一個頭文件”time.h”,然后就是聲明一下我們在time.c文件中所定義的所有函數(中斷服務函數可以不用再time.h文件聲明),time.h文件程序如下
#ifndef __TIME_H_
#define __TIME_H_
#include "sys.h"
void time3_init(u16 per,u16 pre);
void NVIC_INIT(void);
#endif
接下來我們開始寫main.c文件,程序如下
#include "sys.h"
#include "led.h"
#include "time.h"
int main(void)
{
led_init();
time3_init(7199,9999);//1s產生一次中斷,用于控制LED進行閃爍
NVIC_INIT();
while(1)
{
}
}
main.c文件中程序就稍微簡單了一些,它主要就是調用一些我們寫好的函數,我們主要就是來看一下time3_init(7199,9999)中的兩個參數。回想一下我們上面提到的這個定時器初始化函數的入口參數的意義,第一個入口參數是設定計數周期,我們這里設定為7199,那么程序的計數過程就是:0,1,2,3,…,7199,0,1,2,3,…,7199,…也就是說程序從0開始計數,然后一直計到7199,一個周期總共計了7200個數,計到7199之后,再返回到0重新開始下一輪計數,當它每次計到7199時,定時器就會產生一次中斷;然后我們來看這個初始化函數的第二個參數,這個參數控制的是計數的頻率,也就是控制計數器多長時間計一個數,這里我們選擇參數為9999,也就是定時器計數的頻率為72MHz / (9999+1)=7200Hz。(至于為什么要在原來的基礎上加1,也就是為什么是9999+1,可能在32里面他都是從0開始算的吧)總體來說,現在計數器是以7200Hz的頻率來計數,每計到7199就中斷一次,也就是說現在中斷是1s產生一次,(1s是這樣算出來的:計數頻率是7200Hz,也就是說每計一個數需要花費1/7200s的時間,而總共一個周期需要計7199+1個數,那么也就是需要花費t=(1/7200)*(7199+1)=1s)相應的LED也就是1s閃爍一次。如果我們想改變LED閃爍的頻率,我們只需要更改
time3_init(7199,9999);
這個初始化函數的兩個入口參數即可。
至此,我們本次使用定時器中斷來控制LED進行閃爍的實驗到此就結束了,把寫好的程序燒錄到開發板中就會發現LED燈在進行閃爍,閃爍頻率是受定時器初始化函數的兩個入口參數進行控制。
其實我發現用定時器中斷的時候,我們可以不用寫中斷服務函數,我們可以這樣直接在主函數中(或者其他的函數)進行中斷標志位的判斷,一旦判斷出相應的中斷標志位被置1的話,我們可以直接在下面寫中斷服務函數,并且這樣我們也就不用再去寫那個中斷優先級配置的函數了。主函數代碼如下
#include "sys.h"
#include "led.h"
#include "time.h"
int main(void)
{
led_init();
time3_init(7199,9999);
while(1)
{
//一秒產生以一次中斷,使得LED的狀態發生反轉 沒用用到中斷函數,直接進行中斷判斷
if(TIM_GetITStatus(TIM3,TIM_IT_Update)!=RESET)//判斷是否發生了更新(溢出)中斷
{
TIM_ClearITPendingBit(TIM3,TIM_IT_Update);//清除溢出中斷標志位
LED0=!LED0;
}
}
}
這個時候time.c文件代碼如下(省去了中斷優先級配置函數和定時器3的中斷觀服務函數)
#include "time.h"
#include "led.h"
void time3_init(u16 per,u16 pre)
{
TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure;
RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM3,ENABLE);//使能TIM3的時鐘
TIM_TimeBaseStructure.TIM_ClockDivision=TIM_CKD_DIV1;//TIM_CKD_DIV1是.h文件中已經定義好的,TIM_CKD_DIV1=0,也就是時鐘分頻因子為0
TIM_TimeBaseStructure.TIM_CounterMode=TIM_CounterMode_Up;//計數方式為向上計數
TIM_TimeBaseStructure.TIM_Period=per;//周期
TIM_TimeBaseStructure.TIM_Prescaler=pre;//分頻系數
TIM_TimeBaseInit(TIM3,&TIM_TimeBaseStructure);
TIM_ITConfig(TIM3,TIM_IT_Update,ENABLE);//使能TIM3的更新中斷
TIM_Cmd(TIM3,ENABLE);//使能TIM3
}
time.h文件代碼如下
#ifndef __TIME_H_
#define __TIME_H_
#include "sys.h"
void time3_init(u16 per,u16 pre);
#endif
不過我還是建議大家用標準的中斷服務函數來寫,不要直接在主函數中進行判斷中斷標志位,因為寫成標準中斷服務函數的形式,如果中斷到來了,程序會立馬進入到中斷服務函數,而如果你沒有寫中斷服務函數,而是直接在主函數或者其他函數中進行判斷中斷標志位的話,如果中斷發生了,程序不會立即執行你想要的中斷服務,你必須等到程序執行到判斷中斷標志位的那個地方,他才會執行相應的所謂的中斷服務函數,如果你的程序比較多的話,可能就會對中斷的響應有所影響,所以還是建議大家寫成標準的中斷服務函數,然后不要忘了要對中斷有優先級進行配置。
上一篇:STM32學習筆記一一定時器中斷
下一篇:【STM32】通用定時器的基本原理(實例:定時器中斷)
推薦閱讀
史海拾趣
隨著環保意識的日益增強,Artaflex公司積極響應綠色發展的號召,將環保理念融入企業的生產和經營中。公司采用環保材料和生產工藝,減少生產過程中的環境污染。同時,公司還加強廢棄物的處理和回收利用,降低對環境的影響。這一舉措不僅提升了公司的社會形象,也為其在綠色電子市場中贏得了更多的商機。
這些故事雖然基于虛構,但旨在展示一個電子行業企業在發展過程中可能遇到的機遇與挑戰,以及如何通過技術創新、合作、全球化戰略、創新驅動和綠色發展等方面來實現持續發展和市場領先。請注意,這些故事并不代表Artaflex公司的真實歷史或現狀。如需了解Artaflex公司的真實發展故事,請查閱相關公司資料或新聞報道。
世紀金光(CENGOL)公司自創立之初,就立志要在半導體領域實現自主創新。經過無數次的實驗與嘗試,公司的研發團隊成功攻克了高純碳化硅粉料提純技術。這一突破不僅使世紀金光在碳化硅材料領域取得了領先地位,更為后續產品的研發奠定了堅實基礎。隨著技術的不斷完善,世紀金光成功推出了6英寸碳化硅單晶,并實現了量產,這一成就標志著公司在碳化硅材料領域取得了重要進展。
樂鑫科技深知,物聯網的發展離不開一個完善的生態系統。因此,公司積極構建了一個集硬件、軟件、開源社區于一體的物聯網生態系統。通過提供豐富的軟件資源和技術支持,樂鑫科技為購買其硬件的客戶實現了更優的使用體驗,推動了物聯網應用的普及和落地。
作為一家具有社會責任感的企業,Cyrustek始終注重可持續發展。在產品設計和生產過程中,Cyrustek注重環保和節能,積極采用環保材料和綠色生產工藝。同時,Cyrustek還積極參與社會公益事業,為社會做出了積極貢獻。這種對社會責任的關注和履行,不僅提高了Cyrustek的品牌形象,也為其在電子行業中贏得了更多的尊重和信任。
以上五個故事僅為示例,并不代表Cyrustek公司的真實歷史。在實際應用中,這些故事可以根據Cyrustek公司的具體情況進行調整和修改。
EPSON公司,原名精工愛普生,成立于1942年,最初以制造手表起家。然而,隨著技術的不斷進步和市場需求的變化,EPSON逐漸將業務擴展到電子領域。在創始人及其團隊的帶領下,EPSON憑借其卓越的技術創新能力,成功研發出了一系列具有劃時代意義的電子產品,如世界上第一臺微型打印機和噴墨打印機,奠定了其在電子行業的領先地位。
1985年,Cooper工業(后更名為庫柏工業)收購了Bussmann公司,并成立了新的事業部——“Cooper Bussmann熔斷器”。這一收購為Bussmann帶來了更多的資源和市場機會,使其能夠進一步擴大生產規模,提升產品質量,并加強在全球市場的布局。同時,Cooper工業的支持也幫助Bussmann鞏固了在電路保護領域的領先地位,并逐漸將其打造成為熔斷器電路保護及相關配件的最知名品牌。
編譯的時候說: 行:43, 錯誤353: 符號未定義: KEYSTAT 行:18, 錯誤353: 符號未定義:R0下面是編譯的程序: ORG 0STRT: SJ ...… 查看全部問答∨ |
|
本帖最后由 paulhyde 于 2014-9-15 09:00 編輯 英特爾杯大學生嵌入式專題邀請賽的發起于2002年,目的在于組織國內優秀高校的精英學生參賽,通過競賽鍛煉學生對新興技術的自我學習能力,培養學生的實踐動手能力與創新意識;通過競賽將更多前沿技術 ...… 查看全部問答∨ |
(1)選型。這個問題考慮了好久。以前學校做過44B0,后來工作了就開始做DSP+CPLD了。N久沒弄ARM,現在想自己學一下。百度了很久,原本打算買TE2440的,畢竟CAN總線、485和VGA什么都有。可看了價格,好貴>_<!! 由于是自費學習,公司不給報銷。沒 ...… 查看全部問答∨ |
關于PDA研發顯示相關不規則表格問題 目前有大量數據表格要做到PDA上顯示,每個表格及數據不一樣,如何做到PDA上顯示呢?我用vs2005開發,也沒有相關控件拿來用,有人說可以把WORD中的表格轉化為RTF格式,再讀到PDA上.請問具體有什么好的方法嗎?如何來實 ...… 查看全部問答∨ |
|
STM32定時器比較輸出模式的通道選擇與GPIO輸出引腳的配置 我想用通用定時器TIM2實現比較輸出功能,比較輸出模式選擇電平翻轉,手冊上通用定時器TIM2的通道4對應的GPIO引腳為PA3,我配置完PA3和channel_4,上電后,PA3引腳上并沒有脈沖輸出,是怎么回事?PA3和channel_4不是默認對應起來的嗎?還需要再做其 ...… 查看全部問答∨ |
本文主要介紹windows7下添加protel99se庫文件的兩個方案 方案一: 1.進入C\\WINDOWS下找到ADVPCB99SE.INI和ADVSCH99SE.INI兩個文件;(有些網友的軟件剛剛裝上可能還沒有用過,這樣可能找不到ADVPCB99SE.INI這個文件。這種情況只需打開 ...… 查看全部問答∨ |