#include <avr/io.h>
#include <util/delay.h>
#include <stdint.h>
#define F_CPU 16000000UL // Clock de 16MHz
#define BAUD 9600
#define DOUT_PIN PC1 // Pino de dados (entrada)
#define PD_SCK_PIN PC0 // Pino de clock (saída)
int32_t offset = 0;
float scale_factor = 1.0; // Fator de escala inicial
// Funções UART
void uart_init(void) {
uint16_t ubrr = F_CPU / 16 / BAUD - 1;
UBRR0H = (ubrr >> 8);
UBRR0L = ubrr;
UCSR0B = (1 << TXEN0); // Habilita transmissão
UCSR0C = (1 << UCSZ01) | (1 << UCSZ00); // 8 bits de dados, 1 bit de parada
}
void uart_putc(char c) {
while (!(UCSR0A & (1 << UDRE0)));
UDR0 = c;
}
void uart_puts(const char* s) {
while (*s) {
uart_putc(*s++);
}
}
void uart_print_int32(int32_t num) {
if (num < 0) {
uart_putc('-');
num = -num;
}
char buf[12];
int i = 0;
if (num == 0) {
buf[i++] = '0';
} else {
while (num > 0) {
buf[i++] = '0' + (num % 10);
num /= 10;
}
}
for (int j = i - 1; j >= 0; j--) {
uart_putc(buf[j]);
}
}
void uart_print_float(float num, int decimals) {
if (num < 0) {
uart_putc('-');
num = -num;
}
int32_t int_part = (int32_t)num;
float frac_part = num - int_part;
uart_print_int32(int_part);
uart_putc('.');
for (int i = 0; i < decimals; i++) {
frac_part *= 10;
int digit = (int)frac_part;
uart_putc('0' + digit);
frac_part -= digit;
}
}
// Funções HX711
int32_t read_raw(void) {
while (PINC & (1 << DOUT_PIN)); // Aguarda DOUT ficar baixo
uint32_t data = 0;
for (int i = 0; i < 24; i++) {
PORTC |= (1 << PD_SCK_PIN);
_delay_us(1);
data = (data << 1) | (PINC & (1 << DOUT_PIN) ? 1 : 0);
PORTC &= ~(1 << PD_SCK_PIN);
_delay_us(1);
}
// Pulso adicional para ganho 128
PORTC |= (1 << PD_SCK_PIN);
_delay_us(1);
PORTC &= ~(1 << PD_SCK_PIN);
_delay_us(1);
// Extensão de sinal para 32 bits
if (data & 0x800000) {
data |= 0xFF000000;
}
return (int32_t)data;
}
int32_t read_average(int times) {
int64_t sum = 0;
for (int i = 0; i < times; i++) {
sum += read_raw();
}
return sum / times;
}
int32_t get_value(int times) {
return read_average(times) - offset;
}
float get_units(int times) {
return (float)get_value(times) / scale_factor;
}
void set_scale(float s) {
scale_factor = s;
}
void tare(void) {
offset = read_average(10);
}
void power_down(void) {
PORTC |= (1 << PD_SCK_PIN);
}
void power_up(void) {
PORTC &= ~(1 << PD_SCK_PIN);
}
int main(void) {
uart_init();
uart_puts("HX710B Demo com AVR Clib\r\n");
uart_puts("Inicializando a escala\r\n");
// Configuração dos pinos
DDRC |= (1 << PD_SCK_PIN); // Saída
DDRC &= ~(1 << DOUT_PIN); // Entrada
// Antes de configurar a escala
uart_puts("Antes de configurar a escala:\r\n");
uart_puts("leitura: \t\t");
uart_print_int32(read_raw());
uart_puts("\r\n");
uart_puts("média: \t\t");
uart_print_int32(read_average(20));
uart_puts("\r\n");
uart_puts("valor: \t\t");
uart_print_int32(get_value(5));
uart_puts("\r\n");
uart_puts("unidades: \t\t");
uart_print_float(get_units(5), 1);
uart_puts("\r\n");
set_scale(2280.0);
tare();
// Após configurar a escala
uart_puts("Após configurar a escala:\r\n");
uart_puts("leitura: \t\t");
uart_print_int32(read_raw());
uart_puts("\r\n");
uart_puts("média: \t\t");
uart_print_int32(read_average(20));
uart_puts("\r\n");
uart_puts("valor: \t\t");
uart_print_int32(get_value(5));
uart_puts("\r\n");
uart_puts("unidades: \t\t");
uart_print_float(get_units(5), 1);
uart_puts("\r\n");
uart_puts("Leituras:\r\n");
while (1) {
uart_puts("leitura única:\t");
uart_print_float(get_units(1), 1);
uart_puts("\t| média:\t");
uart_print_float(get_units(10), 1);
uart_puts("\r\n");
power_down();
_delay_ms(5000);
power_up();
}
return 0;
}