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

0 Usuarios y 2 Visitantes están viendo este tema.

Desconectado dogflu66

  • Moderador Local
  • DsPIC30
  • *****
  • Mensajes: 3549
Re: PIC BASIC del PIC Simulator IDE
« Respuesta #165 en: 18 de Abril de 2007, 10:22:15 »
A ver cuando lo vemos dar el primer paso...   :-)

Esta rutina que controla el servo, es nueva,  estoy experimentando con ella, ya que no es una rutina lineal realizada con contadores, 1 contador por servo, o tambien un unico contador pero muchas comparaciones. programando el timer para que desborde siempre con el mismo valor, el minimo posible que permita que se incrementen contador o contadores, y se comprueben todas las comparaciones, esto hace que la rutina tradicional por contadores no tenga muy buena resolución, sino utilizas una velocidad de reloj muy elevada.

Con esta nueva rutina cuando este terminada, espero conseguir mover 24 servos con una buena resolución y estabilidad, sin necesidad de usar velocidades muy elevadas de reloj, en fin, ya veremos..  :mrgreen:
« Última modificación: 18 de Abril de 2007, 10:28:03 por dogflu66 »
Saludos desde Granada, España.

Desconectado aitopes

  • Moderadores
  • DsPIC33
  • *****
  • Mensajes: 5100
    • uControl
Re: PIC BASIC del PIC Simulator IDE
« Respuesta #166 en: 18 de Abril de 2007, 12:23:23 »
Mmm.....entonces creo que me conviene esperarte...ja ja ja!

24 servos es un muy buen numero!

Saludetes.
Si cualquier habilidad que aprende un niño será obsoleta antes de que la use, entonces, ¿qué es lo que tiene que aprender? La respuesta es obvia:
La única habilidad competitiva a largo plazo es la habilidad para aprender
“. Seymour Papert

Desconectado dogflu66

  • Moderador Local
  • DsPIC30
  • *****
  • Mensajes: 3549
Re: PIC BASIC del PIC Simulator IDE
« Respuesta #167 en: 19 de Abril de 2007, 18:55:25 »
Completando el ejemplo anterior del control del servomotor.
- Ahora se muestra en pantalla el tiempo en mSeg. de la señal de control del servo.
- Fusionado en el programa anterior la rutina division con decimales

Código: [Seleccionar]
'***************** Placa Entrenadora (PIC EBadic) ***************************************
'NOMBRE:16F88_Pic_EBasic_LCD_Timer1_ADC_PWM_Servo_11
'Descripcion: Control de un servomotor (Futaba S3003) usando el ADC, Timer1, Interrupciones
'Micro: pic16f88 / 8mhz reloj interno
'Version: 1.0
'Fecha/Autor: 4/07, By COS
'Uso del LCD con bus de datos a 4Bit y sin pin de RW
'uso del timer1 para controlar el PWM, de periodo 20mSeg.
'lectura de entrada analogica y conversion a tiempo
'conversion de tiempo a valores a cargar en el timer1
'Version 1.1
'se fusiona la rutina de divicion con decimales
'para mostrar el tiempo del ducty cycle en pantalla, minimo 0.43mSeg. y maximo 2.26mSeg.
'modificacion del formato de salida de la informacion por el lcd
'************************************************************************************************
'-------------------------------------Puertos del LCD---------------------------------------------
Define LCD_BITS = 4  'indicamos que el bus de datos del lcd sera de 4bit
Define LCD_DREG = PORTA  'el bus de datos sera el puerto A
Define LCD_DBIT = 0  'el bus de datos seran los 4 bit menos significativos del puerto A
Define LCD_RSREG = PORTB  'el bit de control RS sera del puerto B
Define LCD_RSBIT = 7  'se usara el RB7 como RS
Define LCD_EREG = PORTB  'el bit de control E sera del puerto B
Define LCD_EBIT = 6  'se usara el RB6 como E
'Define LCD_RWREG = PORTA  'el bit de control RW sera del puerto A (si se suprime el compilador no protesta)
'Define LCD_RWBIT = 5  'se usara el RA5 como RW (si se suprime el compilador no protesta)
Define LCD_COMMANDUS = 2000  'Tiempo de espera despues de ejecutar un comando del lcd en uSeg.
Define LCD_DATAUS = 50  'Tiempo de espera despues de enviar un dato al LCD en uSeg.
Define LCD_INITMS = 5  '50  'Tiempo de espera despues de inicializar el Display, solo se ejecuta una vez en mSeg.
'****************************************************************************************************
Define SIMULATION_WAITMS_VALUE = 1  'Ignora los valores de Waitms
'--------------------------------------Reasignacion de nombres---------------------------------------
Symbol led_amarillo = PORTA.7  'led amarillo
Symbol led_verde = PORTB.0  'led verde
Symbol luz_lcd = PORTB.3  'retroiluminacion del lcd
'------------------------------------declaracion de variables---------------------------------------
'-------------------------------Variables del ADC y Rutina division------------------------------
Dim entero As Word  'parte entera
Dim decimal As Word  'los dos decimales
Dim division As Long  'almacenara el numero con los dos decimales
Dim factor_escala As Word  'situa la parte entera del numero
Dim reg_timer1 As Word  'valor maximo que puede contener el registro del TMR1
Dim tiempo_ms As Word  'tiempo a on de la señal de control del servo en mSeg.
Dim aux_adc_4 As Word  'auxiliar
Dim adc_4 As Word  'contiene el valor de la entrada ADC
'----------------------------------------variables calculo y control PWM-----------------------------
Dim pwm As Word  'variable de paso
Dim pwm_nop As Word  'variable de paso
Dim aux_pwm As Long  'calculo del tiempo a ON, de la señal de control
Dim aux_pwm_nop As Long  'calculo del tiempo a OFF, de la señal de cotrol
Dim timer_pwm As Word  'valor del tiempo a on, para ser interpretado
Dim timer_pwm_nop As Word  'valor del tiempo a off, para ser interpretado
Dim flag1_pwm As Byte  'variable que determina si ON o a OFF de la señal de control
Dim flag2_pwm As Byte  'controla la actualizacion de una nueva posicion del servo
'------------------------------------asignacion de valores a las variables--------------------------
pwm = 62535
pwm_nop = 28535
aux_pwm = 62535
flag1_pwm = 1
flag2_pwm = 0
entero = 0
decimal = 0
division = 0
adc_4 = 0
reg_timer1 = 65535  'maximo valor registro de 16 bit del TMR1
factor_escala = 100  'factor de escala para dos decimal
'------------------------------------Definicion de puertos------------------------------------------
Define ADC_SAMPLEUS = 0  'el minimo, configuracion del ADC
Define ADC_CLOCK = 5  '16Tad a 8Mhz = 2uSeg, minimo permitido por el micro 1.5uSeg, configuracion ADC
'_______________registros afectados por Define ADC_CLOCK y ADCIN________________
ANSEL = %00010000  'los pin I/O digitales y RA4 analogico
ADCON0 = %01100000  'Fosc/16 a 8Mhz (ADCON1.ADCS2=1) =2uSeg (minimo 1.uSeg), channel RA4
ADCON1 = %01000000  'voltage reference (AVdd/AVss) y seleccion de escala division clock/2 ADCON1.ADCS2=1
'_______________________________________________________________________________
CMCON = 0x07  'comparador a off
OSCCON = 0x7e  'set intrc To 8mhz, se usara reloj interno a 8Mhz
TRISA = 0x00  'Puerto A como salidas
TRISB = 0x00  'puerto B como salidas
TRISA.4 = 1  'como entrada (RA4, adc)
TRISA.6 = 1  'como entrada (RA6, tecla S1)
TRISA.5 = 1  'como entrada (RA5, tecla S2)
PORTB.3 = 1  'luz lcd a on (RB3)
PORTA.7 = 1  'led amarillo a off, negado
PORTB.0 = 1  'led verde a off, negado
'------------------------------------Inicializacion de Interrupciones-----------------------------
T1CON.TMR1CS = 0  'asigna el reloj interno al timer1, se incrementa cada ciclo de instruccion
T1CON.T1CKPS0 = 0  'factor del preescales del timer1, 0
T1CON.T1CKPS1 = 0  'factor del preescales del timer1, 0
TMR1H = 0xf8  'carga el registro del contador para que desborde cada 1mSeg, byte alto
TMR1L = 0x30  'carga el registro del contador para que desborde cada 1mSeg, byte bajo
T1CON.TMR1ON = 1  'habilitacion del TMR1, comienza a incrementarce
'PIE1.TMR1IE = 1  'activa las interrupciones del timer1
INTCON.PEIE = 1  'bit de habilitacion de interrupciones de perifericos
Enable  'INTCON.GIE habilita todas las interrupciones globales
'------------------------------------Inicio-------------------------------------------------------
Lcdinit  'inicializa el lcd sin cursor
WaitMs 1000  'espera 1Seg
Lcdout "LCD_Tmr1_ADC_PWM"  'escribe en el lcd
Lcdcmdout LcdLine2Home  'seleciona la linea dos como proxima para escritura
Lcdout "Servo S3003"  'escribe en el lcd
WaitMs 3000  'espera 3Seg
Lcdcmdout LcdClear  'borra el display
PIE1.TMR1IE = 1  'activa las interrupciones del timer1
'------------------------------------rutinas del Programa----------------------
main:  'comienza el programa principal
If flag2_pwm = 1 Then  'permite una nueva posicion del servo
Gosub lee_adc  'salto con retorno a la rutina de lectura del ADC
aux_pwm = ((adc_4 + 240) * 250) / (1023 + 370)  'tiempo a ON de la señal de control del servo
'240 y 370 fijan los mavolores minimo y valores maximos del ducty cycle
aux_pwm_nop = 2000 - aux_pwm  'calculo del tiempo de la señal de control a OFF
aux_pwm_nop = 65535 - ((aux_pwm_nop * 100) / 5)  'valor a cargar en el timer1, OFF
aux_pwm = 65535 - ((aux_pwm * 100) / 5)  'valor a cargar en el timer1, ON
pwm = aux_pwm  'se cambia de long a word, para acelerar la rutina de interrupciones
pwm_nop = aux_pwm_nop  'se cambia de long a word, apra acelerar la rutina de interrupciones
Gosub print_lcd  'salto con retorno a la rutina que muestra los dato por el display
flag2_pwm = 0  'bloquea la rutina hasta que se procese la nueva posicion
tiempo_ms = ((reg_timer1 - pwm) * 5) / 100  'calculo en mSeg.
division = dvsion_dcmles(tiempo_ms, factor_escala)  'llama a la funcion dvsion_dcmles, que retorna un long
Gosub formato_decimales  'extrae e imprime con formato decimal
Endif

Goto main  'impide que termine el programa principal
End  'es conveniente ponerlo siempre segun el manual
formato_decimales:  '____________________da formato a los decimales y los saca por el lcd
entero = division.HW  'sede el word alto a entero, parte entera
decimal = division.LW  'sede el byte alto del word bajo a decimal_1
Lcdout #entero, "."  'muestra los datos en el lcd
If decimal < 10 Then Lcdout "0"
Lcdout #decimal, "         "  'muestra los datos en el lcd
Return                                           
'--------------------------------------Subrrutina lectura ADC
lee_adc:  '_______________________lee la entrada analogica
Adcin 4, adc_4  'lee el valor de la entrada analogica y lo carga en adc_4
Return                                           
print_lcd:  '____________________muestra los datos por el display
Lcdcmdout LcdLine1Home  'cursor al principio
Lcdout "ADC--TMR1--mSeg."  'magnitudes
Lcdcmdout LcdLine2Home  'selecciona la linea dos del lcd y cursor a inicio
If adc_4 < 1000 Then Lcdout "0"  'para mantener la plantilla
If adc_4 < 100 Then Lcdout "0"  'para mantener la plantilla
If adc_4 < 10 Then Lcdout "0"  'para mantener la plantilla de salida
Lcdout #adc_4, " ", #pwm, " "  'muestra los datos en el lcd
Return                                           
'________Argumentos de entrada dos variables tipo word, dividendo y divisor, argumento de salida una variable tipo long
Function dvsion_dcmles(dvdo As Word, dvsor As Word) As Long  '________Rutina funcion division con decimales
Dim f_entera As Word  'variable local, contendra la parte entera
Dim f_resto As Word  'varable local, contendra el resto
Dim f_decimal As Word  'contendra la parte decimal
f_entera = dvdo / dvsor  'obtengo la division
f_resto = dvdo Mod dvsor  'obtengo el resto
f_decimal = (f_resto * 100) / dvsor  'calculo 1 decimal, para obtener 2 decimales multiplicar por 100
dvsion_dcmles.HW = f_entera  'almacena la parte entera en el word alto
dvsion_dcmles.LW = f_decimal  'almacena la parte decimal word bajo
'Recuerda que la parte decimal tiene que ser mostrada en el display con plantilla de 1 o mas digitos siempre
End Function                                     
'--------------------------------Interrupciones---------------------------------------------------
On Interrupt  'Comienzan las rutinas de las interrupciones, desactiva las interrupciones
Save System  'Guarda los valores del sistema para poder reemprender el curso normal del programa
'___________Rutina generadora del PWM, para la entrada de control del servomotor
If flag1_pwm = 1 Then  'controla el tiempo de la señal del servo a OFF
RB4 = 0  'salida del servo a OFF
TMR1H = timer_pwm_nop.HB  'recarga el contador del timer1 para que desborde, tiempo a off
TMR1L = timer_pwm_nop.LB  'recarga el contador del timer1 para que desborde, tiempo a off
flag1_pwm = 0  'permite la alternancia entre señal del servo a ON o a OFF
flag2_pwm = 1  'permiten que entren nuevos valoles del ADC, nueva posicion del servomotor
timer_pwm = pwm  'recarga la rutina con los nuevos valores del potenciometro
timer_pwm_nop = pwm_nop  'recara la rutina con los nuevos valores del potenciometro
Else
RB4 = 1  'salida de la señal de contol del servo a ON
TMR1H = timer_pwm.HB  'recarga el contador del timer1 para que desborde, tiempo a on
TMR1L = timer_pwm.LB  'recarga el contador del timer1 para que desborde, tiempo a on
flag1_pwm = 1  'permite la alternancia entre señal del servo a ON o a OFF
Endif
PIR1.TMR1IF = 0  'borra el flag de salto del tmr1
Resume  'activa las interrupciones y retorna al curso normal del programa antes del salto
End                                               
« Última modificación: 22 de Diciembre de 2007, 23:46:28 por dogflu66 »
Saludos desde Granada, España.

Desconectado dogflu66

  • Moderador Local
  • DsPIC30
  • *****
  • Mensajes: 3549
Re: PIC BASIC del PIC Simulator IDE
« Respuesta #168 en: 19 de Abril de 2007, 18:57:20 »
La simulacion:

Saludos desde Granada, España.

Desconectado Resistencio

  • PIC12
  • **
  • Mensajes: 82
Re: PIC BASIC del PIC Simulator IDE
« Respuesta #169 en: 20 de Abril de 2007, 01:36:42 »
MASTER !!! esto esta muy bueno COS !!! Vengo algo lento pero practicando...

Se podria ensayar sobre la obtencion de una senoide...quizas usando el recurso del PWM y algun pasabajos...???

Estuve viendo algo en el FORO, pero no me anime a preguntar, porque hay opiniones desencontradas, y no quise generar mas polemica...quizas cuando se enfrien un poco los animos pregunte algo por ahi...de hecho el post se interrumpe abruptamente y no se arriba a ninguna solucion...

Algunos piensan que se puede resolver con la utilizacion de un DAC (y eso es verdad) pero nos deja sin la practica perseguida, que es la de experimentar con los MICROS...

En fin, si se puede hacer alguan simulacion de senoide, diente y triangular, me pongo a ensayar algo !!!

SALUDOS y gracias por este "curro" (trabajo - laburo - aqui en Argentina)...Ahora me voy a mirar una vez mas el "golcito" que se hizo este "chaval", que le dicen la "pulga atomica"...lo tenes ??? ejem...creo que jugara para nosotros en el proximo mundial !!!  :-) :-) :-) :-/ :-/ :-/ :-) :-) :-)

______________________________
"Justo a mi, me toco ser Yo" QUINO


Desconectado dogflu66

  • Moderador Local
  • DsPIC30
  • *****
  • Mensajes: 3549
Re: PIC BASIC del PIC Simulator IDE
« Respuesta #170 en: 21 de Abril de 2007, 14:25:47 »
Pues en principio con los Amp. Operacionales se puede hace de todo, pero en este caso es algo que no me he planteado, es cuestion de investigar un poco a ver que sale.... ire viendo a ver que me encuentro... :mrgreen:
Saludos desde Granada, España.

Desconectado dogflu66

  • Moderador Local
  • DsPIC30
  • *****
  • Mensajes: 3549
Re: PIC BASIC del PIC Simulator IDE
« Respuesta #171 en: 25 de Abril de 2007, 18:30:26 »
Dejo un nuevo ejemplo, en esta ocasión para poder controlar la EBasic mediante el Hyperterminal.
es una forma de llevarse el menu puesto a cualquier sitio, y asi poder configurar la EBasic o cualquier
otro equipo desde cualquier ordenador que tenga algun programa terminal compatible.

Por desgracia el simulador no comprende todos los caracteres de control que uso, asi que el menu no saldra tan lucido.
pero en el Hyperterminal del windows va muy bien.


Saludos desde Granada, España.

Desconectado dogflu66

  • Moderador Local
  • DsPIC30
  • *****
  • Mensajes: 3549
Re: PIC BASIC del PIC Simulator IDE
« Respuesta #172 en: 25 de Abril de 2007, 18:32:35 »
El codigo:

Código: [Seleccionar]
'********************************** PIC Entrenadora BASIC ***************************************
'NOMBRE: 16F88_Pic_EBasic_LCD_RS232_Menu_10
'VERSION: 1.0
'MICRO: PIC16F88
'Fecha/Autor: 4/07 By COS
'DESCRIPCION: Control de los led de la EBasic por medio de un menu en el Hyperterminal
'programar el hyperterminal del Windows:
'Bits por segundo: 4800
'Bits de datos: 8
'Paridad: Ninguno
'Control de flujo: Ninguno
'LCD a 4 bit, sin bit de RW
'************************************************************************************************
'-------------------------------------PUERTOS DEFINIDOS POR EL SISTEMA----------------------------
'-------------------------------------Puertos del LCD---------------------------------------------
Define LCD_BITS = 4  'indicamos que el bus de datos del lcd sera de 4bit
Define LCD_DREG = PORTA  'el bus de datos sera el puerto A
Define LCD_DBIT = 0  'el bus de datos seran los 4 bit menos significativos del puerto A
Define LCD_RSREG = PORTB  'el bit de control RS sera del puerto B
Define LCD_RSBIT = 7  'se usara el RB7 como RS
Define LCD_EREG = PORTB  'el bit de control E sera del puerto B
Define LCD_EBIT = 6  'se usara el RB6 como E
'Define LCD_RWREG = PORTA 'el bit de control RW sera del puerto A (si se suprime el compilador no protesta)
'Define LCD_RWBIT = 5 'se usara el RA5 como RW (si se suprime el compilador no protesta)
Define LCD_COMMANDUS = 2000  'Tiempo de espera despues de ejecutar un comand del lcd en uSeg.
Define LCD_DATAUS = 50  'Tiempo de espera despues de enviar un dato al LCD en uSeg.
Define LCD_INITMS = 5  '50  'Tiempo de espera despues de inicializar el Display, solo se ejecuta una vez en mSeg.
'--------------------------------Reasignacion de nombres---------------------------------------
Symbol led_amarillo = PORTA.7  'led amarillo
Symbol led_verde = PORTB.0  'led verde
'--------------------------------Definicion de caracteres de control del Hyperterminal--------
Const ff = 0x0c  'FF, Avance de pagina
Const bell = 0x07  'BELL, Señal sonora
Const sp = 0x20  'SP, Espacio
Const bksp = 0x08  'BKSP, Retroceso
'--------------------------------------Declaracion DE VARIABLES-------------------------------------
'-------------------------------------Variables sub_rutinas del puerto serie---------------------
Dim assi As Byte  'Contiene el valor de lectura del puerto serie
Dim n_usart As Byte  'Numero de datos del USART y del bufer IMAGEN de control
Dim usart As Byte  'Variable indice que apunta al ultimo dato adquirido por la USART
Dim aux_usart As Byte  'Auxiliar de la variable indice usart del USART
Dim c_serial As Byte  'Como USART pero para la lectura de control del bufer IMAGEN
Dim bufer As Byte  'Indica si hay datos por leer en el bufer USART
Dim n_aux As Byte  'contador para borrar el bufer_soft
'************************************variables de los timer****************************************
Dim pause As Word  'contiene el valor para simular el comando Waitms
Dim timer_1ms As Word  'base de tiempos se incrementa cada 1mSeg, timer del PAUSE
'------------------------------------Variables tipo array puerto serie----------------------------------
Dim usart_imagen(91) As Byte  'Componen el bufer IMAGEN para control del bufer USART
Dim usart_bufer(91) As Byte  'Componen el bufer de la USART de bajo nivel
'-----------------------------------------------ASIGNACIONES----------------------------------------
'-------------------------------------Asignacion de valores del TIMER1----------------------------
pause = 0  'genera una pausa en MSeg
timer_1ms = 0  'en mSeg
'-------------------------------------Asigna valores a las variables de la rutina del puerto serie--
usart = 0
aux_usart = 0
c_serial = 0
bufer = 0
n_usart = 90
assi = 0
n_aux = 0
'**************************************DEFINICION DE PUERTOS*************************************
'----------------------ASIGNACION DE I/O y valores de inicio de las salidas---------------------
ANSEL = 0x00  'los pin I/O digitales
CMCON = 0x07  'comparador a off
OSCCON = 0x7e  'set intrc To 8mhz, se usara reloj interno a 8Mhz
TRISA = 0x00  'Puerto A como salidas
TRISB = 0x00  'puerto B como salidas
TRISA.4 = 1  'como entrada (RA4, adc)
TRISA.6 = 1  'como entrada (RA6, tecla S1)
TRISA.5 = 1  'como entrada (RA5, tecla S2)
'TRISB.5 = 0 'RB5(Tx, RS232)
TRISB.2 = 1  'RB2 (Rx, RS232)
PORTB.3 = 1  'luz lcd a on (RB3)
PORTA.7 = 1  'led amarillo a off
PORTB.0 = 1  'led verde a off
'------------------------------------INICIO DEL PUERTO SERIE, TIMER E INTERRUPCIONES------------------
Hseropen 4800  'Velocidad del puerto serie e inicializa los comandos de bajo nivel que controlan la USART
Gosub clear_bufer  'Borra el BUFFER IMAGEN y por lo tanto tambien al USART, OBLIGATORIO POR LO MENOS UNA VEZ
T1CON.TMR1CS = 0  'asigna el reloj interno al timer1, se incrementa cada ciclo de instruccion
T1CON.T1CKPS0 = 0  'factor del preescales del timer1, 0
T1CON.T1CKPS1 = 0  'factor del preescales del timer1, 0
TMR1H = 0xf8  'carga el registro del contador para que desborde cada 1mSeg, byte alto
TMR1L = 0x2f  'carga el registro del contador para que desborde cada 1mSeg, byte bajo
T1CON.TMR1ON = 1  'habilitacion del TMR1, comienza a incrementarce
'PIE1.TMR1IE = 1  'activa las interrupciones del timer1
'PIE1.RCIE = 1  'Activa la interrupcion de la USART en modo rx
INTCON.PEIE = 1  'bit de habilitacion de interrupciones de perifericos
Enable  'INTCON.GIE habilita todas las interrupciones globales
'--------------------------------------Inicio Programa--------------------------------------------------
Lcdinit  'inicializa el LCD sin cursor
PIE1.TMR1IE = 1  'activa las interrupciones del timer1
PIE1.RCIE = 1  'Activa la interrupcion de la USART en modo rx
pause = 0  '1000  'prepara una pausa de 1Seg
Gosub pause_ms  'espera el tiempo que indica pause
Lcdout "16F88_RS232_MENU"  'imprime en el LCD el literal
Lcdcmdout LcdLine2Home  'selecciona linea y cursor al principio
Lcdout "4800 Baud.--1.0"  'escribe la cadena de literales en el lcd
Hserout ff, CrLf, CrLf, "VER. 1.0 - TX/RX", CrLf, "TX -> MENU POR RS232", CrLf, "By COS", CrLf, CrLf  'envia presentacion al RS232
Gosub clear_bufer  'Borra el BUFFER IMAGEN y por lo tanto tambien al USART, OBLIGATORIO POR LO MENOS UNA VEZ
pause = 0  '3000  'prepara una pausa de 3Seg
Gosub pause_ms  'hace una pausa de tiempo indicado por pause
'Lcdcmdout LcdClear  'borra el display
'--------------------------------------Main Programa----------------------------------------------------
Gosub print_menu  'envia el menu principal al hyperterminal
main:
Gosub readserial  'lee un caracter del puerto serie, salto con retorno
If assi >= 0x30 And assi <= 0x31 Then  'filtro de caracteres, "0" y el "1"
Hserout bell  'señal sonora
Hserout assi  'envia al hyperterminal
pause = 0  '1000  'carga la base de tiempos
Gosub pause_ms  'espera el tiempo indicado por pause
If assi = "0" Then Gosub control_led_amarillo  'salta a la rutina de control del led amarillo
If assi = "1" Then Gosub control_led_verde  'salta a la rutina de control del led verde
Endif
Goto main
End                                               
'--------------------------------------FIN DEL MAIN-------------------------------------------
'--------------------------------------Rutinas Programa-----------------------------------------------
print_menu:
Hserout ff  'Paguina en blanco
Hserout "   Menu de Control de los Led de la Pic EBasic  ", CrLf  'implime la cadena literal y salta a una nueva linea
Hserout "------------------------------------------------", CrLf  'implime la cadena literal y salta a una nueva linea
Hserout "0 - Para menu Led amarillo", CrLf  'implime la cadena literal y salta a la siguiente linea
Hserout "1 - Para menu Led verde", CrLf  'implime la cadena literal y salta siguiente linea
Hserout "------------------------------------------------", CrLf  'implime la cadena literal y salta siguiente linea
Hserout "->"  'cursor
Hserout bell  'señal sonora
Return                                           
control_led_verde:
Hserout ff  'pagina en blanco
Hserout "    Menu control del Led Verde   ", CrLf  'implime la cadena literal y salta a una nueva linea
Hserout "---------------------------------", CrLf  'implime la cadena literal y salta a una nueva linea
Hserout "0 - Led verde a Off", CrLf  'implime la cadena literal y salta a una nueva linea
Hserout "1 - Led verde a On", CrLf  'implime la cadena literal y salta a una nueva linea
Hserout "2 - Para Salir", CrLf  'implime la cadena literal y salta a una nueva linea
Hserout "---------------------------------", CrLf  'implime la cadena literal y salta a una nueva linea
Hserout "->"  'cursor
assi = 0  'borra el ultimo caracter leido del bufer serie
While assi <> "2"  'controla el menu
Gosub readserial  'lee caracter del bufer serial (retorna en assi)
If assi >= 0x30 And assi <= 0x32 Then  'filtro de opciones o teclas
Hserout bell  'señal sonora
Hserout assi  'caracter leido del bufer serie
pause = 0  '1000  'prepara una pausa de 1Seg.
Gosub pause_ms  'pausa indicada por pause
Hserout bell  'señal sonora
Gosub retrocede_caracter  'salto a la rutina de borra caracter
If assi = "0" Then led_verde = 1  'led verde a off
If assi = "1" Then led_verde = 0  'led verde a on
If assi = "2" Then Gosub print_menu  'reimprime el menu principal
Endif
Wend
Return                                           
control_led_amarillo:
Hserout ff  'pantalla en blanco
Hserout "    Menu control del Led Amarillo   ", CrLf  'implime la cadena literal y salta a una nueva linea
Hserout "------------------------------------", CrLf  'implime la cadena literal y salta a una nueva linea
Hserout "0 - Led Amarillo a Off", CrLf  'implime la cadena literal y salta a una nueva linea
Hserout "1 - Led Amarillo a On", CrLf  'implime la cadena literal y salta a una nueva linea
Hserout "2 - Para Salir", CrLf  'implime la cadena literal y salta a una nueva linea
Hserout "------------------------------------", CrLf  'implime la cadena literal y salta a una nueva linea
Hserout "->"  'cursor
assi = 0  'borra el ultimo caracter leido del bufer serie
While assi <> "2"  'controla el menu
Gosub readserial  'lee caracter del bufer serial (retorna en assi)
If assi >= 0x30 And assi <= 0x32 Then  'filtro de opciones o teclas
Hserout bell  'señal sonora
Hserout assi  'caracter leido del bufer serie
pause = 0  '1000  'prepara una pausa de 1Seg.
Gosub pause_ms  'pausa indicada por pause
Hserout bell  'señal sonora
Gosub retrocede_caracter  'salto a la rutina de borra caracter
If assi = "0" Then led_amarillo = 1  'led amarillo a off
If assi = "1" Then led_amarillo = 0  'led amarillo a on
If assi = "2" Then Gosub print_menu  'reimprime el menu principal
Endif
Wend
Return                                           
retrocede_caracter:  'borra caracter
Hserout bksp, sp, bksp
Return                                           
pause_ms:  'rutina de espera, rutina tipo Waitms, pause establese el tiempo total en mSeg
timer_1ms = 0  'al borrar el contador se activa y comienza la cuenta de mSeg
While timer_1ms < pause  'tiempo en mSeg maximos a contar
Wend
Return                                           
'------------------------------ rutinas para el control del bufer del puerto serie-------------
readserial:
'RUTINA DE LECTURA DEL BUFFER DEL PUERTO SERIE (ASSI)
If bufer = 1 Then  'si bufer tiene datos
assi = usart_bufer(c_serial)  'se lee el valor del bufer y se asigna assi
usart_imagen(c_serial) = 0  'se marca como leida para que pueda ser llenada de nuevo
c_serial = c_serial + 1  'se incrementa el indice del bufer
If c_serial >= n_usart Then c_serial = 0  'se verifica si se llego al final del bufer
If usart_imagen(c_serial) = 0 Then bufer = 0  'si no quedan mas datos en el bufer se marca como vacio
Else
assi = 0
Endif
Return                                           
clear_bufer:  'inicializa el bufer imagen y borra error del puerto fisico en modo Rx
'_________________________Borra e inicializa el bufer imagan del puerto serie
c_serial = 0
While c_serial <= n_usart  'se ejecuta tantas veces como variables tiene el bufer
usart_imagen(c_serial) = 0  'borra el indicador de variable del bufer con datos
c_serial = c_serial + 1
Wend
c_serial = 0  'variables de control del bufer
usart = 0
bufer = 0
assi = 0
'_________________________Borra el error del puerto serie en Rx
RCSTA.OERR = 0
RCSTA.CREN = 0
RCSTA.CREN = 1
Return                                           
'--------------------------------------SIBRUTINAS ESPECIALES---------------------------------------------
On Interrupt  'desactiva las interrupciones
Save System  'Guarda los valores del sistema
'*****************************base de tiempos********************************************
If PIR1.TMR1IF = 1 Then  'comprueba que la interrupcion la proboco el timer1
If timer_1ms < pause Then timer_1ms = timer_1ms + 1  'contador para control del timer_1ms
TMR1H = 0xf8  'recarga el contador del timer1 para que desborde pasado 1mSeg, byte alto
TMR1L = 0x2f  'recarga el contador del timer1 para que desborde pasado 1mSeg, byte bajo
PIR1.TMR1IF = 0  'borra el bit de salto del timer1
Endif
'*****************************BUFFER PUERTO SERIE****************************************
If PIR1.RCIF = 1 Then  'comprueba que es esta la interrupcion activa del modulo USAR
If usart < n_usart Then  'comprueba que el bufer de entrada no esta lleno
If usart_imagen(usart) = 0 Then  'comprueba que la posicion esta vacia
aux_usart = usart  'retiene la posicion antigua del bufer
usart = usart + 1  'indica cual sera la posicion siguiente del bufer
usart_imagen(aux_usart) = 1  'indica que hay dato en el bufer de entrada
bufer = 1  'indica que el bufer tine datos
Hserget usart_bufer(aux_usart)  'carga el dato en el bufer
Else
Hserget usart_bufer(n_usart)  'descarga la usart para que no se bloquee porque el bufer de entrada esta lleno
Endif
Else
If usart_imagen(0) = 0 Then  'comprueba que esta vacia la primera posicion del bufer
usart_imagen(0) = 1  'marca que hay dato en esa posicion del bufer
bufer = 1  'marca que el bufer tiene datos
usart = 1  'establece la proxima posicion del bufer
Hserget usart_bufer(0)  'lee la usart y guarda el dato en el bufer
Else
Hserget usart_bufer(n_usart)  'descarga la usart porque el bufer esta lleno
Endif
Endif
PIR1.RCIF = 0  'borra el bit de salto del Rx
Endif
'_________________________Borra el error del puerto serie en Rx
If RCSTA.OERR = 1 Then
RCSTA.OERR = 0
RCSTA.CREN = 0
RCSTA.CREN = 1
Endif
Resume  'activa las interrupciones y retorna al curso normal del programa antes del salto
End                                               


PD. las rutinas de tiempo fueron suprimidas para el Simulador
Saludos desde Granada, España.

Desconectado dogflu66

  • Moderador Local
  • DsPIC30
  • *****
  • Mensajes: 3549
Re: PIC BASIC del PIC Simulator IDE
« Respuesta #173 en: 25 de Abril de 2007, 18:35:33 »
Para Ver la Simulacion:


Saludos desde Granada, España.

Desconectado dogflu66

  • Moderador Local
  • DsPIC30
  • *****
  • Mensajes: 3549
Re: PIC BASIC del PIC Simulator IDE
« Respuesta #174 en: 26 de Abril de 2007, 04:52:07 »
El programa genera un bufer de entrada de 90 caracteres, asi que la EBasic recordara todos los caractes que pulseis (fifo).
Por lo tanto no pulseis muchos rapidamente o tendreis que esperar que los interprete todos...  :mrgreen:
« Última modificación: 02 de Octubre de 2010, 07:08:54 por dogflu66 »
Saludos desde Granada, España.

Desconectado dogflu66

  • Moderador Local
  • DsPIC30
  • *****
  • Mensajes: 3549
Re: PIC BASIC del PIC Simulator IDE
« Respuesta #175 en: 27 de Abril de 2007, 18:48:48 »
Este es un ejemplo mas simple para controlar un servomotor:

