打印
[Atmel]

每天跟我读点资料:SAM D SERCOM USART配置8

[复制链接]
1245|0
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
本帖最后由 ddllxxrr 于 2016-3-22 12:04 编辑

一但在PC终端1键入一个字符,它将通过EDBG到达SAM D21 Xplained pro(发送)。由于SERCOM3 RXC中断是使能的,一但EDBG USART接收到字符后,应用程序将执行SERCOM3_Handler
。在SERCOM3_Handler中它将检查INTFLAG寄存器中SERCOM3RXC标志设置状态。这个位将在当终端1键入的字符完全被SERCOM3接收完时置1
。接收的字符将在SERCOM3的数据寄存器中,并且它被读到变量edbg_rx_data.
。现在DRE-连接到EXT2连接头的SERCOM2数据寄存器空中断标志将被检查设置状态。这个位将在SERCOM22的数据寄存器是空并且准备被写时置位。
。如果DRE被置位,然后edbg_rx_data中的数据被放置在SERCOM2中数据寄存器。这个数据被传到另一个SAM D21 Xplained pro(接收者)。
。现在另一个SAM D21板子的INTFLAG寄存器SERCOM2RXC标志被置位并且SERCOM2_Handler将提供服务。
。在SERCOM2_Handler中一但检查出RXC被置位状态,数据从SERCOM2数据寄存器中写到变量ext_rx_data
。现在连接到EDBGSERCOM3数据寄存器DRE将被检查设置状态。这个位当SERCOM3是空的并准备写时被置位
。如果DRE位被设置然后ext_rx_data的数据将被放到SERCOM3数据寄存器中。这个数据通过EDBG被传到PC终端2
当一个在PC终端2键入的字符以上述相同的顺序字符将到达PC终端1.
在这个应用代码中可以处理接收和发送,所以SAM D21 Xplained 板子能被同样的二进制文件编程。
注意:这个应用也可以测试如.TXT文件有相隔的字符。
最终的应用在main.c文件中的“基础配置”将要如下:
#include <asf.h>
#define USART_BAUD_RATE 9600
#define USART_SAMPLE_NUM 16
#define SHIFT 32
uint8_t edbg_rx_data,ext_rx_data;
/* function prototype */
void edbg_usart_clock_init(void);
void edbg_usart_pin_init(void);
void edbg_usart_init(void);
void ext_usart_clock_init(void);
void ext_usart_pin_init(void);
void ext_usart_init(void);
uint16_t calculate_baud_value(const uint32_t baudrate,const uint32_t peripheral_clock,
uint8_t sample_num);
/*ext_usart handler*/
void SERCOM2_Handler()
{
if (SERCOM2->USART.INTFLAG.bit.RXC){
ext_rx_data = SERCOM2->USART.DATA.reg;
if (SERCOM3->USART.INTFLAG.bit.DRE)
{
SERCOM3->USART.DATA.reg = ext_rx_data;
}
}
}
/*edbg_usart handler*/
void SERCOM3_Handler()
{
if (SERCOM3->USART.INTFLAG.bit.RXC){
edbg_rx_data = SERCOM3->USART.DATA.reg;
if (SERCOM2->USART.INTFLAG.bit.DRE)
{
SERCOM2->USART.DATA.reg = edbg_rx_data;
}
}
}
/*Assigning pin to the alternate peripheral function*/
static inline void pin
/*Assigning pin to the alternate peripheral function*/
static inline void pin_set_peripheral_function(uint32_t pinmux)
{
uint8_t port = (uint8_t)((pinmux >> 16)/32);
PORT->Group[port].PINCFG[((pinmux >> 16) - (port*32))].bit.PMUXEN = 1;
PORT->Group[port].PMUX[((pinmux >> 16) - (port*32))/2].reg &= ~(0xF << (4 * ((pinmux >> 16) & 0x01u)));
PORT->Group[port].PMUX[((pinmux >> 16) - (port*32))/2].reg |= (uint8_t)((pinmux & 0x0000FFFF) << (4 * ((pinmux >> 16) & 0x01u)));
}
/*
* internal Calculate 64 bit division, ref can be found in
*/
static uint64_t long_division(uint64_t n, uint64_t d)
{
int32_t i;
uint64_t q = 0, r = 0, bit_shift;
for (i = 63; i >= 0; i--) {
bit_shift = (uint64_t)1 << i;
r = r << 1;
if (n & bit_shift) {
r |= 0x01;
}


if (r >= d) {
r = r - d;
q |= bit_shift;
}
}
return q;
}


