La FRDM-KL25Z és una plataforma de desenvolupament per a la familia de porcesadors Kinetis L Series KL1x y KL2x basat en el procesador ARM Cortex M0 de 32 bits. Aquesta plataforma és distribuïda per Freescale, i és una gran alternativa a Arduino a causa de la seva senzilla programació i el seu baix cost.

FRDM-KL25Z 

La FRDM-KL25Z té unes grans prestacions per a poder fer projectes d'instrumentació, robotica o pràcticament qualsevol prototip a dissenyar degut a: la seva amplia memòria flash y SRAM, la alta freqüència d'operació, el gran nombre de pins, entre els quals hi ha varis protocolos de comunicació, al acceleròmetre integrat, un LED a disposició, etc.

A més a més, es pot fer servir amb el entorn de programació CodeWarrior de Freescale o amb el compilador en línia MBED que utilitza un sistema fàcil i ràpid amb moltes llibreries per facilitar la programació.

Característiques modifica

 
ARM Cortex-M0

Característiques principals modifica

Les característiques de la FRDM-KL25Z són les següents:

  • 32 Bits ARM Cortex M0+ Core.
  • 128KB de flash.
  • 16KB de SRAM.
  • Freqüència de operació fins a 48 Mhz.
  • 2xSPI, 2xI2C, 3xUART, 6xPWM, 6xADC, DAC, GPIO.
  • USB OTG d'alta velocitat.
  • OpenSDA USB program and debug interface.
  • LED RGB PWM per a l'usuari.
  • Touch slider capacitiu.
  • Acelerometre de 3 eixos digital integrat.
  • Voltatge d'operació: 1.71V - 3.6V.
  • Voltatge d'entrada: 4.3V - 9V.
  • Botó de reset.
  • Ports d'expansio per a IN/OUT.

Cortex M0 modifica

El cortex M0 és un microcontrolador RISC amb una arquitectura Von Neumann, és a dir, consta de un sol bus per a les dades i les instruccions. Aquest microcontrolador utilitza un conjunt de instrccions anomenades THUMB el qual esta compost majoritàriament per instruccions de 16 bits, encara que existeixen algunes funcions que utilitzen instruccions de 32 bits. En general, el còrtex M0 té un conjunt de 56 instruccions base, i per això poden tenir més d'una forma.

El ARM Córtex M0+ consta de 2 nivells de pipeline, 16 registres de 32 bits, el NVIC y un multiplicador de 32 bits que varia segons el fabricant. En de la FRDM-KL25Z compta amb un multiplicador de un sol cicle.

El Córtex M0 compta amb el següent:

  • 32 interrupcions amb 4 nivell de prioritat cadascuna
  • 1 NMI (Nonmaskable Interrupt)
  • Mapa de memoria definit per a la portabilitat del software, és a dir, el espai de memoria és lineal
  • Systick Timer per a l'ús de RTOS
  • Instrucció SVC per a l'ús de RTOS
  • Excepción Fault Handling per a detectar errors en el sistema
  • Suport de format de memoria little endian y big endian

Cortex M0+ modifica

Introducció del Cortex M0+ modifica

El Cortex-M0+ es un superset optimitzat del Cortex-M0. El Cortex-M0+ té una compatibilitat de instruccions complerta amb el Cortex-M0 permetent fer servir les mateixes eines de compilació i debugging. El pipeline del Cortex-M0+ té 2 etapes (una menys que el Cortex M0) el que permet un estalvi major de energia. A més a més, existeix una opció silicon que és afegir el Micro Trace Buffer (MTB) que dona una traça simple de instruccions. En el Cortex-M0+ poden ser afegides algunes característiques del Cortex-M3 i Cortex-M4, com per exemple la unitat de protecció de memoria (MPU).

Les característiques claus del Cortex-M0+ són:

  • Arquitectura ARMv6-M
  • 2 etapes de pipeline
  • Set d'instruccions: (lel mateix que el Cortex-M0)
    • Thumb-1 (most), missing CBZ, CBNZ, IT.
    • Thumb-2 (some), only BL, DMB, DSB, ISB, MRS, MSR.
    • Hardware de multiplilcació d'integers de 32-bits amb resultat de 32 bits
  • De 1 a 32 interrupcions, més NMI

