0% found this document useful (0 votes)
31 views22 pages

Mbed BK Ed2 CH 14

The document discusses letting go of the mbed libraries and instead directly accessing microcontroller registers to control peripherals. It describes how control registers provide communication between the CPU and peripherals by acting as doorways. Examples show defining register addresses and directly writing to registers to set pin directions and values to implement digital input and output without using mbed libraries. Control concepts discussed include registers for pin selection, pin modes, power control, and peripheral clocks. The document also provides an example of directly accessing the DAC control register.
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
31 views22 pages

Mbed BK Ed2 CH 14

The document discusses letting go of the mbed libraries and instead directly accessing microcontroller registers to control peripherals. It describes how control registers provide communication between the CPU and peripherals by acting as doorways. Examples show defining register addresses and directly writing to registers to set pin directions and values to implement digital input and output without using mbed libraries. Control concepts discussed include registers for pin selection, pin modes, power control, and peripheral clocks. The document also provides an example of directly accessing the DAC control register.
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
You are on page 1/ 22

Chapter 14: Letting go

of the mbed Libraries tw rev. 03.11.16

If you use or reference these slides or the associated textbook, please cite the original authors’ work as follows:
Toulson, R. & Wilmshurst, T. (2016). Fast and Effective Embedded Systems Design - Applying the ARM mbed
(2nd edition), Newnes, Oxford, ISBN: 978-0-08-100880-5.
www.embedded-knowhow.co.uk
Letting Go of the mbed Libraries

The mbed library contains many useful functions, which allow us to write simple
and effective code. This seems a good thing, but it is also sometimes limiting.
What if we want to use a peripheral in a way not allowed by any of the
functions? Therefore it is useful to understand how peripherals can be
configured by direct access to the microcontroller’s registers. In turn, this leads
to a deeper insight into some aspects of how a microcontroller works. As a by-
product, and because we will be working at the bit and byte level, this study
develops further skills in C programming.
Control Register Concepts
How does the CPU, running its program, communicate with all the peripherals
on the microcontroller?
Control Register Concepts
Each microcontroller peripheral has one or more system control registers which
act as the doorway between the peripheral and the CPU.
To the CPU, these
registers look just like
memory locations, and
each has its own address
in the memory map.

Each of the bits in the


register is wired across to
the peripheral. They might
carry control or status
information, or provide a
path for data flow.

The microcontroller
peripherals also usually
generate interrupts, for
example to flag when an
ADC conversion is
complete.
mbed Digital I/O Control Registers
Using the control registers, it is possible to set each port pin as an input or as an
output. Each port has a 32-bit register whose bits control the direction of each of
its pins, called the FIODIR registers. There are also single-byte versions.
A second set of registers, called FIOPIN, hold the data value of the
microcontroller’s pins, whether they have been set as input or output.

Register Register Function Register


Name Address
FIOnDIR Sets the data direction of each pin in Port n, where n takes value 0 to 4. A port pin -
is set to output when its bit is set to 1, and as input when it is set to 0. Accessible
as word. Reset value = 0, i.e. all bits are set to input on reset.
FIO0DIR Example of above for Port 0. 0x2009C000
FIO2DIR Example of above for Port 2. 0x2009C040
FIOnDIRp Sets the data direction of each pin in byte p of Port n, where p takes value 0 to 3. -
A port pin is set to output when its bit is set to 1. Accessible as byte.
FIO0DIR0 Example of above, Port 0 byte 0. 0x2009C000
FIO0DIR1 Example of above, Port 0 byte 1. 0x2009C001
FIO2DIR0 Example of above, Port 2 byte 0. 0x2009C040
FIO0PIN Sets the data value of each bit in Port 0 or 2. Accessible as word. Reset value = 0. 0x2009C014
FIO2PIN 0x2009C054
FIO0PIN0 Sets the data value of each bit in least significant byte of Port 0 or 2. Accessible as 0x2009C014
FIO2PIN0 byte. Reset value = 0. 0x2009C054

Example Digital I/O Control Registers


