This article uses mini2440 as the development environment to achieve the goal of: implementing a timer interrupt on a bare metal machine to make LED0 flash for 1 second.
This program is modified based on Wei Dongshan's embedded Linux application development and is suitable for mini2440 to do timer interrupt experiments.
Reference address:ARM bare metal timer interrupt
int.c function
/* * init.c: do some initialization */ #include "s3c24xx.h" void disable_watch_dog(void); void clock_init(void); void memsetup(void); void copy_steppingstone_to_sdram(void); void init_led(void); void timer0_init(void); void init_irq(void); /* * Turn off WATCHDOG, otherwise the CPU will restart continuously */ void disable_watch_dog(void) { WTCON = 0; // Turning off WATCHDOG is very simple, just write 0 to this register } #define S3C2410_MPLL_200MHZ ((0x5c<<12)|(0x04<<4)|(0x00)) #define S3C2440_MPLL_200MHZ ((0x5c<<12)|(0x01<<4)|(0x02)) /* * For the MPLLCON register, [19:12] is MDIV, [9:4] is PDIV, and [1:0] is SDIV * The calculation formula is as follows: * S3C2410: MPLL(FCLK) = (m * Fin)/(p * 2^s) * S3C2410: MPLL(FCLK) = (2 * m * Fin)/(p * 2^s) * Where: m = MDIV + 8, p = PDIV + 2, s = SDIV * For this development board, Fin = 12MHz * Set CLKDIVN to make the division ratio: FCLK:HCLK:PCLK=1:2:4, * FCLK=200MHz, HCLK=100MHz, PCLK=50MHz */ void clock_init(void) { // LOCKTIME = 0x00ffffff; // Use the default value CLKDIVN = 0x03; // FCLK:HCLK:PCLK=1:2:4, HDIVN=1,PDIVN=1 /* If HDIVN is non-zero, the CPU's bus mode should be changed from "fast bus mode" to "asynchronous bus mode" */ __asm__( "mrc p15, 0, r1, c1, c0, 0\n" /* Read control register*/ "orr r1, r1, #0xc0000000\n" /* Set to "asynchronous bus mode" */ "mcr p15, 0, r1, c1, c0, 0\n" /* Write control register*/ ); /* Determine whether it is S3C2410 or S3C2440 */ if ((GSTATUS1 == 0x32410000) || (GSTATUS1 == 0x32410002)) { MPLLCON = S3C2410_MPLL_200MHZ; /* Now, FCLK=200MHz, HCLK=100MHz, PCLK=50MHz */ } else { MPLLCON = S3C2440_MPLL_200MHZ; /* Now, FCLK=200MHz, HCLK=100MHz, PCLK=50MHz */ } } /* * Set up the memory controller to use SDRAM */ void memsetup(void) { volatile unsigned long *p = (volatile unsigned long *)MEM_CTL_BASE; /* This function is assigned in this way, instead of assigning the configuration value like the previous experiment (such as the mmu experiment) * It is written in an array because it is used to generate "position-independent code" so that this function can be used in * SDRAM can run in steppingstone before */ /* Storage controller 13 register values */ p[0] = 0x22011110; //BWSCON p[1] = 0x00000700; //BANKCON0 p[2] = 0x00000700; //BANKCON1 p[3] = 0x00000700; //BANKCON2 p[4] = 0x00000700; //BANKCON3 p[5] = 0x00000700; //BANKCON4 p[6] = 0x00000700; //BANKCON5 p[7] = 0x00018005; //BANKCON6 p[8] = 0x00018005; //BANKCON7 /* REFRESH, * HCLK=12MHz: 0x008C07A3, * HCLK=100MHz: 0x008C04F4 */ p[9] = 0x008C04F4; p[10] = 0x000000B1; //BANKSIZE p[11] = 0x00000030; //MRSRB6 p[12] = 0x00000030; //MRSRB7 } void copy_steppingstone_to_sdram(void) { unsigned int *pdwSrc = (unsigned int *)0; unsigned int *pdwDest = (unsigned int *)0x30000000; while (pdwSrc < (unsigned int *)4096) { *pdwDest = *pdwSrc; pdwDest++; pdwSrc++; } } /* * LED1, LED2, LED4 correspond to GPB5, GPB6, GPB7, GPB8 */ #define GPB5_out (1<<(5*2)) #define GPB6_out (1<<(6*2)) #define GPB7_out (1<<(7*2)) #define GPB8_out (1<<(8*2)) #define GPB5_msk (3<<(5*2)) #define GPB6_msk (3<<(6*2)) #define GPB7_msk (3<<(7*2)) #define GPB8_msk (3<<(8*2)) void init_led(void) { // Set the 4 pins corresponding to LED1, LED2, LED3, and LED4 as output GPBCON &= ~(GPB5_msk | GPB6_msk | GPB7_msk | GPB8_msk); GPBCON |= GPB5_out | GPB6_out | GPB7_out | GPB8_out; } /* * Timer input clock Frequency = PCLK / {prescaler value+1} / {divider value} * {prescaler value} = 0~255 * {divider value} = 2, 4, 8, 16 * The clock frequency of Timer0 in this experiment = 100MHz/(99+1)/(16)=62500Hz * Set Timer0 to trigger an interrupt every 0.5 seconds: */ void timer0_init(void) { TCFG0 = 99; // Prescaler 0 = 99 TCFG1 = 0x03; // Select 16-division TCNTB0 = 62500; // Trigger an interrupt every 0.5 seconds TCON |= (1<<1); // Manual update TCON = 0x09; // Automatically load, clear the "manual update" bit, and start timer 0 } /* * Timer 0 interrupt enable */ void init_irq(void) { // Timer 0 interrupt enable INTMSK &= (~(1<<10)); }Interrupt function interrupt.c
#include "s3c24xx.h" void Timer0_Handle(void) { /* * Each interruption causes the 4 LEDs to change state, alternating between on and off */ if(INTOFFSET == 10) { GPBDAT = ~(GPBDAT & (0xf << 5)); } // Clear interrupt SRCPND = 1 << INTOFFSET; INTPND = INTPND; }Main function main.c
int main(void) { while(1); return 0; }
This program is modified based on Wei Dongshan's embedded Linux application development and is suitable for mini2440 to do timer interrupt experiments.
Previous article:ARM learning timer Timer0 experiment
Next article:Arm learning process
- Popular Resources
- Popular amplifiers
Recommended Content
Latest Microcontroller Articles
- Learn ARM development(16)
- Learn ARM development(17)
- Learn ARM development(18)
- Embedded system debugging simulation tool
- A small question that has been bothering me recently has finally been solved~~
- Learn ARM development (1)
- Learn ARM development (2)
- Learn ARM development (4)
- Learn ARM development (6)
He Limin Column
Microcontroller and Embedded Systems Bible
Professor at Beihang University, dedicated to promoting microcontrollers and embedded systems for over 20 years.
MoreSelected Circuit Diagrams
MorePopular Articles
- LED chemical incompatibility test to see which chemicals LEDs can be used with
- Application of ARM9 hardware coprocessor on WinCE embedded motherboard
- What are the key points for selecting rotor flowmeter?
- LM317 high power charger circuit
- A brief analysis of Embest's application and development of embedded medical devices
- Single-phase RC protection circuit
- stm32 PVD programmable voltage monitor
- Introduction and measurement of edge trigger and level trigger of 51 single chip microcomputer
- Improved design of Linux system software shell protection technology
- What to do if the ABB robot protection device stops
MoreDaily News
- Microchip Accelerates Real-Time Edge AI Deployment with NVIDIA Holoscan Platform
- Microchip Accelerates Real-Time Edge AI Deployment with NVIDIA Holoscan Platform
- Melexis launches ultra-low power automotive contactless micro-power switch chip
- Melexis launches ultra-low power automotive contactless micro-power switch chip
- Molex leverages SAP solutions to drive smart supply chain collaboration
- Pickering Launches New Future-Proof PXIe Single-Slot Controller for High-Performance Test and Measurement Applications
- Apple faces class action lawsuit from 40 million UK iCloud users, faces $27.6 billion in claims
- Apple faces class action lawsuit from 40 million UK iCloud users, faces $27.6 billion in claims
- The US asked TSMC to restrict the export of high-end chips, and the Ministry of Commerce responded
- The US asked TSMC to restrict the export of high-end chips, and the Ministry of Commerce responded
Guess you like
- About the sending problem of single chip microcomputer serial port mode 3
- Week 1: Learn about the hardware information of the development board
- imx6ull transplant alsa
- Central media report: Beixing is becoming a potential unicorn company
- "Playing with the board" + Zhou Hangci's book Chapter 8, Example 4
- Recommend a fast source code style conversion tool AStyle
- Is there something wrong with the advanced search?
- 【Silicon Labs BG22-EK4108A Bluetooth Development Review】 + First Look at the W7230F1 Development Board
- (c = getchar()) Under what circumstances will it be equal to EOF?
- There is an allgro17.2 BRD file that needs to be converted to PCB format below PAD9.5