Отправляет email-рассылки с помощью сервиса Sendsay
  Все выпуски  

Анонсы журнала "Лаборатория электроники и программирования" Новые статьи 24 номера


1. Автоматизация поиска информации в сети интернет. Занятие 5.

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

Для этого в программу нужно добавить таймер. Делается это следующим образом.

Результат работы программы в окне отладки:

время ожидания - '1', сек

время ожидания - '2', сек

время ожидания - '3', сек

время ожидания - '4', сек

время ожидания - '5', сек

время ожидания - '6', сек

время ожидания - '7', сек

время ожидания - '8', сек

время ожидания - '9', сек

время ожидания - '10', сек

Таймаут!

страница загружена - первая

 

2. Программирование на языке С на примере микроконтроллера ATmega168.  Программный RTC и будильники.

В выпуске журнала №12 (статья 5) был рассмотрен пример использования внешней микросхемы RTC. RTC можно сделать и программно, если такая реализация подходит для реализации проекта (аппаратный RTC в большинстве случаев работает более точно, потребляет меньше энергии, но стоимость такого решения больше).

                Для реализации программного RTC запрограммируем таймер 2 на срабатывание каждую миллисекунду. Добавим переменные для секунд, минут и часов. В обработке прерывания таймера 2 будем вести подсчет миллисекунд и каждую секунду изменять переменную секунд и при необходимости изменять переменную минут и   часов. В основном цикле программы будем выводить текущее время по UART в терминальную программу.

Программа написана для среды разработки ATMEL Studio® [1].

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

//

// Часы реального времени (RTC). программная реализация

//

 

#include <avr/io.h> // описание регистров микроконтроллера

#define F_CPU 16000000L // задали частоту микроконтроллера

#include <util/delay.h> // подключаем функции задержки

#include <avr/interrupt.h> // подключим библиотеку для работы с прерываниями

#include <stdio.h> // библиотека стандартного ввода-вывода

#include <avr/pgmspace.h> // библиотека для работы с Flash памятью программ

 

// функция передачи байта

void UART_TX_byte(char tx_data) // передаваемый байт

{

                while(!(UCSR0A & (1<<UDRE0))) {} // ожидаем окончания передачи

                UDR0 = tx_data; // начало передачи данных

}

 

// функция передачи строки

void UART_TX_string(char * str) // указатель на строку

{

                while((*str) != 0x00) // проверка на окончание строки

                {

                               UART_TX_byte(*(str++)); // передаем текущий байт и увеличиваем указатель (на следующий элемент)

                }

}

 

char msg[100];

 

// Программный таймер RTC

#define msec_cnt_top 1000 // значение счета (мс) - 1 сек

volatile unsigned int msec_cnt = 0; // счетчик таймера (мс)

volatile unsigned int sec = 0; // секунды

volatile unsigned int min = 0; // минуты

volatile unsigned int hour = 0; // часы

 

// главная функция

int main(void)

{

               

                // настройка UART

                UCSR0B |= (1<<TXEN0); // разрешим передачу данных

                // при сбросе установлено

                // UMSEL == 00 - асинхронный режим

                // UPM = 00 - без паритета

                // USBS = 0 - 1 стоп бит

                // UCSZ = 011 - 8 бит данные

                // 8N1 - 8 бит, без паритета, 1 стоп-бит

                UBRR0 = 16; // скорость 57600 при 16000000 и U2X = 0

               

                // счетчик времени на таймере 2

                // время срабатывания - 1 мс

                // 16000000/64/1000 = 250 - значение сравнения

                // режим CTC (2)

                TCCR2A |= (1<<WGM21);

                TCCR2B |= (1<<CS22); // делитель на 64

                OCR2A = 250-1;

                TIMSK2 |= (1<<OCIE2A); // разрешим прерывание при сравнении по каналу А

               

                sei(); // разрешим прерывания глобально

               

                // начальная установка времени

                sec = 55;

                min = 59;

                hour = 12;

               

                UART_TX_string("\r\nRTC:\r\n"); 

                              

                // основной цикл программы

    while(1)

    {

                               // вывод текущего времени по UART

                               //sprintf_P(msg,PSTR("%d:%d:%d\r\n"), hour, min, sec);

                               //sprintf_P(msg,PSTR("%2d:%2d:%2d\r\n"), hour, min, sec);

                               sprintf_P(msg,PSTR("%2.2d:%2.2d:%2.2d\r\n"), hour, min, sec);

                               UART_TX_string(msg);

 

                               _delay_ms(1000); // задержка 1 сек

    }

}

 

 

// обработка прерывания таймера 2 при сравнении по каналу А

ISR(TIMER2_COMPA_vect)

{

               

                if(msec_cnt < msec_cnt_top) msec_cnt++; // счетчик миллисекунд - увеличиваем

                else

                {

                               msec_cnt = 0; // сбрасываем счетчик миллисекунд

                               if(sec < 59) sec++; // увеличиваем секунды

                               else

                               {

                                               sec = 0; // сбрасываем секунды

                                               if(min < 59) min++; // увеличиваем минуты

                                               else

                                               {

                                                               min = 0; // сбрасываем минуты

                                                               if(hour < 23) hour++; // увеличиваем часы

                                                               else

                                                               {

                                                                              hour = 0; // сбрасываем часы

                                                               }

                                               }

                               }

                }

}

 

 

Результат работы программы:

RTC:

12:59:55

12:59:56

12:59:57

12:59:58

12:59:59

13:00:00

13:00:01

13:00:02

13:00:03

В следующем примере добавим будильник. Для этого сделаем переменные для хранения времени срабатывания будильника и будем проверять их в функции обработки прерывания (изменения выделены серым). Заметим, что проверяются также и миллисекунды. Это позволяет избежать двойного срабатывания будильника в течение одной секунды.

В третьем примере добавим второй будильник, который будет через каждые 10 секунд переключать светодиод.

http://journal.electroniclab.ru/journal_content_024.htm  


В избранное