⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 sendmcu.c

📁 教鞭驱动程序的发送端、接收端、双机串口通信仿真
💻 C
字号:
/*******************************************************************************
*  描述:                                                                       *
*         当用户点触摸屏时,产生笔中断,单片机开始将系统当前各种状态,按照
*         数据包协议,经过nrf401发送出去                                       *
*         引导符:长度:两个字节,内容:1)0xFF,2)0x55,
*         数据包:长度:3个字节,内含按键情况,触摸屏上的位移信息              *
*                 a)按键信息的采集                                             *
*                 b)绝对移动:将每一次的测量值,直接作为数据                   *
*                                                                              *
*         结束符:长度:1字节,内容:'E'                                       *                                               
*******************************************************************************/  

#include "reg51.h"
#include "intrins.h"

//引脚功能
sbit pw401=P2^5;  //rnf401_Power
sbit led=P2^6;    //指示灯

//触摸屏接口定义
sbit DCLK=P1^0;   //时钟
sbit CS=P1^1;     //片选
sbit DIN=P1^2;    //输入
sbit BUSY=P1^3;   //忙
sbit DOUT=P1^4;   //输出
sbit zd_PEN=P3^2; //中断口

//ads7843延时
void delay(unsigned char i);
//ads7843初始化
void start();
//ads7843写控制字
void ads7843_wr(unsigned char num);
//ads7843读数据
unsigned char ads7843_rd();
//中断服务
void ZhongDuan();
//发送数据包后,闪灯以示正常工作
void work();


//***  按键检测
unsigned char key_s, key_v, tmp;
unsigned char sjb[7] = {0xFF,0x55,0x80,0x01,0x01,'E','\0'};

sbit    K0 = P2^0; //模式:相对:0,绝对:1
unsigned char key_s0, key_v0;
sbit	K1 = P2^1; //左键
unsigned char key_s1, key_v1;
sbit    K2 = P2^2; //右键
unsigned char key_s2, key_v2;
sbit    K3 = P2^3; //上一页
unsigned char key_s3, key_v3;
sbit    K4 = P2^4; //下一页
unsigned char key_s4, key_v4;


//unsigned char i = 0;

void send_sjb();
void delayms(unsigned char ms);
void send_char(unsigned char txd);


bit scan_key1()	
// 扫描按键
{
	key_s1 = 0x00;
 	key_s1 |= K1;
	return(key_s1 ^ key_v1);	
}

void proc_key1()
// 键处理
{
	if((key_v1 & 0x01) == 0)
	{

       IE = 0x00;				// 禁止任何中断
	// K1按下,左键单击
    // 左键按下,数据包为0xFF,0x55,0000 0001 b,0x00,0x00,'E','\0' 
    sjb[2]|=0x01;sjb[3]=1;sjb[4]=1;
    send_sjb();
    // 左键抬起,数据包为0xFF,0x55,1111 1110 b,0x00,0x00,'E','\0'
	sjb[2]&=~0x01;
    send_sjb();
	   IE=0x81; //1000 0001 EA=1中断允许,
     }
}

bit scan_key2()	
// 扫描按键
{
	key_s2 = 0x00;
	key_s2 |= K2;
	return(key_s2 ^ key_v2);	
}

void proc_key2()
// 键处理
{
	if((key_v2 & 0x01) == 0)
	{
	   IE = 0x00;				// 禁止任何中断
	// K2按下,右键单击
    // 右键按下,数据包为0xFF,0x55,0000 0100 b,0x00,0x00,'E','\0' 
    sjb[2]|=0x04;sjb[3]=1;sjb[4]=1;
    send_sjb();
    // 右键抬起,数据包为0xFF,0x55,1111 1011 b,0x00,0x00,'E','\0'
	sjb[2]&=0xfb;
    send_sjb();
	   IE=0x81; //1000 0001 EA=1中断允许,
	   
     }
}

bit scan_key3()	
// 扫描按键
{
	key_s3 = 0x00;
	key_s3 |= K3;
	return(key_s3 ^ key_v3);	
}

void proc_key3()
// 键处理
{
	if((key_v3 & 0x01) == 0)
	{			
	   IE = 0x00;				// 禁止任何中断
	// K3按下,PU键单击
    // PU键按下,数据包为0xFF,0x55,0000 1000 b,0x00,0x00,'E','\0' 
	sjb[2]|=0x08;sjb[3]=1;sjb[4]=1;
    send_sjb();
    // PU键抬起,数据包为0xFF,0x55,1111 0111 b,0x00,0x00,'E','\0'
	sjb[2]&=0xf7;
    send_sjb();
	   IE=0x81; //1000 0001 EA=1中断允许,		  
	   
     }
}

bit scan_key4()	
// 扫描按键
{
	key_s4 = 0x00;
	key_s4 |= K4;
	return(key_s4 ^ key_v4);	
}

void proc_key4()
// 键处理
{
	if((key_v4 & 0x01) == 0)
	{		
	   IE = 0x00;				// 禁止任何中断
	// K4按下,PD键单击
    // PD键按下,数据包为0xFF,0x55,0001 0000 b,0x00,0x00,'E','\0' 
	sjb[2]|=0x10;sjb[3]=1;sjb[4]=1;
    send_sjb();
    // PD键抬起,数据包为0xFF,0x55,1110 1111 b,0x00,0x00,'E','\0'
	sjb[2]&=0xef;
    send_sjb();
	   IE=0x81; //1000 0001 EA=1中断允许,
     }
}

void mykey()
{
	if(!K0)sjb[2]|=0x02;
	else  sjb[2]&=~0x02;

	if(!K1)sjb[2]|=0x01;
	else  sjb[2]&=~0x01;
	
	if(!K2)sjb[2]|=0x04;
	else  sjb[2]&=~0x04;

	if(!K3)sjb[2]|=0x08;
	else  sjb[2]&=~0x08;

	if(!K4)sjb[2]|=0x10;
	else  sjb[2]&=~0x10;

}


main()
{

// 寄存器初始化
	TMOD = 0x20;			// 定时器1工作于8位自动重载模式, 用于产生波特率
	TH1 = 0xFD;				// 波特率9600
	TL1 = 0xFD;
	
	SCON = 0x50;			// 设定串行口工作方式
	PCON &= 0xef;			// 波特率不倍增
		
	TR1 = 1;				// 启动定时器1
	IE = 0x0;				// 禁止任何中断

	IE=0x81; //1000 0001 EA=1中断允许,
    IP=0x01;

    pw401=1;
//

//    ads7843_wr(0x80); //送控制字 10011000 即用差分方式读X坐标 详细请见有关资料
	
	while(1)
	{  

//检测K1       
		if(scan_key1())		// 扫描按键
		{  // send_char('c');
		    delayms(10);			// 延时去抖动
			if(scan_key1())			// 再次扫描
			{   
				key_v1 = key_s1;		// 保存键值
	     		proc_key1();			// 键处理
			}
		}

//检测K2
		if(scan_key2())		// 扫描按键
		{  // send_char('c');
		    delayms(10);			// 延时去抖动
			if(scan_key2())			// 再次扫描
			{   
				key_v2 = key_s2;		// 保存键值
	     		proc_key2();			// 键处理
			}
		}		

//检测K3
		if(scan_key3())		// 扫描按键
		{  // send_char('c');
		    delayms(10);			// 延时去抖动
			if(scan_key3())			// 再次扫描
			{   
				key_v3= key_s3;		// 保存键值
	     		proc_key3();			// 键处理
			}
		}
//检测K4
		if(scan_key4())		// 扫描按键
		{  // send_char('c');
		    delayms(10);			// 延时去抖动
			if(scan_key4())			// 再次扫描
			{   

				key_v4 = key_s4;		// 保存键值
	     		proc_key4();			// 键处理

			}
		}
  //串口发送检测信号		
		if(RI)						// 是否有数据到来
		{
			RI = 0;
			tmp = SBUF;				// 暂存接收到的数据
			P0 = tmp;				// 数据传送到P0口
			send_char(tmp);			// 回传接收到的数据
		}
		
	}

}


// 传送一个字符
void send_char(unsigned char txd)
{
	SBUF = txd;
	while(!TI);				// 等特数据传送

	TI = 0;					// 清除数据传送标志
}

// 传送字串
void send_sjb()
{
	unsigned char i = 0;
	while(sjb[i] != '\0')
	{
		SBUF = sjb[i];
		while(!TI);				// 等特数据传送
		TI = 0;					// 清除数据传送标志
		i++;					// 下一个字符
	}	

	work();

}

