Reputation: 15
//*----------------------------------
//*
//* PROGRAM NAME:
//* MAX5402_test.asm
//*
//* AUTHOR(S):
//* Wilmer
//*
//* Version:
//* 1.0
//*
//* Last Updated:
//* 12/01/2016
//*
//* Target:
//* ATmega16A
//*
//* DESCRIPTION:
//* This program tests the
//* MAX5402 Digital POT. using
//* subroutines MAX5402_SPI_init,
//* to initialize the ATmega16A's
//* hardware for SPI, and
//* subroutine MAX5402_SPI_write
//* to write an 8-bit value to the
//* Digital POT to set the position
//* of the wiper.
//*
//* PORTS:
//*
//* PORTA:
//* Not Used.
//*
//* PORTB:
//* PIN5 = MOSI OUPUT
//* PIN7 = SCK OUTPUT
//*
//* PORTC:
//* J-Tag Pins
//* PIN0 = CHIP SELECT OUTPUT
//*
//* PORTD:
//* Not Used.
//*
//* Version History:
//* 1.0 Original Version
//*
//*----------------------------------
start:
//--------Port Configuration--------//
sbi DDRC, 0 ; Port C, Pin0 as
; output for chip
; select
ldi r16, $BF ; PORTB as output
out DDRB, r16; and MISO as Input
//----------Initilize Stack----------//
ldi r16, LOW(RAMEND)
out SPL, r16
ldi r16, HIGH(RAMEND)
out SPH, r16
//Initialize SPI//
call MAX5402_SPI_init
main_loop:
//Write to the MAX5402//
ldi r16, $AB
call MAX5402_SPI_write
rjmp main_loop
//*-------------------------------------
//*
//* SUBROUTINE NAME:
//* MAX5402_SPI_init
//*
//* AUTHOR(S):
//* Wilmer
//*
//* MODIFIES:
//* SPCR (SPI Control Register)
//*
//* DESCRITION:
//* Initialize SPI hardware to
//* communicate with the MAX5402
//*
//*-------------------------------------
MAX5402_SPI_init:
push r16 ; conserve
//---Configuring SPI Control Register---//
;SPI Interrupt disabled
;SPI enabled
;MSB transmitted first
;Master Selected
;Clock Phase & Polarity = 0
;SCK Frequency = fosc/128
ldi r16, (0 << SPIE) | (1 << SPE) | (0 << DORD) | (1 << MSTR) |
(0 << CPOL) | (0 << CPHA) | (1 << SPR1) | (1 << SPR0)
out SPCR,r16
//-------Clear SPI Interrupt Flag-------//
in r16, SPSR
in r16, SPDR
pop r16 ; restore
ret
//*--------------------------------
//*
//* SUBROUTINE NAME:
//* MAX5402_SPI_write
//*
//* AUTHOR(S):
//* Wilmer
//*
//* MODIFIES:
//* R16
//*
//* DESCRITION:
//* Writes 8-bit value in r16.
//* This value is used to set the
//* wiper position of the MAX5402.
//*
//*--------------------------------
MAX5402_SPI_write:
push r17 ; conserve
push r18
push r19
ldi r19, $FF ; Max Value
ldi r17, $00 ; select MAX5402
out PINC, r17
//----------Send Data to Slave----------//
send_data:
out SPDR, r16 ; send data to the
; SPI Data Register
//-----Wait for Data to be Transfered-----//
wait:
sbis SPSR, SPIF
rjmp wait
inc r16 ; cpmare r16 to max value
cpse r16, r19 ; if equal, stop sending data
rjmp send_data ; and repeat
ldi r17, 1 ; de-select MAX5402
out PINC, R16
pop r19
pop r18
pop r17 ; restore
ret
Hello, I'm writing this program (a tester) for a MAX5402 Digital potentiometer using the ATmega16A. For this program, the H terminal of the MAX5402 is set to +5V and the terminal L to ground to create a simple potential divider with its output at terminal W (Datasheet for reference: https://datasheets.maximintegrated.com/en/ds/MAX5402.pdf).
What I need to do is write a subroutine that initializes the MCU's SPI hardware for the MAX5402 and another subroutine that sends an 8-bit value to it using r16 (0x00 --> 0xFF). This 8-bit value is used to set the position of the MAX5402's wiper.
My problem is that when using ATMEL STUDIO 7.0 for emulation, the wiper is outputting only 2.5V. No matter what value I send to it, the output does not change.
I've triple checked all physical connections, so the problem has to be in the code; but I cannot figure out what's wrong. Any help is greatly appreciated, Thank you!
Upvotes: 0
Views: 164
Reputation: 8449
The MAX5402_SPI_write
routine looks peculiar. Why are you sending so many bits over SPI?
From the data sheet, it looks like the device expects: notCS low, one byte over SPI, then notCS high again. You are sending many bytes over SPI in the middle step. This will corrupt the data, and the device will default to the middle value, as you are seeing.
Upvotes: 0