EFM32单片机使用

时钟初始化 clk_init()

CMU:时钟管理单元
LFXO: Low frequency crystal oscillator

  • CMU_OscillatorEnable(cmuOsc_LFXO, true, true);
    功能:使能振荡器
    Oscillator:有源晶振;Crystal:无源晶振
  • CMU_ClockSelectSet(cmuClock_LFA,cmuSelect_LFXO);
    功能:给时钟分支选择参考时钟或振荡器
    LFA: LF A 分支;低频A时钟
  • CMU_ClockSelectSet(cmuClock_LFB,cmuSelect_LFXO);
    功能:给时钟分支选择参考时钟或振荡器
    LFB: LF B 分支;低频B时钟
void clk_init(void)
{
    CMU_ClockEnable(cmuClock_HFPER, true);    /* High frequency peripheral clock */
    CMU_ClockEnable(cmuClock_CORELE, true);   /* Low energy clocking module clock */
    CMU_ClockEnable(cmuClock_GPIO, true);     /* General purpose input/output clock */
    CMU_OscillatorEnable(cmuOsc_LFXO, true, true);
    CMU_ClockSelectSet(cmuClock_LFA,cmuSelect_LFXO);
    CMU_ClockSelectSet(cmuClock_LFB,cmuSelect_LFXO);            
}

内存系统控制器初始化 MSC_Init()

  • MSC:Memory System Controller (em_msc.c)
  • #define MSC ((MSC_TypeDef ) MSC_BASE) /*MSC base pointer /
    Register Map实现方式:将基地址转换成结构体地址,结构体定义了对应的寄存器映射(Register Map),offset和芯片手册相对应。MSC_TIMEBASE寄存器就在其中。
  • 6位:PERIOD周期 — 0 – 1US 1 – 5US(5US应该仅仅被用在1MHz的AUXHFRCO品牌)
    5:0位:被MSC用来对flash写和擦除进行time(打节拍)的timebase
void MSC_Init(void)
{
#if defined( _MSC_TIMEBASE_MASK )
  uint32_t freq, cycles;
#endif
  /* Unlock the MSC 解锁MSC */
  MSC->LOCK = MSC_UNLOCK_CODE;
  /* Disable writing to the flash 禁止flash写操作 */
  MSC->WRITECTRL &= ~MSC_WRITECTRL_WREN;

#if 0
#if defined( _MSC_TIMEBASE_MASK )
  /* Configure MSC->TIMEBASE according to selected frequency */
#ifdef EMLIB_THIN
  freq = 14000000;
#else
  freq = CMU_ClockFreqGet(cmuClock_AUX);
#endif

  if (freq > 7000000)
  {
    /* Calculate number of clock cycles for 1us as base period */
    freq   = (freq * 11) / 10;
    cycles = (freq / 1000000) + 1;

    /* Configure clock cycles for flash timing */
    MSC->TIMEBASE = (MSC->TIMEBASE & ~(_MSC_TIMEBASE_BASE_MASK |
                                       _MSC_TIMEBASE_PERIOD_MASK)) |
                    MSC_TIMEBASE_PERIOD_1US |
                    (cycles << _MSC_TIMEBASE_BASE_SHIFT);
  }
  else
  {
#ifndef EMLIB_THIN    
    /* Calculate number of clock cycles for 5us as base period */
    freq   = (freq * 5 * 11) / 10;
    cycles = (freq / 1000000) + 1;

    /* Configure clock cycles for flash timing */
    MSC->TIMEBASE = (MSC->TIMEBASE & ~(_MSC_TIMEBASE_BASE_MASK |
                                       _MSC_TIMEBASE_PERIOD_MASK)) |
                    MSC_TIMEBASE_PERIOD_5US |
                    (cycles << _MSC_TIMEBASE_BASE_SHIFT);
#endif /* EMLIB_THIN */
  }
#endif
#endif
}

串口初始化 uart_init()

void uart_init(void)
{
    LEUART_Init_TypeDef leuart0Init =
    {
      .enable   = leuartEnable,       /* Activate data reception on LEUn_TX pin. */
      .refFreq  = 0,                    /* Inherit the clock frequenzy from the LEUART clock source */
      .baudrate = 9600,                 /* Baudrate = 9600 bps */
      .databits = leuartDatabits8,      /* Each LEUART frame containes 8 databits */
      .parity   = leuartNoParity,       /* No parity bits in use */
      .stopbits = leuartStopbits1,      /* Setting the number of stop bits in a frame to 2 bitperiods */
    };

    //CMU_ClockEnable(cmuClock_HFPER, true);
    //CMU_ClockEnable(cmuClock_CORELE, true);

    //CMU_ClockSelectSet(cmuClock_LFA, cmuSelect_LFRCO);
    //CMU_ClockSelectSet(cmuClock_LFB, cmuSelect_LFRCO);

    CMU_ClockEnable(cmuClock_LEUART0, true);    

    LEUART_Reset(LEUART0); //复位
    LEUART_Init(LEUART0, &leuart0Init); //初始化

    /* Route LEUART1 TX pin to DMA location 1 */
    LEUART0->ROUTE = LEUART_ROUTE_TXPEN | LEUART_ROUTE_RXPEN |
                   LEUART_ROUTE_LOCATION_LOC1;

    /* Enable GPIO for LEUART1. TX is on PB13 */
    GPIO_PinModeSet(gpioPortB,                /* GPIO port */
                  13,                        /* GPIO port number */
                  gpioModePushPull,         /* Pin mode is set to push pull */
                  1);                       /* High idle state */

    /* Enable GPIO for LEUART1. RX is on PB14 */
    GPIO_PinModeSet(gpioPortB,            /* Port */
                  14,                    /* Port number */
                  gpioModeInputPull,    /* Pin mode is set to input only, with pull direction given bellow */
                  1);                   /* Pull direction is set to pull-up */    
    /* 有效接收数据中断使能 */
    LEUART_IntEnable(LEUART0, LEUART_IEN_RXDATAV);
    LEUART0->IFC = 0xffff; //清空所有的中断标志

    NVIC_EnableIRQ(LEUART0_IRQn); //初始化外部中断    

    FifoInit(&uart_rx_fifo); //初始化队列
}

void uart_send_buf(uint8_t *buf, uint8_t length)
{
    while (length--)
    {
        LEUART_Tx(LEUART0, *buf++);
    }
}

void uart_send_string(char *str)
{
    while (*str)
    {
        LEUART_Tx(LEUART0, *str++);
    }
}

//接收中断函数
void LEUART0_IRQHandler(void) 
{
    static uint8_t data;
    __IO uint32_t leuartif;      

    leuartif = LEUART_IntGet(LEUART0);
    LEUART_IntClear(LEUART0, leuartif);

    if (leuartif & LEUART_IF_RXDATAV)
    {                       
        data = LEUART0->RXDATA; 
        //接收到数据data处理 
    }
}

ADC初始化 adc_init()

void adc_init(void)
{
    ADC_Init_TypeDef       init = ADC_INIT_DEFAULT;
    ADC_InitSingle_TypeDef singleInit = ADC_INITSINGLE_DEFAULT;

    CMU_ClockEnable(cmuClock_ADC0, true);

    init.timebase = ADC_TimebaseCalc(0);
    init.prescale = ADC_PrescaleCalc(7000000, 0);
    ADC_Init(ADC0, &init);

    singleInit.reference  = adcRef2V5; //内部参考电压2.5V
    singleInit.input      = adcSingleInpCh4;
    singleInit.resolution = adcRes12Bit; //12bit采样
    singleInit.acqTime = adcAcqTime256;
    ADC_InitSingle(ADC0, &singleInit);  //单次ADC转换      
}

你可能感兴趣的:(单片机软件)