Les silicon options són les següents:

  • Velocitat del hardware de multiplicació d'integers: de 1 cicle o de 32 cicles
  • 8 regions de MPU (el mateix que el Cortex-M3 i el Cortex-M4)
  • Vector table relocation (el mateix que el Cortex-M3 i el Cortex-M4)
  • Únic cicle del port I/O (únic pel Cortex-M0+)
  • Micro Trace Buffer (MTB) (únic pel Cortex-M0+)

Registres del Córtex M0+ modifica

El Córtex M0+ conté 16 registres de 32 bits i alguns registres especials:

  • R0-R12: Registres d'ús general. Aquests estan dividits en registres alts (del 0 al 7) i baixos (8 al 12).
  • R13- Stack Pointer: Aquest registre es seleccionat mitjançant el bit 1 del registre de Control:
    • 0: Main Stack Pointer (MSP): És el stack pointer després del reset i és utilitzat durant les ISR
    • 1: Process Stack Pointer (PSP): Aquest és utilitzat en el mode thread
  • R14-Link Register: Emmagatzema un valor de retorn per a les rutines, funcions e ISRs
  • R15-PC: Conté la direcció actual del programa, al fer el reset aquest registre es carrega amb 0x00000004.

Modes d'usuari del porcessador modifica

El processador té 7 modes bàsics d'operació:

  • Mode usuari: És el mode on s'executen la majoria de les tasques (sense privilegis especials)
  • FIQ: Quan s'activa una interrupció de prioritat alta
  • IRQ; Quan s'activa una interrupció de prioritat baixa
    • Supervisor: Quan s'activa el reset o una interrupció Software
    • Abort: Per a gestionar violacions d'accés a memoria
    • Indefinit: Per a gestionar instruccions indefinides
    • System: Mode privilegiat. En algunes versions en aquest mode s'utilitzen els mateixos registres que en el mode usuari

Avantatges i Desavantatges modifica

Avantatges modifica

  • Baix cost
  • Procesador ARM Cortex M0+
  • Fàcil de programar
  • La FRDM-KL25Z esta estandarditzada i per tant té un gran suport en la xarxa
  • Bons entorns de programació
  • Flexibilitat per a poder fer un gran nombre de projectes
  • Molta documentació
  • Gran nombre de pins
  • Possibilitat de programar a baix nivell

Desavantatges modifica

  • IDE offline (code warrior) és car
  • Baix rendiment per a prototips grans

Arduino UNO vs FRDM-KL25Z modifica

 
ARDUINO UNO
Processador Voltatge d'entrada Voltatge d'operació Velocitat CPU Analògics I/O PWM SRAM Flash USB UART LED
FRDM-KL25Z ATmega328P 7-12 V 5 V 16 MHZ 6 inputs / 0 outputs 6 2 KB 32 KB Estàndard 1 NO
Arduino UNO ARM Cortex M0+ 4.3V - 9V 1.71V - 3.6V 48 Mhz 6 inputs / 0 outputs 6 16 KB 128 KB MicroUSB 3

Còdi d'exemple modifica

A continuació es mostren diferents exemples de codi en les plataformes de Mbed i de CodeWarrior:

Mbed modifica

Touch - Hello World! modifica

#include "mbed.h"
#include "TSISensor.h"

int main(void) {
 PwmOut led(LED_GREEN);
 TSISensor tsi;

 while (true) {
 led = 1.0 - tsi.readPercentage();
 wait(0.1);
 }
}

Accelerometre - Hello World! modifica

#include "mbed.h"
#include "MMA8451Q.h"

#define MMA8451_I2C_ADDRESS (0x1d<<1)

int main(void) {
 MMA8451Q acc(PTE25, PTE24, MMA8451_I2C_ADDRESS);
 PwmOut rled(LED_RED);
 PwmOut gled(LED_GREEN);
 PwmOut bled(LED_BLUE);

 while (true) {
 rled = 1.0 - abs(acc.getAccX());
 gled = 1.0 - abs(acc.getAccY());
 bled = 1.0 - abs(acc.getAccZ());
 wait(0.1);
 }
}

