标签:
1 /* ****************************************************
2 程序参考地址
3 http://blog.chinaunix.net/uid-21658993-id-1819849.html
4 图片显示
5 http://www.51hei.com/mcu/4161.html
6 ********************************************************/
7 #ifndef _12864_H_
8 #define _12864_H_
9 #define LCD_DATA P0
10 sbit RS = P2^4; //并行的指令/数据选择信号: 1数据, 0命令
11 sbit RW = P2^5; //并行读写选择信号:1读, 0写
12 sbit E = P2^6; //并行使能端:1有效
13 sbit PSB = P2^1; //并/串接口选择:1并,0串
14 sbit RET = P2^3; //复位:0有效
15
16 bit checkBusy()
17 { bit busy;
18 RS = 0;
19 RW = 1;
20 E = 1;
21 delayUs();
22 busy = (bit)(LCD_DATA&0x80);
23 E = 0;
24 return busy;
25 }
26 void wait()
27 {
28 while(checkBusy());
29 }
30 void writeCmd(uchar cmd)
31 {
32 wait();
33 RS = 0;
34 RW = 0;
35 E = 0;
36 delayUs();
37 LCD_DATA = cmd;
38 delayUs();
39 E = 1;
40 delayUs();
41 E = 0;
42 }
43 void writeData(uchar dat)
44 {
45 wait();
46 RS = 1;
47 RW = 0;
48 E = 0;
49 delayUs();
50 LCD_DATA = dat;
51 delayUs();
52 E = 1;
53 delayUs();
54 E = 0;
55 }
56
57 void setPosition(uchar x, uchar y) //4*8
58 { uchar p;
59 switch(x%4)
60 {
61 case 0: p = 0x80; break; //第0行
62 case 1: p = 0x90; break; //第1行
63 case 2: p = 0x88; break; //第2行
64 case 3: p = 0x98; break; //第3行
65 }
66 p += y;
67 writeCmd(p);
68 }
69 void lcd_mesg(uchar * str)
70 { uchar n = 0;
71 while(str[n] != ‘\0‘)
72 {
73 writeData(str[n++]);
74 }
75 }
76 void lcd_draw(unsigned char code *pic)
77 {
78 unsigned i,j,k;
79 writeCmd(0x34);//扩充指令集
80 for(i=0;i<2;i++)//上半屏和下半屏
81 {
82 for(j=0;j<32;j++)//上下半屏各32行
83 {
84 writeCmd(0x80+j);//写行地址(y地址)
85 if(i==0)
86 {
87 writeCmd(0x80);//写列地址(x地址),上半屏列地址为0x80,下半屏列地址为0x88
88 }
89 else
90 {
91 writeCmd(0x88);
92 }
93 for(k=0;k<16;k++)//写入列数据
94 {
95 writeData(*pic++);
96 }
97 }
98 }
99 writeCmd(0x36);//显示图形
100 writeCmd(0x30);//基本指令集
101 }
102 void init_lcd()
103 {
104 PSB = 1; //并口方式
105 writeCmd(0x30); //基本指令, 扩充指令为34H
106 delayMs(10);
107 writeCmd(0x0c); //显示开, 关光标
108 delayMs(10);
109 writeCmd(0x01); //清屏
110 delayMs(10);
111 }
112
113 #endif
#ifndef _24C02_H_
#define _24C02_H_
uchar flag_lock; //键盘锁定标识,1有效
uchar userpsw[6];
uchar adminpsw[6];
/*24C02读写驱程序*/
sbit scl=P1^1;
sbit sda=P1^2;
sbit wp=P1^0; //写保护
//应答函数:在SCL保持高电平期间,拉低SDA,且保持4us以上,再拉高
void iic_ack()
{
scl=0; //默认初值为0
scl=1; //SCL保持高电平
delay_5us();
sda=1;
delay_5us();
sda=0;
delay_5us();
scl=0; //SCL结束保持高
sda=1; //SDA返回原值
}
void iic_start() //开始信号,上升沿
{
sda=1; //发送起始条件的数据信号
scl=1; //发送起始条件的时钟信号
delay_5us();
sda=0; //发送起始信号
delay_5us();
scl=0; //钳住IIC总线,准备发送或接收数据
delay_5us();
}
void iic_stop() //结束信号,下降沿
{
sda=0; //发送结束条件的数据信号
scl=1; //发送结束条件的时钟信号
delay_5us();
sda=1; //发送结束信号
delay_5us();
}
void writex(unsigned char x) //写一个字节
{
unsigned char i;
for(i=0;i<8;i++) //循环8次,由高到低赋给SDA
{
scl=0; //允许更改SDA
delay_5us(); //存在边沿时间,需等5us
sda=x&0x80; //SDA = 数据和10000000按位与; 串口SDA只送最高位
x=x<<1;
delay_5us();
scl=1;
delay_5us();
scl=0;
}
}
unsigned char readx() //读一个字节
{
unsigned char i,value;
for(i=0;i<8;i++) //8次读取1个字节
{
scl=0;
delay_5us();
scl=1; //保持着SDA的值,以便读出从机数据
delay_5us();
if(sda==1)
{
value=(value<<1)|1;
}
if(sda==0)
{
value=(value<<1)|0;
}
delay_5us();
}
return value;
}
//向24C02的地址address中写入一个字节的数据info
void write_24c02(unsigned char address,unsigned char info)
{
iic_start();
writex(0xae); //24c02芯片地址为111,写方向位0:1010 1110
iic_ack();
writex(address);
iic_ack();
writex(info);
iic_ack();
iic_stop();
}
//从24C02的地址address中读取一个字节的数据
unsigned char read_24c02(unsigned char address)
{
unsigned char value;
iic_start();
writex(0xae);
iic_ack();
writex(address);
iic_ack();
iic_start();
writex(0xaf); //24c02芯片地址为111,读方向位1:1010 1111
iic_ack();
value=readx();
iic_stop();
return(value);
}
void initset_read()
{
uchar tmp;
flag_lock=read_24c02(20); //读出键盘锁定标识并显示,地址20,出厂状态为0
delay_ms(50);
for(tmp=0;tmp<6;tmp++)
{
adminpsw[tmp]=read_24c02(10+tmp);
}
delay_ms(50);
for(tmp=0;tmp<6;tmp++)
{
userpsw[tmp]=read_24c02(tmp);
}
delay_ms(50);
}
void init_24c02() //总线初始化,拉高释放总线,并读出错误计数和密码
{
wp=1;
scl=1;
delay_5us();
sda=1;
delay_5us();
initset_read(); //将外部存储器中的密码读入缓存区
}
#endif
/* ****************************************************
程序参考地址
http://www.51hei.com/mcu/1730.html
********************************************************/
#ifndef _DS1302_H_
#define _DS1302_H_
sbit CLK=P3^6; //DS1302引脚定义
sbit IO=P3^4;
sbit CE=P3^5; //RST
sbit ACC0=ACC^0;
sbit ACC7=ACC^7;
extern uchar timer_cnt;
void Input_1byte(uchar TD) //DS1302输入一字节数据
{
uchar i;
ACC=TD;
for(i=8;i>0;i--)
{
IO=ACC0;
CLK=1;
CLK=0;
ACC=ACC>>1;
}
}
uchar Output_1byte(void) //DS1302输出一字节数据
{
uchar i;
for(i=8;i>0;i--)
{
ACC=ACC>>1;
ACC7=IO;
CLK=1;
CLK=0;
}
return(ACC);
}
void Write_DS1302(uchar add,uchar dat)//向DS1302写
{
CE=0;
CLK=0;
CE=1;
Input_1byte(add);
Input_1byte(dat);
CE=0;
}
uchar Read_DS1302(uchar add) //从DS1302读
{
uchar inf; //信息临时存储变量
CE=0;
CLK=0;
CE=1;
Input_1byte(add);
inf=Output_1byte();
CE=0;
return(inf);
}
/**********************DS1302初始化*****************************/
void init_1302()
{
if(Read_DS1302(0xd1)==0x55) //判断内存单元的内容,是否进行初始化
return;
else
{
Write_DS1302(0x8e,0x00); //关闭写保护
Write_DS1302(0x90,0x00); //电池充电设置
Write_DS1302(0x80,0x00); //秒
Write_DS1302(0x82,0x51); //分
Write_DS1302(0x84,0x17); //时
Write_DS1302(0x86,0x17); //日
Write_DS1302(0x88,0x04); //月
Write_DS1302(0x8c,0x16); //年
Write_DS1302(0xd0,0x55); //写RAM
Write_DS1302(0x8e,0x80); //打开写保护
}
}
/*********************************************************
* DS1302显示 *
**********************************************************/
void disp_ds1302()
{
uchar min,min1,min2;
uchar hour,hour1,hour2;
uchar date,date1,date2;
uchar mon,mon1,mon2;
uchar year,year1,year2;
//******读出1302的日期******/
min=Read_DS1302(0x83); //读分:min1=十位,min2=个位
min2=min&0x0f;
min1=min>>4;
hour=Read_DS1302(0x85); //读时:hour1=十位,hour2=个位
hour2=hour&0x0f;
hour1=hour>>4;
date=Read_DS1302(0x87); //读日期:date1=十位,date2=个位
date2=date&0x0f;
date1=date>>4;
mon=Read_DS1302(0x89); //读月份:mon1=十位,mon2=个位
mon2=mon&0x0f;
mon1=mon>>4;
year=Read_DS1302(0x8d); //读年份:year1=十位,year2=个位
year2=year&0x0f;
year1=year>>4;
//******显示1302的日期******/
setPosition(0,0);
writeData(2+0x30);
writeData(0+0x30);
writeData(year1+0x30); //年
writeData(year2+0x30);
writeData(‘-‘); //-
writeData(mon1+0x30); //月
writeData(mon2+0x30);
writeData(‘-‘); //-
writeData(date1+0x30); //日
writeData(date2+0x30);
writeData(‘ ‘); //空格
writeData(hour1+0x30); //时
writeData(hour2+0x30);
if(timer_cnt<18) writeData(‘:‘);
else writeData(‘ ‘);
writeData(min1+0x30); //分
writeData(min2+0x30);
}
#endif
#ifndef _KEYSCAN_H_
#define _KEYSCAN_H_
#define keyport P3
uchar key=0; //按键值
/*------------------------------------------------
按键扫描函数,返回扫描键值
------------------------------------------------*/
unsigned char key_scan(void)//键盘扫描函数,使用行列反转扫描法
{
uchar cord_h,cord_l; //行列值中间变量
keyport=0xf0; //行线输出全为0,P3=1111 0000
cord_h=keyport&0xf0; //读入列线值
if(cord_h!=0xf0) //有键按下
{
delay_ms(5); //去抖
if(cord_h!=0xf0)
{
cord_h=keyport&0xf0; //读入列线值
keyport=cord_h|0x0f; //输出当前列线值
delay_ms(5);
cord_l=keyport&0x0f; //读入行线值
while((keyport&0x0f)!=0x0f);//等待松开并输出
return(cord_h+cord_l); //键盘最后组合码值
}
}
return(0xff); //返回"无键按下",键盘不起作用
}
/*------------------------------------------------
键值处理函数,返回扫键值
------------------------------------------------*/
unsigned char key_value(void) //按下相应的键显示相对应的码值
{
switch(key_scan())
{
case 0xee:return 0;break; //0 1110 1110
case 0xde:return 1;break; //1
case 0xbe:return 2;break; //2
case 0x7e:return 3;break; //3
case 0xed:return 4;break; //4
case 0xdd:return 5;break; //5
case 0xbd:return 6;break; //6
case 0x7d:return 7;break; //7
case 0xeb:return 8;break; //8
case 0xdb:return 9;break; //9
case 0xbb:return 10;break; //a * 键
case 0x7b:return 11;break; //b # 键
case 0xe7:return 12;break; //c 管理/退出键
case 0xd7:return 13;break; //d 删除键
case 0xb7:return 14;break; //e 清空键
case 0x77:return 15;break; //f 确认键
default:return 0xff;break;
}
}
#endif
标签:
原文地址:http://www.cnblogs.com/Afterwork/p/5899344.html