Инструменты пользователя

Инструменты сайта


sources:stm8l_i2c

Различия

Показаны различия между двумя версиями страницы.

Ссылка на это сравнение

sources:stm8l_i2c [2024/03/15 14:12] – создано Юрийsources:stm8l_i2c [2024/03/15 15:12] (текущий) Юрий
Строка 4: Строка 4:
  
 ====== Работа с шиной I2C на STM8L ====== ====== Работа с шиной I2C на STM8L ======
-{{tag>исходники stm8l}}+{{tag>исходники stm8l STM8L151}}
  
 В этой заметке будет рассматриваться работа контроллера STM8L15x с шиной I2C в режиме мастер.  В этой заметке будет рассматриваться работа контроллера STM8L15x с шиной I2C в режиме мастер. 
Строка 10: Строка 10:
  
 Поэтому, на основе [[https://www.st.com/resource/en/application_note/an3281-stm8-8bit-mcus-ic-optimized-examples-stmicroelectronics.pdf|AN3281 Application note. STM8 8-bit MCUs I2C optimized examples]] был написан код, фрагменты которого приведены ниже. Код рассчитан на работу в режиме Master с одним Slave устройством. При несложной доработке, он подойдет и для работы с несколькими slave'ами. Поэтому, на основе [[https://www.st.com/resource/en/application_note/an3281-stm8-8bit-mcus-ic-optimized-examples-stmicroelectronics.pdf|AN3281 Application note. STM8 8-bit MCUs I2C optimized examples]] был написан код, фрагменты которого приведены ниже. Код рассчитан на работу в режиме Master с одним Slave устройством. При несложной доработке, он подойдет и для работы с несколькими slave'ами.
 +
 +Код писался под микроконтроллер STM8L151C6/STM8L151C8 но будет вполне работоспособен и на других чипах семейства STM8L.
  
 Для начала, макросы зависящие от конкретного контроллера и/или включения на плате: Для начала, макросы зависящие от конкретного контроллера и/или включения на плате:
Строка 379: Строка 381:
 </sxh> </sxh>
  
 +Пример применения будет выглядеть примерно так (на примере чтения термодатчика WF5803F):
 +
 +<sxh cpp>
 +typedef enum {
 +    ts_Start,
 +    ts_InProgress,
 +    ts_Ready
 +} TS_State_t;
 +
 +static TS_State_t  TS_State = (TS_State_t)0;
 +
 +uint8_t data[10];
 +
 +bool TS_I2C_StartConvertion(uint8_t timeout)
 +{
 +    bool res;
 +    // Установка счетчика таймаута (он декрементируется в прерывании таймера каждую миллисекунду)
 +    disableInterrupts();
 +    i2cTimeoutDelay1ms = timeout;
 +    enableInterrupts();
 +    /* Send Start Convertion 
 +    | 0x30 | CMD | RW | Sleep_time<3:0> | Sco | Measurement<2:0> | */
 +    data[0] = 0x0A;
 +
 +    res = TS_I2C_Write(0x30,data,1,&i2cTimeoutDelay1ms);
 +    
 +    /*!< While the bus is busy */
 +    // Это ожидание не обязательно, если контроллеру "есть чем заняться"
 +    // Без этого, уходит "в сон" раньше чем заканчивается передача последнего байта
 +    Wait_While_Flag_Set(SR3,I2C_SR3_BUSY,(i2cTimeoutDelay1ms == 0));
 +    return res;
 +}
 +
 +int16_t TS_I2C_ReadTemperature(uint8_t* Result, uint8_t timeout)
 +{
 +    uint16_t T;
 +    disableInterrupts();
 +    i2cTimeoutDelay1ms = timeout;
 +    enableInterrupts();
 +
 +    do {
 +        *Result = TS_I2C_Read(0x02,data,1,&i2cTimeoutDelay1ms);
 +        if (*Result && 
 +            (data[0] & 0x01) ) {
 +            //Data Ready
 +
 +        }
 +    } while (*Result && i2cTimeoutDelay1ms && !(data[0] & 0x01));
 +
 +    if (*Result) {
 +        *Result = TS_I2C_Read(0x06,data,5,&i2cTimeoutDelay1ms);
 +    }
 +
 +    if (*Result) {
 +        T = calculatePress(data);
 +    }
 +  return T;
 +}
 +
 +/**
 +  * @brief Чтение температуры. Вызывается из главного цикла несколько раз с интервалом 20мс (пока Result не примет истинное значение)
 +  * @param Result указателдь на код результата операции: TRUE - 
 +  *               успешно, FALSE - ошибка датчика
 +  *  
 +  * @return int16_t Температура (q12,4). 
 +  * 
 +*/
 +int16_t TS_I2C_GetTemperature(uint8_t * Result)
 +{
 +    uint16_t T = 0;
 +    bool res;
 +    *Result = FALSE;
 +
 +    switch (TS_State) {
 +    case ts_Start : 
 +        TS_I2C_Start();
 +        TS_State = ts_InProgress;
 +        break;
 +    case ts_InProgress :
 +        TIM3_On();
 +        res = TS_I2C_StartConvertion(3);
 +        TIM3_Off();
 +        if (res) {
 +            TS_State = ts_Ready;
 +        } else {
 +            if ( --Rep ) {
 +                TS_I2C_Stop();
 +                TS_State = ts_Start;
 +            } else {
 +                flags.flNeedTermo = 0;
 +                Rep = REPEATE_CNT;
 +                TS_I2C_Stop();
 +                SET_ALARM(TempSemsorFail);
 +                TS_State = ts_Start;
 +            }
 +        }
 +        break;
 +    case ts_Ready : 
 +        TIM3_On();
 +        T = TS_I2C_ReadTemperature(Result,4);
 +        TIM3_Off();
 +        if (*Result) {
 +            Rep = REPEATE_CNT;
 +            TS_I2C_Stop();
 +            CLEAR_ALARM(TempSemsorFail);
 +            TS_State = ts_Start;
 +        } else {
 +            if ( --Rep ) {
 +                TS_I2C_Stop();
 +                TS_State = ts_Start;
 +            } else {
 +                flags.flNeedTermo = 0;
 +                Rep = REPEATE_CNT;
 +                TS_I2C_Stop();
 +                SET_ALARM(TempSemsorFail);
 +                TS_State = ts_Start;
 +            }
 +        }
 +        break;
 +    default: 
 +        TS_State = ts_Start;
 +    }
 +    return T;
 +}
 +</sxh>
  
  
sources/stm8l_i2c.txt · Последнее изменение: 2024/03/15 15:12 — Юрий

Если не указано иное, содержимое этой вики предоставляется на условиях следующей лицензии: GNU Free Documentation License 1.3
GNU Free Documentation License 1.3 Donate Powered by PHP Valid HTML5 Valid CSS Driven by DokuWiki