Connecting LPC1768 pins to mbed pins
Most of the mbed pins connect directly to the LPC1768 microcontroller. These
connections can be seen in the mbed circuit diagram, and are summarised
below. Against each mbed pin which connects directly is shown the LPC1768 pin
number, its port bit id, and any further function applied by the mbed. Any function
not used by the mbed is not shown (but can be found in the data sheet).

76(P0.9/MOSI1)
77(P0.8/MISO1)
78(P0.7/SCK1)
79(P0.6)
46(P0.0/TXD3/SDA1)
47(P0.1/RXD3/SCL1)
60(P0.18/MOSI) 81(P0.4/CAN_RX2)
61(P0.17/MISO) 80(P0.5/CAN_TX2)
62(P0.15/TXD1/SCK) 48(P0.10/TXD2/SDA2)
63(P0.16/RXD1) 49(P0.11/RXD2/SCL2)
9(P0.23/AD0.0) 75(P2.0/PWM1.1)
8(P0.24/AD0.1) 74(P2.1/PWM1.2)
7(P0.25/AD0.2) 73(P2.2/PWM1.3)
6(P0.26/AD0.3/AOUT) 70(P2.3/PWM1.4)
21(P1.30/AD0.4) 69(P2.4/PWM1.5)
20(P1.31/AD0.5) 68(P2.5/PWM1.6)

LED1: P1.18 LED2: P1.20 LED3: P1.21 LED3: P1.23


A Digital Output Application
This program replicates the opening LED flashing program, without using mbed
libraries. It switches port 2 bit 0 (and hence mbed pin 26) high and low.

/*Program Example 14.1: Sets up a digital output pin using control registers, and
flashes an led.
*/
// function prototypes
void delay(void);

//Define addresses of digital i/o control registers, as pointers to volatile data


#define FIO2DIR0 (*(volatile unsigned char *)(0x2009C040))
#define FIO2PIN0 (*(volatile unsigned char *)(0x2009C054))

int main() {
FIO2DIR0=0xFF; // set port 2, lowest byte to output
while(1) {
FIO2PIN0 |= 0x01; // OR bit 0 with 1 to set pin high
delay();
FIO2PIN0 &= ~0x01; // AND bit 0 with 0 to set pin low
delay();
}
}
//delay function
void delay(void){
int j; //loop variable j
for (j=0;j<1000000;j++) {
j++;
j--; //waste time
}
}
Digital Inputs
We can create digital inputs simply by setting a port bit to input, using the
correct bit in an FIODIR register. Program Example 14.3 develops the previous
example, by including a digital input from a switch.
/* Program Example 14.3: Uses digital input and output using control registers, and
flashes an LED. LEDS connect to mbed pins 25 and 26. Switch input to pin 9.
*/
// function prototypes
void delay(void);
//Define Digital I/O registers
#define FIO0DIR0 (*( volatile unsigned char *)(0x2009C000))
#define FIO0PIN0 (*( volatile unsigned char *)(0x2009C014))
#define FIO2DIR0 (*(volatile unsigned char *)(0x2009C040))
#define FIO2PIN0 (*(volatile unsigned char *)(0x2009C054))
//some variables
char a;
char b;
char i;

