1. 2440 bare metal lighting LED

Publisher:tmgouziLatest update time:2022-02-11 Source: eefocus Reading articles on mobile phones Scan QR code
Read articles on your mobile phone anytime, anywhere

Start with the code (first write a code like a normal microcontroller):


/********led.c****************************/


#define GPFCON (*(volatile unsigned long *)0x56000050)


#define GPFDAT (*(volatile unsigned long *)0x56000054)


/*The number behind is the address of the pin register. (volatile unsignedlong *) This is a forced conversion, which is to force the number behind to be converted into a volatile unsigned long pointer type. The first "*" represents the data stored at this address*/


static voidpin_init(void)


{

/*First look at the pin that the LED is connected to in the schematic diagram, and then find the register address of the pin in the datasheet*/


GPFCON&=~(3<<8); //GPF4 corresponding control bit cleared to 0


GPFCON&=~(3<<10); //GPF5 corresponding control bit cleared to 0


GPFCON&=~(3<<12); //GPF6 corresponding control bit cleared to 0


GPFCON |=1<<8; //GPF4 corresponding control bit is set to output


GPFCON |=1<<10;


GPFCON |=1<<12;


GPFDAT&=~(1<<4); //GPF4 sets output 0


GPFDAT&=~(1<<5); //GPF5 sets output 0


GPFDAT&=~(1<<6); //GPF6 sets output 0


}


static void delay(volatile unsigned int a)


{

        int k;


        k=30000;


        while(--k>0)


                for(;a>0;a--);


}


int main ()


{

        int temp=1; //Using the inverted flag


        pin_init();


        while(1)


        {

        if (temp>0)


        {

                GPFDAT |=1<<4;


                delay(6000);


                GPFDAT |=1<<5;


                delay(6000);        


                GPFDAT |=1<<6;


                delay(6000);


                temp=-1;


        }


        else


        {

                GPFDAT &=~(1<<4);


                delay(6000);


                GPFDAT &=~(1<<5);


                delay(6000);


                GPFDAT &=~(1<<6);


                delay(6000);


                temp=1;


        }


 


        }


        return 0;


}


The c code is relatively simple, and the next step is to use the startup file.


The startup file contains some initialization information. The related initialization work includes:


(1) Create an exception vector table, set up the stack, and initialize the hardware


Hardware-related initialization tasks include:


① Turn off the watchdog  

②Initialize the clock

③ Initialize SDRAM


(2) Set the return address of the main function

(3) Call the main function

(4) Complete some cleanup work


A brief description:


First of all, the exception vector table is not necessary. Its function is to establish a relationship between the user program and the startup code, and between the startup codes. This is accomplished by a series of jump instructions. When an exception occurs in the system, the processor will force the PC pointer to point to the corresponding exception handling function in the exception vector table by hardware. In order for the development board to enter the reset exception handling function after power-on (this function completes the initialization work of the following steps), the exception vector table should be written at the very beginning of the startup code.


Then setting up the stack is necessary


It is necessary to turn off the watchdog, otherwise the chip will be in a continuous restart process.


Initializing the clock means setting the clock frequency. The default system clock is 12M, which can be set according to your actual situation.


If you want to use SDRAM, you need to initialize SDRAM.


Since this program is relatively simple, the compiled code is definitely less than 4k, so the writing of the startup file can be divided into two experiments:


⑴ The program runs directly in SRAM (Steppingstone) without copying the contents of nand flash to SDRAM.


; ...


.text

.global _start

_start:

           ldr r0, =0x53000000 ; WATCHDOG register address

           mov r1,#0x0                     

           str r1,[r0] ; Assign WATCHDOG to 0, turn off the watchdog            

           ldr sp, =4096 ; Set up the stack, sram is 4k



           bl main ; Call the main function in the C program

loop:

           b loop


The above does not initialize sdran, and uses the default clock of 12M. At this time, the running address in the makefile should be set to -Ttext 0


⑵Button control LED


Here you just need to modify the led.c file.


