📄 elevator.c
字号:
#include<avr/io.h>
#include<avr/interrupt.h>
#include<avr/signal.h>
#include<avr/pgmspace.h>
#include"success.h"
#define PRG_RDB(addr) pgm_read_byte(addr)
#define PPI_0_PA (unsigned char *) 0x5000
#define PPI_0_PB (unsigned char *) 0x5001
#define PPI_0_PC (unsigned char *) 0x5002
#define PPI_0_CT (unsigned char *) 0x5003
#define PPI_1_PA (unsigned char *) 0x6000
#define PPI_1_PB (unsigned char *) 0x6001
#define PPI_1_PC (unsigned char *) 0x6002
#define PPI_1_CT (unsigned char *) 0x6003
#define TLCD_CTRL (unsigned char *)0x7000;
#define TLCD_DATA (unsigned char *)0x7001;
//=============================================================
// 功能描述:定义点阵字模
//=============================================================
unsigned char font_A[]={0x60,0xf0,0x60,0x60,0x60,0x60,0x60,0x60}; //指示箭头
unsigned char font_B[]={0x00,0x42,0xa5,0x00,0x00,0x24,0x18,0x00};
unsigned char font_number[9][8]={ {0x02,0x03,0x02,0x02,0x02,0x02,0x07,0x00},
{0x06,0x09,0x09,0x04,0x02,0x01,0x0f,0x00},
{0x06,0x09,0x08,0x06,0x08,0x09,0x06,0x00},
{0x04,0x02,0x05,0x05,0x0f,0x04,0x04,0x00},
{0x0f,0x01,0x07,0x09,0x08,0x09,0x06,0x00},
{0x06,0x09,0x01,0x07,0x09,0x09,0x06,0x00},
{0x0f,0x09,0x04,0x04,0x04,0x04,0x04,0x00},
{0x06,0x09,0x09,0x06,0x09,0x09,0x06,0x00},
{0x06,0x09,0x09,0x0e,0x08,0x09,0x06,0x00}}; //数字1-9
unsigned char all[8];
unsigned char all1[8];
unsigned char font_f[8];
unsigned char blank[]={0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00};
unsigned char font[8];
//=============================================================
// 功能描述:定义TEXT LCD的显示内容
//=============================================================
volatile const char string_data[]=" WELCOME! \rInput the number";
volatile const char string_data1[]="lift is running!";
volatile const char string_data2[]=" F have reached!\r GOODBYE! ";
//=============================================================
// 功能描述:定义步进电机的相序
//=============================================================
const unsigned char one_phase1[]={0x01,0x04,0x08,0x02}; //电机正转
const unsigned char one_phase2[]={0x02,0x08,0x04,0x01}; //电机倒转
//=============================================================
// 功能描述:各主要参数的设定
//=============================================================
unsigned int cnt; //语音
unsigned char *lcd_data,*lcd_control; //TEXT LCD
volatile unsigned char phase_pnt1=0,stepspeed=0xea,phase_pnt2=0,dir=0; //电机
unsigned char *line,*green,*red,*ppi_ctrl,*ppi_ctrl1,*ppi_pb,in; //点阵
unsigned char *key,*seg,bin,f=1; //键盘
unsigned char fnd[]={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x98,0xa7,0xb3,0x9d,0x96,0x87,0xff};//键盘
//=============================================================
// 功能描述:各主要函数的设定
//=============================================================
void initialize_text_lcd(void); //TEXT LCD初始化
void lcd_control_wait(void); //TEXT LCD控制字延时
void lcd_data_wait(void); //TEXT LCD显示值延时
void initialize_ppi(void); //键盘与点阵初始化
void initializemotor(void); //电机初始化
void matrix(unsigned char *matrix1); //点阵赋值与显示
void move (unsigned char *shift1,unsigned char i);
void display(unsigned char *green1,unsigned char *red1);
unsigned char key_scan(void); //键盘扫描与输出
void out_put(unsigned char in);
void go_step_1phase(void); //电机运转
void print_message(char *message);//TEXT LCD显示
void function(void); //清中断(电梯停转),TEXT LCD显示楼层已到,播放提示语音
void delay(int d1,int d2);
//=============================================================
// 语法格式: int main(void)
// 实现功能: 主函数
//=============================================================
int main(void)
{ unsigned char m,n,c=1,b=1,d=0;
MCUCR|=(1<<SRE); //设定控制字,访问外部存储器
DDRD=0Xf0; //将d口高四位设定成输出口
initialize_ppi(); //键盘与点阵初始化
initialize_text_lcd(); //TEXT LCD初始化
*seg=fnd[0];
print_message((char*)string_data); //TEXT LCD显示欢迎字幕
do{ delay(50,50);
in=key_scan(); //扫描键值
if(in!=0&&in!=0x88) //0X88设定为关门键
{out_put(in); //将键值转化为所对应的数字
if(bin>d) //如果当前所选楼层大于前一次所选楼层
{
initialize_text_lcd(); //TEXT LCD显示电梯正在运行
print_message((char*)string_data1);
initializemotor(); //初始化电机,电机开始正转
if(dir==1) f=f+2;
dir=0; d=bin; //dir为0时表示电梯向上运行,为1时表示向下,bin为所选楼层
for(n=0;n<(bin-c);n++)
{
matrix(font_A); //电梯上升期间,点阵显示相关内容
f++; b++;
if(f==bin) //电梯到达目标楼层
{function(); //电梯停转,TEXT LCD显示,播放语音
delay(100,100);
//扫描按键是否为关门键,否,则点阵变为静态显示,
// 是,则跳出此循环返回程序开头进行下一次楼层选择
do{in=key_scan();
if(in==0x88) break;
for(m=0;m<8;m++)
all1[m]=font_A[m]|font_number[f-1][m];
display(blank,all1);
}while(1);
}
} c=b;
}
if(bin<d) //如果当前所选楼层小与上次所选楼层
{initialize_text_lcd();
print_message((char*)string_data1);
initializemotor();
if(dir==0) f=f-2;
dir=1; d=bin;
for(n=0;n<(c-bin);n++)
{ matrix(font_A);
f--; b--;
if(f==(bin-2))
{function();
do{
in=key_scan();
if(in==0x88) break;
for(m=0;m<8;m++)
all1[m]=font_A[m]|font_number[f+1][7-m];
display(blank,all1);
}while(1);
}
} c=b;
}
if(bin==1) //如果所选楼层为1层
{dir=0;
initialize_text_lcd();
print_message((char*)string_data1);
initializemotor();
for(n=0;n<(c-bin);n++)
matrix(font_A);
function();
do{
in=key_scan();
if(in==0x88) break;
for(m=0;m<8;m++)
all1[m]=font_A[m]|font_number[0][m];
display(blank,all1);
}while(1);
f=1;c=1;b=1,d=1; //所有参数全部变为初始化状态
}
}display(font_B,font_B); //当按下关门键时,点阵进行相关显示
}while(1);
}
//=============================================================
// 语法格式: void function(void)
// 实现功能: 清中断(电机停转), TEXT LCD显示到达楼层,播放提醒语音
//=============================================================
void function(void)
{ cli();
initialize_text_lcd();
*lcd_data=bin+'0';
print_message((char*)string_data2);
for(cnt=0;cnt<1179;cnt++)
{*ppi_pb=PRG_RDB(&snd_data[cnt]);
delay(10,30);}
}
//=============================================================
// 语法格式: void delay(int d1,int d2)
// 实现功能: 进行延时
//=============================================================
void delay(int d1,int d2)
{int i,j;
for(i=0;i<d1;i++)
{for(j=0;j<d2;j++);
}
}
//=============================================================
// 语法格式: void initialize_ppi(void)
// 实现功能: 键盘与点阵的初始化
//=============================================================
void initialize_ppi(void)
{line=PPI_0_PA;
green=PPI_0_PB;
red=PPI_0_PC;
ppi_ctrl=PPI_0_CT;
ppi_ctrl1=PPI_1_CT;
seg=PPI_1_PA;
ppi_pb=PPI_1_PB;
key=PPI_1_PC;
*ppi_ctrl=0x80;
*ppi_ctrl1=0x80;
*key=0x00;
}
//=============================================================
// 功能模块: 点阵显示模块
// 实现功能: 实现点阵的静态与动态的显示
// 包含函数: void matrix(unsigned char *matrix1)
// void move(unsigned char *move1,unsigned char i)
// void display(unsigned char *green1,unsigned char *red1)
// void display(unsigned char *green1,unsigned char *red1)
//=============================================================
void matrix(unsigned char *matrix1)
{ unsigned char i=0;
for(i=0;i<8;i++)
{move(matrix1,i); display(all,blank);}
for(i=0;i<8;i++) font[i]=0;
}
void move(unsigned char *move1,unsigned char i)
{ unsigned char k,j,m;
k=0;
j=7-i;
do{ font[j]=move1[k];
if(dir==0)
{for(m=0;m<8;m++)
all[m]=font[m]|font_number[f][m];}
else
{for(m=0;m<8;m++)
all[m]=font[m]|font_number[f][7-m];}
j++;
k++;
} while(i--);
}
void display(unsigned char *green1,unsigned char *red1)
{unsigned char i=0,j=0;
for (j=0;j<15;j++)
{for (i=0;i<8;i++)
{ *green=green1[i];
*red=red1[i];
if(dir==0) *line=(0x01<<i);
else *line=(0x80>>i);
delay(100,70);
}
}
}
//=============================================================
// 功能模块: 键盘模块
// 实现功能: 实现键盘扫描与键值和所实现功能按键值得转化
// 包含函数: unsigned char key_scan(void) 使用的是线翻转法
// void out_put(unsigned char in)
//=============================================================
unsigned char key_scan(void)
{unsigned char save_low,save_high;
*ppi_ctrl1=0x81;
*seg=fnd[bin];
*key=0xf0;
delay(10,10);
save_low=*key&0x0f;
*ppi_ctrl1=0x80;
*seg=fnd[bin];
*key=0x00;
if(save_low)
{
*ppi_ctrl1=0x88;
*seg=fnd[bin];
*key=0x0f;
delay(10,10);
save_high=*key&0xf0;
*ppi_ctrl1=0x80;
*seg=fnd[bin];
*key=0x00;
if(!save_high)
return 0;
save_high|=save_low;
return save_high;
}
return 0;
}
void out_put(unsigned char in)
{unsigned char a=0;
switch(in){
case 0x11:a=0x01;
break;
case 0x21:a=0x02;
break;
case 0x41:a=0x03;
break;
case 0x81:a=0x0a;
break;
case 0x12:a=0x04;
break;
case 0x22:a=0x05;
break;
case 0x42:a=0x06;
break;
case 0x82:a=0x0b;
break;
case 0x14:a=0x07;
break;
case 0x24:a=0x08;
break;
case 0x44:a=0x09;
break;
case 0x84:a=0x0c;
break;
case 0x18:a=0x0d;
break;
case 0x28:a=0x00;
break;
case 0x48:a=0x0e;
break;
case 0x88:a=0x0f;
break;
default:
break;
}
bin=a;
*seg=fnd[bin];
}
//=============================================================
// 功能模块: 电机模块
// 实现功能: 实现电机的正转反转与加速减速
// 包含函数: void initializemotor(void) 电机初始化,电机开始运转
// SIGNAL(SIG_OVERFLOW0) 定义溢出中断0,用于控制电机运转
// void go_step_1phase(void) 控制电机正转与反转
// SIGNAL(SIG_INTERRUPT0) 外部中断0控制电机加速
// SIGNAL(SIG_INTERRUPT6) 外部中断6控制电机减速
//=============================================================
void initializemotor(void)
{EIMSK=0X41;
EICRA=0X02;
EICRB=0X20;
TCNT0=stepspeed;
TCCR0=0X07;
TIMSK=0X01;
sei();
}
SIGNAL(SIG_OVERFLOW0)
{ go_step_1phase();
TCNT0=stepspeed;}
void go_step_1phase(void)
{if(!dir)
{PORTD=(one_phase1[phase_pnt1++]<<4);phase_pnt1&=0x03;}
else
{PORTD=(one_phase2[phase_pnt2++]<<4);phase_pnt2&=0x03;}
}
SIGNAL(SIG_INTERRUPT0)
{
stepspeed=stepspeed+3;
}
SIGNAL(SIG_INTERRUPT6)
{
stepspeed=stepspeed-3;
}
//=============================================================
// 功能模块: TEXT LCD模块
// 实现功能: 实现TEXT LCD的显示
// 包含函数: void initialize_text_lcd(void) TEXT LCD初始化
// void print_message(char *message) TEXT LCD显示
// void lcd_control_wait(void)
// void lcd_data_wait(void)
//=============================================================
void initialize_text_lcd(void)
{lcd_control=TLCD_CTRL;
lcd_data=TLCD_DATA;
lcd_control_wait();
*lcd_control|=0x38;
lcd_control_wait();
*lcd_control|=0x02;
lcd_control_wait();
*lcd_control|=0x01;
lcd_control_wait();
*lcd_control|=0x06;
lcd_control_wait();
*lcd_control|=0x0c;
lcd_control_wait();
}
void print_message(char *message)
{unsigned char i;
for(i=0;;i++)
{if(message[i]=='\0') break;
else if(message[i]=='\r')
{*lcd_control=0xc0;
lcd_control_wait();
}
else{*lcd_data=message[i];
lcd_data_wait();
}
}
}
void lcd_control_wait(void)
{delay(40,35);}
void lcd_data_wait(void)
{delay(10,10);}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -