洪嵐峰 發表於 2023-4-10 19:20:28

WINBOND W78C32C-40 製作電子秤具小數兩位

以下是使用 WINBOND W78C32C-40

製作電子秤並實現小數兩位顯示的一個簡單程序示例:

// 引入頭文件
#include <reg32c32.h>
#include <intrins.h>

// 定義引腳連接
sbit LCD_RS = P1^0; // LCD RS 引腳
sbit LCD_RW = P1^1; // LCD RW 引腳
sbit LCD_EN = P1^2; // LCD EN 引腳
sbit LCD_D4 = P1^3; // LCD 數據引腳 D4
sbit LCD_D5 = P1^4; // LCD 數據引腳 D5
sbit LCD_D6 = P1^5; // LCD 數據引腳 D6
sbit LCD_D7 = P1^6; // LCD 數據引腳 D7
sbit AD_CS = P2^0; // AD 轉換器片選引腳
sbit AD_CLK = P2^1; // AD 轉換器時鐘引腳
sbit AD_DIN = P2^2; // AD 轉換器數據輸入引腳
sbit AD_DOUT = P2^3; // AD 轉換器數據輸出引腳

// 定義函數
void delay(unsigned int x);
void init_adc();
unsigned int read_adc(unsigned char channel);
void init_lcd();
void lcd_cmd(unsigned char command);
void lcd_data(unsigned char data);
void lcd_display(unsigned char x, unsigned char y, unsigned char *str);

// 延時函數
void delay(unsigned int x)
{
unsigned int i, j;
for (i = 0; i < x; i++) {
for (j = 0; j < 500; j++);
}
}

// 初始化 ADC 函數
void init_adc()
{
AD_CS = 1;
AD_CLK = 0;
AD_DIN = 1;
}

// 讀取 ADC 值函數
unsigned int read_adc(unsigned char channel)
{
unsigned char i;
unsigned int value = 0;

AD_CS = 0;

AD_CLK = 0;
AD_DIN = 1;
_nop_();
AD_CLK = 1;
_nop_();
AD_CLK = 0;

AD_CLK = 0;
AD_DIN = 1;
_nop_();
AD_CLK = 1;
_nop_();
AD_CLK = 0;

AD_CLK = 0;
AD_DIN = 0;
_nop_();
AD_CLK = 1;
_nop_();
AD_CLK = 0;

AD_CLK = 0;
AD_DIN = channel;
_nop_();
AD_CLK = 1;
_nop_();
AD_CLK = 0;

for (i = 0; i < 10; i++) {
    AD_CLK = 0;
    _nop_();
    AD_CLK = 1;
    _nop_();
    AD_CLK = 0;
    if (AD_DOUT == 1) {
        value |= (1 << (9 - i));
    }
}

AD_CS = 1;

return value;
}

// 初始化 LCD 函數
void init_lcd()
{
lcd_cmd(0x28); // 4 位數據總線,2 行顯示
lcd_cmd(0x0c);  // 開啟顯示,不顯示光標
lcd_cmd(0x06);  // 光標右移,不移動屏幕
lcd_cmd(0x01);  // 清屏
}

// LCD 命令函數
void lcd_cmd(unsigned char command)
{
LCD_RS = 0;
LCD_RW = 0;
LCD_EN = 0;
LCD_D7 = command & 0x80;
LCD_D6 = command & 0x40;
LCD_D5 = command & 0x20;
LCD_D4 = command & 0x10;

LCD_EN = 1;
_nop_();
_nop_();
LCD_EN = 0;

LCD_D7 = command & 0x08;
LCD_D6 = command & 0x04;
LCD_D5 = command & 0x02;
LCD_D4 = command & 0x01;

LCD_EN = 1;
_nop_();
_nop_();
LCD_EN = 0;

delay(5);
}

// LCD 數據函數
void lcd_data(unsigned char data)
{
LCD_RS = 1;
LCD_RW = 0;
LCD_EN = 0;
LCD_D7 = data & 0x80;
LCD_D6 = data & 0x40;
LCD_D5 = data & 0x20;
LCD_D4 = data & 0x10;

LCD_EN = 1;
_nop_();
_nop_();
LCD_EN = 0;

LCD_D7 = data & 0x08;
LCD_D6 = data & 0x04;
LCD_D5 = data & 0x02;
LCD_D4 = data & 0x01;

LCD_EN = 1;
_nop_();
_nop_();
LCD_EN = 0;

delay(5);
}

// LCD 顯示函數
void lcd_display(unsigned char x, unsigned char y, unsigned char *str)
{
if (y == 0) {
lcd_cmd(0x80 + x);
} else if (y == 1) {
lcd_cmd(0xc0 + x);
}

while (*str) {
    lcd_data(*str++);
}
}

