I am using the plural because these processors include different clocks, each one of them can then be sourced by different oscillators...
It looks quite complex, especially if you try to understand the C (or ASM) code that configures them, but there are some basic concepts behind that, if understood, help in shredding light on the matter.
First of all a clock system is something that is used to give the pace, typically for the execution of instructions.
The processor itself needs a clock to be able to execute a program, but some of it's components, such as timers (or the ADC) may eventually use a different clock to perform instructions at regular intervals.
A clock needs an oscillator signal in input, this can be generated by a crystal or by a digital device, then this signal is manipulated in a way that the frequency matches the needed one.
Typically the clock system contains a digital divider that lowers the input frequency dividing it by a programmable number.
The TI workshop material illustrates which clock systems are present in the MPS430G2, this explanation can be found here (MSP430G2xx User's Guide) and here (workshop guide, useful when watching the workshop videos)
A more detailed description is available in the user guide which can be downloaded here (MSP430G2xx User's Guide), you really need to download this one if you want to program this MCU.
In summary, there are 3 different clock systems (plus a separate one for the ADC) they are :
- MCLK : The Master Clock, it is used to drive the CPU
- SMCLK : The Sub Master Clock, used normally for "fast" peripherals
- ACLK : Auxiliary Clock - An independent clock used for "slow" peripherals
The available oscillators are :
- DCO : Digital Controlled Oscillator - Internal oscillator used by default to drive the MCLK with frequencies from 0 to 16MHz
- VLO : Very Low frequency/power Oscillator - Internal oscillator used to typically for the ACLK clock
- XT1 : External low frequency crystal (optional)
- XT2 : External high frequency crystal (optional)
You should have the MPS430G2xx user guide open now at chapter 5.
The beginning of the chapter explains in greater detail the few lines I introduced here, then it gets a bit technical -good for general understanding-, but the part that really we need is the 5.3.
Here we understand how to manipulate the registers to drive the clock systems the way we need.
Controlling the DCO
Remember : DCO is an oscillator, not a clock, it is fed as input to a clock.
The DCO uses a single 8 bit register to configure the oscillating frequency, these 8 bits are grouped into two sets : the lower 5 (0-4 MODx) control the divider within the frequency range selected with the 3 highest bits (5-7 DCOx).
Setting the ACLK
Aclk is configured using the register BCSCTL1, also used to partially configure the external crystal oscillators.
BCSCTL1 is an 8 bit register where it is possible to set the frequency divider for ACLK (DIVAx , bits 4 and 5) with values : 1,2,4,8.
Bits 0-3 set the frequency range
Setting MCLK and SMCLK
Those two clock systems are configured via the BCSCTL2 8 bit register.
MCLK oscillator can be DCO,XT2,XT1,VLO, basically any available oscillator and this si selected witht eh two highest bits of the register (6-7 SELMx).
SMCLK instead can be sourced from the DCO or from the optional XT2 with bit 3 SELS.
There are then two bits per each clock to set the divider (1,2,4,8) being DIVMx and DIVSx
Settings the external (optional) crystal oscillators
These oscillators are set using the BCSCTL3 register.
I am not detailing this part, let's just say an interesting feature is that different internal capacitors can be coupled to the external crystal by setting this register.
Getting started to code
Finally, let's get to real coding.
You should check this video first : An Introduction to Code Composer Studio on the MSP430
A few things might be not completely clear, that's ok... we'll get here, you can also avoid soldering the optional crystal.
In the third video of the workshop the GPIO is used to blink an LED with a frequency set by a timer, whose frequency depends on a clock.
In the third exercise of the workshop we bump into this instruction :
BCSCTL3 |= LFXT1S_2;
If you are not used to C syntax, this is a short version of BCSCTL3 = BCSCTL3 | LFXT1S_2;
LFXT1S_2 is a constant (defined in the .h file) and its value is 0x20 (0010 0000).
By using an OR ( | ) operation with this constant on a variable we turn on in the variable (a register in this case) all the bits that are "1" in the constant leaving the others unchanged.
This is typical when we configure a register that contains different settings : we need to change just one part of it leaving the rest unchanged.
Example :
A = 1101 1011;
B = 0000 1110;
A |= B;
1101 1011 |
0000 1110
------------
A= 1101 1111
Example :
A = 1101 1011;
B = 0000 1110;
A |= B;
1101 1011 |
0000 1110
------------
A= 1101 1111
Similarly, if we need to turn off some bits, we will use an AND operation ( & ) which is visible in the same exercise with the following instruction :
IFG1 &= ~OFIFG;
In this case the IFG1 (Interrupt flag register) is used to clear the flag OFIFG which is it's second bit (0000 0010).
We use and AND when we want to turn off (set to 0) one or more bits, and with this operation only the bits that are "1" in the constant will remain unchanged, the others will be turned off.
So, our goal was to turn off the second bit, therefore we need to first reverse all the bit of the constant.
0000 0010 -> 1111 1101
This is done with a NOT operation ( ~ )
There is another way of singularly set bits on some specific registers, this si done using the _bis_xx calls, which are a bit special since they are assembly calls from C.
_bis_SR_register(SCG1 + SCG0);
_bis_SR_register(SCG1 + SCG0);
This is possible because the MPS430xx family supports some specific assembly instructions that can directly manipulate single bits.
Now, the next instruction should be a bit more understandable :
BCSCTL2 |= SELM_3 + DIVM_3;
The BCSCTL2 register configures MCLK and SMCLK, in this case we are targeting the CPU clock (MCLK) and we are setting two parameters :
1) We select the the source oscillator (SELM_x)
2) We select the frequency divider divider (DIVM_x)
Notice that doing BCSCTL2 |= SELM_3 + DIVM_3; is exactly the same thing as doing
BCSCTL2 |= SELM_3;
BCSCTL2 |= DIVM_3;
SELM_3 is 0011b and it represents the VLO (low frequency) oscillator, by using this we are planning to use our CPU very slowly so we are reasonably targeting an application that does not require CPU intensive calculations or anyway an extremely quick response.
Since we are just blinking an LED...
Moreover we use the highest divider DIVM_3 = 0011b = /8 from the set [1,2,4,8] so we are driving the CPU as slow as possible.
No comments:
Post a Comment