使用读写寄存器的方法直接读写arduino due的数字和模拟管脚

arduino due 的数字和模拟管脚的控制除了可以使用digitalWrite, digitalRead,analogRead等函数,还可以使用直接寄存器读写的方法来完成。据说直接读写寄存器的方法来控制数字和模拟管脚,速度要比digitalWrite,digitalRead,analogRead要快些,能快多少我没试验,但至少没了函数调用,免去了函数调用堆栈退栈的时间。由于arduino due 的管脚定义与atmel sam cpu的定义不同,使用函数读写还需要进行管脚的映射,也会耗时多些,所以直接使用读写寄存器的方法速度会有所提升。直接读写寄存器控制管脚必须使用sam cpu的定义,先看下arduino due 管脚和cpu管脚的映射关系,如图:

arduino-due-pinout-A4

sam cpu的管脚寄存器有四组,分别对应编号A B C D。比如,如果要读写due D29管脚,实质上是读写sam cpu D6管脚的寄存器。

 

数字管脚的控制

PIO_PER  - write 1's here to enable pin
PIO_OER  - write 1's here to set pins as OUTPUT
PIO_ODR  - write 1's here to set pins as INPUT
PIO_SODR   - write 1's here to set output pins HIGH
PIO_CODR   - write 1's here to set output pins LOW
PIO_PDSR  - read's actual state of the pins on the port.
PIO_PUDR  - write 1's here to switch off internal pull-up for pins
PIO_PUER  - write 1's here to switch on internal pull-up for pins

如果要写due D29管脚,可以使用如下代码:

pinMode (29, OUTPUT) ;

PIOD->PIO_SODR=0x40;

//sam cpu D6 管脚设置为高电平

//sam cpu A组寄存器对应的指针是PIOA,B组寄存器对应的指针是PIOB,依此类推。其中"PIOA->"也可以用"REG_PIOA"代替

//寄存器最右一位对应的是该组第一个管脚(即编号为0的管脚),0x40对应的是编号为6的管脚,在该例中为sam cpu D6管脚

//

PIOD->PIO_CODR=0x40;

//sam cpu D6 管脚设置为低电平

读due D29管脚,可以使用如下代码:

pinMode (29,INPUT) ;

uint8_t flag=PIOD->PIO_PDSR&0x40;//获取sam cpu D6 管脚电平状态

模拟管脚

due A0 ~ A7管脚对应sam cpu 管脚AD7~AD0,对应sam cpu ADC寄存器(从右数)第7~0位

due A8 ~ A11管脚对应sam cpu 管脚AD10~AD13,对应sam cpu ADC寄存器(从右数)第10~13位

读取due A0管脚:

void setup() {       
  Serial.begin(9600); 

 analogReadResolution(12);//设置adc分辨率为12bit

  ADC->ADC_MR |= 0x80;  //set free running mode on ADC 使用该模式可以加快读取速度

  ADC->ADC_CR=2;         // Starts ADC conversion.
  ADC->ADC_CHER = 0x80; //enable ADC on pin A0

  }

void loop() {
  unsigned int i;    
  while((ADC->ADC_ISR & 0x80)==0); // 等待AD转换完毕

 i=ADC->ADC_CDR[7]; //获取sam cpu AD7的值
  }