久久久久久久999_99精品久久精品一区二区爱城_成人欧美一区二区三区在线播放_国产精品日本一区二区不卡视频_国产午夜视频_欧美精品在线观看免费
標題:
51單片機實驗板lcd1602無法正確顯示
[打印本頁]
作者:
Acrux
時間:
2025-7-9 11:18
標題:
51單片機實驗板lcd1602無法正確顯示
想用過普中開發板來實現一個出租車計價器的方案,但是lcd1602無法正確顯示,代碼和開發板如下
1.jpg
(137.84 KB, 下載次數: 0)
下載附件
2025-7-9 12:10 上傳
單片機源程序如下:
#include <reg52.h>
// #include <stdio.h> // 不再需要,可以移除
// -------------------- 類型定義 --------------------
typedef unsigned char u8;
typedef unsigned int u16;
// -------------------- 引腳定義 --------------------
// LCD1602
sbit LCD_RS = P2^6;
sbit LCD_RW = P2^5;
sbit LCD_EN = P2^7;
#define LCD_DataPort P0
// 獨立按鍵
sbit KEY_START_STOP = P3^1; // K1: 開始/停止
sbit KEY_CLEAR = P3^0; // K2: 清零 / 設置值-
sbit KEY_MILEAGE = P3^2; // K3: 里程+0.1 / 設置值+
sbit KEY_SET = P3^3; // K4: 設置
// -------------------- 全局變量 --------------------
// 計價器狀態: 0-停止, 1-計價中, 2-設置模式
u8 status = 0;
// 設置模式子狀態: 0-未設置, 1-設置起步價, 2-設置起步里程, 3-設置單價
u8 setting_mode = 0;
// --- 計價參數 (默認值) ---
u16 base_price = 130; // 起步價: 13.0 元
u16 base_mileage = 30; // 起步里程: 3.0 公里
u16 unit_price = 23; // 單價: 2.3 元/公里
// --- 實時數據 ---
u16 mileage = 0; // 行車里程 (x0.1 公里)
u16 price = 0; // 總價 (x0.1 元)
u16 time_s = 0; // 行車時長 (秒)
u16 time_m = 0; // 分
u16 time_h = 0; // 時
// 定時器中斷計數變量
u16 timer_count = 0;
// -------------------- 函數聲明 --------------------
// 延時
void DelayMs(u16 ms);
// LCD驅動
void LcdWriteCmd(u8 cmd);
void LcdWriteData(u8 dat);
void LcdInit();
void LcdSetCursor(u8 row, u8 col);
void LcdShowString(u8 row, u8 col, u8 *str);
void LcdShowNum(u8 row, u8 col, u16 num, u8 len); // 顯示數字
void LcdShowTime(); // 單獨的時間顯示函數
// 顯示界面
void UpdateDisplay();
void DisplaySettingMode();
// 核心邏輯
void CalculatePrice();
void KeyAction();
void ResetAll();
void Timer0Init();
// -------------------- 主函數 --------------------
void main() {
Timer0Init();
LcdInit();
ResetAll();
while(1) {
KeyAction();
if (status == 1) { // 只有在計時狀態才需要不斷刷新時間
LcdShowTime();
}
}
}
// -------------------- 核心邏輯函數 --------------------
void CalculatePrice() {
if (mileage <= base_mileage) {
price = base_price;
} else {
unsigned long temp_price = (unsigned long)(mileage - base_mileage) * unit_price;
price = base_price + temp_price / 10;
}
// 價格計算后立即更新顯示
if (status != 2) {
UpdateDisplay();
}
}
void KeyAction() {
if (KEY_START_STOP == 0) {
DelayMs(20);
if (KEY_START_STOP == 0) {
if (status != 2) {
status = !status;
if(status == 1 && mileage == 0){
CalculatePrice(); // 開始時就計算一次價格
} else if (status == 0) {
// 停止計時,但顯示保持不變
}
UpdateDisplay(); // 更新顯示(特別是狀態字符)
}
}
while(KEY_START_STOP == 0);
}
if (KEY_CLEAR == 0) {
DelayMs(20);
if (KEY_CLEAR == 0) {
if (status == 0) {
ResetAll();
} else if (status == 2) {
switch(setting_mode) {
case 1: if(base_price > 50) base_price -= 10; break;
case 2: if(base_mileage > 10) base_mileage -= 10; break;
case 3: if(unit_price > 10) unit_price -= 1; break;
}
DisplaySettingMode();
}
}
while(KEY_CLEAR == 0);
}
if (KEY_MILEAGE == 0) {
DelayMs(20);
if (KEY_MILEAGE == 0) {
if (status == 1) {
mileage++;
CalculatePrice();
} else if (status == 2) {
switch(setting_mode) {
case 1: base_price += 10; break;
case 2: base_mileage += 10; break;
case 3: unit_price += 1; break;
}
DisplaySettingMode();
}
}
while(KEY_MILEAGE == 0);
}
if (KEY_SET == 0) {
DelayMs(20);
if (KEY_SET == 0) {
if(status == 1) return;
status = 2;
setting_mode++;
if (setting_mode > 3) {
setting_mode = 0;
status = 0;
ResetAll();
} else {
DisplaySettingMode();
}
}
while(KEY_SET == 0);
}
}
void ResetAll() {
status = 0; // 確保是停止狀態
mileage = 0;
price = 0;
time_s = 0;
time_m = 0;
time_h = 0;
T0 = 0; // 如果有,也停止計時器
UpdateDisplay(); // 更新整個顯示
LcdShowTime();
}
// -------------------- 顯示相關函數 (無sprintf) --------------------
// 更新主顯示界面(里程和價格)
void UpdateDisplay() {
// 第一行: L:XXX.XKM P:XXXX.X
LcdShowString(0, 0, "L: KM P: "); // 模板,用空格覆蓋舊數據
LcdShowNum(0, 2, mileage / 10, 3); // 里程整數部分,最多3位
LcdWriteData('.');
LcdShowNum(0, 6, mileage % 10, 1); // 里程小數部分
LcdShowNum(0, 11, price / 10, 4); // 價格整數部分,最多4位
LcdWriteData('.');
LcdShowNum(0, 16, price % 10, 1); // 價格小數部分
// 在時間前面顯示狀態符號
LcdSetCursor(1, 0);
if(status == 1) LcdWriteData('T'); // Timing
else if(status == 0) LcdWriteData('S'); // Stop
else if(status == 2) LcdWriteData('C'); // Config
}
// 單獨更新時間顯示,減少LCD刷新
void LcdShowTime() {
// 第二行: T:HH:MM:SS
LcdSetCursor(1, 1);
LcdShowString(1, 1, ":");
LcdShowNum(1, 2, time_h, 2);
LcdShowString(1, 4, ":");
LcdShowNum(1, 5, time_m, 2);
LcdShowString(1, 7, ":");
LcdShowNum(1, 8, time_s, 2);
}
// 顯示設置模式界面
void DisplaySettingMode() {
LcdWriteCmd(0x01); // 清屏
UpdateDisplay(); // 顯示狀態'C'
switch(setting_mode) {
case 1:
LcdShowString(0, 0, "Set Base Price ");
LcdShowNum(1, 5, base_price/10, 3);
LcdWriteData('.');
LcdShowNum(1, 9, base_price%10, 1);
LcdShowString(1, 10, " Yuan ");
break;
case 2:
LcdShowString(0, 0, "Set Base Mile ");
LcdShowNum(1, 5, base_mileage/10, 2);
LcdWriteData('.');
LcdShowNum(1, 8, base_mileage%10, 1);
LcdShowString(1, 9, " KM ");
break;
case 3:
LcdShowString(0, 0, "Set Unit Price ");
LcdShowNum(1, 5, unit_price/10, 2);
LcdWriteData('.');
LcdShowNum(1, 8, unit_price%10, 1);
LcdShowString(1, 9, " Y/KM ");
break;
}
}
// -------------------- 定時器和中斷 --------------------
void Timer0Init() {
TMOD &= 0xF0;
TMOD |= 0x01;
TH0 = (65536 - 1000) / 256;
TL0 = (65536 - 1000) % 256;
EA = 1;
ET0 = 1;
TR0 = 1;
}
void timer0_isr() interrupt 1 {
TH0 = (65536 - 1000) / 256;
TL0 = (65536 - 1000) % 256;
if (status == 1) {
timer_count++;
if (timer_count >= 1000) {
timer_count = 0;
time_s++;
if (time_s >= 60) {
time_s = 0;
time_m++;
if (time_m >= 60) {
time_m = 0;
time_h++;
}
}
}
}
}
// -------------------- LCD底層驅動 --------------------
void DelayMs(u16 ms) {
u16 i, j;
for(i=ms; i>0; i--)
for(j=120; j>0; j--);
}
void LcdWriteCmd(u8 cmd) {
LCD_RS = 0;
LCD_RW = 0;
LCD_DataPort = cmd;
DelayMs(1);
LCD_EN = 1;
DelayMs(1);
LCD_EN = 0;
}
void LcdWriteData(u8 dat) {
LCD_RS = 1;
LCD_RW = 0;
LCD_DataPort = dat;
DelayMs(1);
LCD_EN = 1;
DelayMs(1);
LCD_EN = 0;
}
void LcdInit() {
LcdWriteCmd(0x38);
LcdWriteCmd(0x0C);
LcdWriteCmd(0x06);
LcdWriteCmd(0x01);
DelayMs(5);
}
void LcdSetCursor(u8 row, u8 col) {
u8 addr;
if (row == 0) {
addr = 0x80 + col;
} else {
addr = 0x80 + 0x40 + col;
}
LcdWriteCmd(addr);
}
void LcdShowString(u8 row, u8 col, u8 *str) {
LcdSetCursor(row, col);
while(*str != '\0') {
LcdWriteData(*str++);
}
}
// *** 新增的顯示數字的函數 ***
// 在(row, col)顯示數字num,共顯示len位,不足則前面補空格
void LcdShowNum(u8 row, u8 col, u16 num, u8 len) {
u8 i;
u8 buf[5]; // 假設數字最大5位
for (i = 0; i < len; i++) {
buf[len - 1 - i] = (num % 10) + '0';
num /= 10;
}
// 如果數字本身位數小于len,前面補空格
for (i = 0; i < len; i++) {
if (num == 0 && buf[i] == '0' && i < len - 1) { // 找到最高位
if(i < len - 1) buf[i] = ' '; // 將高位0轉換為空格, 但保留個位數0
} else {
break; // 找到第一個非零數字后停止
}
}
// 處理num=0的情況
if (len > 1 && buf[0] == ' ') {
// 確保個位數如果是0,能正常顯示
if(len > 1 && num == 0){
// 此處確保至少有一個'0'顯示
}
}
LcdSetCursor(row, col);
for (i = 0; i < len; i++) {
LcdWriteData(buf[i]);
}
}
復制代碼
作者:
IdeaMing
時間:
2025-7-9 13:39
1,檢查pin腳定義,
2,檢查端口是否有輸出正確的數據,
3,檢查數據的LSB還是MSB.
作者:
man1234567
時間:
2025-7-9 15:46
學習板自帶的1602例程移植就好。
作者:
單片機重購
時間:
2025-7-9 16:28
首先你使用LCD1602的液晶屏應該是有自帶的驅動程序。從你需要實現的目的開始求我們現在,你的要是沒有看到的。不知道你的具體要求是什莫。你是不是覺得LCD1602比較簡單,我給你說我之前用普中科技的板子寫代碼用來寫字符的時候時,我也出錯了。所以我大概率判斷是你的LCD1602的驅動程序有問題,是需要去查看LCD1602驅動程序的問題。也有可能是你的端口輸出數據的問題,數據到底是LSB還是MSB呢,你是不是把數據的類型搞錯了哦。是不是輸出的數據類型不對等的呢。
作者:
hhdsdy
時間:
2025-7-9 18:07
這個程序是從這塊開發板的1602移植的嗎?看照片各個模塊的引腳是固定死無法自己定義的,所以軟件得服從硬件,先把各個引腳定義為硬件的實際連接才行。
作者:
轉角遇見劫匪
時間:
2025-7-9 18:30
首先你使用LCD1602的液晶屏應該是有自帶的驅動程序。從你需要實現的目的開始求我們現在,你的要是沒有看到的。不知道你的具體要求是什莫。你是不是覺得LCD1602比較簡單,我給你說我之前用普中科技的板子寫代碼用來寫字符的時候時,我也出錯了。所以我大概率判斷是你的LCD1602的驅動程序有問題,是需要去查看LCD1602驅動程序的問題。也有可能是你的端口輸出數據的問題,數據到底是LSB還是MSB呢.
作者:
hhdsdy
時間:
2025-7-9 22:47
地板樓的“單片機重購”和6樓的“ID:1156151”帖子怎么一模一樣?是同一個人嗎?
作者:
人中狼
時間:
2025-7-10 16:43
沒查忙
作者:
joyb
時間:
2025-7-11 08:49
單獨實驗1602
歡迎光臨 (http://m.zg4o1577.cn/bbs/)
Powered by Discuz! X3.1
主站蜘蛛池模板:
亚洲 欧美 综合
|
亚洲高清免费视频
|
久久久久国产精品视频
|
亚洲视频免费
|
激情久久久
|
精品黄色片
|
成人做爰www看视频软件
|
国产美女自拍视频
|
欧美亚洲国产精品
|
91视频免费观看
|
av网站在线免费观看
|
久久精品国产一区二区
|
欧美自拍视频
|
a视频在线观看
|
国产1级片
|
久草视频免费看
|
亚洲欧美日韩一区二区
|
诱人的大乳奶3做爰
|
国产成人亚洲精品自产在线
|
香蕉综合网
|
欧美亚洲国产精品
|
天天爽夜夜操
|
天天综合色
|
欧美日韩在线一区二区
|
国产在线黄色
|
日韩视频网
|
欧美一级一级
|
亚洲激情一区
|
日韩午夜在线观看
|
www中文字幕
|
国产亚洲区
|
特一级黄色片
|
日韩成人精品视频
|
波多野结衣一级片
|
一级黄色片免费观看
|
免费网站黄色
|
黄色在线小视频
|
一级片在线观看视频
|
国产午夜在线观看
|
日韩精品视频在线免费观看
|
九九九久久久
|