電路原理圖的設計
2.1 傳送帶產品計數器設計的電路原理圖
2.2LCD顯示模塊[11]
2.3計數模塊  
2.4 鍵盤模塊
3 軟件系統設計
3.1 軟件系統的流程結構
3.2 LCD顯示程序模塊
/*-----------------------------------------------------------
文件名:lcd1602.h頭文件
功能:LCD1602驅動函數的聲明
-----------------------------------------------------------*/
#ifndef _LCD1602_H_
#define _LCD1602_H_
#include <reg52.h>
#define uint unsigned int
#define uchar unsigned char
//接口定義
sbit LcdRs = P2^0;
sbit LcdRw = P2^1;
sbit LcdEn = P2^2;
sfr DBPort = 0x80; //P0口為LCD數據總線
/*-----------------------------------------------------------
功能:LCD初始化函數
-----------------------------------------------------------*/
void LCD_Initial();
/*-----------------------------------------------------------
功能:LCD顯示字符(ASIIC碼)函數
參數:x-列0~15;y-行0~1;str-要顯示的字符串指針
-----------------------------------------------------------*/
void LCD_Prints(uchar x, uchar y,uchar *str);#endif
/*-----------------------------------------------------------
文件名:lcd1602.c
函數功能:LCD1602的驅動函數
原理:采用普通IO口方式模擬LCD1602時序,未采用總線方式
-----------------------------------------------------------*/
#include <REG52.H>
#include <intrins.h> //次頭文件中定義有_nop_()函數
#include "lcd1602.h"
/*-----------------------------------------------------------
功能:內部等待函數
返回參數:P0數據
-----------------------------------------------------------*/
uchar LCD_Wait(void)
{LcdRs=0;
LcdRw=1; _nop_();
LcdEn=1; _nop_();
//while(DBPort&0x80);
/* 在用Proteus仿真時,屏蔽此語句,否則會進入死循環,
實際硬件操作時打開此語句.*/
LcdEn=0;
return DBPort;}
/*-----------------------------------------------------------
功能:寫LCD命令/數據 函數
參數:style為寫命令/數據,0-命令,1-數據;input為寫入的8位命令/數據
-----------------------------------------------------------*/
#define LCD_COMMAND 0 // 命令
#define LCD_DATA 1 // 數據
#define LCD_CLEAR_SCREEN 0x01 // 清屏
#define LCD_HOMING 0x02 // 光標返回原點
void LCD_Write(bit style, uchar input)
{LcdEn=0;
LcdRs=style;
LcdRw=0; _nop_();
DBPort=input; _nop_();
LcdEn=1; _nop_();
LcdEn=0; _nop_();
LCD_Wait();}
/*-----------------------------------------------------------
功能:設置LCD顯示模式
參數:DisplayMode 見下面的定義
-----------------------------------------------------------*/
//顯示模式定義
#define LCD_SHOW 0x04 //顯示開
#define LCD_HIDE 0x00 //顯示關
#define LCD_CURSOR 0x02 //顯示光標
#define LCD_NO_CURSOR 0x00 //無光標
#define LCD_FLASH 0x01 //光標閃動
#define LCD_NO_FLASH 0x00 //光標不閃動
void LCD_SetDisplay(uchar DisplayMode)
{LCD_Write(LCD_COMMAND, 0x08|DisplayMode); }
/*-----------------------------------------------------------
功能:設置LCD輸入模式
參數:InputMode 見下面的定義
-----------------------------------------------------------*/
#define LCD_AC_UP 0x02 // 地址計數器增加方式
#define LCD_AC_DOWN 0x00 // 此為缺省設置
#define LCD_MOVE 0x01 // 畫面可平移
#define LCD_NO_MOVE 0x00 // 畫面不可平移
void LCD_SetInput(uchar InputMode)
{LCD_Write(LCD_COMMAND, 0x04|InputMode);}
//初始化LCD 詳見LCD1602.h中的說明
void LCD_Initial()
{LcdEn=0;
LCD_Write(LCD_COMMAND,0x38); //8位數據端口,2行顯示,5*7點陣
LCD_Write(LCD_COMMAND,0x38); //此句不能省
LCD_SetDisplay(LCD_SHOW|LCD_NO_CURSOR); //開啟顯示, 無光標
LCD_Write(LCD_COMMAND,LCD_CLEAR_SCREEN); //清屏
LCD_SetInput(LCD_AC_UP|LCD_NO_MOVE); //AC遞增, 畫面不?}
/*-----------------------------------------------------------
功能:液晶字符顯示的位置函數
參數:x-列0~15;y-行0~1;
-----------------------------------------------------------*/
void LCD_Pos(uchar x, uchar y)
{if(y==0)
LCD_Write(LCD_COMMAND,0x80|x);
if(y==1)
LCD_Write(LCD_COMMAND,0x80|(x-0x40));}
//將字符(ASIIC碼)輸出到液晶顯示 詳見LCD1602.h中的說明
void LCD_Prints(uchar x, uchar y,uchar *str)
{LCD_Pos(x,y);
while(*str!='\0'){ LCD_Write(LCD_DATA,*str); str++;}}
3.3計數程序模塊
#include"lcd1602.h"
#define uchar unsigned char
#define uint unsigned int
uchar out[6];
sbit STAR_KEY =P3^2;//定義鍵與單片機的連接引腳
sbit L0=P1^0; //定義SFR中引腳的位
sbit L1=P1^1;
sbit L2=P1^2;
sbit L3=P1^3;
sbit L4=P1^4;
sbit L5=P1^5;
sbit L6=P1^6;
sbit L7=P1^7;
sbit MOTOR=P3^0;
uchar n[2]={1,0};
void delayms(uint x) //延時子程序
{uchar y;
while(x--){for(y=0;y<123;y++){;}}
uchar Keynum() //按鍵子程序1
{uchar key=0;
STAR_KEY=1; //置初值
if(STAR_KEY==0){delayms(10);if(STAR_KEY==0)n[0]=0;n[1]=1;} //按下STAR鍵則n[0]=0;n[1]=1return n[1]; //返回n值}
void xianshi(uint dispbuf) //顯示子程序
{out[0]=dispbuf/10000+0x30;
out[1]=((dispbuf%10000)/1000)+0x30;
out[2]=((dispbuf%1000)/100)+0x30;
out[3]=((dispbuf%100)/10)+0x30;
out[4]=dispbuf%10+0x30;
out[5]='\0';
LCD_Initial(); //LCD初始化
LCD_Prints(1, 0,"The Speed Is"); //LCD輸出
LCD_Prints(10, 1,"n/min");
LCD_Prints(4, 1,out); }
uint qiuzhi() //求用撥碼盤所置數的值的子程序
{ uchar a;
uchar b;
uchar c;
uchar d;
uchar e;
uchar f;
uchar g;
uchar h;
uint p=0;
if (L0==1) {a=1;} else {a=0;} //將電平信號變為數字的值
if (L1==1) {b=1;} else {b=0;}
if (L2==1) {c=1;} else {c=0;}
if (L3==1) {d=1;} else {d=0;}
if (L4==1) {e=1;} else {e=0;}
if (L5==1) {f=1;} else {f=0;}
if (L6==1) {g=1;} else {g=0;}
if (L7==1) {h=1;} else {h=0;}
p=a+b*2+c*2*2+d*2*2*2+e*2*2*2*2+f*2*2*2*2*2+g*2*2*2*2*2*2+h*2*2*2*2*2*2*2;
return p; // 返回所求的P值}
void main(void) //主程序
{uint q;
IT0=1; //負跳變觸發
EA=1; //開總允許中斷
EX0=1; //開INTO中斷
TMOD=0X05; //置T0為計數器 方式1
TL0=0; //置計數器初值
TH0=0;
while(1) //無限循環
{ q=qiuzhi(); //調用求值子程序求出所置的數
if (MOTOR==1) {xianshi(q);} else {xianshi(TL0);Keynum();TR0=n[1];} //當電動機關閉時顯示用薄碼盤所置的數并停止計數,電機啟動時則開始計數,并顯示計數值
if (TL0==q) {TR0=0;MOTOR=1;} else {Keynum();MOTOR=n[0];} }}
//當計數值與所置數相同時關閉電機,停止計數,當計數值不等時則將電機啟動與關閉交由按鍵控制,所以不存在計數值超過置數值的情況 void Int0(void) interrupt 0 //中斷服務程序,工作寄存器用0組
{ TL0=0;TR0=1; }//重置計數值,重新開始計數
4 仿真及調試
 |