Sie sind auf Seite 1von 40

CURSO DE PROGRAMACIN DEL DSP TMS320F2812

M.Sc. Victor Sotelo


CLASE 1
Carpetas del CD:

CDVaritek19.- Contiene los manuales de usuario, datasheets, zipeados, manuales de perifricos

DSP2812_2010.- Contiene los cdigo fuente de los laboratorios para la versin 4 del Code Composer,
los archivos ms actualizados estn en esta pgina web.

Colcacode V3.- Instalador del programa Colcacode en la versin 2, las nuevas versiones se pueden
bajar de esta pgina web.

CC4.- Para instalar el code composer 4 se recomienda bajar la ltima versin en la pgina web de
texas instruments: www.ti.com buscar con las palabras code composer 4.

http://focus.ti.com/docs/toolsw/folders/print/ccstudio.html

Elija la opcin : TMDSCCS-HWN01A

Hay que inscribirse con datos personales y un email previamente.

Instalacin del CC4

* Instalar el programa "setup_CCS_4_Platinum.zip"

* Instalar los dos archivos zippeados:


sprc077.zip
sprc097.zip Buscar la versin v120 en la siguiente referencia.

La ltima versin de ambos se puede encontrar en la pgina web del tms320f2812:

http://focus.ti.com/docs/prod/folders/print/tms320f2812.html

El programa que viene en el sprc097, "DSP281x_HeaderFiles", baja una serie de cabeceras con todos
los registros que se van a direccionar, de manera que la programacin sea ms sencilla gracias a las
estructuras que han sido aadidas en sus archivos, tambin incluye los archivos de configuracin
obligatoria que se deben incluir en todo proyecto. La ruta de la carpeta que se crea es:

C:\tidcs\c28\dsp281x\v120

El programa que viene en el sprc077 es un software para el manejo de motores de induccin, lo


interesante es que baja una serie de programas y libreras que se pueden utilizar para el manejo de
perifricos. La ruta de la carpeta que se crea es:

C:\tidcs\DMC\c28\v32x

* Instalar la carpeta de laboratorios

La carpeta de laboratorios "DSP2812_2010" debe ser instalada bajo la ruta principal de disco duro
"C:\\"

CLASE 2
El Code Composer V4

Cuando se carga por primera vez el Code Composer versin 4, hay que seleccionar la opcin de
usar una licencia libre limitada. "Use Free Limited License". Se debe registrar en la pgina web de
Texas Instruments y luego el servidor le enviar un correo con el archivo conteniendo la licensia.

Workspaces - Espacios de Trabajo

El CC trabaja con grupos de proyectos llamados espacios de trabajo o "Workspaces", esto significa
que hay una estructura de manejo de los archivos que pertenecen a cada proyecto. Un Worspace viene
a ser una carpeta adonde se van a poner varios proyectos. Cada uno de esos proyectos tambin estn
contenidos en sus respectivas carpetas.

Cuando se arranca el CC cada vez, aparece un dilogo donde se pregunta por el nombre del Workspace
con el que se va a trabajar. Saldr un workspace por defecto pero es preferible que la primera vez se
direccione a la carpeta adonde estn los archivo de proyecto en "C:\\DSP2812_2010".

El CODE COMPOSER STUDIO V4

El CC4 es una suite de programacin, muy parecida a las herramientas de desarrollo en .NET, Java,
PHP etc.

En la parte baja del lado izquierdo aparece un cuadro con la raz de todos los proyectos con los que se
va a trabajar, si no apareciera este cuadro se puede activar dando View->C/C++ Projects. Para activar
cualquiera de los proyectos se le puede seleccionar con el mouse, dar click derecho y luego entrar la
opcin de "Open Project".
Perspectivas

El juego de cuadros (frames) se manejan a travs de "perspectivas", se puede observar en el lado


superior derecho que est seleccionada la perspectiva C/C++ y no la Debug:

Si le d click a Debug, todos los cuadros cambian a otra disposicin, se puede decir que las ventanas se
colocan en lugares ms cmodos para la programacin, as como se activan y se desactivan diferentes
opciones, de acuerdo a las preferencias del usuario. El CC recuerda que cuadros y que posiciones
tenan despus que ha cerrado el program.

Puede ocurrir que alguna vez el CC se cuelgue y tenga que cerrar la aplicacin, entonces es probable
que la disposicin de los cuadros regresen a una ubicacin por defecto o anterior.

El primer cono de perspectivas se utiliza para crear un juego de cuadros o varios juegos, de acuerdo a
las preferencias del usuario. Ud. puede crear todas las perspectivas que necesite.

Generar un Proyecto:

Para crear un nuevo proyecto se da la opcin File->New. Aparece un men de opciones para crear
diferentes tipos de archivos y proyectos:
Se le da nombre al proyecto y luego 3 veces Next, es decir se seleccionan las opciones por defecto y
luego se configura el modelo de DSP en la siguiente pantalla:
Para crear un proyecto se deben tener algunas consideraciones. Hay 5 archivos en lenguaje C muy
importantes que siempre deben ser includos en todos los proyectos, estos han sido instalados gracias a
los Headers que vienen en los archivos zippeados.

Para agregar archivos de programas en C, ASM o C++ seleccione el proyecto activo, luego dar click
derecho y escoger "Link Files to Projects".
Los archivos y carpetas que deben incluirse en la raz de su proyecto son los siguientes:
Las rutas son las siguientes:

C:\tidcs\c28\dsp281x\v111\DSP281x_common\source
Donde se encuentran:
DSP281xDefaultIsr.C
DSP281xPieCtrl.c
DSP281xPievect.c
DSP281xSysCtrl.c

C:\tidcs\c28\dsp281x\v111\DSP281x_headers\source
Donde se encuentra:
DSP281xGlobalVariableDefs.c

NOTA IMPORTANTE

El archivo DSP281x_SysCtrl.c define la frecuencia del DSP por el registro que maneja el PLL,
originalmente viene con una lnea de programa asumiendo que tiene un cristal de 30MHz tal como:

// Initialize the PLLCR to 0xA


InitPll(0xA);
// Initialize the peripheral clocks
InitPeripheralClocks();
Para la tarjeta Varitek 19 que viene con un Oscilador de 50MHz Hay que cambiar el valor de 0xA por
el de 0x6:

// Initialize the PLLCR to 0x6 quiere decir 3 veces la frecuencia del oscilador o cristal de entrada
InitPll(0x6); //PLL con Osc 50MHz para generar 150MHz
// Initialize the peripheral clocks
InitPeripheralClocks();

Ruta a las cabeceras Includes

Recuerde en seleccionar el proyecto, dar click derecho, seleccionar en el men la opcin Build
Properties, para ver el siguiente men:
Como se observa en la figura anterior hay que incluir las rutas Path de las carpetas Include, con el
cono que tiene la hoja y un signo mas en color verde.

Si fuera necesario en este men en la seccin C2000 Linker bajo Basic Options puede cambiar el
tamao del Apilador Stack, que normalmente se configura por defecto a 0x400 ( el 0x significa que el
valor es hexadecimal), o tambin si fuera necesario alguna relocacin de la memoria puede cambiar el
valor del Heap.

Archivos de configuracin de la memoria

Ahora borre el archivo CMD que viene por defecto 2812_RAM_Lnk.cmd.

Se debe incluir dos archivos para que el compilador pueda hacer el proceso de linkeo, estos archivos
estn en la carpeta CMD de todos los proyectos, estos son:

* DSP281x_Headers_nonBIOS.cmd .- Configuracin de todos los registros del DSP y su ubicacin en


la memoria

* F2812_VARITEK19_RAM_lnk.cmd .- Disponibilidad de la memoria especfica de la tarjeta, en este


caso de la Varitek19

La carpeta CMD es preferible copiarla de otros proyectos anteriores y pegarla en la carpeta del
proyecto. Todo lo que se descarga dentro de la carpeta es incluida automticamente en el proyecto, por
eso no debe dejar archivos que no sean tiles porque podran generar errores de compilacin.

La carpeta Debug sale automticamente cuando se compila el programa.

Las carpetas a construir son:

* Source .- Donde se agregan los archivos de programa en ANSI C (*.c) , C++ (*.cpp) o ensamblador
ASM (*.asm).

