Depois de vários testes descobri que meu erro foi habilitar o PLL(pois eu queria que ele rodasse mais rápido),O PLL é um recurso pra elevar a frequencia de trabalho do microcontrolador, mas se for configurado errado o microcontrolador nem funciona devido o clock exceder o potencial do hardware.
Vamos a um exemplo, que foi o que aconteceu comigo, coloquei um clock de 20Mhz dai configurei o PLL para não divir o clock vindo do prescaler logo isso excede a capacidade de clock e então o microcontrolador não funciona,observe que o simulador não alerta para este tipo de erro o que leva a algumas pessoas a se descabelar com sua aplicação(pois mesmo o código estando correto o microcontrolador não funciona),uma vez me lembro de um seguidor do blog ter um problema parecido e na época eu não soube explicar o por que, mas agora diante deste problema resolvi investigar pra trazer a vcs um "estudo de caso".
Para validar minhas suspeitas montei um código simples que apenas alterna um dos pinos do microcontrolador,pois segundo o datasheet essa operação gasta um ciclo de maquina(ou seja o sinal de saída terá a metade a frequência do clock interno),inicialmente eu mandei liga e desligar a porta do microcontrolador em C pra minha surpresa o sinal em nível alto era maior que o em nível baixo,então mandei que setasse apenas um pino e agora o sinal de saída foi simétrico(ou seja em C quando se seta a porta o compilador XC8 deve executar outras rotinas que o faz ter esse delay), Então para não ter essas influencia do compilador resolvi fazer o código em assembly(é então o sinal ficou fiel ao clock sem delay), mas como o laço for gasta alguns ciclo de maquina, resolvi executar o processo de alternar o led 3 vezes antes de retornar o laço "for".O resultado é visto nas figuras a seguir com um clock interno de 2,5Mhz.
Figura 1 - sinal completo.
Figura 2 - detalhe dos sinais.
Veja que o postcaler esta para 1 ou seja não irá dividir o clock de saída(assim teremos qual o clock máximo que vamos ter j[a descontados a divisão por 4 do PIC), com esse procedimento podemos esta realizando algo conhecido como "overclock" ou seja forçar o hardware a trabalhar no limite, dentre os possíveis consequências podemos ter imprecisões nos conversores ADC,ou erros nas comunicações serial rs232,SPI, e outros,Então minha sugestão é testar para saber se realmente essas frequências de trabalho mais elevadas não se torne um problema para sua aplicação.
Os resultados encontrados para as configurações foram:
Usando um cristal de 20MHZ sem o PLL ligado
#pragma config FOSC = HS // 2,5 MHZ
Usando um cristal de 20MHZ com o PLL ligado
#pragma config PLLDIV = 2 - para o valor 1 e 0 o microcontrolador atinge seu limete e não funciona mais
#pragma config FOSC = HSPLL_HS // 0MHZ - fica resetado.
#pragma config PLLDIV = 3
#pragma config FOSC = HSPLL_HS // 20MHZ -- > 8X mais rapido
#pragma config PLLDIV = 4
#pragma config FOSC = HSPLL_HS // 15MHZ -- > 6X mais rapido
#pragma config PLLDIV = 5
#pragma config FOSC = HSPLL_HS // 12MHZ -- > 4,8X mais rapido
O código fonte :
/* * Avaliação de desempenho 18F4550 * * Compilador : MPlabXC8. * Microcontrolador: 18F4550. * Autor: Aguivone. * Versão: 1. * Data : 24 de janeiro de 2017. * * Neste exemplo vou demontrar como configurar o oscilador para usar o pll do pic(eleva seu clock e definir o quão mais rápido ele se tornara) */ #include <xc.h> #define _XTAL_FREQ 20000000 // // CONFIG1L #pragma config PLLDIV = 5 // 1X #pragma config CPUDIV = OSC1_PLL2// System Clock Postscaler Selection bits ([Primary Oscillator Src: /1][96 MHz PLL Src: /2]) #pragma config USBDIV = 1 // USB Clock Selection bit (used in Full-Speed USB mode only; UCFG:FSEN = 1) (USB clock source comes directly from the primary oscillator block with no postscale) // CONFIG1H #pragma config FOSC = HSPLL_HS //HS para cristal de 16 ou 20mhz(habilitei o pll interno mas para este exemplo nem precisava podia usar somete o HS) #pragma config FCMEN = OFF // Fail-Safe Clock Monitor Enable bit (Fail-Safe Clock Monitor disabled) #pragma config IESO = OFF // Internal/External Oscillator Switchover bit (Oscillator Switchover mode disabled) // CONFIG2L #pragma config PWRT = ON // Power-up Timer Enable bit (PWRT enabled) #pragma config BOR = ON // Brown-out Reset Enable bits (Brown-out Reset disabled in hardware and software) #pragma config BORV = 2 // Brown-out Reset Voltage bits (Setting 1 2.79V) #pragma config VREGEN = OFF // USB Voltage Regulator Enable bit (USB voltage regulator disabled) // CONFIG2H #pragma config WDT = OFF // Watchdog Timer Enable bit (WDT disabled (control is placed on the SWDTEN bit)) #pragma config WDTPS = 32768 // Watchdog Timer Postscale Select bits (1:32768) // CONFIG3H #pragma config CCP2MX = OFF // CCP2 MUX bit (CCP2 input/output is multiplexed with RB3) #pragma config PBADEN = OFF // PORTB A/D Enable bit (PORTB<4:0> pins are configured as digital I/O on Reset) #pragma config LPT1OSC = OFF // Low-Power Timer 1 Oscillator Enable bit (Timer1 configured for higher power operation) #pragma config MCLRE = ON // MCLR Pin Enable bit (RE3 input pin enabled; MCLR pin disabled) // CONFIG4L #pragma config STVREN = ON // Stack Full/Underflow Reset Enable bit (Stack full/underflow will cause Reset) #pragma config LVP = OFF // Single-Supply ICSP Enable bit (Single-Supply ICSP disabled) #pragma config ICPRT = OFF // Dedicated In-Circuit Debug/Programming Port (ICPORT) Enable bit (ICPORT disabled) #pragma config XINST = OFF // Extended Instruction Set Enable bit (Instruction set extension and Indexed Addressing mode disabled (Legacy mode)) // CONFIG5L #pragma config CP0 = OFF // Code Protection bit (Block 0 (000800-001FFFh) is not code-protected) #pragma config CP1 = OFF // Code Protection bit (Block 1 (002000-003FFFh) is not code-protected) #pragma config CP2 = OFF // Code Protection bit (Block 2 (004000-005FFFh) is not code-protected) #pragma config CP3 = OFF // Code Protection bit (Block 3 (006000-007FFFh) is not code-protected) // CONFIG5H #pragma config CPB = OFF // Boot Block Code Protection bit (Boot block (000000-0007FFh) is not code-protected) #pragma config CPD = OFF // Data EEPROM Code Protection bit (Data EEPROM is not code-protected) // CONFIG6L #pragma config WRT0 = OFF // Write Protection bit (Block 0 (000800-001FFFh) is not write-protected) #pragma config WRT1 = OFF // Write Protection bit (Block 1 (002000-003FFFh) is not write-protected) #pragma config WRT2 = OFF // Write Protection bit (Block 2 (004000-005FFFh) is not write-protected) #pragma config WRT3 = OFF // Write Protection bit (Block 3 (006000-007FFFh) is not write-protected) // CONFIG6H #pragma config WRTC = OFF // Configuration Register Write Protection bit (Configuration registers (300000-3000FFh) are not write-protected) #pragma config WRTB = OFF // Boot Block Write Protection bit (Boot block (000000-0007FFh) is not write-protected) #pragma config WRTD = OFF // Data EEPROM Write Protection bit (Data EEPROM is not write-protected) // CONFIG7L #pragma config EBTR0 = OFF // Table Read Protection bit (Block 0 (000800-001FFFh) is not protected from table reads executed in other blocks) #pragma config EBTR1 = OFF // Table Read Protection bit (Block 1 (002000-003FFFh) is not protected from table reads executed in other blocks) #pragma config EBTR2 = OFF // Table Read Protection bit (Block 2 (004000-005FFFh) is not protected from table reads executed in other blocks) #pragma config EBTR3 = OFF // Table Read Protection bit (Block 3 (006000-007FFFh) is not protected from table reads executed in other blocks) // CONFIG7H #pragma config EBTRB = OFF // Boot Block Table Read Protection bit (Boot block (000000-0007FFh) is not protected from table reads executed in other blocks) void main(void) { TRISB = 0X00; //saída B1 e B0 TRISA = 0XFF; // TRISD = 0X00; //saídas TRISE = 0X00; //saídas TRISC = 0X10; //todas são entradas//somente C4 é entrada (SDI) ADCON0 = 0x00;//configura os pinos para portas digitais(ADC OFF) ADCON1 = 0x0F;//configura os pinos para portas digitais(ADC OFF) for(;;) { asm("BSF PORTD,0"); asm("BCF PORTD,0");//para garantir que cada instrução leve 1 ciclo de maquina asm("BSF PORTD,0");// ou seja a frequência interna é igual a metade da frequência do sinal asm("BCF PORTD,0"); asm("BSF PORTD,0"); asm("BCF PORTD,0"); } }
Nenhum comentário :
Postar um comentário
olá,digite aqui seu comentário!