This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

AMC7832: DAC output changes value without command

Part Number: AMC7832

Hello!

I am using the AMC7832 for an analog expension card with 8 analog inputs and 8 analog outputs. To test the fuction, i have connected the 8 DACs to the 8 ADCs. 

My problem is that after a short time (average 30 seconds) the output of the DACs changes to 0V (i am using the DACs for the range of 0 to +10V).

I had the same problem with the ADCs, but i have solved the problem over the software.

Maybe someone can help me to solve the problem.

THX,

Tobi

  • Hi Tobias,

    I would suspect there is an issue with your setup that is causing the device to reset. Can you post your schematic?

    Thanks!
  • here is my schematic, maybe you can find an issue

  • I do not see any obvious issues with your schematic. Do you think you could use a oscilloscope to capture the value of the supplies, DAC, and reference during one of these events?
  • Thanks for your help so far Paul,

    I have measured the voltages at the IC and I figured out that not the DAC is the problem!

    It seems like the ADC auto conversion stops after a not specified time, at the moment I solved the problem, by just give the adctrig a tick to restart the auto conversion.

    However I don't understand why the auto conversion stops, I will read the datasheet again and maybe i can find a better solution.

    I have added two screenshots, the first shows the supply voltages during the "auto conversion stop", the second shows the DAC output, which stays stable, during the event

    p.s. have a nice weekend :)

  • How many unique conversions can you read before it stops? If it is just one then I think you may not actually be in auto mode. You could also double check your code an make sure you are not modifying any registers by accident, like the configuration registers or mux register.

    Thanks!
  • It looks like sometimes the problem doesn't occure...

    I have counted the DAV ticks before the stop of the ADC, and the value was 107000 conversion ticks.
    My suspicion is that it is relating to the temperature channel, but I am not 100% sure.

    I will create a flow chart with the commands for the AMC7832 and show it here...
  • Hi Tobias,

    Any updates?
  • Hi Paul,

    I am 99% sure that the problem only occurs when the temperature sensor is activated (and auto conversion is used).

    Maybe its because I don't wait for the DAV tick?

    At the moment its not really possible to use interrupts because I am using FreeRTOS!

    We are changing our design and will use an own microcontroller for AMC7832, then it will be possible to wait for the tick.

    As promised here are the used commands:

  • Hi Tobias,

    I do not think waiting (or not waiting) for the DAV pulse is causing the ADC to stop converting. I suspect that there is a bug in the code where another register is being written to. Is it possible that the MUX registers are being written to by mistake or in an integer overflow situation?

    Thanks!
    Paul
  • Hi Paul,

    I have added you the code snippet in which the temperature is handled! (it is done periodically)

    I have also checked the rest of the code, and I do not believe that the MUX registers are written accidentally!

    void AMC7832_temperature(card_slots *Card)
    {
    	if (FlashStorage[Card->SP_position].InitFlag.TemperatureActiv == 1)
    	{
    		if (Card_Analog[Card->SP_position].TempActiv == 0)
    		{
    			AMC7832_Write(0x15, 0x02, Card->SPI_port, Card->CS_port[1], Card->CS_pin[1]); // mux configuration to enable temperature sensor ADC
    			AMC7832_Write(0xC0, 0x01, Card->SPI_port, Card->CS_port[1], Card->CS_pin[1]); // starts auto conversion
    			Card_Analog[Card->SP_position].TempActiv = 1;
    		}
    
    		uint8_t temp[3];
    		float tempsave;
    
    		volatile uint8_t position = Card->SP_position;
    
    		AMC7832_Read(0x78, temp, Card->SPI_port, Card->CS_port[1], Card->CS_pin[1]); // read temp data low byte
    		uint8_t cache = temp[2];
    		AMC7832_Read(0x79, temp, Card->SPI_port, Card->CS_port[1], Card->CS_pin[1]); // read temp data high byte
    
    		int16_t temperatur = ((temp[2] << 8) | cache) & 0x0FFF; //combines the two temp registers of AMC7832
    
    		if ((temperatur & 0x0E00) == 0x0E00) //check if temp is negativ; calculate the temp in °C
    		{
    			tempsave = (((float) (4096 - temperatur) / 4.0f) * (-1.0f));
    		}
    		else
    		{
    			tempsave = ((float) temperatur / 4.0f);
    		}
    
    		if ((tempsave > 125.0f) || (tempsave < -40.0f)) //check if temp is out of range, common at about 0°C because temp in registers is unstable; possible that one reg is over 0° and the other under 0°
    		{
    			tempsave = 0;
    			Card_Analog[position].countTemp--;
    		}
    
    		Card_Analog[position].meanTemp = Card_Analog[position].meanTemp + tempsave;
    		Card_Analog[position].countTemp++;
    		if (Card_Analog[position].countTemp >= 50)
    		{
    			Card_Analog[position].temperature = (float) Card_Analog[position].meanTemp / 50.0f;
    			Card_Analog[position].meanTemp = 0;
    			Card_Analog[position].countTemp = 0;
    			tempsave = 0;
    		}
    	}
    	else
    	{
    		if (Card_Analog[Card->SP_position].TempActiv == 1)
    		{
    			AMC7832_Write(0x15, 0x00, Card->SPI_port, Card->CS_port[1], Card->CS_pin[1]); // mux configuration to disable temperature sensor ADC
    			AMC7832_Write(0xC0, 0x01, Card->SPI_port, Card->CS_port[1], Card->CS_pin[1]); // starts auto conversion
    			Card_Analog[Card->SP_position].TempActiv = 0;
    		}
    	}
    }
    
    void AMC7832_Write(uint8_t control_l, uint8_t data, SPI_HandleTypeDef SPI_Port, GPIO_TypeDef* CS_Port, uint16_t CS_Pin)
    {
    	uint8_t spi_transmit[3];
    	uint8_t spi_receive[3];
    
    	spi_transmit[0] = 0x00; 	//control byte high -> decides read/write
    	spi_transmit[1] = control_l; 	//control byte low -> address of register
    	spi_transmit[2] = data; 	//data write byte
    
    	HAL_GPIO_WritePin(CS_Port, CS_Pin, 0);
    	HAL_SPI_TransmitReceive(&SPI_Port, spi_transmit, spi_receive, 3, 1);
    	HAL_GPIO_WritePin(CS_Port, CS_Pin, 1);
    }
    
    void AMC7832_Read(uint8_t control_l, uint8_t *data_rec, SPI_HandleTypeDef SPI_Port, GPIO_TypeDef* CS_Port, uint16_t CS_Pin)
    {
    	uint8_t spi_transmit[3];
    
    	spi_transmit[0] = 0x80; 	//control byte high -> decides read/write
    	spi_transmit[1] = control_l; 	//control byte low -> address of register
    	spi_transmit[2] = 0x00; 	//data write byte
    
    	*data_rec = 0x00;
    
    	HAL_GPIO_WritePin(CS_Port, CS_Pin, 0);
    	HAL_SPI_TransmitReceive(&SPI_Port, spi_transmit, data_rec, 3, 1);
    	HAL_GPIO_WritePin(CS_Port, CS_Pin, 1);
    }

    Thanks,

    Tobias

  • Hi Tobias,

    I do not see anything obviously wrong with your code, but are you using SPI_CS2 port anywhere else on your system besides the RESET pin of the AMC? I noticed you specify the CS port in you SPI Read and Write functions, maybe you are resetting the AMC during another devices read/write operation?
  • Hi Tobias,

    Were you able to resolve this?

    Paul