main.c

来自「最新版IAR FOR ARM(EWARM)5.11中的代码例子」· C语言 代码 · 共 451 行 · 第 1/2 页

C
451
字号


/*-----------------------------------------------------------------------------
 * Function Name       : configure_leds
 * Object              : Configure pios to control led states
 *-----------------------------------------------------------------------------*/
static void configure_leds(void)
{
  /* Configure the pin in output */
  BASE_PIO_LED->PIO_OER = (LED_A | LED_B);
  /* Set the PIO controller in PIO mode instead of peripheral mode */
  BASE_PIO_LED->PIO_PER = (LED_A | LED_B);
  /* Disable pull-up */
  BASE_PIO_LED->PIO_PPUDR = (LED_A | LED_B);

  /* Set the default state for the led */
  if (led_a_active)
    BASE_PIO_LED->PIO_SODR = LED_A;
  else
    BASE_PIO_LED->PIO_CODR = LED_A;

  if (led_b_active)
    BASE_PIO_LED->PIO_SODR = LED_B;
  else
    BASE_PIO_LED->PIO_CODR = LED_B;
}


/*-----------------------------------------------------------------------------
 * Function Name       : timer_handler
 * Object              : Handler for TC interrupt
 *-----------------------------------------------------------------------------*/
void timer_handler(void)
{
  volatile unsigned long dummy;
  /* Clear status bit */
  dummy = AT91C_BASE_TC0->TC_SR;

  /* Toggle LED state */
  if (BASE_PIO_LED->PIO_ODSR & LED_B) {
    BASE_PIO_LED->PIO_CODR = LED_B;
  } else {
    BASE_PIO_LED->PIO_SODR = LED_B;
  }
}


/*-----------------------------------------------------------------------------
 * Function Name       : configure_tc
 * Object              : Configure TC
 *-----------------------------------------------------------------------------*/
static void configure_tc(void)
{
    volatile unsigned long dummy;

    /* Enable periph clock for the PIO controller */
    AT91C_BASE_PMC->PMC_PCER = (1 << AT91C_ID_TC0);

    /* Enable the periph */
    /* Disable the clock and the interrupts */
    AT91C_BASE_TC0->TC_CCR = AT91C_TC_CLKDIS;
    AT91C_BASE_TC0->TC_IDR = 0xFFFFFFFF;

    /* Clear status bit */
    dummy = AT91C_BASE_TC0->TC_SR;

    /* Set the Mode of the Timer Counter */
    AT91C_BASE_TC0->TC_CMR = AT91C_TC_CLKS_TIMER_DIV5_CLOCK | AT91C_TC_CPCTRG;
    AT91C_BASE_TC0->TC_RC = AT91B_MASTER_CLOCK >> 12;  /* MCKR divided by 1024 * 4 */

    /* Enable interrupts */
    /* Disable the interrupt on the interrupt controller */
    AT91C_BASE_AIC->AIC_IDCR = (1 << AT91C_ID_TC0);
    /* Save the interrupt handler routine pointer and the interrupt priority */
    AT91C_BASE_AIC->AIC_SVR[AT91C_ID_TC0] = (unsigned long) timer_handler;
    /* Store the Source Mode Register */
    AT91C_BASE_AIC->AIC_SMR[AT91C_ID_TC0] = AT91C_AIC_SRCTYPE_INT_HIGH_LEVEL | AT91C_AIC_PRIOR_LOWEST;
    /* Clear the interrupt on the interrupt controller */
    AT91C_BASE_AIC->AIC_ICCR = (1 << AT91C_ID_TC0);

    AT91C_BASE_TC0->TC_IER = AT91C_TC_CPCS;

    /* Enable the interrupt on the interrupt controller */
    AT91C_BASE_AIC->AIC_IECR = (1 << AT91C_ID_TC0);

    /* Enable the LED B timer */
    if (led_b_active) {
      /* Clock is started */
      AT91C_BASE_TC0->TC_CCR = AT91C_TC_CLKEN;
      /* Counter is reset and the clock is started */
      AT91C_BASE_TC0->TC_CCR = AT91C_TC_SWTRG;
    }
}


/*----------------------------------------------------------------------------
 * Function Name       : dbgu_print_ascii
 * Object              : This function is used to send a string through the
 *                       DBGU channel (Very low level debugging)
 *----------------------------------------------------------------------------*/
