19.9
實驗3:DTC外部中斷觸發傳輸
19.9.1
硬件設計
本實驗的目標是使用外部中斷來觸發DTC傳輸,因此需要用到一個按鍵。
外部中斷在前面已經學過了,按鍵的硬件電路請參考前面的第16章“外部中斷”章節。
19.9.2
軟件設計
19.9.2.1
新建工程
對于e2studio開發環境:
拷貝一份我們之前的e2s工程“19_UART_Receive_Send”,然后將工程文件夾重命名為“20_DTC_External_IRQ”,最后再將它導入到我們的e2studio工作空間中。
對于Keil開發環境:
拷貝一份我們之前的Keil工程“19_UART_Receive_Send”,然后將工程文件夾重命名為“20_DTC_External_IRQ”,并進入該文件夾里面雙擊Keil工程文件,打開該工程。
工程新建好之后,在工程根目錄的“src”文件夾下面新建“dtc”文件夾,再進入“dtc”文件夾里面新建源文件和頭文件:“bsp_dtc.c”和“bsp_dtc.h”。工程文件結構如下。
列表18:文件結構
左右滑動查看完整內容
20_DTC_External_IRQ ├─ ...... └─src ├─ led │ ├─ bsp_led.c │ └─ bsp_led.h ├─ debug_uart │ ├─ bsp_debug_uart.c │ └─ bsp_debug_uart.h ├─ dtc │ ├─ bsp_dtc.c │ └─ bsp_dtc.h └─ hal_entry.c
19.9.2.2
FSP配置
在前面的“外部中斷”章節,相信大家已經學會如何配置外部中斷了。這次實驗我們要使用外部中斷來觸發/激活DTC傳輸,而使用外部中斷要用到我們的按鍵。
打開該工程的FSP配置界面。我們先加入外部中斷。點到“Pins”頁面,在ICU0里面找到IRQ09,這里我們選用P004引腳(SW2按鍵連接的引腳)連接到外部中斷IRQ09

然后點到“Stacks”頁面,按照“New Stack”→“Input”→“External IRQ”的步驟添加一個ICU模塊來配置外部中斷。ICU模塊的配置可按照如下圖所示進行配置,中斷觸發方式默認選擇上升沿觸發,中斷優先級設置比UART中斷大一點,設置為優先級10。

接著我們在“Stacks”頁面繼續加入DTC模塊,按如下圖所示步驟添加。

我們按如下圖配置一下DTC:

DTC配置項(與上圖相對應)
表8:DTC配置屬性描述

