Blackfin DSP(二):寄存器操做與GPIO

  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 必不可少,作到哪都到哪,纔能有所領悟~不看手冊,那是不行地。。。

相關文章
相關標籤/搜索