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的documentation关于计时器的信息。
假设TIM6->CCR1 = n_ms; // Start PWM duty for channel 3
的行设置为TIM6->SR&TIM_SR_CC2IF
,假设计时器到达TIM6->ARR = n_ms-1; // Auto reload value
后do while
处应有一个标志
添加此<Inserted>
循环后,我的STM停止响应,并且Iam无法对其进行调试。
答案 0 :(得分:0)
计数器设置正确吗?
不是。计时器配置中有很多问题,让我们找出其中的一些问题:
#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%确定该计时器将下降。