msp430 launchpad el microcontrolador mas barato

micro430

Bovino adolescente
#22
Bueno antes de iniciar como se crean los programas y demas lo principal que debemos saber del microcontrolador que vamos a ocupar, son sus principales caracteristicas:


1.- ALU de 16 bits que efectúa operaciones lógicas (AND, OR, XOR), substracciones, adiciones y comparaciones.

2.-RISC(Reduced Instruction Set Computing) con 27 instrucciones y 7 modos de direccionamiento.

3.-Arquitectura Ortogonal, además cualquier instrucción se puede usar con cualquier modo de direccionamiento.

4.-Todos los registros en la CPU son completamente accesibles.

5.-Las operaciones entre registros se llevan a cabo en un ciclo.

6.-Los registros de 16 bits reducen la cantidad de veces que se accede a la memoria al ejecutar una instrucción.

7.-El bus de direcciones de 16 bits permite el acceso y los brincos a lo largo de todo el mapa de memoria.

8.-El generador de constantes proporciona las 6 constantes mas usadas para reducir el tamaño del código y facilitar la
programación a través de instrucciones emuladas.

9.-Transferencias de memoria a memoria sin necesidad de registros intermedios.

10.- Instrucciones y modos de direccionamiento para 8 y 16 bits (Byte y Word).

11.-12 registros de propósito general que pueden almacenar tanto datos como direcciones.

12.-Construida utilizando lógica estática con la cual no hay un mínimo de frecuencia de operación, lo cual permita que la CPU pueda ser detenida.
 

micro430

Bovino adolescente
#23
Otra caracteristica que debemos tomar en cuenta a la hora de programar es :

La longitud de las instrucciones cambia, y no todas las instrucciones se ejecutan en un ciclo de reloj ya que pueden tardar de 1 a 5 ciclos de reloj, esto hace que estos microcontroladores sean una mezcla entre las principales arquitecturas (CISC y RISC).

El siguiente diagrama a bloques de la CPU MSP430 proporcionado por Texas Instruments ™ podemos observar los 16 registros que la conforman, así como la ALU de 16 bits la cual puede recibir sus operandos de cualquiera de los 16 registros los cuales a su vez a través del bus de direcciones y datos pueden acceder a cualquier parte de la memoria.

También podemos ver las banderas del Registro de Estado que son afectadas cuando se ejecuta una instrucción, las demás banderas en el registro de estado solo son afectadas para entrar a un modo de ahorro de energía o permitir las interrupciones enmascarables. Otro punto interesante en esta diagrama a bloques es que la ALU toma su señal de reloj desde MCLK y solamente esta.


 

vicocalan

Bovino maduro
#24
Hola, quisiera ver si me pudieras orientar sobre como generar dos salidas de pwm usando solo una entrada analogica con un potenciometro para variar la frecuencia de la señal, estoy aprendiendo a programar este micro y ando un poco perdido.
 

micro430

Bovino adolescente
#25
Hola, quisiera ver si me pudieras orientar sobre como generar dos salidas de pwm usando solo una entrada analogica con un potenciometro para variar la frecuencia de la señal, estoy aprendiendo a programar este micro y ando un poco perdido.
Lo que pides es algo ya mas avanzado, mi objetivo primordial es dar un curso introductorio, pero te puedo dar unas pistas, las salidad pwm las puedes generar ya sea con interrupciones o con el TIMER, para variar la frecuencia es usando el ADC10 donde ese valor que contenga el registro ADC10MEM lo tienes que tomar en cuenta para variar el ciclo util de la señal. Y que lenguaje estas usando??
 

vicocalan

Bovino maduro
#26
Estoy usando c con el compilador code composer, la señal pwm las estoy generando por medio del registro mclk, ya que necestio generar una señal de hasta 160 kHz maximo de acuerdo a la entrada del pot, y otra salida pwm con frecuencia maxima de 8kHz, mi problema es como hacer que estas dos frecuencias varien en funcion del adc10mem, como hablilito la segunda salida pwm???
 

micro430

