Ir ao conteúdo

Intrudera6

Membro Pleno
  • Posts

    451
  • Cadastrado em

  • Última visita

Tópicos solucionados

  1. O post de Intrudera6 em relógio programável com uso do PIC16F877A foi marcado como solução   
    Aqui vai o programa em Bascom, no qual eu uso 2 teclas num RTC DS3231 (mesma biblioteca do DS1307 mas uso algumas funções próprias a mais para ter mais controle), mas tem um tempo enorme que não programo em Bascom e não lembro mais direito como funciona! Mas neste caso o Paulo tem toda condição de te ajudar, ele é o rei do Bascom!
     
    $regfile = "m328pdef.dat" ' specify the used micro $crystal = 16000000 ' Frequência do Cristal em Hz $loadersize = &H800 ' Bootloader de 2048 bytes $baud = 19200 ' use baud rate $hwstack = 64 ' default use 32 for the hardware stack $swstack = 40 ' default use 10 for the SW stack $framesize = 160 ' default use 40 for the frame space $initmicro Const Valor_prescale = 256 Const Interrupcoes_por_segundo = 100 Const Tempo_aguardando = Interrupcoes_por_segundo * 2 ' Tempo em segundos Const Preload = 65535 - _xtal \(valor_prescale * Interrupcoes_por_segundo) + 1 Const T_acerta_segundos = 60 * 10 ' intervalo de tempo em segundos para acertar o relógio pelo RTC Const T_acerta = Interrupcoes_por_segundo * T_acerta_segundos 'address of Ds3231 Const Ds3231w = &HD0 ' Endereço de escrita do RTC Ds3231 Const Ds3231r = &HD1 ' Endereço de leitura do RTC Ds3231 'configure the scl and sda pins Config Sda = Portc.4 Config Scl = Portc.5 Config I2cdelay = 2 ' para 500 kHz (aproximadamente) Config Lcdpin = Pin , Db4 = Portd.4 , Db5 = Portd.5 , Db6 = Portd.6 , Db7 = Portd.7 , E = Portc.1 , Rs = Portc.2 Config Lcd = 16 * 2 ' Configurando o LCD Config Pinb.0 = Input ' Configura porta B0 para entrada Config Pinb.1 = Input ' Configura porta B1 para entrada Set Pinb.0 ' Liga resistência interna do AVR (valor é forçado a 1 se não está apertado) Set Pinb.1 ' Liga resistência interna do AVR (valor é forçado a 1 se não está apertado) S2 Alias Pinb.0 ' Define que porta B0 é S2 S1 Alias Pinb.1 ' Define que porta B1 é S1 Buzzer: Config Portd.3 = Output ' Define porta D3 para saída (Buzzer) Buzzer Alias Portd.3 ' Define que porta D3 é Buzzer Config Clock = User ' we use I2C for the clock Config Date = Dmy , Separator = / Timer1_label: Config Timer1 = Timer , Prescale = Valor_prescale ' Valores possíveis para Prescale => 1|8|64|256|1024 On Timer1 Tim1_isr ' Executa rotina Tim1_usr nas interrupções do Timer1 Timer1 = Preload Enable Timer1 Timer0_label: ' usando para sincronismo do buzzer Const Const_timer0 = 193 Config Timer0 = Timer , Prescale = 64 On Timer0 Tim0_isr Timer0 = Const_timer0 Enable Interrupts ' As interrupções são habilitadas ' Fornece o número máximo de dias do mês na variável Global NDias Declare Sub Diasmes(ano_ent As Word , Mes_ent As Byte ) ' Formata a saída com dois dígitos e separador retornando na variável Entrada_Texto Declare Sub Formata(entrada As Byte , Entrada_texto As String * 8 , Complemento As String * 1) Dim Cont As Dword , Cont_ant As Dword Dim Contador As Dword , Contador2 As Dword , Contador_ant As Dword Dim Var1dword As Dword , Var2dword As Dword Dim Var1word As Word , Var2word As Word Dim Var1byte As Byte , Var2byte As Byte Dim Posicao As Byte , Buzzer_aux As Word Dim Acerta As Bit , S1_apertado As Bit , S2_apertado As Bit , Bissexto As Bit Dim Status_teclas As Bit , S1_aux As Bit , S2_aux As Bit , Mostra As Bit Dim Centesimo As Byte , Segundo As Byte , Minuto As Byte , Hora As Byte Dim Dia As Byte , Mes As Byte , Ano As Word , Ano2 As Word , Anoaux As Byte Dim Ndias As Byte Dim Laco As Bit , Buzzer_up As Bit Dim Linha1 As String * 8 , Linha2 As String * 8 , Aux As String * 1 'dim the used variables Dim Lvar1 As Long , Mday As Byte , Bweekday As Byte , Strweekday As String * 10 Dim Strdate As String * 8 , Strtime As String * 8 Dim Bsec As Byte , Bmin As Byte , Bhour As Byte Dim Bday As Byte , Bmonth As Byte , Byear As Byte Dim Lsecofday As Long , Wsysday As Word , Lsyssec As Long , Wdayofyear As Word Dim Temperatura As Single , Temp_msb As Byte , Temp_lsb As Byte Dim Sec_alarme1 As Byte , Min_alarme1 As Byte , Hour_alarme1 As Byte Dim Weekday_alarme1 As Byte , Day_alarme1 As Byte Dim Min_alarme2 As Byte , Hour_alarme2 As Byte Dim Weekday_alarme2 As Byte , Day_alarme2 As Byte Dim Ds3231_control As Byte , Ds3231_control_status As Byte , Ds3231_aging_offset As Byte Contador = 0 Cont = 0 Centesimo = 00 Segundo = 00 Minuto = 30 Hora = 12 Dia = 01 Mes = 01 Ano = 2012 Gosub Pega_hora_rtc Call Diasmes(ano , Mes) Cont_ant = 1 ' força que mostre no LCD Cls Set S1_apertado ' = 1 se o botão esquerdo não foi apertado Set S2_apertado ' = 1 se o botão direito não foi apertado Posicao = 0 Reset Acerta ' = 0 se não está em modo de edição Reset Mostra ' = 1 mostra Temperatura (se o RTC está conectado). Reset Buzzer Reset Buzzer_up Buzzer_aux = 0 Do S1_aux = S1 S2_aux = S2 If S2_aux = 0 Then 'If Buzzer_aux <= 200 Then ' 1/10 de segundo 'If Buzzer_up = 0 Then 'Set Buzzer 'Waitus 125 'Else 'Reset Buzzer 'Waitus 125 'Incr Buzzer_aux 'End If 'Buzzer_up = Not Buzzer_up 'End If If S2_apertado = 1 Then Buzzer_aux = 0 Timer0 = Const_timer0 Enable Timer0 End If 'Set Buzzer 'Waitus 125 'Reset Buzzer 'Waitus 125 Else Disable Timer0 Reset Buzzer Reset Buzzer_up 'Buzzer_aux = 0 End If If S1_aux = 1 And S1_apertado = 1 Then Status_teclas = 0 If Acerta = 0 And S2_aux = 0 Then ' se S2 (botão direito) está apertado mostra Temperatura ou não mostra (permuta) Reset Status_teclas If S2_apertado = 1 Then Reset S2_apertado Mostra = Not Mostra End If Else If Acerta = 0 And S2_apertado = 0 And S2_aux = 1 Then Set S2_apertado End If If Acerta = 0 And S1_aux = 0 Then ' Botão da esquerda (S1=0) apertado entra em modo de edição (Acerta => 1) Reset S1_apertado If Status_teclas < 1 Then Set Status_teclas Contador_ant = Contador ' Começa a contar o tempo até 2 segundos Else Var1dword = Contador - Contador_ant If Var1dword >= Tempo_aguardando Then ' Até ser maior ou igual a 2 segundos Posicao = 1 End If End If Else If Acerta = 0 And Posicao = 1 And S1_aux = 1 Then Set Acerta Set S1_apertado Reset Status_teclas Else If S1_aux = 0 And S2_aux = 1 Then ' Botão da esquerda (S1=0) apertado e Botão da direita (S2=1) não apertado If S1_apertado = 1 Then Reset S1_apertado If Posicao < 6 Then Incr Posicao Else Posicao = 0 Reset Acerta Reset Status_teclas End If End If Elseif S1_aux = 1 And S1_apertado = 0 Then Set S1_apertado End If End If End If End If If Posicao > 0 And Posicao <= 6 Then ' colocar o cursor piscando na posição de edição If Posicao < 4 Then Var1byte = Posicao - 1 Var1byte = Var1byte * 3 Var1byte = Var1byte + 1 Locate 1 , Var1byte ' Linha 1 do LCD Else Var1byte = 6 - Posicao Var1byte = Var1byte * 3 Var1byte = Var1byte + 1 Locate 2 , Var1byte ' Linha 2 do LCD End If Cursor On Blink Else Posicao = 0 Reset Acerta Cursor Off Blink End If Acerta_hora: If S1_aux = 1 Then ' Botão da esquerda (S1=1) não apertado If Posicao > 0 And Acerta = 1 Then If S2_aux = 0 And S2_apertado = 1 Then ' Botão da direita (S2=0) apertado Reset S2_apertado Select Case Posicao Case 1 : If Hora < 23 Then Incr Hora Else Hora = 0 End If Gosub Settime_aux Gosub Mostrahora Case 2 : If Minuto < 59 Then Incr Minuto Else Minuto = 0 End If Gosub Settime_aux Gosub Mostrahora Case 3 : If Segundo >= 30 Then If Minuto < 59 Then Incr Minuto Else Minuto = 0 End If End If Timer1 = Preload Centesimo = 0 Segundo = 0 Gosub Settime_aux Gosub Mostrahora Case 4 To 5 : If Posicao = 4 Then Var1word = Ano Mod 100 If Var1word < 99 Then Incr Ano Else Ano = Ano - Var1word End If Else If Mes < 12 Then Incr Mes Else Mes = 1 End If End If Call Diasmes(ano , Mes) If Dia > Ndias Then Dia = Ndias Gosub Setdate_aux Gosub Mostradata Case 6 : If Dia < Ndias Then Incr Dia Else Dia = 1 End If Gosub Setdate_aux Gosub Mostradata End Select Cont_ant = 0 Elseif S2_aux = 1 And S2_apertado = 0 Then ' Botão da direita (S2=1) não apertado Set S2_apertado End If Elseif S1_apertado = 0 Then Set S1_apertado End If End If Mostra_no_lcd: Dim Segundos_dia As Dword Dim Segundos_dia_ant As Dword Gosub Getdatetime Segundos_dia = Secofday() If Cont_ant <> Cont And Err > 0 Or Err = 0 And Segundos_dia <> Segundos_dia_ant Then If Err = 0 Then Segundos_dia_ant = Segundos_dia End If Cont_ant = Cont If Contador > Contador2 Then Contador2 = Contador + T_acerta ' tempo em segundos para acertar o relogio automaticamente pelo RTC Gosub Pega_hora_rtc ' acerta o relógio interno pelo RTC End If Gosub Mostrahora Gosub Mostradata End If Loop End 'end program _init_micro: Set Ddrc.3 Reset Portc.3 'LCD: R/W low Return ' Fornece o número máximo de dias do mês na variável NDias Sub Diasmes(ano_ent As Word , Mes_ent As Byte ) Local Div4 As Word Div4 = Ano_ent And 3 ' equivalente a Mod 4, e se é maior que 0 não é divisível If Div4 > 0 Then Reset Bissexto Else Set Bissexto Var2word = Ano_ent Mod 400 ' se é maior que 0 não é divisível Var1word = Ano_ent Mod 100 ' se é maior que 0 não é divisível If Var1word = 0 And Var2word > 0 Then Reset Bissexto End If End If If Mes_ent = 2 Then Ndias = 28 + Bissexto Else Var1byte = Mes_ent And &B00001001 If Var1byte = &B00001000 Or Var1byte = &B00000001 Then Ndias = 31 Else Ndias = 30 End If End If End Sub ' ============================================================================== ' Formata a saída com dois dígitos e separador retornando na variável Entrada_Texto Sub Formata(entrada As Byte , Entrada_texto As String * 8 , Complemento As String * 1) If Entrada < 10 Then Entrada_texto = Entrada_texto + "0" End If Entrada_texto = Entrada_texto + Str(entrada) Entrada_texto = Entrada_texto + Complemento End Sub ' ============================================================================== 'only when we use I2C for the clock we need to set the clock date time 'called from datetime.lib Dim Weekday As Byte Getdatetime: I2cstart ' Generate start code I2cwbyte Ds3231w ' Enviando endereço de escrita no Ds3231 I2cwbyte 0 ' Endereço no Ds3231 I2cstart ' Generate start code I2cwbyte Ds3231r ' Enviando endereço de leitura no Ds3231 I2crbyte _sec , Ack I2crbyte _min , Ack ' MINUTES I2crbyte _hour , Ack ' Hours I2crbyte Weekday , Ack ' Day of Week I2crbyte _day , Ack ' Day of Month I2crbyte _month , Ack ' Month of Year I2crbyte _year , Nack ' Year I2cstop If Err = 0 Then ' Err = 0 => não houve erro na leitura no relógio RTC via i2c _sec = Makedec(_sec) : _min = Makedec(_min) : _hour = Makedec(_hour) _day = Makedec(_day) : _month = Makedec(_month) : _year = Makedec(_year) Else ' ou usando o relógio via Timer1 _sec = Segundo : _min = Minuto : _hour = Hora _day = Dia : _month = Mes : Var2word = Ano Mod 100 : _year = Var2word End If Return Weekdays: Data "Segunda" , "Terça" , "Quarta" , "Quinta" , "Sexta" , "Sábado" , "Domingo" Setdate: _day = Makebcd(_day) : _month = Makebcd(_month) : _year = Makebcd(_year) I2cstart ' Generate start code I2cwbyte Ds3231w ' Enviando endereço de escrita no Ds3231 I2cwbyte 4 ' Endereço no Ds3231 I2cwbyte _day ' Send Data to dia I2cwbyte _month ' Month I2cwbyte _year ' Yesr I2cstop Return Setdate_aux: Var1word = Ano Mod 100 _year = Var1word _month = Mes _day = Dia Gosub Setdate Return Settime: _sec = Makebcd(_sec) : _min = Makebcd(_min) : _hour = Makebcd(_hour) I2cstart ' Generate start code I2cwbyte Ds3231w ' Enviando endereço de escrita no Ds3231 I2cwbyte 0 ' Endereço no Ds3231 I2cwbyte _sec ' Send Data to SECONDS I2cwbyte _min ' MINUTES I2cwbyte _hour ' Hours I2cstop Return Settime_aux: _hour = Hora _min = Minuto _sec = Segundo Gosub Settime Return Getalarme1: I2cstart ' Generate start code I2cwbyte Ds3231w ' Enviando endereço de escrita no Ds3231 I2cwbyte &H07 ' Endereço Alarme1 no Ds3231 I2cstart ' Generate start code I2cwbyte Ds3231r ' Enviando endereço de leitura no Ds3231 I2crbyte Sec_alarme1 , Ack ' Segundos Alarme1 I2crbyte Min_alarme1 , Ack ' Minutos Alarme1 I2crbyte Hour_alarme1 , Ack ' Horas Alarme1 I2crbyte Weekday_alarme1 , Ack ' Dia da Semana Alarme1 I2crbyte Day_alarme1 , Nack I2cstop If Err = 0 Then ' Err = 0 => não houve erro na leitura no relógio RTC via i2c Sec_alarme1 = Makedec(sec_alarme1) : Min_alarme1 = Makedec(min_alarme1) ' Dia do Mês Alarme1 Hour_alarme1 = Makedec(hour_alarme1) : Day_alarme1 = Makedec(day_alarme1) End If Return Setalarme1: Sec_alarme1 = Makebcd(sec_alarme1) : Min_alarme1 = Makebcd(min_alarme1) Hour_alarme1 = Makebcd(hour_alarme1) : Day_alarme1 = Makebcd(day_alarme1) I2cstart ' Generate start code I2cwbyte Ds3231w ' Enviando endereço de escrita no Ds3231 I2cwbyte &H07 ' Endereço Alarme1 no Ds3231 I2cwbyte Sec_alarme1 ' Send Data to SECONDS I2cwbyte Min_alarme1 ' MINUTES I2cwbyte Hour_alarme1 ' Hours I2cwbyte Weekday_alarme1 I2cwbyte Day_alarme1 I2cstop Return Getalarme2: I2cstart ' Generate start code I2cwbyte Ds3231w ' Enviando endereço de escrita no Ds3231 I2cwbyte &H0B ' Endereço Alarme2 no Ds3231 I2crbyte Min_alarme2 , Ack ' Minutos Alarme2 I2crbyte Hour_alarme2 , Ack ' Horas Alarme2 I2crbyte Weekday_alarme2 , Ack ' Dia da Semana Alarme2 I2crbyte Day_alarme2 , Nack ' Dia do Mês Alarme2 I2cstop If Err = 0 Then ' Err = 0 => não houve erro na leitura no relógio RTC via i2c Min_alarme2 = Makedec(min_alarme2) : Hour_alarme2 = Makedec(hour_alarme2) Day_alarme2 = Makedec(day_alarme2) End If Return Setalarme2: Min_alarme2 = Makebcd(min_alarme2) : Hour_alarme2 = Makebcd(hour_alarme2) Day_alarme2 = Makebcd(day_alarme2) I2cstart ' Generate start code I2cwbyte Ds3231w ' Enviando endereço de escrita no Ds3231 I2cwbyte &H0B ' Endereço Alarme2 no Ds3231 I2cwbyte Min_alarme2 ' MINUTES I2cwbyte Hour_alarme2 ' Hours I2cwbyte Weekday_alarme2 I2cwbyte Day_alarme2 I2cstop Return Gettemp: I2cstart ' Generate start code I2cwbyte Ds3231w ' Enviando endereço de escrita no Ds3231 I2cwbyte &H11 ' Endereço Temperatura no Ds3231 I2cstart ' Generate start code I2cwbyte Ds3231r ' Enviando endereço de leitura no Ds3231 I2crbyte Temp_msb , Ack I2crbyte Temp_lsb , Nack I2cstop If Err = 0 Then ' Err = 0 => não houve erro na leitura no relógio RTC via i2c Rotate Temp_lsb , Right , 6 Temperatura = Temp_lsb / 4 Temperatura = Temperatura + Temp_msb End If Return Getstatus: I2cstart ' Generate start code I2cwbyte Ds3231w ' Enviando endereço de escrita no Ds3231 I2cwbyte &H0E ' Endereço do Status no Ds3231 I2cstart ' Generate start code I2cwbyte Ds3231r ' Enviando endereço de leitura no Ds3231 I2crbyte Ds3231_control , Ack I2crbyte Ds3231_control_status , Ack I2crbyte Ds3231_aging_offset , Nack I2cstop Return Pega_hora_rtc: Reset Laco Do Gosub Getdatetime ' Pega a Data e Hora do RTC If Err > 0 Then ' se o RTC não está conectado pula e usa os valores padrão Exit Do End If If _sec <> Segundo And Laco = 1 Then Segundo = _sec : Centesimo = 0 : Minuto = _min : Hora = _hour Dia = _day : Mes = _month : Ano = _year + 2000 Exit Do Else Laco = Not Laco End If Loop Return Mostrahora: 'Home 'Lowerline Locate 1 , 1 If Err = 0 Then Lcd Time$ Else Linha1 = "" Aux = ":" Call Formata(hora , Linha1 , Aux) Call Formata(minuto , Linha1 , Aux) Aux = "" Call Formata(segundo , Linha1 , Aux) Lcd Linha1 ' usando o RTC Ds3231 ou o relógio vai Timer1 End If Return Mostradata: 'Lowerline Locate 2 , 1 If Err = 0 And Mostra = 1 Then Gosub Gettemp End If If Acerta = 0 And Mostra = 1 And Err = 0 Then 'Lcd Str(temperatura) ; " C" ; " " Lcd Fusing(temperatura , "##.##") ; Chr(223) ; "C " Else If Err = 0 Then Lcd Date$ Else Ano2 = Ano Mod 100 Anoaux = Ano2 Linha2 = "" Aux = "/" Call Formata(dia , Linha2 , Aux) Call Formata(mes , Linha2 , Aux) Aux = "" Call Formata(anoaux , Linha2 , Aux) Lcd Linha2 End If End If Return '------------------------------------------------------------------ ' Sub-rotina de timer0, chamada para gerar tons no Buzzer ' Tim0_isr: Timer0 = Const_timer0 If Buzzer_aux <= 200 Then If Buzzer_up = 0 Then Set Buzzer Set Buzzer_up Else Reset Buzzer Reset Buzzer_up Incr Buzzer_aux End If Else Disable Timer0 End If Return '------------------------------------------------------------------ ' Sub-rotina de timer1, chamada 1 vez por segundo ou mais, dependendo da Constante Interrupções_por_segundo ' Tim1_isr: Timer1 = Preload Incr Contador If Centesimo < 99 Then Incr Centesimo Else Centesimo = 0 If Segundo < 59 Then Incr Segundo Else Segundo = 0 If Minuto < 59 Then Incr Minuto Else Minuto = 0 If Hora < 23 Then Incr Hora Else Hora = 0 If Dia < Ndias Then Incr Dia Else Dia = 1 If Mes < 12 Then Incr Mes Else Mes = 1 Incr Ano End If Call Diasmes(ano , Mes) End If End If End If End If Incr Cont End If Return '------------------------------------------------------------------  

Sobre o Clube do Hardware

No ar desde 1996, o Clube do Hardware é uma das maiores, mais antigas e mais respeitadas comunidades sobre tecnologia do Brasil. Leia mais

Direitos autorais

Não permitimos a cópia ou reprodução do conteúdo do nosso site, fórum, newsletters e redes sociais, mesmo citando-se a fonte. Leia mais

×
×
  • Criar novo...

LANÇAMENTO!

eletronica2025-popup.jpg


CLIQUE AQUI E BAIXE AGORA MESMO!