当我尝试构建 teeny 4.1 编码器>speedTest.ino 示例时,出现类型转换错误,从 volatile uint32_t* 到 volatile unsigned char*
When I try to build the teeny 4.1 encoder>speedTest.ino example I get a type conversion error, from volatile uint32_t* to volatile unsigned char*
当我尝试构建 teeny 4.1 编码器>speedTest.ino 示例时,出现以下错误:
错误:无法在初始化中将'volatile uint32_t {aka volatile long unsigned int}'转换为'volatile unsigned char*'
#define portOutputRegister(pin) ((digital_pin_to_info_PGM[(pin)].reg + 0))**
有关以下错误的更多详细信息。
硬件和软件
木板
青少年 4.1
Arduino IDE 版本
1.8.19
Teensyduino 版本 1.56,适用于 windows 7 及更高版本(今天 3/22/2022 从 teensyduino 网站下载)
板子是 Teensy 4.1
我的操作系统是Windows10 pro
Arduino 草图
使用包含的编码器>speedtest.ino 最新版本,从 https://github.com/PaulStoffregen/Encoder 下载。 Teensyduino 1.56 附带的版本也会出现同样的错误。
/* Encoder Library - SpeedTest - for measuring maximum Encoder speed
* http://www.pjrc.com/teensy/td_libs_Encoder.html
*
* This example code is in the public domain.
*/
// This SpeedTest example provides a simple way to verify how much
// CPU time Encoder is consuming. Connect a DC voltmeter to the
// output pin and measure the voltage while the encoder is stopped
// or running at a very slow speed. Even though the pin is rapidly
// pulsing, a DC voltmeter will show the average voltage. Due to
// software timing, it will read a number much less than a steady
// logic high, but this number will give you a baseline reading
// for output with minimal interrupt overhead. Then increase the
// encoder speed. The voltage will decrease as the processor spends
// more time in Encoder's interrupt routines counting the pulses
// and less time pulsing the output pin. When the voltage is
// close to zero and will not decrease any farther, you have reached
// the absolute speed limit. Or, if using a mechanical system where
// you reach a speed limit imposed by your motors or other hardware,
// the amount this voltage has decreased, compared to the baseline,
// should give you a good approximation of the portion of available
// CPU time Encoder is consuming at your maximum speed.
// Encoder requires low latency interrupt response. Available CPU
// time does NOT necessarily prove or guarantee correct performance.
// If another library, like NewSoftSerial, is disabling interrupts
// for lengthy periods of time, Encoder can be prevented from
// properly counting the intput signals while interrupt are disabled.
// This optional setting causes Encoder to use more optimized code,
// but the downside is a conflict if any other part of your sketch
// or any other library you're using requires attachInterrupt().
// It must be defined before Encoder.h is included.
//#define ENCODER_OPTIMIZE_INTERRUPTS
#include <Encoder.h>
#include "pins_arduino.h"
// Change these two numbers to the pins connected to your encoder
// or shift register circuit which emulates a quadrature encoder
// case 1: both pins are interrupts
// case 2: only first pin used as interrupt
Encoder myEnc(5, 6);
// Connect a DC voltmeter to this pin.
const int outputPin = 12;
/* This simple circuit, using a Dual Flip-Flop chip, can emulate
quadrature encoder signals. The clock can come from a fancy
function generator or a cheap 555 timer chip. The clock
frequency can be measured with another board running FreqCount
http://www.pjrc.com/teensy/td_libs_FreqCount.html
+5V
| Quadrature Encoder Signal Emulator
Clock |
Input o----*-------------------------- ---------------------------o Output1
| |14 | |
| _______|_______ | | _______________
| | CD4013 | | | | CD4013 |
| 5 | | 1 | | 9 | | 13
---------| D Q |-----|----*----| D Q |------o Output2
| | | | | | |
| | 3 | | | 11 | |
| ----|> Clk | ---------|> Clk |
| | | | |
| 6 | | 8 | |
| ----| S | ----| S |
| | | | | | |
| | 4 | _ | 2 | 10 | _ | 12
| *----| R Q |--- *----| R Q |----
| | | | | | | |
| | |_______________| | |_______________| |
| | | | |
| | | 7 | |
| | | | |
--------------------------------------------------------------
| | |
| | |
----- ----- -----
--- --- ---
- - -
*/
void setup() {
pinMode(outputPin, OUTPUT);
}
#if defined(__AVR__) || defined(TEENSYDUINO)
#define REGTYPE unsigned char
#else
#define REGTYPE unsigned long
#endif
void loop() {
volatile int count = 0;
volatile REGTYPE *reg = portOutputRegister(digitalPinToPort(outputPin));
REGTYPE mask = digitalPinToBitMask(outputPin);
while (1) {
myEnc.read(); // Read the encoder while interrupts are enabled.
noInterrupts();
*reg |= mask; // Pulse the pin high, while interrupts are disabled.
count = count + 1;
*reg &= ~mask;
interrupts();
}
}
完整错误读数
Arduino: 1.8.19 Hourly Build 2019/02/04 10:33 (Windows 10), TD: 1.56, Board: "Teensy 4.1, Serial, 600 MHz, Faster, US English"
In file included from C:\Program Files (x86)\Arduino\hardware\teensy\avr\cores\teensy4/core_pins.h:33:0,
from C:\Program Files (x86)\Arduino\hardware\teensy\avr\cores\teensy4/wiring.h:39,
from C:\Program Files (x86)\Arduino\hardware\teensy\avr\cores\teensy4/WProgram.h:45,
from C:\Users\name\AppData\Local\Temp\arduino_build_426018\pch\Arduino.h:6:
SpeedTest: In function 'void loop()':
C:\Program Files (x86)\Arduino\hardware\teensy\avr\cores\teensy4/pins_arduino.h:149:75: error: cannot convert 'volatile uint32_t* {aka volatile long unsigned int*}' to 'volatile unsigned char*' in initialization
#define portOutputRegister(pin) ((digital_pin_to_info_PGM[(pin)].reg + 0))
^
C:\Users\name~1\AppData\Local\Temp\arduino_modified_sketch_275677\SpeedTest.ino:101:27: note: in expansion of macro 'portOutputRegister'
volatile REGTYPE *reg = portOutputRegister(digitalPinToPort(outputPin));
^
C:\Users\name~1\AppData\Local\Temp\arduino_modified_sketch_275677\SpeedTest.pde: At global scope:
SpeedTest:46: error: redefinition of 'Encoder myEnc'
Encoder myEnc(5, 6);
^
C:\Users\name~1\AppData\Local\Temp\arduino_modified_sketch_275677\SpeedTest.ino:46:9: note: 'Encoder myEnc' previously declared here
Encoder myEnc(5, 6);
^
SpeedTest:49: error: redefinition of 'const int outputPin'
const int outputPin = 12;
^
C:\Users\name~1\AppData\Local\Temp\arduino_modified_sketch_275677\SpeedTest.ino:49:11: note: 'const int outputPin' previously defined here
const int outputPin = 12;
^
SpeedTest: In function 'void setup()':
SpeedTest:89: error: redefinition of 'void setup()'
void setup() {
^
C:\Users\name~1\AppData\Local\Temp\arduino_modified_sketch_275677\SpeedTest.ino:89:6: note: 'void setup()' previously defined here
void setup() {
^
SpeedTest: In function 'void loop()':
SpeedTest:99: error: redefinition of 'void loop()'
void loop() {
^
C:\Users\name~1\AppData\Local\Temp\arduino_modified_sketch_275677\SpeedTest.ino:99:6: note: 'void loop()' previously defined here
void loop() {
^
In file included from C:\Program Files (x86)\Arduino\hardware\teensy\avr\cores\teensy4/core_pins.h:33:0,
from C:\Program Files (x86)\Arduino\hardware\teensy\avr\cores\teensy4/wiring.h:39,
from C:\Program Files (x86)\Arduino\hardware\teensy\avr\cores\teensy4/WProgram.h:45,
from C:\Users\name~1\AppData\Local\Temp\arduino_build_426018\pch\Arduino.h:6:
C:\Program Files (x86)\Arduino\hardware\teensy\avr\cores\teensy4/pins_arduino.h:149:75: error: cannot convert 'volatile uint32_t* {aka volatile long unsigned int*}' to 'volatile unsigned char*' in initialization
#define portOutputRegister(pin) ((digital_pin_to_info_PGM[(pin)].reg + 0))
^
C:\Users\name~1\AppData\Local\Temp\arduino_modified_sketch_275677\SpeedTest.pde:101:27: note: in expansion of macro 'portOutputRegister'
volatile REGTYPE *reg = portOutputRegister(digitalPinToPort(outputPin));
^
redefinition of 'Encoder myEnc'
This report would have more information with
"Show verbose output during compilation"
option enabled in File -> Preferences.
我进行了搜索,但无法在任何地方找到答案。我在 Github here 上发现了类似的问题,但版本不同:
https://github.com/PaulStoffregen/Encoder/issues/44
但是没有“direct_pin_red.h”,这就是答案所说的添加代码的内容。
他说要将以下代码添加到该文件
#if defined(__IMXRT1062__)
#define IO_REG_TYPE uint32_t
#define PIN_TO_BASEREG(pin) (portInputRegister(digitalPinToPort(pin)))
#define PIN_TO_BITMASK(pin) (digitalPinToBitMask(pin))
#define DIRECT_PIN_READ(base, mask) (((*(base)) & (mask)) ? 1 : 0)
我在 Arduino\hardware\teensy\avr\libraries\Encoder\utility\direct_pin_read.h
中找到了一个具有类似代码的文件
#define IO_REG_TYPE uint32_t
#define PIN_TO_BASEREG(pin) (portOutputRegister(pin))
#define PIN_TO_BITMASK(pin) (digitalPinToBitMask(pin))
#define DIRECT_PIN_READ(base, mask) (((*(base)) & (mask)) ? 1 : 0)
唯一的区别是 git 答案中的 PIN_TO_BASEREG 定义是
#define PIN_TO_BASEREG(引脚)(端口输出寄存器(引脚))
对
#define PIN_TO_BASEREG(pin) (portInputRegister(digitalPinToPort(pin)))
所以我尝试更改它以匹配给定的解决方案,但我得到了同样的错误。
我不确定为什么将此称为 volatile uint32_t* 到 volatile unsigned char* 之间的转换错误,或者我需要更改定义的地方。
宏定义明显错误。看起来它是为旧的 AVR Teensies 完成的,并没有针对 32 位 ARM 板进行调整。对于 T4.x,您只需将其替换为
// #if defined(__AVR__) || defined(TEENSYDUINO)
// #define REGTYPE unsigned char
// #else
// #define REGTYPE unsigned long
// #endif
using REGTYPE = uint32_t;
编译。您也可以替换完整的寄存器内容并简单地使用
#include <Encoder.h>
#include "pins_arduino.h"
// Change these two numbers to the pins connected to your encoder
// or shift register circuit which emulates a quadrature encoder
// case 1: both pins are interrupts
// case 2: only first pin used as interrupt
Encoder myEnc(5, 6);
// Connect a DC voltmeter to this pin.
const int outputPin = 12;
void setup() {
pinMode(outputPin, OUTPUT);
}
void loop() {
volatile int count = 0;
while (1) {
myEnc.read(); // Read the encoder while interrupts are enabled.
noInterrupts();
digitalWriteFast(outputPin, HIGH);
count = count + 1;
digitalWriteFast(outputPin, LOW);
interrupts();
}
}
但是,我不确定测量对于 600MHz T4 是否有意义。 outputPin 将仅高几纳秒...
当我尝试构建 teeny 4.1 编码器>speedTest.ino 示例时,出现以下错误:
错误:无法在初始化中将'volatile uint32_t {aka volatile long unsigned int}'转换为'volatile unsigned char*' #define portOutputRegister(pin) ((digital_pin_to_info_PGM[(pin)].reg + 0))**
有关以下错误的更多详细信息。
硬件和软件 木板 青少年 4.1
Arduino IDE 版本 1.8.19
Teensyduino 版本 1.56,适用于 windows 7 及更高版本(今天 3/22/2022 从 teensyduino 网站下载)
板子是 Teensy 4.1
我的操作系统是Windows10 pro
Arduino 草图
使用包含的编码器>speedtest.ino 最新版本,从 https://github.com/PaulStoffregen/Encoder 下载。 Teensyduino 1.56 附带的版本也会出现同样的错误。
/* Encoder Library - SpeedTest - for measuring maximum Encoder speed
* http://www.pjrc.com/teensy/td_libs_Encoder.html
*
* This example code is in the public domain.
*/
// This SpeedTest example provides a simple way to verify how much
// CPU time Encoder is consuming. Connect a DC voltmeter to the
// output pin and measure the voltage while the encoder is stopped
// or running at a very slow speed. Even though the pin is rapidly
// pulsing, a DC voltmeter will show the average voltage. Due to
// software timing, it will read a number much less than a steady
// logic high, but this number will give you a baseline reading
// for output with minimal interrupt overhead. Then increase the
// encoder speed. The voltage will decrease as the processor spends
// more time in Encoder's interrupt routines counting the pulses
// and less time pulsing the output pin. When the voltage is
// close to zero and will not decrease any farther, you have reached
// the absolute speed limit. Or, if using a mechanical system where
// you reach a speed limit imposed by your motors or other hardware,
// the amount this voltage has decreased, compared to the baseline,
// should give you a good approximation of the portion of available
// CPU time Encoder is consuming at your maximum speed.
// Encoder requires low latency interrupt response. Available CPU
// time does NOT necessarily prove or guarantee correct performance.
// If another library, like NewSoftSerial, is disabling interrupts
// for lengthy periods of time, Encoder can be prevented from
// properly counting the intput signals while interrupt are disabled.
// This optional setting causes Encoder to use more optimized code,
// but the downside is a conflict if any other part of your sketch
// or any other library you're using requires attachInterrupt().
// It must be defined before Encoder.h is included.
//#define ENCODER_OPTIMIZE_INTERRUPTS
#include <Encoder.h>
#include "pins_arduino.h"
// Change these two numbers to the pins connected to your encoder
// or shift register circuit which emulates a quadrature encoder
// case 1: both pins are interrupts
// case 2: only first pin used as interrupt
Encoder myEnc(5, 6);
// Connect a DC voltmeter to this pin.
const int outputPin = 12;
/* This simple circuit, using a Dual Flip-Flop chip, can emulate
quadrature encoder signals. The clock can come from a fancy
function generator or a cheap 555 timer chip. The clock
frequency can be measured with another board running FreqCount
http://www.pjrc.com/teensy/td_libs_FreqCount.html
+5V
| Quadrature Encoder Signal Emulator
Clock |
Input o----*-------------------------- ---------------------------o Output1
| |14 | |
| _______|_______ | | _______________
| | CD4013 | | | | CD4013 |
| 5 | | 1 | | 9 | | 13
---------| D Q |-----|----*----| D Q |------o Output2
| | | | | | |
| | 3 | | | 11 | |
| ----|> Clk | ---------|> Clk |
| | | | |
| 6 | | 8 | |
| ----| S | ----| S |
| | | | | | |
| | 4 | _ | 2 | 10 | _ | 12
| *----| R Q |--- *----| R Q |----
| | | | | | | |
| | |_______________| | |_______________| |
| | | | |
| | | 7 | |
| | | | |
--------------------------------------------------------------
| | |
| | |
----- ----- -----
--- --- ---
- - -
*/
void setup() {
pinMode(outputPin, OUTPUT);
}
#if defined(__AVR__) || defined(TEENSYDUINO)
#define REGTYPE unsigned char
#else
#define REGTYPE unsigned long
#endif
void loop() {
volatile int count = 0;
volatile REGTYPE *reg = portOutputRegister(digitalPinToPort(outputPin));
REGTYPE mask = digitalPinToBitMask(outputPin);
while (1) {
myEnc.read(); // Read the encoder while interrupts are enabled.
noInterrupts();
*reg |= mask; // Pulse the pin high, while interrupts are disabled.
count = count + 1;
*reg &= ~mask;
interrupts();
}
}
完整错误读数
Arduino: 1.8.19 Hourly Build 2019/02/04 10:33 (Windows 10), TD: 1.56, Board: "Teensy 4.1, Serial, 600 MHz, Faster, US English"
In file included from C:\Program Files (x86)\Arduino\hardware\teensy\avr\cores\teensy4/core_pins.h:33:0,
from C:\Program Files (x86)\Arduino\hardware\teensy\avr\cores\teensy4/wiring.h:39,
from C:\Program Files (x86)\Arduino\hardware\teensy\avr\cores\teensy4/WProgram.h:45,
from C:\Users\name\AppData\Local\Temp\arduino_build_426018\pch\Arduino.h:6:
SpeedTest: In function 'void loop()':
C:\Program Files (x86)\Arduino\hardware\teensy\avr\cores\teensy4/pins_arduino.h:149:75: error: cannot convert 'volatile uint32_t* {aka volatile long unsigned int*}' to 'volatile unsigned char*' in initialization
#define portOutputRegister(pin) ((digital_pin_to_info_PGM[(pin)].reg + 0))
^
C:\Users\name~1\AppData\Local\Temp\arduino_modified_sketch_275677\SpeedTest.ino:101:27: note: in expansion of macro 'portOutputRegister'
volatile REGTYPE *reg = portOutputRegister(digitalPinToPort(outputPin));
^
C:\Users\name~1\AppData\Local\Temp\arduino_modified_sketch_275677\SpeedTest.pde: At global scope:
SpeedTest:46: error: redefinition of 'Encoder myEnc'
Encoder myEnc(5, 6);
^
C:\Users\name~1\AppData\Local\Temp\arduino_modified_sketch_275677\SpeedTest.ino:46:9: note: 'Encoder myEnc' previously declared here
Encoder myEnc(5, 6);
^
SpeedTest:49: error: redefinition of 'const int outputPin'
const int outputPin = 12;
^
C:\Users\name~1\AppData\Local\Temp\arduino_modified_sketch_275677\SpeedTest.ino:49:11: note: 'const int outputPin' previously defined here
const int outputPin = 12;
^
SpeedTest: In function 'void setup()':
SpeedTest:89: error: redefinition of 'void setup()'
void setup() {
^
C:\Users\name~1\AppData\Local\Temp\arduino_modified_sketch_275677\SpeedTest.ino:89:6: note: 'void setup()' previously defined here
void setup() {
^
SpeedTest: In function 'void loop()':
SpeedTest:99: error: redefinition of 'void loop()'
void loop() {
^
C:\Users\name~1\AppData\Local\Temp\arduino_modified_sketch_275677\SpeedTest.ino:99:6: note: 'void loop()' previously defined here
void loop() {
^
In file included from C:\Program Files (x86)\Arduino\hardware\teensy\avr\cores\teensy4/core_pins.h:33:0,
from C:\Program Files (x86)\Arduino\hardware\teensy\avr\cores\teensy4/wiring.h:39,
from C:\Program Files (x86)\Arduino\hardware\teensy\avr\cores\teensy4/WProgram.h:45,
from C:\Users\name~1\AppData\Local\Temp\arduino_build_426018\pch\Arduino.h:6:
C:\Program Files (x86)\Arduino\hardware\teensy\avr\cores\teensy4/pins_arduino.h:149:75: error: cannot convert 'volatile uint32_t* {aka volatile long unsigned int*}' to 'volatile unsigned char*' in initialization
#define portOutputRegister(pin) ((digital_pin_to_info_PGM[(pin)].reg + 0))
^
C:\Users\name~1\AppData\Local\Temp\arduino_modified_sketch_275677\SpeedTest.pde:101:27: note: in expansion of macro 'portOutputRegister'
volatile REGTYPE *reg = portOutputRegister(digitalPinToPort(outputPin));
^
redefinition of 'Encoder myEnc'
This report would have more information with
"Show verbose output during compilation"
option enabled in File -> Preferences.
我进行了搜索,但无法在任何地方找到答案。我在 Github here 上发现了类似的问题,但版本不同:
https://github.com/PaulStoffregen/Encoder/issues/44
但是没有“direct_pin_red.h”,这就是答案所说的添加代码的内容。
他说要将以下代码添加到该文件
#if defined(__IMXRT1062__)
#define IO_REG_TYPE uint32_t
#define PIN_TO_BASEREG(pin) (portInputRegister(digitalPinToPort(pin)))
#define PIN_TO_BITMASK(pin) (digitalPinToBitMask(pin))
#define DIRECT_PIN_READ(base, mask) (((*(base)) & (mask)) ? 1 : 0)
我在 Arduino\hardware\teensy\avr\libraries\Encoder\utility\direct_pin_read.h
中找到了一个具有类似代码的文件#define IO_REG_TYPE uint32_t
#define PIN_TO_BASEREG(pin) (portOutputRegister(pin))
#define PIN_TO_BITMASK(pin) (digitalPinToBitMask(pin))
#define DIRECT_PIN_READ(base, mask) (((*(base)) & (mask)) ? 1 : 0)
唯一的区别是 git 答案中的 PIN_TO_BASEREG 定义是
#define PIN_TO_BASEREG(引脚)(端口输出寄存器(引脚))
对
#define PIN_TO_BASEREG(pin) (portInputRegister(digitalPinToPort(pin)))
所以我尝试更改它以匹配给定的解决方案,但我得到了同样的错误。
我不确定为什么将此称为 volatile uint32_t* 到 volatile unsigned char* 之间的转换错误,或者我需要更改定义的地方。
宏定义明显错误。看起来它是为旧的 AVR Teensies 完成的,并没有针对 32 位 ARM 板进行调整。对于 T4.x,您只需将其替换为
// #if defined(__AVR__) || defined(TEENSYDUINO)
// #define REGTYPE unsigned char
// #else
// #define REGTYPE unsigned long
// #endif
using REGTYPE = uint32_t;
编译。您也可以替换完整的寄存器内容并简单地使用
#include <Encoder.h>
#include "pins_arduino.h"
// Change these two numbers to the pins connected to your encoder
// or shift register circuit which emulates a quadrature encoder
// case 1: both pins are interrupts
// case 2: only first pin used as interrupt
Encoder myEnc(5, 6);
// Connect a DC voltmeter to this pin.
const int outputPin = 12;
void setup() {
pinMode(outputPin, OUTPUT);
}
void loop() {
volatile int count = 0;
while (1) {
myEnc.read(); // Read the encoder while interrupts are enabled.
noInterrupts();
digitalWriteFast(outputPin, HIGH);
count = count + 1;
digitalWriteFast(outputPin, LOW);
interrupts();
}
}
但是,我不确定测量对于 600MHz T4 是否有意义。 outputPin 将仅高几纳秒...