系統組成
-
主控單元:51單片機(如STC89C52)作為核心控制器,協調各模塊工作。
-
掃描模塊:GM65條碼掃描頭,支持二維碼/條形碼識別,通過串口(UART)與單片機通信。
-
顯示模塊:LCD1602液晶屏,用于顯示掃描結果及系統狀態(兩行16字符)。
-
輔助電路:電源穩壓、按鍵控制(可選)、蜂鳴器(掃描成功提示)等。
硬件設計
-
GM65與單片機連接
-
GM65的
TXD
接單片機RXD
(P3.0),RXD
接單片機TXD
(P3.1),共地處理。 -
模塊供電需穩定(5V/3.3V),建議獨立電源或添加濾波電容。
-
-
LCD1602顯示接口
-
使用并口模式:數據線(D0-D7)接P0口,控制線(RS、RW、EN)接P2口。
-
或通過I2C轉接板(如PCF8574)簡化連線,節省IO資源。
-
-
其他外設
-
按鍵:用于觸發掃描或清除顯示(可選)。
-
蜂鳴器:掃描成功時鳴響反饋。
-
軟件流程
-
初始化
-
配置串口:設置波特率(如9600bps)、數據格式(8N1)匹配GM65。
-
初始化LCD1602:清屏、設置顯示模式及光標。
-
-
掃描與數據處理
-
觸發掃描:GM65設置為自動感應模式(或通過按鍵觸發)。
-
數據接收:單片機通過串口中斷接收GM65發送的條碼數據。
-
數據解析:提取有效信息(如去除幀頭幀尾、校驗數據完整性)。
-
-
結果顯示
-
短文本直接顯示(如商品條碼數字)。
-
長文本滾動顯示或截取關鍵字段(如URL二維碼顯示首尾字符)。
-
錯誤提示:顯示“Error”或“Invalid Code”等狀態
-
#include <REGX52.H>
#include "LCD1602.h"
#include "Key.h"
#include "AT24C02.h"
#include "Delay.h"
#include "string.h"
#include "UART.h"
#include <stdio.h>#define BUF_SIZE 64
unsigned char KeyNum;
unsigned int Num;
unsigned char len;
char UartBuf[BUF_SIZE]; // 串口接收緩沖區
unsigned char UartCnt = 0; // 接收計數器
unsigned char flag;
void main()
{// 初始化LCD屏幕LCD_Init();// 在LCD上顯示"Data:"LCD_ShowString(1, 1, "Data:");// 清空第二行,用于后續顯示數據LCD_ShowString(1, 6, " "); // 清空第二行LCD_ShowString(2, 1, " "); // 清空第二行// 初始化UART1Uart1_Init();while (1){// 獲取按鍵值KeyNum = Key();// 當UART緩沖區中有新數據且標志位為1時if (UartBuf[0] != '\0' && flag == 1) // 有新數據到達{// 計算字符串長度len = strlen(UartBuf);flag = 0;// 清空兩行顯示,為顯示新數據做準備LCD_ShowString(1, 6, " "); // 清空第二行LCD_ShowString(2, 1, " "); // 清空第二行// 優先在第一行顯示if (len <= 11) // 第一行剩余空間足夠時,直接顯示在第一行"Data:"之后顯示全部字符{// 從第6列開始顯示數據LCD_ShowString(1, 6, UartBuf);LCD_ShowString(2, 1, " "); // 清空第二行}// 第一行剩余空間不足時換到第二行else if (len <= 27) // 11(第一行剩余)+16(第二行){// 顯示前11個字符在第一行"Data:"之后char firstLinePart[12];strncpy(firstLinePart, UartBuf, 11);firstLinePart[11] = '\0';LCD_ShowString(1, 6, firstLinePart);// 顯示剩余字符在第二行LCD_ShowString(2, 1, UartBuf + 11);}// 超過27字符截斷顯示else{char displayBuf[28];strncpy(displayBuf, UartBuf, 27);displayBuf[27] = '\0';// 顯示前11個字符在第一行"Data:"之后LCD_ShowString(1, 6, displayBuf);// 顯示剩余16個字符在第二行LCD_ShowString(2, 1, displayBuf + 11);}// 打印UART緩沖區中的數據printf("UartRoutine: %s\r\n", UartBuf);len = 0;// 清空UART緩沖區memset(UartBuf, '\0', BUF_SIZE); // 清空緩沖區}if (KeyNum == 1) // K1按鍵,Num自增{KeyNum = 0;P3_4=!P3_4; //按鍵切換模塊開啟// printf("hello\r\n");}}
}void UART_Routine() interrupt 4
{if (RI == 1) // 如果接收標志位為1,接收到了數據{if (UartCnt < BUF_SIZE - 1) // 緩沖區未滿{if (SBUF == '\n' || SBUF == '\r' || SBUF == '\x0d') // 接收到換行符{UartBuf[UartCnt] = '\0'; // 字符串結束符flag = 1;// len=UartCnt;UartCnt = 0;}else{UartBuf[UartCnt++] = SBUF; // 存儲接收到的字符}}else // 緩沖區已滿{UartBuf[BUF_SIZE - 1] = '\0'; // 強制結束字符串UartCnt = 0;}// UART_SendByte(SBUF); // 將收到的數據發回串口RI = 0; // 接收標志位清0}
}
?單片機定制: