test.c

来自「基于C8051F040的液晶」· C语言 代码 · 共 328 行

C
328
字号
//#include "c8051f040.h"
//#include "lcd.h"
#include "c8051f040.h"
typedef unsigned char uchar;
typedef unsigned int uint;
typedef unsigned long ulong;
sbit lcdrs=P5^2;//硬件控制接口
sbit lcdrw=P5^1;
sbit lcdcs=P5^0;
xdata uchar keybuf[16];//输入缓冲区
code uchar disdata[3][16]={"0123456789.+-012","ABCDEFGHIJKLMNOP","QRSTUVWXYZ@#$%&*"};
xdata uchar intbuf[16];//显示int型数据缓冲区
void config(void){
//看门狗禁止
    WDTCN = 0x07;	
    WDTCN = 0xDE;   
    WDTCN = 0xAD;
    SFRPAGE = 0x0F;
    XBR0 = 0x00;	
    XBR1 = 0x00;	
    XBR2 = 0x40;	//交叉开关使能,使得P0-P3口能输出
    XBR3 = 0x00;    
    SFRPAGE = 0x0F;
    P0MDOUT = 0x00; //端口配置,P0-P3,P6-P7口为开漏输出
    P1MDOUT = 0x00; 
    P2MDOUT = 0x00; 
    P3MDOUT = 0x00; 
    P4MDOUT = 0x00; //P4口为开漏
    P5MDOUT = 0x07; 
    P6MDOUT = 0x00; 
    P7MDOUT = 0x00;
					\
    P1MDIN = 0xFF;  //所有端口为数字输入,没有模拟输入端口
    P2MDIN = 0xFF;  
    P3MDIN = 0xFF; 
    SFRPAGE = 0x0F;
    CLKSEL = 0x00;  
    OSCXCN = 0x00;	
    OSCICN = 0x84;	
    //采用内部晶振,为24.5MHZ8分频
}
void delay1ms(uint time){//延迟1ms*time,这不是一个精确值
	uint i;
	uint j;
	for (i=0;i<time;i++){
		for(j=0;j<255;j++);
	}
}	
void delay50us(uchar time){//延时50us*time,不是精确值
	uchar i,j;
	for (i=0;i<time;i++){
		for(j=0;j<12;j++);
	}
}	
void sendc(uchar c){//给lcd送命令
	SFRPAGE = 0x0f;//以下为lcd发送命令虚拟时序
	P4=c;
	lcdrs=0;
	lcdrw=0;
	EA=0;
	lcdcs=1;
	lcdcs=0;
	lcdcs=1;
	lcdrw=1;
	P4=0xff;//先置1,后读取
	lcdrs=0;
	while(P4>=0x80);
	lcdcs=0;
	lcdcs=1;
	EA=1;
	if(c==1)
		delay1ms(2);
                
}
void sendd(uchar c){//给lcd送数据
	SFRPAGE = 0x0f;
	EA=0;
	P4=c;
	lcdrs=1;
	lcdrw=0;
	lcdcs=1;
	lcdcs=0;
	lcdcs=1;
	lcdrw=1;
	P4=0xff;//先置1,后读取
	lcdrs=0;
	while(P4>=0x80);
	lcdcs=0;
	lcdcs=1;
	EA=1;
}	
uchar readd(){//读LCD数据
	uchar k;
	SFRPAGE = 0x0f;
	EA=0;
	lcdrw=1;
	P4=0xff;
	lcdrs=1;
	k=P4;
	lcdcs=0;
	lcdcs=1;
	P4=0xff;//先置1,后读取,否则所读数据可能有误
	lcdrs=0;
	while(P4>=0x80);
	/*读LCD是否为忙,此代码不可省略,否则连续读时若LCD为忙,所读数据是上一周期的数据*/
	lcdcs=0;
	lcdcs=1;
	EA=1;
	return k;
}	
void dispini(){	//lcd显示初始化
	delay1ms(100);
	SFRPAGE=0xf;
	lcdcs=0;         
	lcdrs=1;
	lcdrw=1;
	delay1ms(30);
	sendc(0x38);//8位,2行,5*7字体
	delay1ms(100);
	sendc(0x0c);//显示开,光标关;不闪烁字符
	delay1ms(100);
	sendc(0x06);//增量方式,现不移动
	delay1ms(100);
	sendc(0x01);//清屏
	delay1ms(100);
}
void puti(long  data inum){    
/*将一个int型数据转化成ascii码字符串,结尾以'\0'结束,并将结果存于intbuf(全局变量数组,可在任何地方被调用)*/
	long data t;
 	uchar data c=0;
	bit flag=1;
	t=100000000L;
	for(;c<16;c++)
		intbuf[c]='\0';
	c=0;
	if(inum<0){
		intbuf[0]='-';
		c++;
		inum=-inum;
	}
	for(;t>=10;t/=10){//此为将int型转化成字符串算法
		if(t==10){
			intbuf[c]=inum/t+'0';
			intbuf[++c]=inum%t+'0';
			intbuf[++c]='\0';
			break;
		}
		if(inum<t&flag)
			continue;
		else	{
			flag=0;
			intbuf[c]=inum/t;
			inum-=(long)(intbuf[c]) * t;
			intbuf[c]+='0';
			c++;
		}
	}
}
void showline(uchar  *str,bit page){//page值为0,显示第一行,page为1,显示第二行
	uchar idata  k;
	if(page==0){//控制显示在第几行是通过k的地址不同来实现的
		for(k=0x80;k<0x90;k++){
           	if(*str=='\0'){//*str的指针不下移,会执行到k=0x8f为止
				sendc(k);
				sendd(' ');//显示空格清掉上次显示部分
			}
			else{
				sendc(k); 
				sendd(*str);
				str++;
			}
		}
	}
	if(page==1){
		for(k=0xc0;k<0xd0;k++){
			if(*str=='\0'){
				sendc(k);
				sendd(' ');
			}
			else	{
				sendc(k); 
				sendd(*str);
				str++;
			}
		}
	}
}
void showint(long idata num,bit line){
	puti(num);
	showline(intbuf,line);
}








