Помогите разобратся с работой UART в atmege8
Добавлено: Чт май 02, 2013 09:57:21
По случаю достался релейный блок от газоанализатора "Хоббит" с убитым камнем
(Atmega8L). Камень перепаял на новый и теперь надо в него что-нибудь залить. В середине
90х программировал на турбо си то этому решил что-нибудь с ваять сам. Скачал AVR Studio 5 и
после копирования и объединения нескольких примеров для начинающих получилось вот
это.
Суть в неработающем UART. Специально дописал в прерывании моргании лампочки вот такой
код
На ногах pin30, pin31, pin32 смотрю осциллографом но не чего не вижу такое ощущение что
выходы в подвешенном состоянии и где собака порылась не пойму. Если не трудно ткните
носом чтоб заработало.
(Atmega8L). Камень перепаял на новый и теперь надо в него что-нибудь залить. В середине
90х программировал на турбо си то этому решил что-нибудь с ваять сам. Скачал AVR Studio 5 и
после копирования и объединения нескольких примеров для начинающих получилось вот
это.
Код: Выделить всё
//#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 );
//Настройка внешних портов
DDRC = 0x3f; // назначаем 0-5 линии порта C на
выход
DDRD= 0xf8; // назначаем 4-7 линии
порта D на выход
DataC = STATC; // считали значение порта С из
EEPROM
PORTC = DataC; // и загнали в порт С
DataD = STATD; // считали значение порта D из
EEPROM
PORTD = DataD; // и загнали в порт D
return;
}
//Сообщить состояние портов
void ReadData(void )
{
for (int i = 0; i < 4; i++)
{
UDR = Data[i];
}
return;
}
//***********************************Настраиваем проц.*****************************************
//Изменить состояние портов
void WriteData( void )
{
PORTC = DataC & 0x3f; // и устанавливаем в нужное состояние
PORTD = DataD & 0xf8; // и устанавливаем в нужное состояние
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;
dt = ('k'); UDR = dt;
dt = ('!'); UDR = dt;
dt = (0x0d); UDR = dt;
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;выходы в подвешенном состоянии и где собака порылась не пойму. Если не трудно ткните
носом чтоб заработало.