Bovino adolescente
#27
Estoy usando c con el compilador code composer, la señal pwm las estoy generando por medio del registro mclk, ya que necestio generar una señal de hasta 160 kHz maximo de acuerdo a la entrada del pot, y otra salida pwm con frecuencia maxima de 8kHz, mi problema es como hacer que estas dos frecuencias varien en funcion del adc10mem, como hablilito la segunda salida pwm???
Haber haber creo ya no entendi, quieres generar una señal pwm con dos frecuencias diferentes o solo quieres variar la frecuencias de la señal. Y como va tu codigo.
 

vicocalan

Bovino maduro
#28
Quiero habilitar dos pines para que me generen sus salidas pwm con frecuencias diferentes cada uno que varien en funcion de una sola entrada analogica, con las frecuencias que te habia dicho antes.
Este es el codigo que tengo hasta ahora. En la entrada analogica los valores que me leen se vuelven muy inestables y hace que la frecuencia oscile bastante. Solamente ya he podido habilitar una sola salida, no he buscado como habilitar la otra para que tambien varie su frecuencia con respecto al pot y pues cuando activo el registro P1DIR |= BIT0; BIT1 Y P1DIR |= 0X0c; solamente me funciona el primer pin el otro se mantiene en alto siempre y no varia en el osciloscopio.

#include <msp430.h>

unsigned int i;
unsigned char d;

void main(void)
{
WDTCTL = WDTPW + WDTHOLD; // Stop WDT

if (CALBC1_16MHZ ==0xFF || CALDCO_16MHZ == 0xFF)
{
while(1); // If calibration constants erased
// do not load, trap CPU!!
}
//1Mhz
BCSCTL1 = CALBC1_16MHZ; // Set range
DCOCTL = CALDCO_16MHZ; // Set DCO step + modulation */

ADC10CTL1 = INCH_1 + ADC10DIV_0; // configurar entrada analogica y preescaler por 1 para tener la misma frec del reloj
ADC10CTL0 = SREF_2 + ADC10SHT_3 + REFON + ADC10ON; // colocar una referencia externa de 5v en el pin 6


P1DIR |= BIT0; // configurar P1.0 como salida
P1DIR |= 0X0c; // configurar P1.2 como salida

P1SEL |= 0x0C; // P1.2 a al puerto TA0.1
CCR0 = 1000; // periodo del PWM
CCTL1 = OUTMOD_7; // CCR1 reset/set
TACTL = TASSEL_2 + MC_1; // reloj SMCLK en modo activado

while (1)
{
ADC10CTL0 |= ENC + ADC10SC; //activacion del adc y conversion.
while (ADC10CTL1 & ADC10BUSY); // ADC10BUSY?
if (ADC10MEM < 750) // ADC10MEM = A11 > 0.65?
P1OUT |= 0x01; // Set P1.0 LED on
else
P1OUT &= ~0x01; // Clear P1.0 LED off
CCR0=ADC10MEM*64;
CCR1=CCR0/2;


for(d=240;d>0;d--); // retraso para que la referencia se establice.
for(d=240;d>0;d--);


}
}
 

micro430

Bovino adolescente
#30
Quiero habilitar dos pines para que me generen sus salidas pwm con frecuencias diferentes cada uno que varien en funcion de una sola entrada analogica, con las frecuencias que te habia dicho antes.
Este es el codigo que tengo hasta ahora. En la entrada analogica los valores que me leen se vuelven muy inestables y hace que la frecuencia oscile bastante. Solamente ya he podido habilitar una sola salida, no he buscado como habilitar la otra para que tambien varie su frecuencia con respecto al pot y pues cuando activo el registro P1DIR |= BIT0; BIT1 Y P1DIR |= 0X0c; solamente me funciona el primer pin el otro se mantiene en alto siempre y no varia en el osciloscopio.

#include <msp430.h>

unsigned int i;
unsigned char d;

