Обозначение
|
Наименование
|
Кол.
|
Примечание
|
Микросхемы
|
DD1
|
Uno Arduino
|
1
|
|
Дисплей
|
DD2
|
ЖК модуль МТ-10Т7
|
1
|
|
Резисторы
|
R1
|
Резистор выводной - 10 кОм
|
1
|
|
R2
|
Термистор - 2,2 кОм
|
1
|
|
Конденсаторы
|
C1
|
Конденсатор - 100 нФ
|
1
|
|
C2-C3
|
Конденсатор - 0.1 мкФ
|
2
|
|
Дроссели
|
L2
|
Дроссель выводной - 10 мкГн
|
1
|
|
. Разработка алгоритма
работы управляющей программы
В общем виде управляющая программа
показана на рисунке 3.1.
Рисунок 3.1 - Общий вид управляющей
программы
Общая блок-схема программы
представлена на рисунке 3.1. При подключении питания однократно выполняется
подпрограмма setup(), проверяющая подключение датчика и инициализирующая дисплей.
После этого циклически выполняется подпрограмма loop(), которая считывает и
преобразует полученные с датчиков данные в понятную пользователю форму и
выводит информацию на дисплей, до того момента, пока питание не будет
отключено. Показания давления и температуры сменяют друг друга с интервалом в
три секунды. Блок-схемы программ setup()
n loop() представлены на рисунках 3.2, 3.3.
Рисунок 3.2 - Блок-схема
подпрограммы setup()
Рисунок 3.3 - Блок-схема
подпрограммы loop()
Показание атмосферного давления
считывается с датчика BMP085, умножается на переводной множитель Kmm для перевода из
паскалей в миллиметры ртутного столба и передаются в подпрограмму Pressure (float P), где обрабатывается для
корректного вывода на дисплей. Преобразованные данные (значения разрядов
числового значения давления с точностью до 0,01 мм ртутного столба) передаются
в строку InfoPress[10].
Показание температуры внутри
помещения считывается с датчика BMP085 и аналогично значению давления передается в подпрограмму Temperature (int Tin, int Tout).
Механизм считывания и обработки
внешней температуры несколько сложнее. В качестве датчика внешней температуры
использован терморезистор, поэтому прежде, чем передавать полученное значение в
подпрограмму Temperature (int Tin, int Tout), требуется провести линейную интерполяцию полученного значения
напряжения с термистора и соотнести полученное значение падения напряжения с
соответствующим значением температуры. Для этого полученное значение напряжение
передается в подпрограмму CalcTemperature (float AD), которое возвращает
значение температуры. После этого полученное числовое значение передается в
подпрограмму Temperature (int Tin, int Tout) вместе со значением внутренней температуры. Значение Tout умножается на
поправочный множитель 1,286 для минимизации погрешности. Обработанная
информация заносится в строку InfoTemp[10]. Блок-схемы
подпрограмм
Pressure (float P), Temperature (int Tin, int Tout) и CalcTemperature (float
AD) приведены на рисунках 3.4,
3.5, 3.6.
Рисунок 3.4 - Блок-схема
подпрограммы Pressure (float P)
Рисунок 3.6 - Блок-схема
подпрограммы CalcTemperature (float AD)
Для отображения обработанной
информации используется подпрограмма DispString (char Str[10]). После
установления начального адреса символу с каждой позиции переданной строки
устанавливается соответствие из массива SegmentMap[30], который содержит
передаваемые на семисегментный дисплей коды символов. Блок-схема данной
подпрограммы изображена на рисунке 3.7.
Рисунок 3.7 - Блок-схема
подпрограммы
DispString (char Str[10])
. Разработка управляющей
программы
Листинг управляющей программы:
#include <Wire.h>
#include <Adafruit_BMP085.h>
_BMP085 bmp;
float Kmm =
0.00750063755419211
StPin = 4; //start pin
No for output 4 bits DB0-DB3WR1pin = 8; //pin No for WR1WR2pin = 9; //pin No
for WR1ADpin = 10; // address/data signal
int sensorPin = A0; //
select the input pin for the potentiometerledPin = 13; //select the pin for the
LEDsensorValue = 0; // variable to store the value coming from the sensor
SegmentMap[30] =
{B11101110, B01100000, B00101111, B01101101, B11100001,, B11001111, B01101000,
B11101111, B11101101,, B11000001, B11100110, B11101010, B10101001,, B00000001,
0, B01000011, 0,, B01110000, B00111111, B01111101, B11110001,, B11011111,
B01111000, B11111111, B11111101};
MaskLow[4] = {B00000001,
B00000010, B00000100, B00001000};MaskHigh[4] = {B00010000, B00100000,
B01000000, B10000000};
InfoPress[10];InfoTemp[10];
#define ArrSize
20TStep[ArrSize] = {-40, -35, -30, -25, -20, -15, -10, -5, 0, 5, 10, 15, 20,
25, 30, 35, 40, 45, 50, 55};ADval[ArrSize] = {884, 842, 794, 738, 677, 612,
545, 480, 417, 359, 307, 260, 220, 185, 155, 130, 109, 92, 77, 65};Tout=0;
setup() {.begin(9600);(!
bmp. Begin())
{.println («Could not
find a valid BMP085 sensor, check wiring!»);(1) {}
}();
}
loop() {();
(bmp.readPressure()*Kmm);=CalcTemperature
(analogRead(sensorPin));(bmp.readTemperature(), Tout*1.286);
(InfoPress);(3000);(InfoTemp);(3000);
}
DispString (char
Str[10]) {i=0;();(i=0; i<=10; i++) {(Str[i]);}
}
InitScreen() {pin=0;
//Assign pins for
LCD(WR1pin, OUTPUT);(WR2pin, OUTPUT);(ADpin, OUTPUT);(pin=StPin;
pin<=StPin+3; pin++) {(pin, OUTPUT);}
//Init service
pins(WR1pin, LOW);(WR2pin, LOW);(ADpin, HIGH);
//Unblock LCD
trigger(pin=StPin; pin<=StPin+3; pin++) {(pin, HIGH);}();
}
/////////////////////////////////////////////////////////////////////////////////////////////
ClearScreen() {i=0;();(i=0; i<=9; i++) {();}
}
//////////////////////////////////////////////////////////////////////////////////////////
Pressure (float P)
{pos1, pos2, pos3, pos4,
pos5;
=P/100;=(P-pos1*100)/10;=P-pos1*100-pos2*10;=(P-pos1*100-pos2*10-pos3)*10;=(P-pos1*100.0-pos2*10.0-pos3-pos4/10)*100;
InfoPress[0]=pos1;[1]=pos2;[2]=pos3+20;[3]=pos4;[4]=pos5;[5]=17;[6]=18;[7]=18;[8]=18;[9]=18;
}
////////////////////////////////////////////////////////////////////////
Temperature (double Tin, double Tout)
{[0]=TempSign(Tin);[1]=TempConvers1
(Tin);[2]=TempConvers2 (Tin);[3]=14;[4]=15;[5]=TempSign(Tout);[6]=TempConvers1
(Tout);[7]=TempConvers2 (Tout);[8]=14;[9]=15;
}
//////////////////////////////////////////////////////////////////////////////////////
TempConvers1 (double T)
{int
pos1;=abs(T)/10;pos1;
}
/////////////////////////////////////////////////////////////////////////////////////
TempConvers2 (double T)
{int pos2;=abs(T) -
TempConvers1 (T)*10;pos2;
}
///////////////////////////////////////////////////////////////////////////////
TempSign (double T)
{if (T>=0) {return
17;}{return 16;}
}
////////////////////////////////////////////////////////////
CalcTemperature (int AD)
{int p=1, q=ArrSize,
s;TempPrev, TempItog, del, porAD;
(p<q)
{=(p+q)/2;(ADval[s]>=AD)
{=s+1;
}
{q=s;
}
}
TempPrev=TStep
[s-1];=(5.0/(ADval [s-1] - ADval[s]));=TempPrev+(ADval[s] - AD)*del;TempItog;
}
//////////////////////////////////////////////////////////
StrobeAD() {(ADpin, LOW);(WR1pin, HIGH);(1);(WR1pin, LOW);(ADpin, HIGH);
}
////////////////////////////////////////////////////////////////
WriteAddr0 () //write address 00 to LCD
{int pin=0;(pin=StPin;
pin<=StPin+3; pin++) {(pin, LOW);}();
}
/////////////////////////////////////////////////
DispChar (byte Code) {Ln=0;
//Display Low part(Ln=0;
Ln<=3; Ln++) {(StPin+Ln, (SegmentMap[Code] & MaskLow[Ln]));}();
//Display High
part(Ln=0; Ln<=3; Ln++) {(StPin+Ln, (SegmentMap[Code] & MaskHigh[Ln]));
}
/////////////////////////////////////////////////////
StrobeWR() {(WR1pin, HIGH);(1);(WR1pin, LOW);
}
/////////////////////////////////////////////////////////
DataClr() {pin=0;(pin=StPin; pin<=StPin+3; pin++) {(pin, LOW);}();();
}
Заключение
В данной курсовой работе
продемонстрирована возможность разработки цифровых устройств на
микроконтроллере ATMega328 в составе инструмента для проектирования электронных
устройств Arduino Uno R3.
Конечным результатом проведенной
работы являются электронный барометр с возможностью измерения температуры, его
структурная и принципиальная схемы цифрового, а также алгоритм функционирования
системы и листинг программы.
Таким образом, цели работы курсового
проектирования были достигнуты в полном объеме.
Список источников
1. Каган Б.М., Сташин В.В. Основы проектирования микропроцессорных
устройств автоматики. - М.: Энергоатомиздат, 1987.
2. Хартов В.Я. Микроконтроллеры AVR/. Практикум для
начинающих. - М.: Изд-во МГТУ им. Н.Э. Баумана, 2007.
. Петин В. Проекты с использованием контроллера Arduino. - M.: BHV, 2015.