Stap 7: ATTiny USI I2C Code uitvoering - USI I2C-Slave
Dus, als een eindgebruiker, bent waarschijnlijk u meer geïnteresseerd in hoe interface van de bibliotheek aan uw eigen code! Dit is eenvoudig, en hier is waarom. Ik heb weg gedaan met de ontvangen/verzenden buffers die werden gebruikt in andere USI I2C-implementaties (vooral die op basis van AVR312 app-note) en geïmplementeerd in plaats daarvan het registreren van het protocol van de bank aan het begin van deze tutorial beschreven. De bank is opgeslagen als een serie van wijzers, niet gegevenswaarden, zodat u lokale variabelen in uw code te koppelen aan de geheugenadressen in de I2C registreren bank moet door het instellen van de aanwijzers om te wijzen op uw variabelen. Dit betekent dat uw hoofdlijn code hoeft ooit te poll I2C buffers of verwerken van gegevens aankomsten, de waarden worden bijgewerkt ogenblikkelijk wanneer ze aankomen. Het maakt het ook mogelijk programma variabelen worden ondervraagden te allen tijde door de I2C-interface zonder de hoofdlijn code (dan de vertraging als gevolg van de interrupt). Het is een knappe systeem. Laten we weer eens een kort voorbeeld.
Bijvoorbeeld, laten we zeggen dat we hebben een zeer basissoftware PWM-generator die is het besturen van een LED. Wij willen kunnen Uwijzigtdewaarde PWM (een 16-bits waarde, net omwille van het leren over pointers) zonder dat de hoofdlus ingewikkeld. Met de magie van asynchrone I2C-slave, kunnen wij enkel dat doen!
#include "usi_i2c_slave.h"
Een verwijzing naar de I2C slaaf register bank aanwijzer matrix definiëren
extern char * USI_Slave_register_buffer [];
int main()
{
16-bits PWM waarde creëren
unsigned int pwm_val = 0;
De waarde van de lage byte van pwm toewijzen aan I2C interne adres 0x00
De waarde van de hoge byte van pwm toewijzen aan I2C interne adres 0x01
USI_Slave_register_buffer [0] = (unsigned char *) & pwm_val;
USI_Slave_register_buffer [1] = (unsigned char *)(&pwm_val) + 1;
I2C-slave slave apparaat adres 0x40 initialiseren
USI_I2C_Init(0x40);
Instellen van de pin A0 als uitvoer voor LED (we gaan ervan uit dat dat wat we op chip pin A0 beschikbaar heeft)
DDRA | = 0X01;
while(1)
{
PORTA | = 0X01; LED inschakelen
voor (unsigned int i = 0; ik < pwm_val; i ++)
{
PORTA & = ~ (0x01); LED uitschakelen
}
}
}
En daar heb je het! De hoofdlus verwijst niet naar I2C helemaal, maar bij het verzenden van een PWM-waarde naar de locatie van de 16-bits interne adres van de I2C 0x00/0x01 en kunnen we volledig de controle van de PWM van de LED! Voor extra stabiliteit (om ervoor te zorgen dat alleen de aanwijzer waarden u beschikbaar zijn en om te voorkomen dat strooilicht pointers) ik stel voor dat je veranderen de #define USI_SLAVE_REGISTER_COUNT als het aantal register verwijzingen die u nodig hebt, niet meer en niet minder. Wanneer een toegang (lezen of schrijven) wordt geprobeerd op een register index buiten het bereik 0x00 USI_SLAVE_REGISTER_COUNT - 1, niets is geschreven en is het resultaat nul.