打印
[Atmel]

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

[复制链接]
1557|1
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
主函数如下:
int main (void)
{
system_init();
edbg_usart_clock_init();
edbg_usart_pin_init();
edbg_usart_init();
system_set_sleepmode(SYSTEM_SLEEPMODE_STANDBY);
while(1)
{
if (!rx_started)
{
usart_send_string("\r\n Device entered into standby sleep mode");
while(!SERCOM3->USART.INTFLAG.bit.TXC);
system_sleep();
}
while(rx_started);
usart_send_string("\r\n Character received after wakeup : ");
while(!SERCOM3->USART.INTFLAG.bit.DRE);
SERCOM3->USART.DATA.reg = edbg_rx_data;
}
}
·
。一但设定休眠模式为待机休眠模式,在whiel循环中布尔变量用来检查false状态,而函数usart_send_string用来在window终端打印消息。
System_sleep函数将使设备进入到定义的休眠模式中。
。一但在PC终端键入一个字符,设备从休眠模式中唤醒并进入SERCOM3_Handler函数。
void SERCOM3_Handler()
{
if (SERCOM3->USART.INTFLAG.bit.RXS){
SERCOM3->USART.INTFLAG.bit.RXS = 1;
rx_started = true;
}
if (SERCOM3->USART.INTFLAG.bit.RXC){
edbg_rx_data = SERCOM3->USART.DATA.reg;
rx_started = false;
}
}
。在中断处理程序中,中断标志RXS状态-接收开始被检查。这个标志将被设置当在RxD线上检测出开始状态并且帧开始检测使能(CTRLB.SFDE1).
。如果RXC标志被设置,布尔变量rx_started被设置为true
。现在RXC-接收完成标志被检查,一但从DATA寄存器读出被键入的字符到edbg_rx_data缓冲布尔变量rx_started被设为false
。控制到达主函数的在rx_started缓冲键入值写入到DATA寄存器。现在它将被显示到PC终端上。
最终的在main.c文件中应用程序”SOF检测和唤醒配置”将如下:
#include <asf.h>
#define USART_BAUD_RATE 9600
#define USART_SAMPLE_NUM 16
#define SHIFT 32
uint8_t edbg_rx_data;
volatile bool rx_started = false;
/* Function prototype */
void edbg_usart_clock_init(void);
void edbg_usart_pin_init(void);
void edbg_usart_init(void);
void usart_send_string(const char *str_buf);
uint16_t calculate_baud_value(const uint32_t baudrate,const uint32_t peripheral_clock,
uint8_t sample_num);
/*edbg_usart handler*/
void SERCOM3_Handler()
{
if (SERCOM3->USART.INTFLAG.bit.RXS){
SERCOM3->USART.INTFLAG.bit.RXS = 1;
rx_started = true;
}
if (SERCOM3->USART.INTFLAG.bit.RXC){
edbg_rx_data = SERCOM3->USART.DATA.reg;
rx_started = false;
}
}
/*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 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(S
/* 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,
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_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 |
SERCOM_USART_CTRLB_SFDE;
/* synchronization busy */
while(SERCOM3->USART.SYNCBUSY.bit.CTRLB);
/* SERCOM3 handler enabled */
system_interrupt_enable(SERCOM3_IRQn);
/* receive complete interrupt,receive start interrupt set */
SERCOM3->USART.INTENSET.reg = SERCOM_USART_INTFLAG_RXC | SERCOM_USART_INTFLAG_RXS;
/* SERCOM3 peripheral enabled */
SERCOM3->USART.CTRLA.reg |= SERCOM_USART_CTRLA_ENABLE;
/* synchronization busy */
while(SERCOM3->USART.SYNCBUSY.reg & SERCOM_USART_SYNCBUSY_ENABLE);
}
/* function used to print the character in the terminal */
void usart_send_string(const char *str_buf)
{
while (*str_buf != '\0')
{
while(!SERCOM3->USART.INTFLAG.bit.DRE);
SERCOM3->USART.DATA.reg = *str_buf;
str_buf++;
}
}
int main (void)
{
system_init();
edbg_usart_clock_init();
edbg_usart_pin_init();
edbg_usart_init();
system_set_sleepmode(SYSTEM_SLEEPMODE_IDLE_2);
while(1)
{
if (!rx_started)
{
usart_send_string("\r\n Device entered into standby sleep mode");
while(!SERCOM3->USART.INTFLAG.bit.TXC);
system_sleep();
}
while(rx_started);
usart_send_string("\r\n Character received for wakeup : ");
while(!SERCOM3->USART.INTFLAG.bit.DRE);
SERCOM3->USART.DATA.reg = edbg_rx_data;
}
}
下图展示出SEROM_USART硬件握手应用的输出:

相关下载

相关帖子

沙发
为何这般累| | 2017-11-6 09:21 | 只看该作者
我是一个单片机小白,如何利用SAMD21J18A单片机将引脚PB09收到的数据信息原封不动通过PB08发出,实现串口路由的功能

使用特权

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

本版积分规则

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

2398

主题

6956

帖子

67

粉丝