Современная электроника №2/2024

ИНЖЕНЕРНЫЕ РЕШЕНИЯ 40 WWW.SOEL.RU СОВРЕМЕННАЯ ЭЛЕКТРОНИКА • № 2 / 2024 SCK в отсутствие обмена (Clock Polarity) находится в низком уровне (Low in idle state), а у DDS – в высоком . Но посколь - ку обмен информацией МК с дисплеем происходит на порядок чаще , при ини - циализации устройств выбираем пра - вильную полярность для дисплея (Low in idle state), а перед началом обмена с DDS уже программным способом необ - ходимо переключить полярность на обратную и после окончания обмена – восстановить прежнюю . Это переклю - чение осуществляется изменением бита полярности в регистре SPI0CFG. Други - ми словами , при выводе информации в DDS вначале необходимо переклю - чить бит полярности с « дисплейного » ( заданного в начальной конфигурации ) на «DDS- й », а после окончания выво - да восстановить первоначальное его ( бита ) значение , иначе дисплей рабо - тать не будет . Теперь более конкретно . Вот совмещение двухбайтного чис - ла U.US и массива с двумя элемента - ми : U.UB[ 0] – старший байт и U.UB [1] – младший байт , которые , во - первых , перераспределяют одно и то же место в памяти МК , во - вторых , строго опреде - ляют друг друга , а именно – число U.US однозначно определяет числа U.UB[ 0] и U.UB [1] и наоборот : union { uint16_t US; // U.UB[ 0]- Ст.б. uint8_t UB[1]; // U.UB [1]- Мл.б. } U; // U.US - 2-байтное uint16_t число. Вот п / п вывода двухбайтного сло - ва в DDS: void outspi16(uint16_t wor) { U.US = wor; SPI0CFG = SPI0CFG | 0x10; //IDLE_ HIGN для AD9833 CSAD = 0;// CSAD=0. outspi (U.UB[ 0]); //Ст.б. outspi (U.UB[ 1]); //Мл.б. CSAD = 1; //CSAD=1. SPI0CFG = SPI0CFG & 0xef; / / IDLE_LOW - Для дисплея } Вот определение числа частоты F как 32- разрядного : uint32_t F; // частота в Гц Вот совмещение 4- байтного ( uint32_t ) числа FR.FRL и двух двух - байтных ( uint16_t ) чисел FR.FRS[0] и FR.FRS[1] двухэлементного мас - сива FRS[1] , которые также зани - мают одно и то же место в памя - ти МК и являются соответственно старшим и младшим словами чис - ла FR.FRL . union { uint32_t FRL; // FR.FRS[0]- Ст. uint16_t слово. uint16_t FRS[1]; // FR.FRS[1]- Мл. uint16_t слово. } FR; // FR.FRL - 4-байтное uint32_t число. А вот и сама п / п вывода частоты и фазы в DDS: //Вывод частоты в DDS FR.FRL = F * 32; FR.FRL = FR.FRL << 2; //Сдвиг все- го числа uint32_t влево на 2 бита FR.FRS[0] = (FR.FRS[0]) | 0x4000; //Добавка 2-х ст.бит 01b к ст. сло- ву для FREG0 FR.FRS[1] = ((FR.FRS[1]) >> 2) | 0x4000;//Сдвиг мл. слова вправо на 2 бита (восст.) //и добавка 2-х ст.бит 01b к мл. слову outspi16(0x2108); // Сброс DDS (стоп) outspi16(FR.FRS[1]); // вывод мл. слова частоты в FREG0 outspi16(FR.FRS[0]); // вывод ст. слова частоты в FREG0 outspi16(0xC000); // вывод PHASE0 outspi16(0x2008); // Выход из сброса (запуск) Таким образом , программирование DDS примитивно просто , а приведён - ная выше п / п занимает ничтожный объём программной памяти МК . 3. П / п для измерения напряжения аккумулятора и вывода на дисплей сте - пени его зарядки также проста . Она десятикратно измеряет напряжение (U АКК ), поступающее на вход ADC0.1 (P0.1) МК , усредняет его , сравнивает с порогами (3,2 В , 3,5 В и 3,8 В ) и в зави - симости от среднего значения напря - жения выводит на дисплей рисунок аккумулятора с тем или иным коли - чеством сегментов , а именно : ● если U АКК > 3,8 В , то выводится рису - нок аккумулятора с тремя сегментами ; ● если 3,5 В < U АКК ≤ 3,8 В , то выво - дится рисунок аккумулятора с дву - мя сегментами ; ● если 3,2 В ≤ U АКК ≤ 3,5 В , то выводится рисунок аккумулятора с одним сег - ментом ; ● если U АКК < 3,2 В , то выводится ри - сунок аккумулятора без сегментов ( пустой ). Сама п / п позаимствована из одного из примеров программирования АЦП в Simplisity Studio и адаптирована под настоящую задачу . 4. Теперь по поводу того , как работа - ет п / п , определяющая состояние кно - пок . Как можно увидеть из схемы рис . 1, сигналы от кнопок , очищенные от дре - безга их контактов с помощью DD3, поступают на порты P0.4 и P0.5 МК , для чего в основной программе сде - ланы следующие назначения : sbit KN1 = P0 ^ 4; // Правая кнопка sbit KN2 = P0 ^ 5; // Левая кнопка Отсутствие дребезга контактов позволяет в п / п , связанной с кноп - ками , легко определять их состояние всего двумя простыми командами , которые выполняются в бесконечном цикле (while (1)) , выход из которого (break) осуществляется при нажатии и отпускании соответствующей кнопки : while (1) { if (!KN1) { // Ждём нажатия кноп- ки КН1 while (!KN1); // Ждём отпускания кнопки КН1 ... // Вывод на дисплей цифр и запуск/стоп break; } if (!KN2) { // Ждём нажатия кноп- ки КН2 while (!KN2); // Ждём отпускания кнопки КН2 ... // Вывод на дисплей режима break; } } Вывод на дисплей опущен . Как мож - но убедиться , п / п очень проста . После трансляции всей программы МК для генератора в среде Simplisity Studio в специальном окне , отражаю - щем результат трансляции , появляет - ся следующее сообщение : Program Size: data=69.0 xdata=0 const=812 code=2093 LX51 RUN COMPLETE. 0 WARNING(S), 0 ERROR(S) Finished building target: EFM8SB10F8G-A-QFN20_11.omf Из этого сообщения следует , что программа использует чуть более половины ( всего 69 байт ) внутренней оперативной памяти с прямой адре - сацией (data=69.0) , размер кото - рой 128 байт , внешняя дополнитель - ная оперативная память с косвенной адресацией размером 512 байт не используется вообще ( xdata=0 ), размер кодовой части программы составляет 2093 байт ( code=2093 ) плюс константы 812 байт ( const=812 ) в сумме составля - ют 2093 + 812 = 2905 байт  2,8 Кбайт , т . е . чуть более трети максимально - го размера программной памяти для

RkJQdWJsaXNoZXIy MTQ4NjUy