Informe proyecto expoelectronica
Control en lazo cerrado para motor DC de imán
permanente
Integrantes Diego Armando Amaris MorenoJosé Luis Hernández Lozano
Curso E069 6° semestre Tecnología en electrónica
ProfesorEduardo San Miguel
Año 2010
Funcionamiento
El sistema consta de cuatro partes principales:
1- HMI interfaz hombre maquina.Se hace por medio de un teclado matricial de 4 x 4, por medio de este el usuario ingresa la velocidad que se requiere, teniendo en cuenta el rango de velocidades disponibles, tanto para el motor (500 - 2000rpm) y la rueda (100 – 500rpm).
2- Procesamiento de información.Esta parte es dirigida por el microcontrolador MC9S08JM60 de Freescale, el cual está montado sobre un modulo auto programable desarrollado por la empresa Octoplus de Bucaramanga.Se encarga de capturar, procesar y generar una señal PWM de control, las señales que captura son:
HMI Teclado matricial Realimentación análoga (generador) Realimentación digital (encoder)
Esta información es procesada por el microcontrolador para generar la señal de control PWM (modulación por ancho de pulso) de 5V.
3- Control de potencia.Esta parte inicia con un optoacoplador, se encarga de transmitir la señal de control PWM, al circuito de control de potencia, por medio de luz, para aislar y proteger al microcontrolador del voltaje de operación del motor (24V DC).Luego por medio de un transistor Mosfet se cambia la amplitud de de la señal PWM de 5V a 24V para aplicarla en los terminales del motor y así poder controlar la velocidad del motor por medio del ancho de pulso de la señal, el cual se cambia desde el microcontrolador, por medio del teclado o las realimentaciones.
4- Realimentación.El sistema cuenta con dos tipos de realimentación:
Realimentación análoga: usando un motor adicional acoplado al eje del motor principal se genera un voltaje de 0.3V a 1.5V dependiendo de la velocidad a la que valla el motor principal. Para saber que velocidad representaba cada voltaje se tomaron muestras del voltaje generado por el motor y el valor decimal del conversor análogo/digital del micro (ver figura1), luego con estos datos se logro hacer al algoritmo para realimentación análoga,
el cual consiste en procesar el valor del registro ADCR del micro para obtener su equivalente real en rpm y luego compararlo con el valor rpm que el usuario ingreso por medio del teclado, si el valor equivalente obtenido a partir del ADCR, es menor que el valor ingresado en el teclado el programa aumentara el valor del registro TPM1C3V para aumentar el ancho de pulso de la señal PWM que sale del microcontrolador y por lo tanto aumentar la velocidad del motor, y si el valor equivalente es mayor que el ingresado desde el teclado el programa disminuirá el valor de TPM1C3V para disminuir el ancho de pulso de la señal PWM y así disminuir la velocidad del motor, todo esto con el fin de mantener la velocidad ingresada desde el teclado.
Realimentación digital: se hace por medio de un encoder que consta de un disco plástico de Ø4.5 cm con 10 agujeros de Ø5mm y un sensor óptico. Acoplado al eje del motor principal.Este dispositivo cambia de estado 1 a 0 cada vez que censa un agujero, luego al programar el microcontrolador se decidió darle un tiempo de 100ms para que el contara el número de agujeros que veía en este tiempo. Ahora como se necesita la velocidad en rpm, para poderla comparar con el valor ingresado en el teclado se hizo la siguiente operación dentro del programa:A= # de agujeros que conto el micro en 100ms.B= # de agujeros de la rueda (10).Ø rueda= 6cm, Ø polea motor= 1.7cm
RPM(motor)= ((A x 10)/B)x60seg
Que simplificado queda:
RPM(motor)= A x 60seg RPM(rueda)= (1.7cm x RPM(motor))/6cm
Luego de calcular la velocidad en rpm por medio de la lectura del encoder se procede a comparar este valor con el ingresado en el teclado si es menor el programa aumentara el valor del registro TPM1C3V para aumentar el ancho de pulso de la señal PWM que sale del microcontrolador y por lo tanto aumentar la velocidad del motor, si el valor es mayor que el ingresado desde el teclado el programa disminuirá el valor de TPM1C3V para disminuir el ancho de pulso de la señal PWM y así disminuir la velocidad del motor, todo esto con el fin de mantener la velocidad ingresada desde el teclado.
Control rueda Control motor
valor teclado
valor registro ADCR (micro)
Voltaje generado
valor registro ADCR (micro)
Voltaje generado
100 150 446 0,464 200 563 0,611 250 731 0,794 300 818 0,959 350 984 1,123 400 1038 1,289 450 1286 1,448 500 1429 1,614 435 0,461550 453 0,521600 520 0,528650 532 0,576700 534 0,633750 619 0,686800 687 0,739850 698 0,794900 728 0,797950 758 0,8531000 787 0,9061050 800 0,9611100 842 1,0151150 886 1,0761200 895 1,0791250 948 1,1251300 1007 1,1811350 1045 1,2331400 1088 1,2881450 1102 1,3421500 1182 1,3481550 1195 1,3911600 1204 1,4511650 1282 1,5041700 1312 1,5581750 1417 1,6121800 1458 1,6141850 1531 1,6651900 1598 1,721950 1636 1,7752000 1645 1,826
figura1
Diagrama de flujo del sistema:
Características de funcionamiento:
CONTROL DE POTENCIA
OptoacopladorMosfetMotor 24V
PROCESAMIENTO DE INFORMACION
Microcontrolador MC9S08JM60
5V
REALIMENTACION
Análoga (generador)Digital (encoder)
HMI Teclado
Variación de potencia por medio de señal PWM. Rango de velocidades en la rueda: 100 a 500 rpm. Rango de velocidades en el motor: 500 a 2000 rpm Rango de voltaje del generador: 0.4v a 1.3v dc Resolución del conversor AD 12 bits Tiempo de captura para el encoder: 100ms Voltaje de operación del motor: 24V DC Voltaje de operación circuito de control 5V El control de potencia lo hace un transistor mosfet de canal n, el
IRFZ44N. La etapa de aislamiento, control/potencia es realizada por medio de un
opto acoplador 817C.
Funcionamiento del teclado:
Tecla Función0-9 Configura magnitud de velocidadA Aceptar B Borrar C Activar realimentación análoga (motor-generador)D Activar realimentación digital (encoder)* Capturar ó cambiar velocidad # Activar control de velocidad para el motor, sin pulsarlo normalmente
controla la velocidad de la rueda.
Diagrama eléctrico del sistema
Circuito impreso con PCB Wizard
Programa que contiene el
microcontrolador Lenguaje de programación: C.
Software utilizado: Code Warrior 10
#include <hidef.h> /* for EnableInterrupts macro */#include "derivative.h" /* include peripheral declarations */#include <stdio.h>
const byte NVOPT_INIT @0x0000FFBF = 0x02; // vector redirect, flash unsecureconst byte NVPROT_INIT @0x0000FFBD = 0xFA; // 0xFC00-0xFFFF are protected
extern void _Startup(void);
/********************************************************//*------- Espacio para declaracion de constantes ------*//********************************************************/
/********************************************************//*--- Espacio para declaracion de variables globales --*//********************************************************/
unsigned char uni=0;unsigned char dec=0;unsigned char cen=0;unsigned char umil=0;unsigned char var=0;unsigned long time=0;unsigned long time2=0; unsigned char tecla=0;double dato=0;unsigned long dato3=0;unsigned long dato4=0;double dato2=0;unsigned long vueltas=0;unsigned long cambiar_velocidad=0;unsigned long control_en_motor=0;double promedio=0;unsigned long pro=0;unsigned long error=0;unsigned long v_x_min_motor=0;double v_x_min_rueda=0;unsigned char real_analog=0;unsigned char real_digi=0;
unsigned char tabla[16]={ 0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x27,0x7f,0x6f,0x77,0x7c,0x39,0x5e,0x79,0x71};
unsigned char tabla2[16]={ 0x01,0x02,0x03,0x0a,0x04,0x05,0x06,0x0b,0x07,0x08,0x09,0x0c,0x0f,0x00,0x0e,0x0d};
/********************************************************//********************************************************//*-------------- Espacio para funciones ---------------*//********************************************************/
//////DECODIFICACION PARA MINI DISPLAY CATODO COMUN///////// void deco(void){PTED=tabla[var];return;}
/////////RETARDO1////////// void retar(void){for(time=0;time<255;time++){asm nop}}
/////////RETARDO2////////// void retar2(void){for(time2=0;time2<75;time2++){asm nop }}
//////////BCD A BINARIO///////
void bcd_a_bin (void){dato=0;dato=umil*1000;dato=dato+(cen*100);dato=dato+(dec*10);dato=dato+uni; }
/////////bin a bcd///////////
void bin_a_bcd(void){ uni=0; dec=0; cen=0; umil=0; while(dato2>=1000){ umil++; dato2=dato2-1000; } while(dato2>=100){ cen++; dato2=dato2-100; } while(dato2>=10){ dec++; dato2=dato2-10; } uni=dato2;} /////////PROCESO//////////////void proceso(void){tecla=tabla2[tecla];if(tecla==0x0a){ bcd_a_bin();
TPM1C3V=dato; //al variar el valor de este registro se modifica el ancho de pulso de la señal PWM}if(tecla==0x0b){
uni=0;dec=0;cen=0;umil=0;tecla=0;TPM1C3V=0;real_analog=0;real_digi=0;cambiar_velocidad=0;control_en_motor=0;}
if(tecla==0x0c){ // Realimentacion con convesor A/D motor generadorreal_analog=1;real_digi=0;
cambiar_velocidad=0;
}
if(tecla==0x0d){ // Realimentacion con interrupcion externa IRQ real_analog=0;real_digi=1;cambiar_velocidad=0;
}
if(tecla==0x0F){ // Capturar y cambiar velocidadcambiar_velocidad=1;real_digi=0;real_analog=0;}
if(tecla==0x0e){ control_en_motor=1; // activa control de velocidad para el motordato4++;if(dato4==2){control_en_motor=0; // activa control de velocidad para la ruedadato4=0;}
}
if(tecla>=0 && tecla<=9){umil=cen;cen=dec;dec=uni;uni=tecla;}while(PTBD_PTBD5==0||PTBD_PTBD4==0||PTGD_PTGD3==0||PTGD_PTGD2==0){ PTED=0;}}
///////// CONTROL POR MUESTREO EN RUEDA//////////
void control_por_muestreo_rueda(void){if(dato==150){ // 150 rpmif(ADCR<446){TPM1C3V=TPM1C3V+error;}if(ADCR>446){TPM1C3V=TPM1C3V-error;} }if(dato==200){if(ADCR<563){TPM1C3V=TPM1C3V+error;}if(ADCR>563){TPM1C3V=TPM1C3V-error;} }if(dato==250){if(ADCR<731){TPM1C3V=TPM1C3V+error;}if(ADCR>731){TPM1C3V=TPM1C3V-error;} }if(dato==300){if(ADCR<818){TPM1C3V=TPM1C3V+error;}if(ADCR>818){TPM1C3V=TPM1C3V-error;
} }if(dato==350){if(ADCR<984){TPM1C3V=TPM1C3V+error;}if(ADCR>984){TPM1C3V=TPM1C3V-error;} }
if(dato==400){ if(ADCR<1038){
TPM1C3V=TPM1C3V+error;}if(ADCR>1038){TPM1C3V=TPM1C3V-error;} }
if(dato==450){ if(ADCR<1286){ TPM1C3V=TPM1C3V+error; } if(ADCR>1286){ TPM1C3V=TPM1C3V-error; } } if(dato==500){ // Hasta 500 rpm (en la rueda) if(ADCR<1429){ TPM1C3V=TPM1C3V+error; } if(ADCR>1429){ TPM1C3V=TPM1C3V-error; } }
}
///////// CONTROL POR MUESTREO EN EL MOTOR//////////
void control_por_muestreo_motor(void){if(dato==500){ // desde 500 rpmif(ADCR<435){TPM1C3V=TPM1C3V+error;}if(ADCR>435){TPM1C3V=TPM1C3V-error;} }if(dato==550){if(ADCR<453){TPM1C3V=TPM1C3V+error;}if(ADCR>453){TPM1C3V=TPM1C3V-error;} }if(dato==600){if(ADCR<520){TPM1C3V=TPM1C3V+error;}if(ADCR>520){TPM1C3V=TPM1C3V-error;} }if(dato==650){if(ADCR<532){TPM1C3V=TPM1C3V+error;}if(ADCR>532){TPM1C3V=TPM1C3V-error;} }
if(dato==700){if(ADCR<554){TPM1C3V=TPM1C3V+error;}if(ADCR>554){TPM1C3V=TPM1C3V-error;} }
if(dato==750){ if(ADCR<619){
TPM1C3V=TPM1C3V+error;}if(ADCR>619){TPM1C3V=TPM1C3V-error;} }
if(dato==800){ if(ADCR<687){ TPM1C3V=TPM1C3V+error; } if(ADCR>687){ TPM1C3V=TPM1C3V-error; } } if(dato==850){ if(ADCR<698){ TPM1C3V=TPM1C3V+error; } if(ADCR>698){ TPM1C3V=TPM1C3V-error; } } if(dato==900){ if(ADCR<728){ TPM1C3V=TPM1C3V+error; } if(ADCR>728){ TPM1C3V=TPM1C3V-error; } } if(dato==950){ if(ADCR<758){ TPM1C3V=TPM1C3V+error; } if(ADCR>758){ TPM1C3V=TPM1C3V-error; } } if(dato==1000){ if(ADCR<787){ TPM1C3V=TPM1C3V+error; } if(ADCR>787){ TPM1C3V=TPM1C3V-error; } } if(dato==1050){ if(ADCR<800){ TPM1C3V=TPM1C3V+error; } if(ADCR>800){ TPM1C3V=TPM1C3V-error; } } if(dato==1100){ if(ADCR<842){ TPM1C3V=TPM1C3V+error; } if(ADCR>842){ TPM1C3V=TPM1C3V-error; }
} if(dato==1150){ if(ADCR<886){ TPM1C3V=TPM1C3V+error; } if(ADCR>886){ TPM1C3V=TPM1C3V-error; } } if(dato==1200){ if(ADCR<895){ TPM1C3V=TPM1C3V+error; } if(ADCR>895){ TPM1C3V=TPM1C3V-error; } } if(dato==1250){ if(ADCR<948){ TPM1C3V=TPM1C3V+error; } if(ADCR>948){ TPM1C3V=TPM1C3V-error; } } if(dato==1300){ if(ADCR<1007){ TPM1C3V=TPM1C3V+error; } if(ADCR>1007){ TPM1C3V=TPM1C3V-error; } } if(dato==1350){ if(ADCR<1045){ TPM1C3V=TPM1C3V+error; } if(ADCR>1045){ TPM1C3V=TPM1C3V-error; } } if(dato==1400){ if(ADCR<1088){ TPM1C3V=TPM1C3V+error; } if(ADCR>1088){ TPM1C3V=TPM1C3V-error; } } if(dato==1450){ if(ADCR<1102){ TPM1C3V=TPM1C3V+error; } if(ADCR>1102){ TPM1C3V=TPM1C3V-error; } } if(dato==1500){ if(ADCR<1182){ TPM1C3V=TPM1C3V+error; } if(ADCR>1182){ TPM1C3V=TPM1C3V-error; } } if(dato==1550){ if(ADCR<1195){ TPM1C3V=TPM1C3V+error; } if(ADCR>1195){ TPM1C3V=TPM1C3V-error;
} } if(dato==1600){ if(ADCR<1204){ TPM1C3V=TPM1C3V+error; } if(ADCR>1204){ TPM1C3V=TPM1C3V-error; } } if(dato==1650){ if(ADCR<1282){ TPM1C3V=TPM1C3V+error; } if(ADCR>1282){ TPM1C3V=TPM1C3V-error; } } if(dato==1700){ if(ADCR<1312){ TPM1C3V=TPM1C3V+error; } if(ADCR>1312){ TPM1C3V=TPM1C3V-error; } } if(dato==1750){ if(ADCR<1417){ TPM1C3V=TPM1C3V+error; } if(ADCR>1417){ TPM1C3V=TPM1C3V-error; } } if(dato==1800){ if(ADCR<1458){ TPM1C3V=TPM1C3V+error; } if(ADCR>1458){ TPM1C3V=TPM1C3V-error; } } if(dato==1850){ if(ADCR<1531){ TPM1C3V=TPM1C3V+error; } if(ADCR>1531){ TPM1C3V=TPM1C3V-error; } } if(dato==1900){ if(ADCR<1598){ TPM1C3V=TPM1C3V+error; } if(ADCR>1598){ TPM1C3V=TPM1C3V-error; } } if(dato==1950){ if(ADCR<1636){ TPM1C3V=TPM1C3V+error; } if(ADCR>1636){ TPM1C3V=TPM1C3V-error; } } if(dato==2000){ // Hasta 2000 rpm (en le
motor) if(ADCR<1645){ TPM1C3V=TPM1C3V+error; }
if(ADCR>1645){ TPM1C3V=TPM1C3V-error; } }
}
///////// REALIMENTACION ANALOGA///////
void r_an(void){if(real_analog==1){
if(control_en_motor==0){control_por_muestreo_rueda();dato2=ADCR/2.8;
}if(control_en_motor==1){
control_por_muestreo_motor();dato2=ADCR*1.19;
}bin_a_bcd();}}
/////////MOSTRAR EN DISPLAYS///////////
void mostrar_en_displays(void){
var=uni; deco(); PTCD_PTCD4=1; retar(); PTCD_PTCD4=0;
var=dec; deco(); PTCD_PTCD2=1; retar(); PTCD_PTCD2=0; var=cen; deco(); PTCD_PTCD0=1; retar(); PTCD_PTCD0=0; var=umil; deco(); PTCD_PTCD1=1; retar(); PTCD_PTCD1=0; }
///////////TIEMPO DE CAPTURA (100 ms)//////////
interrupt void segundo( void ){ if (real_digi==1){ v_x_min_motor=vueltas*60;if (control_en_motor==0){ v_x_min_rueda=(1.7*v_x_min_motor)/6;}if (control_en_motor==1){ v_x_min_rueda=v_x_min_motor;}vueltas=0; dato2=v_x_min_rueda; bin_a_bcd(); }r_an();RTCSC_RTIF=1;}
///////////// IRQ/////////////////////interrupt void IRQ( void ){ if (real_digi==1){ vueltas++; if (dato<v_x_min_rueda){ TPM1C3V=TPM1C3V-1; } if (dato>v_x_min_rueda){ TPM1C3V=TPM1C3V+3; } } IRQSC_IRQACK=1; } ///////////TECLADO/////////////////////
interrupt void teclado( void ){ tecla=0;PTBD=0X0E;while (tecla<16){ if (PTBD_PTBD5==0){ proceso(); } tecla++; if (PTBD_PTBD4==0){ proceso(); } tecla++; if (PTGD_PTGD2==0){ proceso(); } tecla++; if (PTGD_PTGD3==0){ proceso(); } tecla++; asm rol PTBD } KBISC_KBACK=1; }
/********************************************************//********************************************************//*------------ Espacio de codigo principal -------------*//********************************************************/ void main(void) {SOPT1 = 0x20; //Deshabilita el modulo COP (WDT)
///////////INICIO DE PROGRAMA//////////
asm cli //habilita interrupciones del micro PTGDD=0x00; //congigura puerto G como entrada PTBDD=0x0F; //congigura puerto B como entrada(para columnas del teclado) y como salida(para filas del teclado) PTFDD=0x1F; //configura Puerto F como entrada(para captura) y salida(para señal PWM) PTEDD=0xFF; //congigura puerto E como salida (SEGMENTOS display) PTCDD=0XFF; //congigura puerto C como salida (catodos comunes de los 4 displays) PTBPE=0x30; //habilita resistencias Pullup Enable del puerto B (B5 y B4) PTGPE=0x0C; //habilita resistencias Pullup Enable del puerto G (G3 y G2) // CONFIGGURACION DEL IRQ IRQSC=0X12; //captura señal del encoder // CONFIGURACION MODULO TIEMPO REAL PARA GENERAR INTERRUPCIONES DE 100 ms RTCMOD=0x00; RTCSC=0x1D; //configura 1ms //CONFIGURACION DEL TECLADO KBISC=0X02; //habilita interrupcion KBI
KBIPE=0XF0; //configura puertos de interrupcion del KBI(B5,B4,G3,G2) //CONFIGURACION DEL PWM TPM1 TPM1SC=0X28; // habilita PWM, centra canales PWM, elije fuente de reloj (24MHz)y selecciona prescalador x 1. TPM1MOD=7500; // configura valor maximo del contador TPM1 en 7500 TPM1C3SC_ELS3B=1; //CH 3 del PWM se activa en alto //CONFIGURACION DEL ADC ADCCFG=0x14; // selecciona 12 bits de convercion, selecciona fuente de reloj "bus", tiempo de muestro largo, divide reloj por 1, selecciona alta velocidad. ADCSC2=0x30; // gatillo por software, habilita funcion de comparacion,tipo de comparacion mayor o igual. ADCSC1=0x29; // selecciona canal 9 del ADC (PTD1)y habilita convercion continua. error=20;
while(1){ //loop infinito que solo hace la rutina "mostrar en displays"mostrar_en_displays();PTBD=0;}
// EnableInterrupts; for(;;) {
} }//*******************************************************
/*Dummy ISR */interrupt void Dummy_ISR( void ) {}
void (* volatile const _UserEntry[])()@0xFABC={ 0x9DCC, // asm NOP(9D), asm JMP(CC) _Startup}; // redirect vector 0xFFC0-0xFFFD to 0xFBC0-0xFBFDvoid (* volatile const _Usr_Vector[])()@0xFBC4= { segundo, // Int.no.29 RTC (at FBC4) (at FFC4) Dummy_ISR, // Int.no.28 IIC (at FBC6) (at FFC6) Dummy_ISR, // Int.no.27 ACMP (at FBC8) (at FFC8) Dummy_ISR, // Int.no.26 ADC (at FBCA) (at FFCA) teclado, // Int.no.25 KBI (at FBCC) (at FFCC) Dummy_ISR, // Int.no.24 SCI2 Transmit (at FBCE) (at FFCE) Dummy_ISR, // Int.no.23 SCI2 Receive (at FBD0) (at FFD0) Dummy_ISR, // Int.no.22 SCI2 Error (at FBD2) (at FFD2) Dummy_ISR, // Int.no.21 SCI1 Transmit (at FBD4) (at FFD4) Dummy_ISR, // Int.no.20 SCI1 Receive (at FBD6) (at FFD6) Dummy_ISR, // Int.no.19 SCI1 error (at FBD8) (at FFD8) Dummy_ISR, // Int.no.18 TPM2 Overflow (at FBDA) (at FFDA) Dummy_ISR, // Int.no.17 TPM2 CH1 (at FBDC) (at FFDC) Dummy_ISR, // Int.no.16 TPM2 CH0 (at FBDE) (at FFDE) Dummy_ISR, // Int.no.15 TPM1 Overflow (at FBE0) (at FFE0) Dummy_ISR, // Int.no.14 TPM1 CH5 (at FBE2) (at FFE2) Dummy_ISR, // Int.no.13 TPM1 CH4 (at FBE4) (at FFE4) Dummy_ISR, // Int.no.12 TPM1 CH3 (at FBE6) (at FFE6) Dummy_ISR, // Int.no.11 TPM1 CH2 (at FBE8) (at FFE8) Dummy_ISR, // Int.no.10 TPM1 CH1 (at FBEA) (at FFEA) Dummy_ISR, // Int.no.9 TPM1 CH0 (at FBEC) (at FFEC) Dummy_ISR, // Int.no.8 Reserved (at FBEE) (at FFEE)
Dummy_ISR, // Int.no.7 USB Statue (at FBF0) (at FFF0) Dummy_ISR, // Int.no.6 SPI2 (at FBF2) (at FFF2) Dummy_ISR, // Int.no.5 SPI1 (at FBF4) (at FFF4) Dummy_ISR, // Int.no.4 Loss of lock (at FBF6) (at FFF6) Dummy_ISR, // Int.no.3 LVI (at FBF8) (at FFF8) IRQ, // Int.no.2 IRQ (at FBFA) (at FFFA) Dummy_ISR, // Int.no.1 SWI (at FBFC) (at FFFC) };
#pragma CODE_SEG Bootloader_ROM
void Bootloader_Main(void);
void _Entry(void) { PTGD = 0x00; PTGDD = 0xF0; //PTG0-3 used for KBI input
PTGPE = 0x0F; //Pull-up enable // MCG clock initialization, fBus=24MHz MCGC2 = 0x36; //MCGC2_EREFS=0; while(!(MCGSC & 0x02)); //wait for the OSC stable MCGC1 = 0x1B;
MCGC3 = 0x48;while ((MCGSC & 0x48) != 0x48); //wait for the PLL is locked
// Flash clock FCDIV=0x4E; // PRDIV8=1; DIV[5:0]=14, flash clock should be 150-200kHz // bus clock=24M, flash clock=fbus/8/(DIV[5:0]+1) // bus clock=24M, flash clock=fbus/8/(DIV[5:0]+1) if(!PTGD_PTGD0) { SOPT1 = 0x20; // disable COP only if bootloader mod is requested // PTG0 is pressed USBCTL0=0x44; USBCTL0_USBVREN=1; Bootloader_Main(); // Bootloader mode } else asm JMP _UserEntry; // Enter User mode}
#pragma CODE_SEG default