ESP8266 Timer1 与 Neopixels WS2812 库冲突
ESP8266 Timer1 conflicts with Neopixels WS2812 library
我想添加一个 Timer1 ISR,使其每 0.25 秒触发一次,并使用 WS2812 240 灯条 LED 进行一些轻微运动。
在 Arduino Nano 上运行良好,因为它有一个
cli();
TCCR1A = 0; // pas de PWM ou OCR
TCCR1B = (0<<WGM13) | (1<<WGM12) | 4; // Clear Timer on Compare match (CTC) mode, OCR1A= PRD
// CS12 CS11 CS10 = 0b100 = 4 =>256 prescaler
OCR1A = 15625; // 62.5 ns * 15625 * 256 prescaler = 0.250 s
// pas de compteur logiciel
TIMSK1 = 1<<OCIE1A; // ISR on Output Compare1 (TCNT1==OCR1)
TIFR1 = 0; // clear T1 IF
TCNT1 = 0; // RAZ T1
sei();
现在我搬到了 ESP8266,在我的项目中也使用 Wifi,没有 OCR,所以我尝试使用 Timer1 ISR(Timer0 用于 Wifi)。
单独使用:
//setup
timer1_attachInterrupt(myTimer1_ISR);
timer1_enable(TIM_DIV16, TIM_EDGE, TIM_SINGLE);
timer1_write(300000); //120000 us/2
...
void ICACHE_RAM_ATTR myTimer1_ISR()
{
//.....
timer1_write(300000);//12us/2
}
但是对于 NeoPixels 库,它给我带来了冲突:
error: void myTimer1_ISR() causes a section type conflict with static
volatile void NeoEsp8266DmaMethodBase::i2s_slc_isr() [with
T_SPEED = NeoEsp8266DmaSpeed400Kbps]
void ICACHE_RAM_ATTR myTimer1_ISR(){
In file included from
...Arduino\libraries\NeoPixelBus_by_Makuna\src/NeoPixelBus.h:67:0,
我相信,NeoPixel 代码也使用 Timer1?
我该如何管理?
谢谢
ESP8266 有一个 Ticker class 可以满足你的目的。
如果您尝试 运行 在回调中花费太长时间的事情,我有一个怪癖,在这种情况下,推荐的使用方法是设置一个标志,然后在循环中检查该标志,做你的事情并重置标志。如果你有一些短的,你可以直接在回调中完成。
这是一个例子。
#include <Ticker.h>
bool doEveryOneMsStuffNow = false; // start with flag false
Ticker everyOneMs;
void setup() {
// ...
everyOneMs.attach(0.001, []() { doEveryOneMsStuffNow = true; }); // lambda call back - this one just sets the flag to true
// ...
}
void loop() {
// ...
if (doEveryOneMsStuffNow) {
doEveryOneMsStuffNow = false; // reset the flag
// do what needs to be done every 1 ms
}
// ...
}
我想添加一个 Timer1 ISR,使其每 0.25 秒触发一次,并使用 WS2812 240 灯条 LED 进行一些轻微运动。
在 Arduino Nano 上运行良好,因为它有一个
cli();
TCCR1A = 0; // pas de PWM ou OCR
TCCR1B = (0<<WGM13) | (1<<WGM12) | 4; // Clear Timer on Compare match (CTC) mode, OCR1A= PRD
// CS12 CS11 CS10 = 0b100 = 4 =>256 prescaler
OCR1A = 15625; // 62.5 ns * 15625 * 256 prescaler = 0.250 s
// pas de compteur logiciel
TIMSK1 = 1<<OCIE1A; // ISR on Output Compare1 (TCNT1==OCR1)
TIFR1 = 0; // clear T1 IF
TCNT1 = 0; // RAZ T1
sei();
现在我搬到了 ESP8266,在我的项目中也使用 Wifi,没有 OCR,所以我尝试使用 Timer1 ISR(Timer0 用于 Wifi)。
单独使用:
//setup
timer1_attachInterrupt(myTimer1_ISR);
timer1_enable(TIM_DIV16, TIM_EDGE, TIM_SINGLE);
timer1_write(300000); //120000 us/2
...
void ICACHE_RAM_ATTR myTimer1_ISR()
{
//.....
timer1_write(300000);//12us/2
}
但是对于 NeoPixels 库,它给我带来了冲突:
error: void myTimer1_ISR() causes a section type conflict with static volatile void NeoEsp8266DmaMethodBase::i2s_slc_isr() [with T_SPEED = NeoEsp8266DmaSpeed400Kbps]
void ICACHE_RAM_ATTR myTimer1_ISR(){
In file included from ...Arduino\libraries\NeoPixelBus_by_Makuna\src/NeoPixelBus.h:67:0,
我相信,NeoPixel 代码也使用 Timer1? 我该如何管理? 谢谢
ESP8266 有一个 Ticker class 可以满足你的目的。
如果您尝试 运行 在回调中花费太长时间的事情,我有一个怪癖,在这种情况下,推荐的使用方法是设置一个标志,然后在循环中检查该标志,做你的事情并重置标志。如果你有一些短的,你可以直接在回调中完成。
这是一个例子。
#include <Ticker.h>
bool doEveryOneMsStuffNow = false; // start with flag false
Ticker everyOneMs;
void setup() {
// ...
everyOneMs.attach(0.001, []() { doEveryOneMsStuffNow = true; }); // lambda call back - this one just sets the flag to true
// ...
}
void loop() {
// ...
if (doEveryOneMsStuffNow) {
doEveryOneMsStuffNow = false; // reset the flag
// do what needs to be done every 1 ms
}
// ...
}