* Include .- Donde se referencian los archivos cabeceras, (*.h), las carpetas que contienen estos
archivos deben ser referenciadas en Project->Properties -> Tool Settings->Include Options, en el men
aparece un signo + en color verde, las carpetas que se encuentran en el projecto se pueden referenciar
con workspace y las que no hay que buscarlas con File System.

* CMD .- En esta carpeta se encuentran los archivos CMD.

CLASE 3
Laboratorio # 1

Despus de seguir los pasos para el armado de un proyecto, se procede a la creacin de un archivo de
tipo (*.c), con el nombre de lab1.c, la forma de crearlo es dando las opciones File->New->Source
File, se debe notar que sale un aviso donde indica que el tipo de archivo no esta definido por defecto,
as que hay que dar el nombre completo, podra ser este del tipo ANSI C (*.c) , C++ (*.cpp) o
ensamblador ASM (*.asm). El archivo se debe crear bajo la carpeta Source. Tambin se debe crear
un archivo de tipo cabecera, con las opciones File->New->Header File, nombrarlo lab1.h y crearlo
bajo la carpeta Include.

lEn el laboratorio #1 se genera una seal de forma senoidal, se hace un barrido de valores con un
cierto tiempo de muestreo y amplitud, para luego hallar una onda de tipo coseno y finalmente los
resultados se graban en un vector llamado salida de un total de 1000 puntos, para ello se realizan las
siguientes tareas:

*Se hace el llamado a los archivos cabeceras, de manera que se pueda tener acceso a las palabras
definidas en los archivos que se instalaron con el spru097.zip, que son las cabeceras de todos los
registros de CPU. Tambin se llama a las cabeceras lab1.h y math.h de acuerdo a las funciones que se
necesitan en el proyecto.

* Se declaran las variables para la construccin de la seal.

* Se agregan las sentencias de cdigo necesarias para el llamado de las funciones que se encuentran
en los archivos obligatorios.

* Con una sentencia FOR se hace la iteracin y se resuelven los datos de salida.

El Programa lab1.c

#include "DSP281x_Device.h"
#include "DSP281x_Examples.h"
#include "math.h"
#include "lab1.h"
float salida[1000]; //variable de salida
long int k=0; //muestra k
float T=0; //periodo de muestreo
const float pi=3.1415926535897932384;
float w=0; //velocidad angular en rad/seg
float t=0; //variable de entrada o tiempo
main(void)
{
DINT; //deshabilita interrupciones
DRTM; //deshabilita interrupciones real time mode
InitSysCtrl(); //inicializa el sistema como PLL,clocks,watchdog
InitPieCtrl(); //inicializa el apoyo de interrupcin de perifricos
IER = 0x0000; //limpia mscara de interrupciones
IFR = 0x0000; //limpia bandera de interrupciones
InitPieVectTable(); //inicializa tabla de interrupciones por defecto
EINT; //habilita interrupciones
ERTM;
T=0.001; //carga el periodo de muestreo =1KHz
w=2*pi*10; //carga la velocidad angular
for (k=0;k<1000;k++)
{
t=k*T;
salida[k]=func_coseno(w*t);
};
}
float func_coseno(float angulo)
{
return 100*cos(angulo);
}
Laboratorio #2

El objetivo del laboratorio #2 es dar al DSP la posibilidad de comunicarse con alguna PC mientras
esta se encuentra corriendo un programa, el archivo que permite esta comunicacin es el monitor.c
junto con su archivo cabecera monitor.h. A travs del puerto serial se pueden enviar y recibir datos,
de manera que el usuario pueda hacer aplicaciones de tiempo real en lenguajes C++, Basic, Java etc
donde se puedan hacer presentaciones en pantalla, enviar mandos apretando pulsadores virtuales,
hacer algn sistema SCADA etc.

En el momento en que uno corre un programa, el DSP se libera de la PC y comienza a ejecutar las
sentencias, pero si entre ellas no hay un manejador de comunciaciones entonces no se pueden
intercambiar datos. Utilizando el programa monitor entonces el DSP est atento a s el puerto serial A
est recibiendo bytes desde la PC.

Cuando llega un byte entonces el DSP ejecuta una rutina de reconocimiento, averiguando o
decodificando qu significa ese byte, utilizando una sentencia CASE, de manera que se puede
inventar una trama con un formato predefinido, por ejemplo como el que se presenta, donde hay una
secuencia a seguir por la PC, para que ambos dispositivos se puedan entender.

La trama de datos debe seguir el siguiente protocolo.

1.- La PC enva un primer byte que es el comando que va a resolver el CASE, este puede ser el
nmero (0) o el nmero (3), el significado de es byte es:

0= Leer DSP

3= Escribir DSP

2.- Si se trata de una lectura, entonces la PC debe enviar 4 bytes con la direccin de la memoria que
se desea leer, con el primer byte teniendo el mayor peso MSB. A continuacin debe enviar
nuevamente 4 bytes, indicando la cantidad de posiciones de memoria se requieren, este nmero es
uno menos a la cantidad de datos que se necesitan, por ejemplo si se envan cuatro bytes con ceros,
entonces por lo menos el DSP devuelve un dato de una memoria.

3.- Para leer los valores de la memoria y haya una sincronizacin entre con el DSP, la PC debe enviar
el byte 64, por cada byte con el valor 64 que enve la PC entonces el DSP responde con un byte de la
posicin de memoria solicitada, este byte es el de mayor peso de los dos bytes que ocupa cada
memoria, notar que las posiciones de memoria tienen un word compuesto por dos bytes.

Si se necesita solo una memoria entonces hay que enviar un total de dos bytes 64.

El programa lab2.c

#include "DSP281x_Device.h"
#include "DSP281x_Examples.h"
#include "lab2.h"
#include "monitor.h"
void main(void)
{
DINT; //deshabilita interrupciones
DRTM; //deshabilita interrupciones real time mode
InitSysCtrl(); //inicializa el sistema como PLL,clocks,watcgdog
InitPieCtrl(); //inicializa el apoyo de interrupcin de perifricos
IER = 0x0000; //limpia mscara de interrupciones
IFR = 0x0000; //limpia bandera de interrupciones
InitPieVectTable(); //inicializa tabla de interrupciones por defecto
EINT; //habilita interrupciones
ERTM;
IniciarSerial(); //Inicializacin de los parmetros del puerto serial A
do{ //hacer loop por lo menos una vez
IteraSerial(); //Rutina de espera del puerto serial
}while(1); //Itera infinitamente
}

El programa monitor.c

