Ir ao conteúdo
  • Cadastre-se

AlyssonMachado

Membro Júnior
  • Posts

    14
  • Cadastrado em

  • Última visita

Reputação

0
  1. Olá Diego, o código que postei anteriormente usando pic16F877a funcionou aqui. Qual problema está tendo? qual suar versão do CCS? poste aqui o seu código pra eu dar uma olhada e testar aqui. To sem CCS no momento, troquei de pc e ainda não arrumei tudo. Assim que tiver posto um outro fonte aqui.
  2. Olá Diego, como pedido corrigi o driver do DS1307 . Segue abaixo o driver: OBS: No código possui umas linhas comentadas ( //delay_us(3) ). Se depois de montado o projeto as vezes der erro de transmissão de dado descomente estas linhas. ERRO que havia no arquivo: funções: void ds1307_get_date(BYTE *dia, BYTE *mes, BYTE *ano, BYTE *dow) void ds1307_get_time(BYTE *hora, BYTE *mim, BYTE *seg) Estavam com os parametro errados ( o erro era compilável ). Como as funções passam os valores por referencia deve ser enviado o endereço da variavel para um ponteiro ( &_mes -> *mes ) e estava enviando endereço para endereço ( &_mes -> &mes ) o que é erro do programador. Concertado isso funcionou perfeitamente. libDS1307.c //////////////////////////////////////////////////////////////////////////////// /// DS1307.C /// /// Driver for Real Time Clock /// /// /// /// ds1307_init() - Enable oscillator without clearing the seconds register -/// /// used when PIC loses power and DS1307 run from 3V BAT /// /// - Disable squarewave output /// /// /// /// ds1307_set_date_time(dia,mes,ano,dow,hora,mim,seg) Set the date/time /// /// /// /// ds1307_get_date(dia,mes,ano,dow) Obter data /// /// /// /// ds1307_get_time(hora,mim,seg) Obter tempo /// /// /// //////////////////////////////////////////////////////////////////////////////// #define RTC_SDA PIN_C4 #define RTC_SCL PIN_C3 #use i2c(master, sda=RTC_SDA, scl=RTC_SCL) BYTE seg; BYTE mim; BYTE hora; BYTE dow; BYTE dia; BYTE mes; BYTE ano; BYTE bin2bcd(BYTE binary_value); BYTE bcd2bin(BYTE bcd_value); void ds1307_init(void) { BYTE segundos = 0; i2c_start(); i2c_write(0xD0); // WR to RTC //delay_us(3); i2c_write(0x00); // REG 0 //delay_us(3); i2c_stop(); //delay_us(3); i2c_start(); i2c_write(0xD1); // RD from RTC //delay_us(3); segundos = bcd2bin(i2c_read(0)); // Read current "seconds" in DS1307 delay_us(3); i2c_stop(); segundos &= 0x7F; delay_us(3); i2c_start(); i2c_write(0xD0); // WR to RTC //delay_us(3); i2c_write(0x00); // REG 0 //delay_us(3); i2c_write(bin2bcd(segundos)); // Start oscillator with current "seconds value //delay_us(3); i2c_stop(); i2c_start(); i2c_write(0xD0); // WR to RTC //delay_us(3); i2c_write(0x07); // Control Register //delay_us(3); i2c_write(0x80); // Disable squarewave output pin //delay_us(3); i2c_stop(); } void ds1307_set_date_time(BYTE dia, BYTE mes, BYTE ano, BYTE dow, BYTE hora, BYTE mim, BYTE seg) { seg &= 0x7F; hora &= 0x3F; i2c_start(); i2c_write(0xD0); // I2C write address i2c_write(0x00); // Start at REG 0 - Seconds i2c_write(bin2bcd(seg)); // REG 0 i2c_write(bin2bcd(mim)); // REG 1 i2c_write(bin2bcd(hora)); // REG 2 i2c_write(bin2bcd(dow)); // REG 3 i2c_write(bin2bcd(dia)); // REG 4 i2c_write(bin2bcd(mes)); // REG 5 i2c_write(bin2bcd(ano)); // REG 6 i2c_write(0x80); // REG 7 - Disable squarewave output pin i2c_stop(); } void ds1307_get_date(BYTE *dia, BYTE *mes, BYTE *ano, BYTE *dow) { i2c_start(); i2c_write(0xD0); i2c_write(0x03); // Start at REG 3 - Day of week i2c_start(); i2c_write(0xD1); *dow = bcd2bin(i2c_read() & 0x7f); // REG 3 *dia = bcd2bin(i2c_read() & 0x3f); // REG 4 *mes = bcd2bin(i2c_read() & 0x1f); // REG 5 *ano = bcd2bin(i2c_read(0)); // REG 6 i2c_stop(); } void ds1307_get_time(BYTE *hora, BYTE *mim, BYTE *seg) { i2c_start(); i2c_write(0xD0); i2c_write(0x00); // Start at REG 0 - Seconds i2c_start(); i2c_write(0xD1); *seg = bcd2bin(i2c_read() & 0x7f); *mim = bcd2bin(i2c_read() & 0x7f); *hora = bcd2bin(i2c_read(0) & 0x3f); i2c_stop(); } BYTE bin2bcd(BYTE binary_value) { BYTE temp; BYTE retval; temp = binary_value; retval = 0; while(1) { // Get the tens digit by doing multiple subtraction // of 10 from the binary value. if(temp >= 10) { temp -= 10; retval += 0x10; } else // Get the ones digit by adding the remainder. { retval += temp; break; } } return(retval); } // Input range - 00 to 99. BYTE bcd2bin(BYTE bcd_value) { BYTE temp; temp = bcd_value; // Shifting upper digit right by 1 is same as multiplying by 8. temp >>= 1; // Isolate the bits for the upper digit. temp &= 0x78; // Now return: (Tens * 8) + (Tens * 2) + Ones return(temp + (temp >> 2) + (bcd_value & 0x0f)); } Veja o funcionamento na imagem ( simulado no proteus ISIS 7.0 ) Abaixo um código exemplo do uso da biblioteca com PIC 16F877A OBS : esse código usa a biblioteca lcd_flex.c ( fornecida por mim neste tópico ) #include<16f877.h> #use delay(clock=4000000) #use rs232(baud=9600,xmit=pin_c6,rcv=pin_c7) #fuses XT,NOWDT,PUT,NOBROWNOUT #include<input.c> #include<string.h> #include<stdio.h> #include<libDS1307.c> #define LCD_DB4 PIN_B4 #define LCD_DB5 PIN_B5 #define LCD_DB6 PIN_B6 #define LCD_DB7 PIN_B7 #define LCD_RS PIN_B2 #define LCD_E PIN_B3 #include<lcd_flex.c> #define BT_ajustaHora_e_mais pin_a0 //botao para entrar no ajuste de hora e dado++ #define BT_ajutaData_e_menos pin_a1 //botao para entrar no ajuste de data e dado-- #define BT_desloca_dir pin_a2 //desloca para direita #define BT_desloca_esq pin_a3 //desloca cursor para esquerda // [...] quantos botões a aplicação exigir #define ajuste_hora 1 #define ajuste_data 2 /* VAriaveis globais */ byte _dia,_mes,_ano,_dow,_hora,_min,_seg; //Variaveis que guardam os dados int op=0; // variavel que mostra qual botao foi prescionado /* Protótipo das funções */ void carrega_dados(); boolean debouce(); void trata_botoes(int op); /* Declaração das funções */ void carrega_dados() { ds1307_get_date(&_dia,&_mes,&_ano,&_dow); ds1307_get_time(&_hora,&_min,&_seg); } boolean debounce(void) { disable_interrupts(INT_TIMER1); //desabilita interrupção delay_ms(150); if((!input(BT_ajustaHora_e_mais ))|(!input( BT_ajutaData_e_menos))) { return true; } else return false; } void trata_botoes(int op) { switch(op) { case ajuste_hora: //[...] Aqui o usuario define os comando de ajuste de hora //printf("ajuste de hora\r") // linha para debug break; case ajuste_data: //[...] Aqui o usuario define os comando de ajuste de data //printf("ajuste de data\r") // linha para debug break; default: break; } } #INT_TIMER1 void atualiza_hora() { /******************************************************/ /* A interrupção é chamada a cada 1s e atualiza */ /* os dados adquiridos pelo DS1307 através do TIMER1 */ /******************************************************/ char dia_semana[7][4]={"dom","seg","ter","qua","qui","sex","sab"}; char dia_hoje[4]; set_timer1(3036-get_timer1()); ds1307_get_time(&_hora,&_min,&_seg); ds1307_get_date(&_dia,&_mes,&_ano,&_dow); strcpy(dia_hoje,dia_semana[_dow-1]); lcd_gotoxy(1,1); printf(lcd_putc,"%s - %02d/%02d/%02d",dia_hoje,_dia,_mes,_ano); lcd_gotoxy(5,2); printf(lcd_putc,"%02d:%02d:%02d ",_hora,_min,_seg); } void main() { /***************************************/ /* Configurações dos PORTS e TIMER1 e */ set_tris_b(0); set_tris_c(0b00011000); set_tris_e(1); set_tris_a(1); enable_interrupts(INT_TIMER1); setup_timer_1( T1_INTERNAL|T1_DIV_BY_8); set_timer1(3036); disable_interrupts(INT_TIMER0); enable_interrupts(GLOBAL); /**************************************/ //Inicializa o LCD e o DS1307 lcd_init(); delay_ms(1000); ds1307_init(); while(1) { /**************************************************************************/ /* Tratamento de botões /* Para o tratamento de botões pode usar as seguinte técnicas: /* >> Botoões no PORTB - trata interrupção de mundança de estado /* Vantagens: >Não é necessário scan em loop infinito /* sempre então o evento será tratado independente do tempo de prescionamento /* Desvantagens: /* >É preciso verificar qual botão foi prescionado /* para então trata-lo /* >Ruídos no PORTB podem causar mau funcionamento /* >> Scan dos butões /* Vantagens /* >Maior estabilidade contra ruídos /* >Cada botão pode ter sua própria função() /* Desvantagens /* >Tempo é crítico /* >Debounce necessita ter outras interrupções desativadas /* Neste programa será usado o scan /* Apenas um modelo como a implementação é trabalhosa não foi feita aqui /**************************************************************************/ if((!input(BT_ajustaHora_e_mais ))) { if(debounce()) { op = ajuste_hora; trata_botoes(op); } } else if((!input(BT_ajutaData_e_menos))) { if(debounce()) { op = ajuste_data; trata_botoes(op); } } enable_interrupts(INT_TIMER1); //após tratar os botões habilita interrupção } } Espero ter ajudado! Abraço!
  3. Grande Matheus! valeu aee pelo post, Muito bom colocar gráficos nas aplicações!! Espero em breve (talvez nem tanto ) poder compartilhar aqui tb com um projeto, vou iniciar nas férias, ligado a automação(faço Eng de controle e automação hehe). To pensado em criar um sistema de automação residencial bem interessante baseado em PIC´s e HOLTEK ( por ser bem baratos). Pretendo acrecentar comunicação wireless ( Zigbee ) e um sistema de segurança completo ( áudio, vídeo , envio de mensagens SMS para proprietário, envio de dados Via internet para quando o proprietario estiver viajando, integração com a PM para chamadas automáticas á polícia) além de climatização e criação de cenários pré-programados, gestão de gastos , sistema SCRN ( que apelidei de sistema de controle de recursos naturais, ou seja, captação de água da chuva, otimização do uso interno da luz solar, etc...). Enfim, projeto extenso, duro mas emocionante. Vai ser pro meu TCC, Falou e obrigado pelo código.
  4. Parabens Matheus pelo projeto! Sou de BH e "brinco" com PIC´s a algum tempo, porém comecei a mexer com USB tem pouco tempo. Primeira coisa que fiz foi estudar o protocolo (USB 2.0 Specification) daí comecei a entender melhor como tudo funciona! Fiz uns programas recentemente baseado em códigos disponíveis na net ( todos para C#), e estudando a linguagem to começando a criar minhas próprias variações. Achei um fonte bacana na NET pra HID ai dei umas modificadas e acrescentei um leitor de temperatura de um lm35 tb: Achei muito bacana sua interface, Como faz pra colocar gráficos? tem algum material que possa disponibilizar? meu email é [email protected] Podemos trocar bastante informação, sou aficionado do uC´s hehe falows
  5. Ta aí , o exemplo pra te dar uma clareada. ta grande porque resolvi postar completo, talvez ache algo que lhe seja útil. Estudando este código saberá trabalhar com a biblioteca que fiz, flwss OBS: a pinagem do LCD não está no padrão do driver CCS lcd.c! para testar você terá que mudar a pinagem. caso não consiga simular, posto depois a biblioteca lcd_flex.c que tenho que é mais fácil modificar os pinos do lcd( não precisar mexer com structs). #include<18F452.H> #use delay(clock=4000000) #fuses XT,NOWDT,LVP,PUT,NOBROWNOUT,NOSTVREN #use rs232(BAUD=9600, xmit=pin_c6, rcv=pin_c7) #define BT input(pin_c4) #define BT1 input(pin_c5) #define BT2 input(pin_c3) #define BT3 input(pin_c2) #define scl pin_d0 #define sda pin_d1 #include<I2C.c> #include<DS1307.c> #include<input.c> #include<lcd.c> #include<string.h> #include<stdio.h> int8 segundos,minutos,horas,data,mes,dia,ano,CH; int j=7; void carrega_alldata_rtc() { I2C_start(); I2C_escreve_byte(slave_ad_write); delay_us(3); I2C_le_ack(); I2C_escreve_byte(0x00); I2C_le_ack(); I2C_start(); I2C_escreve_byte(slave_ad_read); I2C_le_ack(); segundos=I2C_le_byte(); delay_us(2); I2C_ack(); minutos=I2C_le_byte(); delay_us(2); I2C_ack(); horas=I2C_le_byte(); delay_us(2); I2C_ack(); dia=I2C_le_byte(); delay_us(2); I2C_ack(); data=I2C_le_byte(); delay_us(2); I2C_ack(); mes=I2C_le_byte(); delay_us(2); I2C_ack(); ano=I2C_le_byte(); delay_us(2); I2C_nack(); I2C_stop(); } void converte_BCD_to_INT() { segundos=((segundos>>4)*10)+segundos%16; minutos=((minutos>>4)*10)+minutos%16; horas=((horas>>4)*10)+horas%16; data=((data>>4)*10)+data%16; mes=((mes>>4)*10)+mes%16; ano=((ano>>4)*10)+ano%16; } char dia_semana_converte(dia) //lê o dia da semana { char dia_semana[7][4]={"dom","seg","ter","qua","qui","sex","sab"}; char dia_hoje[4]; switch(dia) { case 1: strcpy(dia_hoje,dia_semana[dia-1]); return (dia_hoje); break; case 2: strcpy(dia_hoje,dia_semana[dia-1]); return (dia_hoje); break; case 3: strcpy(dia_hoje,dia_semana[dia-1]); return (dia_hoje); break; case 4: strcpy(dia_hoje,dia_semana[dia-1]); return (dia_hoje); break; case 5: strcpy(dia_hoje,dia_semana[dia-1]); return (dia_hoje); break; case 6: strcpy(dia_hoje,dia_semana[dia-1]); return (dia_hoje); break; case 7: strcpy(dia_hoje,dia_semana[dia-1]); return (dia_hoje); break; default: break; } } #INT_TIMER1 void atualiza_lcd() //Manda para o LCD os dados do RTC { set_timer1(3036-get_timer1()); carrega_alldata_rtc(); converte_BCD_to_INT(); if(segundos>79) segundos-=80; lcd_gotoxy(1,1); printf(lcd_putc,"%s - %02.0u/%02.0u/%02.0u",dia_semana_converte(dia),data,mes,ano); lcd_gotoxy(6,2); printf(lcd_putc,"%02.0u:%02.0u:%02.0u",horas,minutos,segundos); } void ajuste_horas() //função para o ajuste de horas { while(BT) { lcd_gotoxy(j,2); lcd_setcursor(1,0); if(!BT1) { delay_ms(300); j+=3; if(j>13) j=7; } if((j==7)&&(!BT2)) { delay_ms(300); horas-=1; if(horas==-1) horas=23; lcd_setcursor(0,0); lcd_gotoxy(6,2); printf(lcd_putc,"%02.0u",horas); } else if((j==10)&&(!BT2)) { delay_ms(300); minutos-=1; if(minutos==-1) minutos=59; lcd_setcursor(0,0); lcd_gotoxy(9,2); printf(lcd_putc,"%02.0u",minutos); } else if((j==13)&&(!BT2)) { delay_ms(300); segundos-=1; if(segundos==-1) segundos=59; lcd_setcursor(0,0); lcd_gotoxy(12,2); printf(lcd_putc,"%02.0u",segundos); } if((j==7)&&(!BT3)) { delay_ms(300); horas+=1; if(horas==24) horas=0; lcd_setcursor(0,0); lcd_gotoxy(6,2); printf(lcd_putc,"%02.0u",horas); } else if((j==10)&&(!BT3)) { delay_ms(300); minutos+=1; if(minutos==60) minutos=0; lcd_setcursor(0,0); lcd_gotoxy(9,2); printf(lcd_putc,"%02.0u",minutos); } else if((j==13)&&(!BT3)) { delay_ms(300); segundos+=1; if(segundos==60) segundos=0; lcd_setcursor(0,0); lcd_gotoxy(12,2); printf(lcd_putc,"%02.0u",segundos); } } lcd_setcursor(0,0); data_escreve_rtc(0x00,segundos); data_escreve_rtc(0x01,minutos); data_escreve_rtc(0x02,horas); } void ajuste_data() //função para o ajuste de data { while(BT) { lcd_gotoxy(j,2); lcd_setcursor(1,0); if(!BT1) { delay_ms(300); j+=3; if(j>13) j=7; } if((j==7)&&(!BT2)) { delay_ms(300); data-=1; if(data==0) data=31; lcd_setcursor(0,0); lcd_gotoxy(6,2); printf(lcd_putc,"%02.0u",data); } else if((j==10)&&(!BT2)) { delay_ms(300); mes-=1; if(mes==0) mes=12; lcd_setcursor(0,0); lcd_gotoxy(9,2); printf(lcd_putc,"%02.0u",mes); } else if((j==13)&&(!BT2)) { delay_ms(300); ano-=1; if(ano==-1) ano=99; lcd_setcursor(0,0); lcd_gotoxy(12,2); printf(lcd_putc,"%02.0u",ano); } if((j==7)&&(!BT3)) { delay_ms(300); data+=1; if(data==32) data=1; lcd_setcursor(0,0); lcd_gotoxy(6,2); printf(lcd_putc,"%02.0u",data); } else if((j==10)&&(!BT3)) { delay_ms(300); mes+=1; if(mes==13) mes=1; lcd_setcursor(0,0); lcd_gotoxy(9,2); printf(lcd_putc,"%02.0u",mes); } else if((j==13)&&(!BT3)) { delay_ms(300); ano+=1; if(ano==100) ano=1; lcd_setcursor(0,0); lcd_gotoxy(12,2); printf(lcd_putc,"%02.0u",ano); } } lcd_setcursor(0,0); data_escreve_rtc(0x04,data); data_escreve_rtc(0x05,mes); data_escreve_rtc(0x06,ano); } void ajuste_dia() { while(BT) { if(!BT2) { lcd_setcursor(0,0); delay_ms(300); dia-=1; if(dia==-1) dia=7; dia_semana_converte(dia); lcd_gotoxy(8,2); printf(lcd_putc,"%s",dia_semana_converte(dia)); } if(!BT3) { lcd_setcursor(0,0); delay_ms(300); dia+=1; if(dia==8) dia=1; dia_semana_converte(dia); lcd_gotoxy(8,2); printf(lcd_putc,"%s",dia_semana_converte(dia)); } } data_escreve_rtc(0x03,dia); } main() { set_tris_d(0); set_tris_b(0); set_tris_a(0b00111000); set_tris_c(0b00111111); output_d(0); setup_timer_1(T1_INTERNAL|T1_DIV_BY_8); set_timer1(3036); enable_interrupts(INT_TIMER1); enable_interrupts(GLOBAL); disable_interrupts(INT_TIMER0); setup_adc(ADC_OFF); setup_adc_ports(NO_ANALOGS); lcd_init(); //Este trecho apenas simula a primeira vez que o RTC é inicializado ******** //grava_alldata_rtc(80,0,0,1,1,1,0); CH=data_le_rtc(0x00); CH=(((CH/10)<<4)+(CH%10))>>7; segundos=0x50-(data_le_rtc(0x00)); segundos=segundos&0x00; printf("valor do registrador 0x00 = %d",segundos); printf("\rvalor do bit CH = %d",CH); if((CH==1)&&(segundos==0)) { disable_interrupts(INT_TIMER1); lcd_gotoxy(3,1); lcd_putc("\fAjuste de horas"); lcd_gotoxy(6,2); printf(lcd_putc,"%02.0u:%02.0u:%02.0u",horas,minutos,segundos); ajuste_horas(); delay_ms(300); lcd_gotoxy(3,1); lcd_putc("\fAjuste de data"); lcd_gotoxy(6,2); printf(lcd_putc,"%02.0u/%02.0u/%02.0u",data,mes,ano); ajuste_data(); delay_ms(300); lcd_gotoxy(3,1); lcd_putc("\fAjuste de dia"); lcd_gotoxy(8,2); printf(lcd_putc,"%s",dia_semana_converte(dia)); ajuste_dia(); data_escreve_rtc(0x00,0x00); //zera o bit CH do endereço dos segundos } //**************************************************************************** enable_interrupts(INT_TIMER1); lcd_putc('\f'); while(1) { if(!BT) { int cont_bt_pres,i; disable_interrupts(INT_TIMER1); delay_ms(100); if(!BT) { for(i=0;i<10;i++) { if(!BT) {cont_bt_pres++; lcd_putc('\f');} if(cont_bt_pres>3) cont_bt_pres=1; if(cont_bt_pres==1) { lcd_gotoxy(3,1); lcd_putc("Ajuste de horas"); lcd_gotoxy(6,2); printf(lcd_putc,"%02.0u:%02.0u:%02.0u",horas,minutos,segundos); } if(cont_bt_pres==2) { lcd_gotoxy(3,1); lcd_putc("Ajuste de data"); lcd_gotoxy(6,2); printf(lcd_putc,"%02.0u/%02.0u/%02.0u",data,mes,ano); } if(cont_bt_pres==3) { lcd_gotoxy(3,1); lcd_putc("Ajuste de dia"); lcd_gotoxy(8,2); printf(lcd_putc,"%s",dia_semana_converte(dia)); } delay_ms(200); } if(cont_bt_pres==1) ajuste_horas(); if(cont_bt_pres==2) ajuste_data(); if(cont_bt_pres==3) ajuste_dia(); cont_bt_pres=0; lcd_gotoxy(1,2); lcd_putc(" "); } enable_interrupts(INT_TIMER1); lcd_putc('\f'); } if(!BT3) { boolean estado; byte CH_bit,aux_seg; delay_ms(300); estado=!estado; if(estado==1) { desativa_clock_rtc(); printf("\rComando de clock do DS1307 desligado"); } else if(estado==0) { ativa_clock_rtc(); printf("\rComando de clock do DS1307 ligado"); } } if(!BT2) /*********************************/ /* |RS1|RS0|SQWE/out|SQWE|OUT| */ /* | 0 | 0 | 1Hz | 1 | X | */ /* | 0 | 1 |4096kHz | 1 | X | */ /* | 1 | 0 |8192kHz | 1 | X | */ /* | 1 | 1 |32768kHz | 1 | X | */ /* | X | X | 0 | 0 | 0 | */ /* | X | X | 1 | 0 | 1 | */ /*********************************/ { int estado2; delay_ms(300); estado2++; if(estado2==7) estado2=1; if(estado2==1) { seleciona_clockout_rtc(1,0,0,0); //SQW/OUT=1 } else if(estado2==2) { seleciona_clockout_rtc(0,0,0,0); //SQW/OUT=0 } else if(estado2==3) { seleciona_clockout_rtc(0,1,0,0); //SQW/OUT=1Hz } else if(estado2==4) { seleciona_clockout_rtc(0,1,0,1); //SQW/OUT=4096kHz } else if(estado2==5) { seleciona_clockout_rtc(0,1,1,0); //SQW/OUT=8192kHz } else if(estado2==6) { seleciona_clockout_rtc(0,1,1,1); //SQW/OUT=32768kHz } } } } Test man, obrigado cara!! so tava achando biblioteca ruim de mexer com o DS1307, ai peguei o datasheet e fui mandando ver uashausuash. É muuuuito melhor mexer com uma biblioteca que você saiba cada linha dela, fik mais fácil desenvolver o projeto. E tentei deixa-la bem simples de interptetar. Felipe_ZeRo, ta aqui a biblioteca do lcd, creio que te irá ser útil em muitos projetos. abraço! lcd_flex.c #define LCD_DB4 PIN_B4 // NIBLE de dados #define LCD_DB5 PIN_B5 #define LCD_DB6 PIN_B6 #define LCD_DB7 PIN_B7 #define LCD_RS PIN_B2 #define LCD_E PIN_B3 //#define USE_LCD_RW 1 #define lcd_type 2 // 0=5x7, 1=5x10, 2=2 lines #define lcd_line_two 0x40 // LCD RAM address for the 2nd line int8 const LCD_INIT_STRING[4] = { 0x20 | (lcd_type << 2), // Func set: 4-bit, 2 lines, 5x8 dots 0xc, // Display on 1, // Clear display 6 // Increment cursor }; void lcd_send_nibble(int8 nibble){ // Obs: !! converte uma exprecao inteira // para uma booleana (1 or 0). output_bit(LCD_DB4, !!(nibble & 1)); output_bit(LCD_DB5, !!(nibble & 2)); output_bit(LCD_DB6, !!(nibble & 4)); output_bit(LCD_DB7, !!(nibble & 8)); delay_cycles(1); output_high(LCD_E); delay_us(2); output_low(LCD_E); delay_us(2);//teste } // Envia um byte para o LCD. void lcd_send_byte(int8 address, int8 n){ output_low(LCD_RS); delay_us(60); if(address) output_high(LCD_RS); else output_low(LCD_RS); delay_cycles(1); output_low(LCD_E); lcd_send_nibble(n >> 4); delay_us(2); //teste lcd_send_nibble(n & 0xf); } void lcd_init(void){ int8 i; output_low(LCD_RS); output_low(LCD_E); delay_ms(15); for(i=0 ;i < 3; i++){ lcd_send_nibble(0x03); delay_ms(5); } lcd_send_nibble(0x02); for(i=0; i < sizeof(LCD_INIT_STRING); i++){ lcd_send_byte(0, LCD_INIT_STRING[i]); } delay_ms(15); } // posições válidas: // de x=1 a x=16 y // de y=1 a y=2 void lcd_gotoxy(int8 x, int8 y){ int8 address; if(x > 0 && y > 0){ if(y > 1) address = lcd_line_two; else address=0; address += x-1; lcd_send_byte(0, 0x80 | address); // Manda cursor a la posición } } void lcd_putc(char c){ if(c>'\0'){ switch(c){ case '\f': lcd_send_byte(0,1); lcd_send_byte(0,2); delay_ms(2); break; case '\n': lcd_gotoxy(1,2); delay_ms(2); break; case '\b': lcd_send_byte(0,0x10); delay_ms(2); break; case '\t': lcd_send_byte(0,0x14); delay_ms(2); break; default: lcd_send_byte(1,c); delay_ms(2); break; } } } void lcd_put_string(char *string){ //put string, inicia na posicao atucal do cursor //assume que a estring na exceda a ram mostradada do lcd char index=0; while(string[index]!=0){ lcd_putc(string[index++]); } } void lcd_put_string_xy(char *string, char x, char y){ //assume that string not excides from lcd displayed RAM lcd_gotoxy(x,y); lcd_put_string(string); } void lcd_setcursor(short visible, short blink) { lcd_send_byte(0, 0xC|(visible<<1)|blink); } /* ' LCD ' Command Operation ' *********** ***************************************** ' $FE, 1 Clear display ' $FE, 2 Return home ' $FE, $0C Cursor off ' $FE, $0E Underline cursor on ' $FE, $0F Blinking cursor on ' $FE, $10 Move cursor left one position ' $FE, $14 Move cursor right one position ' $FE, $80 Move cursor to beginning of first line ' $FE, $C0 Move cursor to beginning of second line ' *********** ***************************************** */ Oláa, esqueci de comenta!, Fiz com o PIC18F452 porque meu código tinha uma infinidade de funções e a ROM do 16F877A tava meio pequena pro projeto!, mas dependendo do seu ele é mais que suficiente! fiz mais uma função para a biblioteca DS1307.c, para fazer o controle do formato das horas (12h ou 24h). abraço.! boolean seleciona_modo_am(boolean modo) //seleciona o modo de exibição de horas AM/PM { boolean am_modo; if(modo==true) { hor=data_le_rtc(0x02); //Conversão 24H para AM switch(hor) { case 12: hor=72; //O registrador de endereço 0x02 contém os dados break; //da hora. Como ele é em BCD se quiser mandar o case 13: hor=61; //seguinte campo de bits: 01010011 break; //temos que mandar o valor 53 em BCD. case 14: hor=62; //o bit 6 quando setado muda o modo de horário para break; //12horas(AM/PM), e quando é 0 o modo é o de 24horas case 15: hor=63; //O bit 5 em nível 1 quando o bit6 está setado break; //indica PM e quando 0 AM. case 16: hor=64; //Os demais bits são para o horário break; //Portanto para que selecionemos 02horas AM temos case 17: hor=65; // que mandar o valor 42 em BCD pois assim teremos break; //01000010, setando o bit6 indicamos que é formato case 18: hor=66; //12horas e zerando o bit5 indicamos que é AM 02horas break; case 19: hor=67; break; case 20: hor=68; break; case 21: hor=69; break; case 22: hor=70; break; case 23: hor=71; break; case 0: hor=52; break; case 1: hor=41; break; case 2: hor=42; break; case 3: hor=43; break; case 4: hor=44; break; case 5: hor=45; break; case 6: hor=46; break; case 7: hor=47; break; case 8: hor=48; break; case 9: hor=49; break; case 10: hor=50; break; case 11: hor=51; break; default: break; } data_escreve_rtc(0x02,hor); return true; } else if(modo==false) { hor=data_le_rtc(0x02); //conversão AM para 24H switch(hor) { case 72: hor=12; break; case 61: hor=13; break; case 62: hor=14; break; case 63: hor=15; break; case 64: hor=16; break; case 65: hor=17; break; case 66: hor=18; break; case 67: hor=19; break; case 68: hor=20; break; case 69: hor=21; break; case 70: hor=22; break; case 71: hor=23; break; case 40: hor=0; break; case 41: hor=1; break; case 42: hor=2; break; case 43: hor=3; break; case 44: hor=4; break; case 45: hor=5; break; case 46: hor=6; break; case 47: hor=7; break; case 48: hor=8; break; case 49: hor=9; break; case 50: hor=10; break; case 51: hor=11; break; case 52: hor=0; default: break; } data_escreve_rtc(0x02,(hor)); return false; } } //****************** //Exemplo de utilização: // // if(!input(pin_c3)) { delay_ms(300); //filtro para o botão seleciona_modo_am(true); //indica para o RTC que o formato é 12horas /* Se fosse p.ex: 14:15h passaria para 02:15h [COLOR="Red"]PM[/COLOR] */ }
  6. Olá Felipe_ZeRo! Cara fiz uma biblioteca para o RTC DS1307, ainda não implementei fisicamente, mas fiz o projeto no Proteus com o pic 18F452, e funcionou certinho. Ve se te é útil, tá muito completa, e se você achar algum bug dê um report e sinta-se livre para debuga-la. Como biblioteca I2C, adaptei a do Fábio Pereira para atender as especificaões de tempo mínimo de scl e sda do DS1307. Abaixo a biblioteca DS1307.c /***************************************/ /* DS1307.C */ /* Biblioteca para o RTC DS1307 */ /* */ /* autor: Alysson Machado */ /***************************************/ //importante: A biblioteca I2C.c deve estar incluída antes desta bibioteca! const byte slave_ad_write=0xD0; const byte slave_ad_read= 0xD1; byte seg,min,hor,d,dat,a; void data_escreve_rtc(byte word_ad, byte dado) // envia comando de escrita no rtc { //Converte Decimal para BCD dado=((dado/10)<<4)+(dado%10); I2C_start(); I2C_escreve_byte(slave_ad_write); delay_us(3); I2C_le_ack(); I2C_escreve_byte(word_ad); I2C_le_ack(); I2C_escreve_byte(dado); I2C_le_ack(); I2C_stop(); } unsigned char data_le_rtc(byte word_ad_read) //le um byte enviado pelo rtc do barramento I2C { byte rtc_byte; I2C_start(); I2C_escreve_byte(slave_ad_write); delay_us(3); I2C_le_ack(); I2C_escreve_byte(word_ad_read); I2C_le_ack(); I2C_start(); I2C_escreve_byte(slave_ad_read); I2C_le_ack(); rtc_byte=I2C_le_byte(); delay_us(2); I2C_nack(); I2C_stop(); //Converte BCD para decimal rtc_byte=((rtc_byte>>4)*10)+rtc_byte%16; return rtc_byte; } unsigned byte converte_decimal_to_BCD(byte info) //converte o dado para BCD { info=((info/10)<<4)+(info%10); return info; } void grava_alldata_rtc(seg,min,hor,d,dat,m,a) //grava todos os dados no RTC { seg=converte_decimal_to_BCD(seg); min=converte_decimal_to_BCD(min); hor=converte_decimal_to_BCD(hor); d=converte_decimal_to_BCD(d); dat=converte_decimal_to_BCD(dat); m=converte_decimal_to_BCD(m); a=converte_decimal_to_BCD(a); I2C_start(); I2C_escreve_byte(slave_ad_write); delay_us(3); I2C_le_ack(); I2C_escreve_byte(0x00); I2C_le_ack(); I2C_escreve_byte(seg); I2C_le_ack(); I2C_escreve_byte(min); I2C_le_ack(); I2C_escreve_byte(hor); I2C_le_ack(); I2C_escreve_byte(d); I2C_le_ack(); I2C_escreve_byte(dat); I2C_le_ack(); I2C_escreve_byte(m); I2C_le_ack(); I2C_escreve_byte(a); I2C_le_ack(); I2C_stop(); } void desativa_clock_rtc() //desativa o clock do RTC { byte aux_seg; aux_seg=data_le_rtc(0x00); data_escreve_rtc(0x00,(0x50+aux_seg)); } void ativa_clock_rtc() //ativa o clock do RTC { byte aux_seg; aux_seg=data_le_rtc(0x00)-0x50; data_escreve_rtc(0x00,aux_seg); } void zera_segundos_rtc() //zera a contagem dos segundos { data_escreve_rtc(0x00,0); } void seleciona_clockout_rtc(int1 OUT,int1 SQWE,int1 RS1,int1 RS0) //seleciona o estado do pino SQW/OUT { if(SQWE==0) { if(OUT==0) { data_escreve_rtc(0x07,0); } else if(OUT==1) { data_escreve_rtc(0x07,80); } } else if(SQWE==1) { if((RS0==0)&&(RS1==0)) { data_escreve_rtc(0x07,10); } else if((RS0==1)&&(RS1==0)) { data_escreve_rtc(0x07,11); } else if((RS0==1)&&(RS1==1)) { data_escreve_rtc(0x07,13); } } } Abaixo está a biblioteca I2c.c para a comunicação /*************************************************************/ /* I2C.C */ /* Biblioteca de comunicação I2C por software com suporte a memórias */ /* EEPROM */ /* autor: Fábio Pereira */ /*************************************************************/ #ifndef scl //Definições dos pinos de comunicação #define scl pin_b1 //pino de clock #define sda pin_b0 //pino de dados #define EEPROM_SIZE 32768 //tamanho dem bytes da memória eeprom #endif #define seta_scl output_float(scl) //seta o pino scl #define apaga_scl output_low(scl) //apaga o pino scl #define seta_sda output_float(sda) //seta o pino sda #define bit_sda output_high(sda) //coloca nivel no barramento #define apaga_sda output_low(sda) //apaga o pino sda void I2C_start(void) //coloca o barramento na condição de start { apaga_scl; delay_us(3); seta_sda; delay_us(3); seta_scl; delay_us(3); apaga_sda; delay_us(3); apaga_scl; delay_us(3); } void I2C_stop(void) //coloca o barramento na condição de stop { delay_us(3); apaga_scl; delay_us(3); apaga_sda; delay_us(3); seta_scl; delay_us(4); seta_sda; delay_us(3); } void I2C_ack() //coloca o sinal de reconhecimento no barramento { apaga_sda; delay_us(3); seta_scl; delay_us(3); apaga_scl; delay_us(3); seta_sda; delay_us(3); } void I2C_nack() //coloca no barramento o sinal de não reconhecimento { seta_sda; delay_us(3); seta_scl; delay_us(3); apaga_scl; delay_us(3); } boolean I2C_le_ack() //efetua a leitura do sinal de ack/nack { boolean estado; seta_sda; delay_us(3); seta_scl; delay_us(2); do{ estado=input(sda); delay_us(3); apaga_scl; delay_us(3); return estado; delay_us(3); }while(estado!=0); } void I2C_escreve_byte(unsigned byte dado) { //envia um byte pelo barramento I2C int conta=8; delay_us(2); apaga_scl; while(conta) { //envia primeiro o MSB if(shift_left(&dado,1,0)) {seta_sda; delay_us(3);} else { apaga_sda;delay_us(3);} //dá um pulso em scl; seta_scl; delay_us(3); conta--; apaga_scl; delay_us(3); } //ativa sda seta_sda; delay_us(3); } unsigned char I2C_le_byte() //recebe um byte pelo barramento I2C { unsigned char bytelido,conta=8; bytelido=0; apaga_scl; delay_us(3); seta_sda; delay_us(3); while(conta) { //ativa scl seta_scl; delay_us(3); //lê o byte em sda, deslocando em byte lido shift_left(&bytelido,1,input(sda)); conta--; // desativa scl delay_us(3); apaga_scl; delay_us(3); } return bytelido; } void escreve_eeprom(byte dispositivo,long endereco,byte dado) //escreve em um endereço do dispositivo //dispositivo - é o endereço do dispositivo escravo //endereco - é o endereço de memória a ser escrito //dado - é a informação a ser guardada { if(dispositivo>7) dispositivo=7; I2C_start(); I2C_escreve_byte(0xA0|(dispositivo<<1)); I2C_le_ack(); I2C_escreve_byte(endereco>>8); I2C_le_ack(); I2C_escreve_byte(endereco); I2C_le_ack(); I2C_escreve_byte(dado); I2C_le_ack(); I2C_stop(); delay_ms(10); } byte le_eeprom(byte dispositivo,long int endereco) //lê um dado de um endereço específico no dispositivo //dispositivo - é o endereço do dispositivo escravo (0 - 7) //endereco - é o endereço da memória a ser lida { byte dado; if(dispositivo>7) dispositivo=7; I2C_start(); I2C_escreve_byte(0xA0|(dispositivo<<1)); I2C_le_ack(); I2C_escreve_byte(endereco>>8); I2C_le_ack(); I2C_escreve_byte(endereco); I2C_le_ack(); I2C_start(); //envia comando de leitura I2C_escreve_byte(0xA1|(dispositivo<<1)); I2C_le_ack(); dado=I2C_le_byte(); I2C_nack(); I2C_stop(); return dado; } Espero ter ajudado! Abraço.

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...