Re: I2C adress för MCP4728 beter sig konstigt?
Postat: 6 maj 2022, 07:55:04
Beroende på multimeter så kan de ta rätt god tid på sig att reagera. Ska du titta på hur signaler ändrar värde är inte en multimeter rätt verktyg.
Svenskt forum för elektroniksnack.
https://elektronikforumet.com/forum/
Du motiverar en single underline framför en HandleDefinition med att ST gör detta med dubbel underline i ett kompiler direktiv.
Om jag behöver fördröjningar så betyder det att chippet är rätt segt av sig?Swech skrev: ↑6 maj 2022, 09:31:48 Hela tråden handlar ju om att SPI delen inte fungerar som tänkt,
det funkar nästan men med småproblem med i princip allt.
Om man då är lite ödmjuk och inte antar att Microchip gjort fel
utan istället gör en normal felsökning och bekräftar att man verkligen har rätt signaler på bussen,
ACK är i sig en lurig jävel att få till rätt. OM det är fel så kan felen bli så som tråden beskriver....
Swech
Kod: Markera allt
void mcp4728_single_write_command(uint8_t channel, uint8_t Vref, uint8_t power_down, uint8_t gain, uint16_t value){
const uint8_t UDAC = 0x0;
uint8_t pData[3] = {(SINGLE_WRITE_COMMAND << 3) | (channel << 1) | UDAC, (Vref << 8) | (power_down << 5) | (gain << 4) | (value >> 8), value};
HAL_I2C_Master_Transmit(_hi2c, _address << 1, pData, sizeof(pData), Timeout);
HAL_Delay(50);
}
Kod: Markera allt
/* Write to MCP4728 */
mcp4728_init(&hi2c1, 0x4); // Manufacturer I2C settings: A4 (A2 = 1, A1 = 0, A0 = 0)
/* Set values */
mcp4728_set_channel_value(MCP4728_CHANNEL_A, 4095);
mcp4728_set_channel_value(MCP4728_CHANNEL_B, 1000);
mcp4728_set_channel_value(MCP4728_CHANNEL_C, 2000);
mcp4728_set_channel_value(MCP4728_CHANNEL_D, 3000);
/* Set gain */
mcp4728_set_channel_gain(MCP4728_CHANNEL_A, MCP4728_GAIN_1);
mcp4728_set_channel_gain(MCP4728_CHANNEL_B, MCP4728_GAIN_1);
mcp4728_set_channel_gain(MCP4728_CHANNEL_C, MCP4728_GAIN_1);
mcp4728_set_channel_gain(MCP4728_CHANNEL_D, MCP4728_GAIN_1);
/* Set power down */
mcp4728_set_channel_power_down(MCP4728_CHANNEL_A, MCP4728_POWER_DOWN_NORMAL);
mcp4728_set_channel_power_down(MCP4728_CHANNEL_B, MCP4728_POWER_DOWN_NORMAL);
mcp4728_set_channel_power_down(MCP4728_CHANNEL_C, MCP4728_POWER_DOWN_NORMAL);
mcp4728_set_channel_power_down(MCP4728_CHANNEL_D, MCP4728_POWER_DOWN_NORMAL);
/* Set voltage reference */
mcp4728_set_channel_vref(MCP4728_CHANNEL_A, MCP4728_VREF_VDD);
mcp4728_set_channel_vref(MCP4728_CHANNEL_B, MCP4728_VREF_VDD);
mcp4728_set_channel_vref(MCP4728_CHANNEL_C, MCP4728_VREF_VDD);
mcp4728_set_channel_vref(MCP4728_CHANNEL_D, MCP4728_VREF_VDD);
/* Multi write without EEPROM */
mcp4728_multi_write_command();
/* Single write with EEPROM */
mcp4728_set_channel_value(MCP4728_CHANNEL_A, 1000);
mcp4728_single_write_command(MCP4728_CHANNEL_A);
Kod: Markera allt
#include "mcp4728.h"
static I2C_HandleTypeDef *_hi2c;
static uint8_t _address;
#define Timeout 10
#define GERNAL_CALL_COMMAND 0x0
#define GENERAL_CALL_RESET 0x6
#define GENERAL_CALL_WAKE_UP 0x9
#define SINGLE_WRITE_COMMAND 0xB
#define MULTI_WRITE_COMMAND 0x8
static uint16_t channel_value[4] = {0};
static uint8_t channel_power_down[4] = {0};
static uint8_t channel_gain[4] = {0};
static uint8_t channel_vref[4] = {0};
void static transmit_reset(){
uint8_t pData[1] = {GENERAL_CALL_RESET};
HAL_I2C_Master_Transmit(_hi2c, GERNAL_CALL_COMMAND, pData, sizeof(pData), Timeout);
}
void static transmit_wake_up(){
uint8_t pData[1] = {GENERAL_CALL_WAKE_UP};
HAL_I2C_Master_Transmit(_hi2c, GERNAL_CALL_COMMAND, pData, sizeof(pData), Timeout);
}
void mcp4728_init(I2C_HandleTypeDef *hi2c, uint8_t address){
_hi2c = hi2c;
_address = (0xC << 3) | address;
transmit_reset();
transmit_wake_up();
HAL_GPIO_WritePin(LDAC_GPIO_Port, LDAC_Pin, GPIO_PIN_RESET);
}
void mcp4728_set_channel_value(uint8_t channel, uint16_t value){
if(channel <= MCP4728_CHANNEL_D)
channel_value[channel] = value;
}
void mcp4728_set_channel_power_down(uint8_t channel, uint8_t power_down){
if(channel <= MCP4728_CHANNEL_D)
channel_power_down[channel] = power_down;
}
void mcp4728_set_channel_gain(uint8_t channel, uint8_t gain){
if(channel <= MCP4728_CHANNEL_D)
channel_gain[channel] = gain;
}
void mcp4728_set_channel_vref(uint8_t channel, uint8_t vref){
if(channel <= MCP4728_CHANNEL_D)
channel_vref[channel] = vref;
}
void mcp4728_multi_write_command(){
const uint8_t UDAC = 0x0;
for(uint8_t channel = MCP4728_CHANNEL_A; channel <= MCP4728_CHANNEL_D; channel++){
uint8_t multi_write_data[3] = {(MULTI_WRITE_COMMAND << 3) | (channel << 1) | UDAC, (channel_vref[channel] << 7) | (channel_power_down[channel] << 5) | (channel_gain[channel] << 4) | (channel_value[channel] >> 8), channel_value[channel]};
HAL_I2C_Master_Transmit(_hi2c, _address << 1, multi_write_data, sizeof(multi_write_data), Timeout);
}
}
void mcp4728_single_write_command(uint8_t channel){
/* This command should only be called with a time delay about 50 ms due to the EEPROM writing */
if(channel <= MCP4728_CHANNEL_D){
const uint8_t UDAC = 0x0;
uint8_t pData[3] = {(SINGLE_WRITE_COMMAND << 3) | (channel << 1) | UDAC, (channel_vref[channel] << 7) | (channel_power_down[channel] << 5) | (channel_gain[channel] << 4) | (channel_value[channel] >> 8), channel_value[channel]};
HAL_I2C_Master_Transmit(_hi2c, _address << 1, pData, sizeof(pData), Timeout);
}
}
Kod: Markera allt
/*
* mcp4728.h
*
* Created on: May 1, 2022
* Author: Daniel M
*/
#ifndef SRC_MCP4728_MCP4728_H_
#define SRC_MCP4728_MCP4728_H_
#include "main.h"
#include <stdint.h>
#define MCP4728_CHANNEL_A 0x0
#define MCP4728_CHANNEL_B 0x1
#define MCP4728_CHANNEL_C 0x2
#define MCP4728_CHANNEL_D 0x3
#define MCP4728_VREF_VDD 0x0
#define MCP4728_VREF_INTERNAL 0x1
#define MCP4728_POWER_DOWN_NORMAL 0x0
#define MCP4728_POWER_DOWN_1K 0x1
#define MCP4728_POWER_DOWN_100K 0x2
#define MCP4728_POWER_DOWN_500K 0x3
#define MCP4728_GAIN_1 0x0
#define MCP4728_GAIN_2 0x1
void mcp4728_init(I2C_HandleTypeDef *hi2c, uint8_t address);
void mcp4728_set_channel_value(uint8_t channel, uint16_t value);
void mcp4728_set_channel_power_down(uint8_t channel, uint8_t power_down);
void mcp4728_set_channel_gain(uint8_t channel, uint8_t gain);
void mcp4728_set_channel_vref(uint8_t channel, uint8_t vref);
void mcp4728_multi_write_command();
void mcp4728_single_write_command(uint8_t channel);
#endif /* SRC_MCP4728_MCP4728_H_ */
Kod: Markera allt
channel_value[channel] >> 8