/*
* \internal Calculate asynchronous baudrate value (UART)
*/
uint16_t calculate_baud_value(
const uint32_t baudrate,
const uint32_t peripheral_clock,
uint8_t sample_num)
{
/* Temporary variables */
uint64_t ratio = 0;
uint64_t scale = 0;
uint64_t baud_calculated = 0;
uint64_t temp1;
/* Calculate the BAUD value */
temp1 = ((sample_num * (uint64_t)baudrate) << SHIFT);
ratio = long_division(temp1, peripheral_clock);
scale = ((uint64_t)1 << SHIFT) - ratio;
baud_calculated = (65536 * scale) >> SHIFT;
return baud_calculated;
}
/* EDBG UART(SERCOM3) bus and generic clock initialization */
void edbg_usart_clock_init(void)
{
struct system_gclk_chan_config gclk_chan_conf;
uint32_t gclk_index = SERCOM3_GCLK_ID_CORE;
/* Turn on module in PM */
system_apb_clock_set_mask(SYSTEM_CLOCK_APB_APBC, PM_APBCMASK_SERCOM3);


/* Turn on Generic clock for USART */
system_gclk_chan_get_config_defaults(&gclk_chan_conf);
/*Default is generator 0. Other wise need to configure like below */
/* gclk_chan_conf.source_generator = GCLK_GENERATOR_1; */
system_gclk_chan_set_config(gclk_index, &gclk_chan_conf);
system_gclk_chan_enable(gclk_index);
}


/* EDBG UART(SERCOM3) pin initialization */
void edbg_usart_pin_init(void)
{
/* PA22 and PA23 set into peripheral function C */
pin_set_peripheral_function(PINMUX_PA22C_SERCOM3_PAD0);
pin_set_peripheral_function(PINMUX_PA23C_SERCOM3_PAD1);
}
/* EDBG(SERCOM3) UART initialization */
void edbg_usart_init(void)
{
uint16_t baud_value;
baud_value = calculate_baud_value(USART_BAUD_RATE,sys-tem_gclk_chan_get_hz(SERCOM3_GCLK_ID_CORE),
USART_SAMPLE_NUM);
/* By setting the DORD bit LSB is transmitted first and setting the RXPO bit as 1 cor-responding SERCOM PAD[1] will be used for data reception, PAD[0] will be used as TxD pin by setting TXPO bit as 0,16x over-sampling is selected by setting the SAMPR bit as 0,
Generic clock is enabled in all sleep modes by setting RUNSTDBY bit as 1,
USART clock mode is selected as USART with internal clock by setting MODE bit into 1.
*/
SERCOM3->USART.CTRLA.reg = SERCOM_USART_CTRLA_DORD |
SERCOM_USART_CTRLA_RXPO(0x1) |
SERCOM_USART_CTRLA_TXPO(0x0) |
SERCOM_USART_CTRLA_SAMPR(0x0)|
SERCOM_USART_CTRLA_RUNSTDBY |
SERCOM_USART_CTRLA_MODE_USART_INT_CLK ;
/*baud register value corresponds to the device communication baud rate */
SERCOM3->USART.BAUD.reg = baud_value;


/* 8-bits size is selected as character size by setting the bit CHSIZE as 0,
TXEN bit and RXEN bits are set to enable the Transmitter and receiver*/
SERCOM3->USART.CTRLB.reg = SERCOM_USART_CTRLB_CHSIZE(0x0) |
SERCOM_USART_CTRLB_TXEN |
SERCOM_USART_CTRLB_RXEN ;
/* synchronization busy */
while(SERCOM3->USART.SYNCBUSY.bit.CTRLB);
/* SERCOM3 handler enabled */
system_interrupt_enable(SERCOM3_IRQn);
/* receive complete interrupt set */
SERCOM3->USART.INTENSET.reg = SERCOM_USART_INTFLAG_RXC;
/* SERCOM3 peripheral enabled */
SERCOM3->USART.CTRLA.reg |= SERCOM_USART_CTRLA_ENABLE;
/* synchronization busy */
while(SERCOM3->USART.SYNCBUSY.reg & SERCOM_USART_SYNCBUSY_ENABLE);
}