Código: [Seleccionar]
'***************** Placa Entrenadora (PIC EBadic) ***************************************
'NOMBRE: 16F88_Pic_EBasic_Adcin_ServoOut_01
'Descripcion: Control de un servomotor (Futaba S3003) usando las declaraciones Adcin y ServoOut
'Micro: pic16f88 / 8mhz reloj interno
'Version: 1.0
'Fecha/Autor: 4/07, By COS, PSI v7.41
'periodo de la señal de control 20mSeg, duty cycle comprendido entre 0.5 y 2.3 mSeg.
'_________________________Ajuste de la declaracion ADCIN________________________
Define ADC_SAMPLEUS = 10  'el minimo, configuracion del ADC
Define ADC_CLOCK = 5  '16Tad a 8Mhz = 2uSeg, minimo permitido por el micro 1.5uSeg, configuracion ADC
'_______________________________________________________________________________
'_______________registros afectados por Define ADC_CLOCK y ADCIN________________
ANSEL = %00010000  'los pin I/O digitales y RA4 analogico
ADCON0 = %01100000  'Fosc/16 a 8Mhz (ADCON1.ADCS2=1) =2uSeg (minimo 1.uSeg), channel RA4
ADCON1 = %01000000  'voltage reference (AVdd/AVss) y seleccion de escala division clock/2 ADCON1.ADCS2=1
'_______________________________________________________________________________
'------------------------Definicion del funcionamiento de los modulos internos del micro--------------------
CMCON = 0x07  'comparador a off
OSCCON = 0x7e  'set intrc To 8mhz, se usara reloj interno a 8Mhz
TRISA = 0x00  'Puerto A como salidas
TRISB = 0x00  'puerto B como salidas
TRISA.4 = 1  'como entrada (RA4, adc)
TRISA.6 = 1  'como entrada (RA6, tecla S1)
TRISA.5 = 1  'como entrada (RA5, tecla S2)
PORTB.3 = 1  'luz lcd a on (RB3)
PORTA.7 = 1  'led amarillo a off, negado
PORTB.0 = 1  'led verde a off, negado
'Configura el puerto serie RS232 ---------------------
Hseropen 4800
'--------------------Asignacion de nombres a los pins----------------------------------------------------
Symbol led_amarillo = PORTA.7  'led amarillo
Symbol led_verde = PORTB.0  'led verde
Symbol luz_lcd = PORTB.3  'retroiluminacion del lcd
'-----------------------declaracion de variables----------------------------------------------------------
Dim servo_1 As Byte  'valor del ADC y tiempo del duty cycle
Dim tiemp_resta As Word  'tiempo en que la señal de control estara a OFF
'-----------------------Programa principal-------------------------------------
main:
PORTB.4 = 0  'salida de control del servo a estado bajo, pin RB4
Adcin 4, servo_1  'lectura del puerto analogico, pin RA4
Hserout #servo_1, CrLf  'Envia el valor del AN4 al puerto serie
If servo_1 < 50 Then servo_1 = 50  'acota el minimo para que el mecanismo del servo no sufra
If servo_1 > 230 Then servo_1 = 230  'acota el desplazamiento máximo para que el servo no sufra
ServoOut PORTB.4, servo_1  'declaracion para el control de servo motores, resolución de 10uSeg.
'se ajusta de forma automatica a la frecuencia de reloj de trabajo del micro.
tiemp_resta = 20000 - (servo_1 * 10)  'calculo de la señal de control a off en uSeg., periodo - duty = tiempo pendiente
'hasta completar el periodo seleccionado, en este caso 20mSeg.
WaitUs tiemp_resta  'pausa en uSeg. hasta completar el periodo de la señal de control
Goto main



