Главная | Обратная связь | Поможем написать вашу работу!
МегаЛекции

РАЗРАБОТКА ПРОГРАММНОГО ОБЕСПЕЧЕНИЯ




 

Программа написана на языке СИ при этом, в качестве инструментальных средств была использована бесплатная программа AVR Studio 6

Принцип работы программы: в функции (init) производится настройка всех портов микроконтроллера, написание прерываний, инициализация таймеров, часов реального времени, индикатора и датчика влажности. Далее происходит старт таймера и обработка прерываний. Текст программы см. в приложении Г.

 

Результат компиляции и построения программы

 

Компиляция

Построение начато.

Проект "GMD.cproj" (целевые объекты Compile):

Построение с инструментами версии "2.0".

Целевой объект "Compile" в файле "C:\Program Files (x86)\Atmel\Atmel Studio 6.0\Vs\Compiler.targets" из проекта "C:\Users\Wackaloon\Desktop\Курсовик МПК\code\GMD.cproj" (точка входа):

Задача "RunCompilerTask"

C:\Program Files (x86)\Atmel\Atmel Studio 6.0\make\make.exe "GMD.o"

make: `GMD.o' is up to date.

Выполнение задачи "RunCompilerTask" завершено.

Построение целевого объекта "Compile" в проекте "GMD.cproj" завершено.

Построение проекта "GMD.cproj" завершено.

 

Build succeeded.

 

Построение

AVR Memory Usage

----------------

Device: atmega8

Program: 4914 bytes (60.0% Full)

(.text + .data + .bootloader)

Data: 22 bytes (2.1% Full)

(.data + .bss + .noinit)

Done executing task "RunCompilerTask".

Done building target "CoreBuild" in project "GMD.cproj".

Target "PostBuildEvent" skipped, due to false condition; ('$(PostBuildEvent)' != '') was evaluated as ('' != '').

Target "Build" in file "C:\Program Files (x86)\Atmel\Atmel Studio 6.0\Vs\Avr.common.targets" from project "C:\Users\Wackaloon\Desktop\Курсовик МПК\code\GMD.cproj" (entry point):

Done building target "Build" in project "GMD.cproj".

Done building project "GMD.cproj".

 

Build succeeded.

========== Build: 1 succeeded or up-to-date, 0 failed, 0 skipped ==========


 

СПИСОК ИСПОЛЬЗОВАННЫХ ИСТОЧНИКОВ

 

1. DHT11 Temperature & humidity sensor, Datasheet – D Robotics UK

2. DHT22 Temperature & humidity module, Datasheet – AOSONG

3. DHT21 Digital-output temperature and humidity sensor, Datasheet – Hanwei

4. PC 0802-A, Datasheet – POWERTIP

5. PC 1002-A, Datasheet – POWERTIP

6. WH1602L , Datasheet – Winstar Display Co. LTD

7. DS1307 Real-time clock, Datasheet – Maxim Integrated

8. DS1390-1394 Real-time clock, Datasheet – Maxim Integrated

9. ATMega8(L), Datasheet – ATMEL

10. EG-BA -103, Datasheet – ener genie

11. К142ЕН5B, Спецификация [Электронный ресурс] : база данных. — Режим доступа : http://www.radiolibrary.ru/reference/chip/k142en5v.html. Дата обращения 25.03.14

12. L7805, Datasheet – STMicroelectronix

13. LM2596, Datasheet – Texas Instruments

14. Язык СИ для МК [Электронный ресурс] : база данных. — Режим доступа : http://www.123avr.com/05.htm.

Дата обращения 2.04.14


15.

ПРИЛОЖЕНИЕ А


ПРИЛОЖЕНИЕ Б


ПРИЛОЖЕНИЕ В


ПРИЛОЖЕНИЕ Г

 


 

Текст программы

 

Файл timeout.h описывает частоту кварца

#define F_CPU 16000000UL // 8 MHz

#ifndef ALIBC_OLD

#include <util/delay.h>

#else

#include <avr/delay.h>

#endif

 

Файл dht22.h содержит объявления функций для работы с датчиком

#ifndef _DHT22_H_

#define _DHT22_H_

 

#include <inttypes.h>

 

#define THERM_PIN PINC

#define THERM_DDR DDRC

#define THERM_PORT PORTC

 

#define THERM_DQ PC0 // датчик подключен на порт С 0 (ADC0)

/* Utils */

#define THERM_INPUT_MODE() THERM_DDR&=~(1<<THERM_DQ)

#define THERM_OUTPUT_MODE() THERM_DDR|=(1<<THERM_DQ)

#define THERM_LOW() THERM_PORT&=~(1<<THERM_DQ)

#define THERM_HIGH() THERM_PORT|=(1<<THERM_DQ)

#define THERM_READ() ((THERM_PIN&(1<<THERM_DQ))? 1 : 0)

 

typedef enum

{

DHT_ERROR_NONE = 0,

DHT_BUS_HUNG,

DHT_ERROR_NOT_PRESENT,

DHT_ERROR_ACK_TOO_LONG,

DHT_ERROR_SYNC_TIMEOUT,

DHT_ERROR_DATA_TIMEOUT,

DHT_ERROR_CHECKSUM,

DHT_ERROR_TOOQUICK

} DHT22_ERROR_t;

 

int dht22_read(float *temperature, float *humidity);

 

#endif /*_DHT22_H_*/

 

Файл dht22.cpp содержит определения функций для работы с датчиком, алгоритм взят из Datasheet

 

 

#include "DHT22.h"

#include "../timeout.h"

#include <avr/io.h>

// здесь должно быть 40, но датчик добавляет еще один бит в начале

#define DHT22_DATA_BIT_COUNT 41

// прочитать 40 бит данных с датчика,

//сохранить результаты в приватной переменной чтобы прочитать паблик функциями

int dht22_read(float *temperature, float *humidity)

{

uint8_t retryCount;

uint8_t bitTimes[DHT22_DATA_BIT_COUNT];

int currentHumidity;

int currentTemperature;

uint8_t checkSum, csPart1, csPart2, csPart3, csPart4;

 

int i;

 

currentHumidity = 0;

currentTemperature = 0;

checkSum = 0;

 

//

for(i = 0; i < DHT22_DATA_BIT_COUNT; i++)

{

bitTimes[i] = 0;

}

 

// ждать пока не появится высокий уровень

//cli();

THERM_INPUT_MODE();

//sei();

retryCount = 0;

do

{

if (retryCount > 125)

{

return DHT_BUS_HUNG;

}

retryCount++;

_delay_us(2);

} while(!THERM_READ());

// послать активирующий запрос

//cli();

THERM_LOW();

THERM_OUTPUT_MODE(); // низкий уровень на выходе

//sei();

_delay_us(1100); // 1.1 ms

//cli();

THERM_INPUT_MODE(); // переключиться обратно на вход

//sei();

//найти начало импульса

retryCount = 0;

do

{

if (retryCount > 25) //(Spec is 20 to 40 us, 25*2 == 50 us)

{

return DHT_ERROR_NOT_PRESENT;

}

retryCount++;

_delay_us(2);

} while(!THERM_READ());

// найти конец импульса

retryCount = 0;

do

{

if (retryCount > 50) //(минимум 80 us, 50*2 == 100 us)

{

return DHT_ERROR_ACK_TOO_LONG;

}

retryCount++;

_delay_us(2);

} while(THERM_READ());

// прочитать 40 бит данных

for(i = 0; i < DHT22_DATA_BIT_COUNT; i++)

{

// найти начало синхроимпульса

retryCount = 0;

do

{

if (retryCount > 35) //(минимум 50 us, 35*2 == 70 us)

{

return DHT_ERROR_SYNC_TIMEOUT;

}

retryCount++;

_delay_us(2);

} while(!THERM_READ());

// измерить размер импульса данных

retryCount = 0;

do

{

if (retryCount > 50) //( минимум 80 us, 50*2 == 100 us)

{

return DHT_ERROR_DATA_TIMEOUT;

}

retryCount++;

_delay_us(2);

} while(THERM_READ());

bitTimes[i] = retryCount;

}

// поиск конца каждого кусочка

// 0 is 26 to 28 us

// 1 is 70 us

// bitTimes[x] <= 11 is a 0

// bitTimes[x] > 11 is a 1

//

for(i = 0; i < 16; i++)

{

if(bitTimes[i + 1] > 11)

{

currentHumidity |= (1 << (15 - i));

}

}

for(i = 0; i < 16; i++)

{

if(bitTimes[i + 17] > 11)

{

currentTemperature |= (1 << (15 - i));

}

}

for(i = 0; i < 8; i++)

{

if(bitTimes[i + 33] > 11)

{

checkSum |= (1 << (7 - i));

}

}

 

*humidity = ((float)(currentHumidity & 0x7FFF)) / 10.0;

 

if(currentTemperature & 0x8000)

{

// ниже нуля, не очень стандартно

currentTemperature &= 0x7FFF;

*temperature = ((float)currentTemperature / 10.0) * -1.0;

}

else

{

*temperature = (float)currentTemperature / 10.0;

}

 

csPart1 = currentHumidity >> 8;

csPart2 = currentHumidity & 0xFF;

csPart3 = currentTemperature >> 8;

csPart4 = currentTemperature & 0xFF;

 

if(checkSum == ((csPart1 + csPart2 + csPart3 + csPart4) & 0xFF))

{

//*humidity = 10;

return DHT_ERROR_NONE;

}

//*humidity = 20;

return DHT_ERROR_CHECKSUM;

}


 

Для работы с индикатором использовалась свободно распространяемая библиотека, автор Radu Motisan

 

Файл hd44780.h

 

/* @project

*

* License to access, copy or distribute this file:

* This file or any portions of it, is Copyright (C) 2012, Radu Motisan , http://www.pocketmagic.net . All rights reserved.

* This file can be used for free only in private use, educational and non commercial applications, assuming this original

* copyright message is preserved.

*

* @author Radu Motisan, radu.motisan@gmail.com

*

* This file is protected by copyright law and international treaties. Unauthorized access, reproduction

* or distribution of this file or any portions of it may result in severe civil and criminal penalties.

*

* Unless required by applicable law or agreed to in writing, software

* distributed under the License is distributed on an "AS IS" BASIS,

* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.

*

* @purpose HD44780 LCD Minimal interface for Atmega microcontrollers

* http://www.pocketmagic.net/

*/

 

#pragma once

#include <stdio.h>

#include <avr/io.h>

//--------------------------------CONFIGURE LCD------------------------------------------------------//

#define LCD_LINES 2 // number of visible lines of the display

#define LCD_DISP_LENGTH 8 // visibles characters per line of the display

#define LCD_START_LINE1 0x00 // DDRAM address of first char of line 1

#define LCD_START_LINE2 0x40 // DDRAM address of first char of line 2

#define LCD_START_LINE3 0x14 // DDRAM address of first char of line 3

#define LCD_START_LINE4 0x54 // DDRAM address of first char of line 4

 

//Purpose: work with a LCD display

#define LCD_4BIT_D4_PORT PORTD // port for 4bit data bit 0 //D4 poz:3 connector...[digits 0,1,...]

#define LCD_4BIT_D4_PIN 4 // pin for 4bit data bit 0

#define LCD_4BIT_D5_PORT PORTD // port for 4bit data bit 1 //D5

#define LCD_4BIT_D5_PIN 5 // pin for 4bit data bit 1

#define LCD_4BIT_D6_PORT PORTD // port for 4bit data bit 2 //D6

#define LCD_4BIT_D6_PIN 6 // pin for 4bit data bit 2

#define LCD_4BIT_D7_PORT PORTD // port for 4bit data bit 3 //D7

#define LCD_4BIT_D7_PIN 7 // pin for 4bit data bit 3

#define LCD_RS_PORT PORTC // port for RS line //D3 poz:1 connector

#define LCD_RS_PIN 1 // pin for RS line

#define LCD_E_PORT PORTC // port for Enable line //D4 poz:2 connector

#define LCD_E_PIN 2 // pin for Enable line

//#define LCD_RW_PORT LCD_PORT // port for RW line UNUSED - we only WRITE

//#define LCD_RW_PIN 5 // pin for RW line UNUSED - we only WRITE

//---------------------------------------------------------------------------------------------------//

 

// instruction register bit positions, see HD44780U data sheet

#define LCD_CLR 0x0 // DB0: clear display

#define LCD_HOME 0x1 // DB1: return to home position

#define LCD_ENTRY_MODE 0x2 // DB2: set entry mode

#define LCD_ENTRY_INC 0x1 // DB1: 1=increment, 0=decrement

#define LCD_ENTRY_SHIFT 0x0 // DB2: 1=display shift on

#define LCD_ON 0x3 // DB3: turn lcd/cursor on

#define LCD_ON_DISPLAY 0x2 // DB2: turn display on

#define LCD_ON_CURSOR 0x1 // DB1: turn cursor on

#define LCD_ON_BLINK 0x0 // DB0: blinking cursor ?

#define LCD_MOVE 0x4 // DB4: move cursor/display

#define LCD_MOVE_DISP 0x3 // DB3: move display (0-> cursor) ?

#define LCD_MOVE_RIGHT 0x2 // DB2: move right (0-> left) ?

#define LCD_FUNCTION 0x5 // DB5: function set

#define LCD_FUNCTION_8BIT 0x4 // DB4: set 8BIT mode (0->4BIT mode)

#define LCD_FUNCTION_2LINES 0x3 // DB3: two lines (0->one line)

#define LCD_FUNCTION_10DOTS 0x2 // DB2: 5x10 font (0->5x7 font)

#define LCD_CGRAM 0x6 // DB6: set CG RAM address

#define LCD_DDRAM 0x7 // DB7: set DD RAM address

#define LCD_BUSY 0x7 // DB7: LCD is busy

 

// set entry mode: display shift on/off, dec/inc cursor move direction

#define LCD_ENTRY_DEC 0x04 // display shift off, dec cursor move dir

#define LCD_ENTRY_DEC_SHIFT 0x05 // display shift on, dec cursor move dir

#define LCD_ENTRY_INC_ 0x06 // display shift off, inc cursor move dir

#define LCD_ENTRY_INC_SHIFT 0x07 // display shift on, inc cursor move dir

 

// display on/off, cursor on/off, blinking char at cursor position

#define LCD_DISP_OFF 0x08 // display off

#define LCD_DISP_ON 0x0C // display on, cursor off

#define LCD_DISP_ON_BLINK 0x0D // display on, cursor off, blink char

#define LCD_DISP_ON_CURSOR 0x0E // display on, cursor on

#define LCD_DISP_ON_CURSOR_BLINK 0x0F // display on, cursor on, blink char

 

// move cursor/shift display

#define LCD_MOVE_CURSOR_LEFT 0x10 // move cursor left (decrement)

#define LCD_MOVE_CURSOR_RIGHT 0x14 // move cursor right (increment)

#define LCD_MOVE_DISP_LEFT 0x18 // shift display left

#define LCD_MOVE_DISP_RIGHT 0x1C // shift display right

 

// function set: set interface data length and number of display lines

#define LCD_FUNCTION_4BIT_1LINE 0x20 // 4-bit interface, single line, 5x7 dots

#define LCD_FUNCTION_4BIT_2LINES 0x28 // 4-bit interface, dual line, 5x7 dots

#define LCD_FUNCTION_8BIT_1LINE 0x30 // 8-bit interface, single line, 5x7 dots

#define LCD_FUNCTION_8BIT_2LINES 0x38 // 8-bit interface, dual line, 5x7 dots

 

 

//

#define LCD_MODE_DEFAULT ((1<<LCD_ENTRY_MODE) | (1<<LCD_ENTRY_INC) )

// address of data direction register of port x

#define LCD_DDR(x) (*(&x - 1))

 

extern int g_nCurrentLine;

 

inline void lcd_e_high() { LCD_E_PORT |= _BV(LCD_E_PIN); }

inline void lcd_e_low() { LCD_E_PORT &= ~_BV(LCD_E_PIN); }

inline void lcd_rs_high() { LCD_RS_PORT |= _BV(LCD_RS_PIN); }

inline void lcd_rs_low() { LCD_RS_PORT &= ~_BV(LCD_RS_PIN); }

// flush channel E

void lcd_toggle_e(void);

// PURPOSE: send a character or an instruction to the LCD

void lcd_write(uint8_t data,uint8_t rs) ;

// PURPOSE: send an instruction to the LCD

void lcd_instr(uint8_t instr);

 

// PURPOSE: Initialize LCD to 4 bit I/O mode

void lcd_init();

// PURPOSE: send a character to the LCD

void lcd_char(uint8_t data);

// PURPOSE: send a null terminated string to the LCD eg. char x[10]="hello!";

void lcd_string(char *text);

void lcd_string_format(char *szFormat, ...);

// PURPOSE: Set cursor to specified position

// Input: x horizontal position (0: left most position)

// y vertical position (0: first line)

void lcd_gotoxy(uint8_t x, uint8_t y);

// PURPOSE: Move cursor on specified line

void lcd_setline(uint8_t line);

// PURPOSE: Clear display and set cursor to home position

void lcd_clrscr(void);

// FUNCTION: lcd_home

// PURPOSE: Set cursor to home position

void lcd_home(void);

 

Основной файл проекта содержащий логику работы системы

Файл GMD.cpp

#include <avr/io.h>

#include <stdlib.h>

#include <string.h>

#include "timeout.h" // определеяет F_CPU

#include <avr/interrupt.h>

#include <util/delay.h>

#include <avr/sleep.h>

// датчик

#include "sensors/dht22.h"

// lcd

#include "lcd/hd44780.h"

//настройка внешнего прерывния INT0

void init( void )

{

//настраиваем на срабатывание INT0 по переднему фронту

MCUCR |= (1<<ISC01)|(1<<ISC00);

//разрешаем внешнее прерывание INT0

GICR |= (1<<INT0);

//Настроить (разрешить) прерывание по переполнению счетного регистра TCNT0:

TIMSK |= (0<<OCIE2)|(0<<TOIE2)|(0<<TICIE1)|(0<<OCIE1A)|(0<<OCIE1B)|(0<<TOIE1)|(1<<TOIE0);

//1 1 0 Счет от пина Т0. По ниспадающему фронту

TCCR0 |= (1<<CS02)|(1<<CS01)|(0<<CS00);

//отключаем АЦП

ADCSRA |= (0<<ADEN);

//отключаем аналоговый компаратор

ACSR|= (1<<ACD);

//отключаем watchdog

WDTCR |= (1<<WDCE);

WDTCR |= (0<<WDE);

lcd_init();

lcd_clrscr();

TIMER0_OVF_vect();

sei();

sleep_cpu();

}

//функция обработчик внешнего прерывания INT0

ISR( INT0_vect )

{

sleep_cpu();

}

// обработчик переполнения счетчика

ISR(TIMER0_OVF_vect)

{

cli();

sleep_disable();

 

lcd_home();

 

float t = 0 , h = 0;

dht22_read(&t,&h);

lcd_gotoxy(0,0);

lcd_string_format("Humidity");

lcd_gotoxy(0,1);

lcd_string_format(" %2.2f", h);

 

// выбор режима сна

set_sleep_mode(SLEEP_MODE_PWR_DOWN);

 

// в этом режиме МК может проснуться только от

//внешнего прерывания по изменению уровня на INT0 INT1 или от сторожевого таймера

//состояние регистров сохраняется (указано в даташите)

 

sleep_enable();

sei();

sleep_cpu();

 

// ZzZzZzZz.....

}

/*

* основная программа

*/

int main(void) {

while(1)

{

 

}

return (0);

}

 

 





Рекомендуемые страницы:

Воспользуйтесь поиском по сайту:



©2015- 2021 megalektsii.ru Все материалы представленные на сайте исключительно с целью ознакомления читателями и не преследуют коммерческих целей или нарушение авторских прав.