void main(void)
{
WDTCTL = WDTPW + WDTHOLD; // Stop WDT

if (CALBC1_16MHZ ==0xFF || CALDCO_16MHZ == 0xFF)
{
while(1); // If calibration constants erased
// do not load, trap CPU!!
}
//1Mhz
BCSCTL1 = CALBC1_16MHZ; // Set range
DCOCTL = CALDCO_16MHZ; // Set DCO step + modulation */

ADC10CTL1 = INCH_1 + ADC10DIV_0; //Habilitas canal 1 A1 y ADC10DIV sin division
ADC10CTL0 = SREF_2 + ADC10SHT_3 + REFON + ADC10ON; // Habilitas +Veref y Vss, se mantiene el muestreo cada 16 ciclos adc,


P1SEL|= BIT0+BIT2
P1DIR |= BIT0+BIT2; // Seria mejor que habilites haci las salidads

CCR0 = 1000; // periodo del PWM
CCTL1 = OUTMOD_7; // CCR1 reset/set
TACTL = TASSEL_2 + MC_1; // Submaster clock , modo arriba cuenta hasta ccr0

while (1)
{
ADC10CTL0 |= ENC + ADC10SC; //activacion del adc y conversion.
while (ADC10CTL1 & ADC10BUSY); // esta ocupado ADC10?
if (ADC10MEM < 750) // ADC10MEM = A11 > 0.65?
P1OUT |= 0x01; // Set P1.0 LED on
else
P1OUT &= ~0x01; // Clear P1.0 LED off
CCR0=ADC10MEM*64;
CCR1=CCR0/2;


for(d=240;d>0;d--); // retraso para que la referencia se establice.
for(d=240;d>0;d--);


}
}
Pues haber si corre como quieres hay me avisas
 

micro430

Bovino adolescente
#33
Bueno despues de algun tiempo continuo con el tema, debo aclarar que la mayoria de la teoria viene en la hoja de datos por lo que solo voy a dar los puntos importantes ademas para llegar a algun ejemplo basico todavia me van a ser falta un poco mas de tiempo.

LOS REGISTROS DE LA CPU

La CPU cuenta en total con 16 registros, los primeros 4 cumplen con funciones especificas y sus valores tienen repercusiones inmediatas en el dispositivo, mas adelante veremos porque. Los otros 12 son como ya lo mencionamos de propósito general y pueden ser usados para contener datos y direcciones lo cual permite usarlos como variables o apuntadores ya que todos son de 16 bits. A continuación describimos cada uno de ellos:

PC. contador de programa

Se encarga de apuntar a la siguiente instrucción a ejecutar. Como cada instrucción emplea un numero par de bytes (2, 4 o 6) el PC se incrementa de acuerdo a esa cantidad de bytes correspondiente. Ya que el PC solo contiene números pares el bit menos significativo de este registro siempre será cero.

Generalmente se trata de evitar la manipulación de este registro, salvo que se desee implementar un switch-case estilo C/C++ o un manipulador de interrupciones.

SP. Apuntador de pila

Como su nombre lo dice es un registro apuntador lo que quiere decir que contiene una dirección. ¿Dirección de qué? , pues la dirección de la Pila la cual es de tipo FILO (First In Last Out es decir primero en entrar último en salir) y se sitúa en la posición de la RAM que asignemos a este registro. Nos es útil para que las subrutinas e interrupciones se lleven a cabo de manera correcta, se recomienda que sea lo primero que se inicialice y que después de eso se evite su uso ya que puede provocar que el programa se descontrole. Si es completamente necesario el uso de la pila se recomienda usar una instrucción POP por cada instrucción PUSH (ver el set de instrucciones).

Todo esto quedara claro más adelante cuando comencemos con los primeros programas.

Cabe mencionar que por ejemplo en los PIC´s la pila tiene un numero de niveles fijo, en algunos casos es de 8 o mas, esto limita nuestros programas ya que no puede haber mas de cierto numero de subrutinas o interrupciones.

SR. registro de estado

En este registro se hallan diversas banderas que nos informaran como su nombre lo dice del estado del microcontrolador, a pesar de que el registro es de 16 bits, solo están implementados 9 por lo que los otros 7 serán usados por el generador de constantes. En este registro se almacenan 4 banderas las cuales reflejan el estado de la ALU después de que una instrucción es ejecutada, estos son: C( Acarreo), Z(Cero), N(Negativo), V(Sobre flujo).

También contiene 4 bits más que definen el modo de operación en el que se encuentra el microcontrolador, los cuales se explican en la sección de Modos De Ahorro De Energía, por lo pronto enunciamos la función de cada uno de estos 4 bits. SCG1(Sistema generador de reloj 1), SCG0(Sistema generador de reloj 0), OSCOFF, CPUOFF.

El ultimo bit por mencionar es el de GIE (General Interrupt Eneable o Habilitar Interrupciones Globales) el cual al estar en 1 permite las interrupciones de manera global.

Muchos bits aquí mencionados se explicaran en su momento, por ahora es suficiente con entender por ejemplo los bits que por lo regular vienen en otro tipo de microcontroladores (C, Z, N y V) los demás son solo implementados en los MSP430 y por lo tanto describiremos su uso en los periféricos a los cuales de alguna manera pertenecen.

R2 Y R3. Generadores de constantes

Estos registros contienen las 6 constantes más usadas las cuales sirven para emular instrucciones, esto con el objetivo de hacer más ágil y fácil la programación, por ejemplo para incrementar se usa 1 y 2, para borrar un registro se usa 0 etc. A través de el generador de constantes se pueden obtener 24 instrucciones emuladas.

R4 A R15. Registros de proposito general



Como ya se ha mencionado, estos registros pueden guardar tanto datos como direcciones ya que todos son de 16 bits. Es bueno mencionar que las operaciones entre registros son mucho más rápidas que las que tienen que acceder a la memoria (ver modos de direccionamiento). Se recomienda usar estos registros lo más posible.

En el momento de la programación se hara referencia de estos registros mediante las notaciones aquí expuestas, es decir PC,SP,SR,R4-R15.
 

micro430

Bovino adolescente
#34
Modos de direccionamiento.


Los modos de direccionamiento al igual que el set de instrucciones serán empleados solo por el lenguaje ensamblador base principal para nuestro pequeño tutorial.

Los modos de direccionamiento son usados para que la CPU conozca la manera en que le serán accedidos los operandos de la instrucción a ejecutar. Las instrucciones se dividen en dos grandes grupos:

Operando Simple del tipo: [instrucción] destino
Doble Operando del tipo: [instrucción] fuente, destino

Los MSP430™ soportan 7 modos de direccionamiento, de los cuales solo 4 de ellos son implementados físicamente en la CPU (Registro, Indexado, Indirecto e Indirecto con autoincremento) es decir grabados en cilicio, 2 de ellos resultan de usar el PC como un registro (Simbólico e Inmediato) y el ultimo se obtiene indexando un registro cuyo valor es cero (Absoluto), es decir SR cuando se usa como Generador De Constantes.

Las instrucciones de Operando Simple pueden ser usadas con los 7 modos de direccionamiento, en el caso de las instrucciones de Doble Operando, para el caso de su operando fuente se pueden usar los 7 modos de direccionamiento, pero para el caso de el operando destino solo se pueden usar 4.

A continuación se describen los 7 modos de direccionamiento con ejemplos, una breve descripción, ya que no es el objetivo aburrir con teoría complicada acerca de los modos de direccionamiento y por ultimo una tabla con la cantidad de ciclos de reloj que se tarda en ejecutar alguna instrucción dependiendo sus modos de direccionamiento.


Modo registro

Ejemplo de Operando simple:

Registro Antes. R8=0000h
Instrucción INC R8
Registro Después. R8=0001h


Descripción: Dado que utilizamos la instrucción INC, lo que hace este ejemplo es incrementar en 1 el valor del registro 8 (R8).

Ejemplo de Operando doble:

Registros Antes. R4=0010h, R5=07F0h
Instrucción MOV R4,R5
Registro Después. R4=0010h, R5=0010h


Descripción: Ya que se usa la instrucción MOV lo que hace el ejemplo es que mueve el contenido de R4 a R5.Como podemos ver independientemente de la instrucción a usar se nota que solo se usaron registros de la CPU, de hecho este modo de direccionamiento solo se puede usar con los 16 registros de la CPU lo cual hace que este modo sea de los mas veloces y que menos espacio ocupa.

Modo indexado

