- UID
- 373967
- 帖子
- 8822
- 主題
- 2609
- 精華
- 0
- 積分
- 994
- 楓幣
- 0
- 威望
- 971
- 存款
- 34510
- 贊助金額
- 0
- 推廣
- 0
- GP
- 1205
- 閱讀權限
- 50
- 在線時間
- 452 小時
- 註冊時間
- 2023-1-12
- 最後登入
- 2024-11-12
|
以下是使用 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);
}
} |
|