Autor Tema: PIC BASIC del PIC Simulator IDE Oshonsoft (Índice en página 1)  (Leído 859655 veces)

0 Usuarios y 1 Visitante están viendo este tema.

Desconectado 21CURIOSOS

  • PIC12
  • **
  • Mensajes: 56
Re: PIC BASIC del PIC Simulator IDE
« Respuesta #465 en: 09 de Octubre de 2008, 19:36:19 »
Usando el ADC del gatillo como word se me reduce el tiempo de ejecucion, durante un proceso de 13 ciclos (pongo un bucle dentro de la rutina loop: para realizar trece ciclos), se reduce en 600 us.

¿Es que funciona mejor usando los 10 bits ?

Desconectado huesonardo

  • PIC10
  • *
  • Mensajes: 2
Re: PIC BASIC del PIC Simulator IDE
« Respuesta #466 en: 11 de Octubre de 2008, 22:58:16 »
Hola tengo el siguiete problema:
quiero generar un cambio de estado en un pin cada 244µs por lo que configuré el TMR2 con el prescale en 1:1 y el postcale en 1:5. Tengo un PIC16F877A con un cristal de 20Mhz por lo que el calculo me dio

Periodo = (1/20Mhz)x4x244x1x5 =244µs

pero al implementarlo o simularlo en el Pic Simulator IDE la interrupción ocurre solo una vez

¿alguna idea?

Saludos cordiales y agradecimientos a dogflu66 por contestar todas mis dudas...

Código: [Seleccionar]
Define CONF_WORD = 0x3f72

AllDigital
TRISA = 0x00 'PORTA Outputs
INTCON.GIE = 1 'Int General
INTCON.PEIE = 1 'Int Perifericos
PIE1.TMR2IE = 1 'Int TMR2
T2CON.T2CKPS0 = 0 'TMR2 Prescale
T2CON.T2CKPS1 = 0 'TMR2 Prescale
T2CON.TOUTPS0 = 0 'TMR2 Postcale
T2CON.TOUTPS1 = 0 'TMR2 Postcale
T2CON.TOUTPS2 = 1 'TMR2 Postcale
T2CON.TOUTPS3 = 0 'TMR2 Postcale
PR2 = 244 'Overload TMR2
T2CON.TMR2ON = 1 'TMR2 ON
End                                               

On Interrupt

PORTA.0 = Not PORTA.0

PIE1.TMR2IF = 0

Resume 
 

Desconectado dogflu66

  • Moderador Local
  • DsPIC30
  • *****
  • Mensajes: 3549
Re: PIC BASIC del PIC Simulator IDE
« Respuesta #467 en: 12 de Octubre de 2008, 12:39:16 »
Usando el ADC del gatillo como word se me reduce el tiempo de ejecucion, durante un proceso de 13 ciclos (pongo un bucle dentro de la rutina loop: para realizar trece ciclos), se reduce en 600 us.

¿Es que funciona mejor usando los 10 bits ?

Por desgracia no tengo el suficiente tiempo como para analizar de forma completa todos los programas de una forma minuciosa. Pero si te puedo decir lo siguiente:

Cuanto mayor es el numero de BIT de la conversión más pequeños son los pasos, por lo tanto se obtienen movimientos o ajustes mas finos. Que el programa funcione seria maravilloso, pero no puedes seguir trabajando en un programa mientras que las bases contengan errores. Mira lo siguiente:


ADCIN es una función que genera un valor de 10bit, ósea 2 Byte que en este lenguaje equivale a una variable tipo Word.

Por lo tanto no se puede asignar a ADCIN una variable de distinto tipo en este caso una variable de 8bit, ósea 1byte que en este lenguaje se define como Byte.

Si sigues asignado el valor que retorna ADCIN a una variable de 1byte, estas perdiendo los 2 BIT mas significativos de la conversión del ADC, por lo tanto ADCIN el valor máximo que puede suministrar es de 1023, ósea 10bit, solo tienes que hacer unos pequeños cálculos y veras que si suprimes los 2 primeros BIT de esos 10bit veras que estas perdiendo y truncando la mayor parte de los valores de la conversión ADC.

Una vez que tienes la conversión en una variable adecuada tienes que ver en la tabla del manual la resolución del pwm para ver cual es la que esta utilizando. Si la resolución es también de 10bit no hay problema los tipos de datos coinciden tan solo tendrás que modificar tu programa para que trabaje correctamente con los nuevos valores. Y si la resolución no es la adecuada según la tabla tendrás que cambiar de tipo el valor obtenido del adc hasta que coincida con la resolución del pmw.

Cambio de tipo a 8 BIT:

Por lo tanto necesitas hacer un calculo intermedio para pasar de 10bit, que es una mayor resolución, a 8 BIT que es menor. El calculo es muy simple y seria el siguiente:
Dim mcn_1 as word
Dim mcn as byte
Dim variable_aux as long ‘Variable auxiliar par a realizar cálculos largos
Adcin 0, mcn_1
Variable_aux = (255*mcn_1) /1023
Mcn = variable_aux
El problema de este calculo es que necesita variables de tipo Long ya que durante la operación salen valores intermedios superiores a 16bit.

Puedes simplificar la formula de la siguiente forma:

Dim mcn_1 as word
Dim mcn as byte
Adcin 0, mcn_1
Mcn_1 =(10*mcn_1)/1023
Mcn =  mcn_1
El problema en este caso esta en que nunca lograras el valor máximo de la escala que a 8 BIT es de 255, llegara a un valor máximo de 249.5 aproximadamente.

Y otra solución es la de perder los 2 BIT menos significativos de los 10bit de la conversión ADC:

Dim mcn_1 as word
Dim mcn as byte
Adcin 0, mcn_1
Mcn_1 = shiftright(mcn_1,2) ‘Desplaza los BIT de una variable 2 lugares a la derecha y estos se pierden al estar en el extremo.
Mcn= mcn_1

« Última modificación: 13 de Junio de 2016, 11:07:20 por dogflu66 »
Saludos desde Granada, España.

Desconectado 21CURIOSOS

  • PIC12
  • **
  • Mensajes: 56
Re: PIC BASIC del PIC Simulator IDE
« Respuesta #468 en: 12 de Octubre de 2008, 15:20:56 »
Gracias por tu tiempo y comentarios. Como ya te he dico soy novato en el tema y cualquier aportacion es de agradecer.

Decirte que tal como esta el programa el mando me funciona "creo que bastante bien", no obstante queria reducir el tiempo de ejecucion para que fuera mas fiable.

Por tanto tomo nota del ejemplo que me has enviado y de los comentarios que me has pasado

Gracias

Desconectado dogflu66

  • Moderador Local
  • DsPIC30
  • *****
  • Mensajes: 3549
Re: PIC BASIC del PIC Simulator IDE
« Respuesta #469 en: 12 de Octubre de 2008, 15:40:37 »
ADCIN  es una función muy lenta, puedes acelerar notablemente la lectura de ADC utilizando la rutina que te deje anteriormente.
La deje para trabajar a 8bit directamente, solo tienes que cambar 1bit para que trabaje a 10bit si lo prefieres. Y realmente conseguirás acelerar mucho.

Aqui tienes lo necesario para hacerlos:
http://www.todopic.com.ar/foros/index.php?topic=14917.msg126721#msg126721
« Última modificación: 12 de Octubre de 2008, 15:43:51 por dogflu66 »
Saludos desde Granada, España.

Desconectado dogflu66

  • Moderador Local
  • DsPIC30
  • *****
  • Mensajes: 3549
Re: PIC BASIC del PIC Simulator IDE
« Respuesta #470 en: 12 de Octubre de 2008, 21:03:01 »
Hola tengo el siguiete problema:
quiero generar un cambio de estado en un pin cada 244µs por lo que configuré el TMR2 con el prescale en 1:1 y el postcale en 1:5. Tengo un PIC16F877A con un cristal de 20Mhz por lo que el calculo me dio

Periodo = (1/20Mhz)x4x244x1x5 =244µs

pero al implementarlo o simularlo en el Pic Simulator IDE la interrupción ocurre solo una vez

¿alguna idea?

Saludos cordiales y agradecimientos a dogflu66 por contestar todas mis dudas...

Código: [Seleccionar]
Define CONF_WORD = 0x3f72

AllDigital
TRISA = 0x00 'PORTA Outputs
INTCON.GIE = 1 'Int General
INTCON.PEIE = 1 'Int Perifericos
PIE1.TMR2IE = 1 'Int TMR2
T2CON.T2CKPS0 = 0 'TMR2 Prescale
T2CON.T2CKPS1 = 0 'TMR2 Prescale
T2CON.TOUTPS0 = 0 'TMR2 Postcale
T2CON.TOUTPS1 = 0 'TMR2 Postcale
T2CON.TOUTPS2 = 1 'TMR2 Postcale
T2CON.TOUTPS3 = 0 'TMR2 Postcale
PR2 = 244 'Overload TMR2
T2CON.TMR2ON = 1 'TMR2 ON
End                                               

On Interrupt

PORTA.0 = Not PORTA.0

PIE1.TMR2IF = 0

Resume 
 


Cambia "PIE1.TMR2IF = 0" por "PIR1.TMR2IF = 0", y nos cuentas.

PD. Recuerda añadir el MAIN al programa.
Saludos desde Granada, España.

Desconectado dogflu66

  • Moderador Local
  • DsPIC30
  • *****
  • Mensajes: 3549
Re: PIC BASIC del PIC Simulator IDE
« Respuesta #471 en: 12 de Octubre de 2008, 21:05:56 »
Programa basico de configuracion del TMR2 probado en la EBasic:

Cuando se iguala el contador interno del TIMER2 con el valor del registro almacenado en PR2 se produce la interrupción.
TMR2 = PR2 => Interrupción TIMER2. Recordar que TIMER2 no tiene interrupción típica por desbordamiento de su contador.
Como podemos deducir de lo expuesto, la que tiene es por comparación.

T2CON.TMR2ON podríamos decir que hace la función de interruptor sobre el modulo TIMER2, de esta forma si lo apagamos
"T2CON.TMR2ON = 0", cuando nuestro programa no lo está utilizando, disminuimos el consumo del micro. Este BIT no afecta a la
configuración del TIMER2, por lo que no hay que reconfigurar el timer si no es necesario.

El contador del TMR2 es de 8bit y tiene un prescaler y poscaler, ambos dividen por un máximo de 16 pero con distinto numero de bit para su configuración.
La formula para calcular el tiempo en que el módulo genera la interrupción es la siguiente, valor a cargar en el registro PR2:

   PR2 = 256 - (((Tiempo Deseado en uSeg. / (4/8Mhz)) / (Prescaler * Poscaler)) -1)
   Se entiende que 8Mhz es el valor del reloj utilizado.
   Si ((Tiempo Deseado en uSeg. / (4/8Mhz)) / (Prescaler * Poscaler)) -1 es mayor al valor superior del registro del timer + 1, hay que volver a realizar la operación subiendo el valor de  (Prescaler * Poscaler).

Observación: Si se utiliza el modulo CCP trabajando en modo "PWM" hay que usar otro TMR, porque el modulo CCP (PWM) necesita del TMR2 para poder funcionar,
y cuando trabaja el modulo CCP en modo "captura" o en modo "comparador" utiliza el TMR1.

Código: [Seleccionar]
'**********************************************************************************
Define CONFIG = 0x2f50  'Configuración bits (Fuses)
Define CONFIG2 = 0x3ffc  'Configuración bits (Fuses)
Define CLOCK_FREQUENCY = 8  'Clock en Mhz
'Define SIMULATION_WAITMS_VALUE = 1  'Activar para simulación, acelera los comandos WaitMs
'Definicion de puertos-----------------
ANSEL = 0x00  'Los pin I/O digitales (no analogicos)
OSCCON = 0x7e  'Set intrc To 8mhz, se usara reloj interno a 8Mhz
CMCON = 0x07  'Comparador a off
TRISA = 0x00  'Puerto A como salidas
TRISB = 0x00  'Puerto B como salidas
PORTA.7 = 1  'Led amarillo a off
PORTB.0 = 1  'Led verde a off
'Config TMR2
'No prescaler :1
T2CON.T2CKPS0 = 0  'TMR2 Prescaler
T2CON.T2CKPS1 = 0  'TMR2 Prescaler
'Postscaler :16
T2CON.TOUTPS0 = 1  'TMR2 Postcaler
T2CON.TOUTPS1 = 1  'TMR2 Postcaler
T2CON.TOUTPS2 = 1  'TMR2 Postcaler
T2CON.TOUTPS3 = 1  'TMR2 Postcaler
PIE1.TMR2IE = 1  'Int TMR2
INTCON.PEIE = 1  'Int Perifericos
'PR2 = ((1000uSeg. / (4/8Mhz)) / (1 x 16) -1 = 124
PR2 = 124  'Overload TMR2, 1mSeg.
T2CON.TMR2ON = 1  'TMR2 ON
Enable  'INTCON.GIE = 1  'Interrupción General
'-----------------------------------------------
'Bucle rutina principal
main:
'Cambia de estado el led cada 500mSeg.
Toggle RA7
WaitMs 500
Goto main
End                                               
'------------------------------------------------
'Subrutina de control Interrupciones
On Interrupt
Save System
'Cambia de estado el led cada 500mSeg.
Dim _contador As Word
_contador = _contador + 1
If _contador >= 500 Then
Toggle RB0
_contador = 0
Endif
PIR1.TMR2IF = 0
Resume                   

Se puede observar que el parpadeo de ambos leds al principio esta sincronizado, pero pronto dejan de estarlo. El motivo de esto es porque
la rutina de interrupciones le roba tiempo a la rutina principal, y todo el código que está en ella se ralentiza algunos centenares de uSeg., justamente
el mismo tiempo que tarda en ejecutarse el código que hay dentro de la rutina de interrupción y algunos uSeg. más de gestión y control para llegar
a la rutina de interrupción y volver.
« Última modificación: 12 de Febrero de 2023, 18:57:20 por dogflu66 »
Saludos desde Granada, España.

Desconectado huesonardo

  • PIC10
  • *
  • Mensajes: 2
Re: PIC BASIC del PIC Simulator IDE
« Respuesta #472 en: 13 de Octubre de 2008, 00:21:06 »
Hola tengo el siguiete problema:
quiero generar un cambio de estado en un pin cada 244µs por lo que configuré el TMR2 con el prescale en 1:1 y el postcale en 1:5. Tengo un PIC16F877A con un cristal de 20Mhz por lo que el calculo me dio

Periodo = (1/20Mhz)x4x244x1x5 =244µs

pero al implementarlo o simularlo en el Pic Simulator IDE la interrupción ocurre solo una vez

¿alguna idea?

Saludos cordiales y agradecimientos a dogflu66 por contestar todas mis dudas...

Código: [Seleccionar]
Define CONF_WORD = 0x3f72

AllDigital
TRISA = 0x00 'PORTA Outputs
INTCON.GIE = 1 'Int General
INTCON.PEIE = 1 'Int Perifericos
PIE1.TMR2IE = 1 'Int TMR2
T2CON.T2CKPS0 = 0 'TMR2 Prescale
T2CON.T2CKPS1 = 0 'TMR2 Prescale
T2CON.TOUTPS0 = 0 'TMR2 Postcale
T2CON.TOUTPS1 = 0 'TMR2 Postcale
T2CON.TOUTPS2 = 1 'TMR2 Postcale
T2CON.TOUTPS3 = 0 'TMR2 Postcale
PR2 = 244 'Overload TMR2
T2CON.TMR2ON = 1 'TMR2 ON
End                                               

On Interrupt

PORTA.0 = Not PORTA.0

PIE1.TMR2IF = 0

Resume 
 


Cambia "PIE1.TMR2IF = 0" por "PIR1.TMR2IF = 0", y nos cuentas.

PD. Recuerda añadir el MAIN al programa.

cambié el "PIE1.TMR2IF = 0" por "PIR1.TMR2IF = 0" y todo funcionó un millón de gracias.... =)  :-/


Desconectado dogflu66

  • Moderador Local
  • DsPIC30
  • *****
  • Mensajes: 3549
Re: PIC BASIC del PIC Simulator IDE
« Respuesta #473 en: 13 de Octubre de 2008, 10:01:54 »
Me alegro mucho que funcionara...  :D
Saludos desde Granada, España.

Desconectado dogflu66

  • Moderador Local
  • DsPIC30
  • *****
  • Mensajes: 3549
Re: PIC BASIC del PIC Simulator IDE
« Respuesta #474 en: 13 de Octubre de 2008, 10:10:14 »
Gracias por tu tiempo y comentarios. Como ya te he dico soy novato en el tema y cualquier aportacion es de agradecer.

Decirte que tal como esta el programa el mando me funciona "creo que bastante bien", no obstante queria reducir el tiempo de ejecucion para que fuera mas fiable.

Por tanto tomo nota del ejemplo que me has enviado y de los comentarios que me has pasado

Gracias

La configuracin del ADCIN que utilizas tarda aprox. 51uSeg. en darte la lectura.

Esta que te dejo tarda entre 30 a 31 uSeg. aprox. en hacer la lectura, dependiendo de si se elige obtener el formato de la lectura en 8 o 10bit (observad que digo obtener el formato de la lectura en 8 0 10bits, porque el modulo ADC internamente siempre trabaja a 10bits, lo único que se puede cambiar es el formato de salida de los datos.).

Código: [Seleccionar]
'********************************** Para Simular *********************************************
'NOMBRE: 16F88_ADC 8 y 10 Bit
'VERSION: 1.0
'MICRO: PIC16F88
'Fecha/Autor: 10/08 By COS, PSI v7.41
'Descripción: usando el modulo adc directamente.
'************************************************************************************************
Define CONFIG = 0x2f50  'Configuración bits (Fuses)
Define CONFIG2 = 0x3ffc  'Configuración bits (Fuses)
Define CLOCK_FREQUENCY = 8  'Clock en Mhz
Define SIMULATION_WAITMS_VALUE = 1  'Activar para simulación, acelera los comandos WaitMs
'Asignacion de I/O y valores de inicio de las salidas --------------------------------------------
ANSEL = %00010000  'Los pin I/O digitales y RA4 analogico
CMCON = 0x07  'Comparador a off
OSCCON = 0x7e  'Set intrc To 8mhz, se usara reloj interno a 8Mhz
ADCON0 = %01100001  'Fosc/16 a 8Mhz (ADCON1.ADCS2=1) =2uSeg (minimo 1.6uSeg), channel RA4
ADCON1 = %11000000  'Volt. ref.(avdd/avss), selec. de escala division clock/16 ADCON1.ADCS2=1, adc a On
'ADCON1.ADFM = 0  'Activa lectura 8bit del ADC

TRISA = 0x00  'Puerto A como salidas
TRISB = 0x00  'Puerto B como salidas
TRISA.4 = 1  'Como entrada (RA4, adc)
'Declaracion de variables --------------------------------------------------------------------------------
Dim adc_4 As Word
adc_4 = 0
'Bucle principal ------------------------------------------------------------------------------------------
WaitMs 500  'Pausa 500mSeg.
main:
ADCON0.GO = 1  'Activa una conversión ADC
While ADCON0.GO = 1  'Espera hasta terminar la conversión ADC
Wend
'Pasa la lectura con formato de 10Bits a una variable tipo Word
adc_4.HB = ADRESH
adc_4.LB = ADRESL
'adc_4.LB = ADRESH  'ADC a 8 bit, se puede utilizar una variable tipo Byte
Goto main
End

Creo que haces tres lecturas durante el programa por lo que pierdes 153 uSeg.:
Este tiempo se puede reducir a tan solo unos microsegundos si se utilizan las interrupciones del ADC, mientras que se está realizando una lectura puedes estar actualizando otros registros o cálculos que sean necesarios, hasta que el modulo ADC avise de que tiene la nueva lectura.
« Última modificación: 20 de Junio de 2016, 10:04:20 por dogflu66 »
Saludos desde Granada, España.

Desconectado 21CURIOSOS

  • PIC12
  • **
  • Mensajes: 56
Re: PIC BASIC del PIC Simulator IDE
« Respuesta #475 en: 13 de Octubre de 2008, 10:40:45 »
De nuevo gracias, vas tu mas rapido en aportar explicaciones, que yo en poderlas aplicar.

No obstante tengo una duda. Aunque no se nota en el funcionamiento del cotxe, no se como hacer para que en la salida del pwm, la señal sea realmente 0, pues siempre queda algo de señal aunque ponga "pwmduty 1,0", a la salida del pic tengo un led y siempre queda algo encendido.

Adcin 1, vg  'lee el valor del gatillo

   Select Case vg
      Case < 16
         PWMduty 1, 0  'Freno

Otra pregunta que se me ocurre, las interrupciones (y disculpa mi ignorancia) ¿actuarian cuando se modifica elvalor del ADC ?, si es asi, ¿lo puedo utilizar en los tres ADC que utilizo?


Desconectado dogflu66

  • Moderador Local
  • DsPIC30
  • *****
  • Mensajes: 3549
Re: PIC BASIC del PIC Simulator IDE
« Respuesta #476 en: 13 de Octubre de 2008, 15:02:15 »
Así que yendo por partes tenemos:

Estuve analizando tu código en el simulador y no logre que diera un solo pulso. :shock:

Así que estuve probando PWM 1, 0 con tu configuración en la EBasic y a mí si me da en el pin RB3 todo el tiempo cero voltios. Sin embargo en el osciloscopio del simulador, sí configuramos una resolución muy elevada las líneas salen como puntos.

También vi que para valores de vg>=128 la salida de RB3 siempre queda a estado alto. Por lo tanto la resolución en tu caso quedo a 7Bit.

Y el modulo ADC no permite detectar cuando su entrada cambio de valor. En todo caso puedes programar una lectura del ADC cada cierto tiempo creando una base de tiempos.

Otra cosa muy importante que puede verificar gracias a tu programa, es que la función ADCIN cuando se asigna a una variable tipo BYTE, de forma automática entrega las lecturas a 8Bit, por lo que no es necesario hacer cambios de tipo en tu programa. Esto ultimo no esta en el manual. :shock:
Saludos desde Granada, España.

Desconectado dogflu66

  • Moderador Local
  • DsPIC30
  • *****
  • Mensajes: 3549
Re: PIC BASIC del PIC Simulator IDE
« Respuesta #477 en: 13 de Octubre de 2008, 16:55:08 »
Bueno si, puedes adaptar la lectura del ADCIN para aprovechar todo el rango dinámico de trabajo del ADC.

128 es a 1023, PWM siempre a 1
y esto queda vg=(128 * V. adcin)/1023
Saludos desde Granada, España.

Desconectado 21CURIOSOS

  • PIC12
  • **
  • Mensajes: 56
Re: PIC BASIC del PIC Simulator IDE
« Respuesta #478 en: 15 de Octubre de 2008, 04:26:42 »
Paso de nuevo el codigo que he probado, he modificado vg a word y en la lecturadel adc1 he puesto el siguiente codigo

CMCON = 0x07
ADCON0 = %01001001 '
ADCON1 = %11000000


Pero a la que hago la lectura  adcon.go=1 se me queda el programa colgado en el while pero despues de 8 lecturas

ADCON0.GO = 1
While ADCON0.GO = 1  'Espera hasta terminar la conversion ADC
Wend

vg.HB = ADRESH  'ADC a 10bit
vg.LB = ADRESL  'ADC a 10bit


Y despues de esto se me ocurren varias preguntas

¿se puede definir los bits 5-3  del ADCON0 para efectuar la lectura de tres entradas a la vez. ?

Si es asi, ¿ como se pasan los valores a diferentes  variables ?





Código: [Seleccionar]
'********************************** *********************
'NOMBRE: 16F88_MandoJEVO_01
'MICRO: PIC16f88
'Version: 1.0
''*****************************************************************************************************

Define CONF_WORD = 0x2f50
Define CONF_WORD_2 = 0x3ffc
Define CLOCK_FREQUENCY = 8
Define ADC_SAMPLEUS = 10
Define ADC_CLOCK = 5

CMCON = 0x07
ADCON0 = %01001001
ADCON1 = %11000000



Dim duty(16) As Byte  'Duty Cicle
Dim curva(15) As Byte  'Curva grabada
Dim vg As Word  'Valor gatillo
Dim ca As Byte  'Curva actual
Dim cn As Byte  'Curva nueva
Dim mca As Byte  'Modificacion curva actual P5
Dim mcn As Byte  'Modificacion curva nueva  P5
Dim asa As Byte  'Antispin Actual P4
Dim asn As Byte  'Antispin nuevo P4
Dim ai As Byte  'Contador inicio
Dim af As Byte  'Contador fin
Dim a As Byte  'contador
Dim b As Byte
Dim va(4) As Byte
Dim mc(3) As Byte
Dim i As Byte


ANSEL = %00100011
TRISB = %11110111
TRISA = %11111111

'Ver curva actual
Gosub vercurva
Gosub leermemoria
Gosub modificarcurva
Gosub modificararranque


PWMon 1, 12
PWMduty 1, 0

'****************************************************************************
'Rutina principal
loop:
For i = 1 To 13
Gosub vercurva  'Comprueba que no se haya cambiado la curva
If cn <> ca Then Gosub leermemoria
'* Leer gatillo
Gosub salidapwm

Adcin 0, mcn  'lee el valor de p5

If mcn <> mca Then Gosub modificarcurva

'* Leer gatillo
Gosub salidapwm

Adcin 5, asn  'lee el valor de p4

If asn <> asa Then Gosub modificararranque

'* Leer gatillo
Gosub salidapwm
Next i

Goto loop
End                                               


'********************************************************
'Deteccion de la curva a leer
vercurva:
'Ver curva nueva

cn = 0
If PORTA.2 = 1 Then cn = cn + 4
If PORTA.3 = 1 Then cn = cn + 2
If PORTA.4 = 1 Then cn = cn + 1
If PORTA.5 = 1 Then cn = cn + 8

ai = cn * 16  'Posicion inicial de memoria donde leer
af = ai + 14  'Posicion final de memoria donde leer

Return                                           
leermemoria:

'Leer valores Guardados segun la curva a leer
For a = ai To af
b = a - ai
Read a, duty(b)
curva(b) = duty(b)
Next a

'Genera los valores para las modificaciones de curvas

va(0) = (curva(10) - curva(4)) / 5  'Calculo maxima modificacion
va(1) = va(0) * 2  '(va(0) * 10) / 5 es el valor de correccion del 100 % multiplicado por 10
va(2) = va(0)  '(va(0) * 10) / (2 * 5)  es el valor de correccion del 50 % multiplicado por 10
va(3) = (va(0) * 10) / 15  '(va(0) * 10) / (3 * 5) es el valor de correccion del 30 % multiplicado por 10
ca = cn


Return                                           

'********************************************************************************************
'Rutina deteccion posicion del gatillo y entrega de potencia
salidapwm:
For a = 1 To 8

'Adcin 1, vg  'lee el valor del gatillo

ADCON0.GO = 1
While ADCON0.GO = 1  'Espera hasta terminar la conversion ADC
Wend

vg.HB = ADRESH  'ADC a 10bit
vg.LB = ADRESL  'ADC a 10bit


Select Case vg
Case < 64
PWMduty 1, 0  'Freno
Case < 128
PWMduty 1, duty(0)
Case < 192
PWMduty 1, duty(1)
Case < 256
PWMduty 1, duty(2)
Case < 320
PWMduty 1, duty(3)
Case < 384
PWMduty 1, duty(4)
Case < 448
PWMduty 1, duty(5)
Case < 512
PWMduty 1, duty(6)
Case < 576
PWMduty 1, duty(7)
Case < 640
PWMduty 1, duty(8)
Case < 704
PWMduty 1, duty(9)
Case < 768
PWMduty 1, duty(10)
Case < 832
PWMduty 1, duty(11)
Case < 896
PWMduty 1, duty(12)
Case < 960
PWMduty 1, duty(13)
Case <= 1023
PWMduty 1, duty(14)
EndSelect