Sintaxis:
[instrucción] n(destino)
[instrucción] n(fuente), *otro modo


Donde: [instrucción] es cualquiera en el set de instrucciones, fuente y destino son cualquier registro de la CPU, n es un numero cualquiera y *otro modo significa cualquier otro modo de direccionamiento disponible para el destino incluyendo indexado.

Ejemplo de Operando simple:

Registro Antes. R8=0300h
Locación de memoria antes. 0303h=FF0Eh

Instruccion DEC 3(R8)

Registro Después. R8=0300h
Locación de memoria despues. 0303h=FF0Dh


Descripción: La instrucción no altera a R8 si no que altera a la locación de memoria R8 + 3, es decir 300+3=303 que es donde se realiza el decremento ya que se utilizo la instrucción DEC.

Ejemplo de Operando doble:
Registro Antes. R4=0240h, R5=A0F1h
Locación de memoria antes 0245h=FFFFh y A0F7=O777h

Instrucción MOV 5(R4), 6(R5)

Registro Después. R4=0240h, R5=A0F1h
Locación de memoria despues 0245h=FFFFh y A0F7=FFFFh



Descripción: Como en el caso anterior no se modifican los registros R4 ni R5 si no que se modifica el contenido de la dirección R4 +5 y R5+6 es decir (240h+5h=245h) y (A0F1h+6h=A0F7h). Así como con el modo registro, los operandos solo pueden ser registros de la CPU.

Modo simbolico

Sintaxis:
[instrucción] etiqueta1
[instrucción] etiqueta1, *otro modo


Donde: [instrucción] es cualquiera en el set de instrucciones, etiqueta1 es como su nombre lo dice una etiquete la cual contiene una dirección y *otro modo significa cualquier otro modo de direccionamiento disponible para el destino incluyendo el simbólico.

Ejemplo de Operando simple:

Locación de memoria antes ETQ1=FF0Eh
Instrucción CLR ETQ1
Locación de memoria después ETQ1=0000h


Descripción: ETQ1 es una etiqueta que hace referencia a una localidad de memoria, en este caso borra la localidad de memoria ya que eso hace CLR.

Ejemplo de Operando doble:

Locación de memoria antes ETQ1=FEAFh y ETQ2=7421h
Instrucción MOV ETQ1, ETQ2
Locación de memoria después ETQ1=FEAFh y EQT2=FEAFh


Descripción: Como podemos ver el contenido de ETQ1 se mueve a ETQ2.

Modo absoluto

Sintaxis:

[instrucción] &etiqueta1
[instrucción] &etiqueta1, *otro modo


Donde: [instrucción] es cualquiera en el set de instrucciones, etiqueta1 es una etiqueta la cual contiene una dirección , *otro modo significa cualquier otro modo de direccionamiento disponible para el destino incluido Absoluto y "&" es el que caracteriza a este modo.

Ejemplo de Operando simple:

Locación de memoria antes ETQ1=FF0Eh
Instrucción CLR &ETQ1
Locación de memoria después ETQ1=0000h


Descripción: Como podemos ver ocurre exactamente lo mismo que con el modo simbólico esto porque la función que cumplen es la misma, lo único que cambia es como la hacen, aunque como usuarios nunca nos enteramos de la diferencia.

Ejemplo de Operando doble:

Locación de memoria antes ETQ1=FEAFh y ETQ2=7421h
Instrucción MOV &ETQ1, &ETQ2
Locación de memoria después ETQ1=FEAFh y EQT2=FEAFh


Descripción: Ocurre lo mismo que en el modo anterior, edemas de que estos modos cumplen la misma función además generan la misma cantidad de código.

Modo indirecto

Sintaxis:

[instrucción] @fuente
[instrucción] @fuente, *otro modo


Donde: [instrucción] es cualquiera en el set de instrucciones, fuente es cualquier registro de la CPU, *otro modo significa cualquier otro modo de direccionamiento disponible para el destino y "@" caracteriza a este modo.

Ejemplo de Operando simple:

Registro Antes. R5=0240h
Locación de memoria antes 0240h=0021h

Instrucción CLR @R8

