Chinaunix首页 | 论坛 | 博客
  • 博客访问: 927973
  • 博文数量: 210
  • 博客积分: 0
  • 博客等级: 民兵
  • 技术积分: 2070
  • 用 户 组: 普通用户
  • 注册时间: 2014-11-19 21:54
文章分类

全部博文(210)

文章存档

2020年(2)

2019年(18)

2018年(27)

2017年(5)

2016年(53)

2015年(88)

2014年(17)

分类: 嵌入式

2015-05-23 14:27:17

1 电路图:


2 源代码
 
(1)接收程序:
#include
#include
sbit led=P1^0;
#define uchar unsigned char
sbit  LCD_1602_RW=P2^1;
sbit  LCD_1602_RS=P2^0;
sbit  LCD_1602_EN=P2^5; 


/*****************************************************
函数功能:延时1ms
(3j+2)*i=(3×33+2)×10=1010(微秒),可以认为是1毫秒
***************************************************/
void delay_1ms()
{
   float i,j;
for(i=0;i<4;i++)
 for(j=0;j<33;j++)
  ;  
  i++;
}
/**************************************************
函数功能:延时10微妙
程序调用 2us + 子程序返回 2us + R7赋值 1us
**************************************************/
 void delay_10us()
 {
  unsigned int i = 100;
i--;
i--;
i--;
i--;
i--;
i--;
 } 


//读忙标志,LCD工作速度较慢,只有它不忙的时候才可以接受单片机的指令
int lcd_1602_busy()
{
uchar tmp;
P0 = 0xff;
LCD_1602_RW = 1;
LCD_1602_RS = 0;


LCD_1602_EN = 1;
delay_10us();
tmp = P0;
LCD_1602_EN = 0;


//强制转换,将一个8位二进制转换成1位的
//bit是位数据
//如果1602忙,那么tmp的最高位是1
return (bit)(0x80 & tmp);


}


void lcd_1602_write_cmd(uchar cmd)
{
//等待1602不忙
  while(lcd_1602_busy());

LCD_1602_RW = 0;
LCD_1602_RS = 0;
P0 = cmd;


LCD_1602_EN = 1;
delay_10us();
LCD_1602_EN = 0;
}


void lcd_1602_write_data(uchar dat)
{
while(lcd_1602_busy());


LCD_1602_RW = 0;
LCD_1602_RS = 1;
P0 = dat;


LCD_1602_EN = 1;
delay_10us();
LCD_1602_EN = 0;
}


void lcd_1602_init()
{
lcd_1602_write_cmd(0x01); //指令1,发送清屏指令
lcd_1602_write_cmd(0x0c); //指令4,打开显示开关,没有光标
lcd_1602_write_cmd(0x38);    //指令6,8位总线,双行显示,5*7点阵
lcd_1602_write_cmd(0x06); //指令3,光标左移,屏幕上的字左移
lcd_1602_write_cmd(0x01); //清屏,所有的配置完成之后,需要清屏
delay_1ms();
}


void lcd_1602_write_char(uchar x, uchar y, uchar dat)
{
if(x == 0)
{
lcd_1602_write_cmd(0x80 + y%16);
lcd_1602_write_data(dat);
}
else
{
lcd_1602_write_cmd(0xc0 + y%16);
lcd_1602_write_data(dat);
}
}


