I want to use the SPI on an Arduino Mega2560. To keep it simple I am trying to drive a74HC595 shift register. The SPI code is that in the Mega 2560 datasheet and also as I found on-line.
; SPItest3.asm Created: 29/11/2019 ;***************************************************************************** .include "./m2560def.inc" .equ SS_pin = $0 .equ SCK_pin = $1 .equ MOSI_pin = $2 .equ test_pin = $4 .org 0x0000 rjmp reset .org 0x002E TIM0isr: ; timer 0 ISR inc r3 ; add 1 to the count reti reset: clr r1 ; set the SREG to 0 out SREG, r1 ldi r28, LOW(RAMEND) ; init the stack pointer to point to RAMEND ldi r29, HIGH(RAMEND) out SPL, r28 out SPH, r29 ;---------------< Timer/Counter 0 >--------------- ldi r16, 1 ; set the Clock Selector Bits to 001, this puts Timer Counter 0 out TCCR0B, r16 ; TCNT0 in to FCPU/256 mode so it ticks at the CPU freq/256 ldi r16, (1<<TOIE0) ; set the Timer Overflow Interrupt Enable (TOIE0) bit sts TIMSK0, r16 ; of the Timer Interrupt Mask Register (TIMSK0) ;---------------< SPI as Master >--------------- ldi r17, (1<<PB4)|(1<<PB2)|(1<PB1)|(1<<PB0) ; test, MOSI, SCK & SS are outputs out DDRB, r17 ; Rest are inputs ldi r17, (1<<SPE)|(1<MSTR)|(1<SPR1)|(1<SPR0) ; Enable SPI, Master, Clock = Fosc/128 out SPCR, r17 sei main: sbi PORTB,test_pin ; test HIGH \ ldi r21,$2 ; | Make pulse to see on oscilloscope rcall delay ; | cbi PORTB,test_pin ; test LOW / ldi r21,$3 rcall delay inc r18 ; something to send cbi PORTB,SS_pin ; SS low at start of SPI rcall SPI_Transmit ldi r21,$15 rcall delay sbi PORTB,SS_pin ; SS high at end of SPI, Load data to output of 74HC595 ldi r21,$3 rcall delay rjmp main SPI_Transmit: ;-------< Transmit SPI as Master >------ out SPDR, r18 in r17,SPSR SPI_wait: in r17,SPSR sbrs r17,SPIF rjmp SPI_wait ret delay: ;----------< Simple delay function >-------- clr r3 ; set count to 0 count: mov r16, r3 ; test count cp r16, r21 brne count ; continue if not equal ret
There is no activity on either the MOSI, SCK pins or SS pin. If I remove the loop waiting for the transmission to end then the SS pin behaves as shown below.
The top blue trace is from a separate output (PORTB, 4) to give a trigger for the oscilloscope and the bottom red trace is the output from SS (PORT B, 0) which looks as if it is driving a capacitive load.
When I disable the SPI by setting SPCR to 0x00 I get good fast edges to the pulse which suggests to me that it not the hardware doing this. Using the unaltered hardware I can bit-bash the pins and I hve loaded an Arduino sketch and both methods drive the shift register properly.
I have been through the code umpteen times and I can't see what is wrong with it so I will be grateful for any help.
Thank you in advance Roger S