配置完成后,直接右上角點擊生成代碼。
注:讀者可能會疑惑不需要設置DTC中斷回調函數?
19.9.2.3
使用FSP配置器生成的配置
下面的是與我們之前在FSP配置界面上的配置等效的配置代碼:
列表19:代碼清單20?16與FSP配置界面上的配置等效的配置代碼
左右滑動查看完整內容
/* FSP 配置界面的傳輸信息配置(正常傳輸模式)等效于下面 fsp_transfer_info_normal 里
的配置(除了源地址和目標地址)
源地址和目標地址在 FSP 配置界面設置的話不太方便,我們會在 DTC_Init 函數里設置。
關于偏移值(Offset value)和源緩沖大小(Source Buffer Size),在 transfer_info_
→t 里沒有這兩項設置,建議在 FSP 配置界面設置
- 偏移值只有在地址模式是偏移模式的情況下才會用到;
- 而源緩沖大小與之相關的功能本例程不會涉及到,所以暫不考慮。
下面的 fsp_transfer_info_normal 僅作為對比參考,在本例程中是沒有用到的。
*/
//transfer_info_t fsp_transfer_info_normal =
//{
// .transfer_settings_word_b.dest_addr_mode = TRANSFER_ADDR_MODE_FIXED,?
→//每次傳輸后,目標地址指針固定不變
// .transfer_settings_word_b.repeat_area = TRANSFER_REPEAT_AREA_
→SOURCE,//源區域重復 (正常模式下無效)
// .transfer_settings_word_b.irq = TRANSFER_IRQ_END, ?
→//傳輸完成后中斷
// .transfer_settings_word_b.chain_mode = TRANSFER_CHAIN_MODE_
→DISABLED,//不使能(DMAC 沒有該功能,僅 DTC 有)
// .transfer_settings_word_b.src_addr_mode = TRANSFER_ADDR_MODE_FIXED,?
→//每次傳輸后,源地址指針固定不變
// .transfer_settings_word_b.size = TRANSFER_SIZE_2_BYTE, ?
→//每次傳輸 2 字節
// .transfer_settings_word_b.mode = TRANSFER_MODE_NORMAL, ?
→//正常傳輸模式
// .p_dest = (void *) DST_Buffer, ?
→//目標地址
// .p_src = (void const *) SRC_Buffer,
→//源地址
// .num_blocks = 0, //指定傳輸的塊數(正常模式和重復模式下均無效,僅
塊模式下有效)
// .length = 1, //指定傳輸的長度(即正常的傳輸次數或重復模式下重
復大小 或 塊模式下傳輸的塊大小)
//};
// 按照上述傳輸信息配置,期待的正確傳輸結果為:
uint32_tExpected_DST_Buffer[BUFFER_SIZE] = {
0x00000304,0x00000000,0x00000000,0x00000000,
0x00000000,0x00000000,0x00000000,0x00000000,
0x00000000,0x00000000,0x00000000,0x00000000,
0x00000000,0x00000000,0x00000000,0x00000000,
0x00000000,0x00000000,0x00000000,0x00000000,
0x00000000,0x00000000,0x00000000,0x00000000,
0x00000000,0x00000000,0x00000000,0x00000000,
0x00000000,0x00000000,0x00000000,0x00000000};
19.9.2.4
使用代碼配置:正常傳輸模式
下面是DTC在正常模式下傳輸的配置代碼:
列表20:代碼清單20?17 DTC正常傳輸模式配置
左右滑動查看完整內容
/* 正常傳輸模式 */
transfer_info_tmy_transfer_info_normal =
{
.transfer_settings_word_b.dest_addr_mode = TRANSFER_ADDR_MODE_
→INCREMENTED,//每次傳輸后,目標地址指針都會增加
.transfer_settings_word_b.repeat_area = TRANSFER_REPEAT_AREA_SOURCE,
→//源區域重復 (正常模式下無效)
.transfer_settings_word_b.irq = TRANSFER_IRQ_END, ?
→//傳輸完成后中斷
.transfer_settings_word_b.chain_mode = TRANSFER_CHAIN_MODE_
→DISABLED,//不使能(DMAC 沒有該功能,僅 DTC 有)
.transfer_settings_word_b.src_addr_mode = TRANSFER_ADDR_MODE_
→INCREMENTED,//每次傳輸后,源地址指針都會增加
.transfer_settings_word_b.size = TRANSFER_SIZE_4_BYTE, ?
→//每次傳輸 4 字節
.transfer_settings_word_b.mode = TRANSFER_MODE_NORMAL, ?
→//正常傳輸模式
.p_dest = (void*) DST_Buffer, ?
→//目標地址
.p_src = (voidconst *) SRC_Buffer, ?
→//源地址
.num_blocks =0,//指定傳輸的塊數(正常模式和重復模式下均無效,僅塊
模式下有效)
.length =1,//指定傳輸的長度(即正常的傳輸次數或重復模式下重復
大小 或 塊模式下傳輸的塊大小)
};
// 按照上述傳輸信息配置,期待的正確傳輸結果為:
uint32_tExpected_DST_Buffer[BUFFER_SIZE] = {
0x01020304,0x00000000,0x00000000,0x00000000,
0x00000000,0x00000000,0x00000000,0x00000000,
0x00000000,0x00000000,0x00000000,0x00000000,
0x00000000,0x00000000,0x00000000,0x00000000,
0x00000000,0x00000000,0x00000000,0x00000000,
0x00000000,0x00000000,0x00000000,0x00000000,
0x00000000,0x00000000,0x00000000,0x00000000,
0x00000000,0x00000000,0x00000000,0x00000000};
19.9.2.5
使用代碼配置:重復傳輸模式
下面是DTC在重復傳輸模式下傳輸的配置代碼:
列表21:代碼清單20?18 DTC重復傳輸模式配置
左右滑動查看完整內容
/* 重復傳輸模式 */
transfer_info_tmy_transfer_info_repeat =
{
.transfer_settings_word_b.dest_addr_mode = TRANSFER_ADDR_MODE_
→INCREMENTED,//每次傳輸后,目標地址指針都會增加
.transfer_settings_word_b.repeat_area = TRANSFER_REPEAT_AREA_SOURCE,
→//源區域重復 (正常模式下無效)
.transfer_settings_word_b.irq = TRANSFER_IRQ_EACH, ?
→//傳輸完成后中斷
.transfer_settings_word_b.chain_mode = TRANSFER_CHAIN_MODE_
→DISABLED,//不使能(DMAC 沒有該功能,僅 DTC 有)
.transfer_settings_word_b.src_addr_mode = TRANSFER_ADDR_MODE_
→INCREMENTED,//每次傳輸后,源地址指針都會增加
.transfer_settings_word_b.size = TRANSFER_SIZE_4_BYTE, ?
→//每次傳輸 4 字節
.transfer_settings_word_b.mode = TRANSFER_MODE_REPEAT, ?
→//重復傳輸模式
.p_dest = (void*) DST_Buffer, ?
→//目標地址
.p_src = (voidconst *) SRC_Buffer, ?
→//源地址
.num_blocks =0,//指定傳輸的塊數(正常模式和重復模式下均無效,僅塊
模式下有效)
.length =2,//指定傳輸的長度(即正常的傳輸次數或重復模式下重復
大小 或 塊模式下傳輸的塊大小)
};
// 按照上述傳輸信息配置,期待的正確傳輸結果為:
uint32_tExpected_DST_Buffer[BUFFER_SIZE] = {
0x01020304,0x05060708,0x01020304,0x05060708,
0x00000000,0x00000000,0x00000000,0x00000000,
0x00000000,0x00000000,0x00000000,0x00000000,
0x00000000,0x00000000,0x00000000,0x00000000,
0x00000000,0x00000000,0x00000000,0x00000000,
0x00000000,0x00000000,0x00000000,0x00000000,
0x00000000,0x00000000,0x00000000,0x00000000,
0x00000000,0x00000000,0x00000000,0x00000000};
19.9.2.6
使用代碼配置:塊傳輸模式
下面是DTC在塊傳輸模式下傳輸的配置代碼:
列表22:代碼清單20?19 DTC塊傳輸模式配置
左右滑動查看完整內容
/* 塊傳輸模式 */
transfer_info_tmy_transfer_info_block =
{
.transfer_settings_word_b.dest_addr_mode = TRANSFER_ADDR_MODE_
→INCREMENTED,//每次傳輸后,目標地址指針都會增加
.transfer_settings_word_b.repeat_area = TRANSFER_REPEAT_AREA_SOURCE,
→//源區域重復 (正常模式下無效)
.transfer_settings_word_b.irq = TRANSFER_IRQ_END, ?
→//傳輸完成后中斷
.transfer_settings_word_b.chain_mode = TRANSFER_CHAIN_MODE_
→DISABLED,//不使能(DMAC 沒有該功能,僅 DTC 有)
.transfer_settings_word_b.src_addr_mode = TRANSFER_ADDR_MODE_
→INCREMENTED,//每次傳輸后,源地址指針都會增加
.transfer_settings_word_b.size = TRANSFER_SIZE_4_BYTE, ?
→//每次傳輸 4 字節
.transfer_settings_word_b.mode = TRANSFER_MODE_BLOCK, ?
→//塊傳輸模式
.p_dest = (void*) DST_Buffer, ?
→//目標地址
.p_src = (voidconst *) SRC_Buffer, ?
→//源地址
.num_blocks =1,//指定傳輸的塊數(正常模式和重復模式下均無效,僅塊
模式下有效)
.length = BUFFER_SIZE,//指定傳輸的長度(即正常的傳輸次數或重復模式下重復
大小 或 塊模式下傳輸的塊大小)
};
// 按照上述傳輸信息配置,期待的正確傳輸結果為:
uint32_tExpected_DST_Buffer[BUFFER_SIZE] = {
0x01020304,0x05060708,0x090A0B0C,0x0D0E0F10,
0x11121314,0x15161718,0x191A1B1C,0x1D1E1F20,
0x21222324,0x25262728,0x292A2B2C,0x2D2E2F30,
0x31323334,0x35363738,0x393A3B3C,0x3D3E3F40,
0x41424344,0x45464748,0x494A4B4C,0x4D4E4F50,
0x51525354,0x55565758,0x595A5B5C,0x5D5E5F60,
0x61626364,0x65666768,0x696A6B6C,0x6D6E6F70,
0x71727374,0x75767778,0x797A7B7C,0x7D7E7F80};
19.9.2.7
DTC初始化函數
DTC初始化函數如下所示:
列表23:代碼清單20?20 DTC初始化函數
左右滑動查看完整內容
/* DTC 初始化函數 */
voidDTC_Init(void)
{
fsp_err_terr;
/* 使用 FSP 界面的配置:需要先重新設置傳輸的源地址和目的地址 */
#ifndefUSE_MY_TRANSFER_INFOR_CONFIG
set_transfer_dst_src_address(&g_transfer_dtc_cfg, SRC_Buffer, DST_
→Buffer);
#endif
err =R_DTC_Open(&g_transfer_dtc_ctrl, &g_transfer_dtc_cfg);
assert(FSP_SUCCESS == err);
/* 使用我們新的自定義的傳輸信息:重新配置傳輸 */
#ifdefUSE_MY_TRANSFER_INFOR_CONFIG
// 根據我們要使用的傳輸模式進行選擇配置:
#if(DTC_TRANSFER_MODE == DTC_TRANSFER_NORMAL_MODE)//正常模式
err =R_DTC_Reconfigure(&g_transfer_dtc_ctrl, &my_transfer_info_
→normal);
assert(FSP_SUCCESS == err);
#elif(DTC_TRANSFER_MODE == DTC_TRANSFER_REPEAT_MODE)//重復模式
err =R_DTC_Reconfigure(&g_transfer_dtc_ctrl, &my_transfer_info_
→repeat);
assert(FSP_SUCCESS == err);
#elif(DTC_TRANSFER_MODE == DTC_TRANSFER_BLOCK_MODE)//塊模式
err =R_DTC_Reconfigure(&g_transfer_dtc_ctrl, &my_transfer_info_block);
assert(FSP_SUCCESS == err);
#endif//DTC_TRANSFER_MODE
#endif//USE_MY_TRANSFER_INFOR_CONFIG
}
19.9.2.8
按鍵外部中斷回調函數
按鍵外部中斷回調函數如下所示:
列表24:代碼清單20?21按鍵外部中斷回調函數
左右滑動查看完整內容
/* 按鍵按下標志 */
volatilebool key_sw2_press =false;
/* 按鍵中斷回調函數 */
voidicu_external_irq_callback(external_irq_callback_args_t *p_args)
{
/* 判斷中斷通道 */
if(9== p_args->channel)
{
key_sw2_press =true;// 按鍵 SW2 按下
}
}
19.9.2.9
hal_entry入口函數
列表25:代碼清單20?22 hal_entry.c文件
左右滑動查看完整內容
/* 用戶頭文件包含 */ #include"led/bsp_led.h" #include"debug_uart/bsp_debug_uart.h" #include"dtc/bsp_dtc.h" externconstuint32_tSRC_Buffer[BUFFER_SIZE]; externuint32_tDST_Buffer[BUFFER_SIZE]; externuint32_tExpected_DST_Buffer[BUFFER_SIZE]; externvolatilebool dtc_complete_transmission_sign; uint8_tBufferCompare(constuint32_t*pBuffer1,constuint32_t*pBuffer2,? →uint16_tBufferLength) voidBufferShow_HexData(constuint32_t*pBuffer,uint16_tBufferLength); voidhal_entry(void) { /*TODO:add your own code here */ uint8_tres; LED_Init();// LED 初始化 Debug_UART4_Init();// SCI4 UART 調試串口初始化 /* 初始化 DTC */ DTC_Init(); printf("這是一個 DTC 存儲器到存儲器的傳輸實驗例程 "); printf("打開串口助手,查看接收窗口打印的相關提示信息 "); printf("按下按鍵 SW2 激活 DTC 傳輸 "); printf("觀察板載 LED 燈,本實驗使用兩個 LED 燈來指示 DTC 傳輸結果 "); printf("- DTC 數據傳輸失敗,則 LED1 亮(紅色) "); printf("- DTC 數據傳輸成功,則 LED2 亮(藍色) "); printf("-------------------------------------------- "); /* Open ICU module */ R_ICU_ExternalIrqOpen(&g_external_irq9_ctrl, &g_external_irq9_cfg); /* 允許中斷 */ R_ICU_ExternalIrqEnable(&g_external_irq9_ctrl); /* 使能 DTC 模塊 */ R_DTC_Enable(&g_transfer_dtc_ctrl); /*************************************/ /* 使用按鍵外部中斷觸發激活 DTC 傳輸 */ /*************************************/ #ifndefUSE_MY_TRANSFER_INFOR_CONFIG /* 根據 FSP 配置界面的傳輸信息進行傳輸 */ /* 等待激活 DTC 傳輸 */ for(uint16_ti =0; i 1; i++) { /* 等待按鍵按下,按鍵按下一次即激活一次 DTC 傳輸 */ while?(false?== key_sw2_press); key_sw2_press =?false; /* 等待本次傳輸完成 */ R_BSP_SoftwareDelay(5, BSP_DELAY_UNITS_MILLISECONDS);?//加上延時確 保傳輸完成 } #else// 下面的這些是使用自定義的傳輸配置信息配置 #if?(DTC_TRANSFER_MODE == DTC_TRANSFER_NORMAL_MODE)?//正常模式 /* 等待激活 DTC 傳輸 */ for?(uint16_t?i =?0; i 1; i++) { /* 等待按鍵按下,按鍵按下一次即激活一次 DTC 傳輸 */ while?(false?== key_sw2_press); key_sw2_press =?false; /* 等待本次傳輸完成 */ R_BSP_SoftwareDelay(5, BSP_DELAY_UNITS_MILLISECONDS);?//加上延時確 保傳輸完成 } #elif?(DTC_TRANSFER_MODE == DTC_TRANSFER_REPEAT_MODE)?//重復模式 /* 等待激活 DTC 傳輸 */ for?(uint16_t?i =?0; i 4; i++) { /* 等待按鍵按下,按鍵按下一次即激活一次 DTC 傳輸 */ while?(false?== key_sw2_press); key_sw2_press =?false; /* 等待本次傳輸完成 */ R_BSP_SoftwareDelay(5, BSP_DELAY_UNITS_MILLISECONDS);?//加上延時確 保傳輸完成 } #elif?(DTC_TRANSFER_MODE == DTC_TRANSFER_BLOCK_MODE)?//塊模式 /* 等待激活 DTC 傳輸 */ for?(uint16_t?i =?0; i 1; i++) { /* 等待按鍵按下,按鍵按下一次即激活一次 DTC 傳輸 */ while?(false?== key_sw2_press); key_sw2_press =?false; /* 等待本次傳輸完成 */ R_BSP_SoftwareDelay(5, BSP_DELAY_UNITS_MILLISECONDS);?//加上延時確 保傳輸完成 } #endif//DTC_TRANSFER_MODE #endif//USE_MY_TRANSFER_INFOR_CONFIG /* 將傳輸后的數據與我們所期待的結果相比較 */ res =?BufferCompare(DST_Buffer, Expected_DST_Buffer, BUFFER_SIZE); printf("傳輸結果:"); /* 根據兩者數據的比較結果進行判斷 */ if( res !=?0) { /* 源數據與傳輸后數據不相等時,LED1 亮(紅色),表示傳輸失敗 */ LED1_ON; printf("< 傳輸失敗> "); } else { /* 源數據與傳輸后數據相等時,LED1 亮(藍色),表示傳輸成功 */ LED2_ON; printf("< 傳輸成功> "); } printf(" SRC:"); BufferShow_HexData(SRC_Buffer, BUFFER_SIZE); printf(" DST:(應與 Expected_DST 一致)"); BufferShow_HexData(DST_Buffer, BUFFER_SIZE); printf(" Expected_DST:"); BufferShow_HexData(Expected_DST_Buffer, BUFFER_SIZE); while(1) { } #ifBSP_TZ_SECURE_BUILD /* Enter non-secure code */ R_BSP_NonSecureEnter(); #endif }
19.9.3
實驗現象
首先通過宏USE_MY_TRANSFER_INFOR_CONFIG(在bsp_dtc.h文件中)來選擇是使用我們自定義的傳輸信息,還是使用在FSP配置界面配置的傳輸信息。
其次通過宏DMAC_TRANSFER_MODE(在bsp_dtc.h文件中)來選擇不同的傳輸模式。
最后編譯工程并下載到開發板上,打開串口助手可以查看程序運行打印的提示信息。按下啟明6M5開發板上的按鍵SW2,即觸發DT傳輸。如果DTC傳輸成功,則藍色LED2亮起,如果傳輸失敗則紅色LED1亮起。
-
瑞薩
+關注
關注
37文章
22481瀏覽量
90858 -
開發環境
+關注
關注
1文章
270瀏覽量
17637 -
外部中斷
+關注
關注
1文章
135瀏覽量
16603
原文標題:實驗3:DTC外部中斷觸發傳輸——瑞薩RA系列FSP庫開發實戰指南(59)
文章出處:【微信號:瑞薩嵌入式小百科,微信公眾號:瑞薩嵌入式小百科】歡迎添加關注!文章轉載請注明出處。
發布評論請先 登錄
瑞薩RA系列FSP庫開發實戰指南之QSPI讀寫外部Flash芯片實驗
瑞薩RA系列FSP庫開發實戰指南之DTC外部中斷觸發傳輸實驗
評論