PWM application of s3c2440

Publisher:chang_riLatest update time:2016-05-30 Source: eefocusKeywords:s3c2440 Reading articles on mobile phones Scan QR code
Read articles on your mobile phone anytime, anywhere
PWM (Pulse Width Modulation) is a very effective technology that uses the digital output of a microcontroller to control analog circuits. It is widely used in many fields such as measurement, communication, power control and conversion. There are

a total of 5 16-bit timers in the s3c2440 chip, of which 4 timers (timer 0~timer 3) have pulse width modulation function, so PWM function can be easily implemented using s3c2440. The following is a detailed introduction on how to implement the PWM function.

1. PWM is output through pins TOUT0~TOUT3, and these 4 pins are multiplexed with GPB0~GPB3. Therefore, to implement the PWM function, the corresponding pins must first be configured as TOUT output.

2. Then set the output clock frequency of the timer, which is based on PCLK, and then divided by the prescaler parameter configured with register TCFG0 and the divider parameter configured with register TCFG1.

3. Then set the specific width of the pulse. Its basic principle is to configure the count of register TCNTn (internal register) through register TCNTBn. TCNTn is decremented. If it is reduced to zero, it will reload the number in TCNTBn and start counting again. Register TCMPBn is used as a comparison register to compare with the count value. When TCNTn is equal to TCMPBn, the level of TOUTn output will flip, and when TCNTn is reduced to zero, the level will flip again, and it will be repeated. Therefore, the key to this step is to set registers TCNTBn and TCMPBn. The former can determine the length of a counting cycle, and the latter can determine the duty cycle of the square wave. Since the timer of s3c2440 has double buffering, the values ​​of these two registers can be changed while the timer is running, and it will be effective at the beginning of the next cycle.

4. Finally, it is the control of PWM, which is realized through the register TCON. Generally speaking, each timer has 4 bits to be configured (timer 0 has one more dead zone bit): start/stop bit, used to start and stop the timer; manual update bit, used to manually update TCNTBn and TCMPBn. It should be noted here that when starting the timing, this bit must be cleared to zero, otherwise the timer cannot be started; output inversion bit, used to change the output level direction, so that the original high-level output becomes a low level, and the low level becomes a high level; automatic reload bit, used to reload the value in TCNTBn after TCNTn is reduced to zero. When you don’t want to count, you can make the automatic reload invalid, so that after TCNTn is reduced to zero, no new number will be loaded to it, then the TOUTn output will always maintain a level (when the output inversion bit is 0, it is a high-level output; when the output inversion bit is 1, it is a low-level output), so there is no PWM function, so this bit can be used to stop PWM.

PWM has many uses. Here I use the resources of the development board to drive a buzzer and change the frequency of the buzzer by changing the pulse width. The following program uses PWM to drive the buzzer. The pulse width goes from low to high, then from high to low, over and over again. We also use 4 LEDs to indicate the frequency. When the frequency is the highest, all LEDs are on, and when the frequency is the lowest, all LEDs are off. And we use two buttons to pause the buzzer and restart the buzzer respectively:
 
#define _ISR_STARTADDRESS 0x33ffff00
 
#define U32 unsigned int
typedef unsigned char BOOL;
#define TRUE 1  
#define FALSE 0
 
#define pISR_EINT0 (*(unsigned *)(_ISR_STARTADDRESS+0x20))
#define pISR_EINT1 (*(unsigned *)(_ISR_STARTADDRESS+0x24))
 
#define rSRCPND (*(volatile unsigned *)0x4a000000) //Interrupt request status
#define rINTMSK (*(volatile unsigned *)0x4a000008) //Interrupt mask control
#define rINTPND (*(volatile unsigned *)0x4a000010) //Interrupt request status
 
#define rGPBCON (*(volatile unsigned *)0x56000010) //Port B control
#define rGPBDAT (*(volatile unsigned *)0x56000014) //Port B data
#define rGPBUP (*(volatile unsigned *)0x56000018) //Pull-up control B
 
#define rGPFCON (*(volatile unsigned *)0x560 00050) //Port F control
 
#define rEXTINT0 (*(volatile unsigned *)0x56000088) //External interrupt control register 0
 
