Реклама ⓘ
Главная » Микроконтроллеры
Призовой фонд
на апрель 2024 г.
1. 100 руб.
От пользователей

Похожие статьи:


Реклама ⓘ

mikroPascal for AVR. Урок 2. АЦП, UART и отображение

Это второй по счету урок о mikroPascal PRO for AVR. И в нем мы рассмотрим АЦП, подключение LCD дисплея с контроллером HD44780 и немного о передаче данных по UART.

Сначала рассмотрим АЦП

В предыдущем уроке я упомянул о конфигурации портов на выход. Тогда это нужно было, что бы зажигать светодиоды, подключенные к порту. По логике, для работы с АЦП порт на выход конфигурировать нельзя, но разработчики mikroPascal решили иначе.

Давайте напишем простенькую программку, которая будет считывать значение АЦП с C0 порта C.

program ADC_UART;

begin

  DDRB:=0xFF;                  //Порты на выход
  DDRC:=0xFF;                  //
  ADC_Init();                  //Инициализация АЦП
  While TRUE do begin          //Старт цикла
        PORTB:=ADC_Read(0);    //Отправляем в порт результат
  end;                         //измерения АЦП
end.

Из прошлого урока вы знаете, что DDRB:=0xFF это конфигурация порта B на выход. Тоже самое значит и DDRC:=0xFF. Далее идет строчка ADC_Init() – это и есть инициализация AЦП.  Ну и как понятно из названия, в бесконечном цикле я поместил функцию чтения значения АЦП  (в скобках указывается канал, с которого надо считать, так в ATmega8 целых 6 каналов в DIP корпусе и 8-мь в TQFP). Вот что получилось:

Но для снятия показаний такого вольтметра нужно переводить числа из двоичной системы счисления в десятичную, что хоть и не сложно, но отнимает какое-то количество времени. По этому, следующая наша программа будет выводить результат измерения на 7-ми сегментный индикатор. Для начала возьмем индикатор с одним разрядом, а позже попытаемся подключить  4-х разрядную махину.

Теперь приступим к написанию кода. У меня в итоге получилось следующее:

program ADC_UART;
var read_adc:integer;               //Объявляем глобальную переменную
const                               //Блок констант
     d_0:byte=63;
     d_1:byte=6;
     d_2:byte=91;
     d_3:byte=79;
     d_4:byte=102;
     d_5:byte=109;
begin                               //Основное тело программы
  DDRD:=0xFF;                       //Порт на выход
  ADC_Init();                       //Инициализация АЦП
  While TRUE do begin               //Бесконечный цикл
        read_adc:=ADC_Read(0);      //Получаем значение с АЦП
        read_adc:=read_adc*0.0049;  //Переводим в читабельный формат
        case read_adc of            //Подбираем, что отбразить
        0:PORTD:=d_0;
        1:PORTD:=d_1;
        2:PORTD:=d_2;
        3:PORTD:=d_3;
        4:PORTD:=d_4;
        5:PORTD:=d_5;
        end;
  end;
end.

Тут добавились многие знакомые функции паскаля (для тех, кто в нем работал конечно): объявление переменных, констант, оператор «case». Ну а теперь о коде. Так как мы выводим информацию на один индикатор, то смысла в точности нет. Значит можно просто обрезать все значения, кроме единиц, что я и сделал. Но, стандартно в mikroPascal нет никаких функций для работы с 7-ми сегментным индикатором, по этому мне пришлось импровизировать, использовав утилитку под названием «Seven Segment Editor» (о ней я упоминал в предыдущей статье).

Сгенерировав коды чисел 0-5 для индикатора я записал, объявил их как константы и в последствии через оператор case определял, какое число нужно отобразить. А теперь о конвертации числа, считанного АЦП, в читабельный формат. Как правило функция чтения АЦП возвращает значение в двоичном коде, и для операций над ним его нужно конвертировать в десятичную систему счисления. Так как по умолчанию при инициализации АЦП в mikroPascal среда автоматически устанавливает источник опорного напряжения по питанию (5 вольт), то для получения нормального числа нужна вот такая простенькая формула:

Uin(дес.)=Uin(дв.)*0,0049