Registro Después. R5=0240h
Locación de memoriaantes 0240h=0000h


Descripción: Podemos notar que R5 no se ve afectado si no el contenido de R5

Ejemplo de Operando doble:

Registro Antes. R4=0060h, R9=1000h
Locación de memoria antes 0060h=AAA0

Instrucción MOV @R4, R9

Registro Después. R4=0060h, R9=AAA0h
Locación de memoria despues 0060h=AAA0



Descripción: R4 esta actuando como apuntador, lo que hace la instrucción es mover el contenido de la dirección apuntada por R4 al registro 9 (R9) esto se hace sin alterar R4. Hay que mencionar que este modo de direccionamiento es exclusivo de la fuente.

Modo indirecto autoincrementado

Sintaxis:

[instrucción] @fuente+
[instrucción] @fuente+, *otro modo


Donde: [instrucción] es cualquiera en el set de instrucciones, fuente es cualquier registro de la CPU, *otro modo significa cualquier otro modo de direccionamiento disponible para el destino y "@" junto con "+" caracterizan a este modo.

Ejemplo de Operando simple:

Registro Antes. R7=0F28h
Locación de memoriaantes 0F28h=0062h

Instrucción DINC @R7+

Registro Después. R7=0F29h
Locación de memoria despues 0F28h=0064h



Descripción: En este caso se usa la instrucción de doble incremento, lo cual se hace sobre el contenido de la dirección a la que apunta R7, pero aquí si se modifica el registro que usamos como apuntador, es decir R7=R7+1.

Ejemplo de Operando doble:

Registro Antes. R5=FF00h R9=00A0h
Locación de memoria antes FF00h=0034h

Instrucción MOV @R5+, R9

Registro Después. R5=FF01h R9=0034h
Locación de memoria despues FF00h=0034h


Descripción: Dado que R5 actua como apuntador, lo que se modifica es R9 ya que se copia el valor apuntado por R5 a R9 y también R5 ya que se incrementa en 1. También hay que mencionar que este modo solo es para la fuente al igual que el anterior.

Modo inmediato

Sintaxis:

[instrucción] #cte, *otro modo



Donde:: es cualquiera en el set de instrucciones, cte es un valor numérico constante, *otro modo significa cualquier otro modo de direccionamiento disponible para el destino y "#" caracteriza a este modo.

Ejemplo de Operando doble:

Registro Antes. R15=0FF0h
Instrucción MOV #000F, R15
Registro Después. R15=00Fh


Descripción: Mueve la constante 000Fh al registro 15 (R15), este modo es solo para el operando fuente.
 

micro430

Bovino adolescente
#35
Bueno despues de un tiempo sin adelantar nada seguire un poco mas.

Podria seguir escribiendo mas sobre la teoria pero es tan amplio que necesitaria varios temas mas por lo que en adelante voy a ir combinando teoria con algo mas practico para que no sea tan tedioso.


Les dejo como se estructura un programa para que en el proximo tema les deje ya un programa practico "encendido y apagado de un led".



#include "msp430g2553.h" ; define la libreria del micro a utilizar

;-------------------------------------------------------------------------------
ORG 0xC000 ;Inicio del programa es aqui donde inicia la flash
;-------------------------------------------------------------------------------
main
RESET
MOV.W #0x400,SP ; Inicialización del stackpointer se coloca en el tope de la pila mas adelante explicare porque
MOV.W #WDTPW+WDTHOLD,&WDTCTL ; Watchdog timer detenido
MOV.B &CALBC1_1MHZ,&BCSCTL1 ; DCO funcionando a la frecuencia
MOV.B &CALDCO_1MHZ,&DCOCTL ; calibrada de 1MHz
;-------------------------| Programa Principal |--------------------------------

; AQUI VA NUESTRO PROGRAMA PRINCIPAL

;-------------------------| Subrutinas |--------------------------------


;AQUI VAN A IR LAS RUTINAS O SUBRUTINAS

;-------------------------------------------------------------------------------
; Vectores de Interrupción
;-------------------------------------------------------------------------------
ORG 0xFFFE ;Vector de RESET del MSP430
DW RESET

END
END main
 
Arriba