配置 ATSAM3x8e 端口输出

Configuring ATSAM3x8e port to output

我在将我的 SAM3x8e 端口配置为输出时遇到问题,当我用万用表检查引脚时,我得到 1.5V,因此端口 A 的引脚 0 没有打开。我相信我将端口引脚配置为正确输出,但我不知道,我身上没有调试器来查看内部发生的情况。

#include "sam.h"

uint32_t right_tick = 0;
uint32_t left_tick = 0;
uint32_t LED_status = 1;


void InitializeSystemTimer(void)
{
    const uint32_t tickcount = 1000000;
    // set value countdown restarts to
    SysTick->LOAD = tickcount;
    // set interrupt priority
    NVIC_SetPriority(SysTick_IRQn, 3);
    // restart timer
    SysTick->VAL = 0;
    // set system tick counter ClockSource/8, creates system tick exception when hits 0, enable system tick count,
    SysTick->CTRL = SysTick_CTRL_TICKINT_Msk|SysTick_CTRL_ENABLE_Msk;
}

void InitializeIOPorts(void)
{
    // enable Peripheral Clock on Port A
    PMC->PMC_PCER0 = ID_PIOA;
    
    // configure output pins
    
    // claim Port A control of pin 0, 1, 2
    PIOA->PIO_PER = PIO_PER_P0|PIO_PER_P1|PIO_PER_P2;
    // enable Port A output on pins
    PIOA->PIO_WPMR = PIO_WPMR_WPKEY_Msk;
    // set Port A pin 0, 1, 2 to output
    PIOA->PIO_PER = PIO_PER_P0|PIO_PER_P1|PIO_PER_P2;
    // set Port A pin 0, 1, 2 to be accessed directly by setting Output Write Enable Register
    PIOA->PIO_OWER = PIO_PER_P0|PIO_PER_P1|PIO_PER_P2;
    // set Port A pin 0, 1, 2 to high
    PIOA->PIO_ODSR = PIO_PER_P0|PIO_PER_P1|PIO_PER_P2;

    // configure input pins 
    
    // claim Port A control of pin 3, 4
    PIOA->PIO_PER = PIO_PER_P3|PIO_PER_P4;
    // set pull up resistors on pin 3, 4
    PIOA->PIO_PUER = PIO_PER_P3|PIO_PER_P4;
    // set interrupt on pin 3, 4
    PIOA->PIO_IER = PIO_PER_P3|PIO_PER_P4;
    // enable input change interrupt on Pin 3, 4 by setting mask
    PIOA->PIO_IMR = PIO_PER_P3|PIO_PER_P4;
    
    // set priority and enable interrupt for port A
    NVIC_SetPriority(PIOA_IRQn, 3);
    NVIC_EnableIRQ(PIOA_IRQn);
    
}

void InitializeUart(void)
{
    PMC->PMC_PCER0 = ID_UART;
    // baud rate is 84Mhz/(16*45)
    UART->UART_BRGR = uint32_t(45);
    UART->UART_CR = UART_CR_TXEN|UART_CR_RXEN;
    
    NVIC_SetPriority(UART_IRQn,2);
    NVIC_EnableIRQ(UART_IRQn);
}


void SysTick_Handler(void)
{
    if (LED_status == 0)
    {
        PIOA->PIO_SODR = PIO_PER_P0;
        LED_status = 1;
    }
    else
    {
        PIOA->PIO_CODR = PIO_PER_P0;
        LED_status = 0;
    }
    
}

void PIOA_Handler(void)
{
    uint32_t PORTA_interrupt_status = 0;
    PORTA_interrupt_status = PIOA->PIO_ISR;
    
    if ((PORTA_interrupt_status&PIO_PER_P3) == 1)
    {
        left_tick = left_tick+1;  
    }
    if ((PORTA_interrupt_status&PIO_PER_P4) == 1)
    {
        right_tick = right_tick + 1;
    }
}


void UART_Handler(void)
{
    
}


int main(void)
{
    /* Initialize the SAM system */
    SystemInit();
    InitializeSystemTimer();
    InitializeIOPorts();

    /* Replace with your application code */
    while (1) 
    {
    }
}

您应该仔细检查 Atmel SAM3X8E 数据表 部分 31.6 I/O 行编程示例 中给出的示例。 查看提供的示例:

  • 第 4 至 7 行 I/O 上的四个输出信号(例如驱动 LED), 驱动高电平和低电平,无上拉电阻

和以下配置:

Register Value to be Written
PIO_PER  0x0000FFFF
PIO_PDR  0xFFFF0000
PIO_OER  0x000000FF
PIO_ODR  0xFFFFFF00
PIO_IFER 0x00000F00
PIO_IFDR 0xFFFFF0FF
PIO_SODR 0x00000000
PIO_CODR 0x0FFFFFFF
PIO_IER  0x0F000F00
PIO_IDR  0xF0FFF0FF
PIO_MDER 0x0000000F
PIO_MDDR 0xFFFFFFF0
PIO_PUDR 0xF0F000F0
PIO_PUER 0x0F0FFF0F
PIO_ABSR 0x00F00000
PIO_OWER 0x0000000F
PIO_OWDR 0x0FFFFFF0

我们需要倒数第二个字符(就本例中使用的引脚 4 到 7 而言)来确定寄存器是否应该被编程。例如,“PIO_PER 0x0000FFFF”表示应该对寄存器进行编程。并且,相反,“PIO_PDR 0xFFFF0000”表示寄存器应该保持不变。 因此,可以得到如下配置:

PIOA->PIO_PER  = PIO_PER_P0 | PIO_PER_P1 | PIO_PER_P2;
PIOA->PIO_OER  = PIO_PER_P0 | PIO_PER_P1 | PIO_PER_P2;
PIOA->PIO_IFDR = PIO_PER_P0 | PIO_PER_P1 | PIO_PER_P2;
PIOA->PIO_CODR = PIO_PER_P0 | PIO_PER_P1 | PIO_PER_P2;
PIOA->PIO_IDR  = PIO_PER_P0 | PIO_PER_P1 | PIO_PER_P2;
PIOA->PIO_MDDR = PIO_PER_P0 | PIO_PER_P1 | PIO_PER_P2;
PIOA->PIO_PUDR = PIO_PER_P0 | PIO_PER_P1 | PIO_PER_P2;
PIOA->PIO_OWDR = PIO_PER_P0 | PIO_PER_P1 | PIO_PER_P2;

我没有 SAM3X8E 设备来检查此配置,但上述注意事项可能有助于找到解决问题的方法。