logo elektroda
logo elektroda
X
logo elektroda
REKLAMA
REKLAMA
Adblock/uBlockOrigin/AdGuard mogą powodować znikanie niektórych postów z powodu nowej reguły.

[c] problem z odbiorem znaku (UART, mega8)

Qcinski 17 Cze 2009 20:51 2855 3
REKLAMA
  • #1 6669499
    Qcinski
    Poziom 15  
    Witam. Mam problem z odbiorem znaku przez UART na medze8. Jakiego bym znaku nie wysłał zawsze odbiera <00>. Poniżej kod źródłowy
    #include <avr/io.h>
    #include <avr/interrupt.h>
    #include <inttypes.h>
    
    #define F_OSC 1000000		           /* oscillator-frequency in Hz */
    #define UART_BAUD_RATE 4800
    #define UART_BAUD_CALC(UART_BAUD_RATE,F_OSC) ((F_OSC)/((UART_BAUD_RATE)*16l)-1)
    
    #define SPIDI	4	// Port B bit 4 (pin18): MISO : data in (MMC DO)
    #define SPIDO	3	// Port B bit 3 (pin17): MOSI : data out (MMC DI)
    #define SPICLK	5	// Port B bit 5 (pin19): SCK  : clock
    #define SPICS	2	// Port B bit 2 (pin16): SS   : chip select for MMC
    
    char sector[512];
    
    void delay_ms(unsigned short ms) {
    	unsigned short outer1, outer2;
    	outer1 = 200; 
    	while (outer1) {
    		outer2 = 1000;
    		while (outer2) {
    			while ( ms ) ms--;
    			outer2--;
    		}
    		outer1--;
    	}
    }
    
    void usart_putc(unsigned char c) {
       // wait until UDR ready
    	while(!(UCSRA & (1 << UDRE)));
    	UDR = c;    // send character
    }
    
    void uart_puts (char *s) {
    	//  loop until *s != NULL
    	while (*s) {
    		usart_putc(*s);
    		s++;
    	}
    }
    
    char odbierz(void)
    {
      /* Wait for data to be received */
    while ( !(UCSRA & (1<<RXC)) )
    ;
    /* Get and return received data from buffer */
    return UDR;
    }
    
    
    void init(void) {
    	// set baud rate
    	UBRRH  (uint8_t)(UART_BAUD_CALC(UART_BAUD_RATE,F_OSC)>>8);
    	UBRRL = (uint8_t)UART_BAUD_CALC(UART_BAUD_RATE,F_OSC);
    	// Enable receiver and transmitter; enable RX interrupt
    	UCSRB = (1<<RXEN)|(1<<TXEN)|(1<<RXCIE);
    	//asynchronous 8N1
    	UCSRC = (1<<URSEL)|(3<<UCSZ0);
    }
    
    // INTERRUPT can be interrupted
    // SIGNAL can't be interrupted
    SIGNAL (SIG_UART_RECV) { // USART RX interrupt
    	unsigned char c;
    	c = UDR;
    	usart_putc(c);
    }
    
    void serialterminate(void) { // terminate sent string!!!
    	while(!(UCSRA & (1 << UDRE)));
    	UDR = 0x0d;
    	while(!(UCSRA & (1 << UDRE)));
    	UDR = 0x0a;	
    }
    
    void SPIinit(void) {
    	DDRB &= ~(1 << SPIDI);	// set port B SPI data input to input
    	DDRB |= (1 << SPICLK);	// set port B SPI clock to output
    	DDRB |= (1 << SPIDO);	// set port B SPI data out to output 
    	DDRB |= (1 << SPICS);	// set port B SPI chip select to output
    	SPCR = (1 << SPE) | (1 << MSTR) | (1 << SPR1) | (1 << SPR0);
    	PORTB &= ~(1 << SPICS);	// set chip select to low (MMC is selected)
    }
    
    char SPI(char d) {  // send character over SPI
    	char received = 0;
    	SPDR = d;
    	while(!(SPSR & (1<<SPIF)));
    	received = SPDR;
    	return (received);
    }
    
    
    char Command(char befF, uint16_t AdrH, uint16_t AdrL, char befH )
    {	// sends a command to the MMC
    	SPI(0xFF);
    	SPI(befF);
    	SPI((uint8_t)(AdrH >> 8));
    	SPI((uint8_t)AdrH);
    	SPI((uint8_t)(AdrL >> 8));
    	SPI((uint8_t)AdrL);
    	SPI(befH);
    	SPI(0xFF);
    	return SPI(0xFF);	// return the last received character
    }
    
    int MMC_Init(void) { // init SPI
    	char i;
    	PORTB |= (1 << SPICS); // disable MMC
    	// start MMC in SPI mode
    	for(i=0; i < 10; i++) SPI(0xFF); // send 10*8=80 clock pulses
    	PORTB &= ~(1 << SPICS); // enable MMC
    
    	if (Command(0x40,0,0,0x95) != 1) goto mmcerror; // reset MMC
    
    st: // if there is no MMC, prg. loops here
    	if (Command(0x41,0,0,0xFF) !=0) goto st;
    	return 1;
    mmcerror:
    	return 0;
    }
    
    void fillram(void)	 { // fill RAM sector with ASCII characters
    	int i,c;
    	char mystring[18] = "Dowolny tekst! ";
    	c = 0;
    	for (i=0;i<=512;i++) {
    		sector[i] = mystring[c];
    		c++;
    		if (c > 17) { c = 0; }
    	}
    }
    
    int writeramtommc(void) { // write RAM sector to MMC
    	int i;
    	uint8_t c;
    	// 512 byte-write-mode
    	if (Command(0x58,0,512,0xFF) !=0) {
    		uart_puts("MMC: blad zapisu 1 ");
    		return 1;	
    	}
    	SPI(0xFF);
    	SPI(0xFF);
    	SPI(0xFE);
    	// write ram sectors to MMC
    	for (i=0;i<512;i++) {
    		SPI(sector[i]);
    	}
    	// at the end, send 2 dummy bytes
    	SPI(0xFF);
    	SPI(0xFF);
    
    	c = SPI(0xFF);
    	c &= 0x1F; 	// 0x1F = 0b.0001.1111;
    	if (c != 0x05) { // 0x05 = 0b.0000.0101
    		uart_puts("MMC: blad zapisu 2 ");
    		return 1;
    	}
    	// wait until MMC is not busy anymore
    	while(SPI(0xFF) != (char)0xFF);
    	return 0;
    }
    
    int sendmmc(void) { // send 512 bytes from the MMC via the serial port
    	int i;
    	// 512 byte-read-mode 
    	if (Command(0x51,0,512,0xFF) != 0) {
    		uart_puts("MMC: blad odczytu 1 ");
    		return 1;
    	}
    	// wait for 0xFE - start of any transmission
    	// ATT: typecast (char)0xFE is a must!
    	while(SPI(0xFF) != (char)0xFE);
    
    	for(i=0; i < 512; i++) {
    		while(!(UCSRA & (1 << UDRE))); // wait for serial port
    		UDR = SPI(0xFF);  // send character
    	}
    	serialterminate();
    	// at the end, send 2 dummy bytes
    	SPI(0xFF); // actually this returns the CRC/checksum byte
    	SPI(0xFF);
    	return 0;
    }
    
    int main(void) {
    	char znak;
    
    	init();
    	SPIinit();
    
    	uart_puts("Procek online");
    	serialterminate();
    
    	MMC_Init();
    
    	uart_puts("Karta online. Odczyt/zapis? o/z: ");
    	sei();
    	
    	znak = odbierz();
    	
    	if(znak == 'o')
    		{
    			sendmmc();
    			
    			uart_puts("512 bajtow poszlo  ");
    			serialterminate();	
    		}
    	else if(znak == 'z')
    		{
    			fillram();
    			writeramtommc();
    			uart_puts("Zapisano 512 bajtow  ");
    			serialterminate();
    		}
    	else
    		{
    			uart_puts("Cos jest nie tak  ");
    			uart_puts("Twoj znak to: ");
    			usart_putc(znak);
    			serialterminate();
    		}
    
    	return 0;
    }
    
  • REKLAMA
  • #2 6669769
    Kolek
    Poziom 25  
    Wyświetla się cokolwiek na terminalu oprócz tego zera ?
  • REKLAMA
  • #3 6670548
    dawid512
    Poziom 32  
    Po co wykorzystujesz funkcje do odbioru skoro masz odbiór w przerwaniu? W dodatku to co odbierasz to odsyłasz z powrotem :)
  • #4 6671373
    Qcinski
    Poziom 15  
    Wyświetla się "Coś jest nie tak Twoj znak to <00>.
REKLAMA