Skip to content

Instantly share code, notes, and snippets.

@tiagohm
Last active February 22, 2018 01:57
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save tiagohm/0c8a20bcf025c95a543558b8fd2c38ca to your computer and use it in GitHub Desktop.
Save tiagohm/0c8a20bcf025c95a543558b8fd2c38ca to your computer and use it in GitHub Desktop.
PCF8591 - 8-bit A/D and D/A Converter
/*
PCF8591 - Conversor Analógico-Digital e Digital-Analógico de 8 bits.
Autor: Tiago Melo
Blog: Microcontrolandos
Compilador: MikroC PRO PIC
Bibliotecas: Soft_I2C
*/
#define PCF8591_ADDR(addr, rw) (0x90 | (addr << 1) | rw)
//Pinos do PCF8591.
sbit Soft_I2C_Scl at RB0_bit;
sbit Soft_I2C_Sda at RB1_bit;
sbit Soft_I2C_Scl_Direction at TRISB0_bit;
sbit Soft_I2C_Sda_Direction at TRISB1_bit;
typedef union {
char ad_channel_number : 2;
char auto_increment : 1;
char : 1;
char analog_input : 2;
char analog_output_enable : 1;
} PCF8591_Control_Byte;
static PCF8591_Control_Byte ctrlByte;
static char device_address = 0;
void PCF8591_Set_Address(char addr) {
device_address = addr;
}
void PCF8591_Set_Input(char input) {
//Define a configuração das entradas.
ctrlByte.analog_input = input;
//Inicio da transmissão.
Soft_I2C_Start();
//Enviar o primeiro byte: endereço + modo escrita.
Soft_I2C_Write(PCF8591_ADDR(device_address, 0));
//Enviar o segundo byte: byte de controle.
Soft_I2C_Write(*(char*)&ctrlByte);
//Fim da transmissão.
Soft_I2C_Stop();
}
void PCF8591_Set_Channel(char channel) {
//Não queremos usar o auto incremente.
ctrlByte.auto_increment = 0;
//Define o canal.
ctrlByte.ad_channel_number = channel;
//Inicio da transmissão.
Soft_I2C_Start();
//Enviar o primeiro byte: endereço + modo escrita.
Soft_I2C_Write(PCF8591_ADDR(device_address, 0));
//Enviar o segundo byte: byte de controle.
Soft_I2C_Write(*(char*)&ctrlByte);
//Fim da transmissão.
Soft_I2C_Stop();
}
char PCF8591_ADC_Read() {
char rdata;
//Inicio da transmissão.
Soft_I2C_Start();
//Enviar o primeiro byte: endereço + modo leitura.
Soft_I2C_Write(PCF8591_ADDR(device_address, 1));
//Descartamos o primeiro byte. Leitura anterior.
Soft_I2C_Read(1);
rdata = Soft_I2C_Read(0);
//Fim da transmissão.
Soft_I2C_Stop();
return rdata;
}
void PCF8591_DAC_Write(char value) {
//Habilita a saida analógica.
ctrlByte.analog_output_enable = 1;
//Inicio da transmissão.
Soft_I2C_Start();
//Enviar o primeiro byte: endereço + modo escrita.
Soft_I2C_Write(PCF8591_ADDR(device_address, 0));
//Enviar o segundo byte: byte de controle.
Soft_I2C_Write(*(char*)&ctrlByte);
//Envia o terceiro byte: valor do DAC.
Soft_I2C_Write(value);
//Fim da transmissão.
Soft_I2C_Stop();
}
void main() {
//Inicia o Soft I2C.
Soft_I2C_Init();
//Estou utilizando um dispositivo com endereço 0.
PCF8591_Set_Address(0);
//Four-Single Ended Inputs.
PCF8591_Set_Input(0);
while(1) {
char analogValue;
//Selecionamos o canal 1.
PCF8591_Set_Channel(1);
//Le o canal 1.
analogValue = PCF8591_ADC_Read();
//Gera o valor de tensão igual ao valor lido do canal 1.
PCF8591_DAC_Write(analogValue);
//Faz nada por 1s.
Delay_ms(1000);
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment