Individální projekty MPOA

Mikroprocesory s architekturou ARM

Uživatelské nástroje

Nástroje pro tento web


2017:envi-logger

Rozdíly

Zde můžete vidět rozdíly mezi vybranou verzí a aktuální verzí dané stránky.

Odkaz na výstup diff

Obě strany předchozí revize Předchozí verze
Následující verze
Předchozí verze
2017:envi-logger [2018/01/22 04:51]
Miroslav Waldecker [Software]
2017:envi-logger [2018/01/22 06:23] (aktuální)
Miroslav Waldecker [Záver]
Řádek 32: Řádek 32:
   - Konfigurácia pinov   - Konfigurácia pinov
   - Konfigurácia hodinových domén   - Konfigurácia hodinových domén
-  - Kofigurácia periférií a komunikácia ​s obvodmi k nim pripojenými+  - Kofigurácia periférií a komunikácia
   - Správa displeja   - Správa displeja
   - Ukladanie údajov   - Ukladanie údajov
 +
 +===== Konfigurácia pinov =====
 +
 +Pre správnu činnosť periférií je dôležité nastavenie konfigurácií pinov. Každý pin procesora obsahuje multiplexor s privedenými signálmi s rôznych periférií. ​
 +<code c>
 +
 +  CLOCK_EnableClock(kCLOCK_PortC); ​                         ​
 +  CLOCK_EnableClock(kCLOCK_PortB);​
 +  CLOCK_EnableClock(kCLOCK_PortE);​
 +
 +// Set UART
 +
 +  PORT_SetPinMux(PORTC,​ PIN14_IDX, kPORT_MuxAlt3); ​          /* PORTB16 (pin 62) is configured as UART0_RX */
 +  PORT_SetPinMux(PORTC,​ PIN15_IDX, kPORT_MuxAlt3); ​          /* PORTB17 (pin 63) is configured as UART0_TX */
 +  SIM->​SCGC1 = (SIM->​SCGC1 | SIM_SCGC1_UART4_MASK);​
 +
 +  PORT_SetPinMux(PORTB,​ PIN20_IDX, kPORT_MuxAsGpio);​ // GPIO Heater TGS 4146 1->ON
 +  PORT_SetPinMux(PORTB,​ PIN10_IDX, kPORT_MuxAsGpio);​
 +  ​
 +//Set SDHC interface
 +
 +  const port_pin_config_t porte0_pin1_config = {
 +     ​kPORT_PullUp, ​                                           /* Internal pull-up resistor is enabled */
 +     ​kPORT_FastSlewRate, ​                                     /* Fast slew rate is configured */
 +     ​kPORT_PassiveFilterDisable, ​                             /* Passive filter is disabled */
 +     ​kPORT_OpenDrainDisable, ​                                 /* Open drain is disabled */
 +     ​kPORT_HighDriveStrength, ​                                /* High drive strength is configured */
 +     ​kPORT_MuxAlt4, ​                                          /* Pin is configured as SDHC0_D1 */
 +     ​kPORT_UnlockRegister ​                                    /* Pin Control Register fields [15:0] are not locked */
 +   };
 +   ​PORT_SetPinConfig(PORTE,​ PIN0_IDX, &​porte0_pin1_config); ​  /* PORTE0 (pin 1) is configured as SDHC0_D1 */
 +   const port_pin_config_t porte1_pin2_config = {
 +     ​kPORT_PullUp, ​                                           /* Internal pull-up resistor is enabled */
 +     ​kPORT_FastSlewRate, ​                                     /* Fast slew rate is configured */
 +     ​kPORT_PassiveFilterDisable, ​                             /* Passive filter is disabled */
 +     ​kPORT_OpenDrainDisable, ​                                 /* Open drain is disabled */
 +     ​kPORT_HighDriveStrength, ​                                /* High drive strength is configured */
 +     ​kPORT_MuxAlt4, ​                                          /* Pin is configured as SDHC0_D0 */
 +     ​kPORT_UnlockRegister ​                                    /* Pin Control Register fields [15:0] are not locked */
 +   };
 +   ​PORT_SetPinConfig(PORTE,​ PIN1_IDX, &​porte1_pin2_config); ​  /* PORTE1 (pin 2) is configured as SDHC0_D0 */
 +   const port_pin_config_t porte2_pin3_config = {
 +     ​kPORT_PullUp, ​                                           /* Internal pull-up resistor is enabled */
 +     ​kPORT_FastSlewRate, ​                                     /* Fast slew rate is configured */
 +     ​kPORT_PassiveFilterDisable, ​                             /* Passive filter is disabled */
 +     ​kPORT_OpenDrainDisable, ​                                 /* Open drain is disabled */
 +     ​kPORT_HighDriveStrength, ​                                /* High drive strength is configured */
 +     ​kPORT_MuxAlt4, ​                                          /* Pin is configured as SDHC0_DCLK */
 +     ​kPORT_UnlockRegister ​                                    /* Pin Control Register fields [15:0] are not locked */
 +   };
 +   ​PORT_SetPinConfig(PORTE,​ PIN2_IDX, &​porte2_pin3_config); ​  /* PORTE2 (pin 3) is configured as SDHC0_DCLK */
 +   const port_pin_config_t porte3_pin4_config = {
 +     ​kPORT_PullUp, ​                                           /* Internal pull-up resistor is enabled */
 +     ​kPORT_FastSlewRate, ​                                     /* Fast slew rate is configured */
 +     ​kPORT_PassiveFilterDisable, ​                             /* Passive filter is disabled */
 +     ​kPORT_OpenDrainDisable, ​                                 /* Open drain is disabled */
 +     ​kPORT_HighDriveStrength, ​                                /* High drive strength is configured */
 +     ​kPORT_MuxAlt4, ​                                          /* Pin is configured as SDHC0_CMD */
 +     ​kPORT_UnlockRegister ​                                    /* Pin Control Register fields [15:0] are not locked */
 +   };
 +   ​PORT_SetPinConfig(PORTE,​ PIN3_IDX, &​porte3_pin4_config); ​  /* PORTE3 (pin 4) is configured as SDHC0_CMD */
 +   const port_pin_config_t porte4_pin5_config = {
 +     ​kPORT_PullUp, ​                                           /* Internal pull-up resistor is enabled */
 +     ​kPORT_FastSlewRate, ​                                     /* Fast slew rate is configured */
 +     ​kPORT_PassiveFilterDisable, ​                             /* Passive filter is disabled */
 +     ​kPORT_OpenDrainDisable, ​                                 /* Open drain is disabled */
 +     ​kPORT_HighDriveStrength, ​                                /* High drive strength is configured */
 +     ​kPORT_MuxAlt4, ​                                          /* Pin is configured as SDHC0_D3 */
 +     ​kPORT_UnlockRegister ​                                    /* Pin Control Register fields [15:0] are not locked */
 +   };
 +   ​PORT_SetPinConfig(PORTE,​ PIN4_IDX, &​porte4_pin5_config); ​  /* PORTE4 (pin 5) is configured as SDHC0_D3 */
 +   const port_pin_config_t porte5_pin6_config = {
 +     ​kPORT_PullUp, ​                                           /* Internal pull-up resistor is enabled */
 +     ​kPORT_FastSlewRate, ​                                     /* Fast slew rate is configured */
 +     ​kPORT_PassiveFilterDisable, ​                             /* Passive filter is disabled */
 +     ​kPORT_OpenDrainDisable, ​                                 /* Open drain is disabled */
 +     ​kPORT_HighDriveStrength, ​                                /* High drive strength is configured */
 +     ​kPORT_MuxAlt4, ​                                          /* Pin is configured as SDHC0_D2 */
 +     ​kPORT_UnlockRegister ​                                    /* Pin Control Register fields [15:0] are not locked */
 +   };
 +   ​PORT_SetPinConfig(PORTE,​ PIN5_IDX, &​porte5_pin6_config); ​  /* PORTE5 (pin 6) is configured as SDHC0_D2 */
 +   const port_pin_config_t porte6_pin7_config = {
 +     ​kPORT_PullDown, ​                                         /* Internal pull-down resistor is enabled */
 +     ​kPORT_FastSlewRate, ​                                     /* Fast slew rate is configured */
 +     ​kPORT_PassiveFilterDisable, ​                             /* Passive filter is disabled */
 +     ​kPORT_OpenDrainDisable, ​                                 /* Open drain is disabled */
 +     ​kPORT_LowDriveStrength, ​                                 /* Low drive strength is configured */
 +     ​kPORT_MuxAsGpio, ​                                        /* Pin is configured as PTE6 */
 +     ​kPORT_UnlockRegister ​                                    /* Pin Control Register fields [15:0] are not locked */
 +   };
 +   ​PORT_SetPinConfig(PORTE,​ PIN6_IDX, &​porte6_pin7_config); ​  /* PORTE6 (pin 7) is configured as PTE6 */
 +}
 +
 +void BOARD_I2C_ConfigurePins(void) {
 +  CLOCK_EnableClock(kCLOCK_PortE); ​                          /* Port E Clock Gate Control: Clock enabled */
 +
 +//Set IIC
 +  const port_pin_config_t porte24_pin31_config = {
 +    kPORT_PullUp, ​                                           /* Internal pull-up resistor is enabled */
 +    kPORT_FastSlewRate, ​                                     /* Fast slew rate is configured */
 +    kPORT_PassiveFilterDisable, ​                             /* Passive filter is disabled */
 +    kPORT_OpenDrainEnable, ​                                  /* Open drain is enabled */
 +    kPORT_LowDriveStrength, ​                                 /* Low drive strength is configured */
 +    kPORT_MuxAlt5, ​                                          /* Pin is configured as I2C0_SCL */
 +    kPORT_UnlockRegister ​                                    /* Pin Control Register fields [15:0] are not locked */
 +  };
 +  PORT_SetPinConfig(PORTE,​ PIN24_IDX, &​porte24_pin31_config);​ /* PORTE24 (pin 31) is configured as I2C0_SCL */
 +  const port_pin_config_t porte25_pin32_config = {
 +    kPORT_PullUp, ​                                           /* Internal pull-up resistor is enabled */
 +    kPORT_FastSlewRate, ​                                     /* Fast slew rate is configured */
 +    kPORT_PassiveFilterDisable, ​                             /* Passive filter is disabled */
 +    kPORT_OpenDrainEnable, ​                                  /* Open drain is enabled */
 +    kPORT_LowDriveStrength, ​                                 /* Low drive strength is configured */
 +    kPORT_MuxAlt5, ​                                          /* Pin is configured as I2C0_SDA */
 +    kPORT_UnlockRegister ​                                    /* Pin Control Register fields [15:0] are not locked */
 +  };
 +  PORT_SetPinConfig(PORTE,​ PIN25_IDX, &​porte25_pin32_config);​ /* PORTE25 (pin 32) is configured as I2C0_SDA */
 +}
 +
 +void BOARD_InitFlexbus(void){
 + CLOCK_EnableClock(kCLOCK_PortB); ​                          /* Port B Clock Gate Control: Clock enabled */
 + CLOCK_EnableClock(kCLOCK_PortC); ​                          /* Port C Clock Gate Control: Clock enabled */
 + CLOCK_EnableClock(kCLOCK_PortD); ​                          /* Port D Clock Gate Control: Clock enabled */
 +// Set Flexbus
 + PORT_SetPinMux(PORTD,​ PIN6_IDX, kPORT_MuxAlt5); ​           /* PORTD6 (pin A2) is configured as FB_AD0 */
 + PORT_SetPinMux(PORTD,​ PIN5_IDX, kPORT_MuxAlt5); ​           /* PORTD5 (pin A3) is configured as FB_AD1 */
 + PORT_SetPinMux(PORTD,​ PIN4_IDX, kPORT_MuxAlt5); ​           /* PORTD4 (pin A4) is configured as FB_AD2 */
 + PORT_SetPinMux(PORTD,​ PIN3_IDX, kPORT_MuxAlt5); ​           /* PORTD3 (pin B4) is configured as FB_AD3 */
 + PORT_SetPinMux(PORTD,​ PIN2_IDX, kPORT_MuxAlt5); ​           /* PORTD2 (pin C4) is configured as FB_AD4 */
 + PORT_SetPinMux(PORTC,​ PIN10_IDX, kPORT_MuxAlt5); ​          /* PORTC10 (pin C7) is configured as FB_AD5 */
 + PORT_SetPinMux(PORTC,​ PIN9_IDX, kPORT_MuxAlt5); ​           /* PORTC9 (pin D7) is configured as FB_AD6 */
 + PORT_SetPinMux(PORTC,​ PIN8_IDX, kPORT_MuxAlt5); ​           /* PORTC8 (pin A8) is configured as FB_AD7 */
 + PORT_SetPinMux(PORTC,​ PIN7_IDX, kPORT_MuxAlt5); ​           /* PORTC7 (pin B8) is configured as FB_AD8 */
 + PORT_SetPinMux(PORTC,​ PIN6_IDX, kPORT_MuxAlt5); ​           /* PORTC6 (pin C8) is configured as FB_AD9 */
 + PORT_SetPinMux(PORTC,​ PIN5_IDX, kPORT_MuxAlt5); ​           /* PORTC5 (pin D8) is configured as FB_AD10 */
 + PORT_SetPinMux(PORTC,​ PIN4_IDX, kPORT_MuxAlt5); ​           /* PORTC4 (pin A9) is configured as FB_AD11 */
 + PORT_SetPinMux(PORTC,​ PIN2_IDX, kPORT_MuxAlt5); ​           /* PORTC2 (pin A12) is configured as FB_AD12 */
 + PORT_SetPinMux(PORTC,​ PIN1_IDX, kPORT_MuxAlt5); ​           /* PORTC1 (pin B11) is configured as FB_AD13 */
 + PORT_SetPinMux(PORTC,​ PIN0_IDX, kPORT_MuxAlt5); ​           /* PORTC0 (pin B12) is configured as FB_AD14 */
 + PORT_SetPinMux(PORTB,​ PIN18_IDX, kPORT_MuxAlt5); ​          /* PORTB18 (pin D12) is configured as FB_AD15 */
 + PORT_SetPinMux(PORTB,​ PIN17_IDX, kPORT_MuxAlt5); ​          /* PORTB17 (pin E9) is configured as FB_AD16 */
 +
 + PORT_SetPinMux(PORTC,​ PIN11_IDX, kPORT_MuxAlt5); ​          /* PORTC11 (pin B7) is configured as FB_RW_b */
 + PORT_SetPinMux(PORTB,​ PIN19_IDX, kPORT_MuxAlt5); ​          /* PORTB19 (pin D11) is configured as FB_OE_b */
 + PORT_SetPinMux(PORTC,​ PIN3_IDX, kPORT_MuxAlt5); ​           /* PORTC3 (pin A11) is configured as FB_CLKOUT */
 + PORT_SetPinMux(PORTD,​ PIN1_IDX, kPORT_MuxAlt5); ​           /* PORTD1 (pin D4) is configured as FB_CS0_b */
 +}
 +  ​
 +</​code>​
 +
 +===== Konfigurácia hodín =====
 +
 +Ďalšou z esenciálnych konfigurácií,​ je nastavenie hodín pre periférie. Hlavným zdrojom je oscilátor v periférii pre fyzickú vrstvu ethernetu 50MHz. Z nej potom PLL blokom generujem hodiny pre jadro 120MHz, pre pamäť 60MHz, Flexbus (Vzhľadom na obmedzenie SSD1289 radiča 25MHz) 15MHz. ​
 +Zdrojom hodín pre RTC časovač a prevodník snímača tlaku je použitý oscilátor s kryštálom 32,768kHz. Ten funguje aj po vypnutá napájania. Výstup z neho je smerovaný na výstupný pin procesora CLKOUT. ​
 +
 +===== Kofigurácia periférií a komunikácia =====
 +==== TGS4161 a ADC ====
 +
 +Pre zber údajov zo senzoru koncentrácie j epoužitý interný prevodník ADC v single ended móde a internou referenciou. Funkcia pre nastavenie periférií:​
 +
 +<code c>
 +void Init_CO(void) {
 +//Set GPIO for heater control
 + gpio_pin_config_t heater = { kGPIO_DigitalOutput,​ 0, };
 + GPIO_PinInit(GPIOB,​ 20U, &​heater);​
 +//Get ADC default config
 + ADC16_GetDefaultConfig(&​adc16ConfigStruct);​
 +
 + adc16ConfigStruct.resolution = kADC16_ResolutionSE16Bit;​
 + ADC16_Init(DEMO_ADC16_BASE,​ &​adc16ConfigStruct);​
 + ADC16_EnableHardwareTrigger(DEMO_ADC16_BASE,​ false);
 + if (kStatus_Success == ADC16_DoAutoCalibration(DEMO_ADC16_BASE)) {
 + PRINTF("​ADC16_DoAutoCalibration() Done.\r\n"​);​
 + } else {
 + PRINTF("​ADC16_DoAutoCalibration() Failed.\r\n"​);​
 + }
 +
 + adc16ChannelConfigStruct.channelNumber = DEMO_ADC16_USER_CHANNEL;​
 + adc16ChannelConfigStruct.enableInterruptOnConversionCompleted = false;
 +}
 +//Set heater on
 +void Start_sensor(void) {
 + GPIO_SetPinsOutput(GPIOB,​ 1U << 20U);
 +}
 +//Reset heater
 +void Stop_sensor(void) {
 + GPIO_ClearPinsOutput(GPIOB,​ 1U << 20U);
 +}
 +
 +</​code>​
 +Funkcia pre čitanie vzorky vzčítanej prevodníkom - ADC0 kanál 0 single ended:
 +<code c>
 +int32_t get_adc(void) {
 +
 + ADC16_SetChannelConfig(DEMO_ADC16_BASE,​ DEMO_ADC16_CHANNEL_GROUP,​
 + &​adc16ChannelConfigStruct);​
 + while (0U
 + == (kADC16_ChannelConversionDoneFlag
 + & ADC16_GetChannelStatusFlags(DEMO_ADC16_BASE,​
 + DEMO_ADC16_CHANNEL_GROUP)))
 + ;
 + return (ADC16_GetChannelConversionValue(DEMO_ADC16_BASE,​
 + DEMO_ADC16_CHANNEL_GROUP));​
 +}
 +</​code>​
 +
 +Prepočet hodnoty zmeranej AD prevodníkom na koncentráciu ppm CO2:
 +<code c>
 +int32_t get_concentration(void){
 + float adc_mv;
 + float sens_mv;
 + float adc_mv_min;
 + float sens_mv_min;​
 + float delta_emf;
 + int32_t co2ppm;
 +
 +//Prepocet na rozsah + kalibracia
 + adc_mv_min = 5.03321924e-5 * (float)adc_val_min;​
 + adc_mv = 5.03321924e-5 * (float)get_adc();​
 +//Prepocet prevodová charakteristika
 + sens_mv_min = (0.39 - 0.2*adc_mv_min)*1000.0;​
 + sens_mv = (0.39 - 0.2*adc_mv)*1000.0;​
 +//Prepocet na ppm zo semilox charakteristiky v datasheet-e
 + delta_emf = sens_mv_min - sens_mv;
 + sens_mv = powf(10.0,​(0.0161*delta_emf + 2.5441));
 +
 + co2ppm = (int32_t)sens_mv;​
 + return(co2ppm);​
 +
 +}
 +</​code>​
 +
 +==== SHT21, HP03M a ADC ====
 +
 +Nastavenie IIC periférie a GPIO pre ovládanie XCLR - reset signálu pre HP03M.
 +<code c>
 +void Init_iic(void) {
 + BOARD_I2C_ConfigurePins();​
 + gpio_pin_config_t xclr = { kGPIO_DigitalOutput,​ 0, };
 + GPIO_PinInit(GPIOB,​ 10U, &xclr);
 +
 + I2C_MasterGetDefaultConfig(&​masterConfig);​
 + masterConfig.baudRate_Bps = I2C_BAUDRATE;​
 +
 + sourceClock = I2C_MASTER_CLK_FREQ;​
 +
 + I2C_MasterInit(I2C0,​ &​masterConfig,​ sourceClock);​
 +
 +}
 +</​code>​
 +
 +Komunikácia s SHT21. Funkcie pre čítanie teploty a vlhkosti a ich prepočet na °C a %RH:
 +<code c>
 +float read_temp() {
 +
 + uint8_t data[5];
 + uint16_t itemp;
 + float ftemp;
 +
 + data[0] = (uint8_t) SHT21_TRIG_TEMP_HM;​
 + while (kStatus_Success
 + != I2C_MasterStart(I2C0,​ SHT21_I2C_ADDRESS,​ kI2C_Write))
 + ;
 +
 + while (kStatus_Success
 + != I2C_MasterWriteBlocking(I2C0,​ data, 1, kI2C_TransferNoStopFlag))
 + ;
 +
 + while (kStatus_Success
 + != I2C_MasterRepeatedStart(I2C0,​ SHT21_I2C_ADDRESS,​ kI2C_Read))
 + ;
 +
 + while (kStatus_Success
 + != I2C_MasterReadBlocking(I2C0,​ data, 3, kI2C_TransferCompleteFlag))
 + ;
 + itemp = data[0];
 + itemp = itemp << 8;
 + itemp |= data[1];
 + itemp &= 0xFFFC;
 + ftemp = -48.85 + (175.72 * ((float) itemp)) / 65536.0;
 +
 + return (ftemp);
 +}
 +
 +float read_hum() {
 +
 + uint8_t data[5];
 + uint16_t ihum;
 + float fhum;
 +
 + data[0] = (uint8_t) SHT21_TRIG_HUMIDITY_HM;​
 + while (kStatus_Success
 + != I2C_MasterStart(I2C0,​ SHT21_I2C_ADDRESS,​ kI2C_Write))
 + ;
 + while (kStatus_Success
 + != I2C_MasterWriteBlocking(I2C0,​ data, 1, kI2C_TransferNoStopFlag))
 + ;
 + while (kStatus_Success
 + != I2C_MasterRepeatedStart(I2C0,​ SHT21_I2C_ADDRESS,​ kI2C_Read))
 + ;
 +
 + while (kStatus_Success
 + != I2C_MasterReadBlocking(I2C0,​ data, 3, kI2C_TransferCompleteFlag))
 + ;
 + ihum = data[0];
 + ihum = ihum << 8;
 + ihum |= data[1];
 + ihum &= 0xFFFC;
 + fhum = -6.0 + 125.0 * ((float) ihum) / 65536.0;
 + return (fhum);
 +}
 +</​code>​
 +
 +Komunikácia s HP03M a výpočet barometrického tlaku, je zaujímavé,​ že tento senzor obsahuje 2 obvody, v jednom sú kalibračné a kompenzačné údaje, druhý je AD prevodník s meraním teploty pre kompenzáciu a tlaku. Každý z týchto obvodov má inú adresu a iný spôsob ich čítania:
 +
 +<code c>
 +float read_pressure() {
 +
 + uint8_t eeprom_data[18];​
 + uint16_t iPressure;
 + uint16_t iTemperature;​
 + uint8_t data_index;
 + uint16_t C[7];
 + uint8_t coef_A;
 + uint8_t coef_B;
 + uint8_t coef_C;
 + uint8_t coef_D;
 + float fTemp;
 + float fPressure;
 + float dut;
 + float offset;
 + float sensitivity;​
 + float xpress;
 +
 + GPIO_PinWrite(GPIOB,​ 10U, 1);
 +
 +
 + eeprom_data[0] = 0x10;
 +
 + while (kStatus_Success != I2C_MasterStop(I2C0))
 + ;
 +
 +
 + while (kStatus_Success
 + != I2C_MasterStart(I2C0,​ HP03_I2C_EEPROM_ADDRESS,​ kI2C_Write))
 + ;
 +
 + while (kStatus_Success
 + != I2C_MasterWriteBlocking(I2C0,​ eeprom_data,​ 1,
 + kI2C_TransferNoStopFlag))
 + ;
 +
 + while (kStatus_Success
 + != I2C_MasterRepeatedStart(I2C0,​ HP03_I2C_EEPROM_ADDRESS,​ kI2C_Read))
 + ;
 +
 + while (kStatus_Success
 + != I2C_MasterReadBlocking(I2C0,​ eeprom_data,​ 18,
 + kI2C_TransferCompleteFlag))
 + ;
 +
 + for (data_index = 0; data_index <= 6; data_index++) {
 + C[data_index] = eeprom_data[data_index * 2];
 + C[data_index] = C[data_index] << 8;
 + C[data_index] |= eeprom_data[(data_index * 2) + 1];
 + }
 +
 + coef_A = eeprom_data[14];​
 + coef_B = eeprom_data[15];​
 + coef_C = eeprom_data[16];​
 + coef_D = eeprom_data[17];​
 +
 +
 + while (kStatus_Success
 + != I2C_MasterStart(I2C0,​ HP03_I2C_AD_ADDRESS,​ kI2C_Write))
 + ;
 +
 + eeprom_data[0] = 0xFF;
 + eeprom_data[1] = 0xF0;
 +
 + while (kStatus_Success
 + != I2C_MasterWriteBlocking(I2C0,​ eeprom_data,​ 2,
 + kI2C_TransferCompleteFlag))
 + ;
 +
 +
 + while (kStatus_Success
 + != I2C_MasterStart(I2C0,​ HP03_I2C_AD_ADDRESS,​ kI2C_Write))
 + ;
 + eeprom_data[0] = 0xFD;
 +
 + while (kStatus_Success
 + != I2C_MasterWriteBlocking(I2C0,​ eeprom_data,​ 1,
 + kI2C_TransferNoStopFlag))
 + ;
 +
 + while (kStatus_Success
 + != I2C_MasterRepeatedStart(I2C0,​ HP03_I2C_AD_ADDRESS,​ kI2C_Read))
 + ;
 +
 + while (kStatus_Success
 + != I2C_MasterReadBlocking(I2C0,​ eeprom_data,​ 2,
 + kI2C_TransferCompleteFlag))
 + ;
 +
 + iPressure = eeprom_data[0];​
 + iPressure = iPressure << 8;
 + iPressure |= eeprom_data[1];​
 +
 +
 + while (kStatus_Success
 + != I2C_MasterStart(I2C0,​ HP03_I2C_AD_ADDRESS,​ kI2C_Write))
 + ;
 +
 + eeprom_data[0] = 0xFF;
 + eeprom_data[1] = 0xE8;
 +
 + while (kStatus_Success
 + != I2C_MasterWriteBlocking(I2C0,​ eeprom_data,​ 2,
 + kI2C_TransferCompleteFlag))
 + ;
 +
 +
 + while (kStatus_Success
 + != I2C_MasterStart(I2C0,​ HP03_I2C_AD_ADDRESS,​ kI2C_Write))
 + ;
 + eeprom_data[0] = 0xFD;
 +
 + while (kStatus_Success
 + != I2C_MasterWriteBlocking(I2C0,​ eeprom_data,​ 1,
 + kI2C_TransferNoStopFlag))
 + ;
 +
 + while (kStatus_Success
 + != I2C_MasterRepeatedStart(I2C0,​ HP03_I2C_AD_ADDRESS,​ kI2C_Read))
 + ;
 +
 + while (kStatus_Success
 + != I2C_MasterReadBlocking(I2C0,​ eeprom_data,​ 2,
 + kI2C_TransferCompleteFlag))
 + ;
 +
 + iTemperature = eeprom_data[0];​
 + iTemperature = iTemperature << 8;
 + iTemperature |= eeprom_data[1];​
 + GPIO_PinWrite(GPIOB,​ 10U, 0);
 +
 + fTemp = (float)iTemperature;​
 +
 + if(iTemperature >= C[4]){
 + dut = fTemp - (float)C[4] - ((fTemp-(float)C[4])/​128.0) * ((fTemp-(float)C[4])/​128.0) * (float)coef_A / (float)(2^coef_C);​
 + }else{
 + dut = fTemp - (float)C[4] - ((fTemp-(float)C[4])/​128.0) * ((fTemp-(float)C[4])/​128.0) * (float)coef_B / (float)(2^coef_C);​
 + }
 +
 + offset = ((float)C[1]+((float)C[3]-1024.0)*dut/​16384.0)*4.0;​
 + sensitivity = (float)C[0]+ (float)C[2]*dut/​1024.0;​
 + xpress = sensitivity * ((float)iPressure-7168.0)/​16384.0 - offset;
 + fPressure = xpress*10.0/​32.0+(float)C[6] + 253.0;
 + return (fPressure/​10.0);​
 +}
 +</​code>​
 +
 +==== TFT display a FlexBus ====
 +
 +Pre riadenie TFT display-u som využil hotovú knižnicu:
 +https://​www.element14.com/​community/​groups/​development-tools/​blog/​2012/​05/​26/​stm32f4-discovery-hy32d-tft-lcd Tú som však musel naportovať pre K64 procesor a zbernicu FluxBus:
 +Inicializácia:​
 +<code c>
 +void Init_FlexBus(void){
 + flexbus_config_t flexbusUserConfig;​
 +
 + FLEXBUS_GetDefaultConfig(&​flexbusUserConfig);​
 +
 + flexbusUserConfig.waitStates = 2U;
 + flexbusUserConfig.portSize = kFLEXBUS_2Bytes;​
 + flexbusUserConfig.chipBaseAddress = (uint32_t)TFT_DC_ADDRESS;​
 + flexbusUserConfig.chipBaseAddressMask = 1U;
 + flexbusUserConfig.byteLaneShift = kFLEXBUS_Shifted;​
 + flexbusUserConfig.autoAcknowledge = true;
 +
 + FLEXBUS_Init(FB,​ &​flexbusUserConfig);​
 + }
 +</​code>​
 +Zápis dát do pamäte a do registrov:
 +<code c>
 +void vfnSendDataWord(unsigned short value)
 +  {
 +    *((unsigned short*)TFT_BASE_ADDRESS) = value;
 +  }
 +
 +void vfnSendCmdWord(unsigned short cmd)
 +  {
 +    *((unsigned short*)TFT_DC_ADDRESS) = cmd;
 +  }
 +</​code>​
 +
 +==== RTC ====
 +
 +Inicializácia a nastavenie hodín reálneho času:
 +<code c>
 +void Init_rtc(void){
 +
 + rtc_config_t rtcConfig;
 +
 + RTC_GetDefaultConfig(&​rtcConfig);​
 + RTC_Init(RTC,​ &​rtcConfig);​
 +     /* Select RTC clock source */
 + RTC_SetClockSource(RTC);​
 +}
 +
 +void rtc_settime(rtc_datetime_t date){
 +
 +   RTC_StopTimer(RTC);​
 +   RTC_SetDatetime(RTC,​ &date);
 +   RTC_StartTimer(RTC);​
 +}
 +
 +rtc_datetime_t rtc_gettime(void){
 +
 + rtc_datetime_t date;
 +
 + RTC_GetDatetime(RTC,​ &date);
 + return(date);​
 +}
 +</​code>​
 +
 +==== Hlavná slučka a Fat FS ====
 +Kinetis software development kit obsahuje okrem štandardných ovládačov periférií aj middleware pre prácu s USB a SD kartami s podporou Fat FS, ktorý som použil. Tým, že zapisujem namerané údaje v textovom formáte, tieto sú po pripojeni SD karty do počítača bezproblémov spracovateľné. ​ V hlavnej slučke sa periodicky vyčítavajú údaje, ktoré sa okamžite zobrazujú na display-i a každých 10s sa otvorí súbor pre zápis a udaje sa zapíšu vo formáte dátum, čas, koncentrácia CO2, teplota, vlhkosť a tlak. Po zápise sa súbor okamžite uzavrie.
 +<code c>
 +while (1) {
 +
 + date = rtc_gettime();​
 + sprintf(str,​ "​%02hd-%02hd-%04hd %02hd:​%02hd:​%02hd ​    ",​ date.day,
 + date.month,​ date.year, date.hour, date.minute,​ date.second);​
 +
 + LCD_SetTextColor(ASSEMBLE_RGB(0,​ 0, 0));
 + LCD_CharSize(16);​
 + LCD_StringLine(1,​ 1, (uint8_t*) str);
 + co_value = get_concentration();​
 + sprintf(str,​ "​CO2:​%d ppm", co_value);
 + LCD_SetTextColor(ASSEMBLE_RGB(0,​ 0, 0xFF));
 + LCD_CharSize(24);​
 + LCD_StringLine(1,​ 16, (uint8_t*) str);
 +
 + temperature = read_temp();​
 + humidity = read_hum();
 + LCD_SetTextColor(ASSEMBLE_RGB(0xFF,​ 0, 0));
 + sprintf(str,​ "​T: ​  %2.2f C", temperature);​
 + LCD_StringLine(1,​ 40, (uint8_t*) str);
 + LCD_SetTextColor(ASSEMBLE_RGB(0,​ 0, 0xFF));
 + sprintf(str,​ "​RH: ​ %2.2f %%", humidity);
 + LCD_StringLine(1,​ 64, (uint8_t*) str);
 + LCD_SetTextColor(ASSEMBLE_RGB(0xFF,​ 0, 0));
 + pressure = read_pressure();​
 + sprintf(str,​ "​P:​%6.2fhPa",​ pressure);
 + LCD_StringLine(1,​ 88, (uint8_t*) str);
 + Delay(10);​
 +
 + if(card_ok && prev_second != date.second && !(date.second % 10)){
 + sprintf(g_bufferWrite,​ "​%02hd-%02hd-%04hd %02hd:​%02hd:​%02hd %d %2.2f %2.2f %6.2f \r\n", date.day,
 + date.month,​ date.year, date.hour, date.minute,​ date.second,​ co_value, temperature,​ humidity, pressure);
 + f_open(&​g_fileObject,​ _T("/​data.dat"​),​ (FA_WRITE | FA_READ | FA_OPEN_APPEND));​
 +
 + error = f_write(&​g_fileObject,​ g_bufferWrite,​ strlen(g_bufferWrite),​ &​bytesWritten);​
 + f_close(&​g_fileObject);​
 + prev_second = date.second;​
 + }
 + }
 +</​code>​
 +===== Video datalogger =====
 +{{youtube>​R_bAfAzXU1A?​medium}}
 +
 +===== Výpis dát =====
 +V tomto bolku je príklad zmeraných dát, potom ako som začal vetrať. Je vidieť, ako klesá koncentrácia CO2, ale zároveň aj s teplotou...
 +
 +<​file>​
 +14-01-2018 17:20:10 1052 21.98 27.91 1017.92 ​
 +14-01-2018 17:20:20 1021 21.99 27.36 1017.80 ​
 +14-01-2018 17:20:30 971 21.93 26.92 1017.80 ​
 +14-01-2018 17:20:40 955 21.92 26.60 1017.67 ​
 +14-01-2018 17:20:50 939 21.87 25.60 1017.90 ​
 +14-01-2018 17:21:00 920 21.83 24.97 1017.95 ​
 +14-01-2018 17:21:10 909 21.79 24.63 1017.90 ​
 +14-01-2018 17:21:20 884 21.73 24.27 1017.90 ​
 +14-01-2018 17:21:30 898 21.64 24.33 1017.95 ​
 +14-01-2018 17:21:40 883 21.58 23.90 1017.99 ​
 +14-01-2018 17:21:50 917 21.50 24.53 1017.89 ​
 +14-01-2018 17:22:00 905 21.41 24.16 1018.08 ​
 +14-01-2018 17:22:10 872 21.35 23.40 1017.94 ​
 +14-01-2018 17:22:20 862 21.24 23.51 1017.98 ​
 +14-01-2018 17:22:30 909 21.13 23.87 1017.94 ​
 +14-01-2018 17:22:40 861 21.13 22.79 1017.95 ​
 +14-01-2018 17:22:50 833 21.12 22.56 1017.95 ​
 +14-01-2018 17:23:00 841 21.11 22.62 1018.04 ​
 +14-01-2018 17:23:10 821 21.02 22.26 1017.94 ​
 +14-01-2018 17:23:20 814 20.96 22.06 1018.06 ​
 +14-01-2018 17:23:30 803 20.91 21.89 1018.05 ​
 +14-01-2018 17:23:40 819 20.86 21.93 1017.82 ​
 +14-01-2018 17:23:50 864 20.76 23.28 1018.07 ​
 +14-01-2018 17:24:00 841 20.71 22.27 1017.97 ​
 +14-01-2018 17:24:10 799 20.64 21.51 1018.00 ​
 +14-01-2018 17:24:20 794 20.58 21.94 1018.07 ​
 +</​file>​
 +
 +
 +==== Záver ====
 +
 +Tento projekt je prototyp, na ktorom som si overil rôzne senzory, vyskúšal som prostredie MCUXpresso firmy NXP a ich software-ové knižnice pre prácu s ARM procesormi Kinetis KSDK verzie 2.3. K tomu, aby to bol plnohodnotný projekt je nutné prerobiť a dorobiť niekoľko vecí. Najmä radiče pre komunikáciu prerobiť z blokovacieho na neblokovací režim, veľa času stráca procesor tým, že čaká, kým periféria zmeria a odpovie. Ďalej je nutné prerobiť HW vývojovej dosky na zálohovanie z batérie pre kalibračné dáta a hodiny reálneho času. Takisto ovládanie z konzoly a prekopírovávanie uložených dát. Z užívateľského rozhrania je vhodné dorobiť grafické zobrazenie údajov v čase. Debug sériový port, ktorý je teraz použitý previesť na USB com port, a tento sériový port priviesť na malý WiFi modul so serverom, na ktorom budú prístupné namerané údaje z lokálnej siete. Za úvahu stojí aj zmena senzora koncentrácie CO2, keďže je to už pomerne obsolete senzor, ktorý je náchylný na všetky parametre ako napájacie napätie, ktoré v tomto prípade nie je vôbec stabilné, nepresnosť,​ stále je nutné ho kalibrovať a náročný prepočet. ​
 +
 +Zdroje:{{ :​2017:​xwalde01:​envilogger.rar | Zdrojové súbory}}
 +
  
2017/envi-logger.1516593098.txt.gz · Poslední úprava: 2018/01/22 04:51 autor: Miroslav Waldecker