冰楓論壇

 找回密碼
 立即註冊
ads_sugarbook
搜索
查看: 506|回覆: 0
打印 上一主題 下一主題

[討論] WINBOND W78C32C-40 製作電子秤具小數兩位

[複製鏈接]

2609

主題

0

好友

947

積分

高級會員

Rank: 4

UID
373967
帖子
7447
主題
2609
精華
0
積分
947
楓幣
1268
威望
927
存款
26000
贊助金額
0
推廣
0
GP
1205
閱讀權限
50
在線時間
408 小時
註冊時間
2023-1-12
最後登入
2024-5-6

2023端午節紀念勳章 2023中秋節紀念勳章 2023聖誕節紀念勳章

跳轉到指定樓層
1
發表於 2023-4-10 19:20:28 |只看該作者 |倒序瀏覽
以下是使用 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[16];
unsigned char i, j;

init_adc();
init_lcd();

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

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

    str[0] = '-';
    str[1] = '0' + (value / 1000) % 10;
    str[2] = '0' + (value / 100) % 10;
    str[3] = '.';
    str[4] = '0' + (value / 10) % 10;
    str[5] = '0' + value % 10;
    str[6] = ' ';
    str[7] = 'k';
    str[8] = '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[8];
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);
}
}
收藏收藏0 推0 噓0


把本文推薦給朋友或其他網站上,每次被點擊增加您在本站積分: 1骰子

相關文章

複製連結並發給好友,以賺取推廣點數
簡單兩步驟,註冊、分享網址,即可獲得獎勵! 一起推廣文章換商品、賺$$
高級模式
B Color Image Link Quote Code Smilies |上傳

廣告刊登意見回饋關於我們職位招聘本站規範DMCA隱私權政策

Copyright © 2011-2024 冰楓論壇, All rights reserved

免責聲明:本網站是以即時上載留言的方式運作,本站對所有留言的真實性、完整性及立場等,不負任何法律責任。

而一切留言之言論只代表留言者個人意見,並非本網站之立場,用戶不應信賴內容,並應自行判斷內容之真實性。

小黑屋|手機版|冰楓論壇

GMT+8, 2024-5-6 05:10

回頂部