Современная электроника №8/2022
ИНЖЕНЕРНЫЕ РЕШЕНИЯ 43 WWW.SOEL.RU СОВРЕМЕННАЯ ЭЛЕКТРОНИКА ◆ № 8 2022 которые могут показывать время (часы, минуты и секунды) при определённом состоянии управляющего сигнала HK (см. рис. 1 первой части статьи), одна- ко этот режим в приборе не использу- ется (но такая возможность сохранена). Программируется этот ЖКИ достаточ- но просто, однако, на взгляд автора, имеются две проблемы, вызывающие некоторые затруднения в программи- ровании на C51 вывода информации на этот дисплей. Первая проблема: как программно вывести байт через какой- либо порт МК, вторая – каким образом получить десятичные цифры для выво- да на ЖКИ, например, 16-разрядного числа. Вначале о 1-й проблеме. Она может быть решена двумя способами. Пер- вый способ – использовать аппарат- ный SPI и подпрограмму вывода по SPI для BME280, рассмотреннуюранее. Но в этом случае в связи с разными скоростя- ми обмена для BME280 (5 Мбод) иЖКИ (максимум 0,5 Мбод, т.е. на порядок меньше), а также разными настройками (в частности, полярности ифазы), при- дётся каждый раз при выводе инфор- мации наЖКИ и BME280 изменять эти настройки, что очень неудобно. Второй способ – вывести байт в ЖКИ «вручную», т.е. программным способом. Каким образом это мож- но сделать достаточно просто? Как ни странно, но на ассемблере такой вывод не вызывает затруднений. Если имеется байт, и его требуется вывести последовательно через какой-либо порт, например P0.1, то такая проце- дура хорошо известна: байт сдвигает- ся влево через бит переноса C, в кото- ром появляется старший бит байта, т.е. 7-й бит. Далее порту P0.1 присваива- ется значение бита переноса C, и для записи в периферийное устройство (ЖКИ) он стробируется импульсом CLK через какой-либо второй порт, например, P0.2. Для передачи сле- дующего бита байт сдвигается вле- во ещё раз, в C попадает уже 6-й бит, и эта процедура повторяется 7 раз, пока не выведется весь байт. Но в C51 нет такого понятия, как бит перено- са C. Как здесь быть? К счастью, в C51 имеется «лазейка», которая позволя- ет вывести байт подобным образом. Здесь необходимо напомнить, что в области памяти МК EFM8SB10 есть 16 байт с побитовой адресацией (нам хватит и одного). Эта область памяти именуется как bdata. Адресация каж- дого бита байта из области bdata про- исходит точно так же, как это приня- то для портов МК. Например, для бит DI и CLK, выводимых с портов P0.1 и P0.2 соответственно, эта адресация приведена ниже. s bit DI = P0^1; sbit CLK = P0^2; Если назначить какой-либо байт, например, BYTEIO из области bdata, и конкретный бит BITIO, как, напри- мер, 7-й бит BITEIO, то такое назначе- ние на C51 будет выглядеть так: bdata uint8_t BYTEIO; sbit BITIO=BYTEIO^7; Если теперь присвоить выводимо- му через порт P0.1 биту DI значение BITIO, простробировать каждый выво- димый бит сигналом CLK (изменяя его значение с лог.0 на лог.1 и обратно с задержкой 10 мкс) и сдвигать байт BYTEIO циклически влево на 1 бит командой _crol_(BYTEIO,1), то для вывода всего байта получим следую- щую достаточно простую процедуру (т.е. подпрограмму «ручного» выво- да байта): void OUTBLCD(uint8_t OUTB){// Вывод байта в ЖКИ uint8_t j; BYTEIO=OUTB; for (j=0;j<8;j++){ DI=BITIO; CLK=1; DEL10US(); CLK=0; DEL10US(); BYTEIO=_crol_(BYTEIO,1); } } Теперь о том, как получить десятич- ные цифры для вывода 16-разрядно- го числа. Пусть имеется 16-разрядное чис- ло, например, давление P, которое в результате расчётов по формулам для BME280 равно 751 мм рт. ст. В МК это число представлено в двоичном виде, что в 16-ричном виде соответствует числу 0x02ef. Как получить цифры «7», «5» и «1» из этого числа и как их выве- сти на ЖКИ? Эта задача решается так- же достаточно просто. Для этого в области памяти про- грамм (code) необходимо завести мас- сив M[12], состоящий из 12 элементов, коды которых соответствуют кодам выводимых цифр (эти коды приведе- ны в справочном листке (datasheet) на контроллер): code uint8_t M[12]= {//”0” “1” “2” “3” “4” “5” “6” “7” “8” “9” blank “-” 0x0a,0x01,0x02,0x03,0x04,0x05,0x0 6,0x07,0x08,0x09,0x00,0x0f}; Если внимательно приглядеться к этому массиву, то можно обнаружить, что код того или иного элемента мас- сива соответствует его номеру в масси- ве, или, другими словами, его индексу (например, i , в массиве M[ i ]). Напри- мер, код цифры «0» (0x0a) содержит- ся в 0-м элементе массива, код чис- ла «5» (0x05) – в 5-м элементе и т.п. Таким образом, если требуется вывести, например, цифру «5», то, задав индекс i = 5, получим М[5], что соответствует выводимой «пятёрке». Для того чтобы из выводимого числа получить цифры для вывода на ЖКИ, можно воспользоваться оператором sprintf [параметры], используемым для «печати» информации. Этот опе- ратор работает так же, как и оператор printf [параметры], используемый для распечатки данных на мониторе ком- пьютера, выводимых через интерфейс RS-232 (COM-порт). В отличие от опе- ратора printf, который посылает дан- ные на COM-порт компьютера, опе- ратор sprintf помещает эти данные в специальный буфер (массив) в памя- ти МК. Этот буфер указывается в пара- метрах sprintf. В качестве примера рассмотрим вывод на ЖКИ идентификационного номера (ID) BME280, который равен 60h (58h в BMP280). Пусть считан- ный из BME280 идентификационный номер расположен в однобайтовой переменной CHID. Заведём два масси- ва: 1-й (buf[5]) – для вывода пяти байт в ЖКИ (что соответствует выводу всех десяти знакомест, каждое из которых состоит из полубайта или тетрады), 2-й (bufTP[7]) – для получения чисел для давления (3 цифры), влажности (2 цифры) и температуры (2 циф- ры), т.е. всего 7 цифр. Для ID требу- ется только 2 цифры, так что можно воспользоваться этим же массивом (bufTP[7]). Вначале обнуляем массив buf. Затем «печатаем» CHID-оператором sprintf в формате двух 16-ричных цифр в bufTP. После этого необходимо изба- виться от «тройки» в старшем полубай-
RkJQdWJsaXNoZXIy MTQ4NjUy