#include "stdlib.h"
#include "DSP281x_Device.h"
#include "monitor.h"
const float mipi=3.14141515;
Uint16 LoopCount;
Uint16 SendChar;
Uint16 ReceivedChar;
void AddrCant(void);
Uint32 Direccion=0;
int16 *memoria=0;
Uint32 Cantidad=0;
int caso=0;
Uint32 j=0;
void IniciarSerial(void)
{
scia_fifo_init(); // Inicializa el FIFO del SCI
scia_init(); // Inicializa el lazo de iteracin
SendChar = 0;
}
void IteraSerial(void)
{
while(SciaRegs.SCIFFRX.bit.RXFIFST ==0) {
return;
}; // espera por XRDY =1
ReceivedChar = SciaRegs.SCIRXBUF.all; //se lee el byte
SendChar=ReceivedChar; //se guarda en una variable
scia_xmit(SendChar); //se retransmite como ECO para que la PC sepa
caso=ReceivedChar; // se decodifica
switch (caso) { // con el CASE
case 0:
LeerDSP(); // Si el comando es un CERO Leer DSP
break;
case 1:
LeerDSP();
break;
case 2:
LeerDSP();
break;
case 3:
EscribirDSP(); // Si el comando es un TRES Escribir DSP
break;
case 4:
EscribirDSP();
break;
case 5:
EscribirDSP();
break;
};
}
void LeerDSP(void)
{
AddrCant(); //Averiguar la Direccin de memoria y cuantos datos
for (j=0;j<Cantidad+1;j++)
{
memoria=0;
SendChar=memoria[Direccion]; // Buscar el dato en memoria
Direccion++;
do{
while(SciaRegs.SCIFFRX.bit.RXFIFST ==0) { } // esperar a XRDY =1 estado listo
ReceivedChar = SciaRegs.SCIRXBUF.all; //Leer byte del buffer
} while (ReceivedChar!=0x40); // Esperar a que sea el byte 64
scia_xmit(SendChar>>8); //Enviar parte alta del dato
do{
while(SciaRegs.SCIFFRX.bit.RXFIFST ==0) { } // esperar a XRDY =1 estado listo
ReceivedChar = SciaRegs.SCIRXBUF.all;
} while (ReceivedChar!=0x40); // Esperar a que sea el byte 64
scia_xmit(SendChar); //Enviar parte baja del dato
};
}
void EscribirDSP(void)
{
AddrCant();
for (j=0;j<Cantidad+1;j++) // Preparar la cantidad de veces
{
while(SciaRegs.SCIFFRX.bit.RXFIFST ==0) { } // esperar a XRDY =1 estado listo
ReceivedChar = SciaRegs.SCIRXBUF.all; //Leer byte del buffer
scia_xmit(ReceivedChar); // Enviar ECO
SendChar = ReceivedChar<<8; // Sube el valor recibido a la parte alta
while(SciaRegs.SCIFFRX.bit.RXFIFST ==0) { } // esperar a XRDY =1 estado listo
ReceivedChar = SciaRegs.SCIRXBUF.all; //Leer byte del buffer
scia_xmit(ReceivedChar); // Enviar ECO
SendChar = SendChar+ ReceivedChar; // Agrega parte baja del dato
memoria[Direccion]=SendChar; // Graba el valor del dato en memoria
Direccion++; // Incrementa para la prxima direccin
};
}
void scia_init()
{
SciaRegs.SCICCR.all =0x0007; // 1 stop bit, No loopback
// No parity,8 char bits,
// modo asncrono, protocolo idle-line lnea en espera
SciaRegs.SCICCR.bit.SCICHAR = 7;
SciaRegs.SCICTL1.all =0x0003; // Habilitar TX, RX, SCICLK interno,
// Deshabilitar RX ERR, SLEEP, TXWAKE
SciaRegs.SCICTL2.all =0x0003;
SciaRegs.SCICTL2.bit.TXINTENA = 0;
SciaRegs.SCICTL2.bit.RXBKINTENA =1;
SciaRegs.SCIHBAUD =0x0000;
SciaRegs.SCILBAUD =0x0028; //a 150mhz
SciaRegs.SCICCR.bit.LOOPBKENA =0; // No habilitar loop back
SciaRegs.SCICTL1.all =0x0023; // SCI fuera de Reset
}
void scia_xmit(int a)
{
SciaRegs.SCITXBUF=a; // Cargar buffer para transmitir
}

void scia_fifo_init()
{
SciaRegs.SCIFFTX.all=0xE040;
SciaRegs.SCIFFRX.all=0x204f;
SciaRegs.SCIFFCT.all=0x0;
}
void AddrCant(void)
{
int i=0;
Direccion=0;
ReceivedChar=0;
for (i=0;i<4;i++)
{
while(SciaRegs.SCIFFRX.bit.RXFIFST ==0) { } // esperar a XRDY =1 estado listo
ReceivedChar = SciaRegs.SCIRXBUF.all; //Leer byte del buffer
scia_xmit(ReceivedChar);// Enviar ECO
Direccion=(Direccion<<8)+ReceivedChar; // Ir agregando Direccin
};
for (i=0;i<4;i++)
{
while(SciaRegs.SCIFFRX.bit.RXFIFST ==0) { } // esperar a XRDY =1 estado listo
ReceivedChar = SciaRegs.SCIRXBUF.all; //Leer byte del buffer
scia_xmit(ReceivedChar);// Enviar ECO
Cantidad=(Cantidad<<8)+ReceivedChar; // Ir agregando Cantidad
};
}

CLASE 4
Entradas y Salidas GPIOS

Manual Recomendado spru078.pdf Captulo 4.

Por defecto los pines del DSP arranacan como entradas/salidas, estos pueden tomar dos funciones:

* Pueden ser pines para entradas y/salidas

* Pueden tomar su funcin primaria, por ejemplo un pin de PWM.

Los pines estn agrupados en puertos de la A a la F, donde cada puerto puede tener hasta 16 pines. Se le
nombra GPIO seguido del puerto y el nmero de pin; GPIOA5.

Para poder programar los GPIOs ( general purpose input output) hay que definir qu tipo de funcin va
a tener, si es I/O o si va a tomar su funcin primaria, esto se logra con el registro de multiplexacin de
cada puerto, 0=es GPIO, 1=funcin principal:

GpioMuxRegs.GPAMUX.bit.PWM1_GPIOA0 =0;

Esta sentencia obliga a que el pin correspondiente al puerto A, pin 0, que tambin podra ser el pin del
PWM1, sea un I/O en vez de su funcin primaria PWM1.

En realidad la forma correcta de accesar al registro de multiplexacin del puerto A es solicitando


permiso para poder modificarlo, ya que este registro se encuentra protegido, se debe hacer de la
siguiente forma:

EALLOW;
GpioMuxRegs.GPAMUX.bit.PWM1_GPIOA0 =0;
EDIS;

Luego si se ha decidido por utilizar el pin como I/O hay que indicar si es que va a ser de entrada o de
salida, esto se logra con el registro de direccin del puerto, con 0=entrada y 1=salida:

GpioMuxRegs.GPADIR.bit.GPIOA0 = 1; //pin GPIOA0 es salida

Notar que tambin es un registro protegido.

Finalmente hay que programar el pin si en caso fuera una salida, determinando si esta va a estar en
estado lgico uno o cero, esto se logra con cuatro tipo de sentencias:

* GPADAT .- Con 0=estado lgico bajo 1=estado lgico alto

* GPASET .- Con 0=no hace nada 1=fuerza el pin al estado lgico alto

* GPACLEAR .- Con 0=no hace nada 1=fuerza el pin al estado lgico bajo

* GPATOOGLE .- Con 0=no hace nada 1=fuerza el pin a cambiar el estado lgico anterior

No es encesario pedir permiso para actualizar estos registros, por lo que una manera de programacin
completa sera:

EALLOW;
GpioMuxRegs.GPAMUX.bit.PWM1_GPIOA0 =0;
GpioMuxRegs.GPADIR.bit.GPIOA0 = 1; //pin GPIOA0 es salida
EDIS;
GpioDataRegs.GPADAT.bit.GPIOA0 = 1; // Pin de salida en ON

Laboratorio #3

A continuacin se presenta el laboratorio # 3, se han comentado de acuerdo a los avances y preguntas


realizadas en clase. El objetivo del laboratorio es el manejo de las sentencias que manipulan los I/Os
tales como:

* Generacin de una estructura para accesar botones.

* Encendido, apagado y alternado de los GPIOS.

* El uso del pin XF (external flag) con sentencias ASM.

* La creacin de un PWM por software.

* La grabacin de datos en una direccin de memoria especfica.

* La lectura de informacin de algunos pines llamados botones.


* Actualizacin de datos con el Colcacode gracias al monitor.

