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

Код тут:
CODE
#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';
}
}
#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>
//UBRR1L = 5;
//UBRR1H = 0; //скорость обмена UBRR = (Fck/(16*BAUD)) – 1</div>
Но какие я бы способы не пробовал, ничего не помогает.