c - 中断 - 微控制器,Atmega 328p - 捕捉时间
问题描述
免责声明 - 在中断方面,我是个大菜鸟,所以如果您有一些错误要指出,我很高兴听到。我正在编程一个数字霍尔传感器,只要有磁铁,它就像一个开关,我想为它使用一个计时器。d10 引脚,PB2,由 5V 供电。[Atmega328p]
我想用oneround
单轮的时间来计算风速,无限循环。
磁铁以小半径旋转,因此 PIN [默认开启] 将在 0.1s-1.0s 之间的任何速度关闭,然后再打开。
当我尝试打印该值时问题上升TCNT1
,如果我使用 256 的预分频器,它会给出一个数字 - 仍然是随机的,但是数字。现在,如果我使用 1024 预分频器,每次出现磁铁时,它都会不断加 1。
你能告诉我我做错了什么吗?
我可以打印TCNT1
为与 PIN 转回 On 点(即 360 度)的时间差吗?
我需要以毫秒为单位的时间来计算风速。
//include user/defined libraries
#include "i2cmaster.h"
#include "lcd.h"
#include "ds1621.h"
#include <avr/io.h>
#include <avr/interrupt.h>
#include <stdio.h>
#include <unistd.h>
#include <util/delay.h>
//void init_timer1();
volatile unsigned char run = 0;
volatile unsigned int oneround;
void init_timer1() {
//______________________________// Set the Timer Mode to CTC and start timer
TCCR1B |= (1 << WGM12);
OCR1A = 0x3D; // Set the value that you want to count to OCR1A = 0x3D;
PCICR |= (1 << PCIE0);
PCIFR |= (1 << PCIF0);
PCMSK0 |= (1 << PCINT2);
//________________________________________________________________________________________pray this 1010011 1001000 1001001 1010100 works
sei();
}
int main(void) {
// WINDSPEED"
DDRB &= ~(1 << DDB2); // DIRECTION REGISTER INOUT D10 PCINT2 OC1B PB2 SS PWM CTC
PORTB |= (1 << PORTB2); // OUTPUT REGISTER hIGH
//DDRB = 0b11111011; // DIRECTION REGISTER IN OUT
//PORTB = 0b00000100; // OUTPUT REGISTER
i2c_init(); //initialization of communication
LCD_init(); //initialization of the LCD
init_timer1(); // Lets count those laps baby
while (1) { /* O_O KAPUT! */
LCD_set_cursor(1, 1);
printf("%u ", oneround);
// rest of the sensors
}
return 0;
} // Main close
ISR(PCINT0_vect) {
if (run == 0) {
TCCR1B &= ~(1 << CS12); // clear timer and stop
oneround = TCNT1;
TIFR1 |= (1 << OCF1A) | (1 << OCF1B) | (1 << TOV1);
TCCR1B |= (1 << CS22) | (1 << CS21) | (1 << CS20); // set prescaler to 1024 and start timer 1sec
run = 1;
}
else {
run = 0;
}
}
解决方案
首先。
TCCR1B |= (1 << CS22) | (1 << CS21) | (1 << CS20); // set prescaler to 1024 and start timer 1sec
您正在使用 Timer2 ( CS2x
) 的位名称并将它们分配给计时器 1 ( TCCR1x
) 的寄存器。CS2x
== CS1x
,但在语义上它是一个错误。
请参阅数据表,第 15.11.2 章TCCR1B——定时器/计数器 1 控制寄存器 B ,第110页。
当所有 3 位CS12
,CS11
和CS10
置位时,定时器在 T1 引脚上的外部时钟源上工作。如果你想要 1:1024 的预分频器,那么CS11
位应该是 0。
下一个。
当逻辑电平向任一方向变化时,可以触发引脚更改中断。偶尔会有小尖峰,水平可以改变两次,但中断只会触发一次。所以,不要忘记检查输入引脚上的电平。
当你写
TCCR1B &= ~(1 << CS12);
它不会停止定时器,因为它只清除 CS12 位但 CS10 和 CS11 位保留(导致定时器继续使用另一个预分频器计数)。
此外,停止计时器不会重置其值。你需要写TCNT1 = 0;
来重置它。
你也不需要停止柜台。只需使用整个周期来计算差异。
volatile uint16_t prev_timer_value = 0;
volatile uint16_t oneround = 0;
ISR(PCINT0_vect) {
if ((PINB & (1 << PINB2)) == 0) { // Low level on the pin
uint16_t tval = TCNT1; // latch the current timer value;
oneround = tval - prev_timer_value; // calc the difference;
prev_timer_value = tval; // remember a new val
}
}
// To start the timer just start it in the Normal mode
TCCR1A = 0;
TCCR1B = (1 << CS12) | (1 << CS10); // 1:1024
推荐阅读
- powershell - Powershell7 WinSCP New-WinSCPSession 异常
- java - 为什么用标志告诉 JAVA NUMA?
- typescript - .on('mouseover', d => ..) 不提供与 .attr('foo', d => ..) 相同的 `d`
- json - 如何根据用户输入expo react-native在屏幕上显示json数据
- android - 对于具有动态功能模块的 Android 多模块项目,Lint 任务永远不会完成
- python - 如何将 json.loads 解析为字符串转换为字典 python
- css - 我的 CSS 文件对我的 Django 项目没有响应。我该如何让它工作?
- javascript - 如何在 JavaScript 中减去具有不同时间格式的日期?
- php - 无论如何都无法使用 PHP 图形 API 创建 FB 广告 (cURL)
- swift - 导航控制器未应用更改