<?xml version="1.0" encoding="UTF-8"?><rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	
	xmlns:georss="http://www.georss.org/georss"
	xmlns:geo="http://www.w3.org/2003/01/geo/wgs84_pos#"
	>

<channel>
	<title>tutorial - OCFreaks!</title>
	<atom:link href="https://www.ocfreaks.com/tag/tutorial/feed/" rel="self" type="application/rss+xml" />
	<link>https://www.ocfreaks.com/tag/tutorial/</link>
	<description>Overclocking , Gaming , Technology , Robotics &#38; DIY!</description>
	<lastBuildDate>Wed, 04 Dec 2024 06:47:16 +0000</lastBuildDate>
	<language>en-US</language>
	<sy:updatePeriod>
	hourly	</sy:updatePeriod>
	<sy:updateFrequency>
	1	</sy:updateFrequency>
	<generator>https://wordpress.org/?v=6.6.4</generator>
<site xmlns="com-wordpress:feed-additions:1">42777727</site>	<item>
		<title>Create new STM32 project in Keil uVision 5 tutorial</title>
		<link>https://www.ocfreaks.com/create-new-stm32-project-keil-uvision-5-tutorial/</link>
					<comments>https://www.ocfreaks.com/create-new-stm32-project-keil-uvision-5-tutorial/?noamp=mobile#respond</comments>
		
		<dc:creator><![CDATA[Umang Gajera]]></dc:creator>
		<pubDate>Wed, 25 Jul 2018 10:51:26 +0000</pubDate>
				<category><![CDATA[Embedded]]></category>
		<category><![CDATA[guide]]></category>
		<category><![CDATA[stm32]]></category>
		<category><![CDATA[tutorial]]></category>
		<guid isPermaLink="false">http://www.ocfreaks.com/?p=3103</guid>

					<description><![CDATA[<p>In this tutorial we see how to create project in KEIL MDK uVision 5 for STM32 ARM Cortex-M based MCUs. Its for beginners  who want to get started in programming STM32 with Keil. This tutorial also applies for all supported devices across the STM32 Family.</p>
<p>The post <a href="https://www.ocfreaks.com/create-new-stm32-project-keil-uvision-5-tutorial/">Create new STM32 project in Keil uVision 5 tutorial</a> appeared first on <a href="https://www.ocfreaks.com">OCFreaks!</a>.</p>
]]></description>
										<content:encoded><![CDATA[<p><img decoding="async" src="https://www.ocfreaks.com/imgs/embedded/common/keil_5_title.png" class="aligncenter" alt="" width="445px" height="227px" /></p>
<p>In this tutorial we see how to create project in KEIL MDK uVision 5 for STM32 ARM Cortex-M based MCUs. Its for beginners who want to get started in programming STM32 with Keil. This tutorial also applies for all supported devices across the STM32 Family viz. STM32F0/F1/F2/F4/F7/etc/. Keil uV 5 is much different than older Keil uV4. uVision 5 has integrated pack installer which is used to install specific MCU family packs and other libraries. To create project for STM32 MCU, you will first need to install <strong>MDK5 software packs</strong> for your microcontroller family. Either you can download it separately or do it from within the IDE.I recommend adding software packs using IDE.</p>
<p>Basically three(or more?) types of STM32 Keil projects can be created:</p>
<ol>
<li>One that uses CMSIS(core) only.</li>
<li>One that is based on Standard Peripheral Library.</li>
<li>Finally, one that is based on HAL (Hardware abstraction Layer) Library.</li>
</ol>
<p>For the sake of this tutorial we will see how to create CMSIS and SPL based STM32F103C8 Keil uv5 project, as an example, but will work exactly the same for STM32F0, STM32F4, and other families. I will cover HAL based projects in another tutorial. </p>
<h2 class="shead">1) Installing prerequisite STM32 Keil software pack</h2>
<p><strong>If already installed, you can SKIP this.</strong></p>
<p><strong>Step A.</strong> Download latest Keil MDK uVision5 from <a href="https://www.keil.com/demo/eval/arm.htm" target="_blank">Keil&#8217;s website</a>.</p>
<p><strong>Step B.</strong> Install Keil uVision 5 to default path.</p>
<p><strong>STEP C.</strong> Open Keil 5 and click on <span class="doc_ref">&#8220;Pack Installer&#8221;</span> icon as shown below:</p>
<p><img decoding="async" src="https://www.ocfreaks.com/imgs/embedded/common/keil5_pack_installer.png" class="aligncenter" alt="" width="687px" height="179px" /></p>
<p><strong>STEP D.</strong> On the left half on the window, under <span class="doc_ref">&#8220;Devices&#8221;</span> type <span class="doc_ref">&#8220;STM3F103C8&#8221;</span><br />
(<strong>or</strong> other device name depending on the device present on your development board) in search box and select the MCU in the list below. Now, on the right half of the window click on the <span class="doc_ref">&#8220;install&#8221;</span> button which is towards to the right of <span class="doc_ref">&#8220;Keil:STM32F1xxx_DFP&#8221;</span> and <span class="doc_ref">&#8220;Keil:STM32NUCLEO_B&#8221;</span>. Repeat this step if want to add support for other device family. After this, wait until pack installer finishes downloading the required pack files for selected MCU.</p>
<p><img decoding="async" src="https://www.ocfreaks.com/imgs/embedded/stm32_keil_uv5_project_cmsis_spl/c_install_stm32_dfp.png" class="aligncenter" alt="keil install software pack for STM32" width="691px" height="447px" /></p>
<p>Alternatively, you can manually download the software pack and install it directly from <a href="https://www.keil.com/dd2/pack/">MDK5 Software Packs</a>. It will be present Under <span class="doc_ref">&#8220;KEIL-> STMicroelectronics STM32F1 Series Device Support, Drivers&#8221;</span>. In general for STM32Fx Devices.</p>
<p><strong>STEP E.</strong> After installing from Pack Installer you will get a confirmation to reload packs. Click <span class="doc_ref">&#8220;Yes&#8221;</span> as shown below:</p>
<p><img decoding="async" src="https://www.ocfreaks.com/imgs/embedded/common/keil5_pack_install_confirm.png" class="aligncenter" alt="" width="322px" height="165px" /></p>
<h2 class="shead">2) Step by step Tutorial</h2>
<p>Okay, so now we have the necessary packs installed to create our first STM32 project in Keil 5. Just follow the steps mentioned below to create a new project in Keil uV 5 or if your project is not working properly:</p>
<h4>Step 1.</h4>
<p>Open the Keil IDE, under main menu goto <span class="doc_ref">&#8220;Project->New uVision Project&#8230;&#8221;</span> and a window prompt will open asking to save the new project. Type your desired project name and save.</p>
<p><img decoding="async" src="https://www.ocfreaks.com/imgs/embedded/common/keil5_new_project.png" class="aligncenter" alt="new project" width="513px" height="141px" /></p>
<h4>Step 2.</h4>
<p>After that, a new window will appear as shown below. Make sure <span class="doc_ref">&#8220;Software Packs&#8221;</span> is selected for the 1st drop down. In the search box below it, type <span class="doc_ref">&#8220;STM32F103C8&#8221;</span> and then select the device from list below. For e.g.: STM32F103C8 for STM32 Blue Pill, STM32F103RB for Nucleo-F103RB, STM32F030R8 for Nucleo-F030R8 and so on.</p>
<p>Finally click <span class="doc_ref">&#8220;OK&#8221;</span>. </p>
<p><img decoding="async" src="https://www.ocfreaks.com/imgs/embedded/stm32_keil_uv5_project_cmsis_spl/3_select_stm32_mcu.png" class="aligncenter" alt="select STM32 target MCU" width="626px" height="468px" /></p>
<h4>Step 3.</h4>
<p><strong>A. For CMSIS: </strong><br />
Inside the <span class="doc_ref">&#8220;Manage Run-Time Environment Window&#8221;</span> select the check boxes for <span class="doc_ref">&#8220;CORE&#8221;</span> under <span class="doc_ref">&#8220;CMSIS&#8221;</span> and <span class="doc_ref">&#8220;Startup&#8221;</span> under <span class="doc_ref">&#8220;Device&#8221;</span>. If you want to select any other libraries you can do so by selecting the respective checkboxes. Selecting <span class="doc_ref">&#8220;Startup&#8221;</span> will automatically add all the necessary startup/boot files required for STM32F1xx device, so we don&#8217;t have to import them from external sources. The selection of libraries can be changed any time later.</p>
<p><img decoding="async" src="https://www.ocfreaks.com/imgs/embedded/stm32_keil_uv5_project_cmsis_spl/4_stm32_cmsis_startup.png" class="aligncenter" alt="Select libraries" width="560px" height="549px" /></p>
<p><strong>B. For Standard Peripheral Library (SPL):</strong><br />
If you want to use SPL, the select the required peripheral library components as required. Note that some components have dependencies as well, so you will also need to include dependent components. For. E.g. GPIO needs RCC to enable clocks. </p>
<p><img decoding="async" src="https://www.ocfreaks.com/imgs/embedded/stm32_keil_uv5_project_cmsis_spl/4b_stm32_spl.png" class="aligncenter" alt="Select components for SPL" width="560px" height="603px" /></p>
<h4>Step 4.</h4>
<p>Now click on <span class="doc_ref">&#8220;Options for Target&#8221;</span> button as shown below:</p>
<p><img decoding="async" src="https://www.ocfreaks.com/imgs/embedded/stm32_keil_uv5_project_cmsis_spl/5_target_options_stm32.png" class="aligncenter" alt="Keil Options for Target" width="540px" height="196px" /></p>
<p>Make sure the settings match as shown below.</p>
<p><img decoding="async" src="https://www.ocfreaks.com/imgs/embedded/stm32_keil_uv5_project_cmsis_spl/6_setting_stm32.png" class="aligncenter" alt="Target settings" width="626px" height="468px" /></p>
<h4>Step 5.</h4>
<p>Now, click on the <span class="doc_ref">&#8220;Output&#8221;</span> tab. If you want to generate hex file then you can check <span class="doc_ref">&#8220;Create HEX File&#8221;</span>. You also enter a suitable name for the executable output file.</p>
<p><img decoding="async" src="https://www.ocfreaks.com/imgs/embedded/stm32_keil_uv5_project_cmsis_spl/7_output_hex_file.png" class="aligncenter" alt="Create Hex File" width="580px" height="282px" /></p>
<h4>Step 6.</h4>
<p>Then click on the <span class="doc_ref">&#8220;Linker&#8221;</span> tab and Under that tab check the checkbox option which says <span class="doc_ref">&#8220;Use Memory Layout from Target Dialog&#8221;</span>.</p>
<p><img decoding="async" src="https://www.ocfreaks.com/imgs/embedded/common/keil5_linker_options.png" class="aligncenter" alt="keil linker options" width="626px" height="268px" /></p>
<h4>Step 7.</h4>
<p>Now, under the <span class="doc_ref">&#8220;Debug&#8221;</span> tab, select ST-LINK as debugger since its the most common for debugging and programming STM32. Finally to click <span class="doc_ref">&#8220;OK&#8221;</span> to apply settings and close window.</p>
<p><img decoding="async" src="https://www.ocfreaks.com/imgs/embedded/stm32_keil_uv5_project_cmsis_spl/8_select_debugger.png" class="aligncenter" alt="STM32 Keil uv5 Debug options" width="626px" height="468px" /></p>
<h4>Step 8.</h4>
<p>Now, in the source navigation pane on the left area, right click on <span class="doc_ref">&#8220;Source Group 1&#8221;</span> and select <span class="doc_ref">&#8220;Add New Item to Group &#8216;Source Group 1&#8242;&#8221;</span>.</p>
<p><img decoding="async" src="https://www.ocfreaks.com/imgs/embedded/stm32_keil_uv5_project_cmsis_spl/9_add_files.png" class="aligncenter" alt="add new item to source" width="517px" height="370px" /></p>
<h4>Step 9.</h4>
<p>A new window will pop-up to add an item as shown below. Select <span class="doc_ref">&#8220;C File (.c)&#8221;</span> or C++ File (.cpp) , then enter the name of the file in the text box to the right of <span class="doc_ref">&#8220;Name:&#8221;</span> and click <span class="doc_ref">&#8220;Add&#8221;</span>.</p>
<p><img decoding="async" src="https://www.ocfreaks.com/imgs/embedded/stm32_keil_uv5_project_cmsis_spl/10.png" class="aligncenter" alt="add files to keil project" width="460px" height="435px" /></p>
<h4>Step 10.</h4>
<p>Now you can write your code in the editor. To compile your program Press <span class="doc_ref">&#8220;F7&#8221;</span> key or in the main menu goto <span class="doc_ref">&#8220;Project->Build Target&#8221;.</span> To check for any compilation errors you can have a look at the build output at the bottom of main window. Two screenshots of the Keil MDK uVision 5 are given below. </p>
<p><strong>A. For CMSIS Core Project:</strong><br />
<img decoding="async" src="https://www.ocfreaks.com/imgs/embedded/stm32_keil_uv5_project_cmsis_spl/12a_compile_cmsis_only.png" class="aligncenter" alt="Keil uv5 screenshot STM32 CMSIS" width="688px" height="549px" /> </p>
<p><strong>B. For Standard Peripheral Library based Project</strong>:</p>
<p><img decoding="async" src="https://www.ocfreaks.com/imgs/embedded/stm32_keil_uv5_project_cmsis_spl/12b_compile_spl.png" class="aligncenter" alt="Keil uv5 screenshot STM32 SPL" width="690px" height="550px" /> </p>
<p>The post <a href="https://www.ocfreaks.com/create-new-stm32-project-keil-uvision-5-tutorial/">Create new STM32 project in Keil uVision 5 tutorial</a> appeared first on <a href="https://www.ocfreaks.com">OCFreaks!</a>.</p>
]]></content:encoded>
					
					<wfw:commentRss>https://www.ocfreaks.com/create-new-stm32-project-keil-uvision-5-tutorial/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
		<post-id xmlns="com-wordpress:feed-additions:1">3103</post-id>	</item>
		<item>
		<title>MSP430 Timer Programming Tutorial</title>
		<link>https://www.ocfreaks.com/msp430-timer-programming-tutorial/</link>
					<comments>https://www.ocfreaks.com/msp430-timer-programming-tutorial/?noamp=mobile#respond</comments>
		
		<dc:creator><![CDATA[Umang Gajera]]></dc:creator>
		<pubDate>Sun, 22 Jul 2018 12:12:35 +0000</pubDate>
				<category><![CDATA[Embedded]]></category>
		<category><![CDATA[MSP430]]></category>
		<category><![CDATA[tutorial]]></category>
		<guid isPermaLink="false">http://www.ocfreaks.com/?p=3099</guid>

					<description><![CDATA[<p>In this tutorial we will go through MSP430 Timer programming for MSP430x2xx devices like MSP430G2553, MSP430G2231 found on Launchpad development board. We will also cover two timer examples.</p>
<p>The post <a href="https://www.ocfreaks.com/msp430-timer-programming-tutorial/">MSP430 Timer Programming Tutorial</a> appeared first on <a href="https://www.ocfreaks.com">OCFreaks!</a>.</p>
]]></description>
										<content:encoded><![CDATA[<p class="tocpostimage">In this tutorial we will go through MSP430 Timer programming for MSP430x2xx devices like <strong>MSP430G2553, MSP430G2231</strong> found on Launchpad development board. MSP430G2 devices have two 16-bit timers i.e. <strong>Timer_A and Timer_B</strong>. Timer_B is slightly different than Timer_A and also has few more features, but it is <strong>NOT</strong> implemented in both MSP430G2553 and MSP430G2331 micro-controllers. Hence, we will focus on <strong>Timer_A</strong> for this tutorial.</p>
<div class="toc_container">
<span class="toc_title">Table of Contents</span></p>
<div class="toc">
<ol class="toc_list">
<li class="toc_text"><a href="#Intro"><span>Introduction</span></a></li>
<li class="toc_text"><a href="#Timer_Regs"><span>MSP430 Timer Registers</span></a></li>
<li class="toc_text"><a href="#Timer_Config"><span>Configuring &#038; Setting Up Timer in MSP430</span></a></li>
<li class="toc_text"><a href="#Timer_Formulae"><span>Handy MSP430 Timer Formulae for delay calculations</span></a></li>
<li class="toc_text"><a href="#Timer_Examples"><span>MSP430 Timer Examples</span></a></li>
<ol class="toc_list">
<li class="toc_text"><a href="#Example_1"><span>A simple Delay function using Interrupt</span></a></li>
<li class="toc_text"><a href="#Example_2"><span>Blinky using MSP430 Timer Interrupt</span></a></li>
</ol>
</ol>
</div>
</div>
<h2 class="shead" id="Intro" style="margin-top:5px;">Introduction</h2>
<p>MSP430G2553 has two Timer_As viz. <strong>Timer0_A3</strong> and <strong>Timer1_A3</strong> which features 3 capture/compare registers while MSP430G2231 has only 1 timer called <strong>Timer0_A2</strong> with only 2 capture/compare registers. In addition to Capture, Timer_A also supports PWM outputs and interrupts. They also include a Watchdog Timer (WDT+) which I will discuss in another tutorial.</p>
<div class="special sp_blue noteinfo">The naming convention used in datasheet is &#8220;<strong>Timer<em>n</em>_A<em>x</em></strong>&#8221; where <strong>n</strong> = Timer module number, <strong>x</strong> = no. of. capture/compare registers supported.</div>
<p>Timer_A supports four different clock sources: ACLK, SMCLK and 2 external sources: TACLK or INCLK. The selected clock source can then be divided by 1,2,4 or 8. The register used for counting is called TAR(16-bit R/W) and can increment or decrement for each rising edge of clock signal. Compared to Timer blocks of other microcontrollers, these MCUs don&#8217;t support prescaler.  </p>
<h4>Timer Modes:</h4>
<p><strong>Timer_A supports 4 modes of operation:</strong></p>
<ol style="margin-bottom:10px;">
<li><strong>Stop Mode:</strong> In this mode the Timer is Halted.</li>
<li><strong>Up Mode:</strong> Timer repeatedly counts from Zero to value stored in Capture/Compare Register 0 (TACCR0).</li>
<li><strong>Continuous:</strong> Timer repeatedly counts from Zero to 0xFFFF, which is maximum value for 16-bit TAR.</li>
<li><strong>Up/Down Mode:</strong> Timer repeatedly counts from Zero up to the value in TACCR0 and back down to zero.</li>
</ol>
<p><img decoding="async" class="aligncenter" src="https://www.ocfreaks.com/imgs/msp430-tutorial/msp430_timer_modes.png" width="470px" height="620px" alt="Timer Modes in MSP430 microcontrollers"></p>
<h2 class="shead" id="Timer_Regs">MSP430 Timer Registers</h2>
<p><strong>1) <span class="doc_ref">TAR</span> &#8211; Timer Counter Register:</strong> Holds the current count for Timer_A.</p>
<p><strong>2) <span class="doc_ref">TACCRx</span> &#8211; Timer Capture/Compare Register:</strong> In Compare mode, it holds compare value to be compared against TAR. In Capture mode, it holds the current value of TAR when a capture is performed. Maximum value it can store is 0xFFFF since its a 16 bit register.</p>
<p><strong>3) <span class="doc_ref">TACTL</span> &#8211; Control Register:</strong> Used to configure Timer_A. This register is divided as follows:</p>
<ul>
<li><strong>Bit[0] &#8211; <span class="doc_ref">TAIFG</span> &#8211; Timer_A Interrupt Flag</strong>. 0 = No interrupt pending, 1 = Interrupt pending.</li>
<li><strong>Bit[1] &#8211; <span class="doc_ref">TAIE</span> &#8211; Timer_A Interrupt Enable.</strong> 0 = Interrupt Disabled, 1 = Interrupt Enabled.</li>
<li><strong>Bit[2] &#8211; <span class="doc_ref">TACLR</span> &#8211; Timer_A clear.</strong> Setting this bit resets TAR, clock divider, and the count direction. It is automatically reset and is always read as zero.</li>
<li><strong>Bits[5:4] &#8211; <span class="doc_ref">MCx</span> &#8211; Mode Control bits.</strong> Used to select between 4 different modes as given:<br />
[00] = MC_0 &#8211; Stop mode: Timer is halted.<br />
[01] = MC_1 &#8211; Up mode: Timer counts up to TACCR0.<br />
[10] = MC_2 &#8211; Continuous mode: Timer counts up to 0xFFFF.<br />
[11] = MC_3 &#8211; Up/down mode: Timer counts up to TACCR0 then down to 0x0000.</li>
<li><strong>Bit[7:6] &#8211; <span class="doc_ref">IDx</span> &#8211; Input divider.</strong> Selects input clock divider.<br />
[00] = ID_0 &#8211; /1<br />
[01] = ID_1 &#8211; /2<br />
[10] = ID_2 &#8211; /4<br />
[11] = ID_3 &#8211; /8</li>
<li><strong>Bits[9:8] <span class="doc_ref">TASSELx</span> &#8211; Timer_A clock source select.</strong><br />
[00] = TASSEL_0 &#8211; TACLK<br />
[01] = TASSEL_1 &#8211; ACLK<br />
[10] = TASSEL_2 &#8211; SMCLK<br />
[11] = TASSEL_3 &#8211; INCLK (check datasheet)</li>
<li>Other Bits &#8211; Reserved</li>
</ul>
<p><strong>3) <span class="doc_ref">TACCTLx</span> &#8211; Capture/Compare Control Register:</strong> Used to configure capture/compare options. I will only cover the parts of this register which are applicable to this tutorial. We will see it in detail in other tutorials(for Capture mode &#038; PWM).</p>
<ul>
<li><strong>Bit[0] &#8211; <span class="doc_ref">CCIFG</span> &#8211; Capture/compare interrupt flag:</strong> 0 = interrupt pending, 1 = Interrupt pending.</li>
<li><strong>Bit[4] &#8211; <span class="doc_ref">CCIE</span> &#8211; Capture/compare interrupt enable:</strong> This bit enables the interrupt request of the corresponding CCIFG flag. 0 = Interrupt disabled = 1 Interrupt enabled.</li>
<li><strong>Bit[8] &#8211; <span class="doc_ref">CAP</span> &#8211; Capture mode:</strong> Used to select between Compare and Capture mode. We will this bit in its default setting i.e. = 0. 0 = Compare mode, 1 = Capture mode.</li>
</ul>
<p><strong>4) <span class="doc_ref">TAIV</span> &#8211; Interrupt Vector Register:</strong> Used to identify the flag which requested an interrupt. This is a read only register and only uses 3 bits [3:1] called TAIVx. The values for TAIVx which corresponds to various sources is as given below:</p>
<ul>
<li>0x00 = No Interrupt Pending.</li>
<li>0x02 = Capture/Compare 1 &#8211; TACCR1 CCIFG.</li>
<li>0x04 = Capture/Compare 2 &#8211; TACCR2 CCIFG.</li>
<li>0x0A = Timer(TAR) Overflow &#8211; TAIFG.</li>
<li>Other &#8211; Reserved.</li>
</ul>
<div class="special sp_blue noteinfo"><strong>Timer Register Naming Convention:</strong> Using the register names as given in user manual will default to Timer0_A3 registers. For e.g. TACTL is same as TA0CTL. Note that Timer registers are defined as TA<strong>n</strong>CTL, TA<strong>n</strong>CCR0 and so on.. where <strong>n</strong> = Timer module number(in our case 0 or 1). For Timer1_A3 these names will be TA<strong>1</strong>CTL, TA<strong>1</strong>CCR0 and so on. TA<strong>0</strong>CTL and other Timer0_A3 are just redefined as TACTL, TACCR0 and so on. </div>
<h2 class="shead" id="Timer_Config">Configuring &#038; Setting Up Timer in MSP430</h2>
<p>Given, clocks are configured properly, <strong>basic setup</strong> of Timer_A can be done follows:</p>
<ul style="margin-bottom:10px;">
<li>Set the Compare value in <span class="code_var">TACCR0</span> if using Up mode or Up/Down mode. Timer may be stopped by using <span class="code_var">TACCR0 = 0;</span> and can be started/restarted any time by writing a non-zero compare value in <span class="code_var">TACCR0</span> whenever Timer is to be used. Total Counts by timer will be <span class="code_var">TACCR0 + 1</span>.</li>
<li>Set CCIE(Capture/Counter Interrupt Enable) bit in <span class="code_var">TACCTL0</span> to enable interrupt for <strong>CCR0</strong>. We also keep the CAP bit to default value(=0) to enable Compare mode.</li>
<li>Select Clock Source, Input Clock divider and Timer mode using <span class="code_var">TASSELx, IDx, MCx</span> fields respectively.</li>
<li>Enable global Interrupts and we are done.</li>
</ul>
<div class="special sp_yellow noteinfo">Note that TACCR0 has dedicated interrupt vector. Other TACCRx have common interrupt vector(see TAIVx and section 12.2.6 on page 367 in User Manual).</div>
<p>In examples given below we will use Up mode with input clock source as SMCLK(MCx = MC_1) without an divider(IDx = ID_0 i.e. divide by 1). We will set MCLK and SMCLK to run at 1MHz, both sourcing clock from DCO. This is the default configuration.</p>
<pre><code class="language-cpp">
TACCR0 = ..; //Compare Value for TAR
TACCTL0 |= CCIE; //Enable interrupt for CCR0.
TACTL = TASSEL_2 + ID_0 + MC_1; //Select SMCLK, SMCLK/1 , Up Mode
_enable_interrupt();
/* More code */
</code></pre>
<h2 class="shead" id="Timer_Formulae">Handy MSP430 Timer Formulae for delay calculations</h2>
<p>Formula for amount of time taken to increment TAR count by 1 is given as:</p>
<div class="equation" style="font-size:16px;margin-bottom:10px;">Resolution(Delay per TAR Count) in Seconds = </p>
<div class="fraction"><span class="fup">DIV</span><span class="bar">/</span><span class="fdn">Input Clock in Hz</span></div>
</div>
<p>where DIV = Input Clock divider either 1,2,4 or 8.</p>
<p><strong>E.g.:</strong> When using divider of /2 and Input clock of 4MHz we get timer resolution as,</p>
<div class="equation" style="font-size:15px;margin-bottom:10px;">Resolution = </p>
<div class="fraction"><span class="fup">2</span><span class="bar">/</span><span class="fdn">4 x 10<sup>6</sup>Hz</span></div>
<p>Seconds = 0.5 x 10<sup>-6</sup> Seconds = 0.5 µS</div>
<p>The time required for TAR to count from 0 and reach TACCR0 (i.e. overflow or TAR period) is given as:</p>
<div class="equation" style="font-size:16px;margin-bottom:10px;">Timer Period in Seconds = </p>
<div class="fraction"><span class="fup">DIV x (TACCR0 + 1)</span><span class="bar">/</span><span class="fdn">Input Clock in Hz</span></div>
</div>
<p>We subtract 1 from TACCR0 since TAR counts &#8220;TACCR0+1&#8221; times to overflow. This is because count starts from 0.</p>
<p><strong>E.g.:</strong> When using divider of /2, Input clock of 4MHz and TACCR0 = 1000-1 = 999, we get Timer Period as,</p>
<div class="equation" style="font-size:15px;margin-bottom:10px;">Timer Period = </p>
<div class="fraction"><span class="fup">2 x (999 + 1)</span><span class="bar">/</span><span class="fdn">4 x 10<sup>6</sup>Hz</span></div>
<p> = 0.5 x 1000 x 10<sup>-6</sup> S = 500 µS</div>
<h2 class="shead" id="Timer_Examples">MSP430 Timer Examples</h2>
<p>Now, lets cover 2 Timer examples. Both examples are valid for MSP430G2553 , MSP430G2231 and similar MCUs.</p>
<h4 id="Example_1">Example 1: A simple Delay function using Interrupt</h4>
<p>Of-course, we have the option of using inbuilt function <span class="code_var">__delay_cycles(..)</span>, but wheres the fun if we don&#8217;t implement a similar function using Timer? Anyways, in this example we will define a function called <strong><span class="code_var">delayMS(int msec)</span></strong> which generates delay as per given input in mill-seconds. This function is used in conjunction with Timer_A Interrupt for <strong>CCR0</strong>. The time is counting, ISR continuously increments an Overflow counter when <span class="code_var">TAR</span> reaches value in <span class="code_var">TACCR0</span>. We set the value in <span class="code_var">TACCR0</span> such that counting from 0 to <span class="code_var">TACCR0</span> takes exactly 1ms, and hence we get a resolution of 1ms for our delay function. This function will give more accurate delay as MCLK increases, since it contains a few statements which eat up proportionate amount CPU cycles. Now, since we are using <strong>Timer Clock = 1MHz</strong> (SMCLK=1MHz), 1000 ticks will equal to 1ms. Hence, we use <span class="code_var">TACCR0 = 1000</span> inside delay function. In general for <strong>Y</strong> MHz timer clock, <strong>Y</strong> x 1000 ticks are required for 1ms delay. Before exiting the function we use <span class="code_var">TACCR0 = 0</span> to stop the Timer.</p>
<pre><code class="language-cpp">
#include &lt;msp430.h&gt;

