Помогите разобратся с работой UART в atmege8

Обсуждаем контроллеры компании Atmel.
Ответить
Dmti
Родился
Сообщения: 16
Зарегистрирован: Чт май 02, 2013 06:23:11

Помогите разобратся с работой UART в atmege8

Сообщение Dmti »

По случаю достался релейный блок от газоанализатора "Хоббит" с убитым камнем (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 );
	
	//Настройка внешних портов
        //На выводах портов С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();	        //Сохраняем предустановки портов
			//Надо доделать в будущем		//Корректируем время
										//Запускаем таймер
			}
	}
}
Суть в неработающем UART. Специально дописал в прерывании моргании лампочки вот такой код

Код: Выделить всё

//Посылаем слово для проверки порта ПОТОМ УДАЛИТЬ!
	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;
На ногах pin30, pin31, pin32 смотрю осциллографом, но ничего не вижу, такое ощущение, что выходы в подвешенном состоянии, и где собака порылась, не пойму. Если не трудно, ткните носом, чтоб заработало.
Реклама
profyelec
Родился
Сообщения: 2
Зарегистрирован: Чт янв 20, 2011 09:12:17
Откуда: Украина, Львов

Re: Помогите разобратся с работой UART в atmege8

Сообщение profyelec »

Читаем внимательно документацию на камень, раздел USART. Там же кстати есть и примеры.
C Code Example(1)
void USART_Transmit( unsigned char data )
{
/* Wait for empty transmit buffer */
while ( !( UCSRA & (1<<UDRE)) )
;
/* Put data into buffer, sends the data */
UDR = data;
}

Сначала нужно проверить можноли класть новые данные в регистр UDR:

/* Wait for empty transmit buffer */
while ( !( UCSRA & (1<<UDRE)) ) ;

А то у Вас все байты для передачи накладываются один на другой, он даже не успеет передать.
На правильный вопрос даю правильный ответ
Реклама
airborne
Открыл глаза
Сообщения: 40
Зарегистрирован: Сб ноя 12, 2011 17:59:32

Re: Помогите разобратся с работой UART в atmege8

Сообщение airborne »

Начал разбираться с UART на atmega32, отправляю "A" этим кодом:
#include <avr/io.h>

void USART_Init( unsigned int baud )
{
/* Set baud rate */
UBRRH = (unsigned char)(baud>>8);
UBRRL = (unsigned char)baud;
/* Enable receiver and transmitter */
UCSRB = (0<<RXEN)|(1<<TXEN);
/* Set frame format: 8data, 2stop bit */
UCSRC = (1<<URSEL)|(1<<USBS)|(3<<UCSZ0);
}

void USART_Transmit( unsigned char data )
{
/* Wait for empty transmit buffer */
while ( !( UCSRA & (1<<UDRE)) );
/* Put data into buffer, sends the data */
UDR = data;
}

int main(void)
{
USART_Init(25);
while(1)
{
//TODO:: Please write your application code
USART_Transmit("A");
}
}

тестирую в протеусе, получаю "@".
мк 4MHz, Baud rate 9600.

Что я делаю не правильно?
a_skr
Вымогатель припоя
Сообщения: 630
Зарегистрирован: Пн июн 14, 2010 13:07:29
Откуда: Жуковский

Re: Помогите разобратся с работой UART в atmege8

Сообщение a_skr »

на это не ругается?
USART_Transmit("A");

нужно:
USART_Transmit('A');
Реклама
Эиком - электронные компоненты и радиодетали
airborne
Открыл глаза
Сообщения: 40
Зарегистрирован: Сб ноя 12, 2011 17:59:32

Re: Помогите разобратся с работой UART в atmege8

Сообщение airborne »

'A' - на терминале пустота
Реклама
airborne
Открыл глаза
Сообщения: 40
Зарегистрирован: Сб ноя 12, 2011 17:59:32

Re: Помогите разобратся с работой UART в atmege8

Сообщение airborne »

USART_Transmit('a') => @
Реклама
a_skr
Вымогатель припоя
Сообщения: 630
Зарегистрирован: Пн июн 14, 2010 13:07:29
Откуда: Жуковский

Re: Помогите разобратся с работой UART в atmege8

Сообщение a_skr »

все работает. разбирайтесь:
Вложения
mega32_test.zip
(21.75 КБ) 131 скачивание
airborne
Открыл глаза
Сообщения: 40
Зарегистрирован: Сб ноя 12, 2011 17:59:32

Re: Помогите разобратся с работой UART в atmege8

Сообщение airborne »

Выставил на терминале 1 стоп бит и заработало, хотя странно код брал из datasheet, а там написано /* Set frame format: 8data, 2stop bit */
Ответить

Вернуться в «AVR»