void dbgu_print_ascii(const char *buffer)
{
    while (*buffer != '\0') {
        while (!(AT91C_BASE_DBGU->DBGU_CSR & AT91C_US_TXRDY));               
        AT91C_BASE_DBGU->DBGU_THR = (*buffer++ & 0x1FF);
    }
}


/*----------------------------------------------------------------------------
 * Function Name       : dbgu_print_hex8
 * Object              : This function is used to print a 32-bit value in hexa
 *----------------------------------------------------------------------------*/
void dbgu_print_hex8(unsigned long value)
{
    char c = 0;
    char shift = sizeof(unsigned long) * 8;

    dbgu_print_ascii("0x");
    do {
        shift -= 4;
        while (!(AT91C_BASE_DBGU->DBGU_CSR & AT91C_US_TXRDY));
        c = ((value >> shift) & 0xF);
        if (c > 9)
	  AT91C_BASE_DBGU->DBGU_THR = (('A' + (c - 10)) & 0x1FF);
        else
	  AT91C_BASE_DBGU->DBGU_THR = (('0' + c) & 0x1FF);
    } while (shift != 0);
}


/*-----------------------------------------------------------------------------
 * Function Name       : configure_dbgu
 * Object              : Configure DBGU
 *-----------------------------------------------------------------------------*/
static void configure_dbgu (void)
{
    /* Reset and disable receiver */
    AT91C_BASE_DBGU->DBGU_CR = AT91C_US_RSTRX | AT91C_US_RSTTX;

    /* Disable interrupts */
    AT91C_BASE_DBGU->DBGU_IDR = 0xFFFFFFFF;

    /* Configure PIOs for DBGU */
    AT91C_BASE_PIOA->PIO_ASR = AT91C_PA9_DRXD | AT91C_PA10_DTXD;
    AT91C_BASE_PIOA->PIO_BSR = 0;
    AT91C_BASE_PIOA->PIO_PDR = AT91C_PA9_DRXD | AT91C_PA10_DTXD;

    /* === Configure serial link === */
    /* Define the baud rate divisor register [BRGR = MCK / (115200 * 16)] */
    AT91C_BASE_DBGU->DBGU_BRGR = 26;
    /* Define the USART mode */
    AT91C_BASE_DBGU->DBGU_MR = AT91C_US_CHMODE_NORMAL;

    /* Disable the RX and TX PDC transfer requests */
    AT91C_BASE_DBGU->DBGU_PTCR = AT91C_PDC_RXTDIS;
    AT91C_BASE_DBGU->DBGU_PTCR = AT91C_PDC_TXTDIS;

    /* Enable transmitter */
    AT91C_BASE_DBGU->DBGU_CR = AT91C_US_TXEN;
}


/*-----------------------------------------------------------------------------
 * Function Name       : wait
 * Object              : Tempo using jiffies (updated by PITC)
 *-----------------------------------------------------------------------------*/
void wait (unsigned long ms)
{
    volatile unsigned long current_time = jiffies;
    unsigned long prev_jiffies;
    unsigned long target_time = current_time + ms;

    /* Handle the counter overflow */
    if (target_time < current_time) {
        prev_jiffies = current_time;
        while (prev_jiffies <= jiffies)
            prev_jiffies = jiffies;
    }
    /* Loop until the target time is reached */
    while (jiffies < target_time);
}


/*-----------------------------------------------------------------------------
 * Function Name       : Main
 * Object              : Software entry point
 *-----------------------------------------------------------------------------*/
int main()
{
    /* ==== PITC configuration ==== */
    configure_pit();

    /* ==== Timer Counter configuration ==== */
    configure_tc();

    /* === BUTTON configuration (PIO in INPUT) === */
    configure_buttons();

    /* === LED configuration (PIO in OUTPUT) === */
    configure_leds();

    /* ==== DBGU configuration ==== */
    configure_dbgu();

    __enable_interrupt();
    
    dbgu_print_ascii("AT91SAM7S Getting Started program launched ...\n\r");
    dbgu_print_ascii("AT91SAM7S chip ID : ");
    dbgu_print_hex8(AT91C_BASE_DBGU->DBGU_CIDR);
    dbgu_print_ascii("\n\r");

    while (1) {
        if (led_a_active) {
            /* Switch on the led */
            wait(500);
            BASE_PIO_LED->PIO_CODR = LED_A;

            /* Switch off the led */
            wait(500);
            BASE_PIO_LED->PIO_SODR = LED_A;
        }
    }
}

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?