void initTimer_A(void);
void delayMS(int msecs);

unsigned int OFCount;

int main(void)
{
	WDTCTL = WDTPW + WDTHOLD; //Stop watchdog timer
	P1DIR |= BIT0; //Configure P1.0 as Output

	//Set MCLK = SMCLK = 1MHz
	BCSCTL1 = CALBC1_1MHZ;
	DCOCTL = CALDCO_1MHZ;

	initTimer_A();
	_enable_interrupt();

	while(1)
	{
		P1OUT |= BIT0; //Drive P1.0 HIGH - LED1 ON
		delayMS(500); //Wait 0.5 Secs

		P1OUT &= ~BIT0; //Drive P1.0 LOW - LED1 OFF
		delayMS(500); //Wait 0.5 Secs
	}
}

void initTimer_A(void)
{
	//Timer0_A3 Configuration
	TACCR0 = 0; //Initially, Stop the Timer
	TACCTL0 |= CCIE; //Enable interrupt for CCR0.
	TACTL = TASSEL_2 + ID_0 + MC_1; //Select SMCLK, SMCLK/1, Up Mode
}

void delayMS(int msecs)
{
	OFCount = 0; //Reset Over-Flow counter
	TACCR0 = 1000-1; //Start Timer, Compare value for Up Mode to get 1ms delay per loop
	//Total count = TACCR0 + 1. Hence we need to subtract 1.

	while(i<=msecs);

	TACCR0 = 0; //Stop Timer
}

//Timer ISR
#pragma vector = TIMER0_A0_VECTOR
__interrupt void Timer_A_CCR0_ISR(void)
{
	OFCount++; //Increment Over-Flow Counter
}
</code></pre>
<h4 id="Example_2">Example 2: Blinky using MSP430 Timer Interrupt</h4>
<p>In this example, instead of using a dedicated delay function we place the blinky code inside the Timer_A Interrupt itself. The Timer initialization code is same as before. The Timer is never stopped and it repeatedly restarts counting when <span class="code_var">TAR</span> reaches <span class="code_var">TACCR0</span> to generate 1ms delay. Similar to previous example, an overflow counter is maintained by ISR itself. We just need to define how much delay(in ms) we require. This is done by defining a MACRO <span class="code_var">BLINKY_DELAY_MS</span>. Also, note that we won't be using Low Power Mode (LMP0). If you want to use LMP0 than make sure <span class="code_var">TACCR0</span> has a suitable maximum value along with higher clock divider, so CPU stays disabled most of the time. In our case we can use <span class="code_var">TACCR0 = 50000;</span> and use overflow count limit of 10 for 500ms delay. In this way the ISR is called every 50ms when clock divider is 1, and every 200ms when clock divider is 4.</p>
<pre><code class="language-cpp">
#include &lt;msp430.h&gt;
#define BLINKY_DELAY_MS 500 //Change this as per your needs

void initTimer_A(void);
void delayMS(int msecs);

unsigned int OFCount;

int main(void)
{
	WDTCTL = WDTPW + WDTHOLD; //Stop watchdog timer
	P1DIR |= BIT0; //Configure P1.0 as Output

	//Set MCLK = SMCLK = 1MHz
	BCSCTL1 = CALBC1_1MHZ;
	DCOCTL = CALDCO_1MHZ;

	initTimer_A();
	_enable_interrupt();

	OFCount  = 0;
	TACCR0 = 1000-1; //Start Timer, Compare value for Up Mode to get 1ms delay per loop
	/*Total count = TACCR0 + 1. Hence we need to subtract 1.
	1000 ticks @ 1MHz will yield a delay of 1ms.*/

	while(1);
}

void initTimer_A(void)
{
	//Timer Configuration
	TACCR0 = 0; //Initially, Stop the Timer
	TACCTL0 |= CCIE; //Enable interrupt for CCR0.
	TACTL = TASSEL_2 + ID_0 + MC_1; //Select SMCLK, SMCLK/1 , Up Mode
}

//Timer ISR
#pragma vector = TIMER0_A0_VECTOR
__interrupt void Timer_A_CCR0_ISR(void)
{
	OFCount++;
	if(OFCount >= BLINKY_DELAY_MS)
	{
		P1OUT ^= BIT0;
		OFCount = 0;
	}
}
</code></pre>
<p>The post <a href="https://www.ocfreaks.com/msp430-timer-programming-tutorial/">MSP430 Timer Programming Tutorial</a> appeared first on <a href="https://www.ocfreaks.com">OCFreaks!</a>.</p>
]]></content:encoded>
					
					<wfw:commentRss>https://www.ocfreaks.com/msp430-timer-programming-tutorial/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
		<post-id xmlns="com-wordpress:feed-additions:1">3099</post-id>	</item>
		<item>
		<title>LPC1768 Timer Input Capture &#038; Frequency Counter Tutorial</title>
		<link>https://www.ocfreaks.com/lpc1768-timer-input-capture-frequency-counter-tutorial/</link>
					<comments>https://www.ocfreaks.com/lpc1768-timer-input-capture-frequency-counter-tutorial/?noamp=mobile#respond</comments>
		
		<dc:creator><![CDATA[Umang Gajera]]></dc:creator>
		<pubDate>Tue, 17 Jul 2018 18:28:46 +0000</pubDate>
				<category><![CDATA[Embedded]]></category>
		<category><![CDATA[lpc1768]]></category>
		<category><![CDATA[tutorial]]></category>
		<guid isPermaLink="false">http://www.ocfreaks.com/?p=3092</guid>

					<description><![CDATA[<p>In this tutorial we will go through the programming of input capture mode for timer module of ARM Cortex-M3 LPC176x microcontrollers along with a frequency counter example using capture input.</p>
<p>The post <a href="https://www.ocfreaks.com/lpc1768-timer-input-capture-frequency-counter-tutorial/">LPC1768 Timer Input Capture &#038; Frequency Counter Tutorial</a> appeared first on <a href="https://www.ocfreaks.com">OCFreaks!</a>.</p>
]]></description>
										<content:encoded><![CDATA[<p>In this tutorial we will go through the programming of input capture mode for timer module of ARM Cortex-M3 LPC1768 microcontroller along with a frequency counter example using capture input. In my previous <a href="https://www.ocfreaks.com/lpc1768-timer-programming-tutorial/" target="_blank">LPC1768 Timer tutorial</a> we saw how to setup and program the timer module.</p>
<h3>Capture Channels and Input pins</h3>
<p>Each timer block in LPC176x has 2 Input Capture Channels (CAPn.0 &#038; CAPn.1, n=Timer number). Using these Capture channels we can take a snapshot(i.e. capture) of the current value of TC when a signal edge is detected. These channels are mapped to device pins. This mapping of Capture Channel to pins is as given below:</p>
<table class="aligncenter ocf-table" style="margin-bottom:15px; margin-top:5px;">
<tr>
<th colspan="2">Timer0</th>
<th colspan="2">Timer1</th>
<th colspan="2">Timer2</th>
<th colspan="2">Timer3</th>
</tr>
<tr>
<td>Ch.</td>
<td>Pin</td>
<td>Ch.</td>
<td>Pin</td>
<td>Ch.</td>
<td>Pin</td>
<td>Ch.</td>
<td>Pin</td>
</tr>
<tr>
<td>CAP0.0</td>
<td>P1.26</td>
<td>CAP1.0</td>
<td>P0.18</td>
<td>CAP2.0</td>
<td>P0.4</td>
<td>CAP3.0</td>
<td>P0.23</td>
</tr>
<tr>
<td>CAP0.1</td>
<td>P1.27</td>
<td>CAP1.1</td>
<td>P0.19</td>
<td>CAP2.1</td>
<td>P0.5</td>
<td>CAP3.1</td>
<td>P0.24</td>
</tr>
</table>
<h3>Using Capture Inputs in LPC176x</h3>
<p>When using Capture Inputs we use Timer Block in Normal &#8216;<strong>Timer Mode</strong>&#8216; or &#8216;<strong>Counter Mode</strong>&#8216;. </p>
<ol>
<li>In <strong>Timer Mode</strong>, the Peripheral clock is used as a clock source to increment the Timer Counter(TC) every ‘PR+1’ clock cycles. Whenever a signal edge(rising/falling/both) event is detected, the timestamp i.e. the current value of TC is loaded into corresponding Capture Register(CRx) and optionally we can also generate an interrupt every time Capture Register is loaded with a new value. This behavior is configured using CCR. </li>
<li>In <strong>Counter Mode</strong>, external signal is used to increment TC every time an edge(rising/falling/both) is detected. This behavior is configured using CTCR. Corresponding bits for Capture channel must be set to zero in CCR. (See register explanation given below)</li>
</ol>
<p><img decoding="async" class="aligncenter" src="https://www.ocfreaks.com/imgs/lpc1768-tutorial/lpc176x_timer_module_with_capture.png" width="610px" height="340px" alt="ARM CORTEX-M3 LPC1768 LPC1769 Timer Capture Block diagram" /></p>
<p>Here is a simple diagram depicting the capture process. Dashed arrows(for both diagrams) signify the events.</p>
<p><img decoding="async" class="aligncenter" src="https://www.ocfreaks.com/imgs/embedded/common/timer_capture_input_mode_process_lpc_mcu.png" width="520px" height="155px" alt="Microcontroller Input Capture diagram" /></p>
<h2 class="shead">Capture Related Registers:</h2>
<p>Since I have already discussed main Timer Registers in my <a href="https://www.ocfreaks.com/lpc1768-timer-programming-tutorial/" target="_blank">LPC1768 Timer tutorial</a>, we will only have a look at registers relating to capture.</p>
<div class="highlight"><strong>1) <span class="doc_ref">CCRx</span> &#8211; Capture Control Register</strong>: Used to select which type of Egde(rising/falling/both) is used to Capture Registers (CR0-CR1) and optionally to generate an interrupt when a capture event occurs.</p>
<p><strong>For <span class="doc_ref">CR0</span>:</strong></p>
<ul style="margin-bottom:0px;">
<li><strong>Bit 0:</strong> Capture on CAPn.0 rising edge. When set to 1, a transition of 0 to 1 on CAPn.0 will cause CR0 to be loaded with the contents of TC. Disabled when 0.</li>
<li><strong>Bit 1:</strong> Capture on CAPn.0 falling edge. When set to 1, a transition of 1 to 0 on CAPn.0 will cause CR0 to be loaded with the contents of TC. Disabled when 0.</li>
<li><strong>Bit 2:</strong> Interrupt on CAPn.0 event. When set to 1, a CR0 load due to a CAPn.0 event will generate an interrupt. Disabled when 0.</li>
</ul>
<p>Similarly bits 3-5, are for <strong>CR1</strong>.</p>
<p><strong>2) <span class="doc_ref">CR0 &#038; CR1</span> &#8211; Capture Registers:</strong> Each capture register is associated with a Capture Pin. Depending on the settings in CCR, CRn can be loaded with current value of TC when a specific event occurs.</p>
<p><strong>3) <span class="doc_ref">CTCR</span> Count Control Register: Used to select between Timer or Counter Mode.</strong><br />
<strong>Bits[1:0]</strong> &#8211; Used to select Timer mode or which Edges can increment TC in counter mode.</p>
<ul style="margin-bottom:0px;">
<li>[00]: Timer Mode. PC is incremented every Rising edge of PCLK.</li>
<li>[01]: Counter Mode. TC is incremented on Rising edges on the CAP input selected by Bits[3:2].</li>
<li>[10]: Counter Mode. TC is incremented on Falling edges on the CAP input selected by Bits[3:2].</li>
<li>[11]: Counter Mode. TC is incremented on Both edges on the CAP input selected by Bits[3:2].</li>
</ul>
<p><strong>Bits[3:2]</strong> &#8211; Count Input Select. Only applicable if above bits are not [00].</p>
<ul style="margin-bottom:0px;">
<li>[00]: Used to select CAPn.0 for TIMERn as Count input.</li>
<li>[01]: Used to select CAPn.1 for TIMERn as Count input.</li>
<li>[10] &#038; [11]: Reserved.</li>
</ul>
</div>
<h2 class="shead">Frequency Counter using LPC1768 Timer Capture</h2>
<h3>Methods to Measure frequency of an external signal</h3>
<h4>We will cover two methods of Measuring Unknown Signal Frequency:</h4>
<ol>
<li><strong>By Gating/Probing</strong> &#8211; In this method we define a Gating Interval in which we count the number of pulses. <strong>What is Gating Time?</strong> &#8211; Gating Time is amount of time for which we probe the input signal. Once we know the no.of. pulses, we can easily deduce the frequency using Gating time. Here we use the external signal as clock source to increment Timer Counter (TC). The value in TC gives the number of pulses counted per Gating Time. This method relies on selecting a proper Gating Time to get valid and accurate results. </li>
<li><strong>By measuring Period using Interrupts</strong> &#8211; In this method we use an Interrupt Service Routine to find out the time between 2 consecutive pulses i.e. period of the Input signal at that particular instant. This is done using an ISR, but ISR itself is main limiting factor for the maximum frequency which can be measured. Compared to first one, this method can give accurate results, given frequency is below measurement limit.</li>
</ol>
<div class="special sp_blue noteinfo">The maximum input signal frequency which can be reliably measured using first method is half of TIMERn_PCLK, since it takes two successive edges of TIMERn_PCLK to detect one edge of external signal. Hence, using a TIMERn_PCLK of 100Mhz we can measure upto 50Mhz signal properly. For second method we can only measure up to around 0.83 Mhz due to ISR execution delay &#038; context switching overhead.</div>
<p>For measuring Square wave Signal Frequency, external hardware is not required unless the Pulse HIGH Voltage level is > 3.3 Volts, in which case a Voltage divider or Buffer is mandatory. To measure other Signal types like Saw-tooth, Sine wave we will require something that can provide Hysteresis which will define the HIGH &#038; LOW Voltage Threshold, thereby converting it into a Square signal, to detect any of the edges of the unknown signal. This can be done using a Schmitt Trigger Buffer (either Inverting or Non-Inverting &#8211; doesn&#8217;t matter).</p>
<p>For both of examples given below, we will use Timer2 module to measure frequency. Capture Channel CAP2.0 is used as capture input. CAP2.0 is mapped to Pin P0.4 on LPC1768, hence we select CAP2.0 alternate function for P0.4. On mbed platform P0.4 is labelled as p30 and P2.0 as p26. Schematic is also same for both.</p>
<p>To generate a square wave output, we can use LPC176x&#8217;s inbuilt PWM module, configured with 0.02 us resolution. PWM1.1 output channel is used which gives output on Pin P2.0. Refer my <a href="https://www.ocfreaks.com/lpc1768-pwm-programming-tutorial/" target="_blank"> LPC1768 PWM Tutorial </a> for more on PWM. You can also use any external source like a function generator or IC-555 based generator. The example projects linked below also contain <a href="https://www.ocfreaks.com/retarget-redirect-printf-scanf-uart-keil/" target="_blank">retargeted printf() for KEIL</a> which redirects its output to UART0.</p>
<h4>Schematic</h4>
<p><img decoding="async" class="aligncenter" src="https://www.ocfreaks.com/imgs/lpc1768-tutorial/lpc176x_input_capture_mode_eg_sch.png" width="465px" height="275px" alt="ARM Cortex-M3 LPC1768/LPC1769 Capture Mode Frequency Counter Measurement Example Schematic" /></p>
<h3>1. Frequency Counter Example using Gating/Probing:</h3>
<p>In this example we will, we use external signal as clock source for Timer2. Every positive going edge will increment the Timer2 Counter (<span class="code_var">LPC_TIM2->TC</span>) by 1. To count the number of pulses, we start the timer and wait until Gating time. After that we stop the time and read the value in <span class="code_var">LPC_TIM2->TC</span> which gives the no.of. pulses per gating time. For this example I have chosen a gating time of 1 seconds. Obviously, we can get more accurate results using a higher Gating time. For our purpose 1 second is enough to measure signals upto 50Mhz using TIMER2_PCLK=100Mhz. Given Gate time is in ms, the following equation can be used to find the frequency from counted pulses:</p>
<div class="equation">Measured Frequency in Khz = </p>
<div class="fraction"><span class="fup">Counted Pulses</span><span class="bar">/</span><span class="fdn">Gate Time in ms</span></div>
</div>
<p><strong>Source Code Snippet</strong></p>
<pre><code class="language-cpp">
/*(C) Umang Gajera - www.ocfreaks.com
LPC176x Input Capture Tutorial - Example 1(Using Gating) for frequency counter using ARM KEIL
More Embedded tutorials @ www.ocfreaks.com/cat/embedded/
License: GPL.*/

#include &lt;lpc17xx.h&gt;
#include &lt;stdio.h&gt; //for printf() - https://www.ocfreaks.com/retarget-redirect-printf-scanf-uart-keil/
#include "ocf_lpc176x_lib.h" //contains initUART0(), initTimer0() & putc() to retarget printf()

void initPWM(void);
unsigned int pulses = 0;
#define GATE_TIME_MS 1000 // Probing/Gating Time in ms

int main(void)
{
	//SystemInit(); //Gets called by Startup code, sets CCLK=100Mhz, PCLK=25Mhz
	initUART0(); //Initialize UART0 for uart_printf() - see ocf_lpc176x_lib.c
	initTimer0(); //For delayMS() - see ocf_lpc176x_lib.c
	
	/*Using CCLK = 100Mhz and PCLK_TIMER2 = 100Mhz.*/
	LPC_SC->PCONP |= (1<<22); //Power-Up Timer2 module. It is disabled by default.
	LPC_SC->PCLKSEL1 |= (1<<12); //Set bits[13:12] = [01] to select PCLK_TIMER2 = CCLK i.e. 100Mhz in our case. 
	LPC_PINCON->PINSEL0 |= (1<<9) | (1<<8); //Set Bits[9:8] = [11] to Select CAP2.0 for P0.4
	LPC_TIM2->CTCR = 0x1; //Increment TC on rising edges of External Signal for CAP2.0
	LPC_TIM2->PR = 0; //Using lowest PR gives most accurate results
	LPC_TIM2->CCR = 0x0; //Must be [000] for selected CAP input
	LPC_TIM2->TCR = 0x2; //Reset & Disable Timer2 Initially
	
	initPWM(); //To generate square wave signal	
	float FreqKhz = 0;
	printf("OCFreaks.com - LPC1768x Frequency Counter Example 1:\n");

	while(1)
	{
		LPC_TIM2->TCR = 0x1; //Start Timer2
		delayMS(GATE_TIME_MS); //'Gate' signal for defined Time (1 second)
		LPC_TIM2->TCR = 0x0; //Stop Timer2
		
		pulses = LPC_TIM2->TC; //Read current value in TC, which contains  no.of. pulses counted in 1s
		LPC_TIM2->TCR = 0x2; //Reset Timer2 TC
		
		FreqKhz = (double)pulses/GATE_TIME_MS;
		
		if(FreqKhz >= 1000.0) //Display Freq. In MHz
		{
			printf("Frequency = %0.4f MHz\n", FreqKhz/1000.0);
		}
		else //Display Freq. in KHz
		{
			printf("Frequency = %0.2f KHz\n", FreqKhz);
		}
	}
	
	//return 0; //This won't execute normally
}


void initPWM(void)
{
	//Refer: https://www.ocfreaks.com/lpc1768-pwm-programming-tutorial/
	/*Using CCLK = 100Mhz and PCLK_PWM1 = 100Mhz.*/
	
	//By default PWM1 block is powered-on
	LPC_SC->PCLKSEL0 |= (1<<12); //Set bits[13:12] = [01] to select PCLK_PWM1 = CCLK i.e. 100Mhz in our case. 
	LPC_PINCON->PINSEL4 |= (1<<0); // Select PWM1.1 output for Pin2.0
	LPC_PWM1->PCR = 0x0; //Select Single Edge PWM - by default its single Edged so this line can be removed
	LPC_PWM1->PR = 0; //PR+1 = 0+1 = 1 Clock cycle @100Mhz = 0.01us = 10ns
	LPC_PWM1->MR0 = 4; //4x0.01 = 0.04us - period duration i.e. 25Mhz Test frequency
	LPC_PWM1->MR1 = 2; //2x0.01 = 0.02us - pulse duration (50% duty cycle)
	LPC_PWM1->MCR = (1<<1); // Reset PWMTC on PWMMR0 match
	LPC_PWM1->LER = (1<<1) | (1<<0); // update MR0 and MR2
	LPC_PWM1->PCR = (1<<9); // enable PWM1.1 output
	LPC_PWM1->TCR = (1<<1) ; //Reset PWM TC &#038; PR

	LPC_PWM1->TCR = (1<<0) | (1<<3); // enable counters and PWM Mode
	//PWM Generation goes active now!!
}
</code></pre>
<p><strong>Download Example 1 Project Files:</strong></p>
<div class="highlight"><strong>KEIL ARM uV5/uV4 Project for above example</strong> <a href="https://github.com/OCFreaks/LPC1768-Tutorial-Examples/tree/master/Frequency_Counter/Example_1" target="_blank">LPC176x Frequency Counter Example 1</a> [Successfully tested on Keil uV5.23], <a href="https://minhaskamal.github.io/DownGit/#/home?url=https://github.com/OCFreaks/LPC1768-Tutorial-Examples/tree/master/Frequency_Counter/Example_1" target="_blank">Download Project Zip</a>. You can find the HEX file inside objects folder.</div>
<h3>2. Frequency Counter Example using Period Measurement:</h3>
<p>Here, a timer resolution of 0.02us (or 20ns) is selected by using Prescaler value of 1 with PCLK=CCLK=100Mhz. We configure CCR so that the capture occurs for rising edges and an interrupt is also generated.</p>
<p>The main logic of this frequency counter example lies in the Timer2 interrupt handler function itself where we are measuring the period of the square wave signal. Here we use 3 global variables viz.. <strong><span class="code_var">period</span>, <span class="code_var">previous</span> & <span class="code_var">current</span></strong>. We just update period with the difference of <strong><span class="code_var">current</span></strong> and <strong><span class="code_var">previous</span></strong>. But since the timer counter (TC) is free running, an overflow is bound to occur. So, we need to take care of this condition by detecting an overflow condition which is simply when <strong><span class="code_var">current</span></strong> is less than <strong><span class="code_var">previous</span></strong>. In this situation the time difference is calculated as:</p>
<div class="equation">Corrected Diff = (TC_MAX * OVF_CNT) + Current - Previous</div>
<p>where, <strong>TC_MAX</strong> = Maximum value of TC and <strong>OVF_CNT</strong> = Number of times overflow occurred. Since TC is 32bit, its max value in our case is 0xFFFFFFFF. Also, since we are not measuring extremely low frequency signals <strong>OVF_CNT</strong> will be at max 1. Another thing is that, if <strong>OVF_CNT</strong> is >=2 then we will need a datatype of <span class="code_ref"><strong>long long</strong></span> (8 bytes) to store the result since we won't be able to store the result in <span class="code_ref"><strong>int</strong></span> which is 4 bytes for KEIL ARM compiler.</p>
<p>Hence, the equation boils down to:</p>
<div class="equation">Corrected Diff = 0xFFFFFFFF + Current - Previous</div>
<div class="special sp_blue noteinfo">Maximum value for frequency of external signal that can be reliably measured depends on the PCLK, Prescalar (PR) and the execution Latency of Timer Interrupt Routine. Out of the three, the main limiting factor is the interrupt execution latency. If the frequency is too fast, an Interrupt Request (IRQ) will be raised even before current IRQ has been served. If this happens the pending interrupt flag will be set and cpu will immediately serve the same ISR without entering main() function. This will happen back to back and the code inside main() won't execute unless signal frequency is reduced. Also, for measurement to be reliable, NO new IRQ must be raised while ISR is under execution.</p>
<p style="margin-bottom:0px;">Hence, inside ISR we will have to add additional code to indicate this condition using a flag. Inevitably this will increase the interrupt latency, but never the less we will be able reject 'over-the-limit' frequencies without stalling the code inside main(). While testing the code given below I was able to measure frequencies around 833Khz or 0.83Mhz without stalling code inside main.</p>
</div>
<p><strong>Source Code Snippet</strong></p>
<pre><code class="language-cpp">
/*(C) Umang Gajera - www.ocfreaks.com
LPC176x Input Capture Tutorial - Example 2 for Frequency counter using ARM KEIL
More Embedded tutorials @ www.ocfreaks.com/cat/embedded/
License: GPL.*/

#include &lt;lpc17xx.h&gt;
#include &lt;stdio.h&gt; //for printf() - https://www.ocfreaks.com/retarget-redirect-printf-scanf-uart-keil/
#include "ocf_lpc176x_lib.h" //contains initUART0(), initTimer0() & putc() to retarget printf()

void initPWM(void);
unsigned int period = 0;
unsigned int previous = 0;
unsigned int current = 0 ;
int limitFlag = 0;
#define TIMER_RES 0.02 //Depends on Timer PCLK and PR. Used to convert measured period to frequency. 

int main(void)
{
	//SystemInit(); //Gets called by Startup code, sets CCLK=100Mhz, PCLK=25Mhz
	initUART0(); //Initialize UART0 for uart_printf() - see ocf_lpc176x_lib.c
	initTimer0(); //For delayMS() - see ocf_lpc176x_lib.c
	
	/*Using CCLK = 100Mhz and PCLK_TIMER2 = 100Mhz.*/
	LPC_SC->PCONP |= (1<<22); //Power-Up Timer2 module. It is disabled by default.
	LPC_SC->PCLKSEL1 |= (1<<12); //Set bits[13:12] = [01] to select PCLK_TIMER2 = CCLK i.e. 100Mhz in our case. 
	LPC_PINCON->PINSEL0 |= (1<<9) | (1<<8); //Set Bits[9:8] = [11] to Select CAP2.0 for P0.4
	LPC_TIM2->CTCR = 0x0;
	LPC_TIM2->PR = 1; //PR+1 = 1+1 = 2 clock cycles @ 100Mhz = 0.02us res
	LPC_TIM2->TCR = 0x02; //Reset Timer
	LPC_TIM2->CCR = (1<<0) | (1<<2); //Capture on Rising Edge(0->1) and generate an interrupt
	LPC_TIM2->TCR = 0x01; //Enable timer1
	
	NVIC_EnableIRQ(TIMER2_IRQn); //Enable TIMER2 IRQ
	initPWM(); //To generate square wave	
	
	printf("OCFreaks.com - Frequency Counter Example 2\n");

	while(1)
	{
		if(limitFlag)
		{
			printf("Input Frequency limit reached!\n");
			NVIC_EnableIRQ(TIMER2_IRQn); //Try to measure signal frequency again
			delayMS(500);
		}
		else
		{
			printf("Frequency = %0.2f Khz\n",((1.0/(period*TIMER_RES)) * 1000)); //Convert to frequency, 0.02 is Timer resolution
			delayMS(500); //2 Udpates per second
		}
	}
	
	//return 0; //This won't execute normally
}

void TIMER2_IRQHandler(void)
{
	LPC_TIM2->IR |= (1<<4); //Clear Interrupt Flag
	current = LPC_TIM2->CR0;
	if(current < previous) //TC has overflowed
	{
		period = 0xFFFFFFFF + current - previous;
	}
	else
	{
		period = current - previous;
	}
	previous = current; //LPC_TIM2->CR0;
	
	if(period < 60)
	{
		NVIC_DisableIRQ(TIMER2_IRQn);
		limitFlag = 1;
	}
	else limitFlag = 0;
}

