久久久久久久999_99精品久久精品一区二区爱城_成人欧美一区二区三区在线播放_国产精品日本一区二区不卡视频_国产午夜视频_欧美精品在线观看免费

 找回密碼
 立即注冊

QQ登錄

只需一步,快速開始

搜索
查看: 4507|回復: 3
收起左側

stm32定時器pwm模式輸入捕獲

[復制鏈接]
ID:421284 發表于 2018-11-5 19:36 | 顯示全部樓層 |閱讀模式
stm32定時器pwm模式輸入捕獲
stm32中的定時器,除了TIM6TIM7,其他定時器都有輸入捕獲功能。這種模式通常用在對輸入信號頻率frequency、占空比duty、高低脈寬的計算中,具有很廣泛的用途。
STM32的輸入捕獲,簡單的說就是通過檢測TIMx_CHx上的邊沿信號,在邊沿信號發生跳變(比如上升沿/下降沿)的時候,將當前定時器的值(TIMx_CNT)存放到對應的通道的捕獲/比較寄存(TIMx_CCRx)里面,完成一次捕獲。同時還可以配置捕獲時是否觸發中斷/DMA 等。
PWM模式捕獲方法:利用TIM3_CH1PWM輸出,TIM2_CH2捕獲上述PWM信號,并測出頻率和占空比。設置PWM頻率為1KHz,占空比50%
具體步驟:
1. 為了實現PWM輸入捕獲,TIM2占用了2個通道。第2通道的電平變化會被第一通道和第二通道引腳檢測到,其中第一通道被設置為從機模式(如何快速判別主從機模式,規則如下:如果設置的是第二通道作為PWM輸入捕獲,則剩余的第一通道都為從機,反之亦然)。
2. 假設輸入的PWM從低電平開始跳變,在第一個上升沿到來時,1,2通道同時檢測到上升沿。而從機設置為復位模式,所以將TIM2的計數值復位至0,此時不會產生一個中斷請求。
3. 下一個到來的電平是下降沿,此時通道1發生捕獲事件,將計數值存入通道1CCR1里。
4. 然后是第二個上升沿到來后,此時通道2發生捕獲事件,將此時的計數值存入通道2CCR2里。復位模式此時又將TIM2計數值復位至0,等待第二個下降沿到來。
5. 一次捕獲過程完成,則PWM的頻率f=72M/CCR2;占空比:duty=(CCR1/CCR2)X100%
注:
PWM輸入模式時,用到兩個通道(一般用TIMx_CH1TIMx_CH2),只給其中一個通道分配gpio時鐘即可,另一個在內部使用。給一個通道分配gpio時鐘后,需要設置另一個為從機且復位模式。(例如使用ch2,ch1就得設置成從機模式)。當一個輸入信號(TI1TI2)來臨時,主通道捕獲上升沿,從機捕獲下降沿。
CH2通道中:
TI2FP1TI2FP2都來自同一信號TI2 的邊沿檢測,信號相同,同一個TIx輸入映射了兩個ICx信號。
TI2FP1TI2FP2可以分別由連接到的ICx(IC1或是IC2)相對應的控制寄存器設為上升沿或是下降沿觸發,這兩個ICx信號分別在相反的極性邊沿有效。如果TI2FP2設置為上升沿觸發,則TI2FP1設置為下降沿觸發,二者極性相反。
CH1,3,4相同。
file:///C:\Users\ADMINI~1\AppData\Local\Temp\msohtmlclip1\01\clip_image002.jpg
具體程序:
include “pbdata.h”
void RCC_Configuration(void);
void GPIO_Configuration(void);
void NVIC_Configuration(void);
void TIM2_Configuration(void);
void TIM3_Configuration(void);
void USART_Configuration(void);
int fputc(int ch,FILE *f)
{
USART_SendData(USART1,(u8)ch);
while(USART_GetFlagStatus(USART1,USART_FLAG_TXE)==RESET);
return ch;
}
int main(void)
{
RCC_Configuration(); //配置時鐘
GPIO_Configuration();//IO口配置
TIM3_Configuration();
TIM2_Configuration();
NVIC_Configuration();
USART_Configuration();
while(1)
{
if(flag==1)
{
flag=0;
printf(“the duty is %d/r/n”,duty);
printf(“the frequency is %.2fKHz/r/n”,freq);
}
}
}
void RCC_Configuration(void)
{
SystemInit();
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA|RCC_APB2Periph_USART1,ENABLE);
RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2|RCC_APB1Periph_TIM3,ENABLE);
RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO,ENABLE);
}
void GPIO_Configuration(void)
{
GPIO_InitTypeDef GPIO_InitStructure;
//LED
GPIO_InitStructure.GPIO_Pin=GPIO_Pin_9;//TX
GPIO_InitStructure.GPIO_Speed=GPIO_Speed_50MHz;
GPIO_InitStructure.GPIO_Mode=GPIO_Mode_AF_PP;
GPIO_Init(GPIOA,&GPIO_InitStructure);
GPIO_InitStructure.GPIO_Pin=GPIO_Pin_10;//RX
GPIO_InitStructure.GPIO_Mode=GPIO_Mode_IN_FLOATING;
GPIO_Init(GPIOA,&GPIO_InitStructure);
GPIO_InitStructure.GPIO_Pin=GPIO_Pin_6;//PWM,TIM3_CH1
GPIO_InitStructure.GPIO_Speed=GPIO_Speed_50MHz;
GPIO_InitStructure.GPIO_Mode=GPIO_Mode_AF_PP;
GPIO_Init(GPIOA,&GPIO_InitStructure);
GPIO_InitStructure.GPIO_Pin=GPIO_Pin_1;//TIM2_CH2
GPIO_InitStructure.GPIO_Mode=GPIO_Mode_IN_FLOATING;
GPIO_Init(GPIOA,&GPIO_InitStructure);
}
void TIM2_Configuration(void)
{
TIM_TimeBaseInitTypeDef TIM_TimeBaseStruct;
TIM_ICInitTypeDef TIM_ICInitStructure;
TIM_ICInitStructure.TIM_Channel=TIM_Channel_2//選擇TIM2_CH2,選擇輸入端 IC2映射到TI2
TIM_ICInitStructure.TIM_ICPolarity=TIM_ICPolarity_Rising;//上升沿捕獲
TIM_ICInitStructure.TIM_ICSelection=TIM_ICSelection_DirectTI;//映射到TI2
TIM_ICInitStructure.TIM_ICPrescaler=TIM_ICPSC_DIV1;//在捕獲輸入上每探測到一個邊沿執行一次捕獲
TIM_ICInitStructure.TIM_ICFilter=0;//濾波設置,經歷幾個周期跳變認定波形穩定。(采樣高電平,只有連續采集到N個電平是高電平時才認為是有效的,否則低于N個時認為是無效的,N0x0-0xF
TIM_PWMIConfig(TIM2,&TIM_ICInitStructure);//以上是輸入捕獲配置
TIM_SelectInputTrigger(TIM2,TIM_TS_TI2FP2);//選擇濾波后的TI2FP2輸入作為觸發源,觸發下面程序的復位
TIM_SelectSlaveMode(TIM2,TIM_SlaveMode_Reset);//從模式控制器被設置為復位模式-選中的觸發信號上升沿重新初始化計數器并產生一個更新信號(上升沿一到,TIM2->CNT被清零,每次上升沿來到,CNT都會被清零)
TIM_SelectMasterSlaveMode(TIM2,TIM_MasterSlaveMode_Enable);//啟動定時器的被動觸發
TIM_ITConfig(TIM2,TIM_IT_CC2,ENABLE);//捕獲中斷打開
TIM_ClearFlag(TIM2,TIM_IT_CC2);//清除標志位
TIM_Cmd(TIM2,ENABLE);//使能定時器2
}
void TIM3_Configuration(void)
{
TIM_TimeBaseInitTypeDef TIM_TimeBaseStruct;
TIM_OCInitTypeDef TIM_OCInitStructure;
TIM_TimeBaseStruct.TIM_Period=72000;//計數初值
TIM_TimeBaseStruct.TIM_Prescaler=0;//分頻系數
TIM_TimeBaseStruct.TIM_ClockDivision=0;//時鐘分割
TIM_TimeBaseStruct.TIM_CounterMode=TIM_CounterMode_Up;//向上計數模式
TIM_TimeBaseInit(TIM3,&TIM_TimeBaseStruct);
//TIM3_CH1作為pwm輸出
TIM_OCInitStructure.TIM_OCMode=TIM_OCMode_PWM1;
TIM_OCInitStructure.TIM_OutputState=TIM_OutputState_Enable;
TIM_OCInitStructure.TIM_Pulse=36000;
TIM_OCInitStructure.TIM_OCPolarity=TIM_OCPolarity_High;
TIM_OC1Init(TIM3,&TIM_OCInitStructure);
TIM_OC1PreloadConfig(TIM3,TIM_OCPreload_Enable);
TIM_ARRPreloadConfig(TIM3,ENABLE);
TIM_Cmd(TIM3,ENABLE);
}
void NVIC_Configuration(void)
{
NVIC_InitTypeDef NVIC_InitStructure;
NVIC_PriorityGroupConfig(NVIC_PriorityGroup_1);
NVIC_InitStructure.NVIC_IRQChannel =TIM2_IRQn;
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority= 0;
NVIC_InitStructure.NVIC_IRQChannelSubPriority= 1;
NVIC_InitStructure.NVIC_IRQChannelCmd =ENABLE;
NVIC_Init(&NVIC_InitStructure);
}
void USART_Configuration(void)
{
USART_InitTypeDef USART_InitStructure;
USART_InitStructure.USART_BaudRate=115200;
USART_InitStructure.USART_WordLength=USART_WordLength_8b;
USART_InitStructure.USART_StopBits=USART_StopBits_1;
USART_InitStructure.USART_Parity=USART_Parity_No;
USART_InitStructure.USART_HardwareFlowControl=USART_HardwareFlowControl_None;
USART_InitStructure.USART_Mode=USART_Mode_Rx|USART_Mode_Tx;
USART_Init(USART1,&USART_InitStructure);
USART_Cmd(USART1,ENABLE);
USART_ClearFlag(USART1,USART_FLAG_TC);
}
//中斷程序
void TIM2_IRQHandler(void)
{
if(TIM_GetITStatus(TIM2,TIM_IT_CC2)==Bit_SET)
{
float IC2Value=0;
float DutyCycle=0;
float Frequency=0;
float pulse=0;
IC2Value=TIM_GetCapture2(TIM2);//獲得CCR2的值
pulse=TIM_GetCapture1(TIM2);//獲得CCR1的值
DutyCycle=pulse/IC2Value;
Frequency=72000000/IC2Value;
duty=(u32)(DutyCycle*100);
freq=(Frequency/1000);
flag=1;
TIM_ClearITPendingBit(TIM2,TIM_IT_CC2);
}
}
dutyfreq是定義的全局變量
extern u32 duty;
extern u16 freq;
u32 duty=0;
u16 freq=0;
經調試程序可用。頻率和占空比都對。頻率的設置不要太高,因為printf函數發數所需時間較多,兩次捕獲的時間間隔短的話可能使printf不能及時地送出數據,造成數據被刷新。更改方法,使用:USART_SendData();函數發數。
其他應用:
1.測量高電平時間:a,上文中的CCR1就是高電平時間;b,當使用一個通道CH1時,先將觸發沿選為為上升沿,產生捕獲中斷,讀取CCR1中的內容,再改變觸發沿為下降沿,下降沿到來時捕獲,再次讀出CCR1的內容,兩次相減為高電平時間。
2.測量脈沖個數:a,開啟定時器1的捕獲中斷,捕獲信號邊沿(上升沿或下降沿)進中斷,count++計數,再開啟定時器2的更新中斷,定時一定時間進更新中斷,讀取count值,此為脈沖個數。b,開啟外部中斷,配置沿觸發中斷,count++計數,再開啟定時器x的更新中斷,定時一定時間進更新中斷,讀取count值,此為脈沖個數。
3.計算一路信號的頻率,可以選擇定時器的CH1CH2(不可同時計算兩路頻率,否則計算出的頻率是后初始化的那個通道代表的信號頻率。當然,要同時也可以,每次得到頻率后切換通道,將數據通過DMA取走即可),使用PWM輸入捕獲模式,使用上升沿觸發。而CH3CH4通道則不行,如圖2所示,只有紅線所指的4個信號連在了從模式控制器上。所以,對于34通道,計數器的值不可能在接受到信號上升沿時候,有復位這個動作。
file:///C:\Users\ADMINI~1\AppData\Local\Temp\msohtmlclip1\01\clip_image004.jpg
---------------------
原文:https://blog.csdn.net/qq_29413829/article/details/52743273
版權聲明:本文為博主原創文章,轉載請附上博文鏈接!

回復

使用道具 舉報

ID:421502 發表于 2018-11-6 09:10 | 顯示全部樓層
受用了
回復

使用道具 舉報

ID:421502 發表于 2018-11-6 09:11 | 顯示全部樓層
不錯不粗
回復

使用道具 舉報

ID:584195 發表于 2021-8-24 08:51 | 顯示全部樓層
我最近在學習輸入捕獲頻率,真的是謝謝了!
回復

使用道具 舉報

您需要登錄后才可以回帖 登錄 | 立即注冊

本版積分規則

手機版|小黑屋|51黑電子論壇 |51黑電子論壇6群 QQ 管理員QQ:125739409;技術交流QQ群281945664

Powered by 單片機教程網

快速回復 返回頂部 返回列表
主站蜘蛛池模板: 一级免费看片 | www.五月婷婷.com | 最近最新中文字幕 | 亚洲不卡在线视频 | 国产精品久久久久久婷婷天堂 | 一区二区三区视频免费观看 | 久久精彩视频 | 亚洲二区视频 | 一区二区三区四区在线 | 伊人春色在线 | 天天爱爱网 | 国产黄色大片 | 中文久久 | 欧美成人精品在线观看 | 国产日韩欧美中文字幕 | 欧美日韩在线成人 | avhd101在线成人播放 | 在线午夜 | 久久小视频 | 91精品久久久久久久久 | 国产精品爱久久久久久久 | 成人黄色三级毛片 | 日日爱视频 | 国内久久精品 | 成人看片在线观看 | 亚洲国产成人精品女人久久久 | 毛片.com | 91精品国产91久久久久久三级 | 久久精品国产一区二区三区 | 精品久久久999 | 亚洲图片视频一区 | av入口 | 国产成人久久av免费高清密臂 | 国产乱人伦精品一区二区 | 亚洲第一区久久 | 亚洲精品久久久久中文字幕欢迎你 | 国产精品一区二区视频 | 欧美日韩国产高清 | 日韩一区二区三区视频 | 99re在线视频精品 | 日韩在线观看一区 |