BlackfinDSP的寄存器是經過指針操做的,與5一、ARM等MCU同樣,經過「或」操做來置1,經過「與」操做清零。html
在DSP上最簡單的外設非IO口莫屬,可是因爲其功能強大,遠非通常IO口可比,所以區別的稱之爲「GPIO」(general purpose IO),也稱爲PF(programmable flagas)口,本文經過GPIO控制LED來演示寄存器的操做方式。app
//=============== 開發環境 ======================async
上位機: win7 旗艦版ui
DSP環境: CCES1.0.2 (用Blackfin DSP第一節:新建工程一文中的Visual DSP++徹底同樣)spa
開發板 : ADSP-BF561 EZKIT(用561的緣由是,手頭的533EZKIT的GPIO鏈接到了FLASH上,想驅動LED,必須先對FLASH進行操做,比較麻煩,之後會盡可能採 用533,雖然用561,可是操做方式是一致的,只不過寄存器的定義不一樣) prototype
//================ 原理圖 =====================3d
由圖可見,LED1~LED8分別鏈接在PF40~PF47口,當PFx輸出爲高電平時,可點亮相應的LED。指針
//================ 寄存器定義 =====================code
1.方向寄存器(參考Hardware reference)htm
首先,必須將PFx的方向設置爲輸出;
2.設置輸出電平
輸出高電平是經過FLAG_SET寄存器來進行設置的,在相應的位寫1,便可設置爲高電平。定義以下:
輸出低電平是經過FLAG_CLEAR寄存器實現,寫1清除相應的端口電平值。(圖就不貼了)
//=================== 寄存器的操做 ======================
blackfin系列的寄存器定義都是在安裝目錄下的cdefbf5xx.h中定義的,爲此,在程序的開始部分要包含相應的頭文件。好比cdefbf561.h包含了全部561寄存器的定義:
…… #define pFIO2_FLAG_D ((volatile unsigned short *)FIO2_FLAG_D) #define pFIO2_FLAG_C ((volatile unsigned short *)FIO2_FLAG_C) #define pFIO2_FLAG_S ((volatile unsigned short *)FIO2_FLAG_S) #define pFIO2_FLAG_T ((volatile unsigned short *)FIO2_FLAG_T) ……
#define FIO2_FLAG_D 0xFFC01700 /* Flag Data register (mask used to directly */ #define FIO2_FLAG_C 0xFFC01704 /* Flag Clear register */ #define FIO2_FLAG_S 0xFFC01708 /* Flag Set register */ #define FIO2_FLAG_T 0xFFC0170C /* Flag Toggle register (mask used to */
這是一個地址指針,所以能夠直接看成指針來操做,好比置1操做以下:
*pFIO2_DIR |= 0xFF00; /*將pFIO2_DIR的高8位置爲1*/
//=================== 代碼示例=======================
如下代碼中包含了GPIO的輸出、輸入、反轉 這三個功能的設置方法,對於其它功能,能夠查看硬件手冊。
#include <cdefbf561.h> /* C POINTERS TO SYSTEM MMR REGISTER AND MEMORY MAP FOR ADSP-BF561 */ #include <adi_types.h> /* type defines */ #include <ccblkfn.h> /* include the async() function prototype */ void TurnOnLed(uint8_t nLed); void msDelay(uint32_t msec) ; void TurnOffAllLed(void); void ToggleLed(uint8_t nLed); void delay(int i); void main(void) { TurnOnLed(1); // 打開LED1 (PF40) TurnOnLed(2); // 打開LED2 (PF41) msDelay(100); TurnOffAllLed(); // 關閉全部LED TurnOnLed(1); // 打開LED1 (PF40) TurnOnLed(2); // 打開LED2 (PF41) msDelay(100); TurnOffAllLed(); // 關閉全部LED while(1) //blink { ToggleLed(1); //翻轉LED msDelay(100); } } /* GPIO as output */ void TurnOnLed(uint8_t nLed) { *pFIO2_DIR |= 0xFF00; /*set PF40~PF47 as output */ ssync(); *pFIO2_FLAG_S = ( 1 << (nLed+7) ); /*set the corresponding bit in FLAG_SET register as high*/ ssync(); } /* GPIO as input */ void TurnOffAllLed(void) { *pFIO2_DIR |= 0xFF00; /*set PF40~PF47 as output */ ssync(); *pFIO2_FLAG_C = 0xFF00; /*set Flag_clear register to clear the PFx */ ssync(); } /* Toggle GPIO */ void ToggleLed(uint8_t nLed) { *pFIO2_DIR |= 0xFF00; ssync(); *pFIO2_FLAG_T = (1 << (nLed+7) ); // write 1 to toggle ssync(); } /********************************************************************* Function: ezDelay Description: Delays for approximately 1 msec when running at 600 MHz *********************************************************************/ void msDelay(uint32_t msec) { volatile uint32_t i,j; // value of 0x3000000 is about 1 sec so 0xc49b is about 1msec for (j = 0; j < msec; j++) { for (i = 0; i < 0xc49b; i++) ; } }
P.S:要想用好DSP,首先最重要的就是把寄存器的定義讀懂,那Hardware reference 必不可少,作到哪都到哪,纔能有所領悟~不看手冊,那是不行地。。。