📄
字号:
#include <iom16v.h>
#include <macros.h>
#include <eeprom.h>
#pragma interrupt_handler received:18
#pragma interrupt_handler int_1:3
typedef unsigned char uchar;
struct object
{
char class;
unsigned char PRI;
unsigned int number;
};
struct object operation[10]={{'a',1,0,},
{'b',2,0,},
{'c',3,0,},
{'d',4,0,},
{'e',5,0,},
{'f',6,0,},
{'g',7,0,},
{'h',8,0,},
{'i',9,0,},
{'j',10,0,}
};
struct object waiting_numbers[100]={{0,0,0}};
struct object recall={0,0,0};
unsigned char control[10]={1,1,1,1,0,0,0,0,0,0};
unsigned char password[10]={1,2,3,4,5,6,10,10,10,10};
unsigned char PASSWORD[10]={10,10,10,10,10,10,10,10,10,10};
unsigned char new_password[10]={10,10,10,10,10,10,10,10,10,10};
unsigned char data_change[]=
{
0x57,0x41,0x49,0x54,0x49,0x4e,0x47,0x20,0x53,0x55,0x4d,
0x3a,0x20,0x20,0x20,0x20, //WAITING SUM:
0x43,0x55,0x52,0x52,0x45,0x4e,0x54,0x20,0x4e,0x55,0x4d,
0x3a,0x20,0x20,0x20,0x20 //CURRENT NUM:
};
unsigned char check = 0; //检查是否进入了 "控制面板" (1是,0否);
unsigned char a = 0,A = 0; //检查从键盘输入了几个数字
unsigned char keynum[2]={0}; //用来整数化输入的数字
unsigned int restsum = 0; //该操作器剩下排队的人的总数
unsigned char option = 0; //功能判别键
unsigned char address = 5; //该操作器的地址
//-------------------函数声明部分---------------------
void send(struct object A,unsigned char ADDRESS); //通信时信息发送程序
void received(void); //通信时信息接收程序
void LCD_data(unsigned int datas,unsigned int total);//排队人数和号码的显示
void set(void); //功能设定
void pack_up(struct object *p); //数组整形
void sort_number(struct object *p);//数组排序
void delay(void); //延时小程序
void enable(void); //液晶显示的使能小程序
void enshow(void); //液晶显示的命令小程序
void dealkey(unsigned char k); //键盘输入的判别和处理程序
void LCD_display(unsigned char show,unsigned char n,unsigned char *p);
void buzzer(unsigned char n);//蜂鸣提醒小程序
//----------------------------------------------------
//------- 数组从 "小" 到 "大" 的排序 -------
void sort_number(struct object *p)
{
unsigned char a,b;
struct object k;
for(a=0;p[a].number!=0;a++)
for(b=a+1;p[b].number!=0;b++)
if(p[b].number<= p[a].number)
{
k=p[a];
p[a]=p[b];
p[b]=k;
}
else continue;
}
//-----------------------------------------
//----- 数组整理 -- 删除已呼叫的号码 -----
void pack_up(struct object *p)
{
unsigned char a;
for(a=0;p[a].number!=0;a++)
p[a]=p[a+1];
}
//----------------------------------------
void ERROR()
{;}
//----------------- TWI总线 数据发送 程序 -----------------
void send(struct object A,unsigned char ADDRESS)
{
unsigned char START = 0x08;
unsigned char RE_START = 0x10;
unsigned char MT_SLA_ACK = 0X18;
unsigned char MT_SLA_NACK = 0x20;
unsigned char MT_DATA_ACK = 0x28;
unsigned char BROADCAST_W = 0x00;
unsigned char arbitrate_failed = 0x38;
restart:
TWCR = (1<<TWINT)|(1<<TWSTA)|(1<<TWEN); //开始
while (!(TWCR & (1<<TWINT)))
;
if ((TWSR & 0xF8) != START)
if((TWSR & 0xF8) == arbitrate_failed) //总裁失败
{delay();
goto restart;}
ERROR();
TWDR = BROADCAST_W;
TWCR = (1<<TWINT) | (1<<TWEN);
while (!(TWCR & (1<<TWINT)))
;
if ( (TWSR & 0xF8) != MT_SLA_ACK )
if( (TWSR & 0xF8) == arbitrate_failed ) //总裁失败
{delay();
goto restart;}
else if( (TWSR & 0xF8) == MT_SLA_NACK)
ERROR();
TWDR = A.class; //发送class
TWCR = (1<<TWINT) | (1<<TWEN);
while (!(TWCR & (1<<TWINT)))
;
if ((TWSR & 0xF8) != MT_DATA_ACK)
ERROR();
TWDR = A.PRI; //发送优先级
TWCR = (1<<TWINT) | (1<<TWEN);
while (!(TWCR & (1<<TWINT)))
;
if ((TWSR & 0xF8) != MT_DATA_ACK)
ERROR();
TWDR = (unsigned char)(A.number/100); //发送高字节
TWCR = (1<<TWINT) | (1<<TWEN);
while (!(TWCR & (1<<TWINT)))
;
if ((TWSR & 0xF8) != MT_DATA_ACK)
ERROR();
TWDR = (unsigned char)(A.number%100); //发送低字节
TWCR = (1<<TWINT) | (1<<TWEN);
while (!(TWCR & (1<<TWINT)))
;
if ((TWSR & 0xF8) != MT_DATA_ACK)
ERROR();
TWDR = ADDRESS; //发送地址
TWCR = (1<<TWINT) | (1<<TWEN);
while (!(TWCR & (1<<TWINT)))
;
if ((TWSR & 0xF8) != MT_DATA_ACK)
ERROR();
TWCR = (1<<TWINT)|(1<<TWEN)|(1<<TWSTO);
}
//-------------------------------------------------------
//----- 接收来自 "发号机" 或 "其他操作器" 数据的数据处理小程序 -----
void deal_control(uchar n,uchar address,uchar DATA_H,
uchar DATA_L,uchar PRI,uchar class)
{
if(control[n]==1)
{
if(address == 0)
{
waiting_numbers[restsum].number = DATA_H*100+DATA_L;
waiting_numbers[restsum].class = class;
waiting_numbers[restsum].PRI = PRI;
restsum++;
sort_number(waiting_numbers);
}
else
{
unsigned int k;
unsigned char w=0;
k=DATA_H*100+DATA_L;
while(waiting_numbers[w].number!=k)
w++;
while(waiting_numbers[w].number!=0)
waiting_numbers[w]=waiting_numbers[++w];
restsum--;
}
}
}
void deal_reach(uchar class,uchar address,
uchar DATA_H,uchar DATA_L,uchar PRI)
{
switch (class)
{
case 'a' : deal_control(0,address,DATA_H,DATA_L,PRI,class);
break;
case 'b' : deal_control(1,address,DATA_H,DATA_L,PRI,class);
break;
case 'c' : deal_control(2,address,DATA_H,DATA_L,PRI,class);
break;
case 'd' : deal_control(3,address,DATA_H,DATA_L,PRI,class);
break;
case 'e' : deal_control(4,address,DATA_H,DATA_L,PRI,class);
break;
case 'f' : deal_control(5,address,DATA_H,DATA_L,PRI,class);
break;
case 'g' : deal_control(6,address,DATA_H,DATA_L,PRI,class);
break;
case 'h' : deal_control(7,address,DATA_H,DATA_L,PRI,class);
break;
case 'i' : deal_control(8,address,DATA_H,DATA_L,PRI,class);
break;
case 'j' : deal_control(9,address,DATA_H,DATA_L,PRI,class);
break;
}
}
//--------------------------------------------------------
//-----------蜂鸣提醒小程序-------------
void buzzer(unsigned char n)
{
unsigned char t;
unsigned int T;
DDRD|=0x02;
for(t=0;t<=n;t++)
{
PORTD&=0xfd;
for(T=0;T<=50000;T++)
;
PORTD|=0x02;
for(T=0;T<=10000;T++)
;
}
}
//--------------------------------------
//-------------- TWI总线 数据接收 程序----------------
void received()
{
unsigned char broadcast = 0x70;
unsigned char received = 0x90;
unsigned char stop = 0xa0;
unsigned char DATA_H,DATA_L,address,class,PRI;
TWCR = (1<<TWINT)|(1<<TWEA)|(1<<TWEN); //开始接收信息
while (!(TWCR & (1<<TWINT)))
;
if((TWSR & 0xf8) != received)
ERROR();
class = TWDR; //接收到种类
TWCR = (1<<TWINT)|(1<<TWEA)|(1<<TWEN);
while (!(TWCR & (1<<TWINT)))
;
if((TWSR & 0xf8) != received)
ERROR();
PRI = TWDR; //接收到优先级
TWCR = (1<<TWINT)|(1<<TWEA)|(1<<TWEN);
while (!(TWCR & (1<<TWINT)))
;
if((TWSR & 0xf8) != received)
ERROR();
DATA_H = TWDR; //接收到高字节
TWCR = (1<<TWINT)|(1<<TWEA)|(1<<TWEN);
while (!(TWCR & (1<<TWINT)))
;
if((TWSR & 0xf8) != received)
ERROR();
DATA_L = TWDR; //接收到低字节
TWCR = (1<<TWINT)|(1<<TWEA)|(1<<TWEN);
while (!(TWCR & (1<<TWINT)))
;
if((TWSR & 0xf8) != received)
ERROR();
address = TWDR; //接收到地址
TWCR = (1<<TWINT)|(1<<TWEA)|(1<<TWEN);
while (!(TWCR & (1<<TWINT)))
;
if((TWSR & 0xf8) != stop) //stop
ERROR();
TWCR = (1<<TWINT)|(1<<TWEA)|(1<<TWEN);
deal_reach(class,address,DATA_H,DATA_L,PRI);
if(check==0)
LCD_data(waiting_numbers[0].number,restsum);
if(restsum==1)
buzzer(6);
}
//-----------------------------------------------------
//显显显显显显显显显显显显显显显显显显显显显显显显显显显显显显显显
// LCD 数 据 显 示 区
//示示示示示示示示示示示示示示示示示示示示示示示示示示示示示示示示
//------延时函数------
void delay()
{
unsigned char a,b=0;
for(a=0;a<30;a++)
for(b=0;b<100;b++)
;
}
//--------------------
//---使液晶执行指令----
void enable()
{
PORTD &= 0xdf; //选择指令寄存器
PORTD &= 0xbf; //执行写操作
PORTD &= 0x7f; //使能LCD执行指令
delay();
PORTD |= 0x80;
}
//--------------------
//----使液晶显示数据----
void enshow()
{
PORTD |= 0x20; //选择数据寄存器
PORTD &= 0xbf; //执行写操作
PORTD &= 0x7f; //使能LCD执行指令
delay();
PORTD |= 0x80;
}
//----------------------
//---------------- 公用的 "LCD 数据显示"调用程序 ------------------
void LCD_display(unsigned char show,unsigned char n,unsigned char *p)
{
unsigned char a;
PORTB = 0x01;//清除屏幕
enable();
PORTB = 0x38;//8位点阵,双行显示
enable();
PORTB = show;//开显示,显示光标,闪烁
enable();
PORTB = 0x06;//移动光标
enable();
PORTB = 0x80;//显示起始位置
enable();
for(a=0;a<=n;a++)
if(a<=15)
{
PORTB = p[a];
enshow();
}
else if(a==16)
{
PORTB = 0x02;//光标复位一下
enable();
PORTB = 0xc0;
enable();
PORTB = p[a];
enshow();
}
else
{
PORTB = p[a];
enshow();
}
}
//-----------------------------------------------------------------
//-----------------LCD主页和数据显示-------------------
void LCD_data(unsigned int datas,unsigned int total)
{
unsigned char keyboard[]={0x30,0x31,0x32,0x33,0x34,0x35,
0x36,0x37,0x38,0x39,0xef};
unsigned char data_H = (unsigned char)(datas/100);
unsigned char data_L = (unsigned char)(datas%100);
unsigned char n;
data_change[12] = keyboard[total/1000];
data_change[13] = keyboard[(total%1000)/100];
data_change[14] = keyboard[(total%100)/10];
data_change[15] = keyboard[total%10];
data_change[28] = keyboard[data_H/10];
data_change[29] = keyboard[data_H%10];
data_change[30] = keyboard[data_L/10];
data_change[31] = keyboard[data_L%10];
//--------------------------
for(n=12;n<=14;n++) //显示: WAITING SUM : XXXX
{ // CURRENT NUM : XXXX
if(data_change[n] == 0x30) //--------------------------
data_change[n] = 0x20;
else break;
}
for(n=28;n<=30;n++)
{
if(data_change[n] == 0x30)
data_change[n] = 0x20;
else break;
}
LCD_display(0x0c,31,data_change);
}
//--------------------------------------------------
//----在控制面板中显示 "业务开或关" 的小程序----
void show_ON_or_OFF(unsigned char op_number)
{
unsigned char t;
PORTB = 0x02;//光标复位
enable();
PORTB = 0xc4;//显示起始位置
enable();
PORTB = op_number;//显示该业务的编号,(0-9)之间;
enshow();
if(control[option-2]==1) //显示 ON
{
PORTB = 0x02; //光标复位
enable();
PORTB = 0xcd; //显示的起始位置
enable();
PORTB = 0x20;
enshow();
PORTB = 0x4f;
enshow();
PORTB = 0x4e;
enshow();
}
else //显示OFF
{
PORTB = 0x02; //光标复位
enable();
PORTB = 0xcd; //显示的起始位置
enable();
PORTB = 0x4f;
enshow();
PORTB = 0x46;
enshow();
PORTB = 0x46;
enshow();
}
for(t=0;t<=15;t++) //延时一段时间,确保操作的稳定和可靠
delay();
}
//----------------------------------------
//-------- "要求重新输入密码的对话框" LCD显示程序 ----------
void pass_again()
{
unsigned char passagain[]=
{
0x70,0x61,0x73,0x73,0x77,0x6f,0x72,0x64,0x73,0x20, //passwords:
0x61,0x67,0x61,0x69,0x6e,0x20, //again
0x3a //:
};
LCD_display(0x0f,16,passagain);
}
//----------------------------------------------------------
//---------- 提示"数据已成功被保存至EEPROM" ----------
void save_completed()
{
unsigned char ok[]=
{
0x20,0x20,0x4f,0x20,0x4b,0x20,0x21,0x20,0x20,0x20, //O K !
0x73,0x61,0x76,0x65,0x64,0x20, //saved
0x63,0x6f,0x6d,0x70,0x6c,0x65,0x74,0x65,0x64,0x20,//completed
0x21,0x21,0x21
};
LCD_display(0x0c,28,ok);
for(a=0;a<=254;a++)
delay();
}
//-------------------------------------------------
//----------- 提示"数据没有被保存到EEPROM" ----------
void failed()
{
unsigned char failed[]=
{
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -