寻找这个问题的一些帮助我已经坚持了一段时间。
当从从机接收一个字节时,发生错误的转换次数,通常是7但不总是。
Atmega328P作为主人和& ATtiny85作为奴隶。使用AVR-GCC在Atmel Studio 6中编译。
我很确定这是一个时间问题,即使我在代码中找不到任何错误,但我仍尝试USICS1
,USICS0
,USICLK
&的所有组合。 SPI模式0& 1只是为了排除它们(AVR319数据表说USI因为SPI与模式0和1兼容,但我也试过3)。现在,当我等待回复时,我将尝试使用轮询方法而不是中断驱动,并希望继续阅读数据表。我不认为这会解决它,但我没有想法。
// Master - ATmega 328P
#ifndef F_CPU
#define F_CPU 16000000UL
#endif
#include <avr/io.h>
#include <util/delay.h>
#include <avr/interrupt.h>
#include "uart.h"
#define CTRL_PORT DDRB
#define DATA_PORT PORTB
#define SS_PIN PORTB2
#define CLK_PIN PORTB5
#define MOSI_PIN PORTB3
#define MISO_PIN PORTB4
#define UART_BAUD_RATE 9600
volatile char res;
volatile char val = 0x4D;
/*
Initialize SPI and UART
*/
void init()
{
//Set MOSI, clock pin and SS pin as output.
CTRL_PORT = _BV(MOSI_PIN) | _BV(CLK_PIN) | _BV(SS_PIN);
//Enable SPI mode, master and F_CPU/128.
SPCR = _BV(SPE) | _BV(MSTR) | _BV(SPR0) | _BV(SPR1);
uart_init( UART_BAUD_SELECT(UART_BAUD_RATE,F_CPU) );
sei();
}
/*
Transmit char to, and receive char from, the slave.
*/
void Transmit(char data)
{
SPDR = data;
while(!(SPSR & (1<<SPIF))) {}
res = SPDR;
}
/*
Transmit char 'M', for Master, to slave and receive
slaves number, in this case '2'. Print char from slave to serial
*/
int main()
{
init();
while(1)
{
Transmit(val);
uart_putc(res);
_delay_ms(1000);
}
return 0;
}
SLAVE CODE:
#ifndef F_CPU
#define F_CPU 8000000UL
#endif
#include <avr/io.h>
#include <avr/interrupt.h>
#include <util/delay.h>
#define CTRL_PORT DDRB
#define DATA_PORT PORTB
#define SS_PIN PB4
#define CLK_PIN PB2
#define DI_PIN PB0
#define DO_PIN PB1
/*
Initialize USI as slave
*/
void init()
{
//DO pin is configured for output
CTRL_PORT |= _BV(DO_PIN);
//All other pins as input
CTRL_PORT &= ~(_BV(DI_PIN) | _BV(CLK_PIN) | _BV(SS_PIN));
DATA_PORT |= _BV(DI_PIN) | _BV(CLK_PIN);
//Enable USI overflow interrupt, set three wire mode and set
// clock to External, positive edge.
USICR = _BV(USIOIE) | _BV(USIWM0) | _BV(USICS0) | _BV(USICS1);
//Clear overflow flag
USISR = _BV(USIOIF);
sei();
}
/*
USI overflow interrupt - triggered when transfer complete
*/
ISR(USI_OVF_vect)
{
USISR = _BV(USIOIF);
USIDR = 0x32;
}
int main()
{
init();
while(1) {}
return 0;
}
非常感谢您提供的任何帮助,谢谢。
答案 0 :(得分:2)
我将时钟和振荡器关系从fosc / 128更改为fosc / 4,我得到了预期的字符。