打印
[Atmel]

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

[复制链接]
1035|0
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
应用代码能处理发送和接收,所以两块SAM D21 Xplained 板子都可以写入相同的BIN文件。
最终应用的“分数波特率配置”在main.c文件中如下所示:
#include <asf.h>
#define USART_BAUD_RATE 9600
#define FRAC_BAUD_RATE 11000
#define USART_SAMPLE_NUM 16
#define SHIFT 32
uint8_t edbg_rx_data,ext_rx_data;
uint16_t baud;
uint8_t fp;
/* 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);
void calculate_fractional_baud_value(const uint32_t baudrate,const uint32_t periphe-ral_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_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;
}
/* As per the table 24-2 Baud rate equations */
/* Fbaud = Fref/S(BAUD+(FP/8))
fbaud - fractional baud frequency
fref - SERCOM generic clock frequency
S - Number of samples per bit
BAUD - BAUD value
FP - fractional part of baud value
*/
/* fractional baud value calculation */
void calculate_fractional_baud_value(const uint32_t baudrate,const uint32_t periph-eral_clock,uint8_t sample_num)
{
uint64_t mul_ratio;
mul_ratio = (uint64_t)((uint64_t)peripheral_clock*(uint64_t)1000)/(uint64_t)(bau-drate*sample_num);
baud = mul_ratio/1000;
fp = ((mul_ratio - (baud*1000))*8)/1000;
}
/* 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 UART(SERCOM3) 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 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.
*/
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 D */
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)
{
calculate_fractional_baud_value(FRAC_BAUD_RATE,sys-tem_gclk_chan_get_hz(SERCOM2_GCLK_ID_CORE),
USART_SAMPLE_NUM);
/* Fractional baud and Baud value */
SERCOM2->USART.BAUD.reg = SERCOM_USART_BAUD_FRAC_BAUD(baud) | SERCOM_USART_BAUD_FRAC_FP(fp);
/* 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 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(0x1)| SERCOM_USART_CTRLA_RUNSTDBY | SERCOM_USART_CTRLA_MODE_USART_INT_CLK ;
/* 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终端显示如下:

相关下载

相关帖子

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

本版积分规则

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

2398

主题

6956

帖子

67

粉丝