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> | + | {{tag> |
В этой заметке будет рассматриваться работа контроллера STM8L15x с шиной I2C в режиме мастер. | В этой заметке будет рассматриваться работа контроллера STM8L15x с шиной I2C в режиме мастер. | ||
Строка 10: | Строка 10: | ||
Поэтому, | Поэтому, | ||
+ | |||
+ | Код писался под микроконтроллер STM8L151C6/ | ||
Для начала, | Для начала, | ||
Строка 379: | Строка 381: | ||
</ | </ | ||
+ | Пример применения будет выглядеть примерно так (на примере чтения термодатчика WF5803F): | ||
+ | |||
+ | <sxh cpp> | ||
+ | typedef enum { | ||
+ | ts_Start, | ||
+ | ts_InProgress, | ||
+ | ts_Ready | ||
+ | } TS_State_t; | ||
+ | |||
+ | static TS_State_t | ||
+ | |||
+ | 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< | ||
+ | data[0] = 0x0A; | ||
+ | |||
+ | res = TS_I2C_Write(0x30, | ||
+ | | ||
+ | /*!< While the bus is busy */ | ||
+ | // Это ожидание не обязательно, | ||
+ | // Без этого, уходит "в сон" | ||
+ | Wait_While_Flag_Set(SR3, | ||
+ | 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, | ||
+ | if (*Result && | ||
+ | (data[0] & 0x01) ) { | ||
+ | //Data Ready | ||
+ | |||
+ | } | ||
+ | } while (*Result && i2cTimeoutDelay1ms && !(data[0] & 0x01)); | ||
+ | |||
+ | if (*Result) { | ||
+ | *Result = TS_I2C_Read(0x06, | ||
+ | } | ||
+ | |||
+ | if (*Result) { | ||
+ | T = calculatePress(data); | ||
+ | } | ||
+ | return T; | ||
+ | } | ||
+ | |||
+ | /** | ||
+ | * @brief Чтение температуры. Вызывается из главного цикла несколько раз с интервалом 20мс (пока Result не примет истинное значение) | ||
+ | * @param Result указателдь на код результата операции: | ||
+ | * | ||
+ | * | ||
+ | * @return int16_t Температура (q12, | ||
+ | * | ||
+ | */ | ||
+ | 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, | ||
+ | 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; | ||
+ | } | ||
+ | </ | ||
sources/stm8l_i2c.txt · Последнее изменение: 2024/03/15 15:12 — Юрий