For the development board I use, the three buttons of the development board are connected to the GPF0 GPF2 GPG3 pins of 2440 respectively, so the led.c file is modified as follows:


/************************************************************


Button control LED


The schematic diagram shows that the three buttons are connected to GPF0 GPF2 GPG3 of 2440 respectively.


The three LEDs correspond to GPF4, GPF5 and GPF6 respectively.


*****************************************************/


#defineGPFCON (*(volatile unsigned long*)0x56000050)


#defineGPFDAT (*(volatile unsigned long*)0x56000054)


#defineGPGCON (*(volatile unsigned long*)0x56000060)  


#defineGPGDAT (*(volatile unsigned long*)0x56000064)


static voidpin_init(void)


{


/*led*/


GPFCON&=~(3<<8);


GPFCON&=~(3<<10); //GPF5 corresponding control bit cleared to 0


GPFCON&=~(3<<12); //GPF6 corresponding control bit cleared to 0


GPFCON |=1<<8; //GPF4 corresponding control bit is set to output


GPFCON |=1<<10;


GPFCON |=1<<12;


GPFDAT&=~(1<<4); //GPF4 sets output 0


GPFDAT&=~(1<<5); //GPF5 sets output 0


GPFDAT&=~(1<<6); //GPF6 sets output 0


/*key*/


GPFCON&=~(3<<0);


GPFCON&=~(3<<(2*2)); //GPF2 corresponding control bit cleared to 0


GPGCON&=~(3<<(2*3)); //GPG3 corresponding control bit cleared to 0


/* While clearing, also set the pin corresponding to the button to input*/


}


int main ()


{

        unsigned long key_state; //Record the state of the key


        pin_init();


        while(1)


        {

                     /*When a button is pressed, the LED turns on, and when the button is released, the LED turns off*/


                     key_state=GPFDAT;


                     if(key_state&(1<<0))


                            GPFDAT|=(1<<4); //GPF4 sets output 1


                     else


                            GPFDAT&=~(1<<4); //GPF4 sets output 0


                     if(key_state&(1<<2))


                            GPFDAT|=(1<<5); //GPF5 sets output 1


                     else


                            GPFDAT&=~(1<<5); //GPF5 sets output 0


                           


                     key_state=GPGDAT;


                     if(key_state&(1<<3))


                            GPFDAT|=(1<<6); //GPF6 sets output 1


                     else


                            GPFDAT&=~(1<<6); //GPF6 sets output 0


                           


              }


        return 0;


}


 


After modification, re-make and download to the development board, there is a phenomenon that when a button is pressed, the LED lights up, and when the button is released, the LED goes out.


 


⑶ To run the program in SDRAM, the contents of SRAM need to be copied to SDRAM.


A complete startup code is given below. For the explanation of the code, please refer to "Writing Mini Startup Code (Third Edition)". Most of the code is written with reference to the startup code of the ads1.2 library file. The one downloaded here is from Baiwen.com.


For specific code files, see the bare metal code section in the appendix. The required files are: startup.S init.c nand .c s3c24xx.h


At this time, when compiling, you need to set the running address to: -Ttext is 0x30000000


In this way, the startup process of the code is to download the program to the nand flash, and then the hardware automatically copies the first 4k code of nand (mainly initialization code) to SRAM, and then the code starts to execute at address 0 of SRAM, and then the code in SRAM is copied to SDRAM through the code, and then the program control jumps to SDRAM for execution.


;****************************************************************************


; File: init.S


; Function: Set up SDRAM, copy the program to SDRAM, and then jump to SDRAM to continue execution


;****************************************************************************      


 


.equ MEM_CTL_BASE, 0x48000000


.equ SDRAM_BASE, 0x30000000


 


.text


.global _start


_start:


    bl disable_watch_dog ; Disable WATCHDOG, otherwise the CPU will keep restarting


    bl memsetup ; Set up the memory controller


    bl copy_steppingstone_to_sdram ; copy code to SDRAM


    ldr pc, =on_sdram ; Jump to SDRAM and continue execution


