Hướng dẫn Bài 3 - Lập trình điều khiển I/O cho ARM Cortex-M0

Thảo luận trong 'Tutorial với ARM Cortex-M0 của Nuvoton'

Đang xem chủ đề này ( Thành viên: 0, Khách: 0)

  1. daotruongpro

    daotruongpro http://vtechpro.vn

    Tham gia ngày:
    4/9/12
    Bài viết:
    382
    Đã được thích:
    497
    Điểm thành tích:
    93
    Giới tính:
    Nam
    Nghề nghiệp:
    Kỹ sư Điện tử - Truyền thông
    Nơi ở:
    Hà Nội
    Bài này hướng dẫn điều khiển Output ra các PIN của ARM Cortex-M0 NUC140
    - Sơ đồ ghép nối phần cứng trên Board như sau:

    upload_2013-9-26_15-47-49.
    - Các Catot của led được nối với PIN của MCU từ PORT GPC (12-16). Như vậy muốn cho Led sáng thì xuất mức 0 ra các PIN của PORT GPC (12-16).
    - Các lệnh Output như sau:
    + Lệnh Output mức 0: DrvGPIO_ClrBit(E_GPC,Pin); // pin=0 -15
    + Lệnh Output mức 1: DrvGPIO_SetBit(E_GPC,Pin); // pin=0 -15
    Thạch anh sử dụng 12MHz
    Chương trình như sau:
    Mã:
    #include <stdio.h>
    #include "NUC1xx.h"
    #include "Driver\DrvGPIO.h"
    #include "Driver\DrvSYS.h"
    
    int Data=12,i;
    //Chuong trinh Delay
    void Delay(uint32_t counter)
    {
        while(counter--);
    }
    //Chuong trinh chinh
    int main (void)
    {
        /* Unlock the protected registers */   
        UNLOCKREG();
          /* Enable the 12MHz oscillator oscillation */
        DrvSYS_SetOscCtrl(E_SYS_XTL12M, 1);
        /* HCLK clock source. 0: external 12MHz; 4:internal 22MHz RC oscillator */
        DrvSYS_SelectHCLKSource(0);       
        /*lock the protected registers */
        LOCKREG();               
    
        DrvSYS_SetClockDivider(E_SYS_HCLK_DIV, 0); /* HCLK clock frequency = HCLK clock source / (HCLK_N + 1) */
    //PORT_E tu PIN 12 -15 la Output
    for(i=12;i<16;i++)
            {       
                DrvGPIO_Open(E_GPC, i, E_IO_OUTPUT);
        }
      while(1)
        {
            DrvGPIO_ClrBit(E_GPC,Data); //Output lan luot ra cac Led
            Delay(500000); Data++;
            if(Data==16) // Tat ca cac Led deu tat
              {
                  for(i=12;i<16;i++)
                  {
                      DrvGPIO_SetBit(E_GPC,i);//Set Pin =1     
                  }
                Delay(500000);
                Data=12;//Quay lai ban dau
          }
        }
    }
    
    Chúc thành công !
     
  2. phungduchiep

    phungduchiep Kỹ sư

    Tham gia ngày:
    8/5/13
    Bài viết:
    286
    Đã được thích:
    130
    Điểm thành tích:
    43
    Giới tính:
    Nam
    bao giờ trường em mới được đầu tư main này :((
     
  3. daotruongpro

    daotruongpro http://vtechpro.vn

    Tham gia ngày:
    4/9/12
    Bài viết:
    382
    Đã được thích:
    497
    Điểm thành tích:
    93
    Giới tính:
    Nam
    Nghề nghiệp:
    Kỹ sư Điện tử - Truyền thông
    Nơi ở:
    Hà Nội
    Bạn học trường nào vậy??? Thích thì Click thôi bạn cứ gì phải ai đầu tư :-bd.Học điện tử phải có quyết định riêng của mình và hãy làm những gì bạn thích. sau này đi làm bạn sẽ thấy cái giá của việc đó :)):)):))
     
  4. marketer182

    marketer182 Học sinh phổ thông

    Tham gia ngày:
    26/9/13
    Bài viết:
    4
    Đã được thích:
    2
    Điểm thành tích:
    1
    Giới tính:
    Nam
    Như trên source code theo mình hiểu là Bật sáng lần lượt các LED 12 -> 16 sau khi các đèn đều sáng thì tắt lần lượt các đèn từ 12 -> 16 và cứ thế lặp lại sau hàm delay.
    Mình muốn hỏi tại sao lại là 500000 vậy bạn, làm sao để có thể tính được số lần đếm theo thời gian ra số giây cụ thể với xung 12Mhz Delay(500000);

    Yahoo của mình là: smallzero_1911
     
  5. UITsteven

    UITsteven Sinh viên đại học

    Tham gia ngày:
    26/9/13
    Bài viết:
    81
    Đã được thích:
    55
    Điểm thành tích:
    18
    Giới tính:
    Nam
    Mình xin chia sẻ điều khiển I/O trên NUC140 bằng Interrupt Timer và đã test Ok trên KIT Nuvoton của trường:
    Mã:
    #include <stdio.h>
    #include "NUC1xx.h"
    #include "Driver\DrvSYS.h"
    #include "Driver\DrvGPIO.h"
    
    static unsigned char count=0;
    void TMR0_IRQHandler(void)
    {
        unsigned char i=0;
        TIMER0->TISR.TIF=1;
        count++;
    if(count==12)
        {
            DrvGPIO_ClrBit(E_GPC,12);
            DrvGPIO_ClrBit(E_GPC,14);
            DrvGPIO_SetBit(E_GPC,13);
            DrvGPIO_SetBit(E_GPC,15);
         
        }
        else if(count==24)
        {
            DrvGPIO_ClrBit(E_GPC,13);
            DrvGPIO_ClrBit(E_GPC,15);
            DrvGPIO_SetBit(E_GPC,12);
            DrvGPIO_SetBit(E_GPC,14);
            count=0;
        }
    }
    
    void Timer_initial(void)
    {
        /* Step 1. Enable and Select Timer clock source */       
        SYSCLK->CLKSEL1.TMR0_S = 0;    //Select 12Mhz for Timer0 clock source
        SYSCLK->APBCLK.TMR0_EN =1;    //Enable Timer0 clock source
    
        /* Step 2. Select Operation mode */ 
        TIMER0->TCSR.MODE=1;        //Select periodic mode for operation mode
    
        /* Step 3. Select Time out period = (Period of timer clock input) * (8-bit Prescale + 1) * (24-bit TCMP)*/
        TIMER0->TCSR.PRESCALE=0;    // Set Prescale [0~255]
        TIMER0->TCMPR  = 1000000;        // Set TICR(TCMP) [0~16777215]
                                    // (1/12000000)*(0+1)*(1000000)= 1/12s
    
        /* Step 4. Enable interrupt */
        TIMER0->TCSR.IE = 1;
        TIMER0->TISR.TIF = 1;        //Write 1 to clear for safty     
        NVIC_EnableIRQ(TMR0_IRQn);    //Enable Timer0 Interrupt
    
        /* Step 5. Enable Timer module */
        TIMER0->TCSR.CRST = 1;        //Reset up counter
        TIMER0->TCSR.CEN = 1;        //Enable Timer0
    
          TIMER0->TCSR.TDR_EN=1;        // Enable TDR function
    }
    
    int main(void)
    {
        int i=0,j=0;
        /* Unlock the protected registers */ 
        UNLOCKREG();
          /* Enable the 12MHz oscillator oscillation */
        DrvSYS_SetOscCtrl(E_SYS_XTL12M, 1);
    
        /* Waiting for 12M Xtal stalble */
        SysTimerDelay(5000);
    
        /* HCLK clock source. 0: external 12MHz; 4:internal 22MHz RC oscillator */
        DrvSYS_SelectHCLKSource(0);     
        /*lock the protected registers */
        LOCKREG();             
    
        DrvSYS_SetClockDivider(E_SYS_HCLK_DIV, 0); /* HCLK clock frequency = HCLK clock source / (HCLK_N + 1) */
    
        for(i=12;i<16;i++)
        {     
            DrvGPIO_Open(E_GPC, i, E_IO_OUTPUT);
         
        }
        Timer_initial();
    }
     
    NhatPhamdaotruongpro thích bài này.
  6. UITsteven

    UITsteven Sinh viên đại học

    Tham gia ngày:
    26/9/13
    Bài viết:
    81
    Đã được thích:
    55
    Điểm thành tích:
    18
    Giới tính:
    Nam
    Cái này còn tùy thuộc vào Timer mà mình chọn, mình đã có up cái Interrupt Timer đó, có công thức tính thời gian đó, bạn có thể trao đổi với mình
     
  7. marketer182

    marketer182 Học sinh phổ thông

    Tham gia ngày:
    26/9/13
    Bài viết:
    4
    Đã được thích:
    2
    Điểm thành tích:
    1
    Giới tính:
    Nam
    Chào các bạn.. Mình là sinh viên UIT - Hiện trường mình có được tặng bộ KIT Nuvoton NU-LB-NUC140, do mình học khoa Kỹ Thuật Máy Tính nên cũng được sử dụng bộ KIT này trong quá trình học tập.
    Vì còn gà mờ và chắc chắn kiến thức sẽ không được như các bạn học chuyên về cơ điện tử nên mình muốn chia sẻ những điều mà mình học được trong quá trình sử dụng bộ KIT này để các bạn thảo luận làm rõ những nội dung còn thắc mắc.
    [​IMG]
    Dưới đây là một ví dụ tiếp nối ví dụ về lập trình điều khiển I/O cho ARM Cortex-M0
    Nội dung:
    Viết chương trình thực hiện điều khiển đèn LED theo sơ đồ schematic dưới đây trên board NU-LB-NUC140. Theo các yêu cầu:
    a. Bật LED5, LED7. Tắt LED6, LED8.
    b. Delay 1s.
    c. Tắt LED5, LED7. Bật LED6, LED8.
    d. Delay 1s.
    e. Quay lại a.
    -------------------------------------CODE---------------------------------------
    Mã:
    /*-----------------------------------------------------------------------------------------------*/
    /*                                                                                                        */
    /* Chú ý: Hàm delay_loop chỉ là VD không cần thiết trong source code              */
    /*                                                                                                       */
    /*------------------------------------------------------------------------------------------------------*/
    
    #include <stdio.h>
    #include "NUC1xx.h"
    #include "Driver\DrvSYS.h"
    #include "Driver\DrvGPIO.h"
    #include "LCD_Driver.h"
    #include "Seven_Segment.h"
    void delay_loop(void)
    {
    uint32_t i,j;
        for(i=0;i<3;i++)  
        {
            for(j=0;j<60000;j++);
        }
    }
    
    /*----------------------------------------------------------------------------
      Interrupt subroutine
      ----------------------------------------------------------------------------*/
    static unsigned char count=0;
    static unsigned char loop=12; 
    void TMR0_IRQHandler(void) // Timer0 interrupt subroutine
    {
    //    unsigned char i=0;
        TIMER0->TISR.TIF =1;
      
        if(count%2 == 0){
            DrvGPIO_ClrBit(E_GPC,12);
            DrvGPIO_ClrBit(E_GPC,14);
            DrvGPIO_SetBit(E_GPC,13);
            DrvGPIO_SetBit(E_GPC,15);
        }
        else{
            DrvGPIO_ClrBit(E_GPC,13);
            DrvGPIO_ClrBit(E_GPC,15);
            DrvGPIO_SetBit(E_GPC,12);
            DrvGPIO_SetBit(E_GPC,14);
        }
        count++;
    
    }
    
    void Timer_initial(void)
    {
        /* Step 1. Enable and Select Timer clock source */        
        SYSCLK->CLKSEL1.TMR0_S = 0;    //Select 12Mhz for Timer0 clock source
        SYSCLK->APBCLK.TMR0_EN =1;    //Enable Timer0 clock source
    
        /* Step 2. Select Operation mode */  
        TIMER0->TCSR.MODE=1;        //Select periodic mode for operation mode
    
        /* Step 3. Select Time out period = (Period of timer clock input) * (8-bit Prescale + 1) * (24-bit TCMP)*/
        TIMER0->TCSR.PRESCALE=1;    // Set Prescale [0~255]
        TIMER0->TCMPR  = 11060000;        // Set TICR(TCMP) [0~16777215]
                                    // (1/22118400)*(0+1)*(2765)= 125.01usec or 7999.42Hz
                                    // (1/22118400)*(1+1)*(11060000)= 1s
    
        /* Step 4. Enable interrupt */
        TIMER0->TCSR.IE = 1;
        TIMER0->TISR.TIF = 1;        //Write 1 to clear for safty      
        NVIC_EnableIRQ(TMR0_IRQn);    //Enable Timer0 Interrupt
    
        /* Step 5. Enable Timer module */
        TIMER0->TCSR.CRST = 1;        //Reset up counter
        TIMER0->TCSR.CEN = 1;        //Enable Timer0
    
          TIMER0->TCSR.TDR_EN=1;        // Enable TDR function
    }
    
    int main(void)
    {
        int i=0,j=0;
        /* Unlock the protected registers */  
        UNLOCKREG();
          /* Enable the 12MHz oscillator oscillation */
        DrvSYS_SetOscCtrl(E_SYS_XTL12M, 1);
        /* Waiting for 12M Xtal stalble */
        SysTimerDelay(5000);
        /* HCLK clock source. 0: external 12MHz; 4:internal 22MHz RC oscillator */
        DrvSYS_SelectHCLKSource(0);      
        /*lock the protected registers */
        LOCKREG();              
    
        DrvSYS_SetClockDivider(E_SYS_HCLK_DIV, 0); /* HCLK clock frequency = HCLK clock source / (HCLK_N + 1) */
    
    
        for(i=12;i<16;i++)
        {      
            DrvGPIO_Open(E_GPC, i, E_IO_OUTPUT);
        }
        DrvGPIO_ClrBit(E_GPC,13);
        DrvGPIO_ClrBit(E_GPC,15);
        DrvGPIO_SetBit(E_GPC,12);
        DrvGPIO_SetBit(E_GPC,14);
    
        Timer_initial();
    //  
        while(1)
        {
    
        }            
    }
    
    
     
    Last edited: 27/9/13
    nguyenphuochodaotruongpro thích bài này.
  8. phungduchiep

    phungduchiep Kỹ sư

    Tham gia ngày:
    8/5/13
    Bài viết:
    286
    Đã được thích:
    130
    Điểm thành tích:
    43
    Giới tính:
    Nam
    sinh viên đầu tư sao nổi main này :(
     
  9. daotruongpro

    daotruongpro http://vtechpro.vn

    Tham gia ngày:
    4/9/12
    Bài viết:
    382
    Đã được thích:
    497
    Điểm thành tích:
    93
    Giới tính:
    Nam
    Nghề nghiệp:
    Kỹ sư Điện tử - Truyền thông
    Nơi ở:
    Hà Nội
    Đây chỉ là làm trễ theo chu kỳ lệnh thôi bạn. Trong c nếu như tính ra thời gian nó không chính xác được mà chỉ khoảng khoảng thôi. Bạn muốn chính xác phải dùng timer.
     
  10. ngtruc87

    ngtruc87 Học sinh phổ thông

    Tham gia ngày:
    28/9/13
    Bài viết:
    2
    Đã được thích:
    0
    Điểm thành tích:
    1
    Giới tính:
    Nam
    Cho mình hỏi cách xài printf trong Keil, mình đang làm trên Nuc120 mà không tài nào Printf ra UART được hết
     

Chia sẻ trang này