#include "DSP281x_Device.h"
#include "DSP281x_Examples.h"
#include "monitor.h"
#include "lab3.h"
long int i,k,l;
long int retardo=500;
long int test=0; // Variable para buscar errores
void main(void) {
DINT; //deshabilita interrupciones
DRTM; //deshabilita interrupciones real time mode
InitSysCtrl(); //inicializa el sistema como PLL,clocks,watcgdog
InitPieCtrl(); //inicializa el apoyo de interrupcin de perifricos
IER = 0x0000; //limpia mscara de interrupciones
IFR = 0x0000; //limpia bandera de interrupciones
InitPieVectTable(); //inicializa tabla de interrupciones por defecto
EINT; //habilita interrupciones
ERTM;
//Multiplexor de los pines
EALLOW;
GpioMuxRegs.GPAMUX.bit.PWM1_GPIOA0 =0; // Pines de las 6 llaves de PWM1-6
GpioMuxRegs.GPAMUX.bit.PWM2_GPIOA1 =0;
GpioMuxRegs.GPAMUX.bit.PWM3_GPIOA2 =0;
GpioMuxRegs.GPAMUX.bit.PWM4_GPIOA3 =0;
GpioMuxRegs.GPAMUX.bit.PWM5_GPIOA4 =0;
GpioMuxRegs.GPAMUX.bit.PWM6_GPIOA5 =0;

GpioMuxRegs.GPFMUX.bit.MCLKXA_GPIOF8 =0;
GpioMuxRegs.GPFMUX.bit.MCLKRA_GPIOF9 =0;
GpioMuxRegs.GPFMUX.bit.MFSXA_GPIOF10 = 0;
GpioMuxRegs.GPFMUX.bit.MFSRA_GPIOF11 =0;
GpioMuxRegs.GPFMUX.bit.MDXA_GPIOF12 =0;
GpioMuxRegs.GPFMUX.bit.MDRA_GPIOF13 =0;
GpioMuxRegs.GPFMUX.bit.XF_GPIOF14 = 1; // Funcin primaria, no es IO
//Direccin de los pines
GpioMuxRegs.GPADIR.bit.GPIOA0 = 1; //Pwm1 salida
GpioMuxRegs.GPADIR.bit.GPIOA1 =0; // Pwm2 entrada
GpioMuxRegs.GPADIR.bit.GPIOA2 = 1; //Pwm3 salida
GpioMuxRegs.GPADIR.bit.GPIOA3 = 1; //Pwm3 salida
GpioMuxRegs.GPFDIR.all = 0x000;
GpioMuxRegs.GPFDIR.bit.GPIOF8 =0;//MCLKXA entrada
EDIS;
//Datos a poner en los pines
GpioDataRegs.GPADAT.bit.GPIOA0 = 1; // Pin de salida en ON
GpioDataRegs.GPADAT.bit.GPIOA2 = 1; // Pin de salida en ON
GpioDataRegs.GPACLEAR.bit.GPIOA3 =1 ; // 1 Seria apagar, 0 es no hacer nada
GpioDataRegs.GPATOGGLE.bit.GPIOA0 = 1; // Pin de salida cambiar a OFF
InitXintf(); // Inicializacin de la interfase de salida Memoria Externa (velocidad)
EINT;
ERTM;

//XF bandera externa


for (i=0;i<2500;i++) //Los retardo son proporcionales a la velocidad de la memoria
{ //si el programa est instalado en la memoria externa (.text)
GpioDataRegs.GPATOGGLE.bit.GPIOA0 =1; //Alternar estado del pin GPIOA0
for (k=0;k<retardo;k++){asm(" nop");}; // bloque de retardo
asm(" setc xf"); // prender pin conecto al led rojo
asm(" nop");
for (k=0;k<retardo/100;k++){asm(" nop");
};
asm(" clrc xf");
asm(" nop");
};
GpioDataRegs.GPADAT.bit.GPIOA0 =0; //Al terminar dejar pin OFF
botones.all=0;
while(1){ //hacer loop por lo menos una vez
IteraSerial(); // Revisar si hay bytes en el puerto serial A
test++; // test debera cambiar en cada pasada
*(long int *)0x100100=test; // La memoria =0x100100 debe cambiar cada vez
botones.bit.boton0=GpioDataRegs.GPFDAT.bit.GPIOF8; //Leer pin con boton[0]
botones.bit.boton1=GpioDataRegs.GPFDAT.bit.GPIOF9; //Leer pin con boton[1]
botones.bit.boton2=GpioDataRegs.GPFDAT.bit.GPIOF10; //Leer pin con boton[2]
botones.bit.boton3=GpioDataRegs.GPFDAT.bit.GPIOF11; //Leer pin con boton[3]

GpioDataRegs.GPADAT.bit.GPIOA2= botones.bit.boton0 && botones.bit.boton1; //GPIOA2=boton0


and boton1
}; //Itera infinitamente
}

Convertidor Analgico Digital

Manual Recomendado spru060.pdf Captulo 1.

En los modelo anteriores de DSP de la familia 2000 se encontraban dos convertidores ADC, la idea
principal era poder leer las corrientes o voltajes de los motores trifsico, la tercera corriente puede salir
por diferencia. En el caso del modelo TMS320F2812, lo que se ha hecho es colocar un convertidor muy
rpido, de 10.5 MSPS, y en la entrada, a manera de tomar fotos, se encuentran dos unidades de
sample/hold o mantenedores, de manera que cuando se le d la orden de tomar la muestra, el convertidor
captura dos seales a la vez, cada una de ellas proveniente de un multiplexor (Analog MUX). Los dos
multiplexores estn conectados a 8 canales cada uno, llamados canales A y canales B. Por ejemplo el
ltimo canal A se llama ADCIN A0, y el primero del B se llama ADCIN B0.

A diferencia de otros convertidores, el proceso de conversin no termina con la captura de dos datos y la
actualizacin de los resulatdos en solo dos registros, en realidad cuando uno ordena al ADC a realizar la
conversin, lo que se le d es una lista de canales que debe capturar, es decir el convertidor podra leer
un canal tras otro hasta un mximo de 16 canales de forma secuencial, cuando terminara se podra
reiniciar la lectura nuevamente o simplemente finalizar y extraer los datos obetnidos desde los 16
registros de resultados.

La lista no necesariamente debe ser de 16 canales, la cantidad de canales ledos depende de un registro
llamado "nmero mximo de conversiones" ADCMAXCONV.

Modo Cascada

El modo cascada es utilizar todos los recursos del ADC como si fuera un solo equipo integral, en este
modo el ADC puede ser disparado desde todas las formas posibles, este arranque o SOC (start of
conversion) puede obedecer a que nosotros lo programemos por software, obligando al ADC a que
inicie una lectura secuencial de canales en este instante, eso se llamara arranque por software o SW.
Tambin puede iniciar su secuencia de lectura si programamos a los relojes provenientes del EVA o
EVB, finalmente se puede iniciar desde el cambio de estado de un pin llamado ADCSOC.

Cuando se efecta un SOC, el ADC inicia la conversin, primero busca en la lista de canales
ADCCHSELSEQ, qe canal debe leer, si el ADC est en forma secuencial escoge un canal y si esta en
forma simultnea escoge dos canales ( En forma simultnea hay que tener en cuenta que un canal debe
pertenecer al grupo A y el otro al grupo B, adems que ambos debe tener el mismo desfase, por ejemplo
ADCINA3 con el ADCINB3).

Los voltajes del canales (0 a 3v como mximo) son capturados en las unidades sample/hold, luego esos
voltajas con convertidos a valores numricos de 12 bits y descargados en uno de los registros de
resultados. Luego el secuenciador incrementa la cuenta y se procede a leer los siguientes canales que
estn en la lista del ADCCHSELSEQ.

La cantidad de canales que se va a leer depende del registro ADCMAXCONV, cuando se termina
entonces el contador de conversiones puede regresar a cero para esperar a otro SOC, o tambin se le
puede ordenar un Override donde el secuenciador continuara con los canales que siguen en la lista de
forma circular.

Modo DUAL

El convertidor tambin puede ser partido en dos, es un modo de funcionamiento llamado DUAL, en este
caso el ADC se convierte en una forma emulada de dos convertidores, todos los canales del grupo A
pasan a ser parte de un secuenciado SEQ1 con su propia lista y su propio nmero mximo de
conversiones ADCMAXCONV1, y los canales del grupo B a un SEQ2 y ADCMAXCONV1, hay
limitaciones como que el nmero mximo de conversiones solamente puede llegar a 8, y los SOC solo
pueden provenir de algunos perifricos como se puede ver en la firgura anterior. No se recomienda
mucho trabajar en este modo.

Laboratorio # 4

