冰楓論壇

標題: ATTiny13A製作含小數點後一位電子秤 [打印本頁]

作者: 洪嵐峰    時間: 2023-4-2 09:31
標題: ATTiny13A製作含小數點後一位電子秤
材料:

ATTiny13A 微控制器
HX711 秤重模組
10K歐姆電阻
0.1uF陶瓷電容
0.01uF陶瓷電容
7段顯示器(帶小數點)
共陰極顯示器驅動晶片(如74HC595)
9V電池或DC電源供應器
連接腳位:

ATTiny13A:
腳位1 (PB5) -> HX711的SCK
腳位2 (PB3) -> HX711的DT
腳位5 (PB0) -> 共陰極顯示器驅動晶片的DS(串行輸入)
腳位6 (PB1) -> 共陰極顯示器驅動晶片的SHCP(時脈輸入)
腳位7 (PB2) -> 共陰極顯示器驅動晶片的STCP(輸出設定)
HX711:
VCC -> 9V電池正極或DC電源供應器正極
GND -> 9V電池負極或DC電源供應器負極
SCK -> ATTiny13A腳位1 (PB5)
DT -> ATTiny13A腳位2 (PB3)
7段顯示器:
公共端 -> GND
AG -> 共陰極顯示器驅動晶片的Q0Q6(七段顯示器的七個LED段)
時刻校正鈕:

將一個按鈕連接到ATTiny13A腳位3 (PB4),另一端連接到GND。
完整程式碼:

#include <avr/io.h>
#include <util/delay.h>

// 7段顯示器的編碼
const uint8_t digitCode[] = {
  0b00111111, // 0
  0b00000110, // 1
  0b01011011, // 2
  0b01001111, // 3
  0b01100110, // 4
  0b01101101, // 5
  0b01111101, // 6
  0b00000111, // 7
  0b01111111, // 8
  0b01101111  // 9
};

// 初始化HX711模組
void initHX711() {
  // 設定HX711的DT腳位為輸入
  DDRB &= ~(1 << PB3);
  // 設定HX711的SCK腳位為輸出
  DDRB |= (1 << PB5);
  // 將SCK腳位

#include <avr/io.h>
#include <util/delay.h>

// 7段顯示器的編碼
const uint8_t digitCode[] = {
  0b00111111, // 0
  0b00000110, // 1
  0b01011011, // 2
  0b01001111, // 3
  0b01100110, // 4
  0b01101101, // 5
  0b01111101, // 6
  0b00000111, // 7
  0b01111111, // 8
  0b01101111  // 9
};

// 初始化HX711模組
void initHX711() {
  // 設定HX711的DT腳位為輸入
  DDRB &= ~(1 << PB3);
  // 設定HX711的SCK腳位為輸出
  DDRB |= (1 << PB5);
  // 將SCK腳位設定為高電位
  PORTB |= (1 << PB5);
}

// 讀取HX711的ADC值
long readHX711() {
  uint8_t i;
  long data = 0;
  // 等待HX711準備好數據
  while (PINB & (1 << PB3));
  // 計算數據值
  for (i = 0; i < 24; i++) {
    // 將SCK設定為低電位
    PORTB &= ~(1 << PB5);
    _delay_us(1);
    // 讀取DT腳位的數據
    data = (data << 1) | (PINB & (1 << PB3));
    // 將SCK設定為高電位
    PORTB |= (1 << PB5);
    _delay_us(1);
  }
  // 補足一個標誌位和一個符號位
  data = (data ^ 0x800000) - 0x800000;
  return data;
}

// 將數字顯示在7段顯示器上
void displayNumber(float number) {
  uint8_t i, digit;
  // 分離整數和小數部分
  int integer = (int)number;
  int decimal = (int)(number * 10) % 10;
  // 將整數部分顯示出來
  for (i = 0; i < 3; i++) {
    digit = integer % 10;
    PORTB &= ~(1 << PB2); // 先將STCP設為低電位
    shiftOut(digitCode[digit]); // 輸出數字編碼
    PORTB |= (1 << PB2); // 設為高電位,完成輸出
    integer /= 10;
    _delay_ms(1);
  }
  // 顯示小數點

#include <avr/io.h>
#include <util/delay.h>

// 7段顯示器的編碼
const uint8_t digitCode[] = {
  0b00111111, // 0
  0b00000110, // 1
  0b01011011, // 2
  0b01001111, // 3
  0b01100110, // 4
  0b01101101, // 5
  0b01111101, // 6
  0b00000111, // 7
  0b01111111, // 8
  0b01101111  // 9
};

// 初始化HX711模組
void initHX711() {
  // 設定HX711的DT腳位為輸入
  DDRB &= ~(1 << PB3);
  // 設定HX711的SCK腳位為輸出
  DDRB |= (1 << PB5);
  // 將SCK腳位設定為高電位
  PORTB |= (1 << PB5);
}

// 讀取HX711的ADC值
long readHX711() {
  uint8_t i;
  long data = 0;
  // 等待HX711準備好數據
  while (PINB & (1 << PB3));
  // 計算數據值
  for (i = 0; i < 24; i++) {
    // 將SCK設定為低電位
    PORTB &= ~(1 << PB5);
    _delay_us(1);
    // 讀取DT腳位的數據
    data = (data << 1) | (PINB & (1 << PB3));
    // 將SCK設定為高電位
    PORTB |= (1 << PB5);
    _delay_us(1);
  }
  // 補足一個標誌位和一個符號位
  data = (data ^ 0x800000) - 0x800000;
  return data;
}

// 將數字顯示在7段顯示器上
void displayNumber(float number) {
  uint8_t i, digit;
  // 分離整數和小數部分
  int integer = (int)number;
  int decimal = (int)(number * 10) % 10;
  // 將整數部分顯示出來
  for (i = 0; i < 3; i++) {
    digit = integer % 10;
    PORTB &= ~(1 << PB2); // 先將STCP設為低電位
    shiftOut(digitCode[digit]); // 輸出數字編碼
    PORTB |= (1 << PB2); // 設為高電位,完成輸出
    integer /= 10;
    _delay_ms(1);
  }
  // 顯示小數點

#include <avr/io.h>
#include <util/delay.h>

// 7段顯示器的編碼
const uint8_t digitCode[] = {
  0b00111111, // 0
  0b00000110, // 1
  0b01011011, // 2
  0b01001111, // 3
  0b01100110, // 4
  0b01101101, // 5
  0b01111101, // 6
  0b00000111, // 7
  0b01111111, // 8
  0b01101111  // 9
};

// 初始化HX711模組
void initHX711() {
  // 設定HX711的DT腳位為輸入
  DDRB &= ~(1 << PB3);
  // 設定HX711的SCK腳位為輸出
  DDRB |= (1 << PB5);
  // 將SCK腳位設定為高電位
  PORTB |= (1 << PB5);
}

// 讀取HX711的ADC值
long readHX711() {
  uint8_t i;
  long data = 0;
  // 等待HX711準備好數據
  while (PINB & (1 << PB3));
  // 計算數據值
  for (i = 0; i < 24; i++) {
    // 將SCK設定為低電位
    PORTB &= ~(1 << PB5);
    _delay_us(1);
    // 讀取DT腳位的數據
    data = (data << 1) | (PINB & (1 << PB3));
    // 將SCK設定為高電位
    PORTB |= (1 << PB5);
    _delay_us(1);
  }
  // 補足一個標誌位和一個符號位
  data = (data ^ 0x800000) - 0x800000;
  return data;
}

// 將數字顯示在7段顯示器上
void displayNumber(float number) {
  uint8_t i, digit;
  // 分離整數和小數部分
  int integer = (int)number;
  int decimal = (int)(number * 10) % 10;
  // 將整數部分顯示出來
  for (i = 0; i < 3; i++) {
    digit = integer % 10;
    PORTB &= ~(1 << PB2); // 先將STCP設為低電位
    shiftOut(digitCode[digit]); // 輸出數字編碼
    PORTB |= (1 << PB2); // 設為高電位,完成輸出
    integer /= 10;
    _delay_ms(1);
  }
  // 顯示小數點

#include <avr/io.h>
#include <util/delay.h>

// 7段顯示器的編碼
const uint8_t digitCode[] = {
  0b00111111, // 0
  0b00000110, // 1
  0b01011011, // 2
  0b01001111, // 3
  0b01100110, // 4
  0b01101101, // 5
  0b01111101, // 6
  0b00000111, // 7
  0b01111111, // 8
  0b01101111  // 9
};

// 初始化HX711模組
void initHX711() {
  // 設定HX711的DT腳位為輸入
  DDRB &= ~(1 << PB3);
  // 設定HX711的SCK腳位為輸出
  DDRB |= (1 << PB5);
  // 將SCK腳位設定為高電位
  PORTB |= (1 << PB5);
}

// 讀取HX711的ADC值
long readHX711() {
  uint8_t i;
  long data = 0;
  // 等待HX711準備好數據
  while (PINB & (1 << PB3));
  // 計算數據值
  for (i = 0; i < 24; i++) {
    // 將SCK設定為低電位
    PORTB &= ~(1 << PB5);
    _delay_us(1);
    // 讀取DT腳位的數據
    data = (data << 1) | (PINB & (1 << PB3));
    // 將SCK設定為高電位
    PORTB |= (1 << PB5);
    _delay_us(1);
  }
  // 補足一個標誌位和一個符號位
  data = (data ^ 0x800000) - 0x800000;
  return data;
}

// 將數字顯示在7段顯示器上
void displayNumber(float number) {
  uint8_t i, digit;
  // 分離整數和小數部分
  int integer = (int)number;
  int decimal = (int)(number * 10) % 10;
  // 將整數部分顯示出來
  for (i = 0; i < 3; i++) {
    digit = integer % 10;
    PORTB &= ~(1 << PB2); // 先將STCP設為低電位
    shiftOut(digitCode[digit]); // 輸出數字編碼
    PORTB |= (1 << PB2); // 設為高電位,完成輸出
    integer /= 10;
    _delay_ms(1);
  }
  // 顯示小數點
  PORTB &= ~(

#include <avr/io.h>
#include <util/delay.h>

// 7段顯示器的編碼
const uint8_t digitCode[] = {
  0b00111111, // 0
  0b00000110, // 1
  0b01011011, // 2
  0b01001111, // 3
  0b01100110, // 4
  0b01101101, // 5
  0b01111101, // 6
  0b00000111, // 7
  0b01111111, // 8
  0b01101111  // 9
};

// 初始化HX711模組
void initHX711() {
  // 設定HX711的DT腳位為輸入
  DDRB &= ~(1 << PB3);
  // 設定HX711的SCK腳位為輸出
  DDRB |= (1 << PB5);
  // 將SCK腳位設定為高電位
  PORTB |= (1 << PB5);
}

// 讀取HX711的ADC值
long readHX711() {
  uint8_t i;
  long data = 0;
  // 等待HX711準備好數據
  while (PINB & (1 << PB3));
  // 計算數據值
  for (i = 0; i < 24; i++) {
    // 將SCK設定為低電位
    PORTB &= ~(1 << PB5);
    _delay_us(1);
    // 讀取DT腳位的數據
    data = (data << 1) | (PINB & (1 << PB3));
    // 將SCK設定為高電位
    PORTB |= (1 << PB5);
    _delay_us(1);
  }
  // 補足一個標誌位和一個符號位
  data = (data ^ 0x800000) - 0x800000;
  return data;
}

// 將數字顯示在7段顯示器上
void displayNumber(float number) {
  uint8_t i, digit;
  // 分離整數和小數部分
  int integer = (int)number;
  int decimal = (int)(number * 10) % 10;
  // 將整數部分顯示出來
  for (i = 0; i < 3; i++) {
    digit = integer % 10;
    PORTB &= ~(1 << PB2); // 先將STCP設為低電位
    shiftOut(digitCode[digit]); // 輸出數字編碼
    PORTB |= (1 << PB2); // 設為高電位,完成輸出
    integer /= 10;
    _delay_ms(1);
  }
  // 顯示小數點
  PORTB &= ~(1<< PB2);

shiftOut(0b10000000);
PORTB |= (1 << PB2);
_delay_ms(1);
// 將小數部分顯示出來
digit = decimal;
PORTB &= ~(1 << PB2);
shiftOut(digitCode[digit]);
PORTB |= (1 << PB2);
_delay_ms(1);
}

// 將數字編碼輸出到74HC595
void shiftOut(uint8_t data) {
uint8_t i;
for (i = 0; i < 8; i++) {
PORTB &= ~(1 << PB4); // 設定SRCLK為低電位
_delay_us(1);
// 輸出數據位
if (data & 0x80) {
PORTB |= (1 << PB3);
} else {
PORTB &= ~(1 << PB3);
}
_delay_us(1);
// 將SRCLK設定為高電位,數據位輸出到寄存器中
PORTB |= (1 << PB4);
_delay_us(1);
data <<= 1;
}
}

int main() {
float weight = 0;
// 初始化輸出腳位
DDRB |= (1 << PB2) | (1 << PB3) | (1 << PB4);
// 初始化HX711模組
initHX711();
// 設定時鐘頻率為8MHz
CLKPR = 0x80;
CLKPR = 0x00;
// 主循環
while (1) {
// 讀取HX711的ADC值
long adc = readHX711();
// 計算電子秤的重量,假設5kg的重量對應到的ADC值為10000
weight = (float)adc / 10000 * 5;
// 將重量顯示在7段顯示器上
displayNumber(weight);
_delay_ms(100);
}
return 0;
}




歡迎光臨 冰楓論壇 (https://bingfong.com/) Powered by 冰楓