Ir ao conteúdo
  • Cadastre-se

Felipe_zEr0

Membro Pleno
  • Posts

    62
  • Cadastrado em

  • Última visita

Tudo que Felipe_zEr0 postou

  1. @LNW LNW, nesse compilador as variavéis do tipo int são de 8 bits (0-255) por padrão. Tem outros tipos como, int16(0-65535) e int32(0-4294967295). Sim, a ideia de utilizar o bitwise para verificação é muito interessante, e isso acabou por me dar um norte a seguir, dando a atenção de verificar bit a bit recebido. Sendo assim, fiz a divisão de todos os dados recebidos e armazenei eles em 3 bytes distintos (byte_1[8], byte_[2] , byte_3[8]). Considerando que um byte é composto por 8 bits, assim temos 255 possibilidades diferentes, ou seja, para cada combinação recebida é retornado um valor de 0 a 255 decimal. Então, por exemplo, considerando que a informação no primeiro byte_1[8] seja {1,0,1,0,1,0,1,0} [ ou 170 decimal]: Faço a análise do primeiro bit, SE bit[0] = 1; então valor_int = 128; Verifico o próximo bit, SE bit[1] = 1; então valor_int = valor_int + 64; SE bit[2] = 1; então valor_int = valor_int + 32; SE bit[3] = 1; então valor_int = valor_int + 16; SE bit[4] = 1; então valor_int = valor_int + 8; SE bit[5] = 1; então valor_int = valor_int + 4; SE bit[6] = 1; então valor_int = valor_int + 2; SE bit[7] = 1; então valor_int = valor_int + 1; E a verificação prossegue até o ultimo digito do byte, retornando o resultado de valor 170 em uma variável do tipo int. Assim consigo reduzir a informação em um único valor, tornando ainda mais fácil outras comparações com essa informação. O código completo dessa verificação está abaixo: //---------------------------------------------------------------------------------------//// Verifica todos os dígitos do byte, retorna um valor inteiro de 0 - 255 como resultado.////---------------------------------------------------------------------------------------// for(i=0;i<=7;i++) //Cria o Byte_1 { status = input_state(PIN_B0); byte_1[i] = status; if(byte_1[0] == 1) //Se o primeiro bit = 1. { code_1 = 128; if(byte_1[1] == 1) code_1 = code_1 + 64; if(byte_1[2] == 1) code_1 = code_1 + 32; if(byte_1[3] == 1) code_1 = code_1 + 16; if(byte_1[4] == 1) code_1 = code_1 + 8; if(byte_1[5] == 1) code_1 = code_1 + 4; if(byte_1[6] == 1) code_1 = code_1 + 2; if(byte_1[7] == 1) code_1 = code_1 + 1; } else //Senão o primeiro bit = 0. { code_1 = 127; if(byte_1[1] == 0) code_1 = code_1 - 64; if(byte_1[2] == 0) code_1 = code_1 - 32; if(byte_1[3] == 0) code_1 = code_1 - 16; if(byte_1[4] == 0) code_1 = code_1 - 8; if(byte_1[5] == 0) code_1 = code_1 - 4; if(byte_1[6] == 0) code_1 = code_1 - 2; if(byte_1[7] == 0) code_1 = code_1 - 1; } printf("\n\rCODE: %u",code_1); //Resultado da conversão delay_ms(1); //Sincroniza o cursor para a próxima leitura [1]. } @ Também pensei em utilizar a UART do PIC, que sem duvida é o mais indicado, porém testei varias configurações, e não sei qual delas possui a informação completa e correta. A informação (24 bits somente os dados uteis) que o pic recebe é composta por 28 bits, sendo o [Start Bit + 24 bits de dados + 4 bits que funcionam como Stop Bit]. Sendo que eu tmb não sei o valor ideal da velocidade da transmissão (Baud Rate). Será que tem como configurar a quantidade de bits da informação a receber? No manual do compilador, só existem opções de 8 - 9 bits, e utilizando essa configurações não irei receber a informação correta tmb. Então, acabei descartando o uso pelo fato de não saber se a informação é correta ou não e tentando por esse método acima. Enfim, LNW, Felipe_Eletronic, grato pelas sugestões, me ajudaram muito. Obg.
  2. Olá pessoal do fórum, Estou editando um circuito que, recebe uma informação serial de 24bits (3 Bytes) de um receptor 433Mhz, e identificando bit por bit utilizando o pino "RB_0" do PIC16F877A. Cada bit identificado no pino "RB_0" (sendo "0" ou "1") tem o seu valor armazenado em um vetor de [24] posições, ou seja, o valor de cada bit "válido" é armazenado nesse vetor. Identifico corretamente cada bit recebido, porém, o problema é que, não consigo trabalhar com todos os valores recebidos no vetor como se fosse uma única informação, por exemplo, supondo que recebo no pino "RB_0" a seguinte informação abaixo: Para trabalhar com esse código inteiro, eu teria que comparar bit por bit, e isso provavelmente consumira muita memoria do PIC. O ideal seria converter esses dados recebidos em HEX, ou algo mais resumido desde que seja uma unica informação. Como por exemplo: Então, peço a ajuda para saber como manipular corretamente os dados recebidos nesse vetor. 1.Queria saber tmb se é possível dividir a informação do vetor, armazenando cada byte separadamente? Sugestões são bem vindas. Obg! Código Fonte (CCS Compiler): #include <16F877A.h>#device adc=10 //Habilitar ADC de 10 bits, obrigatório. Pode //ser utilizado de 8 bits também.#FUSES NOWDT //No Watch Dog Timer#FUSES XT //Clock <=4Mhz#FUSES PUT //Power Up Timer#FUSES NOPROTECT //Code not protected from reading#FUSES NOBROWNOUT //No brownout reset#FUSES NOLVP //No low voltage prgming, B3(PIC16) or B5(PIC18) used for I/O#FUSES NOCPD //No EE protection#use delay(clock=4000000)#include <stdlib.h>#include <lcd.c>#use rs232(baud=9600, parity=N , xmit=PIN_C6 , rcv=PIN_C7 , bits=8 , ERRORS)//#define botao_reset PIN_B3//#define botao_incremento PIN_B2//#define botao_decremento PIN_B1static unsigned int1 status; static unsigned int data[24] = {0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23}, end_code[4] = {0,1,2,3}, i, e, bit_decoder;unsigned int8 pilot_code;static unsigned int8 code;#INT_EXTvoid ext_isr(){}#int_ccp2void trata_ccp_2(){}#int_TIMER1void TIMER1_isr(void) { setup_timer_1(T1_DISABLED); setup_timer_1(T1_INTERNAL|T1_DIV_BY_8); set_timer1(29732); //0,5sec[29732] 1sec[3036]}void grava_eeprom(){}void ler_eeprom(){}void main(){ setup_ccp2(CCP_CAPTURE_RE); ext_int_edge(L_TO_H); // init interrupt triggering for button press enable_interrupts(INT_EXT); enable_interrupts (int_ccp2); enable_interrupts(INT_TIMER1); enable_interrupts (global); set_timer1(29732); setup_timer_1(T1_INTERNAL|T1_DIV_BY_8); //setup_adc_ports(AN0); //Configura canal 0 analógico //setup_adc(ADC_CLOCK_INTERNAL); //De acordo com relógio interno. //set_adc_channel(0); //Habilita canal 0 //delay_us(20); //Espera um pouco, obrigatório! lcd_init(); //ler_eeprom(); while(1) { while(input(PIN_B0)) //Aguarda o START BIT { delay_ms(1); //Delay de sincronização [0.8](Consulte a timeline) for(i=0;i<=23;i++) { status = input_state(PIN_B0); data[i] = status; printf("\n\rCodigo:%u i:%u S:%u",data[i],i,status); delay_ms(1); //Sincroniza o cursor para a proxima leitura [1]. } for(e=0;e<=3;e++) { status = input_state(PIN_B0); end_code[e] = status; printf("\n\rEndCode:%u",end_code[e]); delay_ms(1); //Sincroniza o cursor para a proxima leitura [1]. } if((end_code[0] == 0) && (end_code[1] == 1) && (end_code[2] == 0) && (end_code[3] == 1)) { printf("\n\r[Codigo OK]"); printf(LCD_PUTC,"\f[Codigo OK]"); } else { printf("\n\r[Codigo Invalido]"); printf(LCD_PUTC,"\fCodigo Invalido"); printf("\n\r[Byte 1] %u %u %u %u %u %u %u %u",data[0],data[1],data[2],data[3],data[4],data[5],data[6],data[7],); printf("\n\r[Byte 2] %u %u %u %u %u %u %u %u",data[8],data[9],data[10],data[11],data[12],data[13],data[14],data[15],); printf("\n\r[Byte 3] %u %u %u %u %u %u %u %u",data[16],data[17],data[18],data[19],data[20],data[21],data[22],data[23],); } while(input(PIN_B0)) { // i=0; //reseta o cursor de data. //e=0; //reseta o cursor de end_code. } } }}
  3. Interessante o assunto do tópico, pelo barramento CAN é possível obter informações de velocidade, nível de combustível, etcs? Já pensei implementar algum tipo de computador de bordo bem simples, principalmente nessa categoria de carro (Gol G3) que não tem esse opcional de fábrica. A família 16F dos pics, possuem suporte ao CAN? Seria legal implementar um projeto desse tipo.
  4. Obrigado pela ajuda galera, ainda não tive tempo de fazer os testes na placa mas assim que possível eu divulgo os resultados á vocês.
  5. AlyssonMachado, muito obrigado pelo ajuda, mas poderia colocar algum código dando um exemplo do uso desse driver que você me mandou ? O código compilou sem erros, agora para saber usar é somente com algum exemplo.
  6. Olá galera, Estou trabalhando em um projeto que utiliza um CI RTC o DS1307, o DS1307 tem a função de exibir os valores como hora e data em um display LCD 16x2 que é controlado pelo PIC16F877A. Uso o CCS compiler, porém eu percebi que não existe o driver para o uso do DS1307, portanto eu pesquisei no fórum da CCS e encontrei um driver "genérico" para o uso do DS1307, só que ele não funciona corretamente, tentei fazer algumas correções, o código segue abaixo: /// 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,min,seg) Set the date/time /// /// /// /// ds1307_get_date(dia,mes,ano,dow) Obter data /// /// /// /// ds1307_get_time(hora,min,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 min; 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 i2c_write(0x00); // REG 0 i2c_stop(); i2c_start(); i2c_write(0xD1); // RD from RTC segundos = bcd2bin(i2c_read(0)); // Read current "seconds" in DS1307 i2c_stop(); segundos &= 0x7F; delay_us(3); i2c_start(); i2c_write(0xD0); // WR to RTC i2c_write(0x00); // REG 0 i2c_write(bin2bcd(segundos)); // Start oscillator with current "seconds value i2c_stop(); i2c_start(); i2c_write(0xD0); // WR to RTC i2c_write(0x07); // Control Register i2c_write(0x80); // Disable squarewave output pin i2c_stop(); } void ds1307_set_date_time(BYTE dia, BYTE mes, BYTE ano, BYTE dow, BYTE hora, BYTE min, 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(min)); // 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 &min, 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); min = 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)); } //////////////////////////////////////////////////////////////////////////////// Abaixo o exemplo de uso do driver DS1307.c: #include <ds1307.c> #include <lcd.c> #define I2C_SCL PIN_C3 #define I2C_SDA PIN_C4 #use i2c(Master,Fast,sda=PIN_C4,scl=PIN_C3) int1 flag=1; int a_seg; void main() { setup_adc_ports(NO_ANALOGS); setup_adc(ADC_OFF); setup_psp(PSP_DISABLED); setup_timer_0(RTCC_INTERNAL|RTCC_DIV_1); setup_timer_1(T1_DISABLED); setup_timer_2(T2_DISABLED,0,1); setup_comparator(NC_NC_NC_NC); setup_vref(FALSE); lcd_init(); enable_interrupts(INT_SSP); enable_interrupts(GLOBAL); lcd_init(); ds1307_init(); //Exemplo: 09/07/2010 (data) // 23:20:00 (hora) ds1307_set_date_time(9,7,10,00,23,20,0); a_seg = seg; while(TRUE) { ds1307_get_time(hora,min,seg); ds1307_get_date(dia,mes,ano,dow); If(a_seg!=seg) { printf(lcd_putc,"\f %02i:%02i:%02i\n %02i/%02i/%02i",hora,min,seg,dia,mes,ano); a_seg=seg; } } } #include "C:\Program Files (x86)\PICC\Projetos\Projects\PIC 16f877A\Transmissor [Versao A].h" Como podem ver o uso é bem simples, é so utilizar o comando ds1307_set_date_time(), ds1307_get_date(),ds1307_get_time() para obter os valores correspondentes. Mas como eu citei, o driver funciona com alguns erros: - O DS1307 não "memoriza" a hora anterior, mesmo estando ligado a bateria. - Quando o PIC é ligado sem utilizar o comando ds1307_set_date_time o valor exibido é "00:00:00". - E quando é utilizado o comando ds_1307_set_date_time o DS1307 sempre inicia na mesma hora configurada (óbvio), sendo assim interrompendo a contagem anterior. Gostaria de saber se alguém poderia me disponibilizar algum driver do DS1307 que funcione corretamente. Desde já agradeço pela ajuda.

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