Olá! hoje exploraremos um pouco do microcontrolador Busy Bee EFM8(EFM8BB1), dentre suas principais características está o fato de ter um ADC de 12BITS,funciona a 25mhz interno, pinos compativel com 5V(pois são geralmente pra 3,3V), sensor de temperatura interno, 4 timers de 16 bits, comunicação UART,SPI e SMBUS/I2C.
Este microcontrolador é totalmente compatível com alguns microcontroladores da linha CIP-51 8051(C8051), sendo praticamente um melhoramento dos projetos anteriores deste componente. Para a utilização deste microcontrolador divergem alguns registradores além do precisar de 2 comando para desligar o "watch dog", sob risco do micro ficar resetando.
Neste exemplo vou demonstrar como acionar um pino usando como base de tempo o timer2 interno deste microcontrolador, apesar de ser um exemplo simples creio que irá ajudar quem está começando a usar este microcontrolador com a interface do Simplicity Studio. Veja na figura a seguir.
O código fonte ://----------------------------------------------------------------------------- // Includes //----------------------------------------------------------------------------- #include "si_toolchain.h" // compiler declarations #include <SI_EFM8BB1_Register_Enums.h> // SFR declarations #include <stdio.h> #include <string.h> #define SYSCLK 24500000 // Internal oscillator frequency in Hz SI_SBIT(BOT1, SFR_P0, 1); // não usado aqui SI_SBIT(BOT2, SFR_P0, 2); // não usado aqui //leds vermelho e sinal de saida SI_SBIT(LED_1,SFR_P1,2); int pisca_led = 0; long tempo_1s = 0; void SiLabs_Startup (void) { WDTCN = 0XDE;// WDTE = 0 (desliga watchdog ) WDTCN = 0xAD;// senão colocar essa seuqencia não desliga deser colocado obrigatoriamente os 2 PCA0MD = 0x08; // habilita sytem clok para timer } void __delay_ms(uint32_t val) {//rotina que usa ciclos de maquina - pode variar devido a interrupções val = 360*val; while(val>1) { val--; } } void __delay_us(uint8_t val) {//rotina que usa ciclos de maquina - pode variar devido a interrupções while(val>1) { val--; } } void Oscillator_Init (void) { HFO0CAL = 0X00; // para alta frequencia CLKSEL = 0x00; //SYSCLK: OpcDiv = 24M5Hz // sem divisão de clock e para alta frequencia// clok interno } void PORT_Init(void) { WDTCN = 0XDE;// WDTE = 0 (desliga watchdog ) WDTCN = 0xAD;// senão colocar essa seuqencia não desliga deser colocado obrigatoriamente os 2 CLKSEL = 0X00; // 24mhz clock interno // WDTCN = 0xDE;//(desliga watchdog ) XBR0 = 0x00; // habilita UART no pino P0.4(TX) and P0.5(RX) ; logo não serão usado como como IO´s gerais XBR2 = 0xC0; // habilita crossbar e pull-ups interno desligados VDM0CN = 0x00; // Colocado porque senão da problema na gravacao da flash(já estava isso) RSTSRC = 0x00; // desativa reset de falha de oscilação. P0MDOUT = 0XC0; //somente pino 6 e 7 são saidas P1MDOUT = 0xFF; //todos saidas P2MDOUT = 0xFF; //todos saidas so tem 2 saidas //configura portas P0MDIN = 0xF9; // apenas P0.1 e P0.2 são analogica P1MDIN = 0xFF; // are digital P0SKIP = 0x3F; //não usado P1SKIP = 0xFE; IE_EA = 1; // liga interrupções } //----------------------------------------------------------------------------- // Timer2_Init //----------------------------------------------------------------------------- // // Configure Timer2 to 16-bit auto-reload and generate an interrupt at // interval specified by <counts> using SYSCLK/48 as its time base. // //----------------------------------------------------------------------------- void Timer2_Init (void) { //100us TMR2CN0 = 0x00; /// time 2 no modo 16 bits TCON = 0;//não habilita timer 0 e 1 CKCON0 = 0XFD; //todos os timer serão ligados ao sysclock e na menor divisão para timer 0 e 1(por 4) TMR2RLH = 0xF6; //quando se usa o modo autocarregar puxa daqui o valor TMR2RLL = 0x70;//quando se usa o modo autocarregar puxa daqui o valor TMR2 = 0xF670; // um valor para primeiro estouro IE_ET2 = 1; // enable Timer2 interrupts TMR2CN0_TR2 = 1; // start Timer2 } //----------------------------------------------------------------------------- // Interrupt Service Routines //----------------------------------------------------------------------------- //----------------------------------------------------------------------------- // Timer2_ISR //----------------------------------------------------------------------------- // This routine changes the state of the LED whenever Timer2 overflows. // //----------------------------------------------------------------------------- SI_INTERRUPT(Timer2_ISR, TIMER2_IRQn) { // tempo de 100us TMR2CN0_TF2H = 0; // limpa tanto a interrupção nos bytes baixo como altos TMR2CN0_TF2L = 0;// clear Timer2 interrupt flag tempo_1s++; } //----------------------------------------------------------------------------- // main() Routine // ---------------------------------------------------------------------------- // Note: the software watchdog timer is not disabled by default in this // example, so a long-running program will reset periodically unless // the timer is disabled or your program periodically writes to it. // // Review the "Watchdog Timer" section under the part family's datasheet // for details. To find the datasheet, select your part in the // Simplicity Launcher and click on "Data Sheet". //----------------------------------------------------------------------------- int main (void) { PORT_Init(); Timer2_Init (); for(;;) { if(tempo_1s > 10000) {//pisca a cada 1s tempo_1s = 0; if(pisca_led == 0) { pisca_led = 1; LED_1 = 1; } else { pisca_led = 0; LED_1 = 0; } } } }
Nenhum comentário :
Postar um comentário
olá,digite aqui seu comentário!