Modulos a utilizar para la simulacion:
- Microcontroller View
- Oscilloscope (Interval 100000)
« Última modificación: 12 de Junio de 2016, 22:21:36 por dogflu66 »
Saludos desde Granada, España.

Desconectado dogflu66

  • Moderador Local
  • DsPIC30
  • *****
  • Mensajes: 3549
Re: PIC BASIC del PIC Simulator IDE
« Respuesta #176 en: 27 de Abril de 2007, 18:54:47 »
Este es un programa totalmente lineal, por lo que no tiene, ni se le puede poner como a los otros la simualcion de multitarea.
Con esto me refiero a que Adcin, ServoOut y Waitus, consumen todo el tiempo del micro mientras se estan ejecutando.
Y con la consiguiente perdida de potencia de proceso.
« Última modificación: 02 de Octubre de 2010, 07:03:52 por dogflu66 »
Saludos desde Granada, España.

Desconectado dogflu66

  • Moderador Local
  • DsPIC30
  • *****
  • Mensajes: 3549
Re: PIC BASIC del PIC Simulator IDE
« Respuesta #177 en: 27 de Abril de 2007, 19:00:02 »
   tiemp_resta = 20000 - (servo_1 * 10)  'calculo de la señal de control a off en uSeg., periodo - duty = tiempo pendiente
                         'hasta completar el periodo seleccionado, en este caso 20mSeg.

Al pasar a uSeg. en la linea anterior, nos evitamos las perdidas por redondeo de la operacion.
Saludos desde Granada, España.

Desconectado dogflu66

  • Moderador Local
  • DsPIC30
  • *****
  • Mensajes: 3549
Re: PIC BASIC del PIC Simulator IDE
« Respuesta #178 en: 29 de Abril de 2007, 06:52:44 »
Ejemplo para simular:

Código: [Seleccionar]
'PROGRAMA PARA PRACTICAR CON INTERRUPCIONES EXTERIORES DEL PIN RB0
'On Interrupt - Interrupts in BASIC
'Turn LED on.  Interrupt on PORTB.0 (INTE) turns LED off.
'Program waits .5 seconds and turns LED back on.
'-------------------------------------------------------------------
Define SIMULATION_WAITMS_VALUE = 1  'ignora los Waitms
'-------------------------------------------------------------------
Symbol led = PORTB.7  'reasigno nombre al portb.7
ANSEL = %00000000  'los pin I/O digitales
CMCON = 0x07  'comparador a off
OSCCON = 0x7e  'set intrc To 8mhz, se usara reloj interno a 8Mhz
TRISB.7 = 0  'declaro portb.7 como salida
TRISB.0 = 1  'declaro portb.0 como entrada
OPTION_REG = 0x7f  'Enable PORTB pullups
INTCON = 0x90  'Enable INTE interrupt
'-------------------------------------------------------------------
main:
High led  'Turn LED on
Goto main  'Do it forever
End                                               
'Interrupt handler
On Interrupt  'Define interrupt handler, disable interrupt
Low led  'If we get here, turn LED off
WaitMs 500  'Wait 0.5 Seconds
INTCON.1 = 0  'Clear interrupt flag
Resume  'Return to main program, enable interrupt

PD. Programa del amigo forero Eyedol, adaptado para el PSI
Saludos desde Granada, España.

Desconectado dogflu66

  • Moderador Local
  • DsPIC30
  • *****
  • Mensajes: 3549
Re: PIC BASIC del PIC Simulator IDE
« Respuesta #179 en: 29 de Abril de 2007, 06:54:33 »
Modulo para la simulacion:

Microcontroller View
Saludos desde Granada, España.


 

anything