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
這樣,完成了不斷接收和轉發的過程。