[英]STM32 Using TIMer to break loop
stm32工作的主要部分。
#include "stm32l0xx.h"
#define SYSCLK_FREQ 131072
void timer_tick(uint16_t n_ms);
int main(void)
{
TIM6->PSC = (SYSCLK_FREQ/1000)-1; //100us
TIM6->CR1 = TIM_CR1_CEN | TIM_CR1_OPM; //one-pulse mode
TIM6->EGR = TIM_EGR_UG; //generate update
TIM6->SR=0; //clear update - after few instructions
...
}
我第一次在那兒使用計時器,它在main之后立即聲明
void delay(uint16_t n_ms)
{
//upcounting timer - 16bit
TIM6->CNT = 65535-n_ms;
TIM6->CR1 = TIM_CR1_CEN | TIM_CR1_OPM; //one-pulse mode
while(!(TIM6->SR & TIM_SR_UIF)); //wait
TIM6->SR = 0;
}
比使用同一計時器的Iam(因為我只有無法中斷的TIM3和僅用於延遲功能的TIM6)
void timer_tick(uint16_t n_ms)
{
//upcounting timer - 16bit
TIM6->CNT = 65535-n_ms;
TIM6->CR1 = TIM_CR1_CEN | TIM_CR1_OPM; //one-pulse mode
TIM6->ARR = n_ms-1; // Auto reload value
TIM6->CCR1 = n_ms; // Start PWM duty for channel 3
//TIM6->CCR2 = n_ms; // Start PWM duty for channel 4
TIM6->CCMR1 = TIM_CCMR1_OC1M_2 | TIM_CCMR1_OC1M_1 | TIM_CCMR1_OC2M_2 | TIM_CCMR1_OC2M_1; // PWM mode on channel 1 & 2
TIM6->CCER = TIM_CCER_CC1E | TIM_CCER_CC2E; // Enable compare on channel 1 & 2
TIM6->DIER = TIM_DIER_UIE; // Enable TIM6 interrupt
TIM6->SR = 0;
}
在這里進行間斷。 Iam調用該函數以將時鍾開始計數到100(Iam賦予其權利),而不是只能實現100 ms的中斷實現開關-在其停止工作並中斷循環之后。
void USART1_IRQHandler(void)
{
static enum {00, 01, 02, 03, CRC} next_frame = 00; // frame construction
if(!sending_flag) //half-duplex
{
if(USART1->ISR&USART_ISR_FE) //frame error check&clear
USART1->ICR = USART_ICR_FECF;
else
timer_tick(100);
do {
switch(next_frame)
{
case 00:{ DOSTUFF; next_frame=01; break; } //starting marker
case 01:{ DOSTUFF; next_frame=02; break; }
case 02:{ DOSTUFF; next_frame=03; break; }
case 03:{ DOSTUFF; next_frame=CRC; break; }
case CRC:{ TIM6->SR = ~TIM_SR_CC2IF; break; } // clear flag
default: break;
}
} while (!(TIM6->SR&TIM_SR_CC2IF)); //TIM_SR_UIF
}
if(USART1->ISR & USART_ISR_TC)
{
USART1->ICR = USART_ICR_TCCF;
GPIOA->BSRR = GPIO_BSRR_BR_11 | GPIO_BSRR_BR_12;
sending_flag=0;
}
}
我確實不了解有關計時器的STM 文檔 。 設置該TIM6->CCR1 = n_ms; // Start PWM duty for channel 3
TIM6->CCR1 = n_ms; // Start PWM duty for channel 3
Iam的TIM6->CCR1 = n_ms; // Start PWM duty for channel 3
假設在定時器達到TIM6->ARR = n_ms-1; // Auto reload value
之后, TIM6->SR&TIM_SR_CC2IF
處應該有一個標志TIM6->ARR = n_ms-1; // Auto reload value
TIM6->ARR = n_ms-1; // Auto reload value
添加完do while
循環后,我的STM停止響應,並且Iam無法調試它。
櫃台設置正確嗎?
並不是的。 計時器配置中存在很多問題,讓我們嘗試找出其中的一些問題:
#define SYSCLK_FREQ 131072
TIM6->PSC = (SYSCLK_FREQ/1000)-1; //100us
時鍾頻率= 131072 獨立於單位,除以1000不會達到100us的期限。
void delay(uint16_t n_ms) { //upcounting timer - 16bit TIM6->CNT = 65535-n_ms; TIM6->CR1 = TIM_CR1_CEN | TIM_CR1_OPM; //one-pulse mode while(!(TIM6->SR & TIM_SR_UIF)); //wait TIM6->SR = 0; }
這不是您使用計時器的方式。 如果要測量一些時間,只需將ARR設置為正確的值並啟動計數器。
您的timer_tick(uint16_t n_ms)
完全錯誤。 計數器從0遞增到ARR值,然后停止(如果設置了一種脈沖模式)。 首先,設置所有定時器配置寄存器,然后啟動計數器。 如果啟動計數器,然后修改ARR,CCRX或其他寄存器,則可以100%確定定時器將下降。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.