Curso de programación de PIC en PICBasic Pro

Si TEM se establece en 0 al iniciar, ¿cómo es que pretendes que se pueda comparar con los valores elegidos?
¿Y por qué restas la variable SENSAR? Esta variable es la que contiene la lectura del conversor AD y su posterior modificación se verá afectada cada nueva lectura.
Supongo que debe ser al revés. O sea, comparar la variable SENSAR y modificar la variable TEM

Esos IF anidados no me agradan. Sería mejor usar una selección de datos con Select Case.
Aparte, se debe establecer un rango, porque las lecturas del conversor AD no son estables.
También sería conveniente realizar un promedio para lograr mejor estabilidad.

No sé qué pretendas hacer, pero no le encuentro sentido a ese programa.
 
gracias por responder los if anidados y las restas es para tener una mejor lectura o la mas estable posible
la Select Case. no la se utilizar si tienes un ejemplo que mejor y pues ya quedo el sensor de temperatura a 10bits ya lo proble y todo y esta funcionando lo dejo por si tienen un mejora que hacer etc

Código:
define ADC_BIST 10
DEFINE ADC_CLOCK 3
DEFINE ADC_SAMPLEUS 50

define OSC 20
DEFINE LCD_DREG PORTC
DEFINE LCD_BITS 4
DEFINE LCD_DBIT 0
DEFINE LCD_RSREG PORTC
DEFINE LCD_RSBIT 4
DEFINE LCD_EREG PORTC
DEFINE LCD_EBIT 5
DEFINE LCD_LINES 2
DEFINE LCD_COMMANDUS 2000
DEFINE LCD_DATAUS 50

ADCON1=14 
PORTB=0
TRISA=1
TRISB=0

SENSAR VAR WORD
TEM VAR WORD
 
SENSAR=0
TEM=0


INICIO:

 ADCIN  0,SENSAR

IF tem=>43 THEN
   ELSE
   SENSAR=SENSAR-1
  
IF TEM=>63 THEN
   ELSE
   SENSAR=SENSAR-2
      
IF TEM=>120 THEN
   ELSE
   SENSAR=SENSAR-3
  
IF TEM=>293 THEN
   ELSE
   SENSAR=SENSAR-4

SENSAR=SENSAR/2
LCDOUT $FE,1                     
LCDOUT $FE,2, "  TEMPERATURA: "  'POCICION DE LA LINEA 1'
LCDOUT $FE,$C0,#SENSAR,%11011111, "C"
PAUSE 500
LCDOUT $FE,1
ENDIF
ENDIF
ENDIF
ENDIF

IF SENSAR>35 THEN
PORTB.0=1
PAUSE 500
LCDOUT $FE,1   'LIMPIAR PANTALLA '
LCDOUT $FE,2, "  VENTILADOR "  'POCICION DE LA LINEA 1'
LCDOUT $FE,$C0, "ENCENDIDO" 'POCICION DE LA 2 LINEA'
PAUSE 2000
      ELSE
IF SENSAR=28 THEN
PORTB.0=0
PAUSE 500
LCDOUT $FE,1   'LIMPIAR PANTALLA '
LCDOUT $FE,2, "  VENTILADOR "  'POCICION DE LA LINEA 1'
LCDOUT $FE,$C0, " APAGADO " 'POCICION DE LA 2 LINEA'
PAUSE 2000
      ENDIF
   ENDIF   
GOTO INICIO:
 
los if anidados y las restas es para tener una mejor lectura o la mas estable posible
De esa forma no se logra una mejor lectura porque no se está involucrando con el conversor AD.
Con lo que se logra una lectura más estable, con lo que te mencioné.
La Select Case no la sé utilizar. Si tienes un ejemplo, que mejor.
En este tema existen varios ejemplos en donde se ha usado.
También cuentas con los temas de ayuda del entorno. Presiona la tecla F1 y aparecerá el documento de ayuda.
De igual forma, si tienes dudas con alguna instrucción, posiciona el cursor en ella y a continuación presiona la tecla F1
 
Que tal como están, una pregunta, y lo he estado buscando en el foro, y mi pregunta es éste sensor dht11 que es de temperatura y humedad, ya tengo la programación en microcode estudio de un sensor de temperatura con un lm35 pero me gustaría añadir éste que contiene los 2 , ¿se podría ? y cómo sería su configuración?, de antemano gracias
 
