欧美极品高清xxxxhd,国产日产欧美最新,无码AV国产东京热AV无码,国产精品人与动性XXX,国产传媒亚洲综合一区二区,四库影院永久国产精品,毛片免费免费高清视频,福利所导航夜趣136
標題:
stm32系列定時器輸入捕獲檢測高、低脈沖時長的方法 附源程序
[打印本頁]
作者:
不知廉恥
時間:
2019-7-16 10:47
標題:
stm32系列定時器輸入捕獲檢測高、低脈沖時長的方法 附源程序
大家好,本人在校老菜雞一個,最近抽空接手了一個項目,其中一個關鍵點在于“通過輸入捕獲檢測任意引腳、任意順序高低電平的持續時間”。
咱們直入主題,stm32的具有豐富的外設資源,小編選擇用stm32f1系列單片機作為核心控制器,來完成這個項目。
方案有兩種:
方案一:采用中斷,例如外部引腳中斷等,直接在檢測到指定電平時,發生跳變進入中斷函數,然后進行計時。
方案二:采用定時器輸入捕獲,在上升沿、下降沿時發生跳變,然后進行計時。
優缺點分析:方案一實行難度較小,但是需要引腳資源較多(一個檢測高電平,一個檢測低電平),時間精度稍微弱一點。
方案二擁有現成的歷程,直接調用即可,通過定時器輸入捕獲模式,中斷里進行計數。
看似使用方案二是最佳的選擇,但是,如果這樣的話,小編就不用寫這篇博客了
.
至于方案一、小弟也還沒有嘗試過,不清楚具體效果如何。
背景介紹(大牛不喜勿噴)
輸入捕獲模式:輸入捕獲模式可以用來測量脈沖寬度或者測量頻率,Stm32定時器除了定時器6和定時器7,其他定時器都有輸入捕獲功能,簡單來說,就是在邊沿信號發生跳變的時候(上升沿、下降沿),將當前定時器的值存放到對應通道的捕獲/比寄存器中,完成一次捕獲,同時,可以再配置捕獲到相應跳變時,是否觸發中斷/DMA等等。
一、測量高電平脈沖寬度:采用正點原子的代碼思路。先將引腳設定為下拉輸入,然后設置輸入捕獲為“上升沿觸發”,將當前定時器中的時間存儲起來,然后再中斷里將觸發方式設置為“下降沿觸發”,再記錄一下觸發時間,二者相減,即可得出高電平持續時間。
二、測量低電平脈沖寬度:與測量高電平脈沖寬度正好相反,不過應該如何設置呢?小編找了很久,也沒有答案,所以只能自己動手,豐衣足食咯。
先看檢測高電平脈沖的代碼:
//定時器2中斷服務程序
void TIM2_IRQHandler(void)
{
if((TIM2CH1_CAPTURE_STA&0X80)==0)// 這里采用了兩個變量作為臨時判斷條件,這兩個變量最初值都為0
{
if (TIM_GetITStatus(TIM2, TIM_IT_Update) != RESET)//如果是發生了中斷,那么向下執行
{
if(TIM2CH1_CAPTURE_STA&0X40)//如果已經捕獲到高電平那么就進一步執行程序。
{
if((TIM2CH1_CAPTURE_STA&0X3F)==0X3F)//
{
TIM2CH1_CAPTURE_STA|=0X80;/
TIM2CH1_CAPTURE_VAL=0XFFFF;
}else TIM2CH1_CAPTURE_STA++;
}
}
if (TIM_GetITStatus(TIM2, TIM_IT_CC1) != RESET)//
{
if(TIM2CH1_CAPTURE_STA&0X40) /
{
TIM2CH1_CAPTURE_STA|=0X80; /
TIM2CH1_CAPTURE_VAL=TIM_GetCapture1(TIM2);
TIM_OC1PolarityConfig(TIM2,TIM_ICPolarity_Rising); /
}else //
{
TIM2CH1_CAPTURE_STA=0;
TIM2CH1_CAPTURE_VAL=0;
TIM_SetCounter(TIM2,0);
TIM2CH1_CAPTURE_STA|=0X40; //
TIM_OC1PolarityConfig(TIM2,TIM_ICPolarity_Falling); //
}
}
}
TIM_ClearITPendingBit(TIM2, TIM_IT_CC1|TIM_IT_Update); /
}//////(小小吐槽一下,網站上傳圖片功能個人感覺有點雞肋。這一段很重要,必須要認真去揣摩TIM2CH1_CAPTURE_STA的賦值關系。不要做拿來主義,這樣只能是拔苗助長,得不償失。)
通過兩個變量的“與”、“賦值”等操作,對高電平進行不同的操作。在輸入捕獲通道中,設置為上升沿觸發。過來一個上升沿,進入中斷,檢查是否標記位被賦值,如果沒有,代表是是第一次檢測到高電平,記錄當前定時器的值,然后設置為下降沿........
測量低電平脈沖時長的代碼:簡述一下思路,就是同樣定義兩個變量,按照上述代碼的格式,照貓畫虎一次,幾乎沒有大的改變。
具體情況,請在代碼文件中進行查看。
備注:有一個語句 TIM_SetCounter(TIM2,0);具體作用我在代碼中也有標注,時間所限,就不再多說了,一切盡在代碼中。有空再來補全相關內容。
單片機源程序如下:
#include "sys.h"
#include "usart.h"
#include "delay.h"
#include "led.h"
#include "stm32f10x.h"
#include "usart1.1.h"
#include "oled.h"
#include "timer.h"
//MPU6050
//串口1發送1個字符
//c:要發送的字符
float x,y=0;
u8 xy[20];//用于接收坐標?
u8 len;
u16 led0pwmval=1;
int main(void)
{
int i=0;
u8 t;
u16 times=0;
NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);
delay_init(); //延時函數初始化
usart_init(19200); //串口初始化為9600
OLED_Init();
LED_Init();
TIM2_Cap_Init(0XFFFF,7199); //以1Mhz的頻率計數 0XFFFF----1111 1111 1111 1111(2進制)//10khz計數頻率,每計數一下是1ms
TIM1_PWM_Init(9999,7199);//1MHZ頻率輸出。
TIM3_PWM_Init(9999,7199);//10kHZ技術頻率。
while(1)
{
//OLED_show();
//show1_all();這兩個暫時取消
//delay_ms(300);不清楚會造成什么樣的后果
TIM_SetCompare3(TIM3,led0pwmval);
TIM_SetCompare4(TIM3,led0pwmval);
// TIM_SetCompare4(TIM1,led0pwmval);
if(USART_RX_STA&0x8000)//判斷接收數組的最高位是否為一,本次接收是否完成
{
len=USART_RX_STA&0x3fff;//取出u16中的低16 位,得到此次接收到的數據長度
USART_RX_STA=0;//對數組清零,方便下一次接收
}
if(GPIO_ReadInputDataBit(GPIOA,GPIO_Pin_5)==0)
{
delay_ms(1000);
LED=0;
printf("1");
}
if(GPIO_ReadInputDataBit(GPIOA,GPIO_Pin_6)==0)
{
delay_ms(1000);
LED=1;
printf("2");
}
if(GPIO_ReadInputDataBit(GPIOA,GPIO_Pin_7)==0)
{
delay_ms(1000);
printf("3");
}
convey();
}
}
復制代碼
目前代碼還存在很多問題,求大神指導如何修改:
交替檢測高低電平.7z
(215.35 KB, 下載次數: 149)
2019-7-16 16:55 上傳
點擊文件名下載附件
作者:
尤曉權
時間:
2020-3-27 09:50
樓主這個程序是用定時器2的兩個輸入捕獲通道,一個配置成檢測高電平脈沖,一個檢測低電平脈沖。但是兩個通道接到一路PWM信號輸入點?
作者:
夜盡天明22
時間:
2020-6-6 21:15
都是捕獲高電平的
作者:
星jy辰
時間:
2020-8-14 20:15
夜盡天明22 發表于 2020-6-6 21:15
都是捕獲高電平的
誤導別人
作者:
星jy辰
時間:
2020-8-14 20:15
夜盡天明22 發表于 2020-6-6 21:15
都是捕獲高電平的
他這個代碼簡直在搞笑吧
作者:
lophost
時間:
2022-1-7 17:05
太扯了,完全不對題
作者:
wliuxiaoxiaow
時間:
2023-8-6 11:49
這個程序能用嗎
歡迎光臨 (http://m.raoushi.com/bbs/)
Powered by Discuz! X3.1