从volatile uint8_t*到uint8_t*的转换无效

invalid conversion from volatile uint8_t* to uint8_t*

本文关键字:uint8 转换 无效 volatile      更新时间:2023-10-16

我正试图在C++中为AVR设置一个库。这个想法是有一种简单的方法来配置你在每个设备上使用的引脚。这是图书馆:

class PINS{
public:
//ATTRIBUTES
uint8_t* DDRaddr;
uint8_t* PORTaddr;
uint8_t* PINaddr;
int pinnum;
//METHODS
void usepin(volatile uint8_t *pin, int num);};
void PINS::usepin(volatile uint8_t *pin, int num){
this->pinnum=num;
if(pin==&PORTB){
this->DDRaddr=&DDRB;
this->PINaddr=&PINB;
this->PORTaddr=&PORTB;}
if(pin==&PORTC){
this->DDRaddr=&DDRC;
this->PINaddr=&PINC;
this->PORTaddr=&PORTC;}
if(pin==&PORTD){
this->DDRaddr=&DDRD;
this->PINaddr=&PIND;
this->PORTaddr=&PORTD;} 
return;}

这就是所谓的

PINS RS;
RS.usepin(&PORTC, 0);

现在这就是我认为的工作方式:

  1. 编写例如"PINS RS;"以创建类PINS的实例;一个名为RS的新引脚
  2. 写入"RS.usepin(PORTB,0);"以将RS引脚配置为MCU的PORTB0
  3. 使用RS.DDRaddr表示DDR,RS.PINaddr表示PIN,RS.PORTaddr表示PORT寄存器
  4. 使用RS.pinnum作为引脚编号;例如:RS.DDRaddr|=(1<

当我试图在Atmel Studio中构建它时,每一行都会出现以下错误:"this->DDRaddr=&DDRB;"错误显示:

错误1从volatile uint8_t*到uint8_t*的无效转换

在我将uint8_t*DDRaddr作为类成员之前,它曾经工作过。我不明白问题出在哪里,我无法从类似但不完全相同的问题中得出结论。有人知道这个特定代码出了什么问题吗?

显然DDRB的类型是volatile uint8_t,但您正试图将其地址分配给uint8_t*。这是不允许的——volatile在这方面遵循与const相同的规则。

如果您打算像这样使用成员,则必须将它们声明为指向volatile:的指针

class PINS{
public:
//ATTRIBUTES
volatile uint8_t* DDRaddr;
volatile uint8_t* PORTaddr;
volatile uint8_t* PINaddr;
// ... rest as before

"volatile"表示读取或写入值是无法优化的副作用。读取或写入volatile值可能会影响某些硬件,可能会导致该值以与您想象的不同的方式进行修改,等等。因此,编译器通常会做出的假设(如果您将x存储到变量中,然后再次读取,结果将是x,等等)是错误的。

如果去掉了易失性,那么编译器可能会生成错误的代码。因此,你必须明确而不是含蓄地这样做。