ATSAMD20G15是ATMEL的一款32位MCU,由于目前网上的资料很少,在调试它的USART的过程中费了不少功夫才把收发功能调通。
ATMEL的编译器AtmelStudio里面可以打开SAMD20的例程,不过例程是以ATSAMD20J18为内核,以它们的官方开发板为载体写的。里面的关于USART的例程有两个,其引脚配置都是官方开发板上的一致。而且直接在编译器上修改例程里面的芯片型号,会提示警告。因为FLASH的大小和烧写起始地址不同,编译出来的elf文件过大无法烧写。所以这里直接新建一个ATSAMD20J18工程后,把例程的代码拷过来修改。具体操作请参考官方提供的pdf文档,或者下面这个高手的文章:http://bbs.21ic.com/icview-857909-1-1.html。
我的工程的开发板上的USART引脚有两根,分别是PA22TX、PA23 RX。阅读了源代码及其注释,还有官网的代码文档后,我了解了该芯片的配置方法。USART异步模式需要两根线,分别是RX和TX,同步模式下还需要一根XCK外部时钟线。显然我的工程应该用异步模式。
默认配置已经按异步模式配好,里面的其他配置项也正好符合,不需要修改。
因为RX和TX两根线是分开的,同时没有XCK线,所以参数mux_setting只能是USART_RX_1_TX_0_XCK_1或者USART_RX_3_TX_2_XCK_3。然后根据收发属性检查引脚PA22和PA23的pad配置,发现mux_setting只能是前者,所以配置代码如下:
void configure_usart(void)
{
struct usart_config config_usart;
usart_get_config_defaults(&config_usart);
config_usart.baudrate = 9600;
config_usart.mux_setting = USART_RX_1_TX_0_XCK_1;
config_usart.pinmux_pad0 = PINMUX_PA22C_SERCOM3_PAD0;
config_usart.pinmux_pad1 = PINMUX_PA23C_SERCOM3_PAD1;
config_usart.pinmux_pad2 = PINMUX_UNUSED;
config_usart.pinmux_pad3 = PINMUX_UNUSED;
while (usart_init(&usart_instance,
SERCOM3, &config_usart) !=STATUS_OK) {
}
usart_enable(&usart_instance);
}
接好线以后可以通信了。测试的时候发现只能发送,不能接收。后来发现,在例程USART callback的代码收到串口数据后会转发回去。接收buffer只有收满后才能回复。因为把接收buffer的大小MAX_RX_BUFFER_LENGTH改得太大,所以以为出现接收问题。
usart_write_wait(),usart_read_buffer_wait(),usart_read_wait(),usart_write_buffer_wait()是收发后一直等到收发成功或超时才返回。
usart_read_buffer_job(),usart_write_buffer_job()是通知中断出现收发,收发到指定的长度后才产生中断。然后用户需要在中断函数中给收发完成做处理。
在主程序中:
uint8_t string[] = "HelloWorld!\r\n";
usart_write_buffer_wait(&usart_instance,string, sizeof(string));
usart_read_buffer_job(&usart_instance,&rxByte, 1); //volatile uint8_trxByte;
while (true) {
}
在接收中断中:
usart_write_buffer_job(&usart_instance,&rxByte, 1);//echo
usart_read_buffer_job(&usart_instance,&rxByte, 1);//receive again
这样,完成了不断接收和转发的过程。