void initPWM(void)
{
	//Refer: https://www.ocfreaks.com/lpc1768-pwm-programming-tutorial/
	/*Using CCLK = 100Mhz and PCLK_PWM1 = 100Mhz.*/
	
	//By default PWM1 block is powered-on
	LPC_SC->PCLKSEL0 |= (1<<12); //Set bits[13:12] = [01] to select PCLK_PWM1 = CCLK i.e. 100Mhz in our case. 
	LPC_PINCON->PINSEL4 |= (1<<0); // Select PWM1.1 output for Pin2.0
	LPC_PWM1->PCR = 0x0; //Select Single Edge PWM - by default its single Edged so this line can be removed
	LPC_PWM1->PR = 1; //PR+1 = 1+1 = 2 Clock cycles @100Mhz = 0.02us
	LPC_PWM1->MR0 = 80; //80x0.02 = 1.6us - period duration i.e. 625Khz Test frequency
	LPC_PWM1->MR1 = 40; //40x0.02 = 0.8us - pulse duration (50% duty cycle)
	LPC_PWM1->MCR = (1<<1); // Reset PWMTC on PWMMR0 match
	LPC_PWM1->LER = (1<<1) | (1<<0); // update MR0 and MR2
	LPC_PWM1->PCR = (1<<9); // enable PWM1.1 output
	LPC_PWM1->TCR = (1<<1) ; //Reset PWM TC &#038; PR

	LPC_PWM1->TCR = (1<<0) | (1<<3); // enable counters and PWM Mode
	//PWM Generation goes active now!!
}
</code></pre>
<p>In the Frequency Counter Program given above, you can increase the values for LPC_PWM1->MR0 and LPC_PWM1->MR1 to measure other lower frequencies. The program will reject frequencies above 833.3 Khz.</p>
<p><strong>Download Example 2 Project Files:</strong></p>
<div class="highlight"><strong>KEIL ARM uV5/uV4 Project for above example</strong> <a href="https://github.com/OCFreaks/LPC1768-Tutorial-Examples/tree/master/Frequency_Counter/Example_2" target="_blank">LPC176x Frequency Counter Example 2</a> [Successfully tested on Keil uV5.23], <a href="https://minhaskamal.github.io/DownGit/#/home?url=https://github.com/OCFreaks/LPC1768-Tutorial-Examples/tree/master/Frequency_Counter/Example_2" target="_blank">Download Project Zip</a>. You can find the HEX file inside objects folder.</div>
<p>The post <a href="https://www.ocfreaks.com/lpc1768-timer-input-capture-frequency-counter-tutorial/">LPC1768 Timer Input Capture &#038; Frequency Counter Tutorial</a> appeared first on <a href="https://www.ocfreaks.com">OCFreaks!</a>.</p>
]]></content:encoded>
					
					<wfw:commentRss>https://www.ocfreaks.com/lpc1768-timer-input-capture-frequency-counter-tutorial/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
		<post-id xmlns="com-wordpress:feed-additions:1">3092</post-id>	</item>
		<item>
		<title>LPC2148 Servo Motor Interfacing Tutorial</title>
		<link>https://www.ocfreaks.com/lpc2148-servo-motor-interfacing-tutorial/</link>
					<comments>https://www.ocfreaks.com/lpc2148-servo-motor-interfacing-tutorial/?noamp=mobile#respond</comments>
		
		<dc:creator><![CDATA[Umang Gajera]]></dc:creator>
		<pubDate>Fri, 13 Jul 2018 11:58:51 +0000</pubDate>
				<category><![CDATA[Embedded]]></category>
		<category><![CDATA[LPC2148 Tutorials]]></category>
		<category><![CDATA[tutorial]]></category>
		<guid isPermaLink="false">http://www.ocfreaks.com/?p=3086</guid>

					<description><![CDATA[<p>In this tutorial we go through interfacing and control of servo motors with ARM7 LPC2148 microcontroller. In my previous tutorial I had explained PWM in ARM7 LPC2148, now its time use PWM block and control servos.</p>
<p>The post <a href="https://www.ocfreaks.com/lpc2148-servo-motor-interfacing-tutorial/">LPC2148 Servo Motor Interfacing Tutorial</a> appeared first on <a href="https://www.ocfreaks.com">OCFreaks!</a>.</p>
]]></description>
										<content:encoded><![CDATA[<p><img decoding="async" class="aligncenter" src="https://www.ocfreaks.com/imgs/lpc2148-tutorial/servo_control_lpc214x_title.png" width="319px" height="175px" /></p>
<p>Hi again folks! In this tutorial we go through interfacing and control of servo motors with ARM7 LPC2148 microcontroller. In my <a href="https://www.ocfreaks.com/lpc2148-pwm-programming-tutorial/" target="_blank">previous tutorial</a> I had explained PWM in ARM7 LPC2148, now its time use PWM block and control servos. RC servos, as the name suggests, are used in RC airplanes, cars and even robots like hexapods, robotic arms, etc. These servos typically accept a PWM signal having a period of 20ms (i.e. a frequency of 50Hz). The commonly used RC servos have a total rotation swing of around 180 degrees(-90 to +90). 0 degree position is called &#8220;neutral&#8221; which is at the center of the total rotation swing, and hence also called the center position. </p>
<ul>
<li>
A pulse width of 500µs or 0.5ms is the minimum pulse width which positions the servo&#8217;s output shaft at -90 degrees. </li>
<li>A pulse width of 1500µs or 1.5ms positions the servo at 0 degree.</li>
<li>Finally a pulse width of 2500µs or 2.5ms is the maximum pulse width which positions the servo at +90 degrees.</li>
</ul>
<p><img decoding="async" class="aligncenter" src="https://www.ocfreaks.com/imgs/embedded/common/std_rc_servo_control_pwm_pulse.png" width="595px" height="340px" alt="Standard servo control pulse for common RC Servo motors" /></p>
<p>With this information, lets proceed with generating a PWM signal to control servo motors using LPC2148.</p>
<div class="special sp_blue noteinfo">PWM signal for RC servos can be generated using Timer or PWM block of LPC214x. Using the PWM block we can generate up to 6 different PWM signals and hence we can control upto 6 servos independently.</div>
<h2 class="shead">Configuring LPC2148 PWM to generate Servo PWM signal</h2>
<h4>Defining the PWM resolution</h4>
<p>Since the PWM pulses vary from 500µs to 2500µs, a resolution of 1µs is more than sufficient. Hence we will configure the PWM block for 1µs resolution and with a period of 20ms(20000µs). Make sure you go through the &#8220;PWM Prescaler (PWMPR) Calculations&#8221; explained in my <a href="https://www.ocfreaks.com/lpc2148-pwm-programming-tutorial/" target="_blank">LPC2148 PWM tutorial</a> previously. As mentioned previously in that tutorial, the basic formula for working the value of PR given resolution is:</p>
<div class="equation" style="font-size:14px;margin-bottom:10px;">Resolution in Seconds = </p>
<div class="fraction"><span class="fup">PR+1</span><span class="bar">/</span><span class="fdn">PCLK in Hz</span></div>
</div>
<p>Since we need resolution is µs scale, we can scale the equation and rewrite it as follows:</p>
<div class="equation" style="font-size:14px;margin-bottom:10px;">Resolution in µs = </p>
<div class="fraction"><span class="fup">PR+1</span><span class="bar">/</span><span class="fdn">PCLK in Mhz</span></div>
</div>
<p>Now, to get the value of PR for 1µs Resolution, given we know and have already set PCLK, can be done as follows:</p>
<div class="equation" style="font-size:14px;margin-bottom:10px;">1 µs Resolution = </p>
<div class="fraction"><span class="fup">PR+1</span><span class="bar">/</span><span class="fdn">PCLK in MHz</span></div>
</div>
<p>Hence,</p>
<div class="equation" style="font-size:14px;margin-bottom:10px;">PR = (1 x PCLK in MHz) &#8211; 1 </div>
<p>Finally, since we will be using CCLK=PCLK=60Mhz, we get PR as follows:</p>
<div class="equation" style="font-size:14px;margin-bottom:10px;">PR = (1 x 60) &#8211; 1  = 59</div>
<p>Visit my <a href="https://www.ocfreaks.com/lpc214x-pll-tutorial-for-cpu-and-peripheral-clock/" target="_blank">tutorial on LPC2148 PLL and Clock setup</a> for more on how to setup CCLK and PCLK.</p>
<h4>Setting up PWM block for 20ms period with output</h4>
<p>Now, assuming both CCLK and PCLK are configured to run at 60Mhz, PWM Block can be configured to control RC Servo as follows:</p>
<div class="highlight">
<ol style="margin-bottom:0px">
<li>Select the PWMx function on the respective IO pin.</li>
<li>Set <strong><span class="code_var">PWMPR = 59</span></strong> to get a resolution of 1us. PWMTC increments every 59+1 Clock cycles @ 60mhz.</li>
<li>Set <strong><span class="code_var">PWMMCR = 0x1</span></strong> (bit0 = 1) to Reset PWMTC on PWMMR0 (and , 0x8= interrupt when PWMMR1 matches PWMTC i.e after PWMMR1 reaches the value assigned to it)</li>
<li>Set <strong><span class="code_var">PWMMR0 = 20000</span></strong> which sets the period to 20ms for all PWM outputs.</li>
<li>Set <strong><span class="code_var">PWMMR1</span></strong> to default PWM pulse time. We will use 1500µs i.e. neutral position.</li>
<li>Set the corresponding bits in <strong><span class="code_var">PWMLER</span></strong> to update the values in match registers.</li>
<li>Set the corresponding bits <strong><span class="code_var">PWMPCR</span></strong> to enable PWMx Output.</li>
</ol>
</div>
<h4>Example to configure &#038; initialize PWM with PWM1 Output:</h4>
<pre><code class="language-cpp">
PINSEL0 |=  (1<<1); //set Bits [1:0] = 10 to select PWM1 for P0.0

PWMPR = 59; //PWMTC increments every 59+1 Clock cycles @ 60mhz to yield a resolution of 1us
PWMMCR = 0x1; //Reset PWMTC on PWMMR0 Match which defines the PWM period
PWMMR0 = 20000; //PWM period of 20ms
PWMMR1 = 1500; //Default Pulse time. Brings servo in neutral position
PWMLER = (1<<0) | (1<<1); //Enable Match 1 &#038; Match 2 Latch to update new values
PWMPCR = (1<<9); //Enable PWM1 Output
PWMTCR = (1<<1); //Reset PWM Counter
PWMTCR = (1<<0) | (1<<3); //IMP! - Enable Counter and PWM
</code></pre>
<h4>Updating new PWM/Pulse values:</h4>
<p>Once PWM1 output is enabled we need to only update PWM match register 1 i.e. PWMMR1 (& PWMLER) with new values to control our servo's position. For updating new Match values to any of the Match register, the corresponding bit in the Latch Enable Register (PWMLER) must be set to 1. After New values are updated the Latch Enable Bit in PWMLER is again reset. Hence, for every update we must set the corresponding bit in PWMLER to 1. This update will happen at the beginning of next PWM period. For more please read the register explanation given in <a href="https://www.ocfreaks.com/lpc2148-pwm-programming-tutorial/" target="_blank">LPC2148 PWM tutorial</a> previously.</p>
<p><strong>Example for updating PWMMR1:</strong></p>
<pre><code class="language-cpp">
while(1) //main control loop
{
 //...
 //..
 PWMMR1 = 900;
 PWMLER |= (1<<1); //Bit[1] corresponds to PWMMR1 Latch
 /*new value will be updated at the beginning of next Period*/
 //..
}
</code></pre>
<h2 class="shead">ARM7 LPC2148 Servo Interfacing examples</p>
<h2>
<h4>Example 1: Simple Servo Control using LPC214x</h4>
<p>In this example we will repeatedly set the servo position to +45, 0, -45 degrees which roughly corresponds to 1ms, 1.5ms and 2ms pulse widths for most RC servos. Here, we will use a delay of 2 seconds between each position. Schematic and Color coding for various servo plugs is also given in the diagram below. Please confirm the color coding of your servo plug before you proceed with any connections.</p>
<p><img decoding="async" class="aligncenter" src="https://www.ocfreaks.com/imgs/lpc2148-tutorial/lpc214x_servo_interfacing_wiring_eg.png" width="505px" height="420px" alt="ARM7 LPC2148 Servo Interfacing wiring connections and schematic" /></p>
<div class="special sp_red notewarning"><strong>Note:</strong> Always double check the polarity of your connections going to servo plug. Connecting it in reserve might damage your servo permanently. The Author cannot be held responsible for any damage arising due to wrong connections for any of examples given here.</div>
<p><strong>Source Code:</strong></p>
<pre><code class="language-cpp">
/*(C) Umang Gajera - www.ocfreaks.com
LPC2148 Servo Interfacing Tutorial - Example 1
More Embedded tutorials @ www.ocfreaks.com/cat/embedded/
License: GPL.*/

#include &lt;lpc214x.h&gt;
#include "lib_funcs.h" //OCFreaks LPC214x Tutorials Library Header

int main(void)
{
	initClocks(); //Set PCLK = CCLK = 60Mhz
	initTimer0(); //For delay functions

	PINSEL0 |=  (1<<1); //set Bits [1:0] = 10 to select PWM1 for P0.0

	PWMPR = 59; //PWMTC increments every 59+1 Clock cycles @ 60mhz to yield a resolution of 1us
	PWMMCR = 0x1; //Reset PWMTC on PWMMR0 Match which defines the PWM period
	PWMMR0 = 20000; //PWM period of 20ms
	PWMMR1 = 1500; //Default Pulse time. Brings servo in neutral position
	PWMLER = (1<<0) | (1<<1); //Enable Match 1 &#038; Match 2 Latch to update new values
	PWMPCR = (1<<9); //Enable PWM1 Output
	PWMTCR = (1<<1); //Reset PWM Counter
	PWMTCR = (1<<0) | (1<<3); //IMP! - Enable Counter and PWM

	delayMS(2000); //Initial delay
	
	while(1)
	{
		PWMMR1 = 1000; //1ms Pulse
		PWMLER |= (1<<1); //Set MR1 Latch
		delayMS(2000); //2 Secs Delay
		
		PWMMR1 = 1500; //1.5ms Pulse
		PWMLER |= (1<<1);
		delayMS(2000);
		
		PWMMR1 = 2000; //2ms Pulse
		PWMLER |= (1<<1);
		delayMS(2000);
		
		PWMMR1 = 1500; //1.5ms Pulse
		PWMLER |= (1<<1);
		delayMS(2000);
	}
	
	//return 0; //This won't execute normally
}
</code></pre>
<p><strong>Project Download:</strong></p>
<div class="highlight"><strong>KEIL ARM uV5/uV4 Project for example given above is on GitHub @</strong> <a href="https://github.com/OCFreaks/LPC2148-Tutorial-Examples/tree/master/Servo_Interfacing/Example_1" target="_blank">Servo Interfacing with LPC2148</a> [Successfully tested on Keil uV5.23], <a href="https://minhaskamal.github.io/DownGit/#/home?url=https://github.com/OCFreaks/LPC2148-Tutorial-Examples/tree/master/Servo_Interfacing/Example_1" target="_blank">Download Project Zip</a>. You can find the HEX file inside objects folder.</div>
<h4>Example 2: Sweep/Interpolate Servo between two positions with LPC214x</h4>
<p>In this example we will sweep the servo between +45 & -45 degrees. The servo shaft will rotate at constant speed between the two defined locations. Here, we have to play with two parameters which define how smooth and fast will the servo move. These are: the delay between two steps and the step increment. In our case we will use a step increment of 20µs and an inter-step delay of 1 period i.e. 20ms. The wiring is same as shown for example 1.</p>
<p><strong>Source Code:</strong></p>
<pre><code class="language-cpp">
/*(C) Umang Gajera - www.ocfreaks.com
LPC2148 Servo Interfacing Tutorial - Example 1
More Embedded tutorials @ www.ocfreaks.com/cat/embedded/
License: GPL.*/

#include &lt;lpc214x.h&gt;
#include "lib_funcs.h" //OCFreaks LPC214x Tutorials Library Header

int main(void)
{
	initClocks(); //Set PCLK = CCLK = 60Mhz
	initTimer0(); //For delay functions

	PINSEL0 |=  (1<<1); //set Bits [1:0] = 10 to select PWM1 for P0.0

	PWMPR = 59; //PWMTC increments every 59+1 Clock cycles @ 60mhz to yield a resolution of 1us
	PWMMCR = 0x1; //Reset PWMTC on PWMMR0 Match which defines the PWM perioed
	PWMMR0 = 20000; //PWM period of 20ms
	PWMMR1 = 1000; //Default(starting) Pulse time for sweep.
	PWMLER = (1<<0) | (1<<1); //Enable Match 1 &#038; Match 2 Latch to update new values
	PWMPCR = (1<<9); //Enable PWM1 Output
	PWMTCR = (1<<1); //Reset PWM Counter
	PWMTCR = (1<<0) | (1<<3); //IMP! - Enable Counter and PWM

	delayMS(1000); //Initial delay
	
	int step = 20; //In us
	int stepDelay = 20; //In ms 
	int pulse=1000;
	while(1)
	{
		while(pulse<2000)
		{
			PWMMR1 = pulse;
			PWMLER |= (1<<1);
			delayMS(stepDelay);
			pulse = pulse + step;
		}
		while(pulse>1000)
		{
			PWMMR1 = pulse;
			PWMLER |= (1<<1);
			delayMS(stepDelay);
			pulse = pulse - step;
		}
	}
	
	//return 0; //This won't execute normally
}
</code></pre>
<p><strong>Project Download:</strong></p>
<div class="highlight"><strong>KEIL ARM uV5/uV4 Project for example given above is on GitHub @</strong> <a href="https://github.com/OCFreaks/LPC2148-Tutorial-Examples/tree/master/Servo_Interfacing/Example_2" target="_blank">Servo Interfacing with LPC2148</a> [Successfully tested on Keil uV5.23], <a href="https://minhaskamal.github.io/DownGit/#/home?url=https://github.com/OCFreaks/LPC2148-Tutorial-Examples/tree/master/Servo_Interfacing/Example_2" target="_blank">Download Project Zip</a>. You can find the HEX file inside objects folder.</div>
<p>The post <a href="https://www.ocfreaks.com/lpc2148-servo-motor-interfacing-tutorial/">LPC2148 Servo Motor Interfacing Tutorial</a> appeared first on <a href="https://www.ocfreaks.com">OCFreaks!</a>.</p>
]]></content:encoded>
					
					<wfw:commentRss>https://www.ocfreaks.com/lpc2148-servo-motor-interfacing-tutorial/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
		<post-id xmlns="com-wordpress:feed-additions:1">3086</post-id>	</item>
		<item>
		<title>Interfacing DHT11 &#038; DHT22 Sensor with LPC1768</title>
		<link>https://www.ocfreaks.com/interfacing-dht11-dht22-sensor-lpc1768/</link>
					<comments>https://www.ocfreaks.com/interfacing-dht11-dht22-sensor-lpc1768/?noamp=mobile#respond</comments>
		
		<dc:creator><![CDATA[Umang Gajera]]></dc:creator>
		<pubDate>Tue, 13 Mar 2018 15:57:24 +0000</pubDate>
				<category><![CDATA[Embedded]]></category>
		<category><![CDATA[lpc1768]]></category>
		<category><![CDATA[tutorial]]></category>
		<guid isPermaLink="false">http://www.ocfreaks.com/?p=3062</guid>

					<description><![CDATA[<p>In this tutorial we learn how to interface DHT11 and DHT22 Humidity and Temperature sensor with ARM Cortex-M3 LPC1768 microcontroller.</p>
<p>The post <a href="https://www.ocfreaks.com/interfacing-dht11-dht22-sensor-lpc1768/">Interfacing DHT11 &#038; DHT22 Sensor with LPC1768</a> appeared first on <a href="https://www.ocfreaks.com">OCFreaks!</a>.</p>
]]></description>
										<content:encoded><![CDATA[<p>In this tutorial we learn how to interface DHT11 and DHT22 Humidity and Temperature sensor with ARM Cortex-M3 LPC1768 microcontroller. I had discussed <a href="https://www.ocfreaks.com/basics-interfacing-dht11-dht22-humidity-temperature-sensor-mcu/">basics of DHT11/DHT22 interfacing</a> in my previous tutorial. Please go through it if you are new to DHTxx Humidity and Temperature sensors.</p>
<h4>A quick recap of the communication process:</h4>
<p><img decoding="async" class="aligncenter" src="https://www.ocfreaks.com/imgs/embedded/dht/dht11_dht22_protocol.png" width="645px" height="320px" alt="DHT11 DHT22 Humidity and Temperature Sensor communication process protocol" /></p>
<h4>DHT11 &#038; DHT22 Data format:</h4>
<p><img decoding="async" class="aligncenter" src="https://www.ocfreaks.com/imgs/embedded/dht/dht_data_format.png" width="505px" height="220px" alt="DHT11 DHT22 Humidity and Temperature Sensor data format" /></p>
<p>Now, lets have a look at steps we need to implement for Programming DTH11/DHT22. Since only one DATA line(PIN) is used, we will use the same GPIO PIN first as OUTPUT to send START condition and then as INPUT to Receive data. </p>
<div class="highlight">
<h4>Steps required for DHT11/DHT22 Interfacing:</h4>
<ol style="margin-bottom:0px;">
<li>Configure PIN to be used to communication as OUTPUT.</li>
<li>Set the PIN O/P to LOW and wait for 18 milli-seconds.</li>
<li>Configure the PIN as INPUT. The pull-up resistor will Pull the bus to HIGH.</li>
<li>Wait until DHT11 responds and pulls the line to LOW after around 40 micro-seconds or else exit as timeout error.</li>
<li>Next, check for 80us LOW followed by 80us HIGH from DHT11. This condition denotes that DHT11 is ready to send data next.</li>
<li>Now, check for 50us LOW followed by 26us to 28us HIGH denoting data bit &#8216;0&#8217; or 50us LOW followed 70us HIGH denoting  data bit &#8216;1&#8217;. Store the interpreted bit in an array. Repeat this for each of 40 bits.</li>
<li>Extract the data bytes from array to record or display it. Optionally the checksum can be used to verify data integrity.</li>
<li>Wait for at least 1 second before starting again to fetch new data.</li>
</ol>
</div>
<h4>Program for Interfacing DHT11/DHT22 with ARM LPC1768/LCP1769:</h4>
<p>In this example we will use PIN P0.0 (marked as P9 on mbed board) for communication with DHT11 sensor. For DHT22 you just need to make a small change in code to display the decimal part. I leave that to the reader. If you are using the bare 4 pin sensor than make sure that DATA pin is pulled up using 4.7K or 10K resistor. If you are using PCB mounted sensor which has 3 pins then external pullup resistor is not required since it is already present on the PCB. Timer0 module is used for generating delay and measuring timing of responses given by DHTxx. You can go through <a href="https://www.ocfreaks.com/lpc1768-timer-programming-tutorial/" target="_blank" rel="noopener">LPC1768 timer tutorial</a> for reference. </p>
<p>We will also use UART0 to send data back to PC and display it using software terminal. <a href="https://www.ocfreaks.com/retarget-redirect-printf-scanf-uart-keil/" target="_blank" rel="noopener">printf() has been targeted</a> such that its output gets redirected to UART0. Checkout my <a href="https://www.ocfreaks.com/retarget-redirect-printf-scanf-uart-keil/" target="_blank" rel="noopener">tutorial on how to retarget printf() in keil</a> and <a href="https://www.ocfreaks.com/lpc1768-uart-programming-tutorial/" target="_blank" rel="noopener">LPC1768 UART tutorial</a> for more. The schematic for connections between DHT11 and LPC214x is as given below:</p>
<p><img decoding="async" class="aligncenter" src="https://www.ocfreaks.com/imgs/lpc1768-tutorial/dht11_lpc1768.png" width="350px" height="250px" alt="LPC2148 DTH11 Interfacing Schematic" /></p>
<p>Before going through to source code, first lets go through some the functions used:</p>
<ul>
<li><span class="code_var">startTimer0()</span> &#8211; Resets counter and Enables Timer0 block.</li>
<li><span class="code_var">unsigned int stopTimer0()</span> &#8211; Disables counting and returns value in T0TC.</li>
<li><span class="code_var">checkResponse(&#8230;)</span> &#8211; Used to check the response from DHTxx. It has 3 parameters viz. <span class="code_ref">unsigned int waitTimeUS, unsigned int margin, bool pinValue</span>. waitTimeUS is simply the expected wait time in micro-seconds. Margin is additional timing error or offset we can account for, since the sensor might have intrinsic timing offets. pinValue is the current expected state of pin which it must hold until the given waitTime.</li>
<li><span class="code_var">char getDataBit()</span> &#8211; This checks the pulses for a &#8216;0&#8217; or a &#8216;1&#8217; and returns the value accordingly. It will return 2 in case of an error.</li>
<li><span class="code_var">printError(const char * str)</span> &#8211; Prints error message and halts program execution by entering infinite while loop. You must reset board in this situation or you can extend the code to handle errors on the fly.</li>
</ul>
<p><strong>DHT11 Humidity &#038; Temperature sensor Interfacing Source Code Snippet</strong></p>
<pre><code class="language-cpp">
/*(C) Umang Gajera - www.ocfreaks.com
DHT11 Humidity and Temperature Sensor Interfacing with LPC1768/LPC1769 Example Source Code for KEIL ARM
More Embedded tutorials @ www.ocfreaks.com/cat/embedded/
License : GPL.*/
#include &lt;lpc17xx.h&gt;
#include &lt;stdio.h&gt; //For retargeted printf() - https://www.ocfreaks.com/retarget-redirect-printf-scanf-uart-keil/
#include "ocf_lpc176x_lib.h" //contains initUART0(), initTimer0() & putc() to retarget printf()

#define LOW 0
#define HIGH 1
void printError(const char * str);
void checkResponse(unsigned int waitTimeUS, unsigned int margin, unsigned char pinValue);
char getDataBit(void);

#define DATA_PIN (1<<0) //Using P0.0 for data communication

int main(void)
{
	unsigned char dataBits[40] = {0};
	char dataBytes[5] = {0};
	
	initTimer0();
	initUART0();
	
	printf("OCFreaks.com - Interfacing DHT11 with LPC1768 Example.\n");
	
	while(1)
	{
		//STEP 1: Set pin to output HIGH which represents idle state
		LPC_GPIO0->FIODIR |= DATA_PIN;
		
		//STEP 2: Pull down pin for 18ms(min) to denote START
		LPC_GPIO0->FIOCLR |= DATA_PIN;
		delayUS(18000); //wait for 18ms
		
		//STEP 3: Pull HIGH and switch to input mode
		//pull-up will pull it HIGH after switching to input mode.
		LPC_GPIO0->FIODIR &= ~(DATA_PIN);
		
		//STEP 4: Wait between 20 to 40us for sensor to respond
		startTimer0();
		while((LPC_GPIO0->FIOPIN & DATA_PIN) != 0)
		{
			if(LPC_TIM0->TC > 40) break; //Timeout
		}
		unsigned int time = stopTimer0();
		
		if(time < 10 || time > 40) 
		{ 
			printError("Failed to communicate with sensor");
		}
		
		//STEP 5: Check for 80us LOW followed by 80us HIGH
		checkResponse(80,5,LOW);
		checkResponse(80,5,HIGH);
		
		//After this DHTxx sends data. Each bit has a preceding 50us LOW. After which 26-28us means '0' and 70us means '1'
		
		//STEP 6: Fetch data
		char data;
		for(int i=0; i < 40; i++)
		{
			data = getDataBit();
			
			if(data == 0 || data == 1)
			{
				dataBits[i] = data;
			}
			else printError("Data Error");
		}
		
		//STEP 7: Extract data bytes from array
		data = 0;
		for(int i=0; i<5; i++) // i is the BYTE counter
		{
			for(int j=0; j<8; j++) // j gives the current position of a bit in i'th BYTE
			{
				if( dataBits[ 8*i + j ] )
					data |= (1<<(7-j)); //we need to only shift 1's by ([BYTESZIE-1] - bitLocation) = (7-j)
			}
			dataBytes[i] = data;
			data = 0;
		}		
		
		printf("Humidity=%d%%, Temp=%d Deg. C\n",dataBytes[0], dataBytes[2]);
		
		//STEP8: Wait for atleast 1 second before probing again
		delayUS(1000000); 
	}
	//return 0;
}

void printError(const char * str)
{
	/*Print error and enter infinite loop to HALT program*/
	printf("%s\n",str);
	while(1);
}

void checkResponse(unsigned int waitTimeUS, unsigned int margin, unsigned char pinValue)
{
	int time = 0;
	int maxwait = waitTimeUS + margin;
	
	startTimer0();
	if(pinValue)
	{
		while(LPC_GPIO0->FIOPIN & DATA_PIN)
		{
			if(LPC_TIM0->TC > (maxwait)) break; 
		}
	}
	else
	{
		while( !(LPC_GPIO0->FIOPIN & DATA_PIN) )
		{
			if(LPC_TIM0->TC > (maxwait)) break; 
		}
	}
	time = stopTimer0();
	
	if(time < (waitTimeUS-margin) || time > maxwait) 
	{
		//printf("Error for wait=%d,margin=%d,pinVal=%d,time=%d\n",waitTimeUS,margin,pinValue,time);
		printError("checkResponse() Error"); //Out of range, including error margin
	}
}

char getDataBit(void)
{
	int time = 0;
	
	checkResponse(50,5,LOW); //Each data bit starts with 50us low
	
	startTimer0();
	while(LPC_GPIO0->FIOPIN & DATA_PIN)
	{
		if(LPC_TIM0->TC > 75)
		{
			return 2; //Error - Timeout for 50us LOW
		}
	}
	time = stopTimer0();
	
	if((time > (27-10)) && (time < (27+10))) //I am getting 21 for HIGH using my DHT11 sensor, so using higher margin
	{
		return 0;
	}
	else if((time > (70-5)) && (time < (70+5)))
	{
		return 1;
	}
	else 
	{ 
		return 2; //Error - Timeout for data pulse
	}
}

</code></pre>
<p>Here is a screenshot of the above example in action:</p>
<p><img decoding="async" class="aligncenter" src="https://www.ocfreaks.com/imgs/lpc1768-tutorial/dht11_lpc1768_example_ss.png" width="549px" height="290px" alt="LPC1768 DTH11 DHT22 Humidity and Temperature sensor Interfacing Example output" /></p>
<div class="highlight"><strong>KEIL ARM uV5 Project for example given above @</strong> <a href="https://github.com/OCFreaks/LPC1768-Tutorial-Examples/tree/master/DHT11_Interfacing" target="_blank" rel="noopener">DHT11 Interfacing with LPC1768 Example</a> [Successfully tested on Keil uV5.23], <a href="https://minhaskamal.github.io/DownGit/#/home?url=https://github.com/OCFreaks/LPC1768-Tutorial-Examples/tree/master/DHT11_Interfacing" target="_blank" rel="noopener">Download Project Zip</a>. You can find the HEX file inside objects folder.</div>
<p>The post <a href="https://www.ocfreaks.com/interfacing-dht11-dht22-sensor-lpc1768/">Interfacing DHT11 &#038; DHT22 Sensor with LPC1768</a> appeared first on <a href="https://www.ocfreaks.com">OCFreaks!</a>.</p>
]]></content:encoded>
					
					<wfw:commentRss>https://www.ocfreaks.com/interfacing-dht11-dht22-sensor-lpc1768/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
		<post-id xmlns="com-wordpress:feed-additions:1">3062</post-id>	</item>
		<item>
		<title>Interrupt Priority Grouping in ARM Cortex-M NVIC</title>
		<link>https://www.ocfreaks.com/interrupt-priority-grouping-arm-cortex-m-nvic/</link>
					<comments>https://www.ocfreaks.com/interrupt-priority-grouping-arm-cortex-m-nvic/?noamp=mobile#respond</comments>
		
		<dc:creator><![CDATA[Umang Gajera]]></dc:creator>
		<pubDate>Tue, 03 Oct 2017 18:13:47 +0000</pubDate>
				<category><![CDATA[Embedded]]></category>
		<category><![CDATA[guide]]></category>
		<category><![CDATA[tutorial]]></category>
		<guid isPermaLink="false">http://www.ocfreaks.com/?p=2918</guid>

					<description><![CDATA[<p>Microcontrollers based on ARM Cortex-M processor feature Nested Vectored Interrupt Controller or NVIC for handling interrupts. NVIC in ARM Cortex-M3 (ARMv7-M) implements fixed 8-bit priority fields in Interrupt Priority Register (IPR), thereby giving us up to 256(28) priority levels. But, not all of the ARM Microcontrollers implement 8 bits for priority levels, in which case [&#8230;]</p>
<p>The post <a href="https://www.ocfreaks.com/interrupt-priority-grouping-arm-cortex-m-nvic/">Interrupt Priority Grouping in ARM Cortex-M NVIC</a> appeared first on <a href="https://www.ocfreaks.com">OCFreaks!</a>.</p>
]]></description>
										<content:encoded><![CDATA[<p>Microcontrollers based on ARM Cortex-M processor feature Nested Vectored Interrupt Controller or <strong>NVIC</strong> for handling interrupts. NVIC in ARM Cortex-M3 (ARMv7-M) implements fixed 8-bit priority fields in <strong>Interrupt Priority Register</strong> (<span class="doc_ref">IPR</span>), thereby giving us up to 256(2<sup>8</sup>) priority levels. But, not all of the ARM Microcontrollers implement 8 bits for priority levels, in which case the remaining priority bits are treated as Zeros because the field size is fixed to 8 bits. The un-implemented bits are LSb aligned. Generally the implemented bits are in proportion with number of external(peripheral) interrupts a given microcontroller supports. These priority fields are stored in the Interrupt Priority Register. Each priority register is 32-bits wide and holds 4 priority fields. This is as shown below:</p>
<p><img decoding="async" class="aligncenter" src="https://www.ocfreaks.com/imgs/embedded/common/interrupt_priority_fields_arm.png" alt="Interrupt Priority Fields in IPRs of ARM Cortex-M3 NVIC" width="535px" height="255px" /></p>
<p style="margin-bottom:0px">Here, <span class="code_var">IRPn</span> represents <strong><em>n</em></strong>th Interrupt Priority Register. <span class="code_var">PRI_m</span> is the Priority field for Interrupt <strong><em>m</em></strong> (<strong>IRQm</strong>).</p>
<ul>
<li>The IPR number <strong>n</strong> for Interrupt <strong>m</strong> is the Quotient of &#8220;<strong>m/4</strong>&#8221; i.e. <span class="code_var">n = (int)m/4 = m DIV 4</span></li>
<li>The byte offset is the remainder of &#8220;<strong>m/4</strong>&#8221; i.e. <span class="code_var">offset = m % 4 = m MOD 4</span></li>
</ul>
<p style="margin-bottom:0px">In Cortex-M3, each of these fields can be further sub-divided into <strong>two parts</strong>, which are:</p>
<ul>
<li><strong>Preemption Priority or Group Priority level:</strong> This is upper part(sub-field) of the 8-bit priority field. This is the main priority level which defines the preemption of interrupt exceptions or IRQs. An Interrupt will preempt the execution of the current Interrupt, if its Group Priority is higher than the Interrupt being currently serviced. Lower priority values denote higher priority &#038; vice-versa.</li>
<li><strong>Sub-Priority Level:</strong> This comes into picture when there are multiple pending interrupts having same preemption or Group Priority. In this case the sub-priority will determine which Interrupt gets executed first. Also note that, if pending ISRs have same Group and Sub-Group priority then the Interrupt having the lowest IRQ number will be executed first.</li>
</ul>
<p>Cortex-M0 Processor only implements 2 bits in the priority field [7:6] and rest bits [5:0] are always treated as Zeros, thereby supporting only 4 unique priority levels. This implementation is fixed for all MCUs which use Cortex-M0 (ARMv6-M) CPU. It also doesn&#8217;t implement Interrupt Priority Grouping.</p>
<h2 class="shead">Interrupt Priority Groups in ARM Cortex-M3</h2>
<p>Based on the sub-divisions, priority groups are formed depending on how many bits are used for preemption and sub-priority levels. The master table which assigns a Priority Grouping Number for each of the 8 possible divisions is shown below:</p>
<table class="aligncenter" style="margin-bottom:15px">
<tr>
<th>Priority Grouping Number</th>
<th>Split Point</th>
<th>Group Priority Bits (x)</th>
<th>Sub Priority Bits (y)</th>
<th>Total Group Priorities</th>
<th>Total Sub Priorities</th>
</tr>
<tr style="text-align:center">
<td>0</td>
<td>[xxxxxxx.y]</td>
<td>[7:1]</td>
<td>[0]</td>
<td>128</td>
<td>2</td>
</tr>
<tr style="text-align:center">
<td>1</td>
<td>[xxxxxx.yy]</td>
<td>[7:2]</td>
<td>[1:0]</td>
<td>64</td>
<td>4</td>
</tr>
<tr style="text-align:center">
<td>2</td>
<td>[xxxxx.yyy]</td>
<td>[7:3]</td>
<td>[2:0]</td>
<td>32</td>
<td>8</td>
</tr>
<tr style="text-align:center">
<td>3</td>
<td>[xxxx.yyyy]</td>
<td>[7:4]</td>
<td>[3:0]</td>
<td>16</td>
<td>16</td>
</tr>
<tr style="text-align:center">
<td>4</td>
<td>[xxx.yyyyy]</td>
<td>[7:5]</td>
<td>[4:0]</td>
<td>8</td>
<td>32</td>
</tr>
<tr style="text-align:center">
<td>5</td>
<td>[xx.yyyyyy]</td>
<td>[7:6]</td>
<td>[5:0]</td>
<td>4</td>
<td>64</td>
</tr>
<tr style="text-align:center">
<td>6</td>
<td>[x.yyyyyyy]</td>
<td>[7]</td>
<td>[6:0]</td>
<td>2</td>
<td>128</td>
</tr>
<tr style="text-align:center">
<td>7</td>
<td>[.yyyyyyyy]</td>
<td>N/A</td>
<td>[7:0]</td>
<td>1</td>
<td>256</td>
</tr>
</table>
<div class="special sp_blue notestar">Note: The split point or the Binary point denotes the segregation of Interrupt Priority Field (in <strong>IPR</strong>) into Group-Priority bits denoted by &#8216;<strong>x</strong>&#8216; and Sub-Priority bits denoted by &#8216;<strong>y</strong>&#8216;.</div>
<p>This Priority Grouping is common for all ARM Cortex-M3 processor based microcontrollers. Any of the 8 possible grouping can be selected using the <span class="code_var">PRIGROUP</span> field (bits[10:8]) of the <span class="doc_ref">AIRCR</span> (Application Interrupt and Reset Control Register). The Priority Grouping Number value shown in the table is assigned to the <strong>PRIGROUP</strong> field of <span class="doc_ref">AIRCR</span>.</p>
<p>For MCUs which implement less than 8 bits, the non-implemented bits are treated as Zeros in the table above. For example LPC17xx devices (like LPC1768/LPC1769) implement only 5 bits for Priority. The remaining(lower) 3 bits are treated as Zeros. This is shown below:</p>
<h4>LPC176x Interrupt Priority Grouping</h4>
<table class="aligncenter" style="margin-bottom:20px">
<tr>
<th>Priority Grouping Number</th>
<th>Split Point</th>
<th>Group Priority Bits (x)</th>
<th>Sub Priority Bits (y)</th>
<th>Total Group Priorities</th>
<th>Total SubGroup Priorities</th>
</tr>
<tr style="text-align:center">
<td>0,1,2</td>
<td>[xxxxx.000]</td>
<td>[7:3]</td>
<td>N/A</td>
<td>32</td>
<td>1</td>
</tr>
<tr style="text-align:center">
<td>3</td>
<td>[xxxx.y000]</td>
<td>[7:4]</td>
<td>[3]</td>
<td>16</td>
<td>2</td>
</tr>
<tr style="text-align:center">
<td>4</td>
<td>[xxx.yy000]</td>
<td>[7:5]</td>
<td>[4:3]</td>
<td>8</td>
<td>4</td>
</tr>
<tr style="text-align:center">
<td>5</td>
<td>[xx.yyy000]</td>
<td>[7:6]</td>
<td>[5:3]</td>
<td>4</td>
<td>8</td>
</tr>
<tr style="text-align:center">
<td>6</td>
<td>[x.yyyy000]</td>
<td>[7]</td>
<td>[6:3]</td>
<td>2</td>
<td>16</td>
</tr>
<tr style="text-align:center">
<td>7</td>
<td>[.yyyyy000]</td>
<td>N/A</td>
<td>[7:3]</td>
<td>1</td>
<td>32</td>
</tr>
</table>
<p>An Example with Priority Grouping of 5 on LPC17xx Devices which implement 5 bits for Priority is as follows:</p>
<p><img decoding="async" class="aligncenter" src="https://www.ocfreaks.com/imgs/embedded/common/priority_grouping_arm_cortex_m.png"  alt="Priority Grouping in ARM Cortex-M3 NVIC" width="535px" height="340px" /></p>
<h4>STM32 (STM32F10xxx) Interrupt Priority Grouping</h4>
<p>Priority Grouping for other Cortex-M3 MCUs from the STM32 family like STM32F103, etc.. which implement only 4 bits of interrupt priority is given below. </p>
<table class="aligncenter" style="margin-bottom:20px">
<tr>
<th>Priority Grouping Number</th>
<th>Split Point</th>
<th>Group Priority Bits (x)</th>
<th>Sub Priority Bits (y)</th>
<th>Total Group Priorities</th>
<th>Total SubGroup Priorities</th>
</tr>
<tr style="text-align:center">
<td>0,1,2,3</td>
<td>[xxxx.0000]</td>
<td>[7:4]</td>
<td>N/A</td>
<td>16</td>
<td>1</td>
</tr>
<tr style="text-align:center">
<td>4</td>
<td>[xxx.y0000]</td>
<td>[7:5]</td>
<td>[4]</td>
<td>8</td>
<td>2</td>
</tr>
<tr style="text-align:center">
<td>5</td>
<td>[xx.yy0000]</td>
<td>[7:6]</td>
<td>[5:4]</td>
<td>4</td>
<td>4</td>
</tr>
<tr style="text-align:center">
<td>6</td>
<td>[x.yyy0000]</td>
<td>[7]</td>
<td>[6:4]</td>
<td>2</td>
<td>8</td>
</tr>
<tr style="text-align:center">
<td>7</td>
<td>[.yyyy0000]</td>
<td>N/A</td>
<td>[7:4]</td>
<td>N/A</td>
<td>16</td>
</tr>
</table>
<p>Similarly we can get the Priority Grouping table for LPC13xx devices like LPC1343/LPC1347 using the master table. Note that LPC134x MCUs implement only 3 bits of Priority hence can give 8 unique priority levels.</p>
<p>PRIGROUP can get a bit confusing since the unimplemented bits are towards the LSb i.e. in the lower half starting from bit location 0. But thankfully all of this hassle is handled by the CMSIS library.</p>
<h2 class="shead">Assigning/Programming Priority Levels using CMSIS</h2>
<p>The CMSIS NVIC functions defined in <span class="code_var">core_cm3.h</span> header defines standard interfaces for Configuring and Assigning Interrupt Priority levels which are listed below. These functions take care of aligning the priority bits as required, if the number of implemented bits are less than 8. First lets see the declarations of these functions.</p>
<pre><code class="language-cpp">
void NVIC_SetPriorityGrouping(uint32_t PriorityGroup);

uint32_t NVIC_GetPriorityGrouping(void);

uint32_t NVIC_EncodePriority(uint32_t PriorityGroup, uint32_t PreemptPriority, uint32_t SubPriority);

void NVIC_DecodePriority(uint32_t Priority, uint32_t PriorityGroup, uint32_t* pPreemptPriority, uint32_t* pSubPriority);

void NVIC_SetPriority(IRQn_Type IRQn, uint32_t priority);

uint32_t NVIC_GetPriority(IRQn_Type IRQn);
</code></pre>
<ul>
<li><strong><span class="code_var">NVIC_SetPriorityGrouping()</span>:</strong> This function is used to select the Priority Grouping. The parameter PriorityGroup is the Priority Grouping Number as given the Tables above. This function changes the <strong>PRIGROUP</strong> bits[10:8] of <span class="doc_ref">AIRCR</span>(Application Interrupt &#038; Reset Control Register) register which defines how the Priority Fields in <strong>IPRs</strong> are split.</li>
<li><strong><span class="code_var">NVIC_GetPriorityGrouping()</span>:</strong> It returns the Priority Grouping(0 to 7) currently selected.</li>
<li><strong><span class="code_var">NVIC_EncodePriority(..)</span>:</strong> This function will return &#8220;encoded&#8221; Priority Field for given a Priority Grouping(0 to 7), Preempt Priority and Sub-Priority. This function automatically takes care of un-implemented bits. The value returned by this function can be directly assigned to required Priority field in <span class="doc_ref">IPRn</span> using <span class="code_var">NVIC_SetPriority(..)</span>.</li>
<li><strong><span class="code_var">NVIC_DecodePriority(..)</span>:</strong> This function will &#8220;decode&#8221; the Priority Field into Pre-empt Priority and Sub-Priority for a given Priority Grouping(0 to 7).</li>
<li><strong><span class="code_var">NVIC_SetPriority(..)</span>:</strong> As the name suggestes, it is used to assign a priority for given Interrupt source. Note that the parameter <span class="code_var">priority</span> must be in accordance with Priority Grouping selected, hence <span class="code_var">NVIC_EncodePriority()</span> must be used to encode priority before calling this function.</li>
<li><strong><span class="code_var">NVIC_GetPriority(..)</span>:</strong> Returns the priority value for given IRQ.</li>
</ul>
<div class="special sp_cyan notewarning">Functions <span class="code_var">NVIC_SetPriorityGrouping()</span>, <span class="code_var">NVIC_GetPriorityGrouping()</span>, <span class="code_var">NVIC_EncodePriority(..)</span> &#038; <span class="code_var">NVIC_DecodePriority(..)</span> are not applicable for <strong>Cortex-M0</strong> since it does not implement Priority Groups. </div>
<p>C/C++ Example 1:</p>
<pre><code class="language-cpp">
#include &lt;lpc17xx.h&gt;

int main(void)
{
	unsigned int priority = 0;
	
	NVIC_SetPriorityGrouping(4); 
	/* bits[7:5] used for Group Priority
	   bits[4:3] used for Sub-Group Priority */
	
	priority = NVIC_EncodePriority(4,2,0);
	/*4= Priority Grouping, 2= Group Priority, 0= Sub-Priority*/

	NVIC_SetPriority(TIMER0_IRQn,priority); //Set new Priority
	
	while(1)
	{
		/*Code.*/
	}
	
	//return 0;
}
</code></pre>
<p>C/C++ Example 2:</p>
<pre><code class="language-cpp">
#include &lt;lpc17xx.h&gt;
#define NUM_IRQn 35 //Total number of peripheral interrupts
#define PRIGROUP_4 4
#define DEFAULT_GROUP_PRI 7
#define DEFAULT_SUB_PRI 3
#define TIMER2_GROUP_PRI 2
#define TIMER2_SUB_PRI 0

int main(void)
{
	unsigned int priority = 0, priGroup = 0;
	
	NVIC_SetPriorityGrouping(PRIGROUP_4); 
	/* bits[7:5] used for Group Priority
	   bits[4:3] used for Sub-Group Priority */
	
	priGroup = NVIC_GetPriorityGrouping();
	
	priority = NVIC_EncodePriority(priGroup, //=4
							DEFAULT_GROUP_PRI, //=7, Preempt/Group Priority
							DEFAULT_SUB_PRI); //=3, SubPriority within Group
	
	for(int currIRQ = 0; currIRQ < NUM_IRQn; currIRQ++ )
	{
		NVIC_SetPriority(currIRQ, priority); //Set new default Priorities for all peripheral IRQs
	}
	
	priority = NVIC_EncodePriority(priGroup, //=4
							TIMER2_GROUP_PRI, //=2, Preempt/Group Priority
							TIMER2_SUB_PRI); //=0, SubPriority within Group
	
	NVIC_SetPriority(TIMER2_IRQn, priority); //Set new higher priority for TIMER2 IRQ	
	
	while(1)
	{
		/*Code.*/
	}
	
	//return 0;
}
</code></pre>
<h2 class="shead">Exception Mask Registers</h2>
<p>ARM Cortex-M3 implements three Exception Mask Registers which are used to disable the execution of certain group or type of Interrupts/Exceptions where they can impact the performance of time critical tasks. This is more useful for applications having real time constraints, where the system has to gurantee completion of certain tasks within required time-frame. These registers can be only accessed via <strong>core register access functions</strong> provided by <strong>CMSIS</strong> which are defined in <span class="code_var">core_cmFunc.h</span>.</p>
<h4>PRIMASK - Priority Mask Register</h4>
<p><span class="doc_ref">PRIMASK</span> register is used to disable interrupts which have configurable priority i.e. External/Peripheral Interrupts when bit[0] in this register is set to 1. When set to 0 this register won't have any effect on interrupts. Rest of the bits[31:1] are reserved.</p>
<p>CMSIS provides 2 functions to access this register viz:<br />
<strong></p>
<ul>
<li><span class="code_var">void __set_PRIMASK(uint32_t priMask)</span></li>
<li><span class="code_var">uint32_t __get_PRIMASK(void)</span></li>
</ul>
<p></strong></p>
<h4>FAULTMASK - FAULT Mask Register</h4>
<p><span class="doc_ref">FAULTMASK</span> register is used to disable all interrupts execpt Non-Maskable Interrupt(NMI) when bit[0] in this register is set to 1. When set to 0 this register won't have any effect on interrupts. Rest of the bits[31:1] are reserved.</p>
<p>CMSIS provides 2 functions to access FAULTMASK register viz:<br />
<strong></p>
<ul>
<li><span class="code_var">void __set_FAULTMASK(uint32_t faultMask)</span></li>
<li>
<span class="code_var">uint32_t  __get_FAULTMASK(void)</span></li>
</ul>
<p></strong></p>
<h4>BASEPRI - Base Priority Mask Register</h4>
<p><span class="doc_ref">BASEPRI</span> register defines the minimum priority to service interrupts. Only Bits[7:0] are used. This 8-bit field is same as the priority field in IPRs. When a certain non-zero 8-bit priority value is set to this register, then it will disable all interrupts having same or lower priority than the value set. If this register is set to 0 then it won't have any effect. Note that this function doesn't shift the priority bits in case some bits are not implemented. The user is responsible for left shifiting the bits by <span class="code_var">(8 - __NVIC_PRIO_BITS)</span> where <span class="code_var">__NVIC_PRIO_BITS</span> is number of implemented priority bits which is defined in the device header file.</p>
<p>CMSIS provides 2 functions to access BASEPRI register viz:<br />
<strong></p>
<ul>
<li><span class="code_var">void __set_BASEPRI(uint32_t basePri)</span></li>
<li>
<span class="code_var">uint32_t  __get_BASEPRI(void)</span></li>
</ul>
<p></strong></p>
<h4>References and Further Reading:</h4>
<ol>
<li><a href="http://infocenter.arm.com/help/topic/com.arm.doc.dui0552a/DUI0552A_cortex_m3_dgug.pdf" target="_blank">ARM Cortex-M3 User Guide</a></li>
<li><a href="http://infocenter.arm.com/help/index.jsp?topic=/com.arm.doc.100165_0201_00_en/index.html" target="_blank">ARM Cortex-M3 Processor Technical Reference Manual</a></li>
<li><a href="http://infocenter.arm.com/help/topic/com.arm.doc.dui0497a/DUI0497A_cortex_m0_r0p0_generic_ug.pdf" target="_blank">ARM Cortex-M0 User Guide</a></li>
<li><a href="http://arm-software.github.io/CMSIS_5/Core/html/modules.html" target="_blank">CMSIS-Core v5 Documentation</a></li>
<li><a href="https://www.nxp.com/docs/en/user-guide/UM10360.pdf" target="_blank">LPC176x/5x User Manual</a></li>
<li><a href="http://www.st.com/resource/en/reference_manual/cd00171190.pdf" target="_blank">STM32F10x User Manual</a></li>
<li><a href="https://www.nxp.com/docs/en/user-guide/UM10375.pdf" target="_blank">LPC13xx User Manual</a></li>
</ol>
<p>The post <a href="https://www.ocfreaks.com/interrupt-priority-grouping-arm-cortex-m-nvic/">Interrupt Priority Grouping in ARM Cortex-M NVIC</a> appeared first on <a href="https://www.ocfreaks.com">OCFreaks!</a>.</p>
]]></content:encoded>
					
					<wfw:commentRss>https://www.ocfreaks.com/interrupt-priority-grouping-arm-cortex-m-nvic/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
		<post-id xmlns="com-wordpress:feed-additions:1">2918</post-id>	</item>
		<item>
		<title>LPC1114 PWM Programming Tutorial</title>
		<link>https://www.ocfreaks.com/lpc1114-pwm-programming-tutorial/</link>
					<comments>https://www.ocfreaks.com/lpc1114-pwm-programming-tutorial/?noamp=mobile#respond</comments>
		
		<dc:creator><![CDATA[Umang Gajera]]></dc:creator>
		<pubDate>Mon, 02 Oct 2017 16:07:02 +0000</pubDate>
				<category><![CDATA[Embedded]]></category>
		<category><![CDATA[lpc1114]]></category>
		<category><![CDATA[tutorial]]></category>
		<guid isPermaLink="false">http://www.ocfreaks.com/?p=2911</guid>

					<description><![CDATA[<p>This time I will discuss ARM Cortex-M0 LPC1114 Pulse Width Modulation (PWM) Tutorial. This programming guide is also applicable for other devices of same family like LPC1115. I will also cover 2 simple LPC1114 PWM examples. I assume you are comfortable with Timers in ARM Cortex-M0 based LPC11xx micro-controllers since PWM block is basically a [&#8230;]</p>
<p>The post <a href="https://www.ocfreaks.com/lpc1114-pwm-programming-tutorial/">LPC1114 PWM Programming Tutorial</a> appeared first on <a href="https://www.ocfreaks.com">OCFreaks!</a>.</p>
]]></description>
										<content:encoded><![CDATA[<p class="tocpostimage"> This time I will discuss <strong>ARM Cortex-M0 LPC1114 </strong><strong>Pulse Width Modulation</strong> (PWM) Tutorial. This programming guide is also applicable for other devices of same family like LPC1115. I will also cover 2 simple LPC1114 PWM examples. I assume you are comfortable with Timers in ARM Cortex-M0 based LPC11xx micro-controllers since PWM block is basically a Timer with PWM mode enabled. Please go through the <a href="https://www.ocfreaks.com/lpc1114-timer-programming-tutorial/">previous tutorial</a> since we will be using the same registers except for PWM Control Register which is covered in this tutorial.</p>
<div class="toc_container">
<span class="toc_title">Table of Contents</span></p>
<div class="toc">
<ol class="toc_list">
<li class="toc_text"><a href="#PWM_Module"><span>ARM Cortex-M0 LPC1114 PWM Module</span></a></li>
<ol class="toc_list">
<li class="toc_text"><a href="#Leading_Edge_PWM"><span>Leading Edge PWM Waveform</span></a></li>
<li class="toc_text"><a href="#PWM_timing_diagram"><span>PWM Timing Diagram Example</span></a></li>
</ol>
<li class="toc_text"><a href="#PWM_Registers"><span>PWM Registers</span></a></li>
<li class="toc_text"><a href="#PWM_Configuration"><span>Configuring LPC111x PWM Block</span></a></li>
<ol class="toc_list">
<li class="toc_text"><a href="#PWM_Prescaler_formula"><span>LPC1114 PWM Prescaler Calculations</span></a></li>
</ol>
<li class="toc_text"><a href="#LPC1114_PWM_Examples"><span>LPC111x PWM Examples</span></a></li>
<ol class="toc_list">
<li class="toc_text"><a href="#Example1"><span>LPC1114 PWM Example 1</span></a></li>
<li class="toc_text"><a href="#Example2"><span>LPC1114 PWM Example 2</span></a></li>
</ol>
</ol>
</div>
</div>
<h4 style="clear:both;"> Pulse Width Modulation (PWM) Basics: </h4>
<p>I&#8217;ve have posted a <a href="https://www.ocfreaks.com/pulse-width-modulation-pwm-tutorial/">Beginner PWM tutorial</a>. If you are new to PWM please have a look there. A Diagram that sums it up is given below. It shows Single Edge Non-Inverting or Left-Aligned PWM with T<sub>ON</sub>, T<sub>OFF</sub> &#038; Period. Duty Cycle is simply T<sub>ON</sub> Divided by Period.</p>
<p><img decoding="async" class="aligncenter" src="https://www.ocfreaks.com/imgs/embedded/common/pwm_basics.png" alt="PWM timing showing T-on, T-off and Period" width="425px" height="180px" /></p>
<h2 class="shead" id="PWM_Module">ARM Cortex-M0 LPC1114 PWM Module</h2>
<p>In LPC11xx Microcontrollers a dedicated PWM block is absent. Instead, PWM support is integrated in the Timers themselves. We just need to use them in PWM mode to generate PWM. LPC111x micro-controllers only support Single Edge PWM outputs. More over, the way PWM support is implemented in these microcontrollers, the PWM pulse is Leading-Edge or Right-Aligned compared to Trailing-Edge or Left-Aligned  PWM which is more common. But thankfully, this does not change the way we control external PWM controlled devices since Leading-Edge/Right-Aligned PWM is just a Phase-Shifted Left-Aligned pulse <strong>&#8211; with the only condition that Duty Cycle (hence T<sub>ON</sub>) remains the same</strong>. Given this condition is satisfied: consider it having a &#8220;offset&#8221; at the beginning, afterwhich its basically Left-Aligned PWM if you disregard the &#8220;initial-offset&#8221; or phase-shift. Here is what it looks like:</p>
<p><img decoding="async" class="aligncenter" id="Leading_Edge_PWM" src="https://www.ocfreaks.com/imgs/embedded/common/leading_edge_inverted_pwm.png" alt="Single edge Inverted, Leading Edge, Right-Aligned PWM waveform" width="385px" height="235px" /></p>
<p>Since we are using Timer in PWM mode, calculations for Prescale and configuration is exactly the same. Essentially we have two 16-bit PWM blocks and two 32-bit PWM blocks. Each capable of generating 3 PWM outputs using first 3 match registers (MR0 to MR2). The last match register (<strong>MR3</strong>) is used to set the PWM Period. The Match outputs pins are used get the PWM output when PWM mode is enabled for the corresponding Match output. Please refer my previous timer tutorial for MAT pins.</p>
<div class="highlight">
<strong>PWM Rules &#8211;</strong> The User Manual mentions Rules for using Single Edge PWM on page 374. </p>
<ol style="margin-bottom:0px">
<li>All PWM outputs will go LOW at the beginning of a PWM cycle unless their match value is 0.</li>
<li>Each PWM output will go HIGH when its match value is reached. <strong>Note:</strong> If no match occurs i.e Match value is greater than Period then the output will remain LOW!</li>
<li>If the Match value is greater than PWM Period or the Cycle Time, and PWM signal is already HIGH, then the signal will be made LOW at the start of next cycle.</li>
<li>If Match value is same as the Period, then PWM output will be reset to LOW at the next clock tick after TC reaches its reset value. Hence, we end up getting one clock pulse at the beginning. This implies we can never get 0% duty-cycle. Its almost 0% but not 0%!</li>
<li>If Match value is zero then PWM output will be HIGH continuously.</li>
</ul>
</div>
<p id="PWM_timing_diagram">Consider that our PWM Period duration is 5 milliseconds and TC increments every 1 millisecond using appropriate prescale value. We set MR3 to 5 i.e. <strong>5 ticks of PWM TC</strong>. We have MR1 = 2 and MR2 = 4. We using T<sub>OFF</sub> as Match values. Whenever the value in TC matches the value in any of the match register, its corresponding output it set to HIGH until the start of next PWM cycle as shown in PWM Timing Diagram below:</p>
<p><img decoding="async" class="aligncenter" src="https://www.ocfreaks.com/imgs/embedded/common/lpc_leading_edge_pwm_waveform.png" alt="Leading Edge or Right-Aligned PWM timing diagram in some LPC MCUs" width="515px" height="315px" /></p>
<h2 class="shead" id="PWM_Registers">Registers used in LPC1114 PWM Programming</h2>
<p>I have already explained TCR, PR, MRx &#038; MCR registers in <a href="https://www.ocfreaks.com/lpc1114-timer-programming-tutorial/">previous LPC1114 Tutorial</a>, so I won&#8217;t explaining them in detail except for PWMC.</p>
<div class="highlight">
<strong>1) <span class="doc_ref">TCR</span> &#8211; Timer Control Register:</strong> This register is used to control the Timer Counter. Only Bits: 0, 1  &#038; 3 are used rest are reserverd.</p>
<p><strong>2) <span class="doc_ref">PR</span> &#8211; (PWM) Prescale Register:</strong> Used to control the resolution of the PWM outputs. The Timer Counter(TC) will increment every PR+1 Peripheral Clock Cycles (PCLK).</p>
<p><strong>3) <span class="doc_ref">MR0 &#8211; MR3</span> (Match Registers):</strong> These four Match registers contain <strong>Pulse T<sub>OFF</sub> (or LOW Time) Values i.e the Number of TC Ticks required to change the output from LOW to HIGH.</strong>.</p>
<p><strong>4) <span class="doc_ref">MCR</span> &#8211; (PWM) Match Control Registers:</strong> It is used to specify what operations can be done when the value in a particular Match register equals the value in TC &#8211; Either generate an Interrupt, or Reset the TC, or Stop, which stops the counters.</p>
<p><strong>5) <span class="doc_ref">PWMC (TM32BxPWMC) </span> &#8211; PWM Control Register:</strong> It is used to configure Match outputs as PWM outputs. As mentioned earlier only <strong>three PWM outputs</strong> can be used at a time since one additional Match Register is used to generate the PWM Period. As recommended by the User Manual MR3 must be used to generate the Period. Only the first 4 bits are used, one for each Match Output. <strong>BITx</strong> is used to enable <strong>PWM Mode</strong> for <strong>MATx</strong>. Hence BIT0 for MAT0, BIT1 for MAT1 and so on. When a bit is 0 the corresponding Match Output is defined by EMx Bit in EMR register. When a bit is 1, PWM Output is enabled for the corresponding Match Output Pin. We are only interested in setting these bits to 1.
</div>
<h2 class="shead" id="PWM_Configuration">Configuring and Initializing PWM in LPC111x</h2>
<p>Now lets see how to configure PWM. First we need to do some basic Calculations for defining the <strong>PWM Period</strong> time and the <strong>PWM Resolution</strong> using a prescale value. For this first we need to define the resolution of our PWM signal. PWM resolution is the minimum time delay that can used to increase or decrease the pulse width. More smaller the increment more fine will be the resolution. PWM Resolution is set using an appropriate Prescale Value.</p>
<div class="special sp_blue noteinfo" id="PWM_Prescaler_formula">
<h4>LPC1114 PWM Prescale Calculations:</h4>
<p>The general formula for <strong>PWM Resolution</strong> at X Mhz PCLK(CCLK) and a given value for prescale (PR) is as given below:</p>
<div class="equation">PWM<sub>RES</sub> =</p>
<div class="fraction"><span class="fup">PR+1</span><span class="bar">/</span><span class="fdn">PCLK<sub>Hz</sub></sup></span></div>
<p> =</p>
<div class="fraction"><span class="fup">PR+1</span><span class="bar">/</span><span class="fdn">X * 10<sup>6</sup></span></div>
<p>Seconds</p></div>
<p>Hence, we get the <strong>Formula for Prescaler (PR) for required PWM resolution (PWM<sub>RES</sub> in Secs)</strong> at given <strong>PCLK(in Hz)</strong> frequency as:</p>
<div class="equation">PR = (PCLK<sub>Hz</sub> * PWM<sub>RES</sub>) &#8211; 1</div>
<div class="equation">PR = ((X * 10<sup>6</sup>) * PWM<sub>RES</sub>) &#8211; 1</div>
<p>Note that here, the PWM Resolution is also the time delay required to increment TC by 1.</p>
<p>Hence, Prescaler value for 1 micro-second resolution i.e. 1us time delay at 48 Mhz PCLK(CCLK) is,</p>
<div class="equation">PR<sub>1us</sub> = (48Mhz * 1uS) -1 = (48*10<sup>6</sup> * 10<sup>-6</sup>) -1 = 47</div>
<p><strong>Note:</strong> with &#8220;PCLK&#8221; I basically mean CCLK since for LPC11xx Microcontrollers: <strong>PCLK=CCLK</strong>.
</div>
<div class="highlight">
After we&#8217;ve worked out the resolution we want, we can now Configure &#038; Initialize PWM Mode as per the following steps:</p>
<ol style="margin-bottom:0px">
<li>Select the MATx function for the PIN on which you need the PWM output using applicable <span class="code_var">LPC_IOCON</span> register.</li>
<li>Assign the Calculated value to <span class="code_var">PR</span>.</li>
<li>Set the Value for PWM Period in <span class="code_var">MR3</span>.</li>
<li>Set the Values for other Match Registers i.e the Pulse Widths.</li>
<li>Set appropriate bit values in <span class="code_var">MCR</span> For e.g. Reset on MR3 Match for using MR3 to define PWM Period</li>
<li>Then Enable PWM outputs using <span class="code_var">PWMC</span>.</li>
<li>Now Reset PWM Timer using <span class="code_var">TCR</span>.</li>
<li>Finally, Enable TC using <span class="code_var">TCR</span>.</li>
</ol>
</div>
<p><strong>Example :</strong></p>
<pre><code class="language-cpp">
//Select MATn.x Function Using appropriate IOCON register for PWM output
LPC_IOCON->..    = ... ; //Select MATx Function for pins being used
LPC_TMRnBx->PR   = ... ; //assign calculated PR value 
LPC_TMRnBx->MR3  = ... ; //Assign PWM Period Duration
LPC_TMRnBx->MRx  = ... ; //Assign Pulse off duration i.e. T<sub>OFF</sub> for other Match Regs
LPC_TMRnBx->MCR  = (1<<10); //Reset TC on MR3 match
LPC_TMRnBx->PWMC = ... ; //enable PWM mode for MATx pins as required
LPC_TMRnBx->TCR  = 0x2; //Reset PWM TC & PR

//Now , the final moment - enable TC
LPC_TMRnBx->TCR  = 0x1; //enable counters for PWM
//Done!
</code></pre>
<h2 class="shead" id="LPC1114_PWM_Examples">ARM Cortex-M0 LPC1114 PWM Examples with code</h2>
<h4 id="Example1">LPC1114 PWM Example 1 &#8211; LED Dimming</h4>
<p>In this PWM Example we will use a Period of 1ms and vary the Duty-cycle from &#8220;almost&#8221; 0%(LED almost OFF) to 100%(Brightest). As mentioned earlier we cannot generate a duty-cycle of 0%(i.e. Signal Continuosly LOW), but it will close to 0%. Connect the LED anode to P1.18 and cathode to GND using a suitable resistor (like >330 Ohms). In the C++ code given below, I have also used 16Bit-Timer0 which is used by <span class="code_var">delayMS(..)</span> function to generate delay before we update MR0 register with new value. Also note that we are using match values corresponding to <strong>T<sub>OFF</sub></strong> time. So we subtract T<sub>ON</sub> from Period to get the match values which essentially makes the output a Phase-shifted PWM.</p>
<p><strong>C++ Source code for Example 1:</strong></p>
<pre><code class="language-cpp">
/*(C) Umang Gajera - www.ocfreaks.com
More Embedded tutorials @ https://www.ocfreaks.com/cat/embedded/
LPC1114 PWM Tutorial Example 1 - LED Dimming using PWM.
License: GPL.*/
#include &lt;lpc11xx.h&gt;

#define PRESCALE_US (48-1) //Used by PWM
#define PRESCALE_MS (48000-1) //Used by 16Bit-TMR0 for generating delay
#define PWM_PERIOD 1000 //in micro-seconds

void init32BTMR0_PWM(void);
inline void updatePulseWidth(unsigned int pulseWidth);
void delayMS(unsigned int milliseconds);
void init16BTimer0(void);

int main (void)
{
	//SystemInit(); //called by Startup Code before main(), hence no need to call again.
	LPC_IOCON->PIO1_6 |= 0x2; //Select CT32B0_MAT0 (MAT0.0) function for PWM O/P, Marked as RXD on LPCXpresso Board

	int pulseWidths[] = {
			PWM_PERIOD-0,PWM_PERIOD-250,
			PWM_PERIOD-500,PWM_PERIOD-750,
			PWM_PERIOD-1000}; //Inverted Pulse Widths for varying LED Brightness
	//Note: PWM_PERIOD-0 = LED almost OFF, PWM_PERIOD-1000 = LED Brightest!
	//PWM Pulses in LPC1114 are Right-Aligned or "inverted"!
	const int numPulseWidths = 5;
	int count=1;
	int dir=0; //direction, 0 = Increasing, 1 = Decreasing

	init32BTMR0_PWM(); //Initialize 32Bit-TMR0 as PWM
	init16BTimer0(); //Used by delayMS()

	while(1)
	{
		updatePulseWidth(pulseWidths[count]); //Update LED Pulse Width
		delayMS(500);

		if(count == (numPulseWidths-1) || count == 0)
		{
			dir = !dir; //Toggle direction if we have reached count limit
		}

		if(dir) count--;
		else count++;
	}
  //return 0; //normally this won't execute ever
}

void init32BTMR0_PWM(void)
{
	/*Assuming CCLK (System Clock) = 48Mhz (set by startup code)*/
	LPC_SYSCON->SYSAHBCLKCTRL |= (1<<9); //Enable 32Bit-TMR0 Clock
	LPC_TMR32B0->CTCR = 0x0;
	LPC_TMR32B0->PR = PRESCALE_US; //Increment TC at every 47999+1 clock cycles
	//48000 clock cycles @48Mhz = 1 mS
	LPC_TMR32B0->MR3 = PWM_PERIOD; //1ms Period duration
	LPC_TMR32B0->MR0 = PWM_PERIOD-250; //Default TOFF time in mS
	LPC_TMR32B0->MCR = (1<<10); //Reset on MR3 Match

	LPC_TMR32B0->PWMC = 0x1; //Enable PWM Mode for MAT0.0

	LPC_TMR32B0->TCR = 0x2; //Reset Timer
	LPC_TMR32B0->TCR = 0x1; //Enable timer
}

inline void updatePulseWidth(unsigned int pulseWidth)
{
	LPC_TMR32B0->MR0 = pulseWidth; //Update MR1 with new value
}

void delayMS(unsigned int milliseconds) //Using 16Bit-TMR0
{
	LPC_TMR16B0->TCR = 0x2; //Reset Timer
	LPC_TMR16B0->TCR = 0x1; //Enable timer

	while(LPC_TMR16B0->TC < milliseconds); //wait until timer counter reaches the desired delay

	LPC_TMR16B0->TCR = 0x0; //Disable timer
}

void init16BTimer0(void)
{
	/*Assuming CCLK (System Clock) = 48Mhz (set by startup code)*/
	LPC_SYSCON->SYSAHBCLKCTRL |= (1<<7); //Enable 16Bit_Timer0 Clock
	LPC_TMR16B0->CTCR = 0x0;
	LPC_TMR16B0->PR = PRESCALE_MS; //Increment TC at every 47999+1 clock cycles
	//48000 clock cycles @48Mhz = 1 mS
	LPC_TMR16B0->TCR = 0x2; //Reset Timer
}
</code></pre>
<div class="highlight"><strong>KEIL ARM uV5 Project for Example #1 on GitHub @</strong> <a href="https://github.com/OCFreaks/LPC1114-Tutorial-Examples/tree/master/MCUXpresso/PWM/Example_1" target="_blank">PWM Example 1 Source</a> [Successfully tested on Keil uV5.23], <strong>Download Project Zip</strong> @ <a href="https://minhaskamal.github.io/DownGit/#/home?url=https://github.com/OCFreaks/LPC1114-Tutorial-Examples/tree/master/MCUXpresso/PWM/Example_1" target="_blank">Example_1.Zip</a></div>
<h4 id="Example2">LPC1114 PWM Example 2 &#8211; Basic RC Servo Control</h4>
<p>In this Example we will sweep a servo from 1000us to 2000us pulse widths, back and forth in steps. The period is set to 20ms(20000us) which is common for servos. PWM1.1 output is selected and will be available on Pin P1.18. <strong>Warning:</strong> Double check all connections when connecting the motor or it will damage your board.</p>
<p><strong>C++ Source Code for Example 2:</strong></p>
<pre><code class="language-cpp">
/*(C) Umang Gajera - www.ocfreaks.com
More Embedded tutorials @ https://www.ocfreaks.com/cat/embedded/
LPC1114 PWM Tutorial Example 2 - Simple Servo Control.
License: GPL.*/
#include &lt;lpc11xx.h&gt;

#define PRESCALE_US (48-1) //Used by PWM
#define PRESCALE_MS (48000-1) //Used by 16Bit-TMR0 for generating delay
#define PWM_PERIOD 20000 //in micro-seconds

void init32BTMR0_PWM(void);
inline void updatePulseWidth(unsigned int pulseWidth);
void delayMS(unsigned int milliseconds);
void init16BTMR0(void);

int main (void)
{
	//SystemInit(); //called by Startup Code before main(), hence no need to call again.
	LPC_IOCON->PIO1_6 |= 0x2; //Select CT32B0_MAT0 (MAT0.0) function for PWM O/P, Marked as RXD on LPCXpresso Board

	int pulseWidths[] = {
			PWM_PERIOD-1000,PWM_PERIOD-1250,
			PWM_PERIOD-1500,PWM_PERIOD-1750,
			PWM_PERIOD-2000}; //Inverted Pulse Widths
	//Note: PWM_PERIOD-1000 will generate a Right aligned Pulse of 1000us and so on..
	//PWM Pulses in LPC1114 are Right-Aligned or "inverted"!
	const int numPulseWidths = 5;
	int count=1;
	int dir=0; //direction, 0 = Increasing, 1 = Decreasing

	init32BTMR0_PWM(); //Initialize 32Bit-TMR0 as PWM
	init16BTMR0(); //Used by delayMS()

	while(1)
	{
		updatePulseWidth(pulseWidths[count]); //Update LED Pulse Width
		delayMS(1000);

		if(count == (numPulseWidths-1) || count == 0)
		{
			dir = !dir; //Toggle direction if we have reached count limit
		}

		if(dir) count--;
		else count++;
	}
  //return 0; //normally this won't execute ever
}

void init32BTMR0_PWM(void)
{
	/*Assuming CCLK (System Clock) = 48Mhz (set by startup code)*/
	LPC_SYSCON->SYSAHBCLKCTRL |= (1<<9); //Enable 32Bit-TMR0 Clock
	LPC_TMR32B0->CTCR = 0x0;
	LPC_TMR32B0->PR = PRESCALE_US; //Increment TC at every 47999+1 clock cycles
	//48000 clock cycles @48Mhz = 1 mS
	LPC_TMR32B0->MR3 = PWM_PERIOD; //20ms Period duration
	LPC_TMR32B0->MR0 = PWM_PERIOD-1250; //Default TOFF time in mS
	LPC_TMR32B0->MCR = (1<<10); //Reset on MR3 Match

	LPC_TMR32B0->PWMC = 0x1; //Enable PWM Mode for MAT0.0

	LPC_TMR32B0->TCR = 0x2; //Reset Timer
	LPC_TMR32B0->TCR = 0x1; //Enable timer
}

inline void updatePulseWidth(unsigned int pulseWidth)
{
	LPC_TMR32B0->MR0 = pulseWidth; //Update MR1 with new value
}

void delayMS(unsigned int milliseconds) //Using 16B-TMR0
{
	LPC_TMR16B0->TCR = 0x2; //Reset Timer
	LPC_TMR16B0->TCR = 0x1; //Enable timer

	while(LPC_TMR16B0->TC < milliseconds); //wait until timer counter reaches the desired delay

	LPC_TMR16B0->TCR = 0x0; //Disable timer
}

void init16BTMR0(void)
{
	/*Assuming CCLK (System Clock) = 48Mhz (set by startup code)*/
	LPC_SYSCON->SYSAHBCLKCTRL |= (1<<7); //Enable 16Bit-TMR0 Clock
	LPC_TMR16B0->CTCR = 0x0;
	LPC_TMR16B0->PR = PRESCALE_MS; //Increment TC at every 47999+1 clock cycles
	//48000 clock cycles @48Mhz = 1 mS
	LPC_TMR16B0->TCR = 0x2; //Reset Timer
}
</code></pre>
<div class="highlight"><strong>KEIL ARM uV5 Project for Example #2 on GitHub @</strong> <a href="https://github.com/OCFreaks/LPC1114-Tutorial-Examples/tree/master/MCUXpresso/PWM/Example_2" target="_blank">PWM Example 2 Source</a> [Successfully tested on Keil uV5.23], <strong>Download Project Zip</strong> @ <a href="https://minhaskamal.github.io/DownGit/#/home?url=https://github.com/OCFreaks/LPC1114-Tutorial-Examples/tree/master/MCUXpresso/PWM/Example_2" target="_blank">Example_2.Zip</a></div>
<p>The post <a href="https://www.ocfreaks.com/lpc1114-pwm-programming-tutorial/">LPC1114 PWM Programming Tutorial</a> appeared first on <a href="https://www.ocfreaks.com">OCFreaks!</a>.</p>
]]></content:encoded>
					
					<wfw:commentRss>https://www.ocfreaks.com/lpc1114-pwm-programming-tutorial/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
		<post-id xmlns="com-wordpress:feed-additions:1">2911</post-id>	</item>
		<item>
		<title>LPC1768 UART Programming Tutorial</title>
		<link>https://www.ocfreaks.com/lpc1768-uart-programming-tutorial/</link>
					<comments>https://www.ocfreaks.com/lpc1768-uart-programming-tutorial/?noamp=mobile#respond</comments>
		
		<dc:creator><![CDATA[Umang Gajera]]></dc:creator>
		<pubDate>Thu, 28 Sep 2017 20:12:07 +0000</pubDate>
				<category><![CDATA[Embedded]]></category>
		<category><![CDATA[lpc1768]]></category>
		<category><![CDATA[tutorial]]></category>
		<guid isPermaLink="false">http://www.ocfreaks.com/?p=2906</guid>

					<description><![CDATA[<p>In this discussion we will go through ARM Cortex-M3 LP1768 UART programming Tutorial. It is also applicable to for other MCUs of LPC17xx family like LPC1769.</p>
<p>The post <a href="https://www.ocfreaks.com/lpc1768-uart-programming-tutorial/">LPC1768 UART Programming Tutorial</a> appeared first on <a href="https://www.ocfreaks.com">OCFreaks!</a>.</p>
]]></description>
										<content:encoded><![CDATA[<p class="tocpostimage">In this discussion we will go through ARM Cortex-M3 LP1768 UART programming Tutorial. It is also applicable to for other MCUs of LPC17xx family like LPC1769. If you are new to UART, you can go through the basic UART tutorial which I&#8217;ve posted @ <a href="https://www.ocfreaks.com/uart-tutorial-basics/">Basic Uart Tutorial</a>.</p>
<div class="toc_container">
<span class="toc_title">Table of Contents</span></p>
<div class="toc">
<ol class="toc_list">
<li class="toc_text"><a href="#UART_Block"><span>LPC1768 UART Block</span></a></li>
<li class="toc_text"><a href="#UART_Registers"><span>LPC176x UART Registers</span></a></li>
<li class="toc_text"><a href="#Baud_Calc"><span>UART Baud Rate Calculation</span></a></li>
<li class="toc_text"><a href="#Config_Init"><span>How to Configure and Initialize UART</span></a></li>
<li class="toc_text"><a href="#UART_Connections"><span>Connections between MCU and PC or Laptop</span></a></li>
<li class="toc_text"><a href="#UART_Examples"><span>UART Examples</span></a></li>
<ol class="toc_list">
<li class="toc_text"><a href="#Example_1"><span>LPC1768 UART Example 1</span></a></li>
<li class="toc_text"><a href="#Example_2"><span>LPC1768 UART Example 2</span></a></li>
</ol>
</ol>
</div>
</div>
<h4>UART basics revisited</h4>
<p>Uart uses TxD(Transmit) Pin for sending Data and RxD(Receive) Pin to get data. UART sends &#038; receives data in form of chunks or packets. These chunks or packets are also referred to as ‘Frames’. While sending Data, LSB(i.e. Data Bit 0) is transmitted First and MSB is transmitted Last. The structure of a UART Packet/Frame using 1 stop bit is as shown below:</p>
<p><img decoding="async" class="aligncenter" src="https://www.ocfreaks.com/imgs/embedded/common/uart_packet_format.png" alt="Uart Packet Frame Format Structure" width="320px" height="140px" /></p>
<p>Here is an example of single Packet/Frame using 8 data bits, even parity and 1 stop bit:</p>
<p><img decoding="async" class="aligncenter" src="https://www.ocfreaks.com/imgs/embedded/common/uart_packet_example.png" alt="Example of a single UART data Packet Frame" width="500px" height="175px" /></p>
<h2 class="shead" id="UART_Block">LPC1768 UART Block</h2>
<p>Now, Lets start with the main Tutorial. ARM Cortex-M3 LPC176x has 4 UART blocks which are UART0 to UART3. UART0/2/3 are identical. UART1 additionally supports Full modem control handshaking &#038; RS-485. Refer Datasheet for more info. After reset UART0 &#038; UART1 are enabled by default. TxD and RxD pins for these blocks are mapped on multiple pins.</p>
<table class="aligncenter" style="margin-bottom:20px">
<tr>
<td>Pins:</td>
<td><strong>TxD</strong></td>
<td><strong>RxD</strong></td>
</tr>
<tr>
<td>UART0</td>
<td> P0.2</td>
<td> P0.3</td>
</tr>
<tr>
<td>UART1</td>
<td> P0.15/P2.0</td>
<td> P0.16/P2.1</td>
</tr>
<tr>
<td>UART2</td>
<td> P0.10/P2.8</td>
<td> P0.11/P2.9</td>
</tr>
<tr>
<td>UART3</td>
<td> P0.0/P0.25/P4.28</td>
<td> P0.1/P0.26/P4.29</td>
</tr>
</table>
<p  style="margin-bottom:0px;">All UART blocks internally have a 16-byte FIFO (First In First Out) structure to hold data. Each byte in this FIFO represents a character which was sent or received <strong>in order</strong>. All blocks also contain 2 registers each, for data access and assembly as given below:</p>
<ul>
<li><strong>Tx has THR(Transmit Holding Register) and TSR(Transmit Shift Register)</strong> &#8211; When Tx Data is written to THR, it is then transferred to TSR which assembles the Transmit data.</li>
<li><strong>Similarly Rx has RSR(Receive Shift Register) and RBR(Receive Buffer Register)</strong> &#8211; When Data is Received at the Rx Pin, it is first assembled in RSR and then transferred into Rx FIFO which can be then accessed using RBR.</li>
</ul>
<div class="special sp_red noteinfo"> UART Pins on LPC176x are 5V tolerant. But I would recommend using 3.3v for UART communication. Hence, if you have RS232 to serial TTL module make sure it has MAX3232 =OR= if you are using FTDI&#8217;s FT232R based USB to serial TTL module make sure it is configured for 3.3v I/O.
</div>
<h2 class="shead" id="UART_Registers">LPC176x UART Registers used in programming</h2>
<p>Before we can use these pins to transfer data, first we need to configure and initialize the UART block in our LPC176x microcontroller. But before doing that, lets go through some of the important registers:</p>
<div class="highlight">
<h4><strong>Data Related Registers </strong></h4>
<p><strong>1) UxRBR &#8211; Receiver Buffer Register:</strong> This register contains the top most byte(8-bit data chunk) in the Rx FIFO i.e the oldest received data in FIFO. Before reading from UxRBR, the DLAB(Divisor Latch Access) bit in U0LCR register must be 0. As mentioned in user manual &#8220;The right approach for fetching the valid pair of received byte and its status bits is first to read the content of the U0LSR register, and then to read a byte from the U0RBR.&#8221;</p>
<p><strong>2) UxTHR &#8211; Transmit Holding Register:</strong> U0THR contains the top most byte in Tx FIFO and in this case its the newest(latest) transmitted data. As in the case with U0RBR , we must set DLAB=0 to access UxTHR for write operation.</p>
<h4><strong> Baud Rate Setup related registers </strong></h4>
<p><strong>1) UxDLL and UxDLM &#8211; Divisor Latch registers:</strong> Both of them hold 8-bit values. These register together form a 16-bit divisor value which is used in baud rate generation. UxDLM holds the upper 8-bits and U0DLL holds the lower 8-bits and the formation is &#8220;<strong>[U0DLM:U0DLL]</strong>&#8220;. Since these form a divisor value and division by zero is invalid, the starting value for U0DLL is 0x01 (and not 0x00). <strong>Please keep this in mind while doing baud-rate calculations. In order to access and use these registers properly, DLAB bit in UxLCR must be first set to 1</strong>. </p>
<p><strong>2) UxFDR &#8211; Fractional Divider Register :</strong> It is used to set the prescale value for baud rate generation. The input clock is the PCLK and output is the desired clock defined by this register. This register actually holds to different 4-bit values (a divisor and a multiplier) for prescaling which are:</p>
<ol>
<li><strong>Bit [3 to 0] &#8211; DIVADDVAL:</strong> This is the prescale divisor value. If this value if 0 then fractional baud rate generator wont have any effect on Uart Baud rate.</li>
<li><strong>Bit [7 to 4] &#8211; MULVAL:</strong> This is prescale multiplier value. Even if fractional baud rate generator is not used the value in this register must be more than or equal to 1 else UART0 will not operate properly.</li>
<li>Other Bits reserved.</li>
</ol>
<p>Remark from User-manual:&#8221; <strong>If the fractional divider is active (DIVADDVAL > 0) and DLM = 0, the value of the DLL register must be 2 or greater!</strong>&#8221;</p>
<h4><strong>Control and Status Registers</strong></h4>
<p><strong>1) UxFCR &#8211; FIFO Control Register: </strong>Used to control Rx/Tx FIFO operations.</p>
<ol>
<li><strong>Bit 0 &#8211; FIFO Enable:</strong> 1 to Enable both Rx and Tx FIFOs and 0 to disable.</li>
<li><strong>Bit 1 &#8211; Rx FIFO Reset:</strong> Writing a 1 will clear and reset Rx FIFO.</li>
<li><strong>Bit 2 &#8211; Tx FIFO Reset:</strong> Writing a 1 will clear and reset Tx FIFO.</li>
<li><strong>Bits [7 to 6]</strong>:</strong> Used to determine that how many Rx FIFO characters must be written before an interrupt is activated.</li>
<li>Others bits are reserved.</li>
</ol>
<p><strong>2) UxLCR &#8211; Line Control Register :</strong> Used to configure the UART block (i.e the data format used in transmission).</p>
<ol>
<li><strong>Bit [1 to 0] &#8211; Word Length Select:</strong> Used to select the length of an individual data chunk. [00] for 5 bit character length. Similarly [01] , [10] , [11] for 6 , 7 , 8 bit character lengths respectively.</li>
<li><strong>Bit 2 &#8211; Stop bit select:</strong>  0 for using 1 stop bit and 1 for using 2 stop bits.</li>
<li><strong>Bit 3 &#8211; Parity Enable:</strong> 0 to disabled Partiy generation &#038; checking and 1 to enable it.</li>
<li><strong>Bit [5 to 4] &#8211; Parity Select:</strong> [00] to Odd-parity , [01] for Even-parity , [10] for forced &#8220;1&#8221;(Mark) parity  and [11] for forced &#8220;0&#8221;(Space) parity.</li>
<li><strong>Bit 6 &#8211; Break Control:</strong> 0 to disable break transmission and 1 to enable it. TxD pin will be forced to logic 0 when this bit is 1!</li>
<li><strong>Bit 7 &#8211; Divisior Latch Access bit:</strong> 0 to disable access to divisor latches and 1 to enable access.</li>
</ol>
<p><strong>3) UxLSR &#8211; Line Status Register:</strong> used to read the status of Rx and Tx blocks. Bits 1 to 4 get cleared after reading UxLSR.</p>
<ol>
<li><strong>Bit 0 &#8211; Receiver Data Ready(RDR):</strong> 0 means UxRBR is empty(i.e Rx FIFO is empty) and 1 means UxRBR contains valid data.</li>
<li><strong>Bit 1 &#8211; Overrun Error(OE):</strong> 1 means Overrun has occured, 0 otherwise. Overrun is the condition when RSR(Receive Shift Register) has new character assembled but the RBR FIFO is full and the new assembled character was eventually lost since no data is written into FIFO when its full.</li>
<li><strong>Bit 2 &#8211; Parity Error(PE):</strong> 1 means a parity error has occured else not. When the value of the parity bit in the recieved character is in wrong state then a parity error occurs.</li>
<li><strong>Bit 3 &#8211; Framing Error(FE):</strong> 1 means that a framing error has taken place else not. Framing error occurs when the stop bit of a received character is zero.</li>
<li><strong>Bit 4 &#8211; Break Interrupt:</strong> 1 means that it has occured else not. A Break Interrupt occurs when the RxD line is pulled low (i.e all 0s) i.e held in spacing state for 1 full character after which Rx Block goes into Idle state. Rx Block gets back to active state when RxD pin is pulled high (i.e all 1s) i.e held in marking state for 1 full character.</li>
<li><strong>Bit 5 &#8211; Transmit Holding Register Empty(THRE):</strong> 0 means UxTHR has valid data and 1 means its empty.</li>
<li><strong>Bit 6 &#8211; Transmitter Empty(TEMT):</strong> 0 means UxTHR and/or UxRSR has valid data and 1 means that both UxTHR and UxRSR are empty.</li>
<li><strong>Bit 7 &#8211; Error in RX FIFO(RXFE):</strong> 0 means that UxRBR has no Rx Errors or Rx FIFO is disabled(i.e 0th bit in U0FCR is 0) and 1 means that UxRBR has at-least one error.	<strong>Note:</strong> This bit is cleared only if UxLSR is read and there are no other subsequent errors in Rx FIFO, else this bit will stay 1</li>
</ol>
<p><strong>4) UxTER &#8211; Transmit Enable Register: </strong>This register is used to enable UART transmission. When bit-7 (i.e TXEN) is set to 1 Tx block will be enabled and will keep on transmitting data as soon as its ready. If bit-7 is set to 0 then Tx will stop transmission. Other bits are reserved.</p>
<h4><strong> Interrupt Related Registers</strong></h4>
<p><strong>1) UxIER &#8211; Interrupt Enable Register:</strong> Set a bit to 0 to disable and 1 to enable the corresponding interrupt. Other bits are reserved.</p>
<ol>
<li><strong>Bit 0</strong> &#8211; RBR Interrupt Enable </li>
<li><strong>Bit 1 </strong>&#8211; THRE Interrupt Enable</li>
<li><strong>Bit 2</strong> &#8211; RX Line Status Interrupt Enable</li>
<li><strong>Bit 8</strong> &#8211; ATEOInt (End of Auto Baud Interrupt) Enable</li>
<li><strong>Bit 9</strong> &#8211; ATBOInt (Auto Baud Time-Out Interrupt) Enable </li>
</ol>
<p><strong>2) UxIIR &#8211; Interrupt Identification Register:</strong> This register is organized as follows:</p>
<ol>
<li><strong>Bit 0 &#8211; Interrupt Pending :</strong> 0 means at-least one interrupt is pending, 1 means no interrupts are pending. Note: This bit is ACTIVE LOW!</li>
<li><strong>Bits [3 to 1] &#8211; Interrupt Identification :</strong> [011] implies Receive Line Status(RLS) , [010] implies Receive Data Available(RDA) , 110 implies Character Time-out Indicator(CTI) , [001] implies THRE Interrupt.</li>
<li><strong>Bits [7 to 6] &#8211; FIFO Enable.</strong></li>
<li><strong>Bit 8 &#8211; ABEOInt :</strong> 1 means Auto Baud Interrupt has successfully ended and 0 otherwise.</li>
<li><strong>Bit 9 &#8211; ABTOInt :</strong> 1 means Auto Baud Interrupt has Timed-out.</li>
<li>All others bits are reserved.</li>
</ol>
</div>
<h2 class="shead" id="Baud_Calc">UART Baud Rate Calculations</h2>
<div class="special sp_blue notestar">
<h4>The main formula for calculating baud rate is given as: </h4>
<div class="equation" style="font-size:14px;">Baud</sub> =</p>
<div class="fraction"><span class="fup">PCLK in Hertz</span><span class="bar">/</span><span class="fdn">16 x (256xDLM + DLL) x (1 + DIVADDVAL/MULVAL)</span></div>
</div>
<p>Where DIVADDVAL &#038; MULVAL are part of &#8220;Fractional Rate Divider&#8221; or &#8220;Baud-Prescaler&#8221; which is used in Baud-Rate generation. This &#8220;Fractional Divider&#8221; is only active when DIVADDVAL > 0. This formula is pretty common for LPC ARM micro-controllers.</p>
<p><strong>which can be further simplified to :</strong></p>
<div class="equation" style="font-size:14px;">Baud</sub> =</p>
<div class="fraction"><span class="fup">MULVAL</span><span class="bar">/</span><span class="fdn">MULVAL + DIVADDVAL</span></div>
<p>X</p>
<div class="fraction"><span class="fup">PCLK in Hertz</span><span class="bar">/</span><span class="fdn">16 x (256xDLM + DLL)</span></div>
</div>
<p style="margin-bottom:0px">with following conditions strictly applied:</p>
<ul style="margin-bottom:5px">
<li>0 < MULVAL <= 15 
<li>0 <= DIVADDVAL <= 14 - if DIVADDVAL > 0 &#038; DLM = 0 then, DLL must be >= 2 
<li>DIVADDVAL < MULVAL</li>
</ul>
<p>Where PCLK is the Peripheral Clock value in Hz , DLM and DLL are the divisor registers which we saw earlier and finally DIVADDVAL and MULVAL are part of the Fractional baudrate generator register.</p>
<p>As it can been seen this formula has 2 prominent parts which are: A <strong>Base value</strong> and a <strong>Fraction Part(Prescaler) </strong> i.e:</p>
<div class="equation">BaudRate = [ Fraction Part (Prescaler) ] x [ Base ]</div>
<p>This Fraction Part i.e. the Fractional Divider or the &#8220;Baud Rate Prescaler&#8221; can be used to scale down or keep the base value as it is (when disabled). Hence, its very useful for fine-tuning and getting the baudrate as accurate as possible.  </p>
</div>
<div class="special sp_red notestar"> <strong>Note</strong>: In real world there are very less chances that you will get the actual baudrate same as the desired baudrate. In most cases the actual baudrate will drift a little above or below the desired baud and also, as the desired baudrate increases this drift or error will also increase &#8211; this is because of the equation itself and the limitations on MULVAL , DIVADDVAL! For e.g. if the desired baud rate is 115200 and depends on the variables you may get a bauds like 114300, 115470, 116050 .. and so on. But in almost all cases it will work as required if the error is not significant. A small amount of error in actual baudrate is generally tolerable in most systems which must be <strong><1.1% (relative error)</strong>.</div>
<p><strong>Now we know the formula, how we do actually start ?</strong></p>
<h4>1) The Dirty and Simplest Method: </h4>
<p>The quickest and also the dirtiest(accuracy wise) method without using any algorithm or fine-tuning is to set DLM=0 and disable the Fractional Divider. In this case MULVAL=1 and DIVADDVAL=0 which makes the Fraction Part(FP) = 1. Now we are left with only 1 unknown in the equation which is UxDLL and hence we simplify the equation and solve for UxDLL.</p>
<div class="equation">UxDLL</sub> =</p>
<div class="fraction"><span class="fup">PCLK in Hertz</span><span class="bar">/</span><span class="fdn">16 x Desired-BaudRate</span></div>
</div>
<p>In my opinion, if possible, you must stay away from above method as it works only for particular bauds &#038; specific PCLK value and moreover computed UxDLL might get out of range i.e. > 255 in which case you have to start increasing DLM and recompute a new value for DLL.</p>
<h4>2) A better Method/Algorithm (Recommended): </h4>
<p>In these method we again start with DLM=0 , DIVADDVAL=0(i.e. Fractional divider disabled) and MULVAL=1 and get an initial value for DLM. If you are lucky you will get a very close baudrate to the desired one. If not then we perform some fine-tuning using DLM, MULVAL and DIVADDVAL and get a new value for DLM. There is on one single method to perform fine-tuning and one can also make an algorithm for computing the best match given the desired baudrate and PCLK. The fine-tuning method or Algorithm which I have given below is a basic one suitable for beginners(in my opinion though). A more invloved Iterative Algorithm is given on Page 324(Rev 4.1) of the user manual.</p>
<div class="highlight">
<h4>Example: PCLK = 25 Mhz and Required Baud Rate is 115200 bauds.</h4>
<p>Lets start with<strong> DLM = 0 , DIVADDVAL = 0 and MULVAL = 1<br />
We have PCLK = 25 Mhz = 25 x 10<sup>6</sup> Hz</strong></p>
<p>So the equation now gets simplified and we can find DLL.</p>
<p>We get <strong>UxDLL  = 13.56</strong>, since it must be an integer we round it to <strong>14</strong>. With <strong>UxDLL = 14</strong> our actual baud rate will be <strong>= 111607.14</strong> with a error of 3592.86(magnitude) which gives a relative error of <strong>3.11%</strong>. Since its greater than 1.1% error specification we cannot use this. Now all we have to do is to get this error as low as possible. This can be done by multiplying it by a suitable fraction defined using MULVAL and DIVADDVAL &#8211; as given in equation. But since MULVAL &#038; DIVADDVAL can be maximum 15 &#038; 14 receptively, we don&#8217;t have much control over the Fraction Part(FP) value.</p>
<p>First lets compute the Required Fraction Part(FP) value given by <strong>FP<sub>required</sub> = [Desired Baud / Actual Baud Rate]</strong>. In our case its <strong>FP<sub>required</sub> = 1.032</strong>. Note that this is the required &#8220;Baud Prescaler&#8221; value that needs to be multiplied by Base value we got above to bring back it to ~115200. Now we have a problem &#8211; the max value for the Fractional part is 1(When Fractional Divider is disabled), but in this case we need an upscaling value which is not possible. Only downscaling is possible(when Fractional Divider is Enabled). So what do we do now? Well, a few approaches can be used. One of the simple approach is to decrease the computed DLL value so that our final baudrate overshoots i.e. we get a positive error. So, then we can try to scale it down using Fractional Part (i.e. MULVAL and DIVADDVAL) to get near to desired baud rate.</p>
<p>Lets set <strong>UxDLL = 12</strong>. We now get new baud rate <strong>= 130208.33</strong> with error = +15008.33 from 115200. Now, we have <strong>FP<sub>required</sub> = 0.8847</strong>. We must try to get Fractional Part of equation as close as possible to 0.8847. The closest possible Fraction to 0.8847 is <strong>FP = 0.8823</strong> which is when <strong>MULVAL=15 and DIVADDVAL=2</strong>. So, multiplying that with computed baud we get: <strong>[Base] x [Fraction Part(FP)] = 130208.33 x 0.8823 = 114882.8 ~ 114882</strong> which is pretty bang on with an error of 318(magnitude) i.e. <strong>0.27%</strong> Relative Error that is well with in 1.1% spec. Hence, we can use the following settings:</p>
<p><strong>PCLK = 25 MHz<br />
U0DLL = 12<br />
U0DLM = 0<br />
MULVAL = 15<br />
DIVADDVAL = 2</strong>
</div>
<div class="special sp_blue noteinfo">Some of the standard Baud rates that can be used are: 2400, 4800, 7200, 9600, 14400, 19200, 28800, 38400, 57600, 115200, 230400, etc..  </div>
<h2 class="shead" id="Config_Init">How to Configure and Initialize UART</h2>
<p>Once you know how UART communication works, configuring and initializing UART is pretty straight forward. In Source Code Examples for this tutorial we will use UART0 with following configuration:</p>
<ul>
<li>BaudRate = 115200 (with PCLK=25Mhz)</li>
<li>Data Length = 8 bits</li>
<li>No Parity Bit</li>
<li>and 1 Stop Bit</li>
</ul>
<p><strong>Note: Its your responsibility to make it sure that configuration is same on both the communicating ends.</strong></p>
<p>As seen in example above: in order to get 115200(114882 actually) bauds at 25Mhz PCLK we must use the following settings for baud generation :</p>
<div class="highlight">
<strong>U0DLL = 12 ; U0DLM = 0 ; MULVAL = 15 ; DIVADDVAL = 2</strong>
</div>
<p>Now, lets write a function &#8220;<strong>InitUART0()</strong>&#8221; which we can use initialize and configure UART0:</p>
<pre><code class="language-cpp">
#define MULVAL      14
#define DIVADDVAL   2
#define Ux_FIFO_EN  (1<<0)
#define Rx_FIFO_RST (1<<1)
#define Tx_FIFO_RST (1<<2)
#define DLAB_BIT    (1<<7)
void InitUART0(void)
{
	LPC_PINCON->PINSEL0 |= (1<<4) | (1<<6); //Select TXD0 and RXD0 function for P0.2 &#038; P0.3!
	//LPC_SC->PCONP |= 1<<3; //Power up UART0 block. By Default it is enabled after RESET.

	LPC_UART0->LCR = 3 | DLAB_BIT ; /* 8 bits, no Parity, 1 Stop bit & DLAB set to 1  */
	LPC_UART0->DLL = 12;
	LPC_UART0->DLM = 0;
	
	//LPC_UART0->IER |= ..; //Edit this if want you to use UART interrupts
	LPC_UART0->FCR |= Ux_FIFO_EN | Rx_FIFO_RST | Tx_FIFO_RST;
	LPC_UART0->FDR = (MULVAL<<4) | DIVADDVAL; /* MULVAL=15(bits - 7:4) , DIVADDVAL=2(bits - 3:0)  */
	LPC_UART0->LCR &= ~(DLAB_BIT);
	//Now since we have applied DLL and DLM we now lock or freeze those valuse by diabling DLAB i.e DLAB=0 
	//Baud= ~115200(114882). Now we can perform UART communication!
}
</code></pre>
<p>Once this is done you are now ready to transfer data using U0RBR and U0THR registers.</p>
<h2 class="shead" id="UART_Connections">Connections between MCU and PC or Laptop</h2>
<p>Here we can have 2 possible scenarios.</p>
<ol style="margin-bottom:0px;">
<li>Your PC/Laptop(older ones) already has a serial port. In this case you will need a RS232 to TTL converter.</li>
<li>Your PC/Laptop doesn&#8217;t have a serial port and you are using USB to Serial converter(FTDI ones, etc..).</li>
</ol>
<div class="highlight">If you are using a separate converter then in both cases the TTL side of the converter have to use a minimum of 3 pins for basic UART communication which are: TxD, RxD and GND. Connect your MCU RxD to TxD of converter and MCU TxD to RxD of converter. Finally connect GND on both sides. Make sure you module supports 3.3v voltage-levels.</div>
<p>Please refer to the connection diagrams &#038; terminal software configuration(and COM ports) as given in <a href="https://www.ocfreaks.com/uart-tutorial-basics/">Basic Uart Tutorial</a>.</p>
<p>Here is a configuration screenshot for  terminal software PuTTYtel which we will be using for examples :<br />
<img decoding="async" class="aligncenter" src="https://www.ocfreaks.com/imgs/embedded/common/puttytel_serial_config.png" alt="PuTTYtel UART,Serial Config" width="452px" height="343px" /></p>
<p><strong>Note</strong>: You can get PuTTYtel from <a href="http://www.chiark.greenend.org.uk/~sgtatham/putty/download.html">Here</a>. Direct download link: <a href="http://the.earth.li/~sgtatham/putty/latest/x86/puttytel.exe">Here</a>. You can also use other similar terminal software as well.</p>
<h2 class="shead" id="UART_Examples">LPC1768 UART Programming Examples</h2>
<p>Now its time to actually use UART in real life! Lets do some communication between your LPC1768(or similar MCU like LPC1769) MCU and PC/Laptop. Before we get into actual examples for LPC1768, first lets define 2 functions which will be used to Read and Write Data from UART block. The code is based on CMSIS which is the Base library for ARM Cortex Micrcontrollers.</p>
<h4>U0Read() &#8211; Read Data from UART0:</h4>
<pre><code class="language-cpp">
#define RDR (1<<0) //Receiver Data Ready
char U0Read(void)
{
	while(!(LPC_UART0->LSR & RDR)); //wait until any data arrives in Rx FIFO
	return LPC_UART0->RBR; 
}
</code></pre>
<h4>U0Write() &#8211; Write Data to UART0:</h4>
<pre><code class="language-cpp">
#define THRE (1<<5) //Transmit Holding Register Empty
void U0Write(char data)
{
	while(!(LPC_UART0->LSR & THRE)); //wait till the THR is empty
	//now we can write to the Tx FIFO
	LPC_UART0->THR = data;
}
</code></pre>
<h4 id="Example_1">LPC1768 UART Example 1</h4>
<p>This demo will print &#8220;Hello from LPC1768!&#8221; on a new line in Serial Terminal repeatedly. The code given below uses Carriage-Return + Line-Feed (i.e. CR+LF) as New-Line(Enter or &#8220;\n&#8221;) character. If you are using Terminal on Linux or MacOS to interfacing LPC176x then only use Line-Feed(LF) character for New-Line. </p>
<pre><code class="language-cpp">
/*(C) Umang Gajera - www.ocfreaks.com
More Embedded tutorials @ www.ocfreaks.com/cat/embedded
LPC1768 Basic UART Example 1 Source Code.
License : GPL.*/