Led tricolor parpadejant modifica

#include "mbed.h"

int main() { 

 DigitalOut rled(LED_RED);
 DigitalOut bled(LED_BLUE);
 DigitalOut gled(LED_GREEN); 

 while (1) { 
 rled = 0;
 gled = 1;
 bled = 1;
 wait(1);
 rled = 1;
 gled = 0;
 bled = 1;
 wait(1);
 rled = 1;
 gled = 1;
 bled = 0;
 wait(1); 
 }
}

Comunicació amb el PC mitjançant port serie modifica

#include "mbed.h" 

Serial pc(USBTX, USBRX);

int main() {
 pc.printf("Echoes back to the screen anything you type\n");
 while(1) {
 pc.putc(pc.getc());
 }
}

Code Warrior modifica

Led Tricolor modifica

#include "derivative.h" /* include peripheral declarations */

#define SLOW_BLINK (10000000)
#define FAST_BLINK (1000000)
#define BLINK_DELAY FAST_BLINK

#define RED				(18) 
#define RED_SHIFT		(1 << 18)
#define GREEN			(19)
#define GREEN_SHIFT		(1 << 19)
#define BLUE			(1)
#define BLUE_SHIFT		(1 << 1)

#define RED_OFF			(GPIOB_PSOR = RED_SHIFT)
#define RED_ON			(GPIOB_PCOR = RED_SHIFT)
#define RED_TOGGLE		(GPIOB_PTOR = RED_SHIFT)

#define GREEN_OFF		(GPIOB_PSOR = GREEN_SHIFT)
#define GREEN_ON		(GPIOB_PCOR = GREEN_SHIFT)
#define GREEN_TOGGLE	(GPIOB_PTOR = GREEN_SHIFT)

#define BLUE_OFF		(GPIOD_PSOR = BLUE_SHIFT)
#define BLUE_ON			(GPIOD_PCOR = BLUE_SHIFT)
#define BLUE_TOGGLE		(GPIOD_PTOR = BLUE_SHIFT)

void delay_time(int);
void init_leds();
void red_on();
void red_off();
void green_on();
void green_off();
void blue_on();
void blue_off();
/********************************************************************/
int main (void)
{
	
	int i=0;

	init_leds();

	while(1)
 {
		i++;						/* just a count variable. */
		red_on();
		delay_time(BLINK_DELAY);	/* Red */
		red_off();
		green_on();
		delay_time(BLINK_DELAY);	/* Green */
		green_off();
		blue_on();
		delay_time(BLINK_DELAY);	/* Blue */
		red_on();
		delay_time(BLINK_DELAY);	/* Blue + Red */
		green_on();
		blue_on();
		delay_time(BLINK_DELAY);	/* Red + Green */
		red_off();
		blue_on();
		delay_time(BLINK_DELAY);	/* Green + Blue */
		red_on();
		delay_time(BLINK_DELAY);	/* Green + Blue + Red */
		green_off();
		blue_off();
	}
}

void red_on(){
	RED_ON;
}

void red_off(){
	RED_OFF;
}

void green_on(){
	GREEN_ON;
}

void green_off(){
	GREEN_OFF;
}

void blue_on(){
	BLUE_ON;
}

void blue_off(){
	BLUE_OFF;
}

/********************************************************************/

void delay_time(int number){
 int cnt;
 for(cnt=0;cnt<number;cnt++);
}
/********************************************************************/