Buenas noches compañeros , por aca nuevamente molestandolos, he estado tratando de leer un tren de pulsos que sale por los pines del puerto del pic, por decir portb.0, despues portb.1 y leerlo siempre por portb.7, lo que quiero es identificar por cual pin salio el tren de pulsos.
Lo que busco hacer es un probador de red que no tenga que estar otra persona en el otro extremo a probar, los que he visto en internet debe haber una persona al extremo del otro punto para verificar si el hilo esta bien o esta abierto, que si es uno a uno o es cruzado.

De ante mano muchas gracias y me puedan colaborar.
 
Hola compañeros, gracias D@rk por tu respuesta, lo del envio de identificador lo tengo claro, pero donde estoy trocado es en la parte de la recepción del identificador, si tendria que hacer por hardware o software. Por Software no me dio utilizando el comando Count, Pulsin o no lo supe inplementar.

Código:
clear
anselh = $00
DEFINE LCD_DREG PORTB                               ; configuro la panta LCD
DEFINE LCD_DBIT 4
DEFINE LCD_RSREG PORTB
DEFINE LCD_RSBIT 1
DEFINE LCD_EREG PORTB
DEFINE LCD_EBIT 0
DEFINE LCD_COMMANDUS 2000
DEFINE LCD_DATAUS 50
TRISB = 0
TrisC = %00000000
PORTC = 0
w var WORD
inicio:
        LCDOUT $FE,1
        LCDOUT $FE,$80,#W      ;Muestro en la pantalla lo que se cargo en w.
        PAUSE 500
Pulsos:

    portC = %00000001            ;Prendo portc.1 o hilo 1 del utp
    pause 300                            ;pause 300 ms
    PULSOUT PORTC.0, 2000    ;envio un tren de pulso
    PULSIN PORTB.3,1,W          ;y los recepciono.
    pause 300
    goto inicio
end
Seria de gran ayuda se me pudiesen dar una mano.
Cordial saludo.
 

Adjuntos

  • Probador de red.jpg
    Probador de red.jpg
    434.2 KB · Visitas: 36
Buenas tardes a todos , quisiera una ayuda o sugerencia con algún moderador , verán , programo en microcode studio 3.0 y compilador PBP 2.6 . Estoy usando dos módulos Xbee y pues por medio del software XCTU eh podido configurar a cada uno , estos modulos pueden comunicarse inalambricamente por comandos AT ( comunicación punto a punto) y el segundo modo es por red , es decir , estos módulos se pueden configurar a cada módulo como coordinador o router , al configurar a uno de ellos como coordinador(ya que es necesario al menos uno para poder crear una red) podemos obtener una trama y esta trama es de la siguiente forma 7E 00 0F 10 01 00 13 A2 00 40 C0 E3 EE FF FE 00 00 se pueden dar cuenta que esta en hexadecimal , toda esta configuración y la trama se obtienen del software XCTU(Este software se puede descargar gratis desde la pagina DIGI , empresa que provee los módulos). Voy al problema :
Estoy trabajando en la comunicación serial , puedo hacer comunicación serial enviando numeros, letras y hasta cadenas pero el detalle esta en recibir cadenas y que el PIC receptor pueda distinguir cada cadena que le envíe , eh configurado los modulos para trabajar en red y pues tengo la trama que es 7E 00 0F 10 01 00 13 A2 00 40 C0 E3 EE FF FE 00 00 , a esta trama le tengo que añadir unos cuantos caracteres depende de lo que quiera hacer , es decir , si quiero prender un led seria de la siguiente manera : TRAMA(7E 00 0F 10 01 00 13 A2 00 40 C0 E3 EE FF FE 00 00) + 01 6A Estos dos ultimos numeros corresponden al comando que le añadí para que el PIC pueda prender el led ,si se dan cuenta todos estos caracteres estan en hexadecimal y para enviar estas combinaciones antecedo con el signo de " $ " . Eh simulado en proteus y pues toda esta trama son enviados pero al momento de que el PIC receptor detecta estos comandos prende el led pero cuando envio otra trama para apagarlo , el PIC no apaga el led . Eh identificado que el problema esta en que el PIC no recibe la cadena de caracteres hexadecimales(trama), no los diferencia y pues al momento que le envie la trama de prender o apagar pues el PIC solo prende el led , no importa cual sea la trama , espero que puedan darme una mano con esto por favor , adjunto código y simulación .


