atmel ASF学习笔记

更新时间:2023-06-10 01:17:54 阅读: 评论:0

Atmel asf学习笔记
前言
前一段时间入手了一块Arduino DUE开发板,入手后网上查询资料发现资料很少,并且和很多的模块不兼容,这块板子的IO口只能承受3.3v的电压,如果想使用5v的模块,又要动手做兼容模块。又因为这块板子采用的MCU是SAM3X8E 是一款ARM的主控,就想把它作为cortex M3开发板使用。
环境搭建
开发工具:atmel studio 6.1
烧写工具 :
开发工具可以在Atmel官网下载,可以从arduino中提取
建立工程
为了快速上手这块板子,我决定采用atmel的asf框架
创建示例工程,由于在单片机程序开发中,需要通过串口输入输出调试信息,所以首先要实现串口通讯,这里先创建一个串口通讯程序的模板
接下来就ok了
生成的代码很整洁但是在对于资源有限,效率要求较高的单片机来说还是显得臃肿。
编译通过下载到mcu中
接下来打开串口,查看输出信息
测试通过!
ASF之串口学习
#include <string.h>
#include "asf.h"//包含了所需要的模块
#include "stdio_rial.h"//串口的出入输出定义
#include "conf_board.h"
#include "conf_clock.h"
#include "conf_example.h"//定义了串口中断入口函数,波特率,串口端口号
/** Size of the receive buffer ud by the PDC, in bytes. */
#define BUFFER_SIZE        100  //定义外设DMA控制器缓冲区大小(字节)
/** USART PDC transfer type definition. */
#define PDC_TRANSFER        1  //串口发送类型定义
/** USART FIFO transfer type definition. */
#define BYTE_TRANSFER      0  //串口发送队列类型定义
/** Max buffer number. */
#define MAX_BUF_NUM        1
/** All interrupt mask. */
#define ALL_INTERRUPT_MASK  0xffffffff
/** Timer counter frequency in Hz. */
#define TC_FREQ            1
#define STRING_EOL    "\r"
#define STRING_HEADER "-- USART Serial Example --\r\n" \
        "-- "BOARD_NAME" --\r\n" \
        "-- Compiled: "__DATE__" "__TIME__" --"STRING_EOL
