用51单片机+LCD12864屏编写的“ID卡号读/写器”
#include <reg52.h> //包含头文件#define uchar unsigned char //宏定义
#define uint unsigned int //宏定义
#define LCD_data P0 //数据口
sbit int0=P3^0; //串口读入
sbit gd = P1^3; //置P1^3端口为高/低电平的转换开关 ,即读/写转换开关
sbit LCD_RS = P1^0; //数据/地址寄存器选择输入 ,lcd为12864
sbit LCD_RW = P1^1; //液晶读/写控制
sbit LCD_EN = P1^2; //液晶使能控制
sbit LCD_gd = P1^3; //置P1^3端口为高/低电平的转换开关 ,即读/写转换开关
sbit LCD_PSB = P2^7; //串/并方式控制
sbit LCD_RST = P2^6; // lcd复位端
uint flag ,i; //串口中断标志位
char a[9]; //字符数组a,a[9]为系统自动增设的终结符(\0)
void init(); //
/*******************************************************************/
/* */
/* z毫秒延时函数 */
/* */
/*******************************************************************/
void delay(uint z)
{
uint x,y;
for(x=z;x>0;x--)
for(y=110;y>0;y--);
}
/*******************************************************************/
/* */
/* 50微秒延时函数 */
/* */
/*******************************************************************/
void delay_50us (uchar t)
{
uchar j;
for(;t>0;t--)
for(j=19;j>0;j--);
}
/*******************************************************************/
/* */
/*检查LCD忙状态 */
/*lcd_busy为1时,忙,等待。lcd-busy为0时,闲,可写指令与数据。 */
/* */
/*******************************************************************/
bit lcd_busy()
{
bit result;
LCD_RS = 0;
LCD_RW = 1;
LCD_EN = 1;
delay_50us(1);
result = (bit)(P0&0x80);
LCD_EN = 0;
return(result);
}
/*******************************************************************/
/* */
/*写指令数据到LCD */
/*RS=L,RW=L,E=高脉冲,D0-D7=指令码。 */
/* */
/*******************************************************************/
void lcd_wcmd(uchar cmd)
{
while(lcd_busy());
LCD_RS = 0;
LCD_RW = 0;
LCD_EN = 0;
delay_50us(2);
P0 = cmd;
LCD_EN = 1;//下降沿写入
delay_50us(8);
LCD_EN = 0;
delay_50us(2);
}
/*******************************************************************/
/* */
/*写显示数据到LCD */
/*RS=H,RW=L,E=高脉冲,D0-D7=数据。 */
/* //显示字符 */
/*******************************************************************/
void lcd_wdat(uchar dat)
{
while(lcd_busy());
LCD_RS = 1;
LCD_RW = 0;
LCD_EN = 0;
delay_50us(1);
P0 = dat;
LCD_EN = 1;//下降沿写入
delay_50us(10);
LCD_EN = 0;
delay_50us(2);
}
/*********************************************************/
/* */
/* 设定显示位置 */
/* */
/*********************************************************/
void lcd_pos(uchar X,uchar Y) //显示地址
{
uchar pos;
if (X==0)
{X=0x80;}
else if (X==1)
{X=0x90;}
else if (X==2)
{X=0x88;}
else if (X==3)
{X=0x98;}
pos = X+Y ;
lcd_wcmd(pos); //显示地址
}
/*******************************************************************/
/* */
/* LCD初始化设定 */
/* */
/*******************************************************************/
void lcd_init() //lcd初始化
{
LCD_PSB = 1; //并口方式
LCD_EN=0;
LCD_RST=0; //复位
delay(5);
LCD_RST=1; //复位恢复
lcd_wcmd(0x34); //扩充指令操作
delay(5);
lcd_wcmd(0x30); //基本指令操作
delay(5);
lcd_wcmd(0x0C); //显示开,关光标
}
/****************串行口字节发送****************/
void UART_SendOneByte(uchar c)
{
SBUF = c;
while(!TI); //若TI=0,在此等待
TI = 0;
}
/****************串行口字符发送****************/
void SendStr(uchar *s)
{
while(*s!='\0') //通过检测是否字符串末尾
{
UART_SendOneByte(*s);
s++;
}
}
/****************串行口字节接收****************/
uchar UART_ReceiveOneByte()
{
uint b; //定义无符号型变量b
b = SBUF;
while(!RI); //若RI=0,在此等待
RI = 0;
return b;
}
/****************串行口数据字符接收****************/
void ReceiveStr()
{
uint b; //定义无符号型变量b
uint bi = 0; //初始化为零
while(b!='\0') //通过检测是否字符串末尾
{
b = UART_ReceiveOneByte();
a[bi] = b;
bi++; //接受的数据存放于数组 a[] 中
}
}
void main()
{
init(); //调用串口初始化子函数
while(1)
{
if(flag==1) //若串口中断标志位打开
{
flag=0; //清除flag标志位 (即关闭串口中断标志位)
ES=0; //关串口中断
lcd_wcmd(0x01); //清除LCD的显示内容
delay(5);
i=0; // i清零
lcd_pos(0,0); //设置显示位置为第一行的第1个字符
while(a[i]!= '\0')
{
lcd_wdat(a[i]);
i++ ;
}
}
}
}
void ser() interrupt 4 //串口中断程序
{
ES=0; //关串口中断
RI=0; //清零串口接收标志位,即允许串口接收
if(gd ==1) //等于1时,为读的状态
{
SendStr("\nR3,0,2\r"); //发送:<LF> R3,0,2<CR> R3:读取USER空间,0:0地址位开始读取,2:数据长度2
delay(150);
ReceiveStr(); // 读取数据暂存于a中 ;
flag=1; //开串口中断标志位
ES=1; //开串口中断
}
else //若gd =0 为写的状态
{
SendStr("\nW3,0,2,246813EF\r"); //发送:<LF> W1,0,2<CR> W3:写入USER空间,0:0地址位开始写入,2:数据长度2
delay(150);
delay(150);
SendStr("\nR3,0,2\r");
delay(150);
ReceiveStr(); //该返回信息暂存于a中
lcd_wcmd(0x01); //清除LCD的显示内容
delay(5);
i=0; // i清零
lcd_pos(0,0); //设置显示位置为第一行的第1个字符
while(a[i]!= '\0')
{
lcd_wdat(a[i]);
i++ ;
}
while(1); //程序处于死机状态
}
}
void init() //单片机初始化
{
TMOD = 0x20; // 定时器T1工作于8位自动重载模式, 用于产生波特率
TH1 = 0xfd; // 波特率9600
TL1 = 0xfd; // 波特率9600
TR1 = 1; // 启动定时器T1
SCON = 0x50; // 设定串行口工作方式1,(SM0=0;SM1=1)及REN=1
EA=1; //开总中断
ES=1; //开串口中断
}
问题如下:
Build target 'Target 1'
compiling ID卡号读写-3.c...
ID卡号读写-3.C(1): warning C500: LICENSE ERROR (R208: RENEW LICENSE ID CODE (LIC))
linking...
*** WARNING L16: UNCALLED SEGMENT, IGNORED FOR OVERLAY PROCESS
SEGMENT: ?PR?LCD_INIT?ID卡号读写_3
*** WARNING L15: MULTIPLE CALL TO SEGMENT
SEGMENT: ?PR?LCD_BUSY?ID卡号读写_3
CALLER1: ?PR?SER?ID卡号读写_3
CALLER2: ?C_C51STARTUP
Program Size: data=22.2 xdata=0 code=578
"ID卡号读写-3" - 0 Error(s), 3 Warning(s).