#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 条评论) |