#define rTCFG0 (*(volatile unsigned *)0x51000000) //Timer configuration
#define rTCFG1 (*(volatile unsigned *)0x51000004) //Timer configuration
#define rTCON (*(vola tile unsigned *)0x51000008) //Timer control
#define rTCNTB0 (*(volatile unsigned *)0x5100000c) //Timer count buffer 0
#define rTCMPB0 (*(volatile unsigned *)0x51000010) //Timer compare buffer 0
 
BOOL stop;
 
static void __irq Key1_ISR(void) //Pause key, turn off the buzzer
{
       rSRCPND = rSRCPND | (0x1<<1);
       rINTPND = rINTPND | (0x1<<1);
      
       rTCON &= ~0x8; //Disable timer auto-reload, that is, turn off the timer
       stop = TRUE;
}
 
void __irq Key4_ISR(void) //Restart key, turn on the buzzer
{
       rSRCPND = rSRCPND | 0x1;
       rINTPND = rINTPND | 0x1;
      
       stop = FALSE;
}
 
 
void delay(int a)
{
       int k;
       for(k=0;k               ;
}
 
void Main(void)
{
       int freq;
      
       rGPBCON = 0x155556; //B0 is TOUT0, B5~B8 are outputs, for LED
       rGPBUP = 0x7ff;
       rGPFCON = 0xaaaa; //Port F is EINT, for the button
       //Some necessary configurations of the button
       rSRCPND = 0x07;
       rINTMSK = ~0x07;
       rINTPND =0x07;
       rEXTINT0 = 0x22;
      
       freq = 2500;
      
       rTCFG0 &= 0xFFFF00;
       rTCFG0 |= 0x31; //prescal is 49
       rTCFG1 &= ~0xF; //1/2, because PCLK is 50MHz, so 50MHz/50/2=500kHz
       rTCNTB0 = 5000;
       rTCMPB0 = freq;
       rTCON &= ~0x1F;       
       rTCON |= 0xf; //dead zone invalid, automatic load, level inversion, manual update, timer start
       rTCON &= ~0x2; //manual update bit cleared, PWM starts working
      
       pISR_EINT0 = (U32)Key4_ISR;
       pISR_EINT1 = (U32)Key1_ISR;
 
       stop = FALSE;
      
       rGPBDAT = ~0x60; //two LEDs are on
      
       while(1)
       {
              //frequency increment
              for (; freq<4950; )
              {
                     freq+=10;
                     rTCMPB0 = freq; //Reassign
                     delay(20000);
                    
                     while (stop == TRUE) //Pause
                     {
                            delay(1000);
                            if (stop ==FALSE) //Judge whether to restart
                            {
                                   rTCON &= ~0x1F;
                                   rTCON |= 0xf;
                                   rTCON &= ~0x2 ; //Restore PWM function
                            }
                     }
                     //The 4 LEDs turn on and off depending on the frequencyif
                     (freq == 100)
                            rGPBDAT = ~0x1e0;
                     if(freq == 1300)
                     rGPBDAT = ~0xe0;
                     if(freq == 2500)
                            rGPBDAT = ~0x60;
                     if(freq == 3700)
                            rGPBDAT = ~0x20;
                     if(freq == 4900)
                            rGPBDAT = ~0x0;
                           
              }
             
              //Frequency decrease
              for( ; freq>50 ; )
              {
                     freq-=10;
                     rTCMPB0 = freq;
                     delay(20000);
                     while (stop == TRUE)
                     {
                            delay(1000);
                            if (stop ==FALSE)
                            {
                                   rTCON &= ~0x1F;
                                   rTCON |= 0xf;
                                   rTCON &= ~0x2 ;
                            }
                     }
                     if(freq == 100)
                            rGPBDAT = ~0x1e0;
                     if(freq == 1300)
                            rGPBDAT = ~0xe0;
                     if(freq == 2500)
                            rGPBDAT = ~0x60;
                     if(freq == 3700)
                            rGPBDAT = ~0x20;
                     if(freq == 4900)
                            rGPBDAT = ~0x0;
              }
       }    
}
 
There are a few points to note here:

1. The buzzer on the development board sounds when the level is high and stops when the level is low. When the TOUT0 timing is invalid, the output is high. Therefore, in order to make the buzzer stop sounding when the PWM is invalid, I reversed the output level (set the output inversion bit in TCON);

2. Here, I jump out of the while loop by pressing the stop flag variable to FALSE and restart the buzzer, but for some reason, if I don’t add a waiting time in the while loop, I can never jump out of the loop body, so I have to add a delay function to let it wait for a while. I can’t give a satisfactory explanation for this problem, and I don’t know where the problem is!
Keywords:s3c2440 Reference address:PWM application of s3c2440

Previous article:Application of s3c2440 timer interrupt
Next article:s3c2440 external interrupt operation

Recommended ReadingLatest update time:2024-11-16 19:55

S3C2440 -- Startup file and Makefile analysis
Nand Flash or Nor Flash boot S3C2440 has 4KB SRAM. If Nand Flash boots, the hardware automatically copies the first 4KB of Nand Flash to SRAM, and then the CPU starts to execute from address 0. If Nor Flash boots, it can be read like memory, so if the CPU boots from Nor Flash, the CPU will still boot from address 0, b
[Microcontroller]
S3C2440 clock system and setting method
I have been busy studying and porting U-boot these days. There is an important step in the process of porting U-boot, which is to set the clock of s3c2440. The clock signals such as Fin, Fclk, Hclk, Pclk, Mpll, Upll, etc. make beginners confused. The various signals are confusing. I have spent some time to sort out th
[Microcontroller]
s3c2440 ARM9 bare metal driver first article - GPIO driver (C)
This article is a supplement to LED drivers: Without further ado, let's get to the code. start.s .text .global _start _start: ldr r0 ,= 0x53000000 @WATCHDOG ADD mov r1 ,#0x0 str r1 , @r1 data is written to r0 to turn off the watchdog ldr sp ,=1024*4 @Set up the stack bl main @jump to main e
[Microcontroller]
Design of LCD1602 driver based on S3C2440
Development target platform: linux -2.6.28+S3C2440+CRAMFS/YAFFS2   Development environment: UBUNTU-9.04+ arm - linux -gcc-3.4.1   This time we need to develop a simple character LCD driver on s3c2440, the details are as follows:   LCD1602 has a total of 16 pins, 3 control signals RS, RW, RE, and 8 data lines DB0~DB7,
[Microcontroller]
S3C2440 Test Program (VII) IIC Experiment 1--Read and Write EEPROM (without interrupt)
Hardware IIC is similar to software simulation IIC. Hardware IIC reads ACK and needs to determine whether the bit4 of register IICCON is 1. Initialization:         rGPEUP = 0xc000; //SDA SCL pull-up off         rGPECON = 0xa0000000; //GPE14 and GPE15 are set to SDA and SCL functions         rIICCON = (1 7)|(0 6)|(1
[Microcontroller]
S3C2440 Test Program (VII) IIC Experiment 1--Read and Write EEPROM (without interrupt)
S3C2440 IIS Configuration
Overview: The built-in IC audio bus of S3C2440 supports 8-bit and 16-bit data output of CODEC (encoding and decoding). IIS supports bus data format and MSB alignment format. The interface provides FIFO access DMA transfer mode to replace interrupts and supports simultaneous alternating reception and transmission of
[Microcontroller]
S3C2440 IIS Configuration
s3c2440 migration u-boot-2016.03 Part 5 supports dm9000 recognition
  1. By looking at /drivers/net/Makefile, I found that if I want to compile, I need to add #define CONFIG_DRIVER_DM9000 #define CONFIG_DM9000_BASE 0x20000000 #define DM9000_IO CONFIG_DM9000_BASE #define DM9000_DATA (CONFIG_DM) in /include/configs/smdk2440.h 9000_BASE+4) #define CONFIG_NETMASK 255.255.255.0 #define CO
[Microcontroller]
s3c2440 migration u-boot-2016.03 Part 5 supports dm9000 recognition
s3c2440 bare metal-abnormal interrupt (3. swi soft interrupt)
#swi (soft interrupt) We know that arm has 7 working modes. Except for usr mode, the other 6 are privileged modes. We know that the usr mode cannot modify the CPSR and directly enter other privileged modes, but Linux applications generally run in the usr mode. Since the usr mode has very low permissions and cannot dir
[Microcontroller]
s3c2440 bare metal-abnormal interrupt (3. swi soft interrupt)
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号