Código:
CODIGO DEL PIC TRANSMISOR


include "modedefs.bas"
DEFINE OSC 4
CMCON=7
TRISA=%00011100
TRISB=%00000000
TX VAR PORTB.2
'RX VAR PORTB.1

BOTON1 VAR PORTA.2
BOTON2 VAR PORTA.3


voidMain:

if boton1=1 then envio1
 
IF BOTON2=1 THEN envio2



GOTO voidmain


envio1:
if boton1=1 then envio1
serout tx,T9600,[$7E,$00,$0F,$10,$01,$00,$13,$A2,$00,$40,$C0,$E3,$EE,$FF,$FE,$00,$00,$01,$6A,13] ; TRAMA para prender led
goto voidmain


envio2:
if boton2=1 then envio2
serout tx,T9600,[$7E,$00,$0F,$10,$01,$00,$13,$A2,$00,$40,$C0,$E3,$EE,$FF,$FE,$00,$00,$00,$6B,13]  ;Trama para apagar led
goto voidmain



END









Código:
CODIGO DEL PIC RECEPTOR



INCLUDE "modedefs.bas"
DEFINE OSC 4
CMCON=7
TRISA=%00000000
PORTA=0
TRISB=%00000010

'TX VAR PORTB.2
RX VAR PORTB.1
dato var WORD


LED VAR PORTA.2


INICIO:
   SERIN RX,T9600,DATO
 
   SELECT CASE DATO
   CASE $7E,$00,$0F,$10,$01,$00,$13,$A2,$00,$40,$C0,$E3,$EE,$FF,$FE,$00,$00,$01,$6A 
   CALL PRENDE
   CASE $7E,$00,$0F,$10,$01,$00,$13,$A2,$00,$40,$C0,$E3,$EE,$FF,$FE,$00,$00,$00,$6B
   CALL APAGA
  

  
   END SELECT

GOTO INICIO

PRENDE:

  HIGH LED

GOTO INICIO

APAGA:

  LOW LED

GOTO INICIO

END
 

Adjuntos

  • Proteus.rar
    15 KB · Visitas: 27
Con esa forma de usar Select Case para comparar los datos no podrás comparar una cadena de bytes.
Recuerda que por RS-232 únicamente se puede recibir un byte a la vez, por lo tanto la variable dato no podrá contener todos los bytes que envías.
Aparte no tiene caso que la declares del tipo Word porque nada más recibirás 8 bits por envío. (1 byte)
Lo que se usa para recibir una cadena en PBP es la instrucción Wait ()

Ejemplos:
Código:
; Código del PIC Transmisor.

; Palabra de configuración PBPX:
#Config
    __CONFIG _HS_OSC & _WDT_OFF & _PWRTE_ON & _LVP_OFF
#EndConfig

include "modedefs.bas"
Define OSC 12

Symbol Boton1 = PORTA.2
Symbol Boton2 = PORTA.3

Inicio:
    ; Configuración USART: (19200 Bps @ 12 MHz. 19231 Bps Reales 0.16% de error.)
    SPBRG =    38    ; 00100110
    TXSTA =    36    ; 00100100
    RCSTA =    144    ; 10010000
    
    CMCON = 7

Programa:

    If boton1 = 1 Then
        GoSub Envio1
        While Boton1 = 1: Wend
    EndIf
 
    If Boton2 = 1 Then
        GoSub Envio2
        While Boton2 = 1: Wend
    EndIf
    
    GoTo programa


Envio1:
    ; Trama para encender el LED
    HSerOut [$7E,$00,$0F,$10,$01,$00,$13,$A2,$00,$40,$C0,$E3,$EE,$FF,$FE,$00,$00,$01,$6A,13]
    Return
    
Envio2:
    ; Trama para apagar el LED:
    HSerOut [$7E,$00,$0F,$10,$01,$00,$13,$A2,$00,$40,$C0,$E3,$EE,$FF,$FE,$00,$00,$00,$6B,13]
    Return

    End

Código:
; Código del PIC receptor.

; Palabra de configuración PBPX:
#Config
    __CONFIG _HS_OSC & _WDT_OFF & _PWRTE_ON & _LVP_OFF
#EndConfig

Include "modedefs.bas"
Define OSC 12

Symbol LED = PORTA.2

Inicio:
    ; Configuración USART: (19200 Bps @ 12 MHz. 19231 Bps Reales 0.16% de error.)
    SPBRG =    38    ; 00100110
    TXSTA =    36    ; 00100100
    RCSTA =    144    ; 10010000
    
    CMCON = 7
    Low LED

Programa:
    HSerIn 100, Apagar, [Wait($7E,$00,$0F,$10,$01,$00,$13,$A2,$00,$40,$C0,$E3,$EE,$FF,$FE,$00,$00,$01,$6A,13)]
    Call Prende
Apagar:
    HSerIn 100, Salir, [Wait($7E,$00,$0F,$10,$01,$00,$13,$A2,$00,$40,$C0,$E3,$EE,$FF,$FE,$00,$00,$00,$6B,13)]
    Call Apaga
Salir:
    GoTo Programa

Prende:
    High LED
    Return

Apaga:
    Low LED
    Return

    End
Tal vez de esa forma funcione, o tal vez no, es cuestión de probar, ya que hace mucho tiempo que no programo en PBP.
 
Con esa forma de usar Select Case para comparar los datos no podrás comparar una cadena de bytes.
Recuerda que por RS-232 únicamente se puede recibir un byte a la vez, por lo tanto la variable dato no podrá contener todos los bytes que envías.
Aparte no tiene caso que la declares del tipo Word porque nada más recibirás 8 bits por envío. (1 byte)
Lo que se usa para recibir una cadena en PBP es la instrucción Wait ()

Ejemplos:
Código:
; Código del PIC Transmisor.

; Palabra de configuración PBPX:
#Config
    __CONFIG _HS_OSC & _WDT_OFF & _PWRTE_ON & _LVP_OFF
#EndConfig

include "modedefs.bas"
Define OSC 12

Symbol Boton1 = PORTA.2
Symbol Boton2 = PORTA.3

Inicio:
    ; Configuración USART: (19200 Bps @ 12 MHz. 19231 Bps Reales 0.16% de error.)
    SPBRG =    38    ; 00100110
    TXSTA =    36    ; 00100100
    RCSTA =    144    ; 10010000
   
    CMCON = 7

Programa:

    If boton1 = 1 Then
        GoSub Envio1
        While Boton1 = 1: Wend
    EndIf

    If Boton2 = 1 Then
        GoSub Envio2
        While Boton2 = 1: Wend
    EndIf
   
    GoTo programa


Envio1:
    ; Trama para encender el LED
    HSerOut [$7E,$00,$0F,$10,$01,$00,$13,$A2,$00,$40,$C0,$E3,$EE,$FF,$FE,$00,$00,$01,$6A,13]
    Return
   
Envio2:
    ; Trama para apagar el LED:
    HSerOut [$7E,$00,$0F,$10,$01,$00,$13,$A2,$00,$40,$C0,$E3,$EE,$FF,$FE,$00,$00,$00,$6B,13]
    Return

    End

Código:
; Código del PIC receptor.

; Palabra de configuración PBPX:
#Config
    __CONFIG _HS_OSC & _WDT_OFF & _PWRTE_ON & _LVP_OFF
#EndConfig

Include "modedefs.bas"
Define OSC 12

Symbol LED = PORTA.2

Inicio:
    ; Configuración USART: (19200 Bps @ 12 MHz. 19231 Bps Reales 0.16% de error.)
    SPBRG =    38    ; 00100110
    TXSTA =    36    ; 00100100
    RCSTA =    144    ; 10010000
   
    CMCON = 7
    Low LED

Programa:
    HSerIn 100, Apagar, [Wait($7E,$00,$0F,$10,$01,$00,$13,$A2,$00,$40,$C0,$E3,$EE,$FF,$FE,$00,$00,$01,$6A,13)]
    Call Prende
Apagar:
    HSerIn 100, Salir, [Wait($7E,$00,$0F,$10,$01,$00,$13,$A2,$00,$40,$C0,$E3,$EE,$FF,$FE,$00,$00,$00,$6B,13)]
    Call Apaga
Salir:
    GoTo Programa

Prende:
    High LED
    Return

Apaga:
    Low LED
    Return

    End
Tal vez de esa forma funcione, o tal vez no, es cuestión de probar, ya que hace mucho tiempo que no programo en PBP.



Hola D@rbytes , gracias por responder al post , eh analizado el código modificado que enviaste y también tenia la idea de usar el USART del pic , pero al momento de simularlo envío la "trama de encender el led" y este efectivamente enciende , al momento de enviar la "trama de apagar el led" , este apaga pero si vuelvo a enviar la "trama de apagado del led" el led enciende (lo cual no deberia de suceder) y eso no es todo, hice una prueba enviando cualquier dato(cualquier cosa) y el led igual enciende , el pic al parecer no esta diferenciando cada trama que se le envía o si yo estoy mal tratando de enviar una trama de esa manera en hexadecimal (con signo $ antepuesto ) ya que la trama me lo genera el propio software XCTU al momento de configurar los módulos XBee , nose si estoy mal en este aspecto de la programación tratando de enviar tramas de ese modo y también eh averiguado sobre el modificador WAITSTR - "Espera por una cadena de caracteres" pero al final es lo mismo que poner un WAIT . Que puedo estar haciendo mal ? o es que no se puede enviar tramas como esto 7E 00 0F 10 01 00 13 A2 00 40 C0 E3 EE FF FE 00 00 01 6A ?:unsure: Agradecería mucho alguna sugerencia por favor.
Gracias;
 
el pic al parecer no está diferenciando cada trama que se le envía o si yo estoy mal tratando de enviar una trama de esa manera en hexadecimal (con signo $ antepuesto )
Escribir en hexadecimal usando $ es tan solo para que tú puedas verlo así en el editor.
El microcontrolador de todos modos enviará el número en binario.
O sea que si mandas $FF, el microcontrolador enviará 11111111, (255) no los dos caracteres FF que serían dos bytes con el valor 70 cada uno.
De igual forma, si escribes 255 se enviará 11111111
Lo que hay que tener en cuenta es que, no es lo mismo enviar "255" como cadena que como entero.
Si se envía como cadena de caracteres se enviarán 3 bytes: 50, 53, 53 (Números correspondientes a la tabla ASCII)
¿Qué puedo estar haciendo mal? ¿O es que no se puede enviar tramas como esto 7E 00 0F 10 01 00 13 A2 00 40 C0 E3 EE FF FE 00 00 01 6A?
Si se pueden enviar así y el microcontrolador también lo recibe, pero una comunicación serial asíncrona tiene sus desventajas.
Se puede perder información durante el envío y se recibirá cualquier cosa, a veces bien y a veces mal.
Para eso se emplea una comprobación de datos calculando el checksum.
Este es enviado dentro de la trama y el receptor debe recalcular eso nuevamente.
Si los datos son válidos, se procesan, si no, se envía una petición con un comando de error.
Calcular el checksum es sencillo, se suman todos los bytes y se hace un AND con 0xFF (255)
Por ejemplo:
34 + 126 + 245 + 89 AND 255 = 238 (De esta forma el checksum nunca sobrepasará 255)
Si el checksum enviado es el mismo que se recalcula en el receptor, entonces los datos estarán correctos.
Otra cosa que mejora la situación es, usar velocidades altas de transmisión.
 
Escribir en hexadecimal usando $ es tan solo para que tú puedas verlo así en el editor.
El microcontrolador de todos modos enviará el número en binario.
O sea que si mandas $FF, el microcontrolador enviará 11111111, (255) no los dos caracteres FF que serían dos bytes con el valor 70 cada uno.
De igual forma, si escribes 255 se enviará 11111111
Lo que hay que tener en cuenta es que, no es lo mismo enviar "255" como cadena que como entero.
Si se envía como cadena de caracteres se enviarán 3 bytes: 50, 53, 53 (Números correspondientes a la tabla ASCII)

Si se pueden enviar así y el microcontrolador también lo recibe, pero una comunicación serial asíncrona tiene sus desventajas.
Se puede perder información durante el envío y se recibirá cualquier cosa, a veces bien y a veces mal.
Para eso se emplea una comprobación de datos calculando el checksum.
Este es enviado dentro de la trama y el receptor debe recalcular eso nuevamente.
Si los datos son válidos, se procesan, si no, se envía una petición con un comando de error.
Calcular el checksum es sencillo, se suman todos los bytes y se hace un AND con 0xFF (255)
Por ejemplo:
34 + 126 + 245 + 89 AND 255 = 238 (De esta forma el checksum nunca sobrepasará 255)
Si el checksum enviado es el mismo que se recalcula en el receptor, entonces los datos estarán correctos.
Otra cosa que mejora la situación es, usar velocidades altas de transmisión.

