日本高清不卡中文字幕-一起草草视频在线观看-亚洲精品一区二区三区色-国产亚洲精品免费视频

您好,歡迎進入深圳市穎特新科技有限公司官方網(wǎng)站!

您現(xiàn)在的位置:首頁 新聞資訊 >> 新聞頭條 >> 說說M451例程講解之LED
新聞資訊
NEWS INFORMATION

說說M451例程講解之LED

關鍵字:M451 發(fā)布時間:2019-05-22
/**************************************************************************//**
 * @file     main.c
 * @version  V3.00
 * $Revision: 3 $
 * $Date: 15/09/02 10:03a $
 * @brief    Demonstrate how to set GPIO pin mode and use pin data input/output control.
             演示如何設置GPIO引腳模式并使用引腳數(shù)據(jù)輸入/輸出控制。
 * @note
 * Copyright (C) 2013~2015 Nuvoton Technology Corp. All rights reserved.
 *
 ******************************************************************************/
#include "stdio.h"
#include "M451Series.h"
#include "NuEdu-Basic01.h"

#define PLL_CLOCK       72000000


void SYS_Init(void)
{
    /*---------------------------------------------------------------------------------------------------------*/
    /* Init System Clock                                                                                       */
    /*---------------------------------------------------------------------------------------------------------*/

    /* Enable HIRC clock (Internal RC 22.1184MHz) */
    CLK_EnableXtalRC(CLK_PWRCTL_HIRCEN_Msk);

    /* Wait for HIRC clock ready */
    CLK_WaitClockReady(CLK_STATUS_HIRCSTB_Msk);

    /* Select HCLK clock source as HIRC and and HCLK clock divider as 1 */
    CLK_SetHCLK(CLK_CLKSEL0_HCLKSEL_HIRC, CLK_CLKDIV0_HCLK(1));

    /* Enable HXT clock (external XTAL 12MHz) */
    CLK_EnableXtalRC(CLK_PWRCTL_HXTEN_Msk);

    /* Wait for HXT clock ready */
    CLK_WaitClockReady(CLK_STATUS_HXTSTB_Msk);

    /* Set core clock as PLL_CLOCK from PLL */
    CLK_SetCoreClock(PLL_CLOCK);

    /* Enable UART module clock */
    CLK_EnableModuleClock(UART0_MODULE);

    /* Select UART module clock source as HXT and UART module clock divider as 1 */
    CLK_SetModuleClock(UART0_MODULE, CLK_CLKSEL1_UARTSEL_HXT, CLK_CLKDIV0_UART(1));

    /*---------------------------------------------------------------------------------------------------------*/
    /* Init I/O Multi-function                                                                                 */
    /*---------------------------------------------------------------------------------------------------------*/

    /* Set PD multi-function pins for UART0 RXD(PD.6) and TXD(PD.1) */
    SYS->GPD_MFPL &= ~(SYS_GPD_MFPL_PD6MFP_Msk | SYS_GPD_MFPL_PD1MFP_Msk);
    SYS->GPD_MFPL |= (SYS_GPD_MFPL_PD6MFP_UART0_RXD | SYS_GPD_MFPL_PD1MFP_UART0_TXD);

}

void UART0_Init()
{
    /*---------------------------------------------------------------------------------------------------------*/
    /* Init UART                                                                                               */
    /*---------------------------------------------------------------------------------------------------------*/
    /* Reset UART module */
    SYS_ResetModule(UART0_RST);

    /* Configure UART0 and set UART0 baud rate */
    UART_Open(UART0, 115200);
}

