丢失的信件去了哪里?

时间:2014-06-12 08:48:24

标签: c string avr uart spi

只显示4个字母。就像在示例中一样,我发送字符串" abcdef",但它只显示4个字母" abcf"。我不知道为什么其他字母不会出现。我正在使用Atmega8和Bray终端。我已经从数据表[http://ww1.microchip.com/downloads/en/DeviceDoc/21822E.pdf][1]开始关注了。但我已经找到了死胡同。

功能的实施

#include <avr/io.h>
#include <math.h>
#include <util/delay.h>

#define DD_SS       PINB2         //Chip select ON RC2
#define DD_MOSI     PINB3          // Master out - Slave in pin
#define DD_MISO     PINB4          // Master in - Slave out pin
#define DD_SCK      PINB5          // Clock from master
#define DDR_SPI     PORTB          // DDR_SPI

void serial_init(void)
{
    UBRRH = 0x00;
    UBRRL = 7;
    UCSRC = (1<<URSEL)|(1<<USBS)|(3<<UCSZ0)|(1 << UCSZ1); 
    UCSRB = (1 << RXEN) | (1 << TXEN)| (1<<RXCIE);
}
unsigned char Usart_Receive(void)           
{
    while ((UCSRA & (1 << RXC)) == 0) {};
    return UDR;
}


void Usart_Transmit(unsigned char c)   
{

    PORTD= 0b00000100;  //RTS Enable
    while ((UCSRA & (1 << UDRE)) == 0) {};
    UDR = c;
    PORTD= 0b00000000;  //RTS Disable
}
void SPI_MasterInit(void)
{
    DDRB = 0b00101100;
    DDR_SPI = (1<<DD_MOSI)|(1<<DD_SCK);
    SPCR = 0b01010000;
    SPSR = 0b00000001;
}
unsigned char spi_transfer(volatile char data)
{
    SPDR = data;
    while(!(SPSR & (1<<SPIF)));
    {
    }
    return SPDR;
}
void SPI_MasterTransmit (uint8_t Data)    
{
    uint16_t address;
    SPCR = (1<<SPE) | (1<<MSTR) | (0<<CPHA);
    DDR_SPI &= ~(1<<DD_SS);                // Select EEPROM
    spi_transfer(WREN);   // Send WRITE_ENABLE command
    DDR_SPI |= (1<<DD_SS);                // Release EEPROM
    DDR_SPI &= ~(1<<DD_SS);   //ss goes low             
    spi_transfer(WRITE); // write data to memory
    spi_transfer  (address>>8);   
    spi_transfer (address);
    spi_transfer(Data);
    DDR_SPI |= (1<<DD_SS);   //ss goes high
}
unsigned char SPI_MasterReceive(uint16_t address)   
{
    unsigned long data;
    SPCR = (1<<SPE) | (1<<MSTR) | (0<<CPHA);
    //waitBusy();
    DDR_SPI &= ~(1<<DD_SS);   //ss goes low
    spi_transfer(READ);  //enable write operation   
    spi_transfer (address>>8);  
    spi_transfer (address);
    data = spi_transfer(0xff);
    DDR_SPI |= (1<<DD_SS);   //goes high
    return data;
}

这是主要功能

int main (void)
{
    char data;  
    unsigned char address;
    serial_init();
    SPI_MasterInit();
    while(1)
    {
      data = Usart_Receive();
      _delay_ms(10);
      SPI_MasterTransmit(data);
      _delay_ms(10);
      data = SPI_MasterReceive(address);    //read data from the memory
      _delay_ms(10); //pause for readability
      Usart_Transmit(data);     
    }           
    return 0;   
} 

我希望有人可以帮助我。 :)

2 个答案:

答案 0 :(得分:2)

您的USART传输速度太快,不适合您的接收器。第四次通过主循环时,USART发送器用“e”覆盖“d”,然后用“f”覆盖。

解决这个问题的一种方法是使用中断来接收数据,而不是像现在这样进行轮询。但是,您无法像中断那样快速地写入EEPROM。相反,您应该在字母到达时将字母排成圆形数组或链表或其他数据结构,然后在时间允许的情况下将它们写入主循环中的EEPROM。

请注意,此解决方案仅适用于突发数据;你节省了爆发然后尽可能地处理它。但如果USART持续太快,那么你永远无法跟上。

答案 1 :(得分:0)

要调试此问题,您需要本地化问题的位置,为此,您必须将实验拆分为子任务。 其中一个是单独检查UART,代码如下:

   while(1)
    {
      data = Usart_Receive();
      _delay_ms(10);
      Usart_Transmit(data);     
    }   

第二个是如果你有JTAG则检查SPI与UART之间的区别,或者如果你得到了使UART工作的管理,则完全检查SPI。对于单独的SPI检查,只需评论Usart_Receive();Usart_Transmit(data);初始化data,并可能在while中增加{{1}}。希望这个想法有所帮助