Перейти к содержанию
    

Помогите разобраться c USART на atmega1284p

Сразу скажу, сильно не пинать, изучаю программирование контроллеров 2.5 дня.

Проект делаю в Atmel Studio, симуляцию произвожу в proteus 8.

Схема подключения тут:

efc8d0c70970t.jpg

Код тут:

#define F_CPU 8000000UL
#define USART_BAUDRATE 9600
#define BAUD_PRESCALE (((F_CPU / (USART_BAUDRATE * 16UL))) - 1)
#define SPI_PORTX PORTB
#define SPI_DDRX DDRB
#define SPI_MISO PB6
#define SPI_MOSI PB5
#define SPI_SCK PB7
#define SPI_SS PB4



#include <avr/io.h>
#include <avr/sleep.h>
#include <inttypes.h>
#include <avr/interrupt.h>
#include <avr/sleep.h>
#include <util/delay.h>
#include <stdint.h> 
#include <stdio.h>



void port_init(void) // ПОРТЫ и Инчицалищация
{
	// ПОРТЫ =)
	DDRB=0x01;   
	PORTB=0x00;
	DDRA=0xFF;
	PORTA=0x00;
	DDRC=0x3F;
	PORTC=0x00;
	// Прерывание
	PCICR |= (1 << PCIE0)|(1 << PCIE2);
	PCMSK0 |= (1<<PCINT0)|(1<<PCINT1)|(1<<PCINT2)|(1<<PCINT3)|(1<<PCINT4)|(1<<PCINT5)|(1<<PCINT6)|(1<<PCINT7);
	PCMSK2 |= (1<<PCINT16)|(1<<PCINT17)|(1<<PCINT18)|(1<<PCINT19)|(1<<PCINT20)|(1<<PCINT21);

}

void USART_Init (void)  // UART1 инициализация
{	
UBRR1 = 51;
//UBRR1L = 5; 
//UBRR1H = 0;	//скорость обмена  UBRR = (Fck/(16*BAUD)) – 1
//			RXC			-	завершение приёма
//			|TXC		-	завершение передачи
//			||UDRE 		-	отсутствие данных для отправки
//			|||FE		-	ошибка кадра
//			||||DOR		-	ошибка переполнение буфера
//			|||||PE		-	ошибка чётности
//			||||||U2X	-	Двойная скорость
//			|||||||MPCM	-	Многопроцессорный режим
//			76543210	
UCSR1A  = 0b00000000;
//			RXCIE		-	прерывание при приёме данных
//			|TXCIE		-	прерывание при завершение передачи
//			||UDRIE		-	прерывание отсутствие данных для отправки
//			|||RXEN		-	разрешение приёма
//			||||TXEN	-	разрешение передачи
//			|||||UCSZ2	-	UCSZ0:2 размер кадра данных
//			||||||RXB8	-	9 бит принятых данных
//			|||||||TXB8	-	9 бит переданных данных
//			76543210
UCSR1B  = 0b00011000;		//  разрешен приём и передача по UART
//			URSEL		-	всегда 1
//			|UMSEL		-	режим:1-синхронный 0-асинхронный
//			||UPM1		-	UPM0:1 чётность
//			|||UPM0		-	UPM0:1 чётность
//			||||USBS	-	топ биты: 0-1, 1-2
//			|||||UCSZ1	-	UCSZ0:2 размер кадра данных
//			||||||UCSZ0	-	UCSZ0:2 размер кадра данных
//			|||||||UCPOL-	в синхронном режиме - тактирование
//			76543210
UCSR1C  = 0b11000110;		 //  8-битовая посылка
}  