Где Uin(дес.)-результат преобразования в виде десятичного числа, Uin(дв.)-число в двоичном коде, полученное с АЦП (В данном случае точность АЦП на частотах до 200КГц = 10 бит, до 1МГц = 8 бит и на 2МГц = 6 бит. Думаю дальше продолжать эту линейку смысла нет (погрешность в 0,5 вольта мало кого устроит)).

Закончив с программой для одноразрядного индикатора, попытаемся сделать то же самое для индикатора, в котором 4 разряда.

Так как нам нужно динамически отображать информацию, я создал специальную функцию, которая этим занимается. Ниже приведен ее код:

procedure Disp(input:real);                     //Объявляем процедуру, отвечающюю за отображение
var i,count,pos_p:integer;                      //Блок объявления локальных переменных
    temp_i:array [0..3] of integer;
    temp_a_s:array [0..3] of string [6];
    temp_s:string [6];
begin
     FloatToStr(input,temp_s);                  //Переводим переменную со знач. АЦП в string
     pos_p:=strchr(temp_s,'.');                 //Если есть знак "." то находим и заменяем его....
     if pos_p <> 0xFFFF then temp_s[pos_p]:='p';
     for i:=0 to 3 do begin                     //Старт цикла for
     temp_a_s[i][0]:=temp_s[i];                 //Копируем посимвольно переменную, содер. знач. АЦП
     temp_i[i]:=StrToInt(temp_a_s[i]);          //То же самое, только еще переводим в массив integer
         case i of                              //Выбираем на какой анод индикатора подать напряжение
         0:PORTB:=0x1;
         1:PORTB:=0x2;
         2:PORTB:=0x4;
         3:PORTB:=0x8;
         end;
         case temp_i[i] of                      //Выбираем что отобразить на индикаторе
         0:PORTD:=d0;
         1:PORTD:=d1;
         2:PORTD:=d2;
         3:PORTD:=d3;
         4:PORTD:=d4;
         5:PORTD:=d5;
         6:PORTD:=d6;
         7:PORTD:=d7;
         8:PORTD:=d8;
         9:PORTD:=d9;
         64:PORTD:=dp;
         end;
         delay_ms(10);                         //Задержка в 10-100 мс. устанавливает частоту мерцания
     end;                                      //индикатора
end;

В основном теле программы значение, считанное с АЦП передается в процедуру. Далее, оно преобразуется из float в string и обрабатывается. Далее число посимвольно записывается в массив типа integer, из которого собственно и формируется на LED индикатор. На создание этой процедуры у меня ушло достаточно большое количество времени (большая часть – изучение особенностей mikroPascal, относительно string). Вот код всей программы (как это не парадоксально, но объявление процедуры и констант больше, чем само тело программыJ ).

program ADC_UART;

var read_adc_i:real;

const d0:byte=192;                              //Здесь мы объявляем константы. Это символы
      d1:byte=249;                              //которые буду отображаться на дисплее.
      d2:byte=164;
      d3:byte=176;
      d4:byte=153;
      d5:byte=146;
      d6:byte=130;
      d7:byte=216;
      d8:byte=128;
      d9:byte=144;
      dp:byte=127;

procedure Disp(input:real);                     //Объявляем процедуру, отвечающую за отображение
var i,count,pos_p:integer;                      //Блок объявления локальных переменных
    temp_i:array [0..3] of integer;
    temp_a_s:array [0..3] of string [6];
    temp_s:string [6];
begin
     FloatToStr(input,temp_s);                  //Переводим переменную со знач. АЦП в string
     pos_p:=strchr(temp_s,'.');                 //Если есть знак "." то находим и заменяем его....
     if pos_p <> 0xFFFF then temp_s[pos_p]:='p';
     for i:=0 to 3 do begin                     //Старт цикла for
     temp_a_s[i][0]:=temp_s[i];                 //Копируем посимвольно переменную, содер. знач. АЦП
     temp_i[i]:=StrToInt(temp_a_s[i]);          //То же самое, только еще переводим в массив integer
         case i of                              //Выбираем на какой анод индикатора подать напряжение
         0:PORTB:=0x1;
         1:PORTB:=0x2;
         2:PORTB:=0x4;
         3:PORTB:=0x8;
         end;
         case temp_i[i] of                      //Выбираем что отобразить на индикаторе
         0:PORTD:=d0;
         1:PORTD:=d1;
         2:PORTD:=d2;
         3:PORTD:=d3;
         4:PORTD:=d4;
         5:PORTD:=d5;
         6:PORTD:=d6;
         7:PORTD:=d7;
         8:PORTD:=d8;
         9:PORTD:=d9;
         64:PORTD:=dp;
         end;
         delay_ms(10);                         //Задержка в 10-100 мс. устанавливает частоту мерцания
     end;                                      //индикатора