Te comprendo D@rbytes y te soy sincero , en proteus para simular el envío de la trama lo hago de pic a pic (transmisor-receptor) y funciona como se manda en la programación pero al momento de implementarlo en físico no responde el encendido del led , es decir , armo mi circuito conectado al primer Xbee , luego abro el software XCTU , conectando el segundo modulo XBee , entro a la ventana para enviar la trama de encendido( el XCTU cuenta con una ventana de transmisión y recepción de datos) , al enviar dicha trama me sale que el envió a sido exitoso(Successful) pero el led no enciende, recuerdo que cuando utilicé el modulo HC-05(Bluetooh) la programación es practicamente la misma a diferencia que aqui tengo que enviar tramas , que puede estar faltando :unsure:? Ya eh leído una y otra vez la hoja de datos del pic (16F628A) y las intrucciones del PBP . Te adjunto una imagen de la trama enviada y recepcionada en proteus.
foto.png
 
No sé qué pase con los XBee pero posiblemente se esté recibiendo ruido.
Tal vez tengas que usar un sistema de codificación como el Manchester, por ejemplo.

Yo tengo programas que envían y reciben hasta más de 50 datos por RS-232 y sin problemas, pero esto de PC a microcontrolador y viceversa.
Luego cambié el modo de comunicación a USB y se acabaron los datos erróneos.
 
Buenas noches compañeros,
Nuevamente por aca molestandolos, estoy tratando de hacer funcionar una varias matriz de led 8x8 con un Max7219, hasta ahora he conseguido hacer funcionar cada una de las matriz pero a la ahora de hacerlo que trabaje uno por uno no me funciona, si alguien me puede colaborar en ver que esta mal en el codigo o en la programacion del Max7219 se lo agradeceria.



2019-10-09.pngAdjunto:
archivo proteus version 8.9
archivo .bas
archivo.COF
archivo.Hex
 

Adjuntos

  • MatrixLed.rar
    29.8 KB · Visitas: 17
Para empezar tenes definido una sola salida de data a los MAX y el resto?.

No hay definidos/asignados PINES del microcontrolador para tal fin tanto en el esquema como en el programa.
 
Buenas noches ricbevi y compañeros, el max7219 se puede trabajar en cascada, lo que entra por Din lo envia por Dout y asi sucesivamente en los que esten conectados, lo que no logro conseguir es hacer el corrimiento al siguiente Max7219, no se como habilitarlo por codigo, el datasheet dice:

El registro no operativo se utiliza cuando se conectan en cascada MAX7219 o MAX7221. Conecte todas las entradas LOAD / CS de todos los dispositivos y conecte DOUT a DIN en dispositivos adyacentes. DOUT es una salida de nivel lógico CMOS que maneja fácilmente DIN de partes sucesivamente en cascada. (Consulte la sección Modos de direccionamiento en serie para obtener información detallada sobre el tiempo de entrada / salida en serie). Por ejemplo, si cuatro MAX7219 están en cascada, para escribir en el cuarto chip, se envía la palabra de 16 bits deseada, seguida de tres no-op códigos (hex XXXX, ver Tabla 2). Cuando LOAD / CS sube, los datos se enclavan en todos los dispositivos. Los primeros tres chips reciben comandos sin operación, y el cuarto recibe los datos deseados.

Bueno sin embargo lo que quiero hacer yo es que cuando termine en la primer matriz siga en le siguiente y eso es lo que no me da.
Este es mi codigo:
Código:
'****************************************************************
'*  Name    : Matrix8x8.BAS                                     *
'*  Author  : [select VIEW...EDITOR OPTIONS]                    *
'*  Notice  : Copyright (c) 2019 [select VIEW...EDITOR OPTIONS] *
'*          : All Rights Reserved                               *
'*  Date    : 26/09/2019                                        *
'*  Version : 1.0                                               *
'*  Notes   :  PIC16F883                                        *
'*          :                                                   *
'****************************************************************
    Include "Modedefs.bas"
    ANSEL = 0
    ANSELH = 0
' ** Set Xtal Value in mHz **

    Define    OSC    20        ' Set Xtal Frequency