/** Receive buffer. */
static uint8_t gs_puc_buffer[2][BUFFER_SIZE];
沈阳森林公园/** Next Receive buffer. */
static uint8_t gs_puc_nextbuffer[2][BUFFER_SIZE];
/** Current bytes in buffer. */
static uint32_t gs_ul_size_buffer = BUFFER_SIZE;
/** Current bytes in next buffer. */
static uint32_t gs_ul_size_nextbuffer = BUFFER_SIZE;
/** Byte mode read buffer. */
static uint32_t gs_ul_read_buffer = 0;
/** Current transfer mode. */
static uint8_t gs_uc_trans_mode = PDC_TRANSFER;//
/** Buffer number in u. */
static uint8_t gs_uc_buf_num = 0;
/** PDC data packet. */
pdc_packet_t g_st_packet, g_st_nextpacket;
/** Pointer to PDC register ba. */
Pdc *g_p_pdc;
/** Flag of one transfer end. */
static uint8_t g_uc_trannd_flag = 0;
/**
* \brief Interrupt handler for USART. Echo the bytes received and start the
* next receive.
*/
void USART_Handler(void)
{
    uint32_t ul_status;
    /* Read USART Status. */
    //函数返回 p_usart->US_CSR,USART0的基地址  ((Usart  *)0x40098000U) ,US_CSR的偏移地址0x0014
    //由于c语言为结构体分配的空间是连续的所以很容易实现基地址+偏移地址
    ul_status = usart_get_status(BOARD_USART);
    //判断当前的传输模式是否为DMA方式
    if (gs_uc_trans_mode == PDC_TRANSFER) {
        /* Receive buffer is full. */
        //? RXBUFF: Reception Buffer Full
        //0: The signal Buffer Full from the Receive PDC channel is inactive.
        //1: The signal Buffer Full from the Receive PDC channel is active
        //在这里默认是1 在这里做与运算只要US_CSR_RXBUFF为1 结果就为真
        if (ul_status & US_CSR_RXBUFF) {
            /* Disable timer. */
            tc_stop(TC0, 0);
            /* Echo back buffer. */
            //g_st_packet 有两个元素
            //1:The pointer to packet data start address. For pointer or next pointer
            //2: Size for counter or next counter register (_CR)
            g_st_packet.ul_addr =(uint32_t)gs_puc_buffer[gs_uc_buf_num];
            g_st_packet.ul_size = gs_ul_size_buffer;
           
            g_st_nextpacket.ul_addr =(uint32_t)gs_puc_nextbuffer[gs_uc_buf_num];
            g_st_nextpacket.ul_size = gs_ul_size_nextbuffer;
           
            //DMA发送初始化
            pdc_tx_init(g_p_pdc, &g_st_packet, &g_st_nextpacket);
           
            if (g_uc_trannd_flag) {
                gs_ul_size_buffer = BUFFER_SIZE;
                gs_ul_size_nextbuffer = BUFFER_SIZE;
                g_uc_trannd_flag = 0;
            }
            gs_uc_buf_num = MAX_BUF_NUM - gs_uc_buf_num;
            /* Restart read on buffer. */
            g_st_packet.ul_addr =
                    (uint32_t)gs_puc_buffer[gs_uc_buf_num];//数组的地址空间是连续的
            g_st_packet.ul_size = BUFFER_SIZE;
           
            g_st_nextpacket.ul_addr =
                    (uint32_t)gs_puc_nextbuffer[ gs_uc_buf_num];
            g_st_nextpacket.ul_size = BUFFER_SIZE;
            //DMA接收初始化
            pdc_rx_init(g_p_pdc, &g_st_packet, &g_st_nextpacket);
            /* Restart timer. */
            tc_start(TC0, 0);
        }
    } el {
        /* Transfer without PDC. */
        if (ul_status & US_CSR_RXRDY) {
            usart_getchar(BOARD_USART, (uint32_t *)&gs_ul_read_buffer);
            usart_write(BOARD_USART, gs_ul_read_buffer);
        }
    }
}
/**
* \brief Interrupt handler for TC0. Record the number of bytes received,
* and then restart a read transfer on the USART if the transfer was stopped.
*/
void TC0_Handler(void)
{
    uint32_t ul_status;
    uint32_t ul_byte_total = 0;
    /* Read TC0 Status. */
    ul_status = tc_get_status(TC0, 0);
    /* RC compare. */
    if (((ul_status & TC_SR_CPCS) == TC_SR_CPCS) &&
            (gs_uc_trans_mode == PDC_TRANSFER)) {
        /* Flush PDC buffer. */
        ul_byte_total = BUFFER_SIZE - pdc_read_rx_counter(g_p_pdc);
        //缓冲区既没用完,也没有没用
        if ((ul_byte_total != 0) && (ul_byte_total != BUFFER_SIZE)) {巴黎欧莱雅广告
            /* Log current size. */
            g_uc_trannd_flag = 1;
            if (pdc_read_rx_next_counter(g_p_pdc) == 0) {
                gs_ul_size_buffer = BUFFER_SIZE;
                gs_ul_size_nextbuffer = ul_byte_total;
            } el {
                gs_ul_size_buffer = ul_byte_total;
                gs_ul_size_nextbuffer = 0;
            }
            /* Trigger USART Receive Buffer Full Interrupt. */
            pdc_rx_clear_cnt(g_p_pdc);
        }
    }
}
/**
* \brief Configure USART in normal (rial rs232) mode, asynchronous,
培训的英文 * 8 bits, 1 stop bit, no parity, 115200 bauds and enable its transmitter
* and receiver.
*/
static void configure_usart(void)
{
    const sam_usart_opt_t usart_console_ttings = {
        BOARD_USART_BAUDRATE,
        US_MR_CHRL_8_BIT,
        US_MR_PAR_NO,
        US_MR_NBSTOP_1_BIT,
        US_MR_CHMODE_NORMAL,
        /* This field is only ud in IrDA mode. */
        0
    };
    /* Enable the peripheral clock in the PMC. */
    sysclk_enable_peripheral_clock(BOARD_ID_USART);
    /* Configure USART in rial mode. */
    usart_init_rs232(BOARD_USART, &usart_console_ttings,
            sysclk_get_cpu_hz());
    /* Disable all the interrupts. */
    usart_disable_interrupt(BOARD_USART, ALL_INTERRUPT_MASK);
    /* Enable the receiver and transmitter. */
    usart_enable_tx(BOARD_USART);
    usart_enable_rx(BOARD_USART);
    /* Configure and enable interrupt of USART. */
    NVIC_EnableIRQ(USART_IRQn);
}
/**
* \brief Configure Timer Counter 0 (TC0) to generate an interrupt every 200ms.
* This interrupt will be ud to flush USART input and echo back.
*/
static void configure_tc(void)
{
    uint32_t ul_div;
表示忠诚的成语    uint32_t ul_tcclks;
word清除格式
    static uint32_t ul_sysclk;
    /* Get system clock. */
    ul_sysclk = sysclk_get_cpu_hz();
    /* Configure PMC. */
    pmc_enable_periph_clk(ID_TC0);
    /* Configure TC for a 50Hz frequency and trigger on RC compare. */
    tc_find_mck_divisor(TC_FREQ, ul_sysclk, &ul_div, &ul_tcclks, ul_sysclk);
    tc_init(TC0, 0, ul_tcclks | TC_CMR_CPCTRG);
    tc_write_rc(TC0, 0, (ul_sysclk / ul_div) / TC_FREQ);
    /* Configure and enable interrupt on RC compare. */
体会    NVIC_EnableIRQ((IRQn_Type)ID_TC0);
    tc_enable_interrupt(TC0, 0, TC_IER_CPCS);
}
/**
*  Configure UART for debug message output.
*/
static void configure_console(void)
{
    const usart_rial_options_t uart_rial_options = {
        .baudrate = CONF_UART_BAUDRATE,
        .paritytype = CONF_UART_PARITY
    };
    /* Configure console UART. */
    sysclk_enable_peripheral_clock(CONSOLE_UART_ID);
    stdio_rial_init(CONF_UART, &uart_rial_options);
}
/**
* \brief Ret the TX & RX, and clear the PDC counter.
*/
static void usart_clear(void)
{
    /* Ret and disable receiver & transmitter. */
    usart_ret_rx(BOARD_USART);
    usart_ret_tx(BOARD_USART);
    /* Clear PDC counter. */
    g_st_packet.ul_addr = 0;
    g_st_packet.ul_size = 0;
    g_st_nextpacket.ul_addr = 0;
    g_st_nextpacket.ul_size = 0;
    pdc_rx_init(g_p_pdc, &g_st_packet, &g_st_nextpacket);
    /* Enable receiver & transmitter. */
    usart_enable_tx(BOARD_USART);
    usart_enable_rx(BOARD_USART);
}
/**
* \brief Display main menu.
*/
static void display_main_menu(void)
{
    puts("-- Menu Choices for this example --\r\n"
            "-- s: Switch mode for USART between PDC and without PDC.--\r\n"
            "-- m: Display this menu again.--\r");
}家字草书
/**
* \brief Application entry point for usart_rial example.
*
* \return Unud (ANSI-C compatibility).
*/
int main(void)
{
    uint8_t uc_char;
    uint8_t uc_flag;
    /* Initialize the SAM system. */
    sysclk_init();
    board_init();
    /* Configure UART for debug message output. */
    configure_console();
    /* Output example information. */
    puts(STRING_HEADER);
    /* Configure USART. */
    configure_usart();
    /* Get board USART PDC ba address. */
    g_p_pdc = usart_get_pdc_ba(BOARD_USART);
    /* Enable receiver and transmitter. */
    pdc_enable_transfer(g_p_pdc, PERIPH_PTCR_RXTEN | PERIPH_PTCR_TXTEN);
    /* Configure TC. */
    configure_tc();
    /* Start receiving data and start timer. */
    g_st_packet.ul_addr = (uint32_t)gs_puc_buffer[gs_uc_buf_num];
    g_st_packet.ul_size = BUFFER_SIZE;
    g_st_nextpacket.ul_addr = (uint32_t)gs_puc_nextbuffer[gs_uc_buf_num];
    g_st_nextpacket.ul_size = BUFFER_SIZE;
    pdc_rx_init(g_p_pdc, &g_st_packet, &g_st_nextpacket);
    puts("-- Start to echo rial inputs -- \r\n"
            "-I- Default Transfer with PDC \r\n"
            "-I- Press 's' to switch transfer mode \r");
    gs_uc_trans_mode = PDC_TRANSFER;
    usart_disable_interrupt(BOARD_USART, US_IDR_RXRDY);
    usart_enable_interrupt(BOARD_USART, US_IER_RXBUFF);
    tc_start(TC0, 0);
    while (1) {
        uc_char = 0;
        uc_flag = uart_read(CONSOLE_UART, &uc_char);
        if (!uc_flag) {
            switch (uc_char) {
            ca 's':
            ca 'S':
                if (gs_uc_trans_mode == PDC_TRANSFER) {
                    /* Transfer to no PDC communication mode. */
                    /* Disable PDC controller. */
                    pdc_disable_transfer(g_p_pdc,
                            PERIPH_PTCR_RXTDIS | PERIPH_PTCR_TXTDIS);
                    /* Disable the RXBUFF interrupt. */
                    usart_disable_interrupt(BOARD_USART, US_IDR_RXBUFF);
                    /* Clear USART controller. */
                    usart_clear();
                    /* Enable the RXRDY interrupt. */
                    usart_enable_interrupt(BOARD_USART, US_IER_RXRDY);
                    gs_uc_trans_mode = BYTE_TRANSFER;
                    puts("-I- Transfer without PDC \r");
                } el if (gs_uc_trans_mode == BYTE_TRANSFER) {
                    pdc_enable_transfer(g_p_pdc,
                            PERIPH_PTCR_RXTEN | PERIPH_PTCR_TXTEN);
                    /* Clear USART controller. */
                    usart_clear();
                    /* Ret pdc current buffer size. */
                    gs_ul_size_buffer = BUFFER_SIZE;
                    gs_ul_size_nextbuffer = BUFFER_SIZE;
                    gs_uc_buf_num = 0;
                    /* Start receiving data. */
                    g_st_packet.ul_addr =
                            (uint32_t)gs_puc_buffer[gs_uc_buf_num];
                    g_st_packet.ul_size = BUFFER_SIZE;
                    g_st_nextpacket.ul_addr =
                            (uint32_t)gs_puc_nextbuffer[gs_uc_buf_num];
                    g_st_nextpacket.ul_size = BUFFER_SIZE;
                    pdc_rx_init(g_p_pdc, &g_st_packet, &g_st_nextpacket);
                   
                    /* Transfer to PDC communication mode, disable RXRDY interrupt and enable RXBUFF interrupt. */
                    usart_disable_interrupt(BOARD_USART, US_IER_RXRDY);
                    usart_enable_interrupt(BOARD_USART, US_IER_RXBUFF);
                    gs_uc_trans_mode = PDC_TRANSFER;
                    puts((const char *)gs_puc_nextbuffer[0]);
                    puts("-I- Transfer with PDC \r");
                }
                break;
丝瓜简笔画            ca 'm':
            ca 'M':
                display_main_menu();
                break;
            default:
                break;
            }
        }
    }
}

本文发布于:2023-06-10 01:17:54,感谢您对本站的认可!

本文链接:https://www.wtabcd.cn/fanwen/fan/82/915607.html

版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。

标签:串口   地址   资料
相关文章
留言与评论(共有 0 条评论)
   
验证码:
推荐文章
排行榜
Copyright ©2019-2022 Comsenz Inc.Powered by © 专利检索| 网站地图