// 主函數
void main()
{
unsigned int value;
unsigned char str;
unsigned char i, j;

init_adc();
init_lcd();

while (1) {
    value = read_adc(0);

    for (i = 0; i < 16; i++) {
        str = ' ';
    }

    str = '-';
    str = '0' + (value / 1000) % 10;
    str = '0' + (value / 100) % 10;
    str = '.';
    str = '0' + (value / 10) % 10;
    str = '0' + value % 10;
    str = ' ';
    str = 'k';
    str = 'g';

    lcd_display(0, 0, "Weight:");
    lcd_display(0, 1, str);

    delay(100);
}
}

注意:以上示例代碼僅供參考,並未經過嚴格測試,實際使用時可能需要做一些修改和優化。

電子秤的製作還需要其他硬件和軟件支持,比如稱重傳感器、AD轉換模塊、運算放大器、濾波電路、校準程序等。
此處僅提供一個簡單的示例代碼。

對於Winbond W78C32C-40 MCU,它是一款8051系列單片機,具有很好的兼容性和穩定性。
在編寫程序時,可以使用Keil C51編譯器進行開發。
以下是一個簡單的示例代碼,可以實現讀取AD轉換值,並在LCD1602液晶屏上顯示稱重結果。


#include <reg51.h>

#define LCD_RS P1_0
#define LCD_RW P1_1
#define LCD_EN P1_2
#define LCD_D7 P1_7
#define LCD_D6 P1_6
#define LCD_D5 P1_5
#define LCD_D4 P1_4

// ADC 初始化函數
void init_adc()
{
    ADCON = 0x80;  // 設置 ADC 控制寄存器,使能 ADC,選擇 AIN0 作為輸入通道
}

// 讀取 ADC 值函數
unsigned int read_adc(unsigned char ch)
{
    unsigned int value;

    ADCON &= 0xf0;
    ADCON |= ch;
    ADIF = 0;
    ADON = 1;
    while (!ADIF);
    value = (ADRESH << 8) | ADRESL;
    ADON = 0;

    return value;
}

// 延時函數
void delay(unsigned int t)
{
    unsigned int i, j;

    for (i = 0; i < t; i++) {
        for (j = 0; j < 120; j++);
    }
}

// LCD 初始化函數
void init_lcd()
{
    lcd_cmd(0x38);  // 設置顯示模式,16x2,5x7 點陣
    lcd_cmd(0x08);  // 關閉顯示,不顯示光標
    lcd_cmd(0x01);  // 清屏
    lcd_cmd(0x06);  // 光標右移,不移動屏幕
    lcd_cmd(0x0c);  // 開啟顯示,不顯示光標
}

// LCD 命令函數
void lcd_cmd(unsigned char command)
{
    LCD_RS = 0;
    LCD_RW = 0;
    LCD_EN = 0;

    LCD_D7 = command & 0x80;
    LCD_D6 = command & 0x40;
    LCD_D5 = command & 0x20;
    LCD_D4 = command & 0x10;

    LCD_EN = 1;
    _nop_();
    _nop_();
    LCD_EN = 0;

    LCD_D7 = command & 0x08;
    LCD_D6 = command & 0x04;
    LCD_D5 = command & 0x02;
    LCD_D4 = command & 0x01;

    LCD_EN = 1;
    _nop_();
    _nop();
LCD_EN = 0;

delay(10);
}

// LCD 數據函數
void lcd_data(unsigned char data)
{
LCD_RS = 1;
LCD_RW = 0;
LCD_EN = 0;
LCD_D7 = data & 0x80;
LCD_D6 = data & 0x40;
LCD_D5 = data & 0x20;
LCD_D4 = data & 0x10;

LCD_EN = 1;
_nop_();
_nop_();
LCD_EN = 0;

LCD_D7 = data & 0x08;
LCD_D6 = data & 0x04;
LCD_D5 = data & 0x02;
LCD_D4 = data & 0x01;

LCD_EN = 1;
_nop_();
_nop_();
LCD_EN = 0;

delay(10);
}

// 顯示重量函數
void display_weight(unsigned int weight)
{
unsigned char str;
sprintf(str, "%d.%d g", weight / 10, weight % 10);

lcd_cmd(0x80);  // 光標移動到第一行第一列
while (*str) {
    lcd_data(*str++);
}
}

void main()
{
unsigned int weight;

init_adc();
init_lcd();

while (1) {
    weight = read_adc(0);
    display_weight(weight);
}
}
頁: [1]
查看完整版本: WINBOND W78C32C-40 製作電子秤具小數兩位