#include "config.h"
#define Self_Define_Isp_Download_Command 0x3d
#define Datecom P0
sfr IAP_CONSTR=0xe7;
sbit E=P2^7; //1602使能引脚
sbit RW=P2^6; //1602读写引脚
sbit RS=P2^5; //1602数据/命令选择引脚
uint8 Showtime[4];
uint8 Showtimedis[4];
uint8 Password[7];
char Keytemp[1];
uint8 addr=9;
uint8 code table[16]={0x3F,0x06,0x5B,0x4F,0x66,0x6D,0x7D,0x07,0x7F,0x6F,0x77,0x7C,0x39,0x5E,0x79,0x71};//数码管编码表管编码表
char code Passnumber[7]={2,1,2,2,0,9,'\0'};
uint8 OS_Q_MEM_SEL KeyValueBuf[8];
uint8 OS_Q_MEM_SEL Command1602Buf[8];
void main(void)
{
TMOD = (TMOD & 0XFF) | 0X21;
SM0=0;
SM1=1;
REN=1;
TH1=0xfd;
TL1=0xfd;
ES=1;
TR1=1;
TL0 = 0x00; //时钟节拍10ms
TH0 = 0xDC;
TR0 = 1;
ET0 = 1;
Lcd_Init(); //运行55ms
OSStart(); //运行1ms
}
void KeyInput(void) //扫描按键,正确按键后将按键信息加入消息队列KeyValueBuf供别的任务处理
{
uint8 temp;
OSQCreate(KeyValueBuf,8); //创建按键值消息队列,占用8字节
//OSWait(K_TMO,1);
while (1)
{
P1=0xf0;
OSWait(K_TMO,2); //等待P1口数据稳定
if(P1!= 0xf0)
{
OSWait(K_TMO,2); //延时20ms去抖
if(P1!=0xf0)
{
temp=Keyscan();
OSWait(K_TMO,2); //延时20ms去抖
if(temp==Keyscan())
{
while(temp==Keyscan()) ; //松手检测
OSQPost(KeyValueBuf,temp); //正确按键后发送按键消息
}
}
}
}
}
void KeyHandle(void) //根据按键消息队列信息实时处理
{ static uint8 i=0;
uint8 j;
OSQCreate(Command1602Buf,8); //建立1602命令消息队列
//OSWait(K_TMO,100);
while(1)
{
OSQPend(Keytemp,KeyValueBuf,0); //等待按键值消息队列有消息,读取
if((Keytemp[0])<=9&&(Keytemp[0])>=0)//0~9号键,即输入正确数字,1602向后写个“*”
{ Password[6]='\0';
Password[i++]=Keytemp[0];
//P2=Password[i-1];
OSQPost(Command1602Buf,WRITE_STAR); //根据按键值向命令1602消息队列发送实时处理命令
}
else if(Keytemp[0]==0x0a) //按下10号按键即向前删除一个“*”
{
Password[--i]=0;
//delay1();
OSQPost(Command1602Buf,DEL_STAR);
}
else if(Keytemp[0]==0x0b) //按下11号按键即删除全部“*”.问题就出在这。
{
for(j=0;j<6;j++)
Password[j]=0;
//delay1();
OSQPost(Command1602Buf,CLR_ALLSTAR);
}
else if(Keytemp[0]==0x0c) //按下12号确认输入显示“#”
{
OSQPost(Command1602Buf,ENTERPASS);
continue;
}
}
}
void Enter1602(void) //1602密码登陆界面处理
{
uint8 temp[1];
OSSemCreate(LCD1602_SEM,0);
Write_string(1,1," -SMALL RTOS- "); //1602初始化登陆界面大概要写250ms
OSWait(K_TMO,2);
Write_string(2,1,"Password:");
while(1)
{
OSQPend(temp,Command1602Buf,0);
switch (temp[0])
{
case(WRITE_STAR): //在1602上写下一个“*”号,密码为六位
if(addr<9&&addr>=15)
addr=9;
else
{addr+=1;Write_char(2,addr,'*');}break;//写一个字符大概30ms
case(DEL_STAR): //删除当前地址“*”
if(addr>9&&addr<16)
{
Write_char(2,addr,' ');
addr-=1;
}break;
case(CLR_ALLSTAR): //删除所有星号,问题就出在这了。只要按下这个键一会就出问题了
addr=9;
Write_string(2,10," ");
break;
case(ENTERPASS): //输入一个'#',即确定键
Write_char(2,16,'#');
if(!strcmp(Password,Passnumber))
{
Write_string(2,1," hello welcome ");
OSWait(K_TMO,OS_TICKS_PER_SEC )
}
else
{
Write_string(2,1," sorry error ");
OSWait(K_TMO,OS_TICKS_PER_SEC );
Write_string(2,1,"Password:");
}
break;
default:break;
}
//OSWait(K_TMO,50);
}
}
void delay1() //延时1毫秒
{
uint8 y;
for(y=100;y>0;y--);
}
void delay() //延时140US液晶屏时序需要
{
uint8 i,j;
for(i=0; i<=100; i++)
for(j=0; j<=20; j++)
;
}
void Write_Command(uint8 c) //写命令指令函数
{
//OS_ENTER_CRITICAL();
Datecom=c;
RS=0;
RW=0;
E=0; //这里写的时序很重要啊,时序不多很难正确写进去啊
delay();
E=1;
delay();
//OS_EXIT_CRITICAL();
}
void Write_Date(uint8 c) //写数据函数
{
//OS_ENTER_CRITICAL();
Datecom=c;
RW=0;
RS=1;
E=0;
delay();
E=1;
delay();
//OS_EXIT_CRITICAL();
}
void Write_char(uint8 hang,uint8 lie,uint8 c) //写字符型数据函数
{
//OS_ENTER_CRITICAL();
if(hang==1)Write_Command(0x80+lie-1);
if(hang==2)Write_Command(0xc0+lie-1);
Write_Date(c);
//delay1();
//OS_EXIT_CRITICAL();
}
void Write_string(uint8 hang,uint8 lie,uint8 *p) //写字符串函数
{
//OS_ENTER_CRITICAL();
if(hang==1)Write_Command(0x80+lie-1);
if(hang==2)Write_Command(0xc0+lie-1);
while(*p!='\0')
{
Write_Date(*(p++));
delay1();
}
//OS_EXIT_CRITICAL();
}
void Lcd_Init() //1602初始化
{
Write_Command(0x01); //清屏指令
Write_Command(0x38); //设置16*2显示,5*7点阵,8位数据接口
Write_Command(0x0c); //开显示,光标不显示,不显示光标
Write_Command(0x06); //当读写一个字符后地址指针光标都加一
}
uint8 Keyscan(void) //矩阵扫描函数,返回扫描到的键值
{
uint8 i,j,temp,Buff[4]={0xfe,0xfd,0xfb,0xf7};
OS_ENTER_CRITICAL();
for(j=0; j<4; j++)
{
P1 = Buff[j];
/*以下三个_nop_();作用为让 P1 口的状态稳定*/
delay();
temp = 0x10;
for(i=0; i<4; i++)
{
if(!(P1 & temp))
{
OS_EXIT_CRITICAL();
return (i+j*4);
}
temp <<= 1;
}
}
OS_EXIT_CRITICAL();
return 0xff;
}
void UART_Interrupt_Recieve(void) interrupt 4 //STC下载不断电串口程序
{
unsigned char k=0;
unsigned int a,b;
if(RI==1)
{
RI=0;
k=SBUF;
if(k==Self_Define_Isp_Download_Command)
{
for(a=1010;a>0;a--)
for(b=100;b>0;b--) ;
IAP_CONSTR=0x60;
}
}
else
{
TI=0;
}
}
这是我的程序,希望哪位大侠有空帮看看。 |