/********************************************************************/
/*	init_leds()
 * initialize the ports for LEDs
 * ******************************************************************/


 void init_leds()
 	 {
	 
 /* 
	 * Initialize the Red LED (PTB18)
	 */

		/* Turn on clock to PortB module */
		SIM_SCGC5 |= SIM_SCGC5_PORTB_MASK;

		/* Set the PTB18 pin multiplexer to GPIO mode */
		PORTB_PCR18 = PORT_PCR_MUX(1);

		/* Set the initial output state to high */
		GPIOB_PSOR |= RED_SHIFT;

		/* Set the pins direction to output */
		GPIOB_PDDR |= RED_SHIFT;


	/*
	 * Initialize the Green LED (PTB19)
	 */

		/* Turn on clock to PortB module */
		SIM_SCGC5 |= SIM_SCGC5_PORTB_MASK;

		/* Set the PTB19 pin multiplexer to GPIO mode */
		PORTB_PCR19 = PORT_PCR_MUX(1);

		/* Set the initial output state to high */
		GPIOB_PSOR |= GREEN_SHIFT;

		/* Set the pins direction to output */
		GPIOB_PDDR |= GREEN_SHIFT;



	/*
	 * Initialize the Blue LED (PTD1)
	 */

		/* Turn on clock to PortB module */
		SIM_SCGC5 |= SIM_SCGC5_PORTD_MASK;

		/* Set the PTD1 pin multiplexer to GPIO mode */
		PORTD_PCR1 = PORT_PCR_MUX(1);

		/* Set the initial output state to high */
		GPIOD_PSOR = BLUE_SHIFT;

		/* Set the pins direction to output */
		GPIOD_PDDR |= BLUE_SHIFT;
	}

PWM modifica

#include "MKL25Z4.h"
#include <math.h>

int main()
{
	
	int count = -250;
 MCG_BASE_PTR->C1 = MCG_C1_IREFS_MASK | MCG_C1_IRCLKEN_MASK; // INTERNAL CLOCK|MCGIRCLK ACTIVE(SET)
 MCG_BASE_PTR->C2 = MCG_C2_IRCS_MASK; // SELECT FAST INTERNAL REFERENCE CLOCK (1)
 SIM_BASE_PTR->SCGC6 |= SIM_SCGC6_TPM2_MASK; // ENABLE TPM2 CLOCK GATE
 SIM_BASE_PTR->SOPT2 |= SIM_SOPT2_TPMSRC(3); // MCGIRCLK IS SELECTED FOR TPM CLOCK

 TPM2_BASE_PTR->SC |= TPM_SC_PS(2); // --preescaler
 TPM2_BASE_PTR->SC |= TPM_SC_CMOD(1); // COUNTER INC. ON EVERY CLOCK

 TPM2_BASE_PTR->MOD = 10000; // Frecuency

 SIM_BASE_PTR->SCGC5 |= SIM_SCGC5_PORTB_MASK;
 PORTB_BASE_PTR->PCR[2] = PORT_PCR_MUX(3); Mux mode

 TPM2_BASE_PTR->CONTROLS[0].CnSC = TPM_CnSC_MSB_MASK | TPM_CnSC_ELSB_MASK; // SELECT CHANNEL MODE

 //TPM2_BASE_PTR->CONTROLS[0].CnV = 750; 
 while(1){
 	if(TPM2_BASE_PTR->CONTROLS[0].CnV == 1250 || TPM2_BASE_PTR->CONTROLS[0].CnV == 750){
 		count = -count;
 	}
 	TPM2_BASE_PTR->CONTROLS[0].CnV +=count;
 }

 
 return 0;
}

Repositoris i exemples de codi modifica

[1] Exemple LED

[2] Exemple ADC

[3] Exemple DAC

[4] Repositori de còdi

Web d'interès modifica

[5] NXP Oficial web

[6] FRDM-KL25Z Development-tools

[7] Mbed Developer

[8] Mbed Platforms

[9] Mbed SerialPC

Referències modifica

  1. «Exemple de LED».
  2. «ADC Exemple».
  3. «Exemple DAC».
  4. «Repositori de còdi».
  5. «nxp oficial».[Enllaç no actiu]
  6. development-tools/freedom-development-boards/freedom-development-platform-for-kinetis-kl14-kl15-kl24-kl25-mcus:FRDM-KL25Z
  7. «Mbed developer» (en anglès).
  8. «Mbed Plataforms» (en anglès).
  9. «Mbed SerialPC» (en anglès).