end;

begin                                          //Основное тело программы :)
     DDRB:=0xFF;                               //Порт B и D на выход
     DDRD:=0xFF;
     ADC_Init();                               //Инициализируем АЦП
     While true do begin                       //Сарт цикла
           read_adc_i:=ADC_Read(0);            //Читаем значение АЦП
           read_adc_i:=read_adc_i*0.0049;      //Переводим в удобную для восприятия форму
           Disp(read_adc_i);                   //Отправляем в процедуру для отображения
     end;
end.                                           //Конец армагеддона :)

Как видите, получился не такой уж и маленький код. А всего-то нужно было вывести информацию на индикатор.

Ну побыстрее нужно закончить с индикаторами и перейти к LCD. Тут в mikroPascal уже есть библиотеки и нам не придется изобретать велосипед.

В этот раз, благодаря вышеупомянутой библиотеке , код получился не большим.

Собственно вот и он:

program ADC_LCD;

var LCD_RS : sbit at PORTD2_bit;                          //Пишем,куда подключили дисплей
var LCD_EN : sbit at PORTD3_bit;
var LCD_D4 : sbit at PORTD4_bit;
var LCD_D5 : sbit at PORTD5_bit;
var LCD_D6 : sbit at PORTD6_bit;
var LCD_D7 : sbit at PORTD7_bit;

var LCD_RS_Direction : sbit at DDD2_bit;
var LCD_EN_Direction : sbit at DDD3_bit;
var LCD_D4_Direction : sbit at DDD4_bit;
var LCD_D5_Direction : sbit at DDD5_bit;
var LCD_D6_Direction : sbit at DDD6_bit;
var LCD_D7_Direction : sbit at DDD7_bit;

var read_adc:string [6];                                  //Объявляем глобальную переменную
    read_adc_temp:real;

begin
     DDRD:=0xFF;                                          //Порт на выход
     ADC_Init();                                          //Инициализация АЦП
     LCD_Init();                                          //Инициализация LCD
     LCD_Cmd(_LCD_CLEAR);                                 //Очищаем дисплей
     LCD_Cmd(_LCD_CURSOR_OFF);                            //Отключаем курсор
     While true do begin                                  //Старт цикла
          read_adc_temp:=ADC_Read(0)*0.0049;              //Считываем значение с АЦП
          FloatToStr(read_adc_temp,read_adc);             //
          lcd_out(1,1,'U(in)= ');                         //Выводим на LCD "U(in)= "
          lcd_out(1,8,read_adc);                          //Выводим то, что считали с АЦП
     end;
end.

Вот и с выводом на LCD покончено. Осталось только одно – отправить значение измеренного напряжения по UART и цели, которые я ставил перед этим уроком, достигнуты!

program ADC_LCD;

var read_adc:string [4];                                            //Объявляем глобальные переменные
    read_adc_temp:integer;

begin
     ADC_Init();                                                    //Инициализация АЦП
     UART1_Init(9600);                                              /Инициализация UART (9600 бод)
     While true do begin                                            //
          read_adc_temp:=ADC_Read(0)*0.0049;                        //"Читаем" АЦП
          IntToStr(read_adc_temp,read_adc);                         //переводим, то что считали в string
          Uart_Write_Text(read_adc);                                //Отправляем в UART
          delay_ms(100);                                            //Задержка 100 мс
     end;
end.

Как видите, код очень маленький и простой. Если добавить переходник USB-UART то можно сделать USB вольтметр J. И в догонку пару слов об этой программе: можно было обойтись и без преобразования в string, а просто передать integer, но мне показалось, что так удобнее.

Кстати, вот и стандартный терминал, который входит в состав mikroPascal. Я выбрал режим отображения данных в виде hex кодов (каждый символ), но так же можно выбрать режим ANCII, DEC и BIN. Кстати, для связи виртуально МК с виртуальным терминалом пришлось использовать виртуальный COM порт (в общем я сходил в другую реальность:) ).

Ниже вы можете посмотреть видеоурок в этой статье. 

Прикрепленные файлы:

Теги:

Опубликована: 0 2
Я собрал 0 2
x

Оценить статью

  • Техническая грамотность
  • Актуальность материала
  • Изложение материала
  • Полезность устройства
  • Повторяемость устройства
  • Орфография
0

Средний балл статьи: 5 Проголосовало: 2 чел.

Комментарии (33) | Я собрал (0) | Подписаться

+2
bytex #
Хотелось чтобы уроки были содержательными и имели полный объём. А то везде максимум 10 уроков и на этом всё, дальше тупик. Да и все уроки в основном для тех кто уже всё понимает.
Автору Спасибо за труды!!! Буду следить...
Ответить
+1
nikdemars #
Молодец! Отличная статейка. Еще хотелось бы узнать как в данной среде осуществить работу с внешними носителями (SD, miniSD, USB2.0), а именно создать там файл, считать данные, отформатировать. Еще интересно как связать микроконтроллер по USB порту с компьютером, и написать программу на Pascal-е, желательно Delphi, чтобы отправлять что-то микроконтроллеру и принимать что-то от него
Ответить
0

[Автор]
zeconir #
Спасибо. В принципе, в какую то из статей внесу UART. И тогда что-нибудь в дельфе накалякаю для "общения". А вот USB в мегах протеус не симулирует (хотя точно не знаю), так что показать не получиться. Да и с USB в микропаскале я честно и не работал. Так что это будет не так уж скоро (когда сам освою)
Ответить
0
nikdemars #
"А вот USB в мегах протеус не симулирует ..." - на макетке собери, не виртуально, а реально, если что на покупку микронтроллера дам (не на самый крутой конечно), могу по почте прислать подарить, только покажи как это делать на языке Pascal
Ответить
0

[Автор]
zeconir #
Спасибо за предложение, но тут проблема упирается не в деньги, а в опыт и время. Я, как говорил выше, не сталкивался в микропаскале с USB. Как сам что-то там пойму, то сделаю урок.
Ответить
0
nikdemars #
Ждем еще уроков
Ответить
0

[Автор]
zeconir #
В общем определился со следующим уроком - будет на этой неделе. Тема - UART, SPI, I2C. Будет все более подробно расписано, так как посчитал что в предыдущих уроках я не полностью раскрывал смысл.
И, если влезет OneWire.
Ответить
+1
Андрей #
Очень жду Ваш следующий урок! С уважением.
Ответить
0
Дмитрий #
Когда наконец выйдет следующий урок?
Ответить
0

[Автор]
zeconir #
Да вот, в ближайшие дни. Все время не хватает
Ответить
0
nikdemars #
Случайно нажал анти-лайк, ждем с нетерпением
Ответить
0

[Автор]
zeconir #
Бывает. Кстати, как смотришь на такой примерчик к теме UART в статье - UART калькулятор (начал уже возиться с кодом к нему)?
Ответить
+1
Alexandr #
zeconir, не забрасывай пожалуйста этих замечательных уроков! Есть в сети и другие сайты, со статьями по MikroPascal, но там в основном рассматриваются основы языка (синтаксис, типы данных и т. д) это всё можно прочесть в книжках по Turbo Pascal. Либо есть примеры кода, но нет схем подключения. У тебя всё доступно и понятно.
Хотелось бы так же увидеть уроки по ШИМ, например плавное включение и гашение светодиода. И примеры работы с таймерами.
Ответить
0
Михаил #
Прошу прощения вопрос конечно глупый, но все же.
Написав программу для мигания светодиодом как залить ее на микропроцессор? У меня есть программа AVRDudeProg но ей нужен файл расширения hex, а при сохранении проекта на микропаскале создается файл mpas? С помощью того, что лежит в Tools создается что-то не то. Как быть?
Ответить
0

[Автор]
zeconir #
Вверху на панели есть кнопка "Build" - это компиляция. После нее можно файл *.hex взять из папки с проектом. Так же скомпилировать проект можно сочетанием клавиш Ctrl + F9.
Прикрепленный файл: Build.JPG
Ответить
+1
LIC #
Спасибо за такую работу, очень помогает тем кто только начинает работать, но и людям с некоторым опытом так-же есть что почерпнуть.
А вот мой вопрос касается функции FloatToStr. Как ограничить количество знаков после запятой? Правило Delphi не работает.
Ответить
0
nikdemars #
var
s: string;
n: real;
begin
n := 10/3;
s := FloatTostrF(n,ffFixed,8,2); //8 - количество знаков до запятой, 2 - количество знаков после запятой
end;
Ответить
0
LIC #
nikdemars спасибо вам за ответ, Я наверное задал не правильно вопрос. Ваш код работает на 100% в Delphi, но mikroPascal как я понял не имеет классического форматирования.
Вопрос возник при выводе на LCD дисплей вывода результата измерения значения АЦП, стандартная функция FloatToStr в mikroPascal выводит 5-ть знаков после запятой, а мне надо обрезать показания до двух знаков. Вот и возник вопрос. Еще раз спасибо.
Ответить
0
nikdemars #
Попробуй так
Прикрепленный файл: 2015-04-17 18-37-47 Скриншот экрана.png
Ответить
+1
LIC #
Спасибо уважаемый nikdemars, я уже сам задумался над функцией преобразования, но оказывается в mikroPascal есть одна хитрость:
program ADC;

var LCD_RS : sbit at PORTB4_bit; //Ïèøåì,êóäà ïîäêëþ÷èëè äèñïëåé
var LCD_EN : sbit at PORTB5_bit;
var LCD_D4 : sbit at PORTB0_bit;
var LCD_D5 : sbit at PORTB1_bit;
var LCD_D6 : sbit at PORTB2_bit;
var LCD_D7 : sbit at PORTB3_bit;

var LCD_RS_Direction : sbit at DDB4_bit;
var LCD_EN_Direction : sbit at DDB5_bit;
var LCD_D4_Direction : sbit at DDB0_bit;
var LCD_D5_Direction : sbit at DDB1_bit;
var LCD_D6_Direction : sbit at DDB2_bit;
var LCD_D7_Direction : sbit at DDB3_bit;

var
read_adc: array[17] of char;
read_adc_temp: real;

begin
DDRB:=0xFF;
ADC_Init();
LCD_Init();
LCD_Cmd(_LCD_CLEAR);
LCD_Cmd(_LCD_CURSOR_OFF);
While true do begin
read_adc_temp:=(ADC_Read(0)*0.0049)*2;
FloatToStr(read_adc_temp,read_adc);
read_adc[5]:=0;
lcd_out(1,6,'V ');
lcd_out(1,1,read_adc);
end;

end.

Изменил переменную read_adc как array of char, я получил возможность регулировать длину выводимого сообщения при помощи задания длины по средством read_adc[5]:=0;, где [5] это общее количество выводимых знаков включая запятую. Теперь если напряжение меньше 10 вольт, то на экране мы видим 5.123V, а если больше, то 10.12V.
Может кому то и понадобится.
Ответить
0
nikdemars #
Я сам люблю delphi, поэтому паскаль мне ближе и mikroPascal соответственно, но после покупки ардуино в корне сменил взгляд (в комплекте шла книжка конспект хакера, по ней за 1 час с нуля сделал все примеры от моргания светодиода, до вывода на ЖКИ и обменом с ПК по USB данными), там можно сделать крутые проекты простыми, даже элементарными шагами. Литературы, примеров, библиотек полно. Сначала я думал, мол че на каждый проект по модулю ардуино надо?! Оказалось нет, можно через ардуино прошивать любые AVR микроконтроллеры прямо из среды программирования, так что рекомендую взглянуть на этот момент.
Ответить
+1
LIC #
Я не люблю спорить на тему "какой язык лучше", а придерживаюсь правила "главное не на чем, а как".
С возрастом восприятие новой информации становится затруднительным процессом, а так как с молодых годов занимался Ассемблером и Паскалем, то эти языки роднее для меня. Честно сказать контроллеры от Atmel не недолюбливаю, больше работаю с ST, Motorola. А AVR сейчас поднял просто из-за наличия старых AT90S4433, решил сделать Вольт-Амперметры для лабораторных блоков питания.
Ответить
0
LIC #
И снова я со своей "ложкой". Вольтметр с использованием LCD дисплея это красиво, но для простого вольтметра бывает хватает и LED индикаторов. Реализация проекта в статье весьма понятна, но как-то не рентабельно использовать один разряд под точку, решил попробовать это изменить:
program LED3;
var read_adc_i:real;
const d0:byte=192;
d1:byte=249;
d2:byte=164;
d3:byte=176;
d4:byte=153;
d5:byte=146;
d6:byte=130;
d7:byte=248;
d8:byte=128;
d9:byte=144;
d10:byte=064; //0.
d11:byte=121; //1.
d12:byte=036; //2.
d13:byte=048; //3.
d14:byte=025; //4.
d15:byte=018; //5.
d16:byte=002; //6.
d17:byte=120; //7.
d18:byte=000; //8.
d19:byte=016; //9.