void SPI_Init(void)
{

SPI_DDRX |= (1<<SPI_MOSI)|(1<<SPI_SCK)|(1<<SPI_SS)|(0<<SPI_MISO);
SPI_PORTX |= (1<<SPI_MOSI)|(1<<SPI_SCK)|(1<<SPI_SS)|(1<<SPI_MISO);
//			SPIE 		-	разрешает /запрещает прерывания от модуля SPI. Если бит установлен в 1, прерывания от SPI разрешены. 
//			|SPE		– включает/выключает модуль SPI. Если бит установлен в 1, модуль SPI включен.
//			||DORD		– определяет порядок передачи данных.
//			|||MSTR	 – определяет режим работы микроконтроллера. (1 mst/0slv)
//			||||CPOL	- режим работы.
//			|||||CPHA 	- режим работы. 
//			||||||SPR1 	-	определяют частоту тактового сигнала SPI модуля,
//			|||||||SPR0 -	определяют частоту тактового сигнала SPI модуля,
//			76543210

SPCR = (1<<SPE)|(0<<DORD)|(1<<MSTR)|(0<<CPOL)|(0<<CPHA)|(1<<SPR1)|(0<<SPR0); //  *разрешение spi,старший бит вперед,мастер, режим 0
SPSR = (0<<SPI2X);
}

void init_devices(void)
{
cli(); // на время инициализации периферии, запрещаем все прерывания
port_init();

sei(); // разрешаем обратно все прерывания
}


void uart_putc( char c )  //UART ПЕРЕДАЧА
{
while( ( UCSR1A & ( 1 << UDRE1 ) ) == 0  );  //ждем окончания передачи предыдущего байта

UDR1 = c;		//передача данных
}	   

unsigned char uart_getc( void )   //UART ПРИЕМ
{

while( ( UCSR1A & ( 1 << RXC1 ) ) == 0  ); 	//ждем приема байта

return UDR1; //считываем принятый байт
}

void uart_puts( char *str )  
{
unsigned char c;
while( ( c = *str++ ) != 0 ) {
	uart_putc( c );
}
}  




int main(void)
{	

init_devices();
_delay_ms(500);
USART_Init();
_delay_ms(1000);
SPI_Init();

//set_sleep_mode(SLEEP_MODE_EXT_STANDBY);
//sleep_enable();
//sei();
//sleep_cpu();
	 while(1)
			{
			_delay_ms(1000);
			UDR1 = 'T';
			 }

}

 

При попытки инициализации осциллограф (виртуальный) показывает какой-то бред, видно на скринщоте выше.

При попытке отправить символ "T" протеус выдает ошибку:

[AVR USART 1] Writing to UDR1 while transmit operation is in progress. Data will be ignored.

Я предполагаю, что вся проблемы в том, что я, пока, не до конца разобрался с тактированием , оно у меня от внутреннего кварца Как вариант в этой части кода:

    UBRR1 = 51;
    //UBRR1L = 5; 
    //UBRR1H = 0;    //скорость обмена  UBRR = (Fck/(16*BAUD)) – 1</div>

Но какие я бы способы не пробовал, ничего не помогает.

Изменено пользователем Herz

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

1. При занесении значения в двуxбайтный регистр сначала заносят значение в регистр xxxH, затем в регистр xxxL. Никак не наоборот!

2. Комментарий и значение двух старших битов регистра UCSR1C не соответствует документации на МК.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

 

1. При занесении значения в двуxбайтный регистр сначала заносят значение в регистр xxxH, затем в регистр xxxL. Никак не наоборот!

Пробовал и так и так, работает. Но буду иметь ввиду.

2. Комментарий и значение двух старших битов регистра UCSR1C не соответствует документации на МК.

Да, спасибо за совет. Дайствительно, из-за невнимательности просрал почти день. Ошибка в 7 бите.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Присоединяйтесь к обсуждению

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

Гость
Ответить в этой теме...

×   Вставлено с форматированием.   Вставить как обычный текст

  Разрешено использовать не более 75 эмодзи.

×   Ваша ссылка была автоматически встроена.   Отображать как обычную ссылку

×   Ваш предыдущий контент был восстановлен.   Очистить редактор

×   Вы не можете вставлять изображения напрямую. Загружайте или вставляйте изображения по ссылке.

×
×
  • Создать...