' ** Declare TRIS Used **
'    TRISB = 0


' ** Declare Pins Used **
    Clk     Var    PortB.0        ' Data is clocked on rising edge of this pin
    Dta      Var    PortB.1        ' Bits are shifted out of this pin
    Load    Var    PortB.2        ' Transfers data to LEDs when Pulsed

' ** Declare Constants **
    No_Op            Con $0    ' Scan-limit register.
    Decode_Reg         Con    $9    ' Decode register, a 1 turns on BCD decoding for each digit.
    Intensity        Con    $A    ' Intensity register.
    ScanLimit_Reg    Con    $B    ' Scan-limit register. 
    Shutdown_Reg    Con    $C    ' On/Off Register.
    Display_test    Con    $F    ' Test mode register (all digits on, 100% bright)

'    Max_Digit    Con    5    ' Amount of LED Displays being used.

' ** Declare Variables **
      Counter        Var    Byte    ' Variable used for the Demo Counting routine
    Max_Disp    Var    Word    ' 16-bit value to be displayed by the MAX7219
    i            Var    byte    ' Digit number to place Decimal point (0-4)
    Register    Var    Byte    ' Pointer to the Internal Registers of the MAX7219
    R_Val        Var    Byte    ' Data placed in Each Register
    Digit        Var    Byte    ' Position of individual numbers within MAX_Disp (0-3)
    Digito        Var    Byte    ' Position of individual numbers within MAX_Disp (0-3) 
    Position    Var    Byte    ' Position of each LED display (1-4)
  
' ** INITIALIZE THE MAX7219 **
' Each register address is sent along with its setting data.
' Because the MAX7219 expects to see a packet of 16 bits, then the LOAD pin is pulsed
' Set the scan limit to 3 (4 digits, numbered 0-3)
' Set the Brightness to 5
' BCD decoding to the lower 4 digits
' Switch the display on.
' Turn Off test mode

i = "a"
  
    Register=Shutdown_Reg    ' Point to the Switch Register
    R_Val=$00                ' Set to One, (switches the display ON)
    Gosub Transfer            ' Transfer this 16-bit Word to the MAX7219 

    Register=No_Op             ' Point to the Scan Register
    R_Val=0                    ' send 3, (Four LED Displays 0-3)
    Gosub Transfer            ' Transfer this 16-bit Word to the MAX7219
      
    Register=ScanLimit_Reg    ' Point to the Scan Register
    R_Val=$07                ' send 3, (Four LED Displays 0-3)
    Gosub Transfer            ' Transfer this 16-bit Word to the MAX7219

    Register=Intensity         ' Point to the Luminance Register
    R_Val=$05                 ' Send 5, (Value for Brightness)
    Gosub Transfer            ' Transfer this 16-bit Word to the MAX7219

    Register=Decode_Reg        ' Point to BCD Decode Register
    R_Val=$00                ' Decode the first 5 digits
    Gosub Transfer            ' Transfer this 16-bit Word to the MAX7219

    Register=Display_test    ' Point to the Test Register
    R_Val=$00                ' Reset to Zero, (turns off Test mode)
    Gosub Transfer            ' Transfer this 16-bit Word to the MAX7219

    Register=Shutdown_Reg    ' Point to the Switch Register
    R_Val=$01                ' Set to One, (switches the display ON)
    Gosub Transfer            ' Transfer this 16-bit Word to the MAX7219

i = "a"
counter = 1

Inicio:

    digito = 1                                      ;Cargo Digito para que comience en 1
    for counter = counter to 8                      ;Contador para las filas de la matriz
        Register = counter                          ;Cargo el valor de Counter a Register para enviarle al max 7219
        for Digit = 1 to 8                          ;Contador de columnas de la matriz
            R_Val=Digito                            ;Cargo el valor de Digito a R_Val para enviarle al max 7219 y prenda led por led como en culebrilla
            Gosub Transfer                          ;Se va a la etiqueta Transfer y envia el dato al Max 7219
            pause 100         
        if digito => 128 then                       ;Pregunta si Digito es mayo o igual a 128
            digito = 0                              ;Se pone a 0 Digito para apagar el led
            R_Val=Digito                            ;Cargo el valor de Digito a R_Val para enviarle al max 7219
            counter = counter + 1                   ;Se incrementa la Counter para pasar a la sigiente fila de la matrix
            Gosub Transfer                          ;Se va a la etiqueta Transfer y envia el dato al Max 7219 y apague el led
            goto devolver                           ;Se va a la etiqueta devolver para que se devuelva nuevamente hacia adelante en la siguiente fila
        endif         
        digito = digito <<1                         ;Se desplaza el led hacia el siguiente led
        next             
    next
                                                    ;Aca se crea el efecto de regresarse hacia el inicio en la otra fila