#include "DSP281x_Device.h"
#include "DSP281x_Examples.h"
#include "monitor.h"
long int i,k;
unsigned int ResultadoADC[16];
void main(void) {
DINT; //deshabilita interrupciones
DRTM; //deshabilita interrupciones real time mode
InitSysCtrl(); //inicializa el sistema como PLL,clocks,watcgdog
InitPieCtrl(); //inicializa el apoyo de interrupcin de perifricos
IER = 0x0000; //limpia mscara de interrupciones
IFR = 0x0000; //limpia bandera de interrupciones
InitPieVectTable(); //inicializa tabla de interrupciones por defecto
IniciarSerial();
// ADC setup
AdcRegs.ADCTRL1.bit.RESET = 1;
asm(" NOP ");
asm(" NOP ");
AdcRegs.ADCTRL1.bit.ACQ_PS = 15;
AdcRegs.ADCTRL3.bit.ADCCLKPS = 1;
AdcRegs.ADCTRL3.bit.ADCBGRFDN = 3;
DSP28x_usDelay(((((long double) 5000L * 1000.0L) / (long double)CPU_RATE) - 9.0L) / 5.0L);
AdcRegs.ADCTRL3.bit.ADCPWDN = 1;
DSP28x_usDelay(((((long double) 5000L * 1000.0L) / (long double)CPU_RATE) - 9.0L) / 5.0L);
AdcRegs.ADCTRL1.bit.RESET = 0;
AdcRegs.ADCTRL1.bit.SEQ_CASC = 1; // 1 Cascada mode
AdcRegs.ADCCHSELSEQ1.all = 0x0128; // Canal B0
AdcRegs.ADCCHSELSEQ2.all = 0xABCD;
AdcRegs.ADCCHSELSEQ3.all = 0x9572;
AdcRegs.ADCCHSELSEQ4.all = 0x4444;
AdcRegs.ADCMAXCONV.bit.MAX_CONV1 = 15;
AdcRegs.ADCMAXCONV.bit.MAX_CONV2 = 7; // Menor a 7 y solo en modo dual
AdcRegs.ADCTRL1.bit.CONT_RUN = 0; // Modo no continuo
AdcRegs.ADCTRL2.bit.SOC_SEQ1 = 1; //Sugerencia de Texas para arrancar correctamente
EINT; //habilita interrupciones
ERTM;
do{ //hacer loop por lo menos una vez
IteraSerial();
AdcRegs.ADCTRL2.bit.SOC_SEQ1 = 1; //Arranque de conversin SOC por SW
while(AdcRegs.ADCST.bit.SEQ1_BSY ==1) {}; //Esperar a que termine
ResultadoADC[0]= AdcRegs.ADCRESULT0>>4; //Leer resultados
ResultadoADC[1]= AdcRegs.ADCRESULT2>>4;
}while(1); //Itera infinitamente
}

CLASE 5
Manejador de Eventos

Manual Recomendado spru065.pdf Captulo 1. Registros en el Captulo 5.

El manejador de eventos consiste bsicamente en un conjunto de perifricos asociados con


temporizadores, entre ellos los denominados relojes de propsito general 1 y 2 (GP timers 1 & 2). Los
timers utilizan como clock base a tres tipos de seales, seleccionadas mediante los bits TCLKS de un
registro de control TxCON que acta sobre un multiplexor, las seales pueden ser el Hispeedclock, un
oscilador externo que ingresa a travs de los pines TCLKINx un clock proveniente de los sensores de
posicin QEP (quadratures encoder pulse).

Antes de que el contador reciba esta seal de clock, se puede prescalar y disminuir la frecuencia de
entrada desde 1 hasta 1:128 veces, de acuerdo a los bits TPS del registro de control TxCON.

Timer 1

El Timer 1 por ejemplo es un contador asociado a su T1PWM y a los PWMs 1-6, el valor de la cuenta
est en el registro TxCNT, tiene hasta 4 formas de contar. En una de las formas de conteo, la cuenta va
desde cero hasta el valor del periodo, que se programa con el registro T1PER, luego cae hasta el valor
cero nuevamente, este modo de conteo se llama continuo arriba. El modo de conteo se programa con los
bits TMODE del registro TxCON. Otro modo de conteo bastante utilizado es el continuo arriba/abajo,
donde el contador al llegar al valor del periodo comienza a disminuir cuenta abajo hasta llegar al cero
nuevamente, se acostumbra llamar a este modo de conteo como simtrico, mientras que al continuo arriba
se le llama antisimtrico.
A parte del Timer 1 hay un comparador que puede utilizar el valor de la cuenta para generar una salida
tipo PWM, se trata del comparador que se programa con el registro T1CMPR, cuando el contador
T1CNT coincide con el valor del T1CMPR entonces se produce un evento, este evento puede servir por
un lado para generar una interrupcin, as como tambin para efectuar el cambio de lgica en un pin de
salida T1PWM. En la siguiente figura se ilustra la forma de una escalera, que representa el valor de
conteo cuando el Timer 1 est trabajando en el modo conitnuo arriba.
Se puede observar primero cmo el contador al llegar al valor del periodo decae inmediatamente a cero.
Por otro lado cuando el valor del contador coincide con el del comparador en "Compare match" entonces
el pin externo TxPWM/TxCMP cambia de estado. El active low o active high es la forma o sentido del
disparo que se requiere segn los dispositivos que se han conectado al pin exterior, de acuerdo a la lgica
de salida. Ambos modos son inversos y pueden ser programados en el registro GPTCONx.

El GPTCON

El registro GPTCON sirve por una lado para programar la forma de disparo, cuando el comparador
coincide con el valor del contador entonces el pin T1PWM puede disparar de 0v a 3.3v, llamado activo
arriba, puede disparar flanco abajo de 3.3v a 0v, llamado activo abajo. Tambin puede servir para
bloquear las seales de salida, para casos de emergencia, as como tambin puede ser programada para
generar una seal de arranque de conversin SOC para el convertidor ADC. Los disparos SOC pueden
ser generados por los eventos de comparacin, periodo o desborde del contador.

Sombras

Algunos de los registros de los Timers tiene un registro escondido llamado sombra, que sirve para que los
cambios, por ejemplo el de la fase del comparador T!CMPR, no se realicen de forma inmediata, sino que
se efecten en un momento ms apropiado, como hacer un cambio cuando el contador llega a cero al
valor del periodo, estos cambios se pueden programar en algunos registros como el TxCON.

Timer 2 y el QEP

El temporizador 2 puede trabajar como un relog, puede generar interrupciones, tambin una seal de
pwm como la T1PWM, puede hacer conteos y cualquiera de las funciones generales, pero as como el
Timer 1 est preparado para manejar las 6 llaves de PWM1-6, el Timer 2 en cambio est preparado para
manejar la entrada de los sensores QEP. Mucho de los dispositivos de control, y principalmente los
motores elctricos, requieren del uso de un sensor de posicin, entre ellos los sensores codificadores
(encoders), los cuales generan un par de seales de onda cuadrada desfasadas en 90 , ya sea para indicar
el movimiento en forma lineal o giratoria, si el sensor est montado en el eje de un motor entonces el
QEP puede indicar el ngulo de la posicin del eje.

Trips

NOTA IMPORTANTE.- Los TxCTRIP son pines muy sensibles, que incluso con el ruido de los chips se
podran dispara casi solos, por lo que si no se va a conectar un driver que obligue al pin a estar a 3.3v, se
recomienda entonces para el caso de laboratorios o desarrollos que permanezcan deshabilitados hasta que
se hagan pruebas con los drivers conectados a los sitemas de emergencia.

Sistema moderno INDCOE

En los manuales se encuentran algunas referencias sobre bits que son reservados, siempre y cuando se
den algunas condiciones, para el caso de las habilitaciones de los comparadores por ejemplo, a veces se
habilita de forma grupal con el sistema antiguo, que es manejado por el bit INDCOE EXTCONA[0], y
a veces se habilita de forma individual el del Timer 1 con el del Timer 2, esto es en el sistema moderno
donde INDCOE=1. Se debe tener precaucin en la programacin, debido a que el estado "Reservado"
significa que no se va a poder modificar el bit, salvo que se pase al estado "No reservado".

Entonces para que el programa funcione bien, primero hay que habilitar el sistema moderno y luego
habilitar la comparacin individualmente con el bit T1CMPOE.

EvaRegs.EXTCONA.bit.INDCOE=1; // Nueva forma sin PDP con CTRIPE, esta lnea debe ir primero
EvaRegs.GPTCONA.bit.T1CMPOE =1; // habilitar las comparaciones, al haber pasado al sistema
moderno ya no es reservado

Si se hubiera programado con la sentencia del T1CMPOE primero, entonces nunca se hubiera modificado
el bit en realidad, seguira con el valor cero porque en ese momento hubiera estado Reservado.
Laboratorio # 5

En el laboratorio 5 se configuran los registros necesarios para el arranque del Timer 1, con la funcin
init_eva_timer1. La variable faseT1 se puede modificar en lnea con el programa Colcacode, de manera
que al manipular la variable, esta puede modificar el valor del comparador T1CMPR, logrando variar la
fase y aprecindola en el osciloscopio.

Programa lab5.c

