当前位置:文档之家› atmel ASF学习笔记

atmel ASF学习笔记

Atmel asf学习笔记前言前一段时间入手了一块Arduino DUE开发板,入手后网上查询资料发现资料很少,并且和很多的模块不兼容,这块板子的IO口只能承受3.3v的电压,如果想使用5v的模块,又要动手做兼容模块。

又因为这块板子采用的MCU是SAM3X8E 是一款ARM的主控,就想把它作为cortex M3开发板使用。

环境搭建开发工具:atmel studio 6.1烧写工具:bossac.exe开发工具可以在Atmel官网下载,bossac.exe可以从arduino中提取建立工程为了快速上手这块板子,我决定采用atmel的asf框架创建示例工程,由于在单片机程序开发中,需要通过串口输入输出调试信息,所以首先要实现串口通讯,这里先创建一个串口通讯程序的模板接下来就ok了编译通过下载到mcu中接下来打开串口,查看输出信息测试通过!ASF之串口学习#include <string.h>#include "asf.h"//包含了所需要的模块#include "stdio_serial.h"//串口的出入输出定义#include "conf_board.h"#include "conf_clock.h"#include "conf_example.h"//定义了串口中断入口函数,波特率,串口端口号/** Size of the receive buffer used 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 use. */static uint8_t gs_uc_buf_num = 0;/** PDC data packet. */pdc_packet_t g_st_packet, g_st_nextpacket;/** Pointer to PDC register base. */Pdc *g_p_pdc;/** Flag of one transfer end. */static uint8_t g_uc_transend_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_transend_flag) {gs_ul_size_buffer = BUFFER_SIZE;gs_ul_size_nextbuffer = BUFFER_SIZE;g_uc_transend_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);}} else {/* 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_transend_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;} else {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 (serial 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_settings = {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 used in IrDA mode. */};/* Enable the peripheral clock in the PMC. */sysclk_enable_peripheral_clock(BOARD_ID_USART);/* Configure USART in serial mode. */usart_init_rs232(BOARD_USART, &usart_console_settings,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 used to flush USART input and echo back.*/static void configure_tc(void){uint32_t ul_div;uint32_t ul_tcclks;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_serial_options_t uart_serial_options = {.baudrate = CONF_UART_BAUDRA TE,.paritytype = CONF_UART_PARITY};/* Configure console UART. */sysclk_enable_peripheral_clock(CONSOLE_UART_ID);stdio_serial_init(CONF_UART, &uart_serial_options); }/*** \brief Reset the TX & RX, and clear the PDC counter.*/static void usart_clear(void){/* Reset and disable receiver & transmitter. */usart_reset_rx(BOARD_USART);usart_reset_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_serial example.** \return Unused (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 base address. */g_p_pdc = usart_get_pdc_base(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 serial 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) {case 's':case '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");} else if (gs_uc_trans_mode == BYTE_TRANSFER) {pdc_enable_transfer(g_p_pdc,PERIPH_PTCR_RXTEN | PERIPH_PTCR_TXTEN);/* Clear USART controller. */usart_clear();/* Reset 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;case 'm':case 'M':display_main_menu();break;default:break;}}}}。

相关主题