void delayms(unsigned char ms)	
// 延时子程序
{						
	unsigned char i;
	while(ms--)
	{
		for(i = 0; i < 120; i++);
	}
}



//==========================================
void ZhongDuan() interrupt 0 //外部中断0 发送数据包
{
unsigned char X1=0,Y1=0;
unsigned char X2=0,Y2=0;
unsigned char s=0,tmpx=0,tmpy=0;
s=0;


IE = 0x00;				// 禁止任何中断
delay(10); //100中断后延时以消除抖动,使得采样数据更准确

start();     //启动SPI
//while(BUSY); //如果BUSY信号不好使可以删除不用
delay(2);

			//写读X值的命令字
			ads7843_wr(0xD8); //送控制字 10011000 即用差分方式读X坐标 详细请见有关资料
			//while(BUSY); //如果BUSY信号不好使可以删除不用
			delay(2);
			DCLK=1; _nop_();_nop_();_nop_();_nop_();
			DCLK=0; _nop_();_nop_();_nop_();_nop_();
			//读X值
			X1=ads7843_rd();
			
			//写读Y值的命令字
			ads7843_wr(0x98); //送控制字 11011000 即用差分方式读Y坐标 详细请见有关资料
			DCLK=1; _nop_();_nop_();_nop_();_nop_();
			DCLK=0; _nop_();_nop_();_nop_();_nop_();
			//读Y值
			Y1=ads7843_rd();
			
			delay(5);

 			//写读X值的命令字
			ads7843_wr(0xD8); //送控制字 10011000 即用差分方式读X坐标 详细请见有关资料
			//while(BUSY); //如果BUSY信号不好使可以删除不用
			delay(2);
			DCLK=1; _nop_();_nop_();_nop_();_nop_();
			DCLK=0; _nop_();_nop_();_nop_();_nop_();
			//读X值
			X2=ads7843_rd();
			
			//写读Y值的命令字
			ads7843_wr(0x98); //送控制字 11011000 即用差分方式读Y坐标 详细请见有关资料
			DCLK=1; _nop_();_nop_();_nop_();_nop_();
			DCLK=0; _nop_();_nop_();_nop_();_nop_();
			//读Y值
			Y2=ads7843_rd();

 			tmpx=(X2>X1)?1:0;
			tmpy=(Y2>Y1)?1:0;

			     if ( tmpx && ( (X2-X1) && (X2-X1)<2 ) ){s=1;sjb[3]=X2;}
				 if (!tmpx && ( (X1-X2) && (X1-X2)<2 ) ){s=1;sjb[3]=X2;}
				 if ( tmpy && ( (Y2-Y1) && (Y2-Y1)<2 ) ){s=1;sjb[4]=Y2;}
				 if (!tmpy && ( (Y1-Y2) && (Y1-Y2)<2 ) ){s=1;sjb[4]=Y2;}

			if(s)
			{
			 mykey();
			 send_sjb();
			}

		   
CS=1;

IE=0x81; //1000 0001 EA=1中断允许,
}


//闪灯示意正在发送数据,并让接收端有足够时间接收所有数据
void work() 
{ led=0;
  delayms(5);			
  led=1;
 

}

//===================================
void delay(unsigned char i)// ads7843延时用
{
while(i--);
}

//==================================
void start() 
{
DCLK=0;
CS=1;
DIN=1;
DCLK=1;
CS=0;
}

//=======================================
void ads7843_wr(unsigned char num) 
{
unsigned char i=0;
DCLK=0;
for(i=0;i<8;i++)     //8位,
   {
   num<<=1;
   DIN=CY;
   DCLK=0; _nop_();_nop_();_nop_(); //上升沿有效
   DCLK=1; _nop_();_nop_();_nop_();
   }
}

//========================================
unsigned char ads7843_rd() 
{
unsigned char i=0;
unsigned char Num=0;
for(i=0;i<8;i++)     //8位,
   {
   Num<<=1;
   DCLK=1; _nop_();_nop_();_nop_(); //下降沿有效
   DCLK=0; _nop_();_nop_();_nop_();
   if(DOUT) Num++;
   }
return(Num);
}

⌨️ 快捷键说明

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