void lcd_1602_write_string(uchar x, uchar y, uchar *string)
{
int i=0;
while(i {
lcd_1602_write_char(x, y++, *(string++));
}
}
void delay()
{
int i,j;
for(i=0;i<1000;i++)
for(j=0;j<100;j++);
}


void lcd_1602_write_left(uchar x, int len, char *string)
{
int i = 0;
while(i {
delay();
lcd_1602_write_string(x, 15-i, string);
i++;
}
}
/*void main() // 00001 110
{

char str[5]="12345";
lcd_1602_init();

lcd_1602_write_string(0,10, "hello");
lcd_1602_write_char(1, 1, 'a');
lcd_1602_write_left(1, 5, str);
}*/
void delay_ms ()
{
int a ,b;
for (b=102;b>0;b--)
{
for (a=250;a>0;a--);


}






}


void serial_init()
{
  EA=0; //关闭中断
  TR1 = 0; //关闭定时器


 
  SM0 = 0;
  SM1 = 1; //选择串口的工作方式1
  PCON = 0;
  TMOD &=0x0F;
TMOD |=0x20;      //配置定时器1,让它作为波特率发生器
TL1 = 0XFD;
  TH1 = 0xFD; //晶振频率11.0592Mhz, 波特率9600
                  //使用定时器1作为波特率发生器,你不能再次使用               定时器1。


  TI = 0;
  RI = 0; //清空标志位


  REN = 1; //打开接收数据的开关
  EA=1;
  TR1 = 1; //打开定时器;
  ES=1;  //  打开串口中断开关
}


//单片机进入中断的条件:标志位等于1,系统会自动查询
//大部分标志位由单片机自动管理,产生中断之后标志位变成1;当单片机查询到标志位等于1时,跳入对应的中断处理程序;在中断处理程序中,大部分标志位会被系统自动清除为0
//51单片机的串口中断标志位会自动变成1,但是不会自动清零


void serial_interrupt() interrupt   4 //这是串行中断
{
  unsigned char temp;
  if(RI == 1)
  {
      RI = 0; //如果不清零,那么程序执行完之后又进入中断

temp =SBUF; 
            //单片机收到的数据放在SBUF寄存器,将它读出保存在变量temp        
        //SBUF=temp;
          // 处理temp
   if(temp == 'B') // 如果收到A 那么灯泡状态取反,并且将A发送出去
{

//led = ~led;
lcd_1602_write_string(0,5, "hello");

}
if(temp== 'b')
{
lcd_1602_write_string(0,5, "bye!!");

}
  }


  if (TI == 1)
  {
    TI = 0;
      
  }
}


int  main()


{


serial_init(); 
lcd_1602_init();     //1602初始化
led = 0;
while(1) ;      //保证程序不退出
{

//SBUF='B';
 //delay_ms ();
 

}




}


(2)发送程序:

#include
sbit led=P1^0;
void interrupt_init()
{
//关闭开关
EX1=0;
EA =0;
       //配置产生中断的方式IT=0是下降沿产生中断
IT1=1;
//打开开关
EA=1;
EX1=1;




}


/*void delay_s ()
{
int a ,b,c;
for(c=13;;c>0;c--)
{
for (b=247;b>0;b--)
{
for (a=142;a>0;a--);
{
 
 
}

}
}






} */
void serial_init()
{
  EA=0; //关闭中断
  TR1 = 0; //关闭定时器


 
  SM0 = 0;
  SM1 = 1; //选择串口的工作方式1
  PCON = 0;
  TMOD &=0x0F;
TMOD |=0x20;      //配置定时器1,让它作为波特率发生器
TL1 = 0XFD;
  TH1 = 0xFD; //晶振频率11.0592Mhz, 波特率9600
                  //使用定时器1作为波特率发生器,你不能再次使用               定时器1。


  TI = 0;
  RI = 0; //清空标志位


  REN = 1; //打开接收数据的开关
  EA=1;
  TR1 = 1; //打开定时器;
  ES=1;  //  打开串口中断开关
}


//单片机进入中断的条件:标志位等于1,系统会自动查询
//大部分标志位由单片机自动管理,产生中断之后标志位变成1;当单片机查询到标志位等于1时,跳入对应的中断处理程序;在中断处理程序中,大部分标志位会被系统自动清除为0
//51单片机的串口中断标志位会自动变成1,但是不会自动清零


void serial_interrupt() interrupt   4 //这是串行中断
{
  unsigned char temp,i=0;
  if(RI == 1)
  {
      RI = 0; //如果不清零,那么程序执行完之后又进入中断

temp =SBUF; 
            //单片机收到的数据放在SBUF寄存器,将它读出保存在变量temp        
        SBUF=temp;
          // 处理temp
   //if(temp == 'A') // 如果收到A 那么灯泡状态取反,并且将A发送出去
//{

// led = ~led;

//}
  }


  if (TI == 1)
  {
    TI = 0;
      
  }
}


 void delay_s ()
{
int a ,b,c;
for(c=13;c>0;c--)
{
for (b=247;b>0;b--)
{
for (a=142;a>0;a--)
{
 
 
}

}
}






}
int  main()


{


serial_init();
interrupt_init ();
led = 0;
while(1)      //保证程序不退出
{

 SBUF='B';
 delay_s ();
 

}




}
void inter0()    interrupt   0
{
int count=0;
count++;
if(count%2 ==0)
{
SBUF = 'b';

}
else 
{
SBUF = 'b';
}
if(count>1000)
{
count = 0;

}




}




注意:在实际操作的过程中,首相要打开的接收的单片机,然后再开启发送的单片机,这样避免文件,信息,数据的丢失。
阅读(1373) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~