Код: Выделить всё
//#include <avr/delay.h> // добавил библиотеку выполнения пауз
//В будущем сделать реальные часы и реализовать недельный таймер
#include <avr/io.h> // для работы с портами
#include <stdio.h> // для включении UART
#include <avr/eeprom.h> // для сохранении в пзу
#include <avr/interrupt.h> // и прерывание будем использовать
uint8_t EEMEM ADDR; //Сетевой адрес устройства
uint8_t EEMEM STATC; //Состояние реле порта С
uint8_t EEMEM STATD; //Состояние реле порта D
int Tmp[5]; //Временный буфер
volatile char ready = 0; //Получена ли строка?
volatile int bufsize = 0; //Длина строки
int Data[5];
#define Adres Data[0] //адрес опрашиваемого устройства
#define Comanda Data[1] //выполняемая команда
#define DataA Data[2] //Вспомогательная переменная
#define DataC Data[3] //Значение порта С
#define DataD Data[4] //Значение порта D
//***********************************Настраиваем проц.*****************************************
void uart_init( void )
{
//настройка скорости обмена
//инициализируем USART
UBRRH = 0;
UCSRA = 0; //Кварц 4 мГц
UBRRL = 0x19; //Скорость на скорость 9600
//8 бит данных, 1 стоп бит, без контроля четности
UCSRC = ( 1 << URSEL ) | ( 1 << UCSZ1 ) | ( 1 << UCSZ0 );
//разрешить прием, передачу данных и прерывание по приёму байта
UCSRB = ( 1 << TXEN ) | ( 1 << RXEN ) | (1 << RXCIE );
//Настройка внешних портов
//На выводах портов С0-5 и D4-7 через ключи сидят 10 реле на D3 светодиод
DDRC = 0x3f; // назначаем 0-5 линии порта C на выход
DDRD= 0xf8; // назначаем 4-7 линии порта D на выход
DataC = STATC; // считали значение порта С из EEPROM
PORTC = DataC; // и загнали в порт С
DataD = STATD; // считали значение порта D из EEPROM
PORTD = DataD; // и загнали в порт D
return;
}
//*************************************блок функций********************************************
//Изменить состояние портов
void WriteData( void )
{
PORTC = DataC & 0x3f; // и устанавливаем в нужное состояние
PORTD = DataD & 0xf8; // и устанавливаем в нужное состояние
return;
}
//Сообщить состояние портов
void ReadData(void )
{
for (int i = 0; i < 4; i++)
{
UDR = Data[i];
}
return;
}
//Изменить адрес устройства в сети
void RenADDR ( void )
{
ADDR = Adres; //Адрес сохраняем сразу
return;
}
//Сохранить состояние портов
void SaveData (void)
{
STATC = DataC; //Сохраняем состояние порта С в ЕРОМ
STATD = DataD; //Сохраняем состояние порта D в ЕРОМ
}
//Копируем из одного массива Tmp в другой рабочий Data
void CopyD (void)
{
for (int i = 0; i < bufsize; i++)
{
Data[i] = Tmp[i];
Tmp[i] = 0;
}
bufsize = 0;
ready = 0;
}
//************************************Обрабатываем события**************************************
//Обработчик прерывания, чтение из порта
ISR (USART_RXC_vect)
{
if ((bufsize < 5) && (bufsize < sizeof(Tmp)-1)) Tmp[bufsize++] = UDR; //Сохраняем следующее сообщение
if (bufsize == 4 && ADDR == Tmp[3]) ready = 1; bufsize = 0; //Строка получена 5 значений
}
/*/Обработчик прерывания, чтение в порт
ISR (USART_TXC_vect)
{
if ((bufsize < 5) && (bufsize < sizeof(Tmp)-1)) UDR = Tmp[bufsize++]; //Читаем следующее сообщение
if (bufsize = 4) ready = 1; //Строка значений отправлена
} //*/
//обработчик прерывания, моргаем светодиодом
ISR(TIMER1_COMPA_vect)
{
PORTD ^=0x08;
//Посылаем слово для проверки порта ПОСЛЕ ОТЛАДКИ УДАЛИТЬ!
unsigned char dt = ('O'); UDR = dt;
unsigned char dt = ('k'); UDR = dt;
unsigned char dt = ('!'); UDR = dt;
unsigned char dt = (0x0d); UDR = dt;
unsigned char dt = (0x0a); UDR = dt;
}
//**************************************Основная программа**************************************
int main(void)
{
//Инициализируем порт
uart_init();
//Запускаем таймер
TCCR1A=0x40; //при совпадении уровень OC1A меняется на противоположный
TCCR1B=0x05; //CLK/1024
TIMSK = 0x10; //разрешаем прерывание по совпадению
sei(); //разрешаем прерывания глобально
//бесконечный цикл
while(1)
{
if(ready) { //Если строка получена, то выполняем тело программы
CopyD(); //Сначала копируем временный массив в постоянный
//Команды управлением процессом
if(Comanda == 1) ReadData(); //Сообщить состояние портов
if(Comanda == 2) WriteData(); //Изменить состояние портов
if(Comanda == 3) RenADDR(); //Меняем адрес
if(Comanda == 4) SaveData(); //Сохраняем предустановки портов
//Надо доделать в будущем //Корректируем время
//Запускаем таймер
}
}
}
Код: Выделить всё
//Посылаем слово для проверки порта ПОТОМ УДАЛИТЬ!
unsigned char dt = ('O'); UDR = dt;
unsigned char dt = ('k'); UDR = dt;
unsigned char dt = ('!'); UDR = dt;
unsigned char dt = (0x0d); UDR = dt;
unsigned char dt = (0x0a); UDR = dt;