int main() {
FIO0DIR0=0x00; // set all bits of port 0 byte 0 to input
FIO2DIR0=0xFF; // set port 2 byte 0 to output
while(1) {
if ((FIO0PIN0&0x01)==1){ // bit test port 0 pin 0 (mbed pin 9)
a=0x01; // this reverses the order of LED flashing
b=0x02; // based on the switch position
}
else {
...
...
The Pin Select Register
The PINSEL register can allocate each pin to one of four possibilities. An
example of part of one register, PINSEL1, is shown. This controls the upper half
of Port 0.

(From LPC17xxx
User Manual Rev.
3.1, UM10360)
The Pin Mode Register
As an example, PINMODE0 is shown. This controls the input characteristics of the
lower half of Port 0. The pattern is the same for every pin, so there’s no need for
repetition. Pull-up and pull-down resistors can be enabled. The repeater mode is a
facility which enables pull-up resistor when the input is a Logic 1, and pull-down if
it’s low. If the external circuit changes so that the input is no longer driven, then the
input will hold its most recent value.
Power Control Registers
To conserve power, it is possible to turn off power and clock to many of the
LPC1768 peripherals. This power management is controlled by the PCONP
register, seen in part here. Where a bit is set to 1, the peripheral is enabled.
Clock Select Registers
Some control is possible over the peripheral’s clock frequency, using the
PCLKSEL registers. This will control the peripheral’s speed of operation and
hence its power consumption. Peripheral clocks are taken from the clock which
drives the CPU, called CCLK. For the mbed, CCLK runs at 96 MHz. Partial
details of PCLKSEL0 are shown. Two bits are used per peripheral to control the
clock frequency to each. The four possible combinations are also shown.
Using the DAC
The LPC1768 DAC has a set of control registers.
DAC power is always enabled, so there is no
need to consider the PCONP register.
The only pin that the DAC output is available on is
Port 0 pin 26, so this must be allocated through
PINSEL1 (where DAC output is labelled AOUT).
This pin is connected to mbed pin 18.
The only register specific to the DAC that we use is the DACR register, shown
here. On the LPC1768 the reference voltage is applied between terminals
labelled VREFP and VREFN; these are connected to 3.3 V and 0 V respectively.
A DAC Application
Program Example 14.4 replicates the simple sawtooth waveform, as first
achieved in Chapter 4. An integer variable, dac_value, is repeatedly
incremented and transferred to the DAC input, in register DACR. It has to be
shifted left 6 times, to place it in the correct bits of the DACR register.

/* Program Example 14.4: Sawtooth waveform on DAC output. View on oscilloscope. Port
0.26 is used for DAC output, i.e. mbed Pin 18
*/
// function prototype
void delay(void);

// variable declarations
int dac_value; //the value to be output

//define addresses of control registers, as pointers to volatile data


#define DACR (*(volatile unsigned long *)(0x4008C000))
#define PINSEL1 (*(volatile unsigned long *)(0x4002C004))

int main(){
PINSEL1=0x00200000; //set bits 21-20 to 10 to enable analog out on P0.26
while(1){
for (dac_value=0;dac_value<1023;dac_value=dac_value+1){
DACR=(dac_value<<6);
delay();
}
}
}

void delay(void) //delay function.


//program continues
Using the ADC
Controlling the ADC through its registers includes selecting or applying the
voltage reference, clock speed, input channel, starting a conversion, detecting a
completion, and reading the output data. The LPC1768 has a number of
registers which control its ADC. Only two are applied here, the ADC control
register, ADCR, and the Global Data Register, ADGDR. As the ADC is switched
off on power-up, it needs to be enabled through bit 12 in the PCONP register.
The ADC Control
Register
The ADC Global Data Register
An ADC Bargraph Application (initialisation)
/* Program Example 14.5: A bar graph meter for ADC input, using control registers to
set up ADC and digital I/O
*/
// variable declarations
char ADC_channel=1; // ADC channel 1
int ADCdata; //this will hold the result of the conversion
int DigOutData=0; //a buffer for the output display pattern

// function prototype
void delay(void);

//define addresses of control registers, as pointers to volatile data


//(i.e. the memory contents)
#define PINSEL1 (*(volatile unsigned long *)(0x4002C004))
#define PCONP (*(volatile unsigned long *)(0x400FC0C4))
#define AD0CR (*(volatile unsigned long *)(0x40034000))
#define AD0GDR (*(volatile unsigned long *)(0x40034004))
#define FIO2DIR0 (*(volatile unsigned char *)( 0x2009C040))
#define FIO2PIN0 (*(volatile unsigned char *)( 0x2009C054))

int main() {
FIO2DIR0=0xFF;// set lower byte of Port 2 to output, this drives bar graph

//initialise the ADC


PINSEL1=0x00010000; //set bits 17-16 to 01 to enable AD0.1 (mbed pin 16)
PCONP |= (1 << 12); // enable ADC clock
AD0CR = (1 << ADC_channel) // select channel 1
| (4 << 8) // Divide incoming clock by (4+1), giving 4.8MHz
| (0 << 16) // BURST = 0, conversions under software control
| (1 << 21) // PDN = 1, enables power
| (1 << 24); // START = 1, start A/D conversion now
...
An ADC Bargraph Application (main while(1) loop)
while(1) { // infinite loop
AD0CR = AD0CR | 0x01000000; //start conversion by setting bit 24 to 1,
//by ORing
// wait for it to finish by polling the ADC DONE bit
while ((AD0GDR & 0x80000000) == 0) { //test DONE bit, wait till it’s 1
}
ADCdata = AD0GDR; // get the data from AD0GDR
AD0CR &= 0xF8FFFFFF; //stop ADC by setting START bits to zero
// Shift data 4 bits to right justify, and 2 more to give 10-bit ADC
// value - this gives convenient range of just over one thousand.
ADCdata=(ADCdata>>6)&0x03FF; //and mask
DigOutData=0x00; //clear the output buffer
//display the data
if (ADCdata>200)
DigOutData=(DigOutData|0x01); //set the lsb by ORing with 1
if (ADCdata>400)
DigOutData=(DigOutData|0x02); //set the next lsb by ORing with 1
if (ADCdata>600)
DigOutData=(DigOutData|0x04);
if (ADCdata>800)
DigOutData=(DigOutData|0x08);
if (ADCdata>1000)
DigOutData=(DigOutData|0x10);

FIO2PIN0 = DigOutData; // set port 2 to Digoutdata


delay(); // pause
}
}

void delay(void){ //delay function.


//program continues
Changing ADC Conversion Speed
One of the limitations of the mbed ADC library is the slow speed of conversion.
This can be varied by adjusting the ADC clock speed. Program Example 14.6
replicates Program Example 5.5, and combines ADC, DAC and digital I/O,
illustrating how these can be used together.
/* Program Example 14.6: Explore ADC conversion times, programming control registers
directly. ADC value is transferred to DAC, while an output pin is strobed to indicate
conversion duration. Observe on oscilloscope
*/
….
….
while(1){ // infinite loop
// start A/D conversion by modifying bits in the AD0CR register
AD0CR &= (AD0CR & 0xFFFFFF00);
FIO2PIN0 |= 0x01; // OR bit 0 with 1 to set pin high
AD0CR |= (1 << ADC_channel) | (1 << 24);
// wait for it to finish by polling the ADC DONE bit
while((AD0GDR & 0x80000000) == 0) {
}
FIO2PIN0 &= ~0x01; // AND bit 0 with 0 to set pin low

ADCdata = AD0GDR; // get the data from AD0GDR


AD0CR &= 0xF8FFFFFF; //stop ADC by setting START bits to zero

// shift data 4 bits to right justify, and 2 more to give 10-bit ADC value
ADCdata=(ADCdata>>6)&0x03FF; //and mask
DACR=(ADCdata<<6); //could be merged with previous line,
// but separated for clarity
//delay(); //insert delay if wished
}
}

A Conclusion on Using the Control Registers

• We have explored the use of the LPC1768 control registers, in connection


with use of the digital I/O, ADC and DAC peripherals.
• We have demonstrated how these registers allow the peripherals to be
controlled directly, without using the mbed libraries. This has allowed
greater flexibility of use of the peripherals, at the cost of getting into the
tiny detail of the registers, and programming at the level of the bits that
make them up.
• Ordinarily we probably wouldn’t want to program like this; it’s time-
consuming, inconvenient and error-prone. However if we need a
configuration or setting not offered by the mbed libraries, this approach
can be a way forward.
• While we’ve only worked in this way in connection with three of the
peripherals, it’s possible to do it with any of them. The three used are
some of the simpler; others require even more attention to detail.
Chapter Review

• In this chapter we have recognised a different way of controlling the


mbed peripherals. It demands a much deeper understanding of the
mbed microcontroller, but allows for much greater flexibility.
• There are registers which relate just to one peripheral, and others which
relate to microcontroller performance as a whole.
• We have begun to implement features that are not currently available in
the mbed library, for example in the change of the ADC conversion
speed.
• The chapter only introduces a small range of the control registers which
are used by the LPC1768. However it should have given you the
confidence to look up and begin to apply any that you need.

You might also like

pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy