Например TDA7294

Форум РадиоКот • Просмотр темы - Часы на светодиодных матрицах с драйверами MAX7219
Форум РадиоКот
Здесь можно немножко помяукать :)

Текущее время: Сб авг 02, 2025 14:01:10

Часовой пояс: UTC + 3 часа


ПРЯМО СЕЙЧАС:



Начать новую тему Ответить на тему  [ Сообщений: 1849 ]     ... , , , 86, , , ...  
Автор Сообщение
Не в сети
 Заголовок сообщения: Re: Часы на светодиодных матрицах с драйверами MAX7219
СообщениеДобавлено: Вт апр 21, 2020 10:01:23 
Друг Кота
Аватар пользователя

Карма: 86
Рейтинг сообщений: 1035
Зарегистрирован: Чт апр 11, 2013 11:19:59
Сообщений: 4884
Откуда: Минск
Рейтинг сообщения: 0
Ну кто ж вам запретит?


Вернуться наверх
 
Не в сети
 Заголовок сообщения: Re: Часы на светодиодных матрицах с драйверами MAX7219
СообщениеДобавлено: Чт апр 30, 2020 22:24:50 
Встал на лапы
Аватар пользователя

Карма: 2
Рейтинг сообщений: 14
Зарегистрирован: Ср июн 04, 2008 00:22:30
Сообщений: 127
Откуда: Украина, Ковель
Рейтинг сообщения: 0
Вроде разобрался как сделать. Не знаю правильно или нет, но работает.
В файле bmp180.c сделал изменения. Калибровочная величина записывается в 0x19 байт eeprom. Можно уходить в обе стороны.
Выкладываю код. Может кому пригодится и автор покритикует... :)
Код:
void bmp180Convert (void)
{
    int8_t pcor;
    pcor = eeprom_read_byte((uint8_t*)0x19);


    pressure = (p + ((x1 + x2 + 3791) >> 4)) * 3 / 40 + pcor;


Вернуться наверх
 
Не в сети
 Заголовок сообщения: Re: Часы на светодиодных матрицах с драйверами MAX7219
СообщениеДобавлено: Пт май 01, 2020 00:00:04 
Друг Кота
Аватар пользователя

Карма: 86
Рейтинг сообщений: 1035
Зарегистрирован: Чт апр 11, 2013 11:19:59
Сообщений: 4884
Откуда: Минск
Рейтинг сообщения: 1
Немножко покритикую.

1. Лучше в eeprom.h добавить макрос, по аналогии с другими ячейками.
2. Коррекцию проводить не в драйвере bmp180, а непосредственно при выводе на экран. Т.е., в функции loadTempString(), там где вызывается bmp180GetPressure().
3. К коррекции лучше добавить +1. Тогда значение ячейки eeprom по умолчанию (0xFF = -1) будет как бы нулём и не будет влиять на показания.


Вернуться наверх
 
Не в сети
 Заголовок сообщения: Re: Часы на светодиодных матрицах с драйверами MAX7219
СообщениеДобавлено: Пт май 01, 2020 09:08:34 
Встал на лапы
Аватар пользователя

Карма: 2
Рейтинг сообщений: 14
Зарегистрирован: Ср июн 04, 2008 00:22:30
Сообщений: 127
Откуда: Украина, Ковель
Рейтинг сообщения: 0
Спасибо за критику. По поводу eeprom.h сразу хотел так сделать. Но не смог реализовать, так как не хватает знаний и опыта в программировании. Потихоньку изучаю...
Добавил в eeprom.h строку #define EEPROM_BMP180CORR 0x19. Теперь разбираюсь как извлечь для подстановки сюда -> eeprom_read_byte((uint8_t*)0x19);


Вернуться наверх
 
Не в сети
 Заголовок сообщения: Re: Часы на светодиодных матрицах с драйверами MAX7219
СообщениеДобавлено: Пт май 01, 2020 09:54:16 
Друг Кота
Аватар пользователя

Карма: 86
Рейтинг сообщений: 1035
Зарегистрирован: Чт апр 11, 2013 11:19:59
Сообщений: 4884
Откуда: Минск
Рейтинг сообщения: 1
Ну вот вместо 0x19 и вставлять.

Вчера попробовал собрать код более новыми версиями компилятора - не получается влезть в 8 килобайт. Надо бы сесть и немного оптимизацией заняться...


Вернуться наверх
 
Не в сети
 Заголовок сообщения: Re: Часы на светодиодных матрицах с драйверами MAX7219
СообщениеДобавлено: Пт май 01, 2020 10:22:47 
Встал на лапы
Аватар пользователя

Карма: 2
Рейтинг сообщений: 14
Зарегистрирован: Ср июн 04, 2008 00:22:30
Сообщений: 127
Откуда: Украина, Ковель
Рейтинг сообщения: 0
Чудеса :shock: раньше так делал и не получалось, а теперь после подсказки все собралось. Наверное допустил синтаксическую ошибку. Спасибо, WiseLord, за подсказку!
Код:
static void loadTempString(void)
{
    uint8_t i;
    uint8_t sm = eep.sensMask;
    int8_t pcor;
    pcor = eeprom_read_byte((uint8_t*)EEPROM_BMP180CORR);


    if (bmp180HaveSensor() && (sm & SENS_MASK_BMP_PRES)) {
        loadPlaceString(LABEL_PRESSURE);
        matrixScrollAddString(" ");
        loadSensorString(bmp180GetPressure() + pcor + 1, LABEL_MMHG);


Тоже пробовал собирать avr-gcc-5.4.0 - не влезает. Сейчас в VirtualBox Debian 9 avr-gcc-4.9.2 и пока помещаюсь - ровно 8192.


Вернуться наверх
 
Не в сети
 Заголовок сообщения: Re: Часы на светодиодных матрицах с драйверами MAX7219
СообщениеДобавлено: Пт май 01, 2020 12:44:51 
Друг Кота
Аватар пользователя

Карма: 86
Рейтинг сообщений: 1035
Зарегистрирован: Чт апр 11, 2013 11:19:59
Сообщений: 4884
Откуда: Минск
Рейтинг сообщения: 1
Попробовал немного оптимизировать код - вроде как с сотню байт удалось выжать. Залил исходники на Github


Вернуться наверх
 
Не в сети
 Заголовок сообщения: Re: Часы на светодиодных матрицах с драйверами MAX7219
СообщениеДобавлено: Пт май 01, 2020 14:54:11 
Встал на лапы
Аватар пользователя

Карма: 2
Рейтинг сообщений: 14
Зарегистрирован: Ср июн 04, 2008 00:22:30
Сообщений: 127
Откуда: Украина, Ковель
Рейтинг сообщения: 0
Да, реально уменьшился код. Спасибо!
Код:
AVR Memory Usage:

Program:  8122 bytes (.text + .data)
Data:     591 bytes (.data + .bss)
А можно еще вопрос? Хочу изменить ширину пробела до 2-х символов (0x00, 0x00, VOID, VOID, VOID). Но во всех настройках портится первый символ и бегущая строка раньше обрывается. Не подскажете где копать?


Вернуться наверх
 
Не в сети
 Заголовок сообщения: Re: Часы на светодиодных матрицах с драйверами MAX7219
СообщениеДобавлено: Пт май 01, 2020 15:58:24 
Друг Кота
Аватар пользователя

Карма: 86
Рейтинг сообщений: 1035
Зарегистрирован: Чт апр 11, 2013 11:19:59
Сообщений: 4884
Откуда: Минск
Рейтинг сообщения: 0
При выводе цифр есть фишка - все они должны быть одной ширины, такой же как и пробел - чтобы было проще реализовать разного рода мигания и скроллинги. Поэтому простым способом, наверное, не получится сделать.

Хотя можете попробовать.

В коде есть несколько вызовов типа mkNumberString(value, 2, ' '). Это формирование строчки из некоторого числа value. двойка - это ширина (в символах) на выходе, ' ' - это пробел, которым будут заполнены нулевые символы в начале. То есть, для числа 34 сформируется строка "34", а для числа 2 - строка " 2". А если вызывать как mkNumberString(value, 2, '0') - то соотвестсвенно сформировались бы "23" и "02".

В общем, идея следующая. Найти по коду эти вызовы, там где они вызываются с пробелом. Вместо пробела подставить другой символ, например 0xBE. Сейчас он не используется (в font-cp1251-08.c), и там идёт сплошная заливка знакоместа, если вдруг такой символ встретится.

Нужно отрисовать этот символ в пробел (0x00, 0x00, 0x00, 0x00, VOID), и вызывать теперь mkNumberString(value, 2, 0xBE); Тогда все статичные цифры будут отображаться как раньше, без сдвигов. А уже основной пробел можно обрезать до двух-трёх пикселов.

Или взять не 0xBE, а какой-нибудь другой символ, из таблицы CP1251, наименее нужный (типа 0xAC).


Вернуться наверх
 
Не в сети
 Заголовок сообщения: Re: Часы на светодиодных матрицах с драйверами MAX7219
СообщениеДобавлено: Пт май 01, 2020 17:46:18 
Встал на лапы
Аватар пользователя

Карма: 2
Рейтинг сообщений: 14
Зарегистрирован: Ср июн 04, 2008 00:22:30
Сообщений: 127
Откуда: Украина, Ковель
Рейтинг сообщения: 0
Спасибо за подробные разъяснения :beer:
На выходных будет чем заняться.


Вернуться наверх
 
Не в сети
 Заголовок сообщения: Re: Часы на светодиодных матрицах с драйверами MAX7219
СообщениеДобавлено: Пн май 04, 2020 20:57:02 
Встал на лапы
Аватар пользователя

Карма: 2
Рейтинг сообщений: 14
Зарегистрирован: Ср июн 04, 2008 00:22:30
Сообщений: 127
Откуда: Украина, Ковель
Рейтинг сообщения: 0
В общем, идея следующая. Найти по коду эти вызовы, там где они вызываются с пробелом. Вместо пробела подставить другой символ, например 0xBE. Сейчас он не используется (в font-cp1251-08.c), и там идёт сплошная заливка знакоместа, если вдруг такой символ встретится.

Нужно отрисовать этот символ в пробел (0x00, 0x00, 0x00, 0x00, VOID), и вызывать теперь mkNumberString(value, 2, 0xBE); Тогда все статичные цифры будут отображаться как раньше, без сдвигов. А уже основной пробел можно обрезать до двух-трёх пикселов.

Сделал все следуя Вашим разъяснениям. Считаю, получилось :-) Но немного по-другому...
Вместо пробела и в коде (там где он используется), и в надписях использовал символ "]" 0x5D. Так проще писать когда нужно в редакторе eeprom использовать "короткий пробел".
Благодарю!


Вернуться наверх
 
Не в сети
 Заголовок сообщения: Re: Часы на светодиодных матрицах с драйверами MAX7219
СообщениеДобавлено: Вт май 19, 2020 10:01:51 
Встал на лапы
Аватар пользователя

Карма: 2
Рейтинг сообщений: 14
Зарегистрирован: Ср июн 04, 2008 00:22:30
Сообщений: 127
Откуда: Украина, Ковель
Рейтинг сообщения: 0
WiseLord, пожалуйста, подскажите как реализована функция записи и чтения байта?
Например, записать в устройство 0x76, адрес 0xF5, значение 0xA0.


Вернуться наверх
 
Не в сети
 Заголовок сообщения: Re: Часы на светодиодных матрицах с драйверами MAX7219
СообщениеДобавлено: Вт май 19, 2020 10:16:30 
Друг Кота
Аватар пользователя

Карма: 86
Рейтинг сообщений: 1035
Зарегистрирован: Чт апр 11, 2013 11:19:59
Сообщений: 4884
Откуда: Минск
Рейтинг сообщения: 0
Про какие устройства и адреса речь?


Вернуться наверх
 
Не в сети
 Заголовок сообщения: Re: Часы на светодиодных матрицах с драйверами MAX7219
СообщениеДобавлено: Вт май 19, 2020 10:27:45 
Встал на лапы
Аватар пользователя

Карма: 2
Рейтинг сообщений: 14
Зарегистрирован: Ср июн 04, 2008 00:22:30
Сообщений: 127
Откуда: Украина, Ковель
Рейтинг сообщения: 0
Датчик BME280 его ID на шине 0x76. Записать по адресу 0xF5 значение 0xA0.
Есть желание попробовать написать драйвер для него...


Вернуться наверх
 
Не в сети
 Заголовок сообщения: Re: Часы на светодиодных матрицах с драйверами MAX7219
СообщениеДобавлено: Вт май 19, 2020 10:33:05 
Друг Кота
Аватар пользователя

Карма: 86
Рейтинг сообщений: 1035
Зарегистрирован: Чт апр 11, 2013 11:19:59
Сообщений: 4884
Откуда: Минск
Рейтинг сообщения: 0
Код:
I2CswStart(0x76);
I2CswWriteByte(0xF5);
I2CswWriteByte(0xA0);
I2CswStop();
Можно для примера смотреть на код bmp180, dht22, rtc.


Вернуться наверх
 
Не в сети
 Заголовок сообщения: Re: Часы на светодиодных матрицах с драйверами MAX7219
СообщениеДобавлено: Вт май 19, 2020 10:35:35 
Встал на лапы
Аватар пользователя

Карма: 2
Рейтинг сообщений: 14
Зарегистрирован: Ср июн 04, 2008 00:22:30
Сообщений: 127
Откуда: Украина, Ковель
Рейтинг сообщения: 0
Спасибо. Буду заниматься...


Вернуться наверх
 
Не в сети
 Заголовок сообщения: Re: Часы на светодиодных матрицах с драйверами MAX7219
СообщениеДобавлено: Вт май 19, 2020 22:10:59 
Встал на лапы
Аватар пользователя

Карма: 2
Рейтинг сообщений: 14
Зарегистрирован: Ср июн 04, 2008 00:22:30
Сообщений: 127
Откуда: Украина, Ковель
Рейтинг сообщения: 0
Нужно извлечь последовательность из n-го количества байт. Задаю начальный адрес(start), буфер промежуточного хранения(buff[]) и длину последовательности(bytes).
Код:
void bme280ReadMem(uint8_t start, uint8_t buff[], uint8_t bytes)
{
    uint8_t i = 0;
    I2CswStart(BME280_ADDR);
    I2CswWriteByte(start);
    I2CswStart(BME280_ADDR | I2C_READ);
   for(i=0; i<bytes; i++) {
      if(i==bytes-1)
         buff[i] = I2CswReadByte(I2C_ACK);
      else
         buff[i] = I2CswReadByte(I2C_NOACK);
   }
    I2CswStop();
}

Затем
Код:
bme280ReadMem(BME280_ADC_DATA_START, data, BME280_ADC_DATA_BYTES);

Так должно работать?


Вернуться наверх
 
Не в сети
 Заголовок сообщения: Re: Часы на светодиодных матрицах с драйверами MAX7219
СообщениеДобавлено: Вт май 19, 2020 22:43:14 
Друг Кота
Аватар пользователя

Карма: 86
Рейтинг сообщений: 1035
Зарегистрирован: Чт апр 11, 2013 11:19:59
Сообщений: 4884
Откуда: Минск
Рейтинг сообщения: 0
Да. Если у bme280 именно такая адресация на чтение.

Разве что вторым параметром я бы uint8_t *buff сделал, а не массив.

Код:
void bme280ReadMem(uint8_t start, uint8_t *buff, uint8_t bytes)
{
    I2CswStart(BME280_ADDR);
    I2CswWriteByte(start);
    I2CswStart(BME280_ADDR | I2C_READ);
    for(uint8_t i = 0; i < bytes; i++) {
        buff[i] = I2CswReadByte(i == bytes - 1 ? I2C_ACK : I2C_NOACK);
    }
    I2CswStop();
}


Вернуться наверх
 
Не в сети
 Заголовок сообщения: Re: Часы на светодиодных матрицах с драйверами MAX7219
СообщениеДобавлено: Вт май 19, 2020 22:54:12 
Встал на лапы
Аватар пользователя

Карма: 2
Рейтинг сообщений: 14
Зарегистрирован: Ср июн 04, 2008 00:22:30
Сообщений: 127
Откуда: Украина, Ковель
Рейтинг сообщения: 0
Как пример использую этот исходник - https://github.com/Yenya/avr-bmp280/blo ... 0/bmp280.c


Вернуться наверх
 
Не в сети
 Заголовок сообщения: Re: Часы на светодиодных матрицах с драйверами MAX7219
СообщениеДобавлено: Чт май 21, 2020 10:51:41 
Встал на лапы
Аватар пользователя

Карма: 2
Рейтинг сообщений: 14
Зарегистрирован: Ср июн 04, 2008 00:22:30
Сообщений: 127
Откуда: Украина, Ковель
Рейтинг сообщения: 0
Пока написал только температуру и давление. Сначала не мог понять почему не инициализировался датчик. Потом посмотрел как сделано чтение в rtc.c и поменял местами команды I2C_ACK, I2C_NOACK. Заработало.
Формула расчета очень громоздкая. А если ее привести требуемым значениям, то вовсе не влазит в 8kb.

bme280.c
Спойлер
Код:
#include <string.h>
#include <util/delay.h>

#include "bme280.h"
#include "i2csw.h"

static int16_t  temperature = 0;
static int16_t pressure = 0;

static uint8_t bme280Sensor = 0;

void bme280ReadMem(uint8_t start, uint8_t *buff, uint8_t bytes)
{
    I2CswStart(BME280_ADDR);
    I2CswWriteByte(start);
    I2CswStart(BME280_ADDR | I2C_READ);
    for(uint8_t i = 0; i < bytes; i++) {
        buff[i] = I2CswReadByte(i == bytes - 1 ? I2C_NOACK : I2C_ACK);
    }
    I2CswStop();
}

static void bme280WriteMem(uint8_t reg, uint8_t value)
{
    I2CswStart(BME280_ADDR);
    I2CswWriteByte(reg);
    I2CswWriteByte(value);
    I2CswStop();
}

static union _bme280cal_union {
    uint8_t bytes[BME280_CAL_DATA_SIZE];
    struct {
        uint16_t dig_t1;
        int16_t  dig_t2;
        int16_t  dig_t3;
        uint16_t dig_p1;
        int16_t  dig_p2;
        int16_t  dig_p3;
        int16_t  dig_p4;
        int16_t  dig_p5;
        int16_t  dig_p6;
        int16_t  dig_p7;
        int16_t  dig_p8;
        int16_t  dig_p9;
    }
} bme280cal;

static void bme280GetCal(void)
{
    memset(bme280cal.bytes, 0, sizeof(bme280cal));
    bme280ReadMem(BME280_CAL_REG_FIRST, bme280cal.bytes, BME280_CAL_DATA_SIZE);
}

void bme280Init(void)
{
    uint8_t buffer[1];
    buffer[0] = 0;
    bme280ReadMem(BME280_ID_REG, buffer, 1);
    if (buffer[0] != BME280_ID_VAL) {
        bme280Sensor = 0;
        return;
    }

    bme280Sensor = 1;
    bme280GetCal();
    bme280WriteMem(BME280_CTRL_MEAS, 0x27);
    bme280WriteMem(BME280_CTRL_CONFIG, 0xA0);

    _delay_ms(BME280_CONV_TIME);

}

uint8_t bme280HaveSensor(void)
{
    return bme280Sensor;
}


#define bme280_20bit_reg(b1, b2, b3)    ( \
        ((int32_t)(b1) << 12) \
        | ((int32_t)(b2) << 4) \
        | ((int32_t)(b3) >> 4) \
)

void bme280Convert(void)
{
        uint8_t data[BME280_ADC_RAWDATA_BYTES];
        int32_t temp_raw, pres_raw,
        var1, var2, t_fine;

        // read the raw ADC data from the I2C registers
        bme280ReadMem(BME280_ADC_DATA_START, data, BME280_ADC_RAWDATA_BYTES);
        pres_raw = bme280_20bit_reg(data[0], data[1], data[2]);
        temp_raw = bme280_20bit_reg(data[3], data[4], data[5]);

        // compute the temperature
        var1 = ((((temp_raw >> 3) - ((int32_t)bme280cal.dig_t1 << 1)))
                * ((int32_t)bme280cal.dig_t2)) >> 11;
        var2 = (((((temp_raw >> 4) - ((int32_t)bme280cal.dig_t1))
                * ((temp_raw >> 4) - ((int32_t)bme280cal.dig_t1))) >> 12)
                * ((int32_t)bme280cal.dig_t3)) >> 14;
        t_fine = var1 + var2;
        temperature = ((t_fine * 5 + 128) >> 8);

        // compute the pressure
        var1 = (((int32_t)t_fine) >> 1) - (int32_t)64000;
        var2 = (((var1 >> 2) * (var1 >> 2)) >> 11) * ((int32_t)bme280cal.dig_p6);
        var2 = var2 + ((var1 * ((int32_t)bme280cal.dig_p5)) << 1);
        var2 = (var2 >> 2) + (((int32_t)bme280cal.dig_p4) << 16);
        var1 = (((bme280cal.dig_p3 * (((var1 >> 2) * (var1 >> 2)) >> 13)) >> 3)
                + ((((int32_t)bme280cal.dig_p2) * var1) >> 1)) >> 18;
        var1 = ((((32768 + var1)) * ((int32_t)bme280cal.dig_p1)) >> 15);

        if (var1 == 0) {
                pressure = 0;
        } else {
                pressure = (((uint32_t)(((int32_t)1048576)-pres_raw)
                        - (var2 >> 12))) * 3125;
                if (pressure < 0x80000000) {
                        pressure = (pressure << 1) / ((uint32_t)var1);
                } else {
                        pressure = (pressure / (uint32_t)var1) * 2;
                }
                var1 = (((int32_t)bme280cal.dig_p9) * ((int32_t)(((pressure>>3) * (pressure >> 3)) >> 13))) >> 12;
                var2 = (((int32_t)(pressure >> 2)) * ((int32_t)bme280cal.dig_p8)) >> 13;
                pressure = (uint32_t)((int32_t)pressure + ((var1 + var2 + bme280cal.dig_p7) >> 4));
        }
}

int16_t bme280GetTemp(void)
{
    return temperature;
}

int16_t bme280GetPressure(void)
{
    return pressure;
}


bme280.h
Спойлер
Код:
#ifndef BME280_H
#define BME280_H

#include <inttypes.h>

#define BME280_ADDR                 0xEC
#define BME280_ID_REG               0xD0
#define BME280_ID_VAL               0x60

// EEPROM calibration addresses
#define BME280_CAL_REG_FIRST        0x88
#define BME280_CAL_REG_LAST         0x9F
#define BME280_CAL_DATA_SIZE        (BME280_CAL_REG_LAST+1 - BME280_CAL_REG_FIRST)

// BME280 registers
#define BME280_CTRL_MEAS            0xF4
#define BME280_CTRL_CONFIG          0xF5

#define BME280_ADC_DATA_START       0xF7
#define BME280_ADC_RAWDATA_BYTES    6    // 3 bytes pressure, 3 bytes temperature

#define BME280_CONV_TIME            50

void bme280Init(void);
uint8_t bme280HaveSensor(void);

void bme280Convert(void);

int16_t bme280GetTemp(void);
int16_t bme280GetPressure(void);
int16_t bme280GetHumidity(void);

#endif // BME280_H


Вернуться наверх
 
Показать сообщения за:  Сортировать по:  Вернуться наверх
Начать новую тему Ответить на тему  [ Сообщений: 1849 ]     ... , , , 86, , , ...  

Часовой пояс: UTC + 3 часа


Кто сейчас на форуме

Сейчас этот форум просматривают: zmey71 и гости: 12


Вы не можете начинать темы
Вы не можете отвечать на сообщения
Вы не можете редактировать свои сообщения
Вы не можете удалять свои сообщения
Вы не можете добавлять вложения

Найти:
Перейти:  


Powered by phpBB © 2000, 2002, 2005, 2007 phpBB Group
Русская поддержка phpBB
Extended by Karma MOD © 2007—2012 m157y
Extended by Topic Tags MOD © 2012 m157y