uchar idata fifo[60];  //用数组构建产度为60的队列
uchar fifoAdd(uchar a){//队列元素增加
	uchar i;
	for(i= 0;i<59;i++){
		fifo[59-i]=fifo[58-i];
	}
	fifo[0] = a;
	return fifo[0];
}
/*--------------------------------------------
键盘扫描函数,返回键值:DYT。2008-08-19
--------------------------------------------*/
/*uchar scankey(void){
	uchar c;
	for(;;){
		P2 = 0xff;
		c = P2&0x0f;
		
		switch(c){
			case 0x0e:c=0;return c;
			case 0x0d:c=1;return c;
			case 0x0b:c=2;return c;
			case 0x07:c=3;return c;
		}
	}
}*/
/*--------------------------------------------
矩阵式键盘扫描函数,返回键值:DYT。2008-08-27
--------------------------------------------*/
Scankey(void){
	xdata uchar col[4]={0x0e,0x0d,0x0b,0x07};
	xdata uchar table[4][4] ={{0,1,2,3,},{4,5,6,7},{8,9,10,11},{12,13,14,15}};
    uchar c,r,p,i;//c:列 r:行  p:端口输入 
    for(;;){
        P7 = 0x0f;
        p = P7;
        if(p != 0x0f){break;}
    }
    switch(p){
    	case 0x0e:c=0;break;
    	case 0x0d:c=1;break;
    	case 0x0b:c=2;break;
    	case 0x07:c=3;break;
    }
    //用于IO口高四位依次置1,用移位运算“>>”实现 
    for(i=0;i<4;i++){
        p=0x80>>i;
		P7=0x0f;
        P7|=p;
		r=P7;
        r&=0x0f;
        if(r==0x0f ){r=i;break;}
    
    }
    return table[r][c];
}

/*---------------------------------------------
逐位显示函数:DYT.2008-08-19
---------------------------------------------*/
void showbit(uchar c,bit line,uchar adr){
	uchar idata k;
	c ='0'+c;
	if(~line){ k = 0x80+adr;}
	else {k = 0xc0+adr;}
	sendc(k);
	delay1ms(255);
	sendd(c);
}
/*---------------------------------------------
确定处理函数:DYT.2008-08-29
---------------------------------------------*/
bit Confirm(uchar *quest){
	bit flag=1;
	showline(quest,0);
	showline("  *YES*    no",1);
	for(;;){
		if(Scankey()==8){
			showline("   yes    *NO*",1); 
			delay1ms(100);
			flag=0;
		}
		else if(Scankey()==9){
			showline("  *YES*    no",1);
			delay1ms(100);
			flag=1;
		}
		else if(Scankey()==13){return flag;}
	}
}

main(void){
	ulong idata x = 100;
	uchar idata add = 0;
	config();
	dispini();
	x=Confirm("Return?");
	/*showline("Scankey test",0);
	while(1){
		x = Scankey();
		showint(x,1);
		delay1ms(200);
	}//矩阵键盘扫描测试程序*/
	//showline("Scankey test:",0);
   	/*while(1){
		x = scankey();
 	    showbit(x,1,add);
		add++;
	}
	while(1){
		if(x<255){
			fifoAdd(x);
			showint(fifo[10],0);
			showint(fifo[20],1);
			x++;
			delay1ms(200);
		}

		else x = 0;
	}*/
	while(1){
		showint(x,0);
		delay1ms(300);
		x++;
		if(x == 99999) x = 0;
	}
}

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?