#include "DSP281x_Device.h"
#include "DSP281x_Examples.h"
#include "lab5.h"
#include "monitor.h"
long int i;
Uint16 faseT1;
void main(void) {
DINT; //deshabilita interrupciones
DRTM; //deshabilita interrupciones real time mode
InitSysCtrl(); //inicializa el sistema como PLL,clocks,watcgdog
InitPieCtrl(); //inicializa el apoyo de interrupcin de perifricos
IER = 0x0000; //limpia mscara de interrupciones
IFR = 0x0000; //limpia bandera de interrupciones
InitPieVectTable(); //inicializa tabla de interrupciones por defecto
EALLOW;
GpioMuxRegs.GPAMUX.bit.T1PWM_GPIOA6=1; //Funcin primaria T1PWM, que no sea IO
GpioMuxRegs.GPFMUX.bit.XF_GPIOF14 = 1;
EDIS;
i=0;
ini_eva_timer1(); //configurar reloj T1
faseT1=EvaRegs.T1CMPR; //inicializa primera vez variable de fase con 50% dcycle
EINT;
ERTM;
do{ //hacer loop por lo menos una vez
IteraSerial(); //PC puede comunicarse con el monitor
EvaRegs.T1CMPR = faseT1; //Se actualiza fase de T1 si PC cambia la varible
}while(1); //Itera infinitamente
}
void ini_eva_timer1(void)
{
EvaRegs.EXTCONA.bit.INDCOE=1; // deshabilita independientemente sistema moderno
EvaRegs.T1PR = 1874;// 10Khz ((HSPCLK/prescala)/frecuencia)-1
EvaRegs.T1CMPR = 937; //50% duty cycle
EvaRegs.T1CNT = 0x0000; // Contador a cero
EvaRegs.T1CON.all = 0x1202; //(75MHz/4) prescala divisor HSPCLK/4
asm(" nop");
asm(" nop");
EvaRegs.T1CON.all = 0x1242; //igual T1CON con arranque del clock bit 6
EvaRegs.GPTCONA.bit.T1PIN =2; // activo arriba
EvaRegs.GPTCONA.bit.T1CTRIPE = 0; // No hacer caso al T1CTRIPE
EvaRegs.GPTCONA.bit.T1CMPOE =1; // habilitar las comparaciones
EvaRegs.GPTCONA.bit.TCMPOE =1; // habilitar ambos comparadores sistema antiguo

Interrupciones y el PIE

Manual Recomendado spru078.pdf Captulo 1. Registros en el Captulo 5.

El DSP tiene un total de 14 interrupciones de hardware, 2 interrupciones no enmascarables que son el


RST y el NMI (non-mascarable interrupt), adems de 12 interrupciones de software, una interupcin de
instruccin ilegal y dos interrupciones especficas para el data log y sistemas operativos de tiempo real
DLOGINT y RTOSINT.
Los vectores de interrupcin que son las memorias donde se guardan las direcciones de salto hacia las
interrupciones se encuentran en dos posibles ubicaciones de acuerdo al bit VMAP. En las direcciones:

* 0x000000 .- VMAP=0

* 0x3FFFC0.- VMAP=1

Sin embargo estas direcciones son libres cuando el bit ENPIE est habilitado, el DSP en este caso utiliza
el PIE (peripheral interrupt expansion) y los vectores son remapeados juntos con los de los perifricos a
la direccin:

* 0x000D00.- ENPIE=1 , por defecto el DSP arranca con este bit apagado.

Tambin hay algunas otras opciones de la ubicacin de los vectores segn:

Para que un perifrico o dispositivo pueda disparar una interrupcin, en primer lugar el bit de mscara
global de hardware INTM debe estar habilitado, tambin el bit de mscara global de grupo PIEACKx, as
como el bit de la interrupcin de grupo en el IER y el bit de mscara en el PIE PIEIERx.

Cuando se produce un evento en el perifrico, como la llegada de un byte en el puerto serial, o la llegada
al periodo de un contador, etc. Si los cuatro bits descritos anteriormente estn habilitado con la lgica en
1=uno, entonces se levanta primero la bandera correspondiente en el PIEIFRx, luego el grupo produce el
levantamiento de la bandera del CPU en el IFR, s todo est correcto entonces se hace una pediticin de
interrupcin al CPU.

El CPU debe tomar algunas acciones de control antes de hacer un salto de interrupcin, por ejemplo debe
guardar el contexto, es decir, debe guardar los valores de algunos registros de uso comn, como el
acumulador, los registros auxiliares, los estado entre otros, luego debe guardar la direccin del contador
de programa o PC ya que cuando termine la interrupcin debe saber de qu instruccin provino para
poder regresar. Despus de hacer un flush del pipeline el CPU busca en su tabla de vectores de
interrupcin, la direccin de salto hacia donde debe transladarse para comenzar con la subrutina de
interrupcin. Terminado el servicio entonces el CPU regresa su contexto y contina con la instruccin
siguiente a la de la instruccin donde se detuvo.

Para saber que interrupcin de CPU (registro IER) y qu interrupcin de PIE se debe programar, es mejor
utilizar la siguiente tabla, despus de sealar la interrupcin, por ejemplo la del periodo del reloj T1
(T1PINT), en la primera columna se puede observar que se trata de la interrupcin de CPU INT2 (por lo
tanto IER= M_INT2), y en la primera fila el PIE INTx.4 (por lo tanto PieCtrlRegs.PIEIER2.all =
M_INT4).
Laboratorio # 6

En el laboratorio 6 se va a configurar al convertidor ADC para que sea disparado por el Timer 1, de
manera que en la interrupcin del periodo el GPTCON dispara el SOC, y luego en la interrupcin del
comparador el ADC ya tuvo tiempo para terminar su secuencia, de manera que se pueden leer los datos
en la variable ResultadoADC.

Para programar las interrupciones se cambian las direcciones de salto por defecto hacia las dos sub
rutinas de interrupcin "interrupt void eva_timerT1PER_isr" y "interrupt void eva_timerT1CMP_isr".

Luego hay que configurar las habilitaciones o mscaras del PIE 4 y 5, as como las interrupciones de
CPU, que en este caso ambas son del grupo 2 por lo que se habilita la interrupcin de CPU 2, con IER =
M_INT2.

En las subrutinas, siempre hay que reactivar las mscaras y banderas de las interrupciones atendidas, as
como rehabilitar el "PIE Acknowlage" o reconocimiento de grupo.

Programa lab6.c
#include "DSP281x_Device.h"
#include "DSP281x_Examples.h"
#include "lab6.h"
#include "monitor.h"
int ResultadoADC[16];
Uint16 fase[1000];
int *Source;
int *Dest;
long int i,k,l;
void main(void) {
DINT; //deshabilita interrupciones
DRTM; //deshabilita interrupciones real time mode
InitSysCtrl(); //inicializa el sistema como PLL,clocks,watcgdog
InitPieCtrl(); //inicializa el apoyo de interrupcin de perifricos
IER = 0x0000; //limpia mscara de interrupciones
IFR = 0x0000; //limpia bandera de interrupciones
InitPieVectTable(); //inicializa tabla de interrupciones por defecto
EALLOW;
PieVectTable.T1PINT = &eva_timerT1PER_isr; // Cambia direccin de la isr de T1PER
PieVectTable.T1CINT = &eva_timerT1CMP_isr; // Cambia direccin de la isr de T1CMP
GpioMuxRegs.GPAMUX.bit.T1PWM_GPIOA6=1;
GpioMuxRegs.GPFMUX.bit.XF_GPIOF14 = 1;
EDIS;
PieCtrlRegs.PIEIER2.all = M_INT4 | M_INT5; // Habilita interrupciones 4 y 5 PIE grupo2
IER = M_INT2; // Habilita interrupcin 2 del CPU
i=0; // contadores a cero
k=0;
l=0;
iniciarADC();
ini_eva_timer1();
EINT;
ERTM;
do{ //hacer loop por lo menos una vez
IteraSerial();
}while(1); //Itera infinitamente
}
void ini_eva_timer1(void)
{
EvaRegs.T1PR = 1874; // 10Khz
EvaRegs.T1CMPR = 937; //50% duty cycle
EvaRegs.EVAIMRA.bit.T1PINT = 1; // Habilitar la int Periodo del T1
EvaRegs.EVAIFRA.bit.T1PINT = 1; // Limpiando la bandera
EvaRegs.EVAIMRA.bit.T1CINT = 1; // Habilitar la int Comparador del T1
EvaRegs.EVAIFRA.bit.T1CINT = 1; // Limpiando la bandera
EvaRegs.T1CNT = 0x0000; // Contador a cero
EvaRegs.T1CON.all = 0x1202; //(75MHz/4)
asm(" nop");
asm(" nop");
EvaRegs.T1CON.all = 0x1242; // Si fuera 0x9242 el T1 no para en emulacin
EvaRegs.GPTCONA.bit.T1CTRIPE =0; // No hacer caso a emergencia T1CTRIP
EvaRegs.GPTCONA.bit.T1TOADC = 2; // interrupt del T1PER
EvaRegs.GPTCONA.bit.T1PIN =2; // activo arriba
EvaRegs.GPTCONA.bit.T1CMPOE =1; // habilitar las comparaciones
EvaRegs.GPTCONA.bit.TCMPOE =1; // habilitar ambos comparadores sistema antiguo
EvaRegs.EXTCONA.bit.INDCOE=1; // Nueva forma sin PDP con CTRIPE
EvaRegs.EVAIMRA.bit.PDPINTA = 0; // Ya no tripea pero si puede interrumpir
}
interrupt void eva_timerT1PER_isr(void)
{
k++; // K es un contador que d el nmero de muestra
if (k>10000) // Si el T1 est en 10Khz entonces una vez por segundo
{ k=0; // cada segundo volver k = 0
if(l<1000) fase[l]=EvaRegs.T1CMPR; //Graba 1000 puntos/segundos de fase T1
l++;
};
EvaRegs.EVAIMRA.bit.T1PINT = 1; // Termin interrupcin entonces actualizar
EvaRegs.EVAIFRA.bit.T1PINT = 1; // mscara y banderas
PieCtrlRegs.PIEACK.all = PIEACK_GROUP2; //Rehabilitar grupo de donde provino interrupt
}
interrupt void eva_timerT1CMP_isr(void)
{
Source= (void *)&AdcRegs.ADCRESULT0; // Actualiza resultados y los graba
Dest = ResultadoADC; // en la variable ResultadoADC
for(i=0; i < 16; i++) // con dos punteros Source y Dest
*Dest++ = *Source++;
EvaRegs.EVAIMRA.bit.T1CINT = 1; // Termin interrupcin entonces actualizar
EvaRegs.EVAIFRA.bit.T1CINT = 1; // mscara y banderas
PieCtrlRegs.PIEACK.all = PIEACK_GROUP2; //Rehabilitar grupo de donde provino interrupt
}
void iniciarADC(void)
{
// Configuracin del ADC:
AdcRegs.ADCTRL1.bit.RESET = 1;
asm(" NOP ");
asm(" NOP ");
AdcRegs.ADCTRL1.bit.ACQ_PS = 15;
AdcRegs.ADCTRL3.bit.ADCCLKPS = 1;
// Arranque de las fuentes
AdcRegs.ADCTRL3.bit.ADCBGRFDN = 3;
DSP28x_usDelay(((((long double) 5000L * 1000.0L) / (long double)CPU_RATE) - 9.0L) / 5.0L);
AdcRegs.ADCTRL3.bit.ADCPWDN = 1;
DSP28x_usDelay(((((long double) 5000L * 1000.0L) / (long double)CPU_RATE) - 9.0L) / 5.0L);
AdcRegs.ADCTRL1.bit.RESET = 0;
AdcRegs.ADCTRL1.bit.SEQ_CASC = 1; // 1 Cascaded mode
AdcRegs.ADCCHSELSEQ1.all = 0x3210; // Canales a ser ledos
AdcRegs.ADCCHSELSEQ2.all = 0x7654;
AdcRegs.ADCCHSELSEQ3.all = 0xBA98;
AdcRegs.ADCCHSELSEQ4.all = 0xFEDC;
AdcRegs.ADCMAXCONV.bit.MAX_CONV1 = 15; // Leer 16 canales por cada SOC
AdcRegs.ADCTRL1.bit.CONT_RUN = 0; // Modo no continuo
AdcRegs.ADCTRL2.bit.EVA_SOC_SEQ1 = 1; // SOC desde EVA
AdcRegs.ADCTRL2.bit.SOC_SEQ1 = 1; //Sugerencia de Kick Off
while(AdcRegs.ADCST.bit.SEQ1_BSY ==1) {}; // esperar a ADC termine
Source= (void *)&AdcRegs.ADCRESULT0; // Actualizar primeros datos en
Dest = ResultadoADC; // variable ResultadoADC
for(i=0; i < 16; i++)
*Dest++ = *Source++;
}

CLASE 6
PWMs

Manual Recomendado spru065.pdf Captulo 1. Registros en el Captulo 5.3

Las llaves de PWMs sirven para el disparo de puentes de IGBTs, Mosfets o BJTs. Son un grupo de 6 pines
PWMs desde el PWM1 hasta el PWM6 para el Event Manager A. Trabajan en parejas, es decir que el
PWM1 y el PWM2 estn asociados y dependen de un slo valor de comparacin, en este caso de un
registro llamado CMPR1. Por ejemplo el PWM3 y PWM4 trabajan con su fase dependiente del registro
CMPR2, en la siguiente figura hasy tres bloques llamados "Full Compare 1,2 y 3", estos sera los tres
comparadores y donde el periodo es el mismo que se program en el Timer 1, es decir, el periodo de las 6
llaves de PWM dependen del registro de periodo T1PR y del modo de conteo.
El ACTRA

As como el GPTCON para el caso del pin T1PWM, en el caso de los 6 PWMs se cuenta con el registro
ACTRA, en este registro se programa la direccin del flanco, s por la logica se requiera que el PWM
dispare en flanco positivo o negativo.

Por ejemplo cuando el comparador CMPR1 coincide con el valor del contador T1CNT, entonces los pines
PWM1 y PWM2 pueden disparar de 0v a 3.3v, llamado activo arriba, pueden disparar flanco abajo de
3.3v a 0v, llamado activo abajo. Tambin puede servir para bloquear las seales de salida, para casos de
emergencia, forzando a los IGBTs en un estado contnuo de 0v 3.3v.

Los DSPs no son capaces de manejar las puertas de los chips de potencia, los IGBTs por ejemplo trabajan
con tensiones de +-5v hasta +-15v, por lo que estos dispositivos deben contar con un predriver. Algunos
predrivers son disparados por flancos positivos para las llaves altas Q1, Q3 y Q5, y flancos negativos para
las llaves bajas, otros son iguales etc, esto depende del predriver y hay que prestar atencin al manual
datasheet del chip.

El COMCONA

El Registro COMCONA maneja la habilitacin de las comparaciones, el momento de recarga de los


CMPRs y ACTRA, el tripeo en caso de fallas y el poner los pines en alta impedancia.

Hay que poner atencin de si se est trabajando con el sistema moderno donde el INDCOE
EXTCONA[0]=1, si este bit es uno, entonces se trabaja en el sistema moderno, donde cada pareja de llaves
PWM son tripeadas o puestas en alta impedancia, y no como en el sistema antiguo donde el bit 9 FCMPOE
ponia a todas las 6 llaves en alta impedancia.
Por ejemplo si EXTCONA[0]=1 (sistema moderno), si ocurre un percance y la lnea de emergencia
conectada al pin GPIOA13/C1TRIP cae a 0v, y adems se habilit el tripeo con el bit 0 de COMCONA
que es el habilitador de C1TRIPE, entonces esta accin forzara a los PWMs 1 y 2 que se pongan en alta
impedancia y que el bit 5 de COMCONA que es el maneja la alta impedancia de los pines FCMP1OE se
caiga a 0 indicando que estn en alta impedancia.

NOTA IMPORTANTE.- Los CxTRIPE son pines muy sensibles, que incluso con el ruido de los chips se
dispara casi solo, por lo que si no se va a conectar un driver que obligue al pin a estar a 3.3v, se recomienda
entonces para el caso de laboratorios o desarrollos que permanezcan deshabilitados hasta que se hagan
pruebas con los drivers conectados a los sitemas de emergencia.

Recordar que para que el programa funcione bien, primero hay que habilitar el sistema moderno con el
INDCOE y luego deshabilitar el CxTRIP.

Laboratorio # 7

En el laboratorio 7 se configuran los registros necesarios para el arranque del Timer 1, con su respectivo
periodo T1PER a 10KHz. Se van a generar 3 seales senoidales desfasadas 120 grado, las cuales van a
poder ser grabadas por un tiempo de 0.5 segundo. Los valores de voltajes van a ser convertidos en fases de
comparacin para los tres CMPRxs, es preferible trabajar en por unidad, de manera que se tenga una
mxima excursin de los comparadores cuando el voltaje solicitado sea igual al voltaje nominal, el cual
debe estar cercano al voltaje de la fuante DC de alimentacin (siempre hay un poco de prdidas por lo que
se recomienda escoger un vnominal = (85%) vfuenteDC.

Las seales sern entregadas a un mdulo de potencia IRAM de 20 amperios, la fuente de alimentacin
podra ser de hasta 600V DC, pero en este caso solo se va a trabajar con 20V por seguridad, incluso hay
una lnea del DSP que va a manejar el rel de alimentacin del mdulo.

Se procece a verificar en el osciloscopio:

* Formas de onda trifsica generadas

* Funcionamiento de un rel manejado por el DSP

* Disparo arriba abajo por el GPTCON

* Tiempo muerto, sus variaciones

* Cambios de frecuencia y amplitud en el motor trifsico Siemens

* Amplificacin del inversor

Programa lab7.c

#include "DSP281x_Device.h"
#include "DSP281x_Examples.h"
#include "lab7.h"
#include "monitor.h"
#include "math.h"
long int i,k;
void ini_eva_timer1(void);
interrupt void eva_timerT1PER_isr(void);
interrupt void eva_timerT1CMP_isr(void);
#pragma DATA_SECTION(VfaseA,"Datos1"); // directiva para ubicar una variable
#pragma DATA_SECTION(VfaseB,"Datos2"); // en alguna seccin especfica
#pragma DATA_SECTION(VfaseC,"Datos3"); // de la memoria
float Va,Vb,Vc; // Variables de las 3 fases elctricas desfasadas 120 grados
float VfaseA[500]; // Tres vectores para guardar datos de los
float VfaseB[500]; // voltajes de fase
float VfaseC[500];
int T1fase=0;
float const pi=3.1415926535;
float Vm=1.4142*320/1.73205; //voltaje fase
float Vn=1.4142*380/1.73205; //voltaje nominal
float w=6.2831853*1.0; //velocidad sincrona rad/seg 2pif
float t=0; //tiempo
float Tm=0.0001; //tiempo de muestreo
unsigned int medioper=0;
void main(void) {
DINT;
DRTM;
InitSysCtrl();
InitPieCtrl();
IER = 0x0000;
IFR = 0x0000;
InitPieVectTable();
EALLOW;
PieVectTable.T1PINT = &eva_timerT1PER_isr; // redireccionar interrupciones
PieVectTable.T1CINT = &eva_timerT1CMP_isr;
GpioMuxRegs.GPAMUX.bit.T1PWM_GPIOA6=1;
GpioMuxRegs.GPFMUX.bit.XF_GPIOF14 = 1;
GpioMuxRegs.GPAMUX.bit.CAP2Q2_GPIOA9 = 0; // Rel de alimentacin es IO
GpioMuxRegs.GPAMUX.bit.PWM1_GPIOA0=1; // Pines de las 6 llaves de PWM1-6
GpioMuxRegs.GPAMUX.bit.PWM2_GPIOA1 =1;
GpioMuxRegs.GPAMUX.bit.PWM3_GPIOA2 =1;
GpioMuxRegs.GPAMUX.bit.PWM4_GPIOA3 =1;
GpioMuxRegs.GPAMUX.bit.PWM5_GPIOA4 =1;
GpioMuxRegs.GPAMUX.bit.PWM6_GPIOA5 =1;
GpioMuxRegs.GPADIR.bit.GPIOA9 = 1; // Rel es salida
EDIS;
GpioDataRegs.GPACLEAR.bit.GPIOA9 = 1; //Abajo prende rel
PieCtrlRegs.PIEIER2.all = M_INT4 | M_INT5;
IER = IER | M_INT2;
i=0;
k=0;
ini_eva_timer1();
medioper = EvaRegs.T1PR/2; // medioper es la mitad del periodo de T1
EINT;
ERTM;
do{ //hacer loop por lo menos una vez
IteraSerial();
}while(1); //Itera infinitamente
}
void ini_eva_timer1(void)
{
EvaRegs.T1PR = 0x0752; // 10Khz
EvaRegs.T1CMPR = 0x03A9;
EvaRegs.EVAIMRA.bit.T1PINT = 1; //Limpieza de banderas y mscaras
EvaRegs.EVAIFRA.bit.T1PINT = 1;
EvaRegs.EVAIMRA.bit.T1CINT = 1;
EvaRegs.EVAIFRA.bit.T1CINT = 1;
EvaRegs.EVAIMRA.bit.PDPINTA = 0; // No tripear en modo antiguo
EvaRegs.T1CNT = 0x0000;
EvaRegs.T1CON.all = 0x9202; //(75MHz/4)
asm(" nop");
asm(" nop");
EvaRegs.T1CON.all = 0x9242;
EvaRegs.GPTCONA.bit.T1TOADC = 2; // interrupt del T1PER
EvaRegs.GPTCONA.bit.T1PIN =2;
EvaRegs.GPTCONA.bit.T1CMPOE =1;
EvaRegs.GPTCONA.bit.TCMPOE =1;
EvaRegs.ACTRA.all = 0x0666; //0000 0110 0110 0110 PWMs invertidos para disparar IGBTs
EvaRegs.COMCONA.all = 0xA6E0; //Compare habilitado,recarga de ACTRA y CMPRs, habilita FCMP
EvaRegs.DBTCONA.bit.DBT = 2; // ciclos que debe haber DB
EvaRegs.DBTCONA.bit.EDBT1 = 1; // habilitar tiempo muerto para las 3 parejas
EvaRegs.DBTCONA.bit.EDBT2 = 1;
EvaRegs.DBTCONA.bit.EDBT3 = 1;
EvaRegs.DBTCONA.bit.DBTPS= 0x4; // prescala tamao del escalo
}
interrupt void eva_timerT1PER_isr(void)
{
i++; // incrementar contador
if(i == 1000) { // cada 1000 veces o un 0.1 segundo incrementar fase de T1PWM
T1fase++;
if (T1fase == EvaRegs.T1PR) T1fase = 0; // si llega al valor de T1PR limpiar
i=0;
};
t=k*Tm; // es el tiempo gracias a la muestra k y el timepo de muestreo Tm
Va=Vm*cos(w*t); // Los voltajes de fase toman una forma senoidal
Vb=Vm*cos(w*t-120*pi/180); // desfasadas 120 grados elctricos
Vc=Vm*cos(w*t+120*pi/180);
if(k<500)
{
VfaseA[k]=Va; // Los primero 500 valores 0.05 seg pueden ser grabados
VfaseB[k]=Vb; // Las grficas salen bien a 30Hz cuando w=6.2831853*30.0
VfaseC[k]=Vc;
};
k++;
EvaRegs.CMPR1 = (unsigned int)(medioper*(1.0+Va/Vn)); // La fase del PWM se ubica
EvaRegs.CMPR2 = (unsigned int)(medioper*(1.0+Vb/Vn)); // a un valor proporcional
EvaRegs.CMPR3 = (unsigned int)(medioper*(1.0+Vc/Vn)); // a su voltaje con respecto
// al 50% del duty cycle para producir una salida bipolar por fase
EvaRegs.T1CMPR = T1fase; // actualiza la fase del T1PWM con la fase
EvaRegs.EVAIMRA.bit.T1PINT = 1;
EvaRegs.EVAIFRA.all = BIT7;
PieCtrlRegs.PIEACK.all = PIEACK_GROUP2;
}
interrupt void eva_timerT1CMP_isr(void)
{
EvaRegs.EVAIMRA.bit.T1CINT = 1;
EvaRegs.EVAIFRA.all = BIT8;
PieCtrlRegs.PIEACK.all = PIEACK_GROUP2;
}

Para ver el grfico producido por la seal coseno, dar a Tools->Graph->Single Time

LLenar con:

- Adq. Buffer size : 500

- 32 bits floating point

- Sample rate Hz: 10000

- Start Address: VfaseA

- Display Data Size: 500


Fuente: www.varitek.us

Das könnte Ihnen auch gefallen