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

[ATmega16][C] SPI - dziwne zachowanie

Myrek1 13 Sie 2008 21:14 1791 3
REKLAMA
  • #1 5436581
    Myrek1
    Poziom 23  
    Mam taki kod jak niżej. Chcę odczytać ekspander po SPI i wysłać jego wartość na PC przez uart. No i jak nic nie jest podłączone do Atmegi, atmega wysyła albo wartość 0xFF albo 0xf8 rejestru SPDR. Dlaczego?

    Czy czasem rejestr SPDR nie powinien być pusty (wartość 0x00) przy odbiorze danej z niepodłączonego pinu MISO, MOSI, SCK czy CS?

    Czy podłącze MCP czy nie to i tak dostaje taką wartość.

    To bezsensu...

    
    #include <io.h>
    #include <interrupt.h>
    #include <MCP23S17.h>
    
    #define SS_NISKI() (PORTB &= ~0x10); //stan niski na SS
    #define SS_WYSOKI() (PORTB |= 0x10); //stan wysoki na SS
    
    char czas, c;
    int dana2;
    
    void uart_wyslij(int znak);
    int mcp23s17_odczytaj_B(void);
    
    ISR(SIG_OVERFLOW0)
    {
    	if(czas++ == 30)
    	{
    		if(c==1)
    		{
    			c=0;
    
    			dana2 = mcp23s17_odczytaj_B();
    			uart_wyslij(dana2);
    
    		}
    		else
    		{
    			c=1;
    		}
    		czas = 0;
    	}
    }
    
    void timer_init(void)
    {
    	TCCR0 |= _BV(CS00) | _BV(CS02);
    	TIMSK |= _BV(TOIE0);
    }
    
    void uart_init(void)
    {
    	UBRRL = 51;
    	UCSRB = _BV(RXEN)|_BV(TXEN);	
    }
    
    void spi_init(void)
    {
    	DDRB |= (1<<DDB4) | (1<<DDB5) | (1<<DDB7); //ustawienie kierunku bitow portu
    	SPCR = _BV(SPE) | _BV(MSTR) | _BV(SPR1) | _BV(SPR1);
    }
    
    void uart_wyslij(int znak)
    {
    	UDR = znak;
    	loop_until_bit_is_set(UCSRA,TXC);
    	UCSRA |= _BV(TXC);
    }
    
    void mcp23s17_wyslij(unsigned int rejestr, unsigned int dana)
    {
    	SS_NISKI();
    
    	SPDR = 0x42;
    	while(!(SPSR & (1<<SPIF)));
    
    	SPDR = rejestr;
    	while(!(SPSR & (1<<SPIF)));
    
    	SPDR = dana;
    	while(!(SPSR & (1<<SPIF)));
    
    	SS_WYSOKI();
    }
    
    void mcp23s17_init(void)
    {
    	mcp23s17_wyslij(IOCONB, 0b00001000);
    	mcp23s17_wyslij(IOCONA, 0b00001000);
    	mcp23s17_wyslij(IODIRB, 0xFF);
    	mcp23s17_wyslij(IODIRB, 0xFF);
    }
    
    int mcp23s17_odczytaj_B(void)
    {
    unsigned int dana;
    
    	SS_NISKI();
    
    	SPDR = 0x43; //odczyt
    	while(!(SPSR & (1<<SPIF)));
    
    	SPDR = GPIOB;
    	while(!(SPSR & (1<<SPIF)));
    
    	SPDR = 0x00;
    	while(!(SPSR & (1<<SPIF)));
    	
    	dana = SPDR;
    
    	SS_WYSOKI();
    
    	return dana;
    }
    
    int main(void)
    {
    	timer_init();
    	uart_init();
    	spi_init();
    	mcp23s17_init();
    	sei();
    	while(1)
    	{
    	}
    }
    


    Dlaczego podczas odczytu rejestru SPDR bez podłączonych linii pojawia się na przemian 0xFF i 0xF8?
  • REKLAMA
  • #2 5440014
    Pijopic
    Poziom 17  
    Jesli linia jest w "powietrzu" to wszystko jest mozliwe, podciagnij ja do masy (tylko gdy jest nie podlaczona) przez rezystor 1k i wtedy sprawdz...
  • REKLAMA
  • #3 5517929
    bobbyAIR
    Poziom 20  
    Myrek1 napisał:

    to podczas odczytu MCP (który jest odpięty, ale linie nie są w powietrzu bo wcześniej jest ADC) to zamiast 0x00

    Jak już ktoś napisał to prawidłowe zachowanie. Na niepodłaczonej linii zawsze będą śmieci. Wynika to ze stany Hi-Z na wyjściu drugiego układu i na wejściu procesora.
  • #4 5519119
    Myrek1
    Poziom 23  
    Linie były podłączone pod inny układ. Ale to nie przez to. Problemem był UART (przesłanie błędnej danej do odczytu).
REKLAMA