#include &lt;lpc17xx.h&gt;

#define THRE        (1<<5) //Transmit Holding Register Empty
#define MULVAL      15
#define DIVADDVAL   2
#define Ux_FIFO_EN  (1<<0)
#define Rx_FIFO_RST (1<<1)
#define Tx_FIFO_RST (1<<2)
#define DLAB_BIT    (1<<7)
#define LINE_FEED   0x0A //LF, For Linux, MAC and Windows Terminals  
#define CARRIAGE_RETURN 0x0D //CR, For Windows Terminals (CR+LF).

void initUART0(void);
void U0Write(char data);

int main(void)
{
	//SystemInit(); //This already gets called by CMSIS Startup Code.
	char msg[] = { 'H','e','l','l','o',' ','f','r','o','m',' ','L','P','C','1','7','6','8','\0' }; 
	int count=0;
	 
	initUART0();
	
	while(1)	
	{
		while( msg[count]!='\0' )
		{
			U0Write(msg[count]);
			count++;
		}
		//Send NEW Line Character(s) i.e. "\n"
		U0Write(CARRIAGE_RETURN); //Comment this for Linux or MacOS
		U0Write(LINE_FEED); //Windows uses CR+LF for newline.
		count=0; // reset counter		
	}
	//return 0; //This won't execute normally
}

void U0Write(char txData)
{
	while(!(LPC_UART0->LSR & THRE)); //wait until THR is empty
	//now we can write to Tx FIFO
	LPC_UART0->THR = txData;
}

void initUART0(void)
{
	/*Assuming CCLK = 100Mhz and PCLK = 25Mhz!*/
	LPC_PINCON->PINSEL0 |= (1<<4) | (1<<6); //Select TXD0 and RXD0 function for P0.2 &#038; P0.3!
	//LPC_SC->PCONP |= 1<<3; //Power up UART0 block. By Default it is enabled after RESET.

	LPC_UART0->LCR = 3 | DLAB_BIT ; /* 8 bits, no Parity, 1 Stop bit & DLAB set to 1  */
	LPC_UART0->DLL = 12;
	LPC_UART0->DLM = 0;
	
	//LPC_UART0->IER |= ..; //Edit this if want you to use UART interrupts
	LPC_UART0->FCR |= Ux_FIFO_EN | Rx_FIFO_RST | Tx_FIFO_RST;
	LPC_UART0->FDR = (MULVAL<<4) | DIVADDVAL; /* MULVAL=15(bits - 7:4) , DIVADDVAL=2(bits - 3:0)  */
	LPC_UART0->LCR &= ~(DLAB_BIT);
	//Now since we have applied DLL and DLM we now lock or freeze those valuse by diabling DLAB i.e DLAB=0 
	//Baud= ~115200(114882). Now we can perform UART communication!
}
</code></pre>
<div class="highlight"><strong>KEIL ARM uV5 Project for Example #1 on GitHub @</strong> <a href="https://github.com/OCFreaks/LPC1768-Tutorial-Examples/tree/master/UART/Example_1" target="_blank">Example 1</a> [Successfully tested on Keil uV5.23], <strong>Download Project Zip</strong> @ <a href="https://minhaskamal.github.io/DownGit/#/home?url=https://github.com/OCFreaks/LPC1768-Tutorial-Examples/tree/master/UART/Example_1" target="_blank">Example_1.Zip</a>. You can find the HEX file inside objects folder.</div>
<h4 id="Example_2">LPC1768 UART Example 2</h4>
<p>In this example you will see the characters that you type on your keyboard i.e. we echo back the characters(data) received by MCU. Serial Terminals only displays the character that it receives via serial Port. When you type a character it is directly sent to the other side via serial port. Hence, in order for us to see the character which we typed, we need to send back the same character. This is what the program below does. Whenever MCU receives a character from the RXD0 pin, it will send the same character back to PC via the TXD0 Pin and it gets displayed in Terminal.</p>
<p>Here is a <strong>snippet</strong> of Example 2: (Full source code given is in KEIL ARM project files &#8211; attached below)</p>
<pre><code class="language-cpp">
/*(C) Umang Gajera - www.ocfreaks.com
More Embedded tutorials @ www.ocfreaks.com/cat/embedded/
LPC1768 Basic UART Example 2 Source Code.
License: GPL.*/

#include &lt;lpc17xx.h&gt;

#define RDR         (1<<0) //Receiver Data Ready
#define THRE        (1<<5) //Transmit Holding Register Empty
#define MULVAL      15
#define DIVADDVAL   2
#define Ux_FIFO_EN  (1<<0)
#define Rx_FIFO_RST (1<<1)
#define Tx_FIFO_RST (1<<2)
#define DLAB_BIT    (1<<7)
#define LINE_FEED   0x0A //LF, For Linux, MAC and Windows Terminals  
#define CARRIAGE_RETURN 0x0D //CR, For Windows Terminals (CR+LF).
#define ENTER       CARRIAGE_RETURN //Ascii value/code for Enter is 0x0D i.e. CR

void initUART0(void);
char U0Read(void);
void U0Write(char data);

int main(void)
{
	initUART0();
	char data = 0;
	
	while(1)		
	{
		data = U0Read(); //Read Data from Rx
		if(data == ENTER) //Check if user pressed Enter key
		{
			//Send NEW Line Character(s) i.e. "\n"
			U0Write(CARRIAGE_RETURN); //Comment this for Linux or MacOS
			U0Write(LINE_FEED); //Windows uses CR+LF for newline.
		}
		else
		{
			U0Write(data); //Tx Read Data back
		}
	}
	//return 0; //Normally this won't execute
}

char U0Read(void)
{
	while(!(LPC_UART0->LSR & RDR)); //wait until data arrives in Rx FIFO
	return LPC_UART0->RBR;
}
</code></pre>
<div class="highlight"><strong>KEIL ARM uV5 Project for Example #2 on GitHub @</strong> <a href="https://github.com/OCFreaks/LPC1768-Tutorial-Examples/tree/master/UART/Example_2" target="_blank">Example 1</a> [Successfully tested on Keil uV5.23], <strong>Download Project Zip</strong> @ <a href="https://minhaskamal.github.io/DownGit/#/home?url=https://github.com/OCFreaks/LPC1768-Tutorial-Examples/tree/master/UART/Example_2" target="_blank">Example_2.Zip</a>. You can find the HEX file inside objects folder.</div>
<p>The post <a href="https://www.ocfreaks.com/lpc1768-uart-programming-tutorial/">LPC1768 UART Programming Tutorial</a> appeared first on <a href="https://www.ocfreaks.com">OCFreaks!</a>.</p>
]]></content:encoded>
					
					<wfw:commentRss>https://www.ocfreaks.com/lpc1768-uart-programming-tutorial/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
		<post-id xmlns="com-wordpress:feed-additions:1">2906</post-id>	</item>
		<item>
		<title>LPC1114 Timer Programming Tutorial</title>
		<link>https://www.ocfreaks.com/lpc1114-timer-programming-tutorial/</link>
					<comments>https://www.ocfreaks.com/lpc1114-timer-programming-tutorial/?noamp=mobile#respond</comments>
		
		<dc:creator><![CDATA[Umang Gajera]]></dc:creator>
		<pubDate>Mon, 25 Sep 2017 19:07:09 +0000</pubDate>
				<category><![CDATA[Embedded]]></category>
		<category><![CDATA[lpc1114]]></category>
		<category><![CDATA[tutorial]]></category>
		<guid isPermaLink="false">http://www.ocfreaks.com/?p=2900</guid>

					<description><![CDATA[<p>Table of Contents Introduction Registers used in LPC111x Timer Programming Configuring Timers in LPC1114 LPC1114 Timer Prescaler Calculation LPC1114 Timer Examples Blinky Example Match Output Example Timer Interrupt Example This time we will go through ARM Cortex-M0 LPC1114 Timer Tutorial. In a previous LPC1114 tutorial we did a blinky example using GPIO and harcoded delays, [&#8230;]</p>
<p>The post <a href="https://www.ocfreaks.com/lpc1114-timer-programming-tutorial/">LPC1114 Timer Programming Tutorial</a> appeared first on <a href="https://www.ocfreaks.com">OCFreaks!</a>.</p>
]]></description>
										<content:encoded><![CDATA[<p class="tocpostimage"><img decoding="async" style="margin-top:20px;"class="aligncenter" src="https://www.ocfreaks.com/imgs/lpc1114-tutorial/tmr_title.png" width="335px" height="140px" /></p>
<div class="toc_container">
<span class="toc_title">Table of Contents</span></p>
<div class="toc">
<ol class="toc_list">
<li class="toc_text"><a href="#Intro"><span>Introduction</span></a></li>
<li class="toc_text"><a href="#Timer_Register"><span>Registers used in LPC111x Timer Programming</span></a></li>
<li class="toc_text"><a href="#Configure_Timer"><span>Configuring Timers in LPC1114</span></a></li>
<ol class="toc_list">
<li class="toc_text"><a href="#Prescaler_Calc"><span>LPC1114 Timer Prescaler Calculation</span></a></li>
</ol>
<li class="toc_text"><a href="#Examples"><span>LPC1114 Timer Examples</span></a></li>
<ol class="toc_list">
<li class="toc_text"><a href="#Example_1"><span>Blinky Example</span></a></li>
<li class="toc_text"><a href="#Example_2"><span>Match Output Example</span></a></li>
<li class="toc_text"><a href="#Example_3"><span>Timer Interrupt Example</span></a></li>
</ol>
</ol>
</div>
</div>
<p>This time we will go through ARM Cortex-M0 LPC1114 Timer Tutorial. In a <a href="https://www.ocfreaks.com/lpc1114-gpio-programming-tutorial/" target="_blank">previous LPC1114 tutorial</a> we did a blinky example using GPIO and harcoded delays, now its time to improvise and use precise delay using timers. LPC111x MCUs have two 16-bit Timers and two 32-bit Timers. Both of them are similar in operation except for the bit size. We will be using 32-bit timers in this tutorial. Each Timer block can be used as a &#8216;Timer&#8217; (e.g. triggering an interrupt every &#8216;t&#8217; microseconds) or as a &#8216;Counter&#8217; and can be also used to demodulate PWM signals given as input, find frequency of external signal, etc.</p>
<h2 class="shead" id="Intro">Introduction</h2>
<p>Each Timer module has its own <strong>Timer Counter(TC)</strong> and <strong>Prescale Register(PR)</strong> associated with it. When a Timer is Reset and Enabled, the TC is set to 0 and incremented by 1 every <strong>&#8216;PR+1&#8217;</strong> clock cycles &#8211; where PR is the value stored in Prescale Register. When it reaches its maximum value it gets reset to 0 and hence restarts counting. Prescale Register is used to define the <strong>resolution</strong> of the timer. If <strong>PR is 0</strong> then TC is incremented every <strong>1 clock cycle of the peripheral clock</strong>. If <strong>PR=1</strong> then TC is incremented every <strong>2 clock cycles of peripheral clock and so on</strong>. By setting an appropriate value in PR we can make timer increment or count: every peripheral clock cycle or 1 microsecond or 1 millisecond or 1 second and so on.</p>
<p>LPC1114/302 (LPC1100L Series) which is found on LPCXpresso Board has <strong>four Match Outputs</strong> and <strong>one Capture Input</strong>.</p>
<h4>Match Register</h4>
<p>A Match Register is a Register which contains a specific value set by the user. When the Timer starts &#8211; every time after TC is incremented the value in TC is compared with match register. If it matches then it can Reset the Timer or can generate an interrupt as defined by the user. We are only concerned with match registers in this tutorial.</p>
<p style="margin-bottom:0px;"><strong>Match Registers can be used to:</strong></p>
<ul style="margin-bottom:10px;">
<li>Stop Timer on Match(i.e when the value in count register is same as than in Match register) and trigger an optional interrupt.</li>
<li>Reset Timer on Match and trigger an optional interrupt.</li>
<li>
To count continuously and trigger an interrupt on match.</li>
</ul>
<h4>External Match Output</h4>
<p>When a corresponding Match register(MRx) equals the Timer Counter(TC) the match output can be controlled using External Match Register(EMR) to : either toggle, go HIGH, go LOW or do nothing.</p>
<h4>Capture Register</h4>
<p>As the name suggests it is used to Capture Input signal. When a transition event occurs on a Capture pin , it can be used to copy the value of TC into any of the 4 Capture Register or to genreate an Interrupt. Hence these can be also used to demodulated PWM signals. We are not going to use them in this tutorial since we are only concerned with using Timer block as a &#8216;Timer&#8217;. We&#8217;ll see them in a later tutorial.</p>
<div class="special sp_blue noteinfo"><strong>Naming Conventions used in this Tutorial</strong>: <strong>CT32Bx</strong> and <strong>TMR32Bx</strong> both are same and refer to 32-Bit Timer &#8216;<strong>x</strong>&#8216;. E.g. CT32B0 and TMR32B0 refer to 32-bit Timer 0. <strong>CT32Bx_MATn</strong> refers to Match output &#8216;<strong>n</strong>&#8216; for 32bit Timer &#8216;<strong>x</strong>&#8216;. These are the naming conventions used in the Datasheet and User Manual of LPC11xx.</div>
<h2 class="shead" id="Timer_Register">Registers used in LPC111x Timer Programming</h2>
<p>We will be using CMSIS based <span class="code_var">lpc11xx.h</span> header file for programming. In CMSIS, all the Registers used to program and use 32-bit timers are defined as members of structure(pointer) <span class="code_var">LPC_TMR32Bx</span> where x is the 32-bit Timer module 0 or 1. So for Timer0 we will use <span class="code_var">LPC_TMR32B0</span> and so on. Registers can be accessed by de-referecing the pointer using &#8220;->&#8221; operator. For, example we can access TCR of Timer0 block as <span class="code_var">LPC_TMR32B0->TCR</span>. Similary for 16-bit Timer block, the structure is defined as  <span class="code_var">LPC_TMR16Bx</span> where x is the 16-bit Timer module 0 or 1. Now lets see some of the main 32-bit timer registers.</p>
<div class="highlight">
<p style="margin-bottom:15px;"><strong>1) <span class="doc_ref">PR (TMR32BxPR)</span>: Prescale Register</strong> &#8211; Stores the maximum value of Prescale counter after which it is reset.</p>
<p><strong>2) <span class="doc_ref">PC (TMR32BxPC)</span>: Prescale Counter Register</strong> &#8211; This register increments on every PCLK(Peripheral clock). This register controls the resolution of the timer. When PC reaches the value in PR , PC is reset back to 0 and Timer Counter is incremented by 1. Hence if PR=0 then Timer Counter Increments on every 1 PCLK. If PR=9 then Timer Counter Increments on every 10th cycle of PCLK. Hence by selecting an appropriate prescale value we can control the resolution of the timer. </p>
<p><strong>3) <span class="doc_ref">TC (TMR32BxTC)</span>: Timer Counter Register</strong> &#8211; This is the main counting register. Timer Counter increments when PC reaches its maximum value as specified by PR. If timer is not reset explicitly(directly) or by using an interrupt then it will act as a free running counter which resets back to zero when it reaches its maximum value which is 0xFFFFFFFF.</p>
<p><strong>4) <span class="doc_ref">TCR (TMR32BxTCR)</span>: Timer Control Register</strong> &#8211; This register is used to enable , disable and reset TC. When bit0 is 1 timer is enabled and when 0 it is disabled. When bit1 is set to 1 TC and PC are set to zero together in sync on the next positive edge of PCLK. Rest of the bits of TCR are reserved.</p>
<p><strong>5) <span class="doc_ref">CTCR  (TMR32BxCTCR)</span>: Count Control register</strong> &#8211; Used to select Timer/Counter Mode. When the value of the CTCR is set to 0x0 Timer Mode is selected.</p>
<p><strong>6) <span class="doc_ref">MCR (TMR32BxMCR)</span>: Match Control register</strong> &#8211; This register is used to control which all operations can be done when the value in MR matches the value in TC. Bits 0,1,2 are for MR0 , Bits 3,4,5 for MR1 and so on.. Here&#8217;s a quick table which shows the usage:</p>
<p><strong>For MR0:</strong></p>
<ul style="margin-bottom:0px;">
<li>Bit 0 : Interrupt on MR0 i.e. trigger an interrupt when MR0 matches TC. Interrupts are enabled when set to 1 and disabled when set to 0.</li>
<li>Bit 1 : Reset on MR0. When set to 1 , TC will be reset when it matched MR0. Disabled when set to 0.</li>
<li>Bit 2 : Stop on MR0. When set to 1 , TC &#038; PC will stop when MR0 matches TC.</li>
</ul>
<p><strong>Similarly bits 3-5 , 6-8 , 9-11 are for MR1 , MR2 , MR3 respectively.</strong></p>
<p><strong>7) <span class="doc_ref">IR (TMR32BxIR)</span>: Interrupt Register</strong> &#8211; It contains the interrupt flags for 4 match and 2 capture interrupts. Bit0 to bit3 are for MR0 to MR3 interrupts respectively. And similarly the next 2 for CR0 &#038; CR1 interrupts. when an interrupt is raised the corresponding bit in IR will be set to 1 and 0 otherwise. Writing a 1 to the corresponding bit location will reset the interrupt &#8211; which is used to acknowledge the completion of the corresponding ISR execution.</p>
<p><strong>8) <span class="doc_ref">EMR  (TMR32BxEMR)</span>: External Match Register</strong> &#8211; It provides both status and control of External Match Output Pins. First four bits are for EM0 to EM3. Next 8 bits are for EMC0 to EMC3 in pairs of 2.</p>
<ul style="margin-bottom:0px;">
<li>Bit 0 &#8211; EM0: External Match 0. When a match occurs between TC and MR0, depending on bits[5:4] i.e. EMC0 of this register, this bit can either toggle, go LOW, go HIGH, or do nothing. This bit is driven to MATx.0 where x=Timer number. </li>
<li>Similarly for Bits 1 (EM1), 2 (EM2) &#038; 3 (EM3).</li>
<li>Bits[5:4] &#8211; EMC0: External Match 0. The values in these bits select the functionality of EM0 as follows:
<ul style="margin-bottom:0px;margin-top:0px;">
<li>0x0 &#8211; Do nothing</li>
<li>0x1 &#8211; Clear the corresponding External Match output to 0 (MATx.m pin is LOW).</li>
<li>0x2 &#8211; Set the corresponding External Match output to 1 (MATx.m pin is HIGH).</li>
<li>0x3 &#8211; Toggle the corresponding External Match output.</li>
</ul>
</li>
<li>Similarly for Bits[7:6] &#8211; EMC1, Bits[9,8] &#8211; EMC2, Bits[11:10] &#8211; EMC3.</li>
</ul>
</div>
<h2 class="shead" id="Configure_Timer">Configuring Timers in LPC1114</h2>
<p>To use timers we need to first configure &#038; initialize them. We need to set appropriate values in <span class="doc_ref">CTCR</span>, <span class="doc_ref">IR</span>, <span class="doc_ref">PR</span> registers and reset <span class="doc_ref">PC</span>, <span class="doc_ref">TC</span> registers. Finally we assign <span class="doc_ref">TCR = 0x01</span> which enables the timer. </p>
<div class="highlight">I would recommend to use the following sequence for Setting up 32-bit Timers:</p>
<ol style="margin-bottom:0px">
<li>Enable Clock Input for the Timer Block using <span class="code_var">LPC_SYSCON->SYSAHBCLKCTRL</span> register</li>
<li>Set appropriate value in <span class="code_var">LPC_TMR32Bx->CTCR</span></li>
<li>Define the Prescale value in <span class="code_var">LPC_TMR32Bx->PR</span></li>
<li>Set Value(s) in Match Register(s) if required</li>
<li>Set appropriate value in <span class="code_var">LPC_TMR32Bx->MCR</span> if using Match registers / Interrupts</li>
<li>Reset Timer using <span class="code_var">LPC_TMR32Bx->TCR</span> &#8211; Which resets PR and TC</li>
<li>Set <span class="code_var">LPC_TMR32Bx->TCR</span> to <span class="code_var">0x01</span> to Enable the Timer when required</li>
<li>Reset <span class="code_var">LPC_TMR32Bx->TCR</span> to <span class="code_var">0x00</span> to Disable the Timer when required</li>
</ol>
</div>
<p><strong>Selecting Match Outputs:</strong> Match outputs for Timer0(CT32B0) and Timer1(CT32B1) is available as an alternate function on pins given below. Match output function must be selected using <a href="https://www.ocfreaks.com/lpc1114-lpc1343-lpc_iocon-register-tutorial/" target="_blank">IOCON registers</a> for the following pins:</p>
<ul style="margin-bottom:10px;">
<li>Timer0 MAT 0 (CT32B0_MAT0) &#8211; PIO1_6</li>
<li>Timer0 MAT 1 (CT32B0_MAT1) &#8211; PIO1_7</li>
<li>Timer0 MAT 2 (CT32B0_MAT2) &#8211; PIO0_1</li>
<li>Timer0 MAT 3 (CT32B0_MAT3) &#8211; PIO2_8</li>
<li>Timer1 MAT 0 (CT32B1_MAT0) &#8211; PIO1_1</li>
<li>Timer1 MAT 1 (CT32B1_MAT1) &#8211; PIO1_2</li>
<li>Timer1 MAT 2 (CT32B1_MAT2) &#8211; PIO1_3</li>
<li>Timer1 MAT 3 (CT32B1_MAT3) &#8211; PIO1_4</li>
</ul>
<p>You can go through my previous <a href="https://www.ocfreaks.com/lpc1114-lpc1343-lpc_iocon-register-tutorial/" target="_blank">tutorial on IOCON register</a> regarding its usage.</p>
<p><strong>Enabling System AHB Clock for Timer:</strong> The input clock for timers is from System AHB clock or simply the System Clock. The System Clock can be derived from the Main Clock using System AHB Clock Divider Register <span class="doc_ref">SYSAHBLKDIV</span>. System Clock for Peripherals like Timers needs to be enabled, before using them, by setting appropriate bits (1=enable, 0=disable) in System AHB Clock Control Register <span class="doc_ref">SYSAHBCLKCTRL</span> as given below:</p>
<ul>
<li>Bit 7 For 16-Bit Timer0 (CT16B0)</li>
<li>Bit 8 For 16-Bit Timer1 (CT16B1)</li>
<li>Bit 9 For 32-Bit Timer0 (CT32B0)</li>
<li>Bit 10 For 32-Bit Timer1 (CT32B1)</li>
</ul>
<div class="special sp_red noteinfo">Note: In LPC1114, the Timer block doesn&#8217;t have a dedicated input Clock Divider. The System Clock (CCLK) is directly given to Timer block. Hence for Timer, <strong>PCLK=CCLK</strong>. Other Peripherals like UART and SPI have their own dividers for clock inputs which is derived directly from Main Clock (MCLK). The default System Clock configured by Startup Code is 48Mhz.</div>
<div class="special sp_blue notestar">
<h4 id="Prescaler_Calc">LPC1114 Timer Prescaler Calculations:</h4>
<p>The delay or time required for 1 clock cycle when PCLK/CCLK(System Clock) = &#8216;X&#8217; Mhz is given by:</p>
<div class="equation">T<sub>PCLK</sub> =</p>
<div class="fraction"><span class="fup">1</span><span class="bar">/</span><span class="fdn">PCLK<sub>Hz</sub></span></div>
<p>=</p>
<div class="fraction"><span class="fup">1</span><span class="bar">/</span><span class="fdn">X * 10<sup>6</sup></span></div>
<p>Seconds</p></div>
<p>It is also the maximum resolution Timer block can provide at a given PCLK(CCLK) frequency of X Mhz. The general formula for Timer resolution at X Mhz PCLK(CCLK) and a given value for prescale (PR) is as given below:</p>
<div class="equation">T<sub>RES</sub> =</p>
<div class="fraction"><span class="fup">PR+1</span><span class="bar">/</span><span class="fdn">PCLK<sub>Hz</sub></sup></span></div>
<p> =</p>
<div class="fraction"><span class="fup">PR+1</span><span class="bar">/</span><span class="fdn">X * 10<sup>6</sup></span></div>
<p>Seconds</p></div>
<p>Hence, we get the <strong>Formula for Prescaler (PR) for required Timer resolution (T<sub>RES</sub> in Secs)</strong> at given <strong>PCLK(in Hz)</strong> frequency as:</p>
<div class="equation">PR = (PCLK<sub>Hz</sub> * T<sub>RES</sub>) &#8211; 1</div>
<div class="equation">PR = ((X * 10<sup>6</sup>) * T<sub>RES</sub>) &#8211; 1</div>
<p>Note that here, the resolution is also the time delay required to increment TC by 1.</p>
<p>Hence, Prescaler value for 1 micro-second resolution/ 1us time delay at 48 Mhz PCLK(CCLK) is,</p>
<div class="equation">PR<sub>1us</sub> = (48Mhz * 1uS) -1 = (48*10<sup>6</sup> * 10<sup>-6</sup>) -1 = 47</div>
<p>Prescale for 1 mS (milli-second) resolution at 48Mhz PCLK(CCLK) is,</p>
<div class="equation">PR<sub>1ms</sub> = (48Mhz * 1ms) -1 = (48*10<sup>6</sup> * 10<sup>-3</sup>) -1 = 47999</div>
</div>
<p>Now lets implement to basic function required for Timer Operation:<br />
<strong>1.</strong> <span class="code_var">void initTimer0(void);</span><br />
<strong>2.</strong> <span class="code_var">void delayMS(unsigned int milliseconds);</span> </p>
<h4>#1) initTimer0(void); [Used in Example #1] </h4>
<div class="special sp_red notestar">
<strong>Attention Plz! :</strong> This function is used to setup and initialize the Timer block. Timer blocks use System AHB Clock (CCLK) as their Input. In our case it is assumed that LPC1114 CPU Clock (CCLK) is set at 48Mhz. Note that this clock speed is default which is configured by startup/boot code.</p>
</div>
<pre><code class="language-cpp">
#define PRESCALE (48000-1)

