|
大家好,本人在校老菜雞一個(gè),最近抽空接手了一個(gè)項(xiàng)目,其中一個(gè)關(guān)鍵點(diǎn)在于“通過(guò)輸入捕獲檢測(cè)任意引腳、任意順序高低電平的持續(xù)時(shí)間”。
咱們直入主題,stm32的具有豐富的外設(shè)資源,小編選擇用stm32f1系列單片機(jī)作為核心控制器,來(lái)完成這個(gè)項(xiàng)目。
方案有兩種:
方案一:采用中斷,例如外部引腳中斷等,直接在檢測(cè)到指定電平時(shí),發(fā)生跳變進(jìn)入中斷函數(shù),然后進(jìn)行計(jì)時(shí)。
方案二:采用定時(shí)器輸入捕獲,在上升沿、下降沿時(shí)發(fā)生跳變,然后進(jìn)行計(jì)時(shí)。
優(yōu)缺點(diǎn)分析:方案一實(shí)行難度較小,但是需要引腳資源較多(一個(gè)檢測(cè)高電平,一個(gè)檢測(cè)低電平),時(shí)間精度稍微弱一點(diǎn)。
方案二擁有現(xiàn)成的歷程,直接調(diào)用即可,通過(guò)定時(shí)器輸入捕獲模式,中斷里進(jìn)行計(jì)數(shù)。
看似使用方案二是最佳的選擇,但是,如果這樣的話(huà),小編就不用寫(xiě)這篇博客了 .
至于方案一、小弟也還沒(méi)有嘗試過(guò),不清楚具體效果如何。
背景介紹(大牛不喜勿噴)
輸入捕獲模式:輸入捕獲模式可以用來(lái)測(cè)量脈沖寬度或者測(cè)量頻率,Stm32定時(shí)器除了定時(shí)器6和定時(shí)器7,其他定時(shí)器都有輸入捕獲功能,簡(jiǎn)單來(lái)說(shuō),就是在邊沿信號(hào)發(fā)生跳變的時(shí)候(上升沿、下降沿),將當(dāng)前定時(shí)器的值存放到對(duì)應(yīng)通道的捕獲/比寄存器中,完成一次捕獲,同時(shí),可以再配置捕獲到相應(yīng)跳變時(shí),是否觸發(fā)中斷/DMA等等。
一、測(cè)量高電平脈沖寬度:采用正點(diǎn)原子的代碼思路。先將引腳設(shè)定為下拉輸入,然后設(shè)置輸入捕獲為“上升沿觸發(fā)”,將當(dāng)前定時(shí)器中的時(shí)間存儲(chǔ)起來(lái),然后再中斷里將觸發(fā)方式設(shè)置為“下降沿觸發(fā)”,再記錄一下觸發(fā)時(shí)間,二者相減,即可得出高電平持續(xù)時(shí)間。
二、測(cè)量低電平脈沖寬度:與測(cè)量高電平脈沖寬度正好相反,不過(guò)應(yīng)該如何設(shè)置呢?小編找了很久,也沒(méi)有答案,所以只能自己動(dòng)手,豐衣足食咯。
先看檢測(cè)高電平脈沖的代碼:
//定時(shí)器2中斷服務(wù)程序
void TIM2_IRQHandler(void)
{
if((TIM2CH1_CAPTURE_STA&0X80)==0)// 這里采用了兩個(gè)變量作為臨時(shí)判斷條件,這兩個(gè)變量最初值都為0
{
if (TIM_GetITStatus(TIM2, TIM_IT_Update) != RESET)//如果是發(fā)生了中斷,那么向下執(zhí)行
{
if(TIM2CH1_CAPTURE_STA&0X40)//如果已經(jīng)捕獲到高電平那么就進(jìn)一步執(zhí)行程序。
{
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); /
}//////(小小吐槽一下,網(wǎng)站上傳圖片功能個(gè)人感覺(jué)有點(diǎn)雞肋。這一段很重要,必須要認(rèn)真去揣摩TIM2CH1_CAPTURE_STA的賦值關(guān)系。不要做拿來(lái)主義,這樣只能是拔苗助長(zhǎng),得不償失。)
通過(guò)兩個(gè)變量的“與”、“賦值”等操作,對(duì)高電平進(jìn)行不同的操作。在輸入捕獲通道中,設(shè)置為上升沿觸發(fā)。過(guò)來(lái)一個(gè)上升沿,進(jìn)入中斷,檢查是否標(biāo)記位被賦值,如果沒(méi)有,代表是是第一次檢測(cè)到高電平,記錄當(dāng)前定時(shí)器的值,然后設(shè)置為下降沿........
測(cè)量低電平脈沖時(shí)長(zhǎng)的代碼:簡(jiǎn)述一下思路,就是同樣定義兩個(gè)變量,按照上述代碼的格式,照貓畫(huà)虎一次,幾乎沒(méi)有大的改變。
具體情況,請(qǐng)?jiān)诖a文件中進(jìn)行查看。
備注:有一個(gè)語(yǔ)句 TIM_SetCounter(TIM2,0);具體作用我在代碼中也有標(biāo)注,時(shí)間所限,就不再多說(shuō)了,一切盡在代碼中。有空再來(lái)補(bǔ)全相關(guān)內(nèi)容。
單片機(jī)源程序如下:
- #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發(fā)送1個(gè)字符
- //c:要發(fā)送的字符
- float x,y=0;
- u8 xy[20];//用于接收坐標(biāo)?
- u8 len;
- u16 led0pwmval=1;
- int main(void)
- {
- int i=0;
- u8 t;
- u16 times=0;
-
- NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);
- delay_init(); //延時(shí)函數(shù)初始化
- usart_init(19200); //串口初始化為9600
- OLED_Init();
- LED_Init();
- TIM2_Cap_Init(0XFFFF,7199); //以1Mhz的頻率計(jì)數(shù) 0XFFFF----1111 1111 1111 1111(2進(jìn)制)//10khz計(jì)數(shù)頻率,每計(jì)數(shù)一下是1ms
- TIM1_PWM_Init(9999,7199);//1MHZ頻率輸出。
- TIM3_PWM_Init(9999,7199);//10kHZ技術(shù)頻率。
- while(1)
- {
- //OLED_show();
- //show1_all();這兩個(gè)暫時(shí)取消
- //delay_ms(300);不清楚會(huì)造成什么樣的后果
- TIM_SetCompare3(TIM3,led0pwmval);
- TIM_SetCompare4(TIM3,led0pwmval);
- // TIM_SetCompare4(TIM1,led0pwmval);
-
- if(USART_RX_STA&0x8000)//判斷接收數(shù)組的最高位是否為一,本次接收是否完成
- {
- len=USART_RX_STA&0x3fff;//取出u16中的低16 位,得到此次接收到的數(shù)據(jù)長(zhǎng)度
- USART_RX_STA=0;//對(duì)數(shù)組清零,方便下一次接收
-
- }
- 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();
- }
- }
復(fù)制代碼
目前代碼還存在很多問(wèn)題,求大神指導(dǎo)如何修改:
交替檢測(cè)高低電平.7z
(215.35 KB, 下載次數(shù): 149)
2019-7-16 16:55 上傳
點(diǎn)擊文件名下載附件
|
評(píng)分
-
查看全部評(píng)分
|