Next a

Return                                           

'*************************************************************
'Ajuste fino de la curva grabada
'Rutina para modificar el centro de la curva
modificarcurva:

Select Case mcn
Case < 22  'P -5
mc(0) = ((va(3) * 5) / 10)
mc(1) = ((va(1) * 5) / 10)

duty(5) = curva(5) - mc(0)
duty(6) = curva(6) - mc(1)
duty(7) = curva(7) - mc(1)
duty(8) = curva(8) - mc(1)
duty(9) = curva(9) - mc(0)

mca = mcn
Return

Case < 44  'P -4
mc(0) = ((va(3) * 4) / 10)
mc(1) = ((va(1) * 4) / 10)

duty(5) = curva(5) - mc(0)
duty(6) = curva(6) - mc(1)
duty(7) = curva(7) - mc(1)
duty(8) = curva(8) - mc(1)
duty(9) = curva(9) - mc(0)

mca = mcn
Return
Case < 66  'P -3
mc(0) = ((va(3) * 3) / 10)
mc(1) = ((va(1) * 3) / 10)

duty(5) = curva(5) - mc(0)
duty(6) = curva(6) - mc(1)
duty(7) = curva(7) - mc(1)
duty(8) = curva(8) - mc(1)
duty(9) = curva(9) - mc(0)

mca = mcn
Return

Case < 88  'P -2
mc(0) = ((va(3) * 2) / 10)
mc(1) = ((va(1) * 2) / 10)

duty(5) = curva(5) - mc(0)
duty(6) = curva(6) - mc(1)
duty(7) = curva(7) - mc(1)
duty(8) = curva(8) - mc(1)
duty(9) = curva(9) - mc(0)

mca = mcn
Return

Case < 110  'P -1
mc(0) = va(3) / 10
mc(1) = va(1) / 10

duty(5) = curva(5) - mc(0)
duty(6) = curva(6) - mc(1)
duty(7) = curva(7) - mc(1)
duty(8) = curva(8) - mc(1)
duty(9) = curva(9) - mc(0)

mca = mcn
Return
Case < 145  'P 0
duty(5) = curva(5)
duty(6) = curva(6)
duty(7) = curva(7)
duty(8) = curva(8)
duty(9) = curva(9)

mca = mcn
Return

Case < 165  'P +1

mc(0) = va(3) / 10
mc(1) = va(2) / 10
mc(2) = va(1) / 10

duty(5) = curva(5) + mc(0)
duty(6) = curva(6) + mc(1)
duty(7) = curva(7) + mc(2)
duty(8) = curva(8) + mc(1)
duty(9) = curva(9) + mc(0)

mca = mcn
Return

Case < 185  'P +2

mc(0) = ((va(3) * 2) / 10)
mc(1) = ((va(2) * 2) / 10)
mc(2) = ((va(1) * 2) / 10)

duty(5) = curva(5) + mc(0)
duty(6) = curva(6) + mc(1)
duty(7) = curva(7) + mc(2)
duty(8) = curva(8) + mc(1)
duty(9) = curva(9) + mc(0)

mca = mcn
Return

Case < 205  'P +3
mc(0) = ((va(3) * 3) / 10)
mc(1) = ((va(2) * 3) / 10)
mc(2) = ((va(1) * 3) / 10)

duty(5) = curva(5) + mc(0)
duty(6) = curva(6) + mc(1)
duty(7) = curva(7) + mc(2)
duty(8) = curva(8) + mc(1)
duty(9) = curva(9) + mc(0)

mca = mcn
Return

Case < 230  'P +4
mc(0) = ((va(3) * 4) / 10)
mc(1) = ((va(2) * 4) / 10)
mc(2) = ((va(1) * 4) / 10)

duty(5) = curva(5) + mc(0)
duty(6) = curva(6) + mc(1)
duty(7) = curva(7) + mc(2)
duty(8) = curva(8) + mc(1)
duty(9) = curva(9) + mc(0)

mca = mcn
Return

Case <= 255  'P +5
mc(0) = ((va(3) * 5) / 10)
mc(1) = ((va(2) * 5) / 10)
mc(2) = ((va(1) * 5) / 10)

duty(5) = curva(5) + mc(0)
duty(6) = curva(6) + mc(1)
duty(7) = curva(7) + mc(2)
duty(8) = curva(8) + mc(1)
duty(9) = curva(9) + mc(0)

mca = mcn
Return

EndSelect

Return                                           

'*****************************************************************
'Ajuste del control de arrancada
modificararranque:
Select Case asn
Case < 25  'P 1
duty(0) = curva(0)
duty(1) = curva(1)
duty(2) = curva(2)
duty(3) = curva(3)
duty(4) = curva(4)
asa = asn
Return

Case < 50  'P 2
duty(0) = curva(0) + (((curva(1) - curva(0)) * 50) / 100)
duty(1) = curva(1)
duty(2) = curva(2)
duty(3) = curva(3)
duty(4) = curva(4)
asa = asn
Return

Case < 75  'P 3
duty(0) = curva(1)
duty(1) = curva(1) + (((curva(2) - curva(1)) * 40) / 100)
duty(2) = curva(2)
duty(3) = curva(3)
duty(4) = curva(4)
asa = asn
Return

Case < 100  'P 4
duty(0) = curva(1) + (((curva(2) - curva(1)) * 40) / 100)
duty(1) = curva(1) + (((curva(2) - curva(1)) * 80) / 100)
duty(2) = curva(2)
duty(3) = curva(3)
duty(4) = curva(4)
asa = asn
Return

Case < 125  'P 5
duty(0) = curva(1) + (((curva(2) - curva(1)) * 80) / 100)
duty(1) = curva(2)
duty(2) = curva(2) + (((curva(3) - curva(2)) * 40) / 100)
duty(3) = curva(3)
duty(4) = curva(4)
asa = asn
Return

Case < 150  'P 6
duty(0) = curva(2)
duty(1) = curva(2) + (((curva(3) - curva(2)) * 40) / 100)
duty(2) = curva(2) + (((curva(3) - curva(2)) * 80) / 100)
duty(3) = curva(3)
duty(4) = curva(4)
asa = asn
Return

Case < 175  'P 7
duty(0) = curva(2) + (((curva(3) - curva(2)) * 40) / 100)
duty(1) = curva(2) + (((curva(3) - curva(2)) * 80) / 100)
duty(2) = curva(3)
duty(3) = curva(3) + (((curva(4) - curva(3)) * 40) / 100)
duty(4) = curva(4)
asa = asn
Return

Case < 200  'p 8
duty(0) = curva(2) + (((curva(3) - curva(2)) * 80) / 100)
duty(1) = curva(3)
duty(2) = curva(3) + (((curva(4) - curva(3)) * 40) / 100)
duty(3) = curva(3) + (((curva(4) - curva(3)) * 80) / 100)
duty(4) = curva(4)
asa = asn
Return

Case < 225  'P 9
duty(0) = curva(3)
duty(1) = curva(3) + (((curva(4) - curva(3)) * 40) / 100)
duty(2) = curva(3) + (((curva(4) - curva(3)) * 80) / 100)
duty(3) = curva(4)
duty(4) = curva(4) + (((curva(5) - curva(4)) * 40) / 100)
asa = asn
Return

Case <= 255  'P 10
duty(0) = curva(3) + (((curva(4) - curva(3)) * 40) / 100)
duty(1) = curva(3) + (((curva(4) - curva(3)) * 80) / 100)
duty(2) = curva(4)
duty(3) = curva(4) + (((curva(5) - curva(4)) * 40) / 100)
duty(4) = curva(4) + (((curva(5) - curva(4)) * 80) / 100)
asa = asn
Return

EndSelect

Return                                         
« Última modificación: 15 de Octubre de 2008, 05:08:40 por 21CURIOSOS »

Desconectado dogflu66

  • Moderador Local
  • DsPIC30
  • *****
  • Mensajes: 3549
Re: PIC BASIC del PIC Simulator IDE
« Respuesta #479 en: 16 de Octubre de 2008, 04:58:08 »
Este PIC solo tiene un convertidor analógico digital, por lo que solo permite asignarlo a una sola entrada al mismo tiempo.
Esto implica que solo se puede hacer una única lectura de un pin a la vez.

Define ADC_SAMPLEUS = 10, Define ADC_CLOCK = 5 y ADCIN modifican con prioridad estos registros ADCON0 y ADCON1, por lo que desconozco la interacción que puedan provocar. De todas formas la rutina tendría que funcionar pero seguramente con menos eficacia ya que la configuración de los Define's suele tener prioridad. Recuerda que las funciones y definiciones cuando utilizan un modulo del PIC tienen que configurarlo cambiando sus registros (esto es lo único bueno que tienen según el prisma con el que se mire. No tenemos que configurar los registros a mano ni saber de funcionamiento interno), tan solo que en general las funciones predefinidas del lenguaje suelen tener menor rendimiento que nuestras propias rutinas.

Saludos desde Granada, España.