/* External connector(SERCOM2) UART bus and generic clock initialization */
void ext_usart_clock_init(void)
{
struct system_gclk_chan_config gclk_chan_conf;
uint32_t gclk_index = SERCOM2_GCLK_ID_CORE;
/* Turn on module in PM */
system_apb_clock_set_mask(SYSTEM_CLOCK_APB_APBC, PM_APBCMASK_SERCOM2);
/* Turn on Generic clock for USART */
system_gclk_chan_get_config_defaults(&gclk_chan_conf);
//Default is generator 0. Other wise need to configure like below
/* gclk_chan_conf.source_generator = GCLK_GENERATOR_1; */
system_gclk_chan_set_config(gclk_index, &gclk_chan_conf);
system_gclk_chan_enable(gclk_index);
}
/* External connector(SERCOM2) pin initialization */
void ext_usart_pin_init(void)
{
/* PA08 and PA09 set into peripheral function*/
pin_set_peripheral_function(PINMUX_PA08D_SERCOM2_PAD0);
pin_set_peripheral_function(PINMUX_PA09D_SERCOM2_PAD1);
}
/* External connector(SERCOM2) UART initialization */
void ext_usart_init(void)
{
uint16_t baud_value;
baud_value = calculate_baud_value(USART_BAUD_RATE,sys-tem_gclk_chan_get_hz(SERCOM2_GCLK_ID_CORE),
USART_SAMPLE_NUM);
/* By setting the DORD bit LSB is transmitted first and setting the RXPO bit as 1 corresponding SERCOM PAD[1] will be used for data reception RXD, PAD[0] will be used as TxD pin by setting TXPO bit as 0, 16x over-sampling is selected by setting the SAMPR bit as 0,
Generic clock is enabled in all sleep modes by setting RUNSTDBY bit as 1,
USART clock mode is selected as USART with internal clock by setting MODE bit into 1.
*/
SERCOM2->USART.CTRLA.reg = SERCOM_USART_CTRLA_DORD |
SERCOM_USART_CTRLA_RXPO(0x1) |
SERCOM_USART_CTRLA_TXPO(0x0) |
SERCOM_USART_CTRLA_SAMPR(0x0)| SERCOM_USART_CTRLA_RUNSTDBY | SERCOM_USART_CTRLA_MODE_USART_INT_CLK ;
/* baud register value corresponds to the device communication baud rate */
SERCOM2->USART.BAUD.reg = baud_value;
/* 8-bits size is selected as character size by setting the bit CHSIZE as 0,
TXEN bit and RXEN bits are set to enable the Transmitter and receiver*/
SERCOM2->USART.CTRLB.reg = SERCOM_USART_CTRLB_CHSIZE(0x0) |
SERCOM_USART_CTRLB_TXEN |
SERCOM_USART_CTRLB_RXEN ;
/* synchronization busy */
while(SERCOM2->USART.SYNCBUSY.bit.CTRLB);
/* SERCOM2 handler enabled */
system_interrupt_enable(SERCOM2_IRQn);
/* receive complete interrupt set */
SERCOM2->USART.INTENSET.reg = SERCOM_USART_INTFLAG_RXC;
/* SERCOM2 peripheral enabled */
SERCOM2->USART.CTRLA.reg |= SERCOM_USART_CTRLA_ENABLE;
/* synchronization busy */
while(SERCOM2->USART.SYNCBUSY.reg & SERCOM_USART_SYNCBUSY_ENABLE);
}
int main (void)
{
system_init();
edbg_usart_clock_init();
edbg_usart_pin_init();
edbg_usart_init();
ext_usart_clock_init();
ext_usart_pin_init();
ext_usart_init();
while(1);
}
PC终端输出将看起来象下边:

完整的工程方案在附件的ZIP目录中,配备这个应用注释。



相关下载

相关帖子

发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

个人签名:http://shop34182318.taobao.com/ http://shop562064536.taobao.com

2399

主题

6963

帖子

68

粉丝