void initTimer0(void)
{
	/*Assuming CCLK (System Clock) = 48Mhz (set by startup code)*/

	LPC_TMR32B0->CTCR = 0x0;
	LPC_TMR32B0->PR = PRESCALE; //Increment TC at every 47999+1 clock cycles
	//48000 clock cycles @48Mhz = 1 mS

	LPC_TMR32B0->TCR = 0x02; //Reset Timer
}
</code></pre>
<h4> #2) delayMS(unsigned int milliseconds); &#8211; LPC1114 Timer Delay Function </h4>
<pre><code class="language-cpp">
void delayMS(unsigned int milliseconds) //Using Timer0
{
	LPC_TMR32B0->TCR = 0x02; //Reset Timer

	LPC_TMR32B0->TCR = 0x01; //Enable timer

	while(LPC_TMR32B0->TC < milliseconds); //wait until timer counter reaches the desired delay

	LPC_TMR32B0->TCR = 0x00; //Disable timer
}
</code></pre>
<div class="spaced">
</div>
<h2 class="shead" id="Examples">Real World LPC1114 Timer Examples with sample code</h2>
<h4 id="Example_1"> Example 1) &#8211; LPC111x Blinky Example using Timer &#038; GPIO</h4>
<p>Now lets write a C/C++ blinky program which flashes an LED every half a second. Since 0.5 second = 500 millisecond we will invoke timer delay function &#8216;delayMS&#8217; as <span class="code_var">delayMS(500)</span>. The LED is connected to Pin PIO0_7.</p>
<pre><code class="language-cpp">
/*(C) Umang Gajera - www.ocfreaks.com 2011-17.
More Embedded tutorials @ www.ocfreaks.com/cat/embedded/
LPC1114 Basic Timer example. License: GPL.*/

#include &lt;lpc11xx.h&gt;

#define PRESCALE (48000-1) //48000 PCLK clock cycles to increment TC by 1 

void delayMS(unsigned int milliseconds);
void initTimer0(void);

int main(void)
{
	//SystemInit(); //called by Startup Code before main(), hence no need to call again.
	initTimer0(); //Initialize Timer0
	LPC_GPIO0->DIR = (1<<7); //Configure PIO0_7 as output

	while(1)
	{
		LPC_GPIO0->DATA = (1<<7); //Turn LED ON
		delayMS(500); //0.5 Second(s) Delay
		LPC_GPIO0->DATA = ~(1<<7); //Turn OFF LED
		delayMS(500);
	}
	//return 0; //normally this wont execute ever
}

void initTimer0(void)
{
	/*Assuming CCLK (System Clock) = 48Mhz (set by startup code)*/
	LPC_SYSCON->SYSAHBCLKCTRL |= (1<<9); //Enable 32Bit Timer0 Clock
	LPC_TMR32B0->CTCR = 0x0;
	LPC_TMR32B0->PR = PRESCALE; //Increment LPC_TMR32B0->TC at every 47999+1 clock cycles
	//48000 clock cycles @48Mhz = 1 mS
	LPC_TMR32B0->TCR = 0x02; //Reset Timer
}

void delayMS(unsigned int milliseconds) //Using Timer0
{
	LPC_TMR32B0->TCR = 0x02; //Reset Timer
	LPC_TMR32B0->TCR = 0x01; //Enable timer

	while(LPC_TMR32B0->TC < milliseconds); //wait until timer counter reaches the desired delay

	LPC_TMR32B0->TCR = 0x00; //Disable timer
}

</code></pre>
<div class="highlight"><strong>MCUXpresso Project for Example #1 on GitHub @</strong> <a href="https://github.com/OCFreaks/LPC1114-Tutorial-Examples/tree/master/MCUXpresso/Timer/LPC1114_Timer_Ex_1/" target="_blank">Example 1</a>, <strong>Download Project Workspace as Zip</strong> @ <a href="https://minhaskamal.github.io/DownGit/#/home?url=https://github.com/OCFreaks/LPC1114-Tutorial-Examples/tree/master/MCUXpresso/Timer" target="_blank">Timer_Ex_1_2_3.Zip</a>. <strong>Note:</strong> Source code for all examples will also work for KEIL ARM as well.</div>
<h4 id="Example_2"> Example 2) &#8211; LPC111x example code using Timer &#038; Match Outputs </h4>
<p>In this C/C++ Example we will use Match outputs 0 and 1 of 32-bit Timer 0 i.e. CT32B0_MAT0 and CT32B0_MAT1. CT32B0_MAT0 is pinned to PIO1_6(P1.6) and CT32B0_MAT1 pinned to PIO1_7(P1.7). You can connect LED to any of the Match ouput pin (PIO1_6 or PIO1_7) and see the code in action. Note that, on LPCXpresso 1114 Board PIO1_6 is marked as RXD and PIO1_7 is marked as TXD since these pin have UART alternate functions.</p>
<pre><code class="language-cpp">
/*(C) Umang Gajera - https://www.ocfreaks.com 2011-17.
More Embedded tutorials @ https://www.ocfreaks.com/cat/embedded/
LPC1114 Timer example 2. License: GPL.*/

#include &lt;lpc11xx.h&gt;

#define PRESCALE (48000-1) //48000 PCLK clock cycles to increment TC by 1 

void initTimer0(void);

int main (void)
{
	//SystemInit(); //called by Startup Code before main(), hence no need to call again.

	LPC_IOCON->PIO1_6 |= 0x2; //Select CT32B0_MAT0 function - Marked as TXD on LPCXpresso Board
	LPC_IOCON->PIO1_7 |= 0x2; //Select CT32B0_MAT1 function - Marked as RXD on LPCXpresso Board

	initTimer0(); //Initialize Timer0

	while(1)
	{
		//Idle loop
	}
	//return 0; //normally this won't execute
}

void initTimer0(void)
{
	/*Assuming CCLK (System Clock) = 48Mhz (set by startup code)*/
	LPC_SYSCON->SYSAHBCLKCTRL |= (1<<9); //Enable 32Bit Timer0 Clock
	LPC_TMR32B0->CTCR = 0x0;
	LPC_TMR32B0->PR = PRESCALE; //Increment LPC_TMR32B0->TC at every 47999+1 clock cycles
	//48000 clock cycles @48Mhz = 1 mS

	LPC_TMR32B0->MR0 = 500; //toggle time in mS
	LPC_TMR32B0->MCR = (1<<1); //Reset on MR0 Match
	LPC_TMR32B0->EMR |= (1<<7) | (1<<6) | (1<<5) | (1<<4); //Toggle Match output for MAT0.0(P2.5), MAT0.1(P2.6)

	LPC_TMR32B0->TCR = 0x02; //Reset Timer
	LPC_TMR32B0->TCR = 0x01; //Enable timer
}
</code></pre>
<div class="highlight"><strong>MCUXpresso Project for Example #2 on GitHub @</strong> <a href="https://github.com/OCFreaks/LPC1114-Tutorial-Examples/tree/master/MCUXpresso/Timer/LPC1114_Timer_Ex_2/" target="_blank">Example 2</a>, <strong>Download Project Workspace as Zip</strong> @ <a href="https://minhaskamal.github.io/DownGit/#/home?url=https://github.com/OCFreaks/LPC1114-Tutorial-Examples/tree/master/MCUXpresso/Timer" target="_blank">Timer_Ex_1_2_3.Zip</a>.</div>
<h4 id="Example_3"> Example 3) &#8211; LPC1114 Timer Interrupt Example Code </h4>
<p>Here we will use a timer interrupt function which will be called periodically to blink an LED. The Timer Interrupt Service Routine (ISR) will toggle PIO0_7(P0.7) every time it is called. If you are using C++ file then you will need to add <span class="code_var">extern &#8220;C&#8221;</span> before the ISR definition or C++ linker won&#8217;t be able to link it properly to generate finally binary/hex file. For C code this is not required. </p>
<div class="special sp_red noteinfo">
<strong>Note:</strong> Please take your time to go through &#8220;initTimer0()&#8221; function. Here I&#8217;ve setup LPC111x Timer Interrupt handler which gets triggered when value in TC equals the value in MR0. I will discuss Interrupts in an upcoming tutorial.</a> </div>
<pre><code class="language-cpp">
/*(C) Umang Gajera - https://www.ocfreaks.com
More Embedded tutorials @ https://www.ocfreaks.com/cat/embedded/
LPC1114 Timer example 3. License: GPL.*/

#include &lt;lpc11xx.h&gt;

#define PRESCALE (48000-1) //48000 PCLK clock cycles to increment TC by 1 

void initTimer0();

int main(void)
{
	//SystemInit(); //called by Startup Code before main(), hence no need to call again.
	LPC_GPIO0->DIR |= (1<<7); //set PIO0_7 as output
	initTimer0();

	while(1)
	{
		//Idle loop
	}
	//return 0; //normally this won't execute
}

void initTimer0(void)
{
	/*Assuming CCLK (System Clock) = 48Mhz (set by startup code)*/
	LPC_SYSCON->SYSAHBCLKCTRL |= (1<<9); //Enable 32Bit Timer0 Clock

	LPC_TMR32B0->CTCR = 0x0;
	LPC_TMR32B0->PR = PRESCALE; //Increment LPC_TMR32B0->TC at every 47999+1 clock cycles
	//48000 clock cycles @48Mhz = 1 mS

	LPC_TMR32B0->MR0 = 500; //Toggle Time in mS
	LPC_TMR32B0->MCR |= (1<<0) | (1<<1); // Interrupt &#038; Reset on MR0 match
	LPC_TMR32B0->TCR |= (1<<1); //Reset Timer0

	NVIC_EnableIRQ(TIMER_32_0_IRQn); //Enable timer interrupt

	LPC_TMR32B0->TCR = 0x01; //Enable timer
}

extern "C" void TIMER32_0_IRQHandler(void) //Use extern "C" so C++ can link it properly, for C it is not required
{
	LPC_TMR32B0->IR |= (1<<0); //Clear MR0 Interrupt flag
	LPC_GPIO0->DATA ^= (1<<7); //Toggle LED
}

</code></pre>
<div class="highlight"><strong>MCUXpresso Project for Example #1 on GitHub @</strong> <a href="https://github.com/OCFreaks/LPC1114-Tutorial-Examples/tree/master/MCUXpresso/Timer/LPC1114_Timer_Ex_3/" target="_blank">Example 3</a>, <strong>Download Project Workspace as Zip</strong> @ <a href="https://minhaskamal.github.io/DownGit/#/home?url=https://github.com/OCFreaks/LPC1114-Tutorial-Examples/tree/master/MCUXpresso/Timer" target="_blank">Timer_Ex_1_2_3.Zip</a>.</div>
<p>The post <a href="https://www.ocfreaks.com/lpc1114-timer-programming-tutorial/">LPC1114 Timer Programming Tutorial</a> appeared first on <a href="https://www.ocfreaks.com">OCFreaks!</a>.</p>
]]></content:encoded>
					
					<wfw:commentRss>https://www.ocfreaks.com/lpc1114-timer-programming-tutorial/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
		<post-id xmlns="com-wordpress:feed-additions:1">2900</post-id>	</item>
		<item>
		<title>LPC1768 PWM Programming Tutorial</title>
		<link>https://www.ocfreaks.com/lpc1768-pwm-programming-tutorial/</link>
					<comments>https://www.ocfreaks.com/lpc1768-pwm-programming-tutorial/?noamp=mobile#respond</comments>
		
		<dc:creator><![CDATA[Umang Gajera]]></dc:creator>
		<pubDate>Thu, 21 Sep 2017 17:07:59 +0000</pubDate>
				<category><![CDATA[Embedded]]></category>
		<category><![CDATA[lpc1768]]></category>
		<category><![CDATA[tutorial]]></category>
		<guid isPermaLink="false">http://www.ocfreaks.com/?p=2876</guid>

					<description><![CDATA[<p>This discussion will guide you through ARM Cortex-M3 LPC1768 PWM programming Tutorial. It is also applicable for LPC1769. I&#8217;ll be covering Single Edge PWM along with examples like how to use to control Motors like Servos and dimming an LED. I assume you are comfortable with Timers and its usage in ARM Cortex-M3 based LPC176x [&#8230;]</p>
<p>The post <a href="https://www.ocfreaks.com/lpc1768-pwm-programming-tutorial/">LPC1768 PWM Programming Tutorial</a> appeared first on <a href="https://www.ocfreaks.com">OCFreaks!</a>.</p>
]]></description>
										<content:encoded><![CDATA[<p class="tocpostimage"> This discussion will guide you through ARM Cortex-M3 LPC1768 PWM programming Tutorial. It is also applicable for LPC1769. I&#8217;ll be covering Single Edge PWM along with examples like how to use to control Motors like Servos and dimming an LED. I assume you are comfortable with Timers and its usage in ARM Cortex-M3 based LPC176x micro-controllers since PWM block is basically a Timer.</p>
<div class="toc_container">
<span class="toc_title">Table of Contents</span></p>
<div class="toc">
<ol class="toc_list">
<li class="toc_text"><a href="#PWM_Module"><span>ARM Cortex-M3 LPC1768 PWM Module</span></a></li>
<ol class="toc_list">
<li class="toc_text"><a href="#PWM_timing_diagram"><span>PWM Timing Diagram Example</span></a></li>
</ol>
<li class="toc_text"><a href="#PWM_Registers"><span>PWM Registers</span></a></li>
<li class="toc_text"><a href="#PWM_Configuration"><span>Configuring PWM Block</span></a></li>
<ol class="toc_list">
<li class="toc_text"><a href="#PWM_Prescaler_formula"><span>PWM Prescaler Calculations</span></a></li>
</ol>
<li class="toc_text"><a href="#LPC1768_PWM_Examples"><span>LPC1768 PWM Examples</span></a></li>
<ol class="toc_list">
<li class="toc_text"><a href="#Servo_Control_Example"><span>LPC1768 PWM Example: Servo Control</span></a></li>
<li class="toc_text"><a href="#LED_Dimming_Example"><span>LPC1768 PWM Example: LED Dimming</span></a></li>
</ol>
</ol>
</div>
</div>
<h4> Pulse Width Modulation Basics: </h4>
<p>I&#8217;ve have posted a <a href="https://www.ocfreaks.com/pulse-width-modulation-pwm-tutorial/">Beginner PWM tutorial</a>. If you are new to PWM please have a look there. A Diagram that sums it up is given below. It shows Single Edge PWM with T-ON, T-OFF &#038; Period. Duty Cycle is simply T-ON Divided by Period.</p>
<p><img decoding="async" class="aligncenter" src="https://www.ocfreaks.com/imgs/embedded/common/pwm_basics.png" alt="PWM timing showing Ton, Toff and Period" width="425px" height="180px" /></p>
<h2 class="shead" id="PWM_Module">ARM Cortex-M3 LPC1768 PWM Module</h2>
<p>These MCUs Contains a single PWM Module called PWM1 and supports 2 types of PWM:<br />
<strong>1) Single Edge PWM</strong> &#8211; Pulse starts with new Period i.e Pulse is always at the beginning<br />
<strong>2) Double Edge PWM</strong> &#8211; Pulse can be present anywhere within the Period</p>
<p>A PWM block, similar to a Timer block, has a Timer Counter and an associated Prescale Register along with Match Registers. These work exactly the same way as in the case of Timers. I&#8217;ve explained them in the introduction part of the <a href="https://www.ocfreaks.com/lpc1768-timer-programming-tutorial/">LPC1768 Timer tutorial</a> . Match Registers 1 to 6 (except 0) are pinned on LPC176x i.e. the corresponding outputs are given to actual Pins on LPC176x MCU. The PWM function must be selected for these Pins, using PINSELx Register, to get the PWM output. These pins are:</p>
<table class="aligncenter" style="margin-bottom:15px;">
<tr>
<td> <strong>Output</strong></td>
<td> PWM1.1</td>
<td>PWM1.2</td>
<td>PWM1.3</td>
<td>PWM1.4</td>
<td>PWM1.5</td>
<td>PWM1.6</td>
</tr>
<tr>
<td><strong>Pin Name</strong></td>
<td>P1.18<br />P2.0</td>
<td>P1.20<br />P2.1<br />P3.25</td>
<td>P1.21<br />P2.2<br />P3.26</td>
<td>P1.23<br />P2.3</td>
<td>P1.24<br />P2.4</td>
<td>P1.26<br />P2.5</td>
</tr>
</table>
<p></center></p>
<div class="special sp_blue noteinfo"><strong>Note :</strong> PWM1.1 output corresponds to PWM Match Register 1 i.e PWM1MR1 , PWM1.2 output corresponds to PWM1MR2 , and so on. Also Match Register 0 i.e PWM1MR0 is NOT pinned because it is used to generate the PWM Period. P3.25 and P3.26 are only available on 100 pin LQFP package.</div>
<p>There are 7 match registers inside the PWM1 block. The first Match register PWM1MR0 is used to generate PWM period and hence we are left with 6 Match Registers PWM1MR1 to PWM1MR6 to generate 6 Single Edge PWM signals or 3 Double Edge PWM signals. Double edge PWM uses 2 match registers hence we can get only 3 double edge outputs.</p>
<div class="highlight">
<strong>PWM Rules &#8211;</strong> The User Manual mentions Rules for using Single Edge and Double Edge PWM on page 524 . The Rules for Single Edged PWM are as:</p>
<ul style="margin-bottom:10px">
<li>1) All single edged PWM outputs will go high at the beginning of a PWM cycle unless their match value is 0.</li>
<li>2) Each PWM output will go low when its match value is reached. <strong>Note:</strong> If no match occurs i.e Match value is greater than Period then the output will remain high!</li>
</ul>
</div>
<p id="PWM_timing_diagram">Consider that our PWM Period duration is 5 milliseconds and TC increments every 1 millisecond using appropriate prescale value. We set PWM1MR0 to 5 i.e. <strong>5 ticks of PWM TC</strong>. We have PWM1MR1 = 2 and PWM1MR2 = 4. Whenever the value in TC matches the value in any of the match register, its corresponding output it set to low until the start of next PWM cycle as shown in PWM Timing Diagram below:</p>
<p><img decoding="async" class="aligncenter" src="https://www.ocfreaks.com/imgs/embedded/common/lpc_pwm_timing_diagram.png" alt="LPC Microcontroller PWM Module Timing Diagram" width="525px" height="325px" /></p>
<p>For Double Edge Rules you can refer the User Manual <strong>Pg. 524</strong>.</p>
<div class="special sp_red noteinfo"><strong>Note:</strong> The last 6 Match Registers i.e PWM1MR1 to PWM1MR6 have an associated PIN from which we get the PWM outputs. The PWM block controls the output of these pins depending on the value in its corresponding Match Register. For Single Edged PWM these Pins are set to High by default when a new Period starts i.e when TC is reset as per the PWM Rules given above.</div>
<h2 class="shead" id="PWM_Registers">Registers used in LPC176x PWM Programming</h2>
<p>Now lets have a look at some important Registers:</p>
<div class="highlight">
<strong>1) <span class="doc_ref">PWM1TCR</span> &#8211; PWM Timer Control Register:</strong> This register is used to control the Timer Counter inside the PWM block. Only Bits: 0, 1  &#038; 3 are used rest are reserverd.</p>
<ul>
<li><strong>Bit 0 :</strong> When 1 both PWM Timer counter and PWM Prescale counter are enabled. When 0 both are disabled.</li>
<li><strong>Bit 1 :</strong> When set to 1 it will reset Reset both Timer and Prescale counter of PWM block (at next edge of PCLK).</li>
<li><strong>Bit 3 :</strong> Enables PWM mode i.e the PWM outputs.</li>
<li>Other Bits : Reserved.</li>
</ul>
<p><strong>2) <span class="doc_ref">PWM1PR</span> &#8211; PWM Prescale Register:</strong> PWMPR is used to control the resolution of the PWM outputs. The Timer Counter(TC) will increment every PWMPR+1 Peripheral Clock Cycles (PCLK).</p>
<p><strong>3) <span class="doc_ref">PWM1MR0</span> &#8211; PWM1MR6 (Match Registers):</strong> These are the seven Match registers as explained above which contain <strong>Pulse Width Values i.e the Number of PWM1TC Ticks</strong>.</p>
<p><strong>4) <span class="doc_ref">PWM1MCR</span> &#8211; PWM Match Control Registers:</strong> The PWM Match Control Register is used to specify what operations can be done when the value in a particular Match register equals the value in TC. For each Match Register we have 3 options : Either generate an Interrupt , or Reset the TC , or Stop .. which stops the counters and disables PWM. Hence this register is divided into group of 3 bits. The first 3 bits are for Match Register 0 i.e PWMMR0 , next 3 for PWMMR1 , and so on.</p>
<ul>
<li><strong>1) Bit 0 :</strong> Interrupt on PWM1MR0 Match &#8211; If set to 1 then it will generate an Interrupt else disable if set to 0.</li>
<li><strong>2) Bit 1 :</strong> Reset on PWM1MR0 Match &#8211; If set to 1 it will reset the PWM Timer Counter i.e. PWM1TC else disabled if set to 0.</li>
<li><strong>3) Bit 2 :</strong> Stop on PWM1MR0 Match &#8211; If this bit is set 1 then both PWM1TC and PWM1PC will be stopped &#038; disable the Counters.</li>
<li><strong>*)</strong> Similarly {Bits 3,4,5} for PWM1MR1 , {Bits 6,7,8} for PWM1MR2 , {Bits 9,10,11} for PWM1MR3 ,{Bits 12,13,14} for PWM1MR4 ,{Bits 15,16,17} for PWM1MR5 , {Bits 18,19,20} for PWM1MR6.</li>
</ul>
<p><strong>5) <span class="doc_ref">PWM1IR</span> &#8211; PWM Interrupt Register:</strong> If an interrupt is generated by any of the Match Register then the corresponding bit in PWM1IR will be set high. Writing a 1 to the corresponding location will clear that interrupt.</p>
<ul>
<li><strong>1) Bits 0,1,2,3</strong> are for PWM1MR0, PWM1MR1, PWM1MR2, PWM1MR3 respectively and </li>
<li><strong>2) Bits 8,9,10</strong> are for PWM1MR4 , PWM1MR5 , PWM1MR6 respectively. Other bits are reserved.</li>
</ul>
<p><strong>6) <span class="doc_ref">PWMLER</span> &#8211; Load Enable Register:</strong> The PWM Load Enable Register is used to control the way Match Registers are updated when PWM generation is active. When PWM mode is active and we apply new values to the Match Registers the new values won&#8217;t get applied immediately. Instead what happens is that the value is written to a &#8220;Shadow Register&#8221; .. it can be thought of as a duplicate Match Register. Each Match Register has a corresponding Shadow Register. The value in this Shadow Register is transferred to the actual Match Register when: PWM1TC is reset (i.e at the beginning of the next period) and the corresponding Bit in PWM1LER is 1.</p>
<p>Hence only when these 2 conditions are satisfied the value is copied to Match Register. Bit &#8216;x&#8217; in PWM1LER corresponds to match Register &#8216;x&#8217;. I.e Bit 0 is for PWM1MR0 , Bit 1 for PWM1MR1 , .. and so on. Using PWM1LER will be covered in the examples section.</p>
<p><strong>7) <span class="doc_ref">PWM1PCR</span> &#8211; PWM Control Register:</strong> This register is used for Selecting between Single Edged &#038; Double Edged outputs and also to Enable/Disable the 6 PWM outputs which go to their corresponding Pins. </p>
<ul style="margin-bottom:0px">
<li>1) <strong>Bits 2 to 6</strong> are used to select between Single or Double Edge mode for PWM 2,3,4,5,6 outputs. If <strong>Bit 2</strong> is set to 1 then PWM1.2(i.e the one corresponding to PWM1MR2) output is double edged else if set 0 then its Single Edged. Similarly <strong>Bit x</strong> for PWM1.x correspondingly.
</li>
<li>2)<strong> Bits 9 to 14</strong> are used to Enable/Disable PWM outputs. If <strong>Bit 9</strong>is set to 1 then PWM1.1 output is enabled , else disabled if set to 0. Similarly remaining bits for PWM1.x correspondingly.
</li>
</ul>
</div>
<h2 class="shead" id="PWM_Configuration">Configuring and Initializing PWM Block</h2>
<p>Now, lets see how to use PWM block. Configuring PWM module is very much similar to Configuring Timer except, additionally, we need to enable the outputs and select PWM functions for the corresponding PIN on which PWM output will be available. But first we need to do some basic Math Calculations for defining the Period time, the resolution using a prescale value and then Pulse Widths. For this First we need to define the resolution of our PWM signal. PWM resolution is the minimum time delay that can used to increase or decrease the pulse width. More smaller the increment more fine will be the resolution. PWM Resolution is set using an appropriate Prescale Value. The calculation for PWM Prescaler is the same which I had shown in the <a href="https://www.ocfreaks.com/lpc1768-timer-programming-tutorial/">Timer Tutorial</a>, here it is once again:</p>
<div class="special sp_blue noteinfo" id="PWM_Prescaler_formula">
<h4>LPC1768 PWM Prescale (PWM1PR) Calculations:</h4>
<p>The general formula for <strong>PWM Resolution</strong> at X Mhz PCLK(CCLK) and a given value for prescale (PR) is as given below:</p>
<div class="equation">PWM<sub>RES</sub> =</p>
<div class="fraction"><span class="fup">PR+1</span><span class="bar">/</span><span class="fdn">PCLK<sub>Hz</sub></sup></span></div>
<p> =</p>
<div class="fraction"><span class="fup">PR+1</span><span class="bar">/</span><span class="fdn">X * 10<sup>6</sup></span></div>
<p>Seconds</p></div>
<p>Hence, we get the <strong>Formula for Prescaler (PR) for required PWM resolution (PWM<sub>RES</sub> in Secs)</strong> at given <strong>PCLK(in Hz)</strong> frequency as:</p>
<div class="equation">PR = (PCLK<sub>Hz</sub> * PWM<sub>RES</sub>) &#8211; 1</div>
<div class="equation">PR = ((X * 10<sup>6</sup>) * PWM<sub>RES</sub>) &#8211; 1</div>
<p>Note that here, the PWM Resolution is also the time delay required to increment PWM TC by 1.</p>
<p>Hence, Prescaler value for 1 micro-second resolution i.e. 1us time delay at 25 Mhz PCLK(CCLK) is,</p>
<div class="equation">PR<sub>1us</sub> = (25Mhz * 1uS) -1 = (25*10<sup>6</sup> * 10<sup>-6</sup>) -1 = 24</div>
<p>Prescale for 1 mS (milli-second) resolution at 25Mhz PCLK(CCLK) is,</p>
<div class="equation">PR<sub>1ms</sub> = (25Mhz * 1ms) -1 = (25*10<sup>6</sup> * 10<sup>-3</sup>) -1 = 24999</div>
<p><strong>Note: </strong>The calculations for <strong>LPC1769</strong> are same except it operates at <strong>120Mhz(max CCLK)</strong>. Hence <strong>default PCLK</strong> will be <strong>30Mhz</strong>.</p>
</div>
<div class="highlight">
Now , After we&#8217;ve worked out the resolution we want .. we can now Configure &#038; Initialize the PWM device as per the following steps:</p>
<ol style="margin-bottom:0px">
<li>Select the PWM function for the PIN on which you need the PWM output using applicable <span class="code_var">LPC_PINCON->PINSELx</span> register.</li>
<li>Select Single Edge or Double Edge Mode using <span class="code_var">LPC_PWM1->PCR</span>. By default its Single Edge Mode.</li>
<li>Assign the Calculated value to <span class="code_var">LPC_PWM1->PR</span>.</li>
<li>Set the Value for PWM Period in <span class="code_var">LPC_PWM1->MR0</span>.</li>
<li>Set the Values for other Match Registers i.e the Pulse Widths.</li>
<li>Set appropriate bit values in <span class="code_var">LPC_PWM1->MCR</span> .. like for e.g. resetting PWM1TC for PWMMR0 match and optionally generate interrupts if required</li>
<li>Set Load Enable Bits for the Match Registers that you&#8217;ve used. This is important!</li>
<li>Then Enable PWM outputs using <span class="code_var">LPC_PWM1->PCR</span>.</li>
<li>Now Reset PWM Timer using <span class="code_var">LPC_PWM1->TCR</span>.</li>
<li>Finally, Enable Timer Counter and PWM Mode using <span class="code_var">LPC_PWM1->TCR</span>.</li>
</ol>
</div>
<p><strong>Example :</strong></p>
<pre><code class="language-cpp">
//Select PWM Function Using appropriate PINSEL register
LPC_PWM1->PCR = ... ; //Select PWM type - By default its Single Edged
LPC_PWM1->PR = ... ; //assign calculated PR value 
LPC_PWM1->MR0 = ... ; //Assign Period Duration
LPC_PWM1->MRx = ... ; //Assign pulse duration i.e widths for other Match Regs.. x=1 to 6
LPC_PWM1->MCR = (1<<1) | ... ; //Reset PWM1TC on PWMMR0 match &#038; Other conditions
LPC_PWM1->LER = (1<<1) | ... ; //update MR0 and other Match Registers
LPC_PWM1->PCR = ... ; //enable PWM outputs as required
LPC_PWM1->TCR = (1<<1) ; //Reset PWM TC &#038; PR

//Now , the final moment - enable PWM TC
LPC_PWM1->PWM1TCR = (1<<0) | (1<<3); //enable counters and PWM Mode
//Done!
</code></pre>
<h4>Updating Match Registers i.e. the Pulse Width</h4>
<p>Once PWM is initialized, you can update any of the Match Registers at anytime using PWMLER. This can be done as follows:</p>
<pre><code class="language-cpp">
LPC_PWM1->MR1 = 50; //Update Pulse Width
LPC_PWM1->LER = (1<<1); //set the corresponding bit to 1
</code></pre>
<p>When you want to update Multiple Match Registers then this can be done as follows:</p>
<pre><code class="language-cpp">
LPC_PWM1->MR1 = 50;
LPC_PWM1->MR2 = 68;
LPC_PWM1->MR3 = 20;

LPC_PWM1->LER = (1<<1) | (1<<2) | (1<<3); //Update Load Enable bit for all MRs together</code></pre>
<h2 class="shead" id="LPC1768_PWM_Examples">Some Real World PWM Examples with sample code</h2>
<p>Below I have given LPC1768 PWM Examples. For LCP1769 just change the PWM Prescale from 24 to 29 and Timer Prescale from 24999 to 29999.</p>
<h4 id="Servo_Control_Example">LPC1768 PWM Example 1: Servo Control</h4>
<p>In this LPC1768 PWM Example we will sweep a servo from 1000us to 2000us pulse widths, back and forth in steps. The period is set to 20ms(20000us) which is common for servos. PWM1.1 output is selected and will be available on Pin P1.18. In the C++ code given below, I have also used Timer0 which is used by <span class="code_var">delayMS(..)</span> function to generate delay before we update PWM1MR1 register with new value. <strong>Warning:</strong> Double check all connections when connecting the motor or it will damage your board.</p>
<p><strong>Source Code for Example 1:</strong></p>
<pre><code class="language-cpp">
/*(C) Umang Gajera - www.ocfreaks.com
More Embedded tutorials @ www.ocfreaks.com/cat/embedded
LPC1768 PWM Tutorial Example 1 - Simple RC Servo Control - KEIL uV5 ARM.
License: GPL */

#include &lt;LPC17xx.h&gt;
#define PWMPRESCALE (25-1) //25 PCLK cycles to increment TC by 1 i.e. 1 Micro-second

void initPWM(void);
void updatePulseWidth(unsigned int pulseWidth);
void delayMS(unsigned int milliseconds);
void initTimer0(void);

int main(void)
{
	//SystemInit(); //gets called by Startup code before main()
	initTimer0(); //Initialize Timer
	initPWM(); //Initialize PWM
	
	int pulseWidths[] = {1000,1250,1500,1750,2000};
	const int numPulseWidths = 5;
	int count=1;
	int dir=0; //direction, 0 = Increasing, 1 = Decreasing 

	while(1)
	{
		updatePulseWidth(pulseWidths[count]); //Update Servo Pulse Width
		delayMS(1000); //Wait for servo to reach the new position

		if(count == (numPulseWidths-1) || count == 0)
		{
			dir = !dir; //Toggle direction if we have reached count limit
		}
		
		if(dir) count--;
		else count++;
	}
  //return 0; //normally this won't execute ever
}

void initPWM(void)
{
	/*Assuming that PLL0 has been setup with CCLK = 100Mhz and PCLK = 25Mhz.*/

	LPC_PINCON->PINSEL3 |= (1<<5); //Select PWM1.1 output for Pin1.18
	LPC_PWM1->PCR = 0x0; //Select Single Edge PWM - by default its single Edged so this line can be removed
	LPC_PWM1->PR = PWMPRESCALE; //1 micro-second resolution
	LPC_PWM1->MR0 = 20000; //20000us = 20ms period duration
	LPC_PWM1->MR1 = 1250; //1ms - default pulse duration i.e. width
	LPC_PWM1->MCR = (1<<1); //Reset PWM TC on PWM1MR0 match
	LPC_PWM1->LER = (1<<1) | (1<<0); //update values in MR0 and MR1
	LPC_PWM1->PCR = (1<<9); //enable PWM output
	LPC_PWM1->TCR = (1<<1); //Reset PWM TC &#038; PR

	LPC_PWM1->TCR = (1<<0) | (1<<3); //enable counters and PWM Mode

	//PWM Generation goes active now!
	//Now you can get the PWM output on Pin P1.18
}

void updatePulseWidth(unsigned int pulseWidth)
{
	LPC_PWM1->MR1 = pulseWidth; //Update MR1 with new value
	LPC_PWM1->LER = (1<<1); //Load the MR1 new value at start of next cycle
}


void delayMS(unsigned int milliseconds) //Using Timer0
{
	LPC_TIM0->TCR = 0x02; //Reset Timer
	LPC_TIM0->TCR = 0x01; //Enable timer

	while(LPC_TIM0->TC < milliseconds); //wait until timer counter reaches the desired delay

	LPC_TIM0->TCR = 0x00; //Disable timer
}

void initTimer0(void) //To setup Timer0 used delayMS() function
{
	/*Assuming that PLL0 has been setup with CCLK = 100Mhz and PCLK = 25Mhz.*/

	LPC_TIM0->CTCR = 0x0;
	LPC_TIM0->PR = 25000-1; //Increment TC at every 24999+1 clock cycles
	//25000 clock cycles @25Mhz = 1 mS

	LPC_TIM0->TCR = 0x02; //Reset Timer
}
</code></pre>
<div class="highlight"><strong>KEIL uV5 Project for Example #1 on GitHub @</strong> <a href="https://github.com/OCFreaks/LPC1768-Tutorial-Examples/tree/master/PWM/Example_1" target="_blank">PWM Example 1 Source</a> [Successfully tested on Keil uV5.23], <strong>Download Project Zip</strong> @ <a href="https://minhaskamal.github.io/DownGit/#/home?url=https://github.com/OCFreaks/LPC1768-Tutorial-Examples/tree/master/PWM/Example_1" target="_blank">Example_1.Zip</a></div>
<h4 id="LED_Dimming_Example">LPC1768 PWM Example 2: LED Dimming</h4>
<p>This example is similar to Example 1, except here we reduce the PWM Period to 1ms and Duty-cycle will vary from 0%(LED OFF) to 100%(Brightest). Connect the LED anode to P1.18 and cathode to GND using a suitable resistor (like >330 Ohms).</p>
<p><strong>Source code for Example 2</strong></p>
<pre><code class="language-cpp">
/*(C) Umang Gajera - www.ocfreaks.com
More Embedded tutorials @ www.ocfreaks.com/cat/embedded
LPC1768 PWM Tutorial Example 2 - LED Dimming using PWM - KEIL uV5 ARM.
License: GPL.
*/

#include &lt;LPC17xx.h&gt;
#define PWMPRESCALE (25-1) //25 PCLK cycles to increment TC by 1 i.e. 1 Micro-second

void initPWM(void);
void updatePulseWidth(unsigned int pulseWidth);
void delayMS(unsigned int milliseconds);
void initTimer0(void);

int main(void)
{
	//SystemInit(); //gets called by Startup code before main()
	initTimer0(); //Initialize Timer
	initPWM(); //Initialize PWM
	
	int pulseWidths[] = {0,250,500,750,1000}; //Pulse Widths for varying LED Brightness
	const int numPulseWidths = 5;
	int count=1;
	int dir=0; //direction, 0 = Increasing, 1 = Decreasing 

	while(1)
	{
		updatePulseWidth(pulseWidths[count]); //Update LED Pulse Width
		delayMS(1000); 

		if(count == (numPulseWidths-1) || count == 0)
		{
			dir = !dir; //Toggle direction if we have reached count limit
		}
		
		if(dir) count--;
		else count++;
	}
  //return 0; //normally this won't execute ever
}

void initPWM(void)
{
	/*Assuming that PLL0 has been setup with CCLK = 100Mhz and PCLK = 25Mhz.*/

	LPC_PINCON->PINSEL3 |= (1<<5); //Select PWM1.1 output for Pin1.18
	LPC_PWM1->PCR = 0x0; //Select Single Edge PWM - by default its single Edged so this line can be removed
	LPC_PWM1->PR = PWMPRESCALE; //1 micro-second resolution
	LPC_PWM1->MR0 = 1000; //1000us = 1ms period duration
	LPC_PWM1->MR1 = 250; //250us - default pulse duration i.e. width
	LPC_PWM1->MCR = (1<<1); //Reset PWM TC on PWM1MR0 match
	LPC_PWM1->LER = (1<<1) | (1<<0); //update values in MR0 and MR1
	LPC_PWM1->PCR = (1<<9); //enable PWM output
	LPC_PWM1->TCR = (1<<1); //Reset PWM TC &#038; PR

	LPC_PWM1->TCR = (1<<0) | (1<<3); //enable counters and PWM Mode

	//PWM Generation goes active now!
	//Now you can get the PWM output on Pin P1.18
}

void updatePulseWidth(unsigned int pulseWidth)
{
	LPC_PWM1->MR1 = pulseWidth; //Update MR1 with new value
	LPC_PWM1->LER = (1<<1); //Load the MR1 new value at start of next cycle
}


void delayMS(unsigned int milliseconds) //Using Timer0
{
	LPC_TIM0->TCR = 0x02; //Reset Timer
	LPC_TIM0->TCR = 0x01; //Enable timer

	while(LPC_TIM0->TC < milliseconds); //wait until timer counter reaches the desired delay

	LPC_TIM0->TCR = 0x00; //Disable timer
}

void initTimer0(void) //To setup Timer0 used delayMS() function
{
	/*Assuming that PLL0 has been setup with CCLK = 100Mhz and PCLK = 25Mhz.*/

	LPC_TIM0->CTCR = 0x0;
	LPC_TIM0->PR = 25000-1; //Increment TC at every 24999+1 clock cycles
	//25000 clock cycles @25Mhz = 1 mS

	LPC_TIM0->TCR = 0x02; //Reset Timer
}
</code></pre>
<div class="highlight"><strong>KEIL uV5 Project for Example #2 on GitHub @</strong> <a href="https://github.com/OCFreaks/LPC1768-Tutorial-Examples/tree/master/PWM/Example_2" target="_blank">PWM Example 2 Source</a> [Successfully tested on Keil uV5.23], <strong>Download Project Zip</strong> @ <a href="https://minhaskamal.github.io/DownGit/#/home?url=https://github.com/OCFreaks/LPC1768-Tutorial-Examples/tree/master/PWM/Example_2" target="_blank">Example_2.Zip</a></div>
<p>The post <a href="https://www.ocfreaks.com/lpc1768-pwm-programming-tutorial/">LPC1768 PWM Programming Tutorial</a> appeared first on <a href="https://www.ocfreaks.com">OCFreaks!</a>.</p>
]]></content:encoded>
					
					<wfw:commentRss>https://www.ocfreaks.com/lpc1768-pwm-programming-tutorial/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
		<post-id xmlns="com-wordpress:feed-additions:1">2876</post-id>	</item>
	</channel>
</rss>

<!--
Performance optimized by W3 Total Cache. Learn more: https://www.boldgrid.com/w3-total-cache/

Page Caching using Disk: Enhanced 

Served from: www.ocfreaks.com @ 2026-03-05 00:27:36 by W3 Total Cache
-->