/*---------------------------------------------------------------------------------------------------------*/
/*  Main Function                                                                                          */
/*---------------------------------------------------------------------------------------------------------*/
int32_t main(void)
{
    int i, j;
    /* Unlock protected registers */
    SYS_UnlockReg();

    /* Init System, peripheral clock and multi-function I/O */
    SYS_Init();

    /* Lock protected registers */
    SYS_LockReg();

    /* Init UART0 for printf */
    UART0_Init();

    printf("\n\nCPU @ %dHz\n",   SystemCoreClock);

    printf("LED test\n\r");

    Initial_LED();

    while(1)
    {
        for(i = 0; i < 9; i++)
        {
            Write_LED_Bar(i);
            for(j = 0; j < 600; j++)
                CLK_SysTickDelay(1000);
        }
有必要說說LED,正所謂每一個程序剛開始都要寫“HELLO WORLD”,而單片機或嵌入式都要點亮小燈,萬物從點燈開始,哈哈
它的結構很簡單
LED,是一種能夠將電能轉化為可見光的固態(tài)的半導體器件,即發(fā)光二極管,它可以直接把電轉化為光。LED的心臟是一個半導體的晶片,晶片的一端附在一個支架上,一端是負極,
另一端連接電源的正極,使整個晶片被環(huán)氧樹脂封裝起來。半導體晶片由兩部分組成,一部分是P型半導體,在它里面空穴占主導地位,另一端是N型半導體,在這邊主要是電子。
這兩種半導體連接起來的時候,它們之間就形成一個P-N結。當電流通過導線作用于這個晶片的時候,電子就會被推向P區(qū),在P區(qū)里電子跟空穴復合,然后就會以光子的形式發(fā)出能量,
這就是LED燈發(fā)光的原理。而光的波長也就是光的顏色,是由形成P-N結的材料決定的。
單個的LED燈珠只能在低電壓(約3V)、低電流(約幾毫安)下工作,發(fā)出的光線很微弱。需要將許多LED燈珠串聯(lián)或并聯(lián)起來;
同時單個LED燈珠是單向導電的,為了充分利用交流電的正負半周電流,這就需要一塊集成電路芯片,將交流220V電源轉變?yōu)殡妷骸㈦娏髂芘cLED集合相匹配的直流電,
以滿足LED燈珠集合體的要求,使其能正常發(fā)光。
下圖是

MCU 外圍連接

電路圖您明白了么?再看軟件的相應的庫文件

/* Peripheral and SRAM base address */
#define SRAM_BASE            (0x20000000UL)                              /*!< (SRAM      ) Base Address */
#define PERIPH_BASE          (0x40000000UL)                              /*!< (Peripheral) Base Address */

 

#define AHBPERIPH_BASE       PERIPH_BASE
#define APBPERIPH_BASE       (PERIPH_BASE + 0x00040000)

 

#define GCR_BASE             (AHBPERIPH_BASE + 0x00000)               
#define CLK_BASE             (AHBPERIPH_BASE + 0x00200)
#define INT_BASE             (AHBPERIPH_BASE + 0x00300)
#define GPIO_BASE            (AHBPERIPH_BASE + 0x04000)
#define GPIOA_BASE           (AHBPERIPH_BASE + 0x04000)
#define GPIOB_BASE           (AHBPERIPH_BASE + 0x04040)
#define GPIOC_BASE           (AHBPERIPH_BASE + 0x04080)
#define GPIOD_BASE           (AHBPERIPH_BASE + 0x040C0)
#define GPIOE_BASE           (AHBPERIPH_BASE + 0x04100)
#define GPIOF_BASE           (AHBPERIPH_BASE + 0x04140)
#define GPIO_DBCTL_BASE      (AHBPERIPH_BASE + 0x04440)
#define GPIO_PIN_DATA_BASE   (AHBPERIPH_BASE + 0x04800)
#define PDMA_BASE            (AHBPERIPH_BASE + 0x08000)
#define USBH_BASE            (AHBPERIPH_BASE + 0x09000)
#define FMC_BASE             (AHBPERIPH_BASE + 0x0C000)
#define EBI_BASE             (AHBPERIPH_BASE + 0x10000)
#define CRC_BASE             (AHBPERIPH_BASE + 0x31000)

 


#define SYS ((SYS_T *) GCR_BASE)
#define SYSINT ((SYS_INT_T *) INT_BASE) 
#define CLK ((CLK_T *) CLK_BASE)
#define PA ((GPIO_T *) GPIOA_BASE)
#define PB ((GPIO_T *) GPIOB_BASE)
#define PC ((GPIO_T *) GPIOC_BASE)
#define PD ((GPIO_T *) GPIOD_BASE)
#define PE ((GPIO_T *) GPIOE_BASE)
#define PF ((GPIO_T *) GPIOF_BASE)
#define GPIO ((GPIO_DBCTL_T *) GPIO_DBCTL_BASE)
#define PDMA ((PDMA_T *) PDMA_BASE)
#define USBH ((USBH_T *) USBH_BASE)
#define FMC ((FMC_T *) FMC_BASE)
#define EBI ((EBI_T *) EBI_BASE)
#define CRC ((CRC_T *) CRC_BASE)

#define GPIO_MODE_INPUT 0x0UL /*!< Input Mode */
#define GPIO_MODE_OUTPUT 0x1UL /*!< Output Mode */
#define GPIO_MODE_OPEN_DRAIN 0x2UL /*!< Open-Drain Mode */
#define GPIO_MODE_QUASI 0x3UL /*!< Quasi-bidirectional Mode */

/* One Bit Mask Definitions */
#define BIT0 0x00000001
#define BIT1 0x00000002
#define BIT2 0x00000004
#define BIT3 0x00000008
#define BIT4 0x00000010
#define BIT5 0x00000020
#define BIT6 0x00000040
#define BIT7 0x00000080
#define BIT8 0x00000100
#define BIT9 0x00000200
#define BIT10 0x00000400
#define BIT11 0x00000800
#define BIT12 0x00001000
#define BIT13 0x00002000
#define BIT14 0x00004000
#define BIT15 0x00008000
#define BIT16 0x00010000
#define BIT17 0x00020000
#define BIT18 0x00040000
#define BIT19 0x00080000
#define BIT20 0x00100000
#define BIT21 0x00200000
#define BIT22 0x00400000
#define BIT23 0x00800000
#define BIT24 0x01000000
#define BIT25 0x02000000
#define BIT26 0x04000000
#define BIT27 0x08000000
#define BIT28 0x10000000
#define BIT29 0x20000000
#define BIT30 0x40000000
#define BIT31 0x80000000

void GPIO_SetMode(GPIO_T *port, uint32_t u32PinMask, uint32_t u32Mode)
{
uint32_t i;

for(i = 0; i < GPIO_PIN_MAX; i++)
{
if(u32PinMask & (1 << i))
{
port->MODE = (port->MODE & ~(0x3 << (i << 1))) | (u32Mode << (i << 1));
}
}
}

void Initial_LED(void)
{
GPIO_SetMode(PB, BIT2, GPIO_MODE_OUTPUT); //LED1
GPIO_SetMode(PB, BIT3, GPIO_MODE_OUTPUT); //LED2
GPIO_SetMode(PC, BIT3, GPIO_MODE_OUTPUT); //LED3
GPIO_SetMode(PC, BIT2, GPIO_MODE_OUTPUT); //LED4
GPIO_SetMode(PA, BIT9, GPIO_MODE_OUTPUT); //LED5
GPIO_SetMode(PB, BIT1, GPIO_MODE_OUTPUT); //LED6
GPIO_SetMode(PC, BIT7, GPIO_MODE_OUTPUT); //LED7
}

關于AHB與APB在我的內核架構一文中有描述,再此不加說明。
你把這幾部分放到一個程序中完全可以運行
I/O管腳的I狀態(tài)可由軟件獨立地配置為輸入,推挽式的輸出,開漏或準雙向模式。復位之后,所有管腳的模式取決于CIOIN (CONFIG0[10])的設置。
每個I/O管腳有一個阻值為110K~300K的弱上拉電阻接到VDD 上,VDD范圍從5.0 V 到2.5 V。

首先我們來看上拉電阻與下拉電阻:

兩者共同的作用是:避免電壓的“懸浮”,造成電路的不穩(wěn)定;


一、上拉電阻如圖所示

1、概念:將一個不確定的信號,通過一個電阻與電源VCC相連,固定在高電平;2、上拉是對器件注入電流;灌電流;3、當一個接有上拉電阻的IO端口設置為輸入狀態(tài)時,它的常態(tài)為高電平;

 

二、下拉電阻如圖所示:

1、 概念:將一個不確定的信號,通過一個電阻與地GND相連,固定在低電平;

2、下拉是從器件輸出電流;拉電流;3、當一個接有下拉電阻的IO端口設置為輸入狀態(tài)時,它的常態(tài)為低電平;

 

要理解推挽輸出,首先要理解好三極管(晶體管)的原理。下面這種三極管有三個端口,分別是基極(Base)、集電極(Collector)和發(fā)射極(Emitter)。

下圖是NPN型晶體管。

 

這種三極管是電流控制型元器件,注意關鍵詞電流控制。意思就是說,只要基極B有輸入(或輸出)電流就可以對這個晶體管進行控制了。

下面請允許我換一下概念,把基極B視為控制端,集電極C視為輸入端,發(fā)射極E視為輸出端。這里輸入輸出是指電流流動的方向。

當控制端有電流輸入的時候,就會有電流從輸入端進入并從輸出端流出。
 

PNP管正好相反,當有電流從控制端流出時,就會有電流從輸入端流到輸出端。

 

那么推挽電路

上面的三極管是N型三極管,下面的三極管是P型三極管,請留意控制端、輸入端和輸出端。

Vin電壓為V+時,上面的N型三極管控制端有電流輸入,Q3導通,于是電流從上往下通過,提供電流給負載。

經(jīng)過上面的N型三極管提供電流給負載(Rload),這就叫「

Vin電壓為V-時,下面的三極管有電流流出,Q4導通,有電流從上往下流過。

經(jīng)過下面的P型三極管提供電流給負載(Rload),這就叫「」。

以上,這就是推挽(push-pull)電路。

 

那么什么是開漏呢?這個在我答案一開頭給出的「網(wǎng)上資料」里講得很詳細了,我這里也簡單寫一下。

要理解開漏,可以先理解開集。

如圖,開集的意思,就是集電極C一端什么都不接,直接作為輸出端口。

如果要用這種電路帶一個負載,比如一個LED,必須接一個上拉電阻,就像這樣。

當Vin沒有電流,Q5斷開時,LED亮。 當Vin流入電流,Q5導通時,LED滅。

開漏電路,就是把上圖中的三極管換成場效應管(MOSFET)。

N型場效應管各個端口的名稱:

場效應管是電壓控制型元器件,只要對柵極施加電壓,DS就會導通。

結型場效應管有一個特性就是它的輸入阻抗非常大,這意味著:沒有電流從控制電路流出,也沒有電流進入控制電路。沒有電流流入或流出,就不會燒壞控制電路。而雙極型晶體管不同,是電流控制性元器件,如果使用開集電路,可能會燒壞控制電路。這大概就是我們總是聽到開漏電路而很少聽到開集電路的原因吧?因為開集電路被淘汰了。

1、開漏全部名字是,內部mos管漏極開路(也可理解為晶體管集電極開路)。輸出引腳只有對地低阻抗以及高阻態(tài)兩種模式。

2、推挽內部有上下兩個mos(或晶體管),輸出引腳有對VCC低阻抗以及對地低阻抗兩種模式。

下面付一個無腦版的,用開關代替晶體管或MOS管。等效電路。

1. 推挽輸出能夠輸出高或者低,而開漏輸出只能輸出低,或者關閉輸出,因此開漏輸出總是要配一個上拉電阻使用。2. 開漏輸出的上拉電阻不能太小,太小的話,當開漏輸出的下管導通時,電源到地的電壓在電阻上會造成很大的功耗,因此這個電阻阻值通常在10k以上,這樣開漏輸出在從輸出低電平切換到高電平時,速度是很慢的。3. 推挽輸出任意時刻的輸出要么是高,要么是低,所以不能將多個輸出短接,而開漏輸出可以將多個輸出短接,共用一個上拉,此時這些開漏輸出的驅動其實是與非的關系。4. 推挽輸出輸出高時,其電壓等于推挽電路的電源,通常為一個定值,而開漏輸出的高取決于上拉電阻接的電壓,不取決于前級電壓,所以經(jīng)常用來做電平轉換,用低電壓邏輯驅動高電壓邏輯,比如3.3v帶5v。

 

單片機的幾種IO口配置

 

單片機學習、開發(fā)和應用中,IO口的配置對功能的實現(xiàn)起著重要的作用,下面介紹常見的四種配置,而現(xiàn)在很多單片機都兼有這四種配置,可供選擇。

 

一.準雙向口配置

 

如下圖,當IO輸出為高電平時,其驅動能力很弱,外部負載很容易將其拉至低電平。當IO輸出為低電平時,其驅動能力很強,可吸收相當大的電流。

 

準雙向口有三個上拉晶體管,一個“極弱上拉”,當端鎖存器為邏輯“1”時打開,當端口懸空時,“極弱上拉”將端口上拉至高電平。

 

第二個上拉晶體管為“弱上拉”,當端口鎖存器為邏輯“1”且端口本身也為“1”時打開,此上拉提供的電流,使準雙向口輸出為“1”。如果此時端口被外部裝置拉到邏輯“0”時,通過施密特觸發(fā)器,控制“弱上拉”關閉,而“極弱上拉”維持開狀態(tài),為了把這個端口拉低,外部裝置必須有足夠的灌電流能力,使管腳上的電壓,降到門檻電以下。

 

第三個上拉晶體管為“強上拉”,當端口鎖存器由“0”跳變到“1”時,這個上拉用來加快端口由邏輯“0”到邏輯“1”的轉換速度。

 

準雙向口做為輸入時,通個一個施密特觸如器和一個非門,用以干擾和濾波。

 

 

 

 

準雙向口用作輸入時,可對地接按鍵,如下圖1,當然也可以去掉R1直接接按鍵,當按鍵閉合時,端口被拉至低電平,當按鍵松開時,端口被內部“極弱上拉”晶體管拉至高電平。當端口作為輸出時,不應對地外接LED如圖形控制,這樣端口的驅動能力很弱,LED只能發(fā)很微弱的光,如果要驅動LED,要采用圖3的方法,這樣準雙向口在輸出為低時,可吸收20mA的電流,故能驅動LED。圖4的方法也可以,不過LED不發(fā)光時,端口要吸收收很大電流。

 

 

 

 

二.開漏輸出配置

 

這種配置,關閉所有上拉晶體管,只驅動下拉晶體管,下拉與準雙向口下拉配置相同,因此只能輸出低電平(吸收電流),和高阻狀態(tài)。不能輸出高電平(輸也電流)。如果要作為邏輯輸出,必須接上拉電阻到VCC。這種配置也可以通過上圖3和圖4來驅動LED。

 

 

 

 

三.推挽輸出配置

 

這種配置的下拉與準雙向口和開漏配置相同,具有較強的拉電流能力,不同的是,具有持續(xù)的強上拉。因此可以用上圖2的方法來驅動LED。

 

 

 

 

四.僅為輸入配置(高阻配置)

 

這種配置不能輸出電流,也不能有收電流,只能作為輸入數(shù)據(jù)使用。

 

 

 

 

以上四種配置各有其特點,在使用中應根據(jù)其特點靈活運用。

 

準雙向口的最大特點是既可以作為輸入,也可以作為輸出,不需要通過控制切換。

 

推挽輸出的特點是,無論輸也高電平還是低電平都有較大的驅動能力,在輸也高電平時,也能直接點亮LED,這在準雙向口中是不能辦到的。這種配置不宜作為輸入,因為這需要外部設備有很強的拉電流的能胃。

 

僅為輸入配置的特點是端口只能作為輸入使用,可以獲得很高的輸入阻抗,在有模擬比較器或ADC的端口中用得較多。

 

開漏輸出配置與準又向口相似,但內部沒有上拉電阻。有很好的電氣兼容性,外部接上拉電阻到3V電源,就能和3V邏輯器件連接。外部接上拉電阻到5V電源,就要以和5V器件連接。

 

需要說明的是以上四種配置均可以作為輸入,也就是都可以檢測端的邏輯狀態(tài),但其特性不同,不是每種配置都可以直接接按鍵

就講到這里,其實這就是I/O口的輸入輸出模式,具體看程序就可以清楚明白了

GPIO_SetMode(PC, BIT7, GPIO_MODE_OUTPUT);//#define GPIO_MODE_OUTPUT 0x0UL /*!< Input Mode */

設置成為了輸出模式,之后我們在來看,這個函數(shù)的具體功能

 while(1)
    {
        for(i = 0; i < 9; i++)
        {
            Write_LED_Bar(i);
            for(j = 0; j < 600; j++)
                CLK_SysTickDelay(1000);
        }
    }

#define _LED1 PB2#define _LED2 PB3#define _LED3 PC3#define _LED4 PC2#define _LED5 PA9#define _LED6 PB1#define _LED7 PC7


#define _LED_Bar_Count      7
void Write_LED_Bar(uint32_t Number)
{
    uint32_t i;
    volatile uint32_t *ptrLED[_LED_Bar_Count] = {&_LED1, &_LED2, &_LED3, &_LED4, &_LED5, &_LED6, &_LED7};

    for(i = 0; i < _LED_Bar_Count; i++)
    {
        if((Number > i) & 0x01)
            *ptrLED[i] = 0; //LED ON
        else
            *ptrLED[i] = 1; //LED OFF
    }
}

如果我們假設Number為一的話,i為零時,1大于零,為真,為一,遇上0X01之后為真,則進行負值為零(開燈)的操作,它是共陽級的操作。

試試我寫的這個

#define _LED1 PB2#define _LED2 PB3#define _LED3 PC3#define _LED4 PC2#define _LED5 PA9#define _LED6 PB1#define _LED7 PC7


volatile uint32_t *ptrLED[_LED_Bar_Count] = {&_LED1, &_LED2, &_LED3, &_LED4, &_LED5, &_LED6, &_LED7};


while(1)
    {
                    
       for(i = 0; i < 7; i++)
        {
          *ptrLED[i]=0;
                    for(j = 0; j < 600; j++)
                    {
              CLK_SysTickDelay(1000);
                    }
                    *ptrLED[i]=1;
                    for(j = 0; j < 600; j++)
                    {
              CLK_SysTickDelay(1000);
                    }
                    if(i==8)
                    {
                    i=0;
                    }
        }
    }

這里需要的庫文件有很多,另外LED很簡單,不需要用到很多的庫函數(shù),下回我說說GPIO.H吧!

 

 

聯(lián)系方式0755-82591179

傳真:0755-82591176

郵箱:vicky@yingtexin.net

地址:深圳市龍華區(qū)民治街道民治大道973萬眾潤豐創(chuàng)業(yè)園A棟2樓A08

晋江市| 怀远县| 双鸭山市| 通道| 临高县| 九台市| 大安市| 子洲县| 宁强县| 沛县| 吉木乃县| 昆明市| 诸城市| 定西市| 阳谷县| 镇康县| 象山县| 黄冈市| 宜君县| 香港 | 吴忠市| 连云港市| 乐至县| 乃东县| 阿拉善右旗| 长沙县| 泽普县| 朝阳县| 桓仁| 扎兰屯市| 蛟河市| 扎兰屯市| 赤峰市| 大新县| 政和县| 长兴县| 东至县| 丰宁| 建宁县| 新宾| 呼伦贝尔市|