I wrote up a function to connect via UART and print a string for debugging purposes. But my logic does not add up somehow... I see the line "Random Number" printed in the console but blazingly fast... no matter what I add for a _delay_ms value, it is not usable. Did I miss out on anything?
Why is my delay function not having any influence on the output on the serial terminal?
void initUSART(void) {
#define BAUDRATE ((F_CPU) / (BAUD * 8UL)-1) // Set Baud Rate Value for UBRR
// Set register
UBRR0H = (BAUDRATE >> 8);
UBRR0L = BAUDRATE;
UCSR0A |= (1 << U2X0);
// Enable USART transmitter and receiver
UCSR0B = (1 << TXEN0) | (1 << RXEN0);
// Set 8 data bits and 1 stop bit
UCSR0C = (1 << UCSZ01) | (1 << UCSZ00);
}
void transmitByte(uint8_t data) {
// Wait for empty transmit buffer
loop_until_bit_is_set(UCSR0A, UDRE0);
UDR0 = data;
}
void printString(const char myString[]) {
uint8_t i = 0;
while (myString[i]) {
transmitByte(myString[i]);
i++;
}
}
int main(void)
{
setup();
randomSeed(adcRead(0));
while (1)
{
printString("Random Number:\n");
_delay_ms(100000);
}
return (0);
}
When I use \r\nat the end of the string, the output gets really strange:
When I try this test code everything works as expected, the LED blinks every second. I really don't see where the difference is, as it is the same function.
/* Blinker Demo */
// ------- Preamble -------- //
#include <avr/io.h> /* Defines pins, ports, etc */
#include <util/delay.h> /* Functions to waste time */
int main(void) {
// -------- Inits --------- //
DDRB |= 0b00000001; /* Data Direction Register B:
writing a one to the bit
enables output. */
// ------ Event loop ------ //
while (1) {
PORTB = 0b00000001; /* Turn on first LED bit/pin in PORTB */
_delay_ms(1000); /* wait */
PORTB = 0b00000000; /* Turn off all B pins, including LED */
_delay_ms(1000); /* wait */
} /* End event loop */
return 0; /* This line is never reached */
}
Related
I am trying to use the SPI communication to read data from the ADXL345 accelerometer. I configured the different pins and SPI in master mode, and tried reading the x, y and z axis accelerations.
My issue is that the SPI readings are always 0. I tried debugging to find the issue and I realized that RXNE is never set even though I'm transmitting data and I don't really get why.
I'm using STM32F103 Board.
Here's my code:
#include "Driver_GPIO.h"
#include "stm32f10x.h"
uint8_t RxData[6];
int x,y,z;
float x_acc,y_acc,z_acc;
void GPIO_Config (void)
{
MyGPIO_Struct_TypeDef NSS={GPIOA,4,Out_OD}; // Output Open Drain
MyGPIO_Struct_TypeDef SCK={GPIOA,5,AltOut_Ppull}; // Alternate Output Push-Pull
MyGPIO_Struct_TypeDef MISO={GPIOA,6,In_Floating}; // Input Floating
MyGPIO_Struct_TypeDef MOSI={GPIOA,7,AltOut_Ppull}; // Alternate Output Push-Pull
RCC->APB2ENR |= RCC_APB2ENR_IOPAEN; //enable GPIOA clk
MyGPIO_Init(&NSS);
MyGPIO_Init(&SCK);
MyGPIO_Init(&MISO);
MyGPIO_Init(&MOSI);
}
void SPI_Enable (void)
{
SPI1->CR1 |= (SPI_CR1_SPE); // SPE=1, Peripheral enabled
}
void SPI_Disable (void)
{
SPI1->CR1 &= ~(SPI_CR1_SPE); // SPE=0, Peripheral Disabled
}
void CS_Enable (void)
{
GPIOA->BSRR |= GPIO_BSRR_BR9;
}
void CS_Disable (void)
{
GPIOA->BSRR |= GPIO_BSRR_BS9;
}
void SPI_Config(void){
RCC->APB2ENR |= RCC_APB2ENR_SPI1EN; // Enable SPI1 CLock
SPI1->CR1 |= SPI_CR1_CPOL| SPI_CR1_CPHA; // CPOL=1, CPHA=1
SPI1->CR1 |= SPI_CR1_MSTR; // Master Mode
SPI1->CR1 |= (SPI_CR1_BR_0)| (SPI_CR1_BR_1); // BR[2:0] = 400: fPCLK/16, PCLK2 = 72MHz, SPI clk = 3.375MHz
SPI1->CR1 &= ~SPI_CR1_LSBFIRST; // LSBFIRST = 0, MSB first
SPI1->CR1 |= (SPI_CR1_SSM) | (SPI_CR1_SSI); // SSM=1, SSI=1 -> Software Slave Management
SPI1->CR1 &= ~SPI_CR1_RXONLY; // RXONLY = 0, full-duplex
SPI1->CR1 &= ~SPI_CR1_DFF; // DFF=0, 8 bit data
SPI1->CR2 = 0;
}
void SPI_Transmission(uint8_t *data, int size){
uint8_t clear;
//check flag TxE //
int i=0;
while (i<size)
{
while (!((SPI1->SR)&(SPI_SR_TXE))){}; // buffer is empty
*(volatile uint8_t *)&SPI1->DR = data[i];
i++;
}
while (!((SPI1->SR)&(SPI_SR_TXE))){}; // buffer is empty
while (((SPI1->SR)&(SPI_SR_BSY))){}; // buffer not communicating
clear= SPI1->DR; // empty Overrun flag
clear= SPI1->SR;
}
void SPI_Receive (uint8_t *data,int size)
{
while (size)
{
while (((SPI1->SR)&(SPI_SR_BSY))) {}; // buffer not communicating
*(volatile uint8_t *)&SPI1->DR = 0; // dummy data
while (!((SPI1->SR) &(SPI_SR_RXNE))){};
// buffer is not empty
*data++= *(volatile uint8_t *)&SPI1->DR;
size--;
}
}
void adxl345_write (uint8_t address, uint8_t value)
{
uint8_t data[2];
data[0] = address|0x40; // multibyte write
data[1] = value;
CS_Enable (); // pull the cs pin low
SPI_Transmission (data,2); // write data to register
CS_Disable (); // pull the cs pin high
}
void adxl345_read (uint8_t address, uint8_t *RxData)
{
address |= 0x80; // read operation
address |= 0x40; // multibyte read
CS_Enable (); // pull the pin low
SPI_Transmission (&address,1); // send address
SPI_Receive (RxData,6); // receive 6 bytes data
CS_Disable ();; // pull the pin high
}
void adxl345_init (void)
{
adxl345_write (0x31, 0x01); // data_format range= +- 4g
adxl345_write (0x2d, 0x00); // reset all bits
adxl345_write (0x2d, 0x08); // power_cntl measure and wake up 8hz
}
int main(void)
{
GPIO_Config();
SPI_Config();
SPI_Enable();
adxl345_init();
do{
adxl345_read(0x32,RxData);
x = ((RxData[1]<<8)|RxData[0]); // DATA X0, X1
y = ((RxData[3]<<8)|RxData[2]); // DATA Y0, Y1
z = ((RxData[5]<<8)|RxData[4]); // DATA Z0, Z1
// Scale Factor for Xout, Yout and Zout is 7.8 mg/LSB for a +-4g, 10-bit resolution
// ==> multiply by 0.0078 to get real acceleration values
x_acc= x * 0.0078;
y_acc= y * 0.0078;
z_acc= z * 0.0078;
}while(1);
}
As already stated you have a lot of issues here
Why NSS pin is configured open-drain? Typically CS lines are push-pull. I don't know the schematics, but this is the first time I see an open-drain CS
In GPIO_Config NSS is pin 4, yet pin 9 is toggled from CS_Enable
If F1 series there is separate clocking bit for the alternate functions, it's not enabled
It is also weird that you are telling that RXNE is always zero and the readings returns zero. Your code should stuck in while loops if RXNE stays zero
I will not analyze magic numbers as I do not have time check every number in the RM. But you have many obvious issues.
Deley or readback is required after enabling the peripheral clock. You instantly set the registers which is wrong. Add __DSB(); or readback (for example (void)RCC->APB2ENR;). Same for all peripherals
I recently purchased a NUCLEO-F446RE board (an STM32F4 product) and one minor issue has been bugging me. All the code I've written executes and works just fine, but they only work after pressing the reset button on the NUCLEO board.
IDE: Keil v5
For example, I wrote code for a blinking LED:
#include "stm32f446xx.h"
int main(void) {
RCC->AHB1ENR |= RCC_AHB1ENR_GPIOAEN;
GPIOA->MODER |= GPIO_MODER_MODE5_0;
GPIOA->ODR |= GPIO_ODR_OD5;
volatile int i;
while(1) {
for(i=0; i<100000; i++)
GPIOA->ODR |= GPIO_ODR_OD5;
for(i=0; i<100000; i++)
GPIOA->ODR &= ~GPIO_ODR_OD5;
}
}
After I run and download the code onto the board, nothing will happen. Once I press reset, the LED will blink as expected.
I'm fairly certain it's something not included in my code because when I run an example program it executes immediately.
For example, a blinking LED provided by KIEL:
#include <stdio.h>
#include "Board_LED.h" // ::Board Support:LED
#include "Board_Buttons.h" // ::Board Support:Buttons
#include "stm32f4xx.h" // Device header
extern int stdout_init (void);
volatile uint32_t msTicks; /* counts 1ms timeTicks */
/*----------------------------------------------------------------------------
* SysTick_Handler:
*----------------------------------------------------------------------------*/
void SysTick_Handler(void) {
msTicks++;
}
/*----------------------------------------------------------------------------
* Delay: delays a number of Systicks
*----------------------------------------------------------------------------*/
void Delay (uint32_t dlyTicks) {
uint32_t curTicks;
curTicks = msTicks;
while ((msTicks - curTicks) < dlyTicks) { __NOP(); }
}
/*----------------------------------------------------------------------------
* SystemCoreClockConfigure: configure SystemCoreClock using HSI
(HSE is not populated on Nucleo board)
*----------------------------------------------------------------------------*/
void SystemCoreClockConfigure(void) {
RCC->CR |= ((uint32_t)RCC_CR_HSION); /* Enable HSI */
while ((RCC->CR & RCC_CR_HSIRDY) == 0); /* Wait for HSI Ready */
RCC->CFGR = RCC_CFGR_SW_HSI; /* HSI is system clock */
while ((RCC->CFGR & RCC_CFGR_SWS) != RCC_CFGR_SWS_HSI); /* Wait for HSI used as system clock */
FLASH->ACR = (FLASH_ACR_PRFTEN | /* Enable Prefetch Buffer */
FLASH_ACR_ICEN | /* Instruction cache enable */
FLASH_ACR_DCEN | /* Data cache enable */
FLASH_ACR_LATENCY_5WS ); /* Flash 5 wait state */
RCC->CFGR |= (RCC_CFGR_HPRE_DIV1 | /* HCLK = SYSCLK */
RCC_CFGR_PPRE1_DIV2 | /* APB1 = HCLK/2 */
RCC_CFGR_PPRE2_DIV1 ); /* APB2 = HCLK/1 */
RCC->CR &= ~RCC_CR_PLLON; /* Disable PLL */
/* PLL configuration: VCO = HSI/M * N, Sysclk = VCO/P */
RCC->PLLCFGR = ( 16ul | /* PLL_M = 16 */
(200ul << 6) | /* PLL_N = 200 */
( 0ul << 16) | /* PLL_P = 2 */
(RCC_PLLCFGR_PLLSRC_HSI) | /* PLL_SRC = HSI */
( 7ul << 24) | /* PLL_Q = 7 */
( 2ul << 28) ); /* PLL_R = 2 */
RCC->CR |= RCC_CR_PLLON; /* Enable PLL */
while((RCC->CR & RCC_CR_PLLRDY) == 0) __NOP(); /* Wait till PLL is ready */
RCC->CFGR &= ~RCC_CFGR_SW; /* Select PLL as system clock source */
RCC->CFGR |= RCC_CFGR_SW_PLL;
while ((RCC->CFGR & RCC_CFGR_SWS) != RCC_CFGR_SWS_PLL); /* Wait till PLL is system clock src */
}
/*----------------------------------------------------------------------------
* main: blink LED and check button state
*----------------------------------------------------------------------------*/
int main (void) {
int32_t max_num = LED_GetCount();
int32_t num = 0;
SystemCoreClockConfigure(); /* configure HSI as System Clock */
SystemCoreClockUpdate();
LED_Initialize();
Buttons_Initialize();
stdout_init(); /* Initializ Serial interface */
SysTick_Config(SystemCoreClock / 1000); /* SysTick 1 msec interrupts */
for (;;) {
LED_On(num); /* Turn specified LED on */
Delay(500); /* Wait 500ms */
while (Buttons_GetState() & (1 << 0)); /* Wait while holding USER button */
LED_Off(num); /* Turn specified LED off */
Delay(500); /* Wait 500ms */
while (Buttons_GetState() & (1 << 0)); /* Wait while holding USER button */
num++; /* Change LED number */
if (num >= max_num) {
num = 0; /* Restart with first LED */
}
printf ("Hello World\n\r");
}
}
The example code doesn't appear to have anything special that will make it run immediately.
Any help is greatly appreciated.
My guess is that it's in the project flash tools settings, maybe "run to main" or "Load Application at Startup" (not your code). To check, copy/paste your code over the top of one of the samples.
In Kiel Following Steps Follow:
Go to "Flash" options.
In flash, go to "Configure Flash Tools".
Go to the last bar/option "Utilities"
In utilities chose "Settings" options.
Finally,tick "Run and Reset" Options.
upload the code, it working without a click reset button.
I got the same problem. In Keil you need to go to "Flash -> Configure Flash Tools -> Utilities" and turn on "Run and reset" option
Regards:)
I have a problem to communicate from an Atmega3216PU to a at42qt2100.
The datasheets are: Atmega32PU16 and AT42QT2100
This is my code:
#include <avr/io.h>
#include <util/delay.h>
#include <stdio.h>
#define F_CPU 16000000
#define UART_BAUD_RATE 9600
#define UART_BAUD_REGISTERS (((F_CPU / (UART_BAUD_RATE * 16UL))) - 1)
int printCHAR(char character, FILE *stream)
{
while ((UCSRA & (1 << UDRE)) == 0) {};
UDR = character;
return 0;
}
FILE uart_str = FDEV_SETUP_STREAM(printCHAR, NULL, _FDEV_SETUP_RW);
void setup(){
// Init SIO
UCSRB |= (1 << RXEN) | (1 << TXEN);
UCSRC |= (1 << URSEL) | (1 << UCSZ0) | (1 << UCSZ1);
UBRRL = UART_BAUD_REGISTERS;
fprintf(&uart_str, "");
stdout = &uart_str;
printf("");
//Init spi
//set MOSI, SCK and SS output, all others input
DDRB |= (1<<DDB7)|(1<<DDB5)|(1<<DDB4);
SPCR |= (1<<SPE)|(1<<MSTR)|(1<<SPR1)|(1<<SPR0)|(1<<CPHA)|(1<<CPOL);
}
void loop(){
uint8_t data = 0b01000000; //Sending this sequence should return device id
printf("Sending: %d \n",data);
_delay_ms(10000);
PORTB &= 0b11101111; // SS auf LOW!! (Pin4)
SPDR = data;
while(!(SPSR & (1<<SPIF)));
PORTB |= (1<<PB4); // SS auf HIGH!! (Pin4)
printf("Receiving: %d \n",SPDR);
_delay_ms(10000);
}
void main(){
setup();
while(1){
loop();
}
}
I should get an answer from the at42qt2100 with the device id 108 but i always get 0. This ist the output: Sending: 64 Receiving: 0
Does anybody see a misconfiguration?
I did a quick overview of the AT42QT2100 datasheet that you reference and I see a couple of problems right away:
After SS is set low, the host must wait >2us (in Free Run mode) before starting SCK. You are immediately initiating a SPI transfer and, if you are running a 16MHz, that means you may be starting the transmission as soon as 62.5ns after setting SS low.
The datasheet also says that the host must send 3 data bytes within 10ms or the transaction will be treated as an error and the communication exchange will be reset. You are sending 1 byte and then waiting 20s before sending the next byte.
The datasheet says that the device settings become active after the 3 bytes have been sent. That means that 3 more bytes must be sent to get the response to your command.
You should be doing something more along the lines of this:
#define NUM_DATA_BYTES 3
void loop(){
uint8_t sendData[NUM_DATA_BYTES] =
{
0b01000000, /* Device Version Command and default values. */
0b00000000, /* Default Value for Byte 2. */
0b11000000, /* Default Value for Byte 3. */
};
uint8_t receiveData[NUM_DATA_BYTES] = { 0 };
uint8_t i;
PORTB &= 0b11101111; // SS auf LOW!! (Pin4)
/* Ensure that >2us delay requirement is met. Although, the
for() loop below will probably introduce enough delay. */
_delay_ms(1);
/* Send command data. */
for (i = 0; i < NUM_DATA_BYTES; i++)
{
SPDR = sendData[i];
while(!(SPSR & (1<<SPIF)));
}
PORTB |= (1<<PB4); // SS auf HIGH!! (Pin4)
/* Delay here may be unnecessary, but it ensures that timing
issues do not occur. */
_delay_ms(1);
PORTB &= 0b11101111; // SS auf LOW!! (Pin4)
_delay_ms(1);
/* Receive device response data. */
for (i = 0; i < NUM_DATA_BYTES; i++)
{
SPDR = sendData[i];
while(!(SPSR & (1<<SPIF)));
receiveData[i] = SPDR;
printf("Receiving byte %d: %d \n", (i + 1), receiveData[i]);
}
PORTB |= (1<<PB4); // SS auf HIGH!! (Pin4)
_delay_ms(10000);
}
I am sure this code is not perfect, but it should help to get you on the right track. Good luck!
I am using a EFM32 Giant Gecko 3700 starter kit for basic UART echoing.
When i echo RX to TX in a while(1) loop in my main function it works. However when i want to use the interrupt function, it no longer works. Checking the registers shows that my data is being read correctly, it just does not send it back.
My code:
#include "efm32gg990f1024.h"
#include "em_chip.h" // required for CHIP_Init() function
#include <string.h>
#define COM_PORT 3 // gpioPortD (USART location #1: PD0 and PD1)
#define UART_TX_pin 0
char rx_char = 0; // Temp variable for storing received characters
int main() {
CHIP_Init(); // This function addresses some chip errata and should be called at the start of every EFM32 application (need em_system.c)
uint8_t i;
char test_string[] = "\n\rHello World!\n\r";
CMU->CTRL |= (1 << 14); // Set HF clock divider to /2 to keep core frequency <32MHz
CMU->OSCENCMD |= 0x4; // Enable XTAL Oscillator
while(! (CMU->STATUS & 0x8) ); // Wait for XTAL osc to stabilize
CMU->CMD = 0x2; // Select HF XTAL osc as system clock source. 48MHz XTAL, but we divided the system clock by 2, therefore our HF clock should be 24MHz
CMU->HFPERCLKEN0 = (1 << 13) | (1 << 1); // Enable GPIO, and USART1 peripheral clocks
GPIO->P[COM_PORT].MODEL = (1 << 4) | (4 << 0); // Configure PD0 as digital output and PD1 as input
GPIO->P[COM_PORT].DOUTSET = (1 << UART_TX_pin); // Initialize PD0 high since UART TX idles high (otherwise glitches can occur)
// Use default value for USART1->CTRL: asynch mode, x16 OVS, lsb first, CLK idle low
// Default frame options: 8-none-1-none
USART1->CLKDIV = (48 << 6); // 48 will give 115200 baud rate (using 16-bit oversampling with 24MHz peripheral clock)
USART1->CMD = (1 << 11) | (1 << 10) | (1 << 2) | (1 << 0); // Clear RX/TX buffers and shif regs, Enable Transmitter and Receiver
USART1->IFC = 0x1FF9; // clear all USART interrupt flags
USART1->ROUTE = 0x103; // Enable TX and RX pins, use location #1 (UART TX and RX located at PD0 and PD1, see EFM32GG990 datasheet for details)
// Print test string
for(i=0; i<strlen(test_string); i++) {
while( !(USART1->STATUS & (1 << 6)) ); // wait for TX buffer to empty
USART1->TXDATA = test_string[i]; // print each character of the test string
}
while(1) {
// what used to be in main loop
/*
if(USART1->STATUS & (1 << 7)) { // if RX buffer contains valid data
rx_char = USART1->RXDATA; // store the data
}
if(rx_char) { // if we have a valid character
if(USART1->STATUS & (1 << 6)) { // check if TX buffer is empty
USART1->TXDATA = rx_char; // echo received char
rx_char = 0; // reset temp variable
}
}
*/
}
}
void USART1_RX_IRQHandler(void)
{
if(USART1->STATUS & (1 << 7)) { // if RX buffer contains valid data
rx_char = USART1->RXDATA; // store the data
}
if(rx_char) { // if we have a valid character
if(USART1->STATUS & (1 << 6)) { // check if TX buffer is empty
USART1->TXDATA = rx_char; // echo received char
rx_char = 0; // reset temp variable
}
}
}
You forgot to enable the interrupt vector in the NVIC, and also in the USART.
USART1->IEN = USART_IEN_RXDATAV;
NVIC_EnableIRQ(USART1_RX_IRQn);
Only 4 letters are showing up. Like in the example, I send the string "abcdef", but it only shows the 4 letters "abcf". I don't know why the other letters don't show up. I'm using Atmega8 and Bray terminal. I'm already following from the datasheet [http://ww1.microchip.com/downloads/en/DeviceDoc/21822E.pdf][1]. But I've already found a dead end.
Implementation of functions
#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;
}
and this is main function
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;
}
I hope someone can help me here. :)
Your USART is transmitting too fast for your receiver. By your fourth time through the main loop, the USART transmitter has overwritten the "d" with "e" and then with "f".
A way to get around this is to use interrupts for receiving data, instead of polling like you are doing now. But you won't be able to write to the EEPROM as fast as the interrupts come. Instead, you should queue up the letters into a circular array or linked list or some other data structure as they arrive, and then write them to EEPROM in the main loop as time allows.
Note that this solution will only help with bursty data; you save up the burst and then deal with it as you can. But if the USART is continuously too fast, then you will never be able to keep up.
To debug this issue you need to localise the place of problem and to do this you have to split your experiment on sub-tasks.
One of them is to check UART separately, the code gets here like:
while(1)
{
data = Usart_Receive();
_delay_ms(10);
Usart_Transmit(data);
}
The second one is to check SPI apart from UART stuff if you have JTAG, or altogether if you get managed with making UART working. For the separate SPI checking just comment Usart_Receive(); and Usart_Transmit(data); initialize data with anything and probably increment it in the while. Hope this idea helps.