#include <reg52.h>
#include <stdio.h>
#include <math.h>
#include <intrins.h>
#define KeyPort P0
#define uchar unsigned char
#define uint unsigned int
#define DataPort P0
sbit ADDO = P1^6;
sbit ADSK = P1^7;
unsigned int num;
unsigned int dnf;
float i;
unsigned int priceV;
//////////////////////////
/*-----------------------------------------------
LCD12864引脚接口
------------------------------------------------*/
sbit RS = P2^4;
sbit RW = P2^5;
sbit E = P2^6;
sbit RES = P2^3;
sbit PSB = P2^1;
sbit PAUSE = P3^0;
unsigned char temp[16];
unsigned char lol[16];
void DelayUs2x(unsigned char t)
{
while(--t);
}
void DelayMs(unsigned char t)
{
while(t--)
{
//大致延时1mS
DelayUs2x(245);
DelayUs2x(245);
}
}
/*------------------------------------------------
检测忙位
------------------------------------------------*/
void Check_Busy()
{
RS=0;
RW=1;
E=1;
DataPort=0xff;
while((DataPort&0x80)==0x80);//忙则等待
E=0;
}
/*------------------------------------------------
写命令
------------------------------------------------*/
void Write_Cmd(unsigned char Cmd)
{
Check_Busy();
RS=0;
RW=0;
E=1;
DataPort=Cmd;
DelayUs2x(5);
E=0;
DelayUs2x(5);
}
/*------------------------------------------------
写数据
------------------------------------------------*/
void Write_Data(unsigned char Data)
{
Check_Busy();
RS=1;
RW=0;
E=1;
DataPort=Data;
DelayUs2x(5);
E=0;
DelayUs2x(5);
}
/*------------------------------------------------
液晶屏初始化
------------------------------------------------*/
void Init_ST7920()
{
DelayMs(40); //大于40MS的延时程序
PSB=1; //设置为8BIT并口工作模式
DelayMs(1); //延时
RES=0; //复位
DelayMs(1); //延时
RES=1; //复位置高
DelayMs(10);
Write_Cmd(0x30); //选择基本指令集
DelayUs2x(50); //延时大于100us
Write_Cmd(0x30); //选择8bit数据流
DelayUs2x(20); //延时大于37us
Write_Cmd(0x0c); //开显示(无游标、不反白)
DelayUs2x(50); //延时大于100us
Write_Cmd(0x01); //清除显示,并且设定地址指针为00H
DelayMs(15); //延时大于10ms
Write_Cmd(0x06); //指定在资料的读取及写入时,设定游标的移动方向及指定显示的移位,光标从右向左加1位移动
DelayUs2x(50); //延时大于100us
}
/*------------------------------------------------
显示字符串
x:横坐标值,范围0~8
y:纵坐标值,范围1~4
------------------------------------------------*/
void LCD_PutString(unsigned char x,unsigned char y,unsigned char *s)
{
switch(y)
{
case 1: Write_Cmd(0x80+x);break;
case 2: Write_Cmd(0x90+x);break;
case 3: Write_Cmd(0x88+x);break;
case 4: Write_Cmd(0x98+x);break;
default:break;
}
while(*s>0)
{
Write_Data(*s);
s++;
DelayUs2x(50);
}
}
/*------------------------------------------------
清屏
------------------------------------------------*/
void ClrScreen()
{
Write_Cmd(0x01);
DelayMs(15);
}
/*------------------------------------------------
延时函数
------------------------------------------------*/
void delay(uchar z)
{
uchar x;
for(;z>0;z--)
for(x=22;x>0;x--);
}
unsigned long ReadCount(void)
{
unsigned long Count; unsigned char i;
ADSK=0; //使能AD(PD_SCK 置低)
Count=0;
while(ADDO); //AD转换未结束则等待,否则开始读取
for (i=0;i<24;i++)
{
ADSK=1; //PD_SCK 置 高 ( 发 送 脉 冲 )
Count=Count<<1; //下降沿来时变量Count左移一位,右侧补零
ADSK=0; //PD_SCK 置低
if(ADDO) Count++;
}
ADSK=1;
Count=Count^0x800000;//第25个脉冲下降沿来时,转换数据
ADSK=0;
return(Count);
}
///////////////////////////////////////////////////////////////// //////////////////////
/*------------------------------------------------
按键扫描函数,返回扫描键值
------------------------------------------------*/
unsigned char KeyScan(void) //键盘扫描函数,使用行列反转扫描法
{
unsigned char cord_h,cord_l;//行列值中间变量
KeyPort=0x0f; //行线输出全为0
cord_h=KeyPort&0x0f; //读入列线值
if(cord_h!=0x0f) //先检测有无按键按下
{
DelayMs(10); //去抖
if((KeyPort&0x0f)!=0x0f)
{
cord_h=KeyPort&0x0f; //读入列线值
KeyPort=cord_h|0xf0; //输出当前列线值
cord_l=KeyPort&0xf0; //读入行线值
while((KeyPort&0xf0)!=0xf0);//等待松开并输出
return(cord_h+cord_l);//键盘最后组合码值
}
}return(0xff); //返回该值
}
/*------------------------------------------------
按键值处理函数,返回扫键值
可以根据需要改变返回值
| 1 | 2 | 3 | + |
| 4 | 5 | 6 | - |
| 7 | 8 | 9 | * |
| 0 | . | = | / |
------------------------------------------------*/
unsigned char KeyPro(void)
{
switch(KeyScan())
{
case 0x77:return 1 ;break;//1
case 0x7b:return 2 ;break;//2
case 0x7d:return 3 ;break;//3
case 0xb7:return 4 ;break;//4
case 0xbb:return 5 ;break;//5
case 0xbd:return 6 ;break;//6
case 0xd7:return 7 ;break;//7
case 0xdb:return 8 ;break;//8
case 0xdd:return 9 ;break;//9
case 0xe7:return 10 ;break;//*
case 0x7e:return 11;break;//A 设置单价
case 0xbe:return 12 ;break;//B 去皮
case 0xde:return 13 ;break;//C 附加功能
case 0xee:return 14 ;break;//D 重置
case 0xed:return 15 ;break;//#
case 0xeb:return 16 ;break;//0
default:return 0;break;
}
}
/*------------------------------------------------
主程序
------------------------------------------------*/
main()
{
int priceV;
char v=0;
unsigned long weight ;
unsigned long heavy ;
float heavy1 ;
float poi;
int d1,d2;
ClrScreen();
Init_ST7920(); //初始化
heavy= ReadCount(); DelayMs(100);
heavy= ReadCount(); DelayMs(100);
heavy= ReadCount(); DelayMs(100);
while (1)
{
for( v=0;v<6;v++)
{ weight += ReadCount(); }
weight =weight/7;
heavy1= weight-heavy ;
heavy1= (float)heavy1/1834.5;
DelayMs(150); DelayMs(150);
if(heavy1>10000)heavy1=0;
d1 = weight / 1000; d2 = weight % 1000;
num=KeyPro();
poi=priceV*heavy1*10;
switch(num)
{
case 1: priceV*=10; priceV+=1; break; // 1
case 2: priceV*=10; priceV+=2; break; // 2
case 3: priceV*=10; priceV+=3; break; // 3
case 4: priceV*=10; priceV+=4; break; // 4
case 5: priceV*=10; priceV+=5; break; // 5
case 6: priceV*=10; priceV+=6; break; // 6
case 7: priceV*=10; priceV+=7; break; // 7
case 8: priceV*=10; priceV+=8; break; // 8
case 9: priceV*=10; priceV+=9; break; // 9
case 16: priceV*=10; break;
case 15: priceV=0; break; // 0
case 11: heavy= ReadCount(); break;
case 12: i+=poi; break;
case 13: i=0; break;
}
sprintf(temp,"重量:%5.2f g " ,heavy1 );
LCD_PutString(0,1, temp);
sprintf(lol,"单价:%4d 元/g ",priceV);
LCD_PutString(0,2, lol);
sprintf(lol,"总价:%4.1f 元/g ",poi/10);
LCD_PutString(0,3, lol);
// sprintf(lol,"共计:%4.1f 元/g ",i/10);
// LCD_PutString(0,4, lol);
sprintf(temp," %4d%-d ",d1,d2);
LCD_PutString(0,4, temp);
DelayMs(200);
if(heavy1>503)
{
ClrScreen();
sprintf(lol,"警告警告警告警告");
LCD_PutString(0,1, lol);
sprintf(lol,"警告警告警告警告");
LCD_PutString(0,2, lol);
sprintf(lol,"警告警告警告警告");
LCD_PutString(0,3, lol);
sprintf(lol,"警告警告警告警告");
LCD_PutString(0,4, lol);
DelayMs(200);
}
}
}
现在不会外接12864
|