devolver:
                                                    ;Cargo Digito para que comience en 128
    digito = 128
    for counter = counter to 8
        Register = counter
        for Digit = 1 to 8                       
            R_Val=Digito
            Gosub Transfer
            pause 100
            if digito <= 1 then
                digito = 0 
                R_Val=Digito
                counter = counter + 1
                if counter > 8 then counter = 8
                Gosub Transfer             
                if counter => 8 then       
                    if counter => 8 then i = "b"
                    if counter => 8 and i = "b" then i = "c"
                    counter = 1
                endif
                goto inicio
            endif         
            digito = digito >>1
        next     
    next
goto Inicio 
' Send a 16-bit word to the MAX7219
Transfer:
select CASE i
    
      case "a"
    Shiftout Dta,Clk,msbfirst,[0,0,0,0,0,0,Register,R_Val] ' Escribe en la primera matriz
    High Load                ' The data is now acted upon 
@    Nop
@    Nop                    ' A small delay to ensure correct clocking times
    Low Load                ' Disable the MAX7219   
    Return                    ' Exit from Subroutine

    case "b"
    Shiftout Dta,Clk,msbfirst,[Register,R_Val,00] ' Escribe en la segunda matriz
    High Load                ' The data is now acted upon 
@    Nop
@    Nop                    ' A small delay to ensure correct clocking times
    Low Load                ' Disable the MAX7219
    Return                    ' Exit from Subroutine

      case "c"
    Shiftout Dta,Clk,msbfirst,[Register,R_Val,0,0,0,0] ' Escribe en la tercera matriz
    High Load                ' The data is now acted upon 
@    Nop
@    Nop                    ' A small delay to ensure correct clocking times
    Low Load                ' Disable the MAX7219
    Return                    ' Exit from Subroutine

end select
return

end

Cordial saludo y de ante mano gracias!
 
Última edición:
Antes de abocarme en sí al programa yo haría un simple demo de cómo se enciende los led de la matriz cuando se cambia de MAX estando en cascada.

Tu programa se queda en el primer MAX y nunca sale de allí por lo que debes investigar como es el asunto.

Nunca trabaje con ese chip.
 
Hola compañeros, bueno he conseguido trabajar las matriz cada vez que temine de trabajar en una pase a la siguiente. Lo consegui inicializando todos los MAX7219, se envian los 16 bits por cada MAX que se tenga, en mi caso son 3. Anteriormente solo envia una sola trama:

Código:
        Shiftout Dta,Clk,msbfirst,[Register,R_Val,Register,R_Val,Register,R_Val,Register,R_Val] 'Inicializo todos los MAX7219
        High Load                ' Activo el dato enviado al MAX7219   
    @    Nop
    @    Nop                        ' Tiempo de espera
        Low Load                ' Deshabilito el MAX7219

Buscando por la web encontre un codigo de una matriz de led 8x32 funcionando, pero me al correrlo en proteus corre de forma vertical, como puedo hacer por codigo para que trabaje de forma horizontal, trate con el codigo de las letras se enderezan pero siguen de forma vertical.

2019-10-11 (1).png

Código:
SEND_DATA:      'PARTE DEL CODIGO QUE ME GUSTARIA QUE ME EXPLICARAN

For CharLine=0 To 5
GoSub Display_inc
Display[i-1]=FC[CharLine]
GoSub Update_data
pause SpeedScrolling 
Next ;CharLine
Return

Display_inc:
For i=0 To 31
Display[i]=Display[i+1]
Next 
Return
Nunca he trabajado los array de esa forma, me podrian colaborar explicando como trabaja esta parte del codigo.
Adjunto codigo y simulacion proteus 8.9

De ante mano muchas gracias.
 

Adjuntos

  • MatrixLedConDesplazamiento.rar
    34.5 KB · Visitas: 31
Atrás
Arriba