I2C adress för MCP4728 beter sig konstigt?
Re: I2C adress för MCP4728 beter sig konstigt?
Eftersom du länkar till den där Mouser sidan, så får vi väl antaga att du har en A4 variant.
Men i så fall, vad är problemet? Adressen framgår av databladet. Varför behöver du läsa den?
> Vad är det nu som får dig att tro att A2 skall vara 1 ???
Det är det som databladet anger om man köper en A4 variant...
Mouser verkar ha A0, A1 och A2 på lager. A4 inte direkt tillgänglig på lager.
Men skit samma, man köper den med den adress som man vill ha och sedan
kör man med den adressen, Varför läsa adressen? Litar du inte på leverantören?
Men i så fall, vad är problemet? Adressen framgår av databladet. Varför behöver du läsa den?
> Vad är det nu som får dig att tro att A2 skall vara 1 ???
Det är det som databladet anger om man köper en A4 variant...
Mouser verkar ha A0, A1 och A2 på lager. A4 inte direkt tillgänglig på lager.
Men skit samma, man köper den med den adress som man vill ha och sedan
kör man med den adressen, Varför läsa adressen? Litar du inte på leverantören?
Re: I2C adress för MCP4728 beter sig konstigt?
Jag litar på leverantören, men jag litar inte på att Microchip har gjort rätt.
Igår testade jag adressen 0x64<<1 och då fick jag en kanal att ge ut 3.04V.
Så något skumt är det med den.
Jag skulle behöva lite hjälp med just I2C. Vad är det exakt jag ska kolla på i databladet för att veta vad jag skall skriva?
Jag vet att med en DAC så kan jag sätta förstärkningen, voltreferensen och utgången på 12-bit. Men just att forma meddelandet till den, har jag svårt.
För det första så har jag möjlighet att flippa med LDAC pinnen. Jag tolkar LDAC MÅSTE användas efter när man har satt vout registret. Dessa är konfigurationer som jag vill använda. Ett problem som jag har, är hur man tolkar detta Jag har inget problem att tolka detta Om jag utgår från att adressen är 0x64 så behöver jag inte bitbanga och trixa med LDAC för att hitta adressen. Det kanske är därför min HAL I2C funktion ej kan hitta adressen.
Igår testade jag adressen 0x64<<1 och då fick jag en kanal att ge ut 3.04V.
Så något skumt är det med den.
Jag skulle behöva lite hjälp med just I2C. Vad är det exakt jag ska kolla på i databladet för att veta vad jag skall skriva?
Jag vet att med en DAC så kan jag sätta förstärkningen, voltreferensen och utgången på 12-bit. Men just att forma meddelandet till den, har jag svårt.
För det första så har jag möjlighet att flippa med LDAC pinnen. Jag tolkar LDAC MÅSTE användas efter när man har satt vout registret. Dessa är konfigurationer som jag vill använda. Ett problem som jag har, är hur man tolkar detta Jag har inget problem att tolka detta Om jag utgår från att adressen är 0x64 så behöver jag inte bitbanga och trixa med LDAC för att hitta adressen. Det kanske är därför min HAL I2C funktion ej kan hitta adressen.
Du har inte behörighet att öppna de filer som bifogats till detta inlägg.
Re: I2C adress för MCP4728 beter sig konstigt?
Läs det du själv citerade från databladet, nej du behöver inte använda den.För det första så har jag möjlighet att flippa med LDAC pinnen. Jag tolkar LDAC MÅSTE användas efter när man har satt vout registret.
Vet inte hur många gånger jag skrivit detta.Om jag utgår från att adressen är 0x64 så behöver jag inte bitbanga och trixa med LDAC för att hitta adressen. Det kanske är därför min HAL I2C funktion ej kan hitta adressen.
Och NEJ, din adress är INTE 0x64, utan snarare 0xC8 eftersom du måste skifta vänster, din adress är för skrivning 0b11001000 vilket blir 0xc8 och för läsning 0b11001001 vilket b lir 0xC9.
Du kan inte använda de funktioner som kräver LDAC, eftersom den kräver precis timing, vilket du inte har någon som helst kontroll över.
Re: I2C adress för MCP4728 beter sig konstigt?
PD0 PD1 = 11 var understruket, varför? Du vill väl använda DACen, inte stänga av den?
Normal mode = 00.
Normal mode = 00.
Re: I2C adress för MCP4728 beter sig konstigt?
> Jag tolkar LDAC MÅSTE användas efter när man har satt vout registret.
Som jag läser det så behöver du LDAC *enbart* om du vill att alla utgångar ska byta värde synkront (samtidigt).
Om det är OK att varje utgång ändrar värde efter sitt respektive I2C kommando, så kan LDAC hållas fast som "låg".
Och igen... *varför* måste du läsa adressen? Den är ju given utifrån vilken variant du har.
Att du "inte litar på Microchip" räcker inte...
Som jag läser det så behöver du LDAC *enbart* om du vill att alla utgångar ska byta värde synkront (samtidigt).
Om det är OK att varje utgång ändrar värde efter sitt respektive I2C kommando, så kan LDAC hållas fast som "låg".
Och igen... *varför* måste du läsa adressen? Den är ju given utifrån vilken variant du har.
Att du "inte litar på Microchip" räcker inte...
Re: I2C adress för MCP4728 beter sig konstigt?
Nu fungerar det!
Det jag MÅSTE göra är att sätta LDAC = Låg, Vänta, LDAC = Hög.
Detta är motsatsen vad det står i databladet. Databladet är lömskt! Men det fungerar
Kod för den i framtiden
Det jag MÅSTE göra är att sätta LDAC = Låg, Vänta, LDAC = Hög.
Detta är motsatsen vad det står i databladet. Databladet är lömskt! Men det fungerar
Kod för den i framtiden
Kod: Markera allt
#include "mcp4728.h"
static I2C_HandleTypeDef *_hi2c;
static uint8_t _address;
uint8_t Timeout = 10;
#define GERNAL_CALL_COMMAND 0x0
#define GENERAL_CALL_RESET 0x6
#define GENERAL_CALL_WAKE_UP 0x9
#define SINGLE_WRITE_COMMAND 0xB
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();
}
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_GPIO_WritePin(LDAC_GPIO_Port, LDAC_Pin, GPIO_PIN_RESET);
HAL_Delay(10);
HAL_GPIO_WritePin(LDAC_GPIO_Port, LDAC_Pin, GPIO_PIN_SET);
}
Re: I2C adress för MCP4728 beter sig konstigt?
Kul att det fungerar men databladet säger att LDAC är aktiv låg. Notera strecket ovanför bokstäverna.
Re: I2C adress för MCP4728 beter sig konstigt?
Databladet säger detta. Men sätter jag LDAC låg så kan jag bara skriva EN gång. Jag måste flippa med LDAC:en.
Du har inte behörighet att öppna de filer som bifogats till detta inlägg.
Re: I2C adress för MCP4728 beter sig konstigt?
Notera att det kan vara skillnad mellan att vara låg generellt och att vara "flank trigged".
Jag vet inte hur det är i just detta fall, men det kan vara skillnad på om pinnen *är*
låg eller om den *går* från hög till låg.
Jag vet inte hur det är i just detta fall, men det kan vara skillnad på om pinnen *är*
låg eller om den *går* från hög till låg.
Re: I2C adress för MCP4728 beter sig konstigt?
Så det var alltså inte en A4 utan en A0
Jag har precis skrivit kod till två andra Microchip DAC och där har jag LDAC låg direkt på kretskortet. Funkar utan problem.
Kan det vara så att du måste initiera GPIO låg vid uppstart ? Har du pulldown på den pinnen ?
Re: I2C adress för MCP4728 beter sig konstigt?
I detta fall är VDD = 3.3V. Jag litar på min processor att när jag säger att GPIO:n ska vara 0V så blir den 0V typ. Inte 0.25V.
Jag har ingen pull-down på LDAC, jag sätter bara den som låg.
Det är lustigt att jag bara kan skriva till kanal A och kanal D samtidigt, men inte B och C. För att skriva till B och C så måste jag göra det enskilt efter start.
Tror du det är kommunikationsproblem?
Du har inte behörighet att öppna de filer som bifogats till detta inlägg.
Re: I2C adress för MCP4728 beter sig konstigt?
> I detta fall är VDD = 3.3V. Jag litar på min processor att när jag säger att GPIO:n ska vara 0V så blir den 0V typ. Inte 0.25V.
OK. Det är nog bra, men har inget att göra med det som jag kommenterade ("flank-triggered" eller "edge-triggered").
OK. Det är nog bra, men har inget att göra med det som jag kommenterade ("flank-triggered" eller "edge-triggered").
Re: I2C adress för MCP4728 beter sig konstigt?
Men enligt databladet så ska jag inte ens behöva röra LDAC. Efter fjärde byten så kommer kanalen att uppdatera sig. Men det verkar inte ske.
Re: I2C adress för MCP4728 beter sig konstigt?
Det är fortfarande något som är "fishy" med det hela.
Det är ju ologiskt att du får olika resultat på de fyra kanalerna exempelvis.
På något vis får jag det till att du kommer i otakt med ditt skickande. Det vill säga att den inte fattar att den får sin sista byte som aktiverar värdet.
Jag försöker se om det är något uppenbart fel i koden, men det enda jag regerar på är att du har lite saker för dig som jag inte känner igen.
ex. pData skall vara en pekare mao. &pData
Sen fattar jag inte varför du deklarerar dina handles med underline (_hi2c) men det hade du någon utläggning om i nån annan tråd. Samma gäller ju med handles att dom anropas med pekare(&hi2c1) = "&" för att det är pekare "h" för att det är handle och "i2c1" för att det är första i2c pheriphalet.
Jag ser INTE vitsen att gå ifrån den standarden som liten (dessutom är det så CubeMX definierar upp det.)
Det är även så att den byte som innehåller adressen inte skall räknas med i storleken (antal bytes) på det som skall skickas det vill säga "Size" i anropet.
Det är ju ologiskt att du får olika resultat på de fyra kanalerna exempelvis.
På något vis får jag det till att du kommer i otakt med ditt skickande. Det vill säga att den inte fattar att den får sin sista byte som aktiverar värdet.
Jag försöker se om det är något uppenbart fel i koden, men det enda jag regerar på är att du har lite saker för dig som jag inte känner igen.
ex. pData skall vara en pekare mao. &pData
Sen fattar jag inte varför du deklarerar dina handles med underline (_hi2c) men det hade du någon utläggning om i nån annan tråd. Samma gäller ju med handles att dom anropas med pekare(&hi2c1) = "&" för att det är pekare "h" för att det är handle och "i2c1" för att det är första i2c pheriphalet.
Jag ser INTE vitsen att gå ifrån den standarden som liten (dessutom är det så CubeMX definierar upp det.)
Det är även så att den byte som innehåller adressen inte skall räknas med i storleken (antal bytes) på det som skall skickas det vill säga "Size" i anropet.
* @param hi2c Pointer to a I2C_HandleTypeDef structure that contains the configuration information for the specified I2C.
* @param DevAddress Target device address: The device 7 bits address value in datasheet must be shifted to the left before calling the interface
* @param pData Pointer to data buffer
* @param Size Amount of data to be sent
* @param Timeout Timeout duration
* @retval HAL status
Re: I2C adress för MCP4728 beter sig konstigt?
Kod: Markera allt
Det är fortfarande något som är "fishy" med det hela.
Jag tycker det också. Det finns ett kommando där man kan sätta alla kanaler samtidigt. Men dock utan gain och vref. Det kanske är sådant jag måste testa?Det är ju ologiskt att du får olika resultat på de fyra kanalerna exempelvis.
På något vis får jag det till att du kommer i otakt med ditt skickande. Det vill säga att den inte fattar att den får sin sista byte som aktiverar värdet.
pData är en vanlig array. Arrayer ÄR pekare.Jag försöker se om det är något uppenbart fel i koden, men det enda jag regerar på är att du har lite saker för dig som jag inte känner igen.
ex. pData skall vara en pekare mao. &pData
Just _ betyder "this" i C språket. Alltså _hi2c betyder att denna fick sitt minne från "konstruktören", dvs init-funktionen och konstruktörens argument heter hi2c.Sen fattar jag inte varför du deklarerar dina handles med underline (_hi2c) men det hade du någon utläggning om i nån annan tråd. Samma gäller ju med handles att dom anropas med pekare(&hi2c1) = "&" för att det är pekare "h" för att det är handle och "i2c1" för att det är första i2c pheriphalet.
Jag ser INTE vitsen att gå ifrån den standarden som liten (dessutom är det så CubeMX definierar upp det.)
Jag vet inte hur CubeMX definerar det. Dom bara skriver hi2c1 eller hi2c2 osv.
Japp! Det gör jag också. Jag använder sizeof på alla uint8_t arrayer.Det är även så att den byte som innehåller adressen inte skall räknas med i storleken (antal bytes) på det som skall skickas det vill säga "Size" i anropet.
Edit
Nu fungerar det igen. Denna gång sänkte jag frekvensen på I2C till 10 kHz och sedan ändrade jag min LDAC.
Kod: Markera allt
void mcp4728_single_write_command(uint8_t channel, uint8_t Vref, uint8_t power_down, uint8_t gain, uint16_t value){
HAL_GPIO_WritePin(LDAC_GPIO_Port, LDAC_Pin, GPIO_PIN_SET);
HAL_Delay(10);
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(10);
HAL_GPIO_WritePin(LDAC_GPIO_Port, LDAC_Pin, GPIO_PIN_RESET);
HAL_Delay(10);
HAL_GPIO_WritePin(LDAC_GPIO_Port, LDAC_Pin, GPIO_PIN_SET);
}
Jag misstänker at man MÅSTE ställa in en inställning att LDAC skall INTE användas. Vilket register man ska göra det, har jag ingen aning om.
Ja, man MÅSTE ha lite över 5 ms i fördröjning. Annars fungerar det inte.