Teensy 4.1与OnePinCapSense库兼容问题:类型转换编译错误
解决Teensy 4.1上OnePinCapSense库的编译类型转换错误
问题背景
在Teensy 4.1上使用OnePinCapSense库实现单引脚电容传感时,出现了32位指针到8位指针的类型转换编译错误,尝试引入pins_arduino.h未解决问题。
编译错误信息
d:\Documents\Arduino\libraries\OnePinCapSense-master\OnePinCapSense.cpp: In member function 'int OnePinCapSense::readCapacitivePin(int)': d:\Documents\Arduino\libraries\OnePinCapSense-master\OnePinCapSense.cpp:58:6: error: cannot convert 'volatile uint32_t* {aka volatile long unsigned int*}' to 'volatile uint8_t* {aka volatile unsigned char*}' in assignment ddr = portModeRegister(port); // get the ddr ^ d:\Documents\Arduino\libraries\OnePinCapSense-master\OnePinCapSense.cpp:59:8: error: cannot convert 'volatile uint32_t* {aka volatile long unsigned int*}' to 'volatile uint8_t* {aka volatile unsigned char*}' in assignment pinIn = portInputRegister(port); // port input register ^ d:\Documents\Arduino\libraries\OnePinCapSense-master\OnePinCapSense.cpp:60:9: error: cannot convert 'volatile uint32_t* {aka volatile long unsigned int*}' to 'volatile uint8_t* {aka volatile unsigned char*}' in assignment pinOut = portOutputRegister(port); ^ exit status 1 Compilation error: exit status 1
测试代码
#include "OnePinCapSense.h" //input pins int capSensePin2 = 2; int capSensePin3 = 3; int capSensePin4 = 4; int capSensePin5 = 5; // baseLine is the maximum quiescent value for all sensor pins. // It will be determined by the calibrate function below. int baseLine = 0 ; // offset will be added to the baseLine to provide a value // to determine when a sensor is touched. const int offset = 50 ; // after calibration, touched will be set by adding offset to the // calibrated baseLine int touched = 0 ; // Cap sense values returned from the library. // There is a seperate value for each sensor to allow for // Multi-touch int capSense2 ; int capSense3 ; int capSense4 ; int capSense5 ; // create an instance of OnePinCapSense class OnePinCapSense opcs = OnePinCapSense(); int calibrate() { int sample = 0 ; for(int i = 2 ; i < 11 ; i+=2) { // take 30 samples and return the highest value for the pin for( int j = 0 ; j < 30 ; j++ ) { sample = opcs.readCapacitivePin(i) ; if( sample > baseLine) { baseLine = sample ; } } } touched = baseLine + offset ; return touched; } // end of calibrate void setup() { Serial.begin(9600); calibrate() ; // give some time to bring up the serial monitor delay(1000) ; Serial.print("Baseline: ") ; Serial.println(baseLine) ; Serial.print("Offset: ") ; Serial.println(offset) ; Serial.print("Touched: ") ; Serial.println(touched) ; } void loop() { capSense2 = opcs.readCapacitivePin(capSensePin2) ; if( capSense2 > touched) { Serial.print("Pin2 On \n"); } else { } capSense3 = opcs.readCapacitivePin(capSensePin3) ; if( capSense3 > touched) { Serial.print("Pin3 On \n"); } else { } capSense4 = opcs.readCapacitivePin(capSensePin4) ; if( capSense4 > touched) { Serial.print("Pin4 On"); } else { } capSense5 = opcs.readCapacitivePin(capSensePin5) ; if( capSense5 > touched) { Serial.print("Pin5 On"); } else { } }
解决方案
错误根源是Teensy 4.1的GPIO端口寄存器为32位(uint32_t*类型),但OnePinCapSense库的变量声明为8位(volatile uint8_t*类型),导致类型不兼容。修改库代码即可解决:
打开
OnePinCapSense.cpp文件,找到readCapacitivePin函数内的变量声明:
原代码:volatile uint8_t* ddr; volatile uint8_t* pinIn; volatile uint8_t* pinOut;修改为:
volatile uint32_t* ddr; volatile uint32_t* pinIn; volatile uint32_t* pinOut;检查
OnePinCapSense.h文件,如果有相关的类型声明,同步修改为uint32_t类型。重新编译代码,错误即可消除。
补充说明
- Teensy 4.x系列采用32位宽的GPIO端口寄存器,而传统AVR Arduino使用8位寄存器,这是类型转换错误的核心原因。
- 修改库的变量类型后,无需额外引入
pins_arduino.h,库本身已间接包含相关定义,修改后可直接适配Teensy的寄存器结构。
内容的提问来源于stack exchange,提问作者Jesse
相关产品推荐
相关产品推荐

