Regístrate gratis para participar de los foros, o si ya estás registrado haz login.
| comentario del autor | Lun Dic 10, 2007 7:45 pm | |
|
Solo hago algunas variaciones para el baud rate pues el pic usa un cristal de 4 Mhz y no de 10 como en la nota de aplicacion (AN976: I2c y EEprom). Al final de todo solo veo en el display (lcd 2x16) ???????? Si alguien me puede ayudar les agradeceria en el alma!! a continuacion el codigo Nota: los registros y pines que se incluyen corresponden a una aplicacion que si me funciona y un fichero con las subrutinas del LCD ;~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ; ; ; RELOJ DS 1307, CRISTAL 32.768 KHz ; ; ;~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ LIST P=16F877 __CONFIG _XT_OSC & _WDT_OFF & _LVP_OFF ;--------------------------------------------------- ; Port C pin descriptions ; SCL bit = 3 ;SALIDA RELOJ I2C ; SDA bit = 4 ;SALIDA DATOS I2C ; Tx bit = 6 ;SALIDA DATOS RS232 ; Rx bit = 7 ;ENTRADA DATOS RS232 ;---------------------------------------------------- ; 4MHz crystal is being used ; ;*******************RAM register definitions********************** datai equ 20h ; Data input byte buffer datao equ 21h ; Data output byte buffer bytecount equ 22h ; Counter for byte loops pollcnt equ 23h ; Counter for polling loops loops equ 24h ; Delay loop counter loops2 equ 25h ; Delay loop counter LCD_TEMP equ 26h ; Posiciones auxiliares en el banco 0 DELAY equ 27h ; para temporizar X_DELAY equ 28h ; para temporizar AUX equ 29h ; para guardar temporalmente DIRH equ 2ah DIRL equ 2bh CounterA equ 2ch CounterB equ 2dh CounterC equ 2eh XmtReg equ 2fh I2C_Banderas equ 30h Segundo equ 31h Minuto equ 32h Hora equ 33h DiaSemana equ 34h Dia equ 35h Mes equ 36h Anho equ 37h W_TEMP equ 38h ;almacén temporal para el registro W ST_TEMP equ 39h ;almacén temporal para el registro STATUS PCLATH_TEMP equ 3ah ;almacén temporal del registro PCLATH BCD0 equ 3bh ;(DECENAS:UNIDADES) BCD1 equ 3ch ;(MILLARES:CENTENAS) BCD2 equ 3dh ;(0:DECENAS DE MIL) FACTOR1 equ 3eh ;Uno de los factores del producto FACTOR2 equ 3fh ;Otro de los factores del subprograma producto SUMA_ALTO equ 40h ;Posición que almacena la parte alta de FACTOR1 desplazado a la izq. SUMA_BAJO equ 41h ;almacenará la parte baja de FACTOR1 desplazado a la izquierda CONTADOR equ 42h ;Para el subprograma de multiplicación, cuenta sumas parciales BIN_ALTO equ 43h ;Parte alta del valor medido en binario BIN_BAJO equ 44h ;Parte baja del periodo en binario TMP equ 45h ;otra variable auxiliar ;*******************Macro definitions***************************** WRITE_ds equ b'11010000' ; Control byte for write operations READ_ds equ b'11010001' ; Control byte for read operations ;*******************Include file********************************** include "p16f877.inc" ; Include file for a PIC16F877 errorlevel -302 ; Suppress message 302 from list file ;********************************************************** LCD_DATA EQU PORTD ;DATOS se conecta a PORTD LCD_DATA_TRIS EQU TRISD ; LCD_CTRL EQU PORTE ;CONTROL se conecta a PORTE LCD_CTRL_TRIS EQU TRISE ; LCD_LINE0 EQU 0x000 ;dirección comienzo línea superior DDRAM del LCD LCD_LINE1 EQU 0x040 ;dirección comienzo línea inferior DDRAM del LCD ; También se deben definir los Bits de control: LCD_E EQU 2 ; Enable será el bit 1 del PORTE LCD_RW EQU 1 ; Read/Write bit 2 del PORTE LCD_RS EQU 0 ; RS será el bit 3 del PORTE ; En STATUS CARRY equ 0 CERO equ 2 ;***************************************************************** org 0x000 ; Set the reset vector goto start ; Go to the beginning of main include "volt2.ASM" ; Solo contiene subrutinas para el LCD ;*******************Begin Main Program**************************** ;--------------------------------------------------------------- start call Init ; Initialize device ;- CARGA INICIAL DEL DS1307------; movlw 00h ; movwf Segundo ;Segundos inician en 00 movlw 42h ; movwf Minuto ;Minutos inician movlw 08h movwf Hora ;Hora inicia en 08 movlw 02h ; movwf DiaSemana ;Dia 2 equivale a lunes movlw 03h ; movwf Dia ;Dia 03 movlw 12h movwf Mes ; Mes 12 equivale a dic. movlw 07h movwf Anho ; Año 2007 clrf PORTC ; goto display ;----------------------------------------------------------------------- call BSTART ; movlw WRITE_ds ; Pbra control modo Escritura movwf datao call TX movlw 0 ; Se indica la direcc. 0h. movwf datao call TX movlw b'00000000' ; activa bit7 del reg 00 (enable reloj). movwf datao call TX call BSTOP ; Termina de enviar datos. bsf PORTC,5 call PDelay call BSTART ; movlw WRITE_ds ; Pbra control modo Escritura movwf datao call TX movlw b'00000111' ; direccc. 07h. movwf datao call TX ; ctl de la señal cuadrada movlw b'00010000' ; output pin 7. señal cuadrada de 1 Hz movwf datao call TX call BSTOP ; Termina de enviar datos. ;------------------------------------------------------ ;-inicializando el reloj ds1307-------------------------; call BSTART ; movlw WRITE_ds ; Pbra control modo Escritura movwf datao call TX ; movlw 0x00 ; direccion inicial 00 movwf datao call TX movf Segundo,0 ; Pasa los segundos de la memoria del PIC16 al DS1307. movwf datao call TX movf Minuto,0 ; movwf datao call TX movf Hora,0 movwf datao call TX movf DiaSemana,0 movwf datao call TX movf Dia,0 movwf datao call TX movf Mes,0 movwf datao call TX movf Anho,0 movwf datao call TX call BSTOP ; Termina de enviar datos. call PDelay ;-------------------------------------------------------------------------------- ;---------------------------------------------------------- ; lee y actualiza el reloj ;---------------------------------------------------------- RTC_LEE call BSTART ; movlw WRITE_ds ; modo escritura call TX movlw 0x00 ; a los segundos. movwf datao call TX call BRESTART movlw READ_ds ; Pbra control modo Lectura movwf datao call TX call RX ; Lee los segundos. movf datai,0 movwf Segundo ; Lo carga en el registro correspondiente. call RX ; movf datai,0 ; movwf Minuto ; call RX ; movf datai,0 movwf Hora call RX movf datai,0 movwf DiaSemana call RX movf datai,0 movwf Dia call RX movf datai,0 movwf Mes ;------------------------------------------------------------ ; GENERA UN NO ACK INDICANDO QUE ES EL ULTIMO BYTE A LEER ;------------------------------------------------------------ bsf STATUS,RP0 ; Select Bank 01 bsf SSPCON2,ACKDT ; Select to send NO ACK bit genera un NO ACK(Generate NO ACK) bcf STATUS,RP0 ; Select Bank 00 call RX ;Recibe el ultimo byte movf datai,0 movwf Anho call BSTOP ; Termina de leer datos. bsf PORTC,5 ;********************************************************** display movlw LCD_LINE1+1 ;Cargo en W la dirección de la línea 0 call LCDSDDA ;y coloco el puntero de la DDRAM del LCD ahí movlw Segundo movwf FSR movlw 7 movwf CONTADOR show movf INDF,0 ; andlw 0xF0 movwf AUX ; swapf AUX,0 ; addlw A'0' ; call LCDPUTCHAR_4_2 ; movf INDF,0 ; andlw 0x0F addlw A'0' ; call LCDPUTCHAR_4_2 ; incf FSR,1 decfsz CONTADOR,1 goto show bcf PORTC,5 goto RTC_LEE nop goto $-1 ; Loop here forever ;_---------------------------------------------- ;*******************Initialization subroutine********************* ; This routine initializes the MSSP module ; for I2C Master mode, with a 100 kHz clock. ;***************************************************************** Init bcf STATUS,RP1 ; Select Bank 01 bsf STATUS,RP0 movlw b'00001110' ;PORTA con RA0 analógica, resto como digitales movwf ADCON1 ;referencia de 5V y resultado justificado ;a la izquierda: ADRESH_ADRESL clrf LCD_DATA_TRIS ;Defino PORTD de salidas movlw 0 ; b'11110001' En el PORTA las 3 salidas movwf LCD_CTRL_TRIS ;para E, RS y R/W movlw 0xCF ; Predivisor de 128 asociado al Watchdog ;///////// ; movwf OPTION_REG movlw b'10011111' movwf TRISC ; Set PORTC to all inputs clrf SSPSTAT ; Disable SMBus inputs bsf SSPSTAT,SMP ; Disable slew rate control movlw 9 ; Load 9 into WREG ((fosc/100khz)/4)-1 = 9 movwf SSPADD ; Setup 100 kHz I2C clock clrf SSPCON2 ; Clear control bits movlw b'00100100' ;Configuracion USART movwf TXSTA ;y activacion de transmision movlw .25 ;9600 baudios movwf SPBRG bcf STATUS,RP0 ; Select Bank 00 movlw b'11000001' ;Configuramos entrada por canal analógico 0 (RA0) movwf ADCON0 ;y reloj RC interno de conversión TAD=4us típico movlw b'00101000' movwf SSPCON ; Enable SSP, select I2C Master mode bcf PIR1,SSPIF ; Clear SSP interrupt flag bcf PIR2,BCLIF ; Clear Bit Collision flag bsf RCSTA,SPEN ;se activa la USART bcf PIR1,ADIF ;Pongo a 0 el flag de fin de conversión call LCD_RST_P2P ;Reset software del módulo LCD call LCDINIT_4 ;Inicializamos el LCD para definir funcionamiento ;interface de 4 bits y 2 líneas visibles call LCDCLEAR ;Limpiamos pantalla al principio retlw 0 ;*******************Start bit subroutine************************** ; This routine generates a Start condition ; (high-to-low transition of SDA while SCL ; is still high. ;***************************************************************** BSTART bcf STATUS,RP1 bcf STATUS,RP0 ; Select Bank 00 bcf PIR1,SSPIF ; Clear SSP interrupt flag bsf STATUS,RP0 ; Select Bank 01 bsf SSPCON2,SEN ; Generate Start condition bcf STATUS,RP0 ; Select Bank 00 bstart_wait btfss PIR1,SSPIF ; Check if operation completed goto bstart_wait ; If not, keep checking retlw 0 ;*******************Restart bit subroutine************************** ; This routine generates a Repeated Start ; condition (high-to-low transition of SDA ; while SCL is still high. ;***************************************************************** BRESTART bcf STATUS,RP1 bcf STATUS,RP0 ; Select Bank 00 bcf PIR1,SSPIF ; Clear SSP interrupt flag bsf STATUS,RP0 ; Select Bank 01 bsf SSPCON2,RSEN ; Generate Restart condition bcf STATUS,RP0 ; Select Bank 00 brestart_wait btfss PIR1,SSPIF ; Check if operation completed goto brestart_wait ; If not, keep checking retlw 0 ;*******************Stop bit subroutine*************************** ; This routine generates a Stop condition ; (low-to-high transition of SDA while SCL ; is still high. ;***************************************************************** BSTOP bcf STATUS,RP1 bcf STATUS,RP0 ; Select Bank 00 bcf PIR1,SSPIF ; Clear SSP interrupt flag bsf STATUS,RP0 ; Select Bank 01 bsf SSPCON2,PEN ; Generate Stop condition bcf STATUS,RP0 ; Select Bank 00 bstop_wait btfss PIR1,SSPIF ; Check if operation completed goto bstop_wait ; If not, keep checking retlw 0 ;*******************Data transmit subroutine********************** ; This routine transmits the byte of data ; stored in 'datao' to the serial EEPROM ; device. Instructions are also in place ; to check for an ACK bit, if desired. ; Just replace the 'goto' instruction, ; or create an 'ackfailed' label, to provide ; the functionality. ;***************************************************************** TX bcf STATUS,RP1 bcf STATUS,RP0 ; Select Bank 00 bcf PIR1,SSPIF ; Clear SSP interrupt flag movf datao,W ; Copy datao to WREG movwf SSPBUF ; Write byte out to device tx_wait btfss PIR1,SSPIF ; Check if operation completed goto tx_wait ; If not, keep checking ; bsf STATUS,RP0 ; Select Bank 01 ; btfsc SSPCON2,ACKSTAT ; Check if ACK bit was received ; goto ackfailed ; This executes if no ACK received retlw 0 ;*******************Data receive subroutine*********************** ; This routine reads in one byte of data from ; the serial EEPROM device, and stores it in ; 'datai'. It then responds with either an ; ACK or a NO ACK bit, depending on the value ; of 'ACKDT' in 'SSPCON2'. ;***************************************************************** RX bcf STATUS,RP1 bcf STATUS,RP0 ; Select Bank 00 bcf PIR1,SSPIF ; Clear SSP interrupt flag bsf STATUS,RP0 ; Select Bank 01 bsf SSPCON2,RCEN ; Initiate reception of byte bcf STATUS,RP0 ; Select Bank 00 rx_wait btfss PIR1,SSPIF ; Check if operation completed goto rx_wait ; If not, keep checking movf SSPBUF,W ; Copy byte to WREG movwf datai ; Copy WREG to datai bcf PIR1,SSPIF ; Clear SSP interrupt flag bsf STATUS,RP0 ; Select Bank 01 bsf SSPCON2,ACKEN ; Generate ACK/NO ACK bit bcf STATUS,RP0 ; Select Bank 00 rx_wait2 btfss PIR1,SSPIF ; Check if operation completed goto rx_wait2 ; If not, keep checking retlw 0 ;PIC Time Delay = 1,0000020 s with Osc = 4 MHz PDelay ;return movlw D'6' ;"6" movwf CounterC movlw D'24' ;D'24' movwf CounterB movlw D'168' ;D'168' movwf CounterA loop decfsz CounterA,1 goto loop decfsz CounterB,1 goto loop decfsz CounterC,1 goto loop return END |
||
| sin valorar | Mie Dic 12, 2007 6:54 pm | |
|
El reloj devuelve los valores en BCD y hay que transformarlos para mostrarlos en la pantalla: Programa: adcon1 = 7 'puerto A y puerto E digital' define osc 4 define lcd_dreg portb 'data port' define lcd_dbit 4 'start data bit 0-4' define lcd_rsreg portb 'RS port rsgister select' define lcd_rsbit 3 'RS bit' define lcd_ereg portb 'Enable port' define lcd_ebit 2 'Enable bit' define lcd_bits 4 'Bus size 4-8' define lcd_lines 2 'numero Lineas' input porta param var byte param=1 f var byte temp1 var byte temp2 var byte 'Defincion reloj ds1307' rtcseg var byte rtcmin var byte rtchor var byte rtcdia var byte rtcmes var byte rtcano var byte rtcsem var byte rtccon var byte rtc_sda var portb.1 rtc_scl var portb.0 'hasta aca ds1307 ' 'Inicializa la hora 12:00:00 1-1-2000' 'Escribir segundos,minutos,horas,dia semana,dias,mes,año,control' 'i2cwrite rtc_sda,rtc_scl,$d0,$00,[$00,$00,$12,$2,$1,$1,$0,$90]' loop: if porta.0=0 then param=param+1 if param>5 then param=1 pause 100 endif if porta.1=0 or porta.2=0 then select case param case 1 temp1=rtchor gosub bcdabin rtchor=temp2 if porta.1=0 then if rtchor>0 then rtchor=rtchor-1 'hora' else if rtchor<23 then rtchor=rtchor+1 'hora' endif temp1=rtchor gosub binabcd rtchor=temp2 case 2 temp1=rtcmin gosub bcdabin rtcmin=temp2 if porta.1=0 then if rtcmin>0 then rtcmin=rtcmin-1 'minutos' else if rtcmin<59 then rtcmin=rtcmin+1 'minutos' endif temp1=rtcmin gosub binabcd rtcmin=temp2 case 3 temp1=rtcdia gosub bcdabin rtcdia=temp2 if porta.1=0 then if rtcdia>1 then rtcdia=rtcdia-1 'dia' else if rtcdia<31 then rtcdia=rtcdia+1 'dia' endif temp1=rtcdia gosub binabcd rtcdia=temp2 case 4 temp1=rtcmes gosub bcdabin rtcmes=temp2 if porta.1=0 then if rtcmes>1 then rtcmes=rtcmes-1 'mes' else if rtcmes<12 then rtcmes=rtcmes+1 'mes' endif temp1=rtcmes gosub binabcd rtcmes=temp2 case 5 temp1=rtcano gosub bcdabin rtcano=temp2 if porta.1=0 then if rtcano>0 then rtcano=rtcano-1 'año' else if rtcano<99 then rtcano=rtcano+1 'año' endif temp1=rtcano gosub binabcd rtcano=temp2 end select i2cwrite rtc_sda,rtc_scl,$d0,$00,[$00,rtcmin,rtchor,$2,rtcdia,rtcmes,rtcano,$90] endif i2cread rtc_sda,rtc_scl,$d1,$00,[rtcseg,rtcmin,rtchor,rtcsem,rtcdia,rtcmes,rtcano,rtccon] lcdout $fe,1 lcdout "Hora:",hex2 rtchor,":",hex2 rtcmin,":",hex2 rtcseg," ",#param lcdout $fe,$c0 lcdout "Fecha:",hex2 rtcdia,"-",hex2 rtcmes,"-20",hex2 rtcano pause 100 goto loop bcdabin: temp2=((temp1>>4)&$0f)*10+(temp1&$0f) return binabcd: temp2=temp1 dig 1 temp2=temp2<<4 temp2=temp2+temp1 dig 0 return MoonBlack |
||
| comentario del autor | Mie Dic 19, 2007 3:26 pm | |
|
Veré como puedo seguir revisando y comparando a ver si encuentro errores en mi código. Gracias nuevamente.... |
||
| sin valorar | Mie Dic 19, 2007 4:43 pm | |
|
Moonblack |
||