procedure Disp(input:real); //процедура отображения
var i,count,pos_p:integer;
temp_i:array [0..3] of integer;
temp_a_s:array [0..3] of string [6];
temp_s:string [6];
begin
FloatToStr(input,temp_s);
pos_p:=strchr(temp_s,'.'); //Ищем "."

if pos_p <> 0xFFFF then
begin
temp_s[(pos_p-1)]:= temp_s[(pos_p-1)] + 10;
temp_s[pos_p]:= temp_s[(pos_p+1)];
temp_s[(pos_p + 1)]:= temp_s[(pos_p + 2)];
end;

for i:=0 to 2 do begin
temp_a_s[i][0]:=temp_s[i];
temp_i[i]:=StrToInt(temp_a_s[i]);

case i of
0:PORTB:=0x1;
1:PORTB:=0x2;
2:PORTB:=0x4;
end;
case temp_i[i] of
0:PORTD:=d0;
1:PORTD:=d1;
2:PORTD:=d2;
3:PORTD:=d3;
4:PORTD:=d4;
5:PORTD:=d5;
6:PORTD:=d6;
7:PORTD:=d7;
8:PORTD:=d8;
9:PORTD:=d9;
10:PORTD:=d10;
11:PORTD:=d11;
12:PORTD:=d12;
13:PORTD:=d13;
14:PORTD:=d14;
15:PORTD:=d15;
16:PORTD:=d16;
17:PORTD:=d17;
18:PORTD:=d18;
19:PORTD:=d19;
end;
delay_ms(10);
end;
end;

begin //Основное тело программы
DDRB:=0xFF;
DDRD:=0xFF;
ADC_Init();
While true do begin
read_adc_i:=ADC_Read(0);
read_adc_i:=(read_adc_i*0.0049)*4;
Disp(read_adc_i);
end;

end.

Первое изменение это добавлены еще 10-ть символов, а именно цифра с точкой. Далее заменил
if pos_p 0xFFFF then temp_s[pos_p]:='p';
на
if pos_p 0xFFFF then
begin
temp_s[(pos_p-1)]:= temp_s[(pos_p-1)] + 10;
temp_s[pos_p]:= temp_s[(pos_p+1)];
temp_s[(pos_p + 1)]:= temp_s[(pos_p + 2)];
end;
Если pos_p не равен 0xFFFF, то он несет в себе номер "ячейки" где у нас хранится знак ".", тогда мы увеличим предшествующий знак в temp_s на 10, что позволит позже отобразить эту цифру уже с точкой. Далее мы сдвигаем все значения в temp_s влево, дабы избавиться от "точки".
Ну и естественно я уменьшил цикл for до трех разрядов.
for i:=0 to 2 do begin
Ну вроде бы и все. Я надеюсь, что не надоел своими "изысканиями".
Еще раз Большое Спасибо Автору.
Ответить
0

[Автор]
zeconir #
Рад, что мои статьи кому-то интересны
Ответить
+1
nikdemars #
Главное не останавливайся, пиши еще!
Ответить
+1
LIC #
Они не просто интересны, эти статьи написаны простым и доступным языком. Спасибо большое и так же присоединяюсь к просьбе, не останавливайтесь.
Ответить
0

