STM32Butterfly2: obsługa cyfrowego termometru MCP9801
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); //Initialize temp controller int res = tempsensor_init(); if(res<0) { char buf[24]; tiny_snprintf( buf, sizeof(buf), "I2cErr %d",res); nlcd_put_string(buf,0,0); for(;;); //Fail never end loop } else { nlcd_put_string( "www.boff.pl", 0, 0 ); nlcd_put_string( "Sensor Temp:", 0, 1 ); } struct temp t; for(;;) { res = tempsensor_get(&t); if(res>=0) { display_temp( 0, 2, &t,"C " ); } else { char buf[24]; tiny_snprintf( buf, sizeof(buf), "I2cErr %d",res); nlcd_put_string(buf,0,2); for(;;); //Failed infinite loop } wait_ms(MEASURE_DELAY_TIME); } return 0; }
W pierwszym kroku działania programu głównego wywoływana jest funkcja time_init(), która odpowiada za konfigurację licznika SysTick. Sprowadza się ona do skonfigurowania priorytetu wywoływanego przerwania przez licznik, ustawienia częstotliwości występowania przerwania oraz włączenia licznika.
Następnym działaniem jest wywołanie funkcji nlcd_init(), odpowiedzialnej za inicjalizację wyświetlacza modułu KAmodLCD1. Funkcja ta odpowiada za włączenie zegarów używanych portów i kontrolera SPI, skonfigurowanie linii używanych w transmisji z wyświetlaczem oraz konfiguracje kontrolera SPI używanego w transmisji z wyświetlaczem pochodzącym z telefonu Nokia 3310. Funkcja nlcd_init() inicjalizuje także wyświetlacz poprzez ustawienie odpowiedniego stanu poszczególnych linii oraz wysłanie komend i danych konfiguracyjnych wyświetlacz.
Kolejnym działaniem jest konfiguracja kontrolera I2C, odpowiada za to funkcja i2cm_init. Jako parametr przyjmuje ona prędkość z jaką transmitowane są dane, w naszym przypadku jest to 100kHz. Listing funkcji został przedstawiony poniżej.
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; }