on_sdram:


    ldr sp, =0x34000000 ; Set up the stack


    bl main


halt_loop:


    b halt_loop


 


disable_watch_dog:


    ; Write 0 to the WATCHDOG register


    mov r1, #0x53000000


    mov r2, #0x0


    str r2, [r1]


    mov pc, lr ; return


 


copy_steppingstone_to_sdram:


    ; Copy all 4K data of Steppingstone to SDRAM


    ; The starting address of Steppingstone is 0x00000000, and the starting address of SDRAM is 0x30000000


   


    mov r1, #0


    ldr r2, =SDRAM_BASE


    mov r3, #4*1024


1: 


    ldr r4, [r1],#4 ; Read 4 bytes of data from Steppingstone and add 4 to the source address


    str r4, [r2], #4 ; Copy this 4-byte data to SDRAM and add 4 to the destination address


    cmp r1, r3 ; Check whether it is completed: Is the source address equal to the unsigned address of Steppingstone?


    bne 1b ; If not finished copying, continue


    mov pc, lr ; return


 


memsetup:


    ; Set up the memory controller to use peripherals such as SDRAM


 


    mov r1, #MEM_CTL_BASE ; Start address of 13 registers of storage controller


    adrl r2, mem_cfg_val ; The starting storage address of these 13 values


    add r3, r1, #52 ; 13*4 = 54


1: 


    ldr r4, [r2], #4 ; Read the setting value and add 4 to r2


    str r4, [r1], #4 ; Write this value to the register and add 4 to r1


    cmp r1, r3 ; Check whether all 13 registers have been set


    bne 1b ; If not written, continue


    mov pc, lr ; return


 


 


.align 4


mem_cfg_val:


    ; Storage controller 13 register settings


    .long 0x22011110 ; BWSCON


    .long 0x00000700 ; BANKCON0


    .long 0x00000700 ; BANKCON1


    .long 0x00000700 ; BANKCON2


    .long 0x00000700 ; BANKCON3 

[1] [2]
Reference address:1. 2440 bare metal lighting LED

Previous article:6. 2440 bare metal development LCD operation
Next article:3. Setting the clock and timer of the bare metal system of s3c2440

Latest Microcontroller Articles
  • Download from the Internet--ARM Getting Started Notes
    A brief introduction: From today on, the ARM notebook of the rookie is open, and it can be regarded as a place to store these notes. Why publish it? Maybe you are interested in it. In fact, the reason for these notes is ...
  • Learn ARM development(22)
    Turning off and on interrupts Interrupts are an efficient dialogue mechanism, but sometimes you don't want to interrupt the program while it is running. For example, when you are printing something, the program suddenly interrupts and another ...
  • Learn ARM development(21)
    First, declare the task pointer, because it will be used later. Task pointer volatile TASK_TCB* volatile g_pCurrentTask = NULL;volatile TASK_TCB* vol ...
  • Learn ARM development(20)
    With the previous Tick interrupt, the basic task switching conditions are ready. However, this "easterly" is also difficult to understand. Only through continuous practice can we understand it. ...
  • Learn ARM development(19)
    After many days of hard work, I finally got the interrupt working. But in order to allow RTOS to use timer interrupts, what kind of interrupts can be implemented in S3C44B0? There are two methods in S3C44B0. ...
  • Learn ARM development(14)
  • Learn ARM development(15)
  • Learn ARM development(16)
  • Learn ARM development(17)
Change More Related Popular Components

EEWorld
subscription
account

EEWorld
service
account

Automotive
development
circle

About Us Customer Service Contact Information Datasheet Sitemap LatestNews


Room 1530, 15th Floor, Building B, No.18 Zhongguancun Street, Haidian District, Beijing, Postal Code: 100190 China Telephone: 008610 8235 0740

Copyright © 2005-2024 EEWORLD.com.cn, Inc. All rights reserved 京ICP证060456号 京ICP备10001474号-1 电信业务审批[2006]字第258号函 京公网安备 11010802033920号