[Автор]
zeconir #
Вот в ближайших планах - ШИМ, и тут мне один товарищ подкинул идею с "разбором" modbus...
Ответить
+1
LIC #
Реализация ШИМ так-же востребован в большой мере, хочу позже попробовать что-то по типу ПИД регулятора сделать. А вот по MODBUS возникает вопрос, а на основе чего, ведь это последовательный протокол как для RS-232, так и для TCP/IP, а ведь есть еще и MODBUS Plus.
Еще раз говорю Вам, большое спасибо, ваши статьи написаны весьма простым языком.
Ответить
0

[Автор]
zeconir #
Если я правильно вас понял... Ведь можно сделать софтовую (программную) обработку данных для модбаса... Ну это в будущем, сейчас делаю про ШИМ, материал уже подготовил, осталось видео снять
Ответить
0
nikdemars #
Еще вариант - поставить 7-сегментник, светодиод, 7-сегментник, светодиод, 7-сегментник, светодиод, 7-сегментник и т.д. До нужной точности и просто в качестве запятой подсвечивать нужный светодиод между семисегментниками
Ответить
0
LIC #
Позволю с вами уважаемый nikdemars не согласиться в данной идее, ведь светодиоды у нас уже есть в корпусе LED матрицы, а для светодиодов придется все равно свой обработчик писать. Но для творчества это так-же может послужить идеей для реализации.
Для интересующихся, это архив с проектом работы на 3 сегмента и симуляция в Proteus.
Прикрепленный файл: ACD_LED3.RAR
Ответить
0
Serg #
Огромное спасибо за ваши уроки. Все наглядно и просто. Микропаскаль мне очень понравился, хоть я немного пишу на С, но начинающим его крайне не рекомендую за его сложность и криптографичность. Паскаль мне как то родней. Тем более, при компилировании в среде микропаскаль, хексы получаются не намного больше Сишных, что меня крайне удивило. Поэтому Си я забросил окончательно и новичкам советую не связываться с этим языком, он чисто для профи, но никак не для нас, любителей. Я почти пол года потратил на изучение Си и толку ноль, хоть и выучил синтаксис языка, писал несложные программы. Время потрачено зря. Спасибо.
Ответить
0
Vit2 #
Не могу понять почему показывает только "3" в первом разряде. Хочу использовать сдвиговый регистр 74HC164

procedure Disp(input:real); //ïðîöåäóðà îòîáðàæåíèÿ
var
i,pos_p:integer;
temp_i:array [0..3] of integer;
temp_a_s:array [0..3] of string [6];
temp_s:string [6];
begin
FloatToStr(1.23,temp_s);
pos_p:=strchr(temp_s,'.'); //Èùåì "."


if pos_p <> 0xFFFF then
begin
temp_s[(pos_p-1)]:= temp_s[(pos_p-1)] + 10;
temp_s[pos_p]:= temp_s[(pos_p+1)];
temp_s[(pos_p + 1)]:= temp_s[(pos_p + 2)];
end;

for i:=0 to 2 do
begin
temp_a_s[i][0]:=temp_s[i];
temp_i[i]:=StrToInt(temp_a_s[i]);
end;

case temp_i[i] of //Âûáèðàåì ÷òî îòîáðàæèòü íà èíäèêàòîðå
0:write_byte(not d0);
1:write_byte(not d1);
2:write_byte(not d2);
3:write_byte(not d3);
4:write_byte(not d4);
5:write_byte(not d5);
6:write_byte(not d6);
7:write_byte(not d7);
8:write_byte(not d8);
9:write_byte(not d9);
10:write_byte(not dd10);
11:write_byte(not dd11);
12:write_byte(not dd12);
13:write_byte(not dd13);
14:write_byte(not dd14);
15:write_byte(not dd15);
16:write_byte(not dd16);
17:write_byte(not dd17);
18:write_byte(not dd18);
19:write_byte(not dd19);
end;
case i of
0:PORTB:=0x01;
1:PORTB:=0x02;
2:PORTB:=0x04;
end;



end;
Ответить
Добавить комментарий
Имя:
E-mail:
не публикуется
Текст:
Защита от спама:
В чем измеряется электрическое сопротивление?
Файлы:
 
Для выбора нескольких файлов использйте CTRL

Pickit 2 - USB-программатор PIC-микроконтроллеров
Pickit 2 - USB-программатор PIC-микроконтроллеров
МиниПК MK809V - 4 ядра, Android 4.4.2 200 Вт усилитель класса D на IRS2092
вверх