LinkedIn YouTube Facebook
Szukaj

Wstecz
Artykuły

STM32Butterfly2: obsługa zewnętrznego RTC z I2C

Poniżej przedstawiono listing programu głównego.

int main(void)
{
    //Initialize system timer
    time_init();
    //Initialize nokia display
    nlcd_init();
    //Initialize the i2c module
    i2cm_init(I2C_SPEED);
    //Print welcome string
    nlcd_put_string( "www.boff.pl", 0, 0 );
    //Register configuration
    static const uint8_t pgm_regs[] =
    {
		0x00,       //Start Addr
        	0x00,       //Sec
        	0x30,		//Min
		0x20,		//Hour
		0x04,		//Day num
		0x05,		//day
		0x06,		//Month
		0x07,		//Year
		0x00		//Config
    };
    static const uint8_t sw_addr = 0;
    uint8_t buf[RTC_REGS_SIZE];
    int code = i2cm_transfer_7bit(I2C_RTC_ADDR,pgm_regs,sizeof(pgm_regs),NULL,0);
    if(code<0)
    {
        print_i2cerr(code);
        for(;;);    //Fail never end loop
    }
    for( ;;)
    {
        //Send configuration registgers
	code = i2cm_transfer_7bit( I2C_RTC_ADDR,&sw_addr,sizeof(sw_addr),buf, sizeof(buf) );
        if(code==0)
        {
            print_date(buf);
        }
        else
        {
            print_i2cerr(code);
            for(;;);    //Fail never end loop
        }
        wait_ms(MEASURE_DELAY_TIME);
    }
    return 0;
}

 

Pierwszym działaniem w programie głównym jest skonfigurowanie licznika SysTick, realizuje to funkcja time_init(). Jej działanie sprowadza się do określenia częstotliwości występowania przerwania od licznika SysTick, ustawienia priorytetu przerwania oraz włączenia licznika.

Drugim działaniem jest wywołanie funkcji nlcd_init(), która opowiada za konfigurację wyświetlacza pochodzącego z telefonu Nokia 3310. Jej działanie polega na włączeniu zegarów dla wykorzystywanych portów GPIO i kontrolera SPI i skonfigurowaniu linii używanych w transmisji przez magistralę SPI oraz dodatkowych sterujących wyświetlaczem. Funkcja konfigurująca wyświetlacz po przeprowadzeniu konfiguracji linii wysyła cykl komend do wyświetlacza, które go inicjalizują.

Następnym działaniem jest konfiguracja kontrolera I2C. Odpowiada za to funkcja i2cm_init, która jako parametr przyjmuje częstotliwość z jaką transmitowane są dane. Poniżej przedstawiono listing funkcji.

errno_t i2cm_init( unsigned clk_speed)
{

	//GPIO configuration
	RCC->APB2ENR |= I2C1_GPIO_ENR;
	io_config(I2C1_PORT,I2C1_SDA_PIN,GPIO_MODE_50MHZ,GPIO_CNF_ALT_OD);
	io_config(I2C1_PORT,I2C1_SCL_PIN,GPIO_MODE_50MHZ,GPIO_CNF_ALT_OD);
	io_set(I2C1_PORT,I2C1_SCL_PIN);
	io_set(I2C1_PORT,I2C1_SDA_PIN);
	//I2C module configuration
	RCC->APB1ENR |= I2C1_ENR;

	/* Enable I2C module*/
	i2c->CR1 |= CR1_PE_SET;
	/* Reset the i2c device */
	i2c->CR1 |= CR1_SWRST;
	nop();
	i2c->CR1 &= ~CR1_SWRST;

	 uint16_t tmpreg = i2c->CR2;
	 /* Clear frequency FREQ[5:0] bits */
	 tmpreg &= CR2_FREQ_RESET;
	 tmpreg |= (uint16_t)(CONFIG_PCLK1_HZ/1000000);
	 i2c->CR2 = tmpreg;

	 //Set speed
	 i2cm_set_speed(clk_speed);

	 /* CR1 configuration */
	 /* Get the I2Cx CR1 value */
	 tmpreg = i2c->CR1;
	 /* Clear ACK, SMBTYPE and  SMBUS bits */
	 tmpreg &= CR1_CLEAR_MASK;
	 /* Configure I2Cx: mode and acknowledgement */
	 /* Set SMBTYPE and SMBUS bits according to I2C_Mode value */
	 /* Set ACK bit according to I2C_Ack value */
	 tmpreg |= I2C_MODE_I2C | I2C_ACK_ENABLE;
	 /* Write to I2Cx CR1 */
	 i2c->CR1 = tmpreg;

	 /* Set I2Cx Own Address1 and acknowledged address */
	 i2c->OAR1 = I2C_AcknowledgedAddress_7bit;

	 i2c->SR1 = 0; i2c->SR2 = 0;

	 /* Enable interrupt controller */
	 nvic_set_priority( I2C1_EV_IRQn, IRQ_PRIO, IRQ_SUB);
     	 nvic_set_priority( I2C1_ER_IRQn, IRQ_PRIO, IRQ_SUB);
	 nvic_irq_enable(I2C1_EV_IRQn,true);
         nvic_irq_enable(I2C1_ER_IRQn,true);
	 return ERR_OK;
}