zoukankan      html  css  js  c++  java
  • 实验3 串口通信

    1. 2400bps从计算机发送任一字节数据,当单片机收到该数据后,将其送到数码管显示,在此数据前加上一序号然后连同此数据一起发送至计算机,当序号超过255时归零。

    #include <reg51.h>

    #define uchar unsigned char

    #define uint unsigned int

    #define ulong unsigned long

    /**

    题目要求:2400bps从计算机发送任一字节数据,当单片机收到该数据后,将其送到数码管显示,在此数据前加上一序号然后连同此数据一起发送至计算机,当序号超过255时归零。

    **/

    /**

    步骤

    接线方式:

    1P0接数码管J12,实现段选

    2、译码器和数码管位选输入短接,J15+J16

    3P2用来控制译码器的输入

    4P1是串口接收中断的指示,P1+JP1

    5、本实验使用的晶振是11.0592

    **/

    //=========全局变量区============================================

    sbit high=P2^4;

    sbit mid=P2^3;

    sbit low=P2^2;

    uint code NumTable[]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f,0x77,0x7c,0x39,0x5e,0x79,0x71};//数字的编码

     

    uint Received_Flag=0;//用来标志是否接收到信号

    uchar ReceiveCount,Data_Received=0;//ReceiveCount是接受的条数,接收到的数据

    uchar code table[]="index ";

    //=========全局变量区结束========================================

     

     

     

    //========函数区开始============================================

    /**

        延时

    **/

    void delay_1ms(uint x){

        uint i=x;

        uint j;

        for(;i>0;--i){

           for(j=110;j>0;--j);

        }

    }

    /**

        在数码管上显示对应的值

    **/

    void display(uchar Num)

    {

        P0=NumTable[Num];

        delay_1ms(1);

        P0=0;      //送完段选信号后,进行消影的处理

    }

     

    /**

        控制数码管显示后3位,并分解计数值

    **/

    void DisplayNumByOrder(uint Value){

           low=0; mid=0; high=0;  display(0);        

            low=1; mid=0; high=0;  display(0);               

            low=0; mid=1; high=0;  display(0);

           low=1; mid=1; high=0;  display(0);

           low=0; mid=0; high=1;  display(0);

           low=1; mid=0; high=1;  display(Value%1000/100);

           low=0; mid=1; high=1;  display(Value%100/10);

           low=1; mid=1; high=1;  display(Value%10);

    }

     

    void init(){      //初始化定时器T1和串口

        SCON =0x50;  //设置串口工作方式1,并打开接收中断

        TMOD =0x20;  //设置T1工作方式2

        PCON =0x00;  //设置SMOD为串口工作方式1

        TL1 =0xf4;      

        TH1 =0xf4;     //2400bps(12MHZ的晶振)

        TR1 =1;      //开启时钟

        ES =1;           //开启串口中断允许

        EA =1;           //开启中断总允许

    }

    /**

        发送数据

    **/

    void SendData(uchar value){

        SBUF=value;

        while(!TI);

        TI=0;

    }

    /**

        处理接收到的数据

    **/

    void ProcessData(){

        int i=0;

        for(i=0;i<6;i++){

           SendData(table[i]);

        }

        SendData(ReceiveCount);

        SendData(':');

        SendData(Data_Received);

    }

    int main(){

     

        init();//初始化数据

        while(1){

           if(1==Received_Flag){//当单片机收到该数据后,将其送到数码管显示

               ES=0;//将串口接收总中断关闭,因为发送数据的时候,往缓冲区内写数据也会引发串口接收中断。

               ProcessData();

               ES=1;

               Received_Flag=0;

           }

           //在此数据前加上一序号然后连同此数据一起发送至计算机,当序号超过255时归零。

           DisplayNumByOrder(Data_Received);  //在数码管上显示

        }

        return0;

    }

     

    //========函数区结束============================================

     

     

    //========中断函数区============================================

     

    /**

        串口接收中断

    **/

    void ser_received() interrupt 4

    {

        RI=0;//RI=1代表缓冲区内有数据,清零以便等待下次数据到来

        Data_Received=(uchar)SBUF;  //从缓冲区内读取数据

        Received_Flag=1;  //设置已经接收到数据

        P1=~P1;

        ReceiveCount++;

    }

    //========中断函数区结束==========================================

    2. 16进制发送一个0-65536之间的任一数,当单片机收到后在数码管上动态显示出来,波特率自定。

    #include <reg51.h>

    #define uchar unsigned char

    #define uint unsigned int

    #define ulong unsigned long

    /**

    题目要求:  16进制发送一个0-65536之间的任一数,当单片机收到后在数码管上动态显示出来,波特率自定。

    **/

    /**

    步骤

    接线方式:

    1P0接数码管J12,实现段选

    2、译码器和数码管位选输入短接,J15+J16

    3P2用来控制译码器的输入

    4P1是串口接收中断的指示,P1+JP1

    5、本实验使用的晶振是11.0592

    **/

    //=========全局变量区============================================

    sbit high=P2^4;

    sbit mid=P2^3;

    sbit low=P2^2;

    uint code NumTable[]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f,0x77,0x7c,0x39,0x5e,0x79,0x71};//数字的编码

     

    uint Received_Flag=0;//用来标志是否接收到信号

    uchar ReceiveCount,DecodeCount,Data_Received=0;//ReceiveCount是已经接收的条数,DecodeCount是已经解析的数目,Data_Received是接收到的数据

    ulong NumToDisplay=0;

    //=========全局变量区结束========================================

     

     

     

    //========函数区开始============================================

    /**

      延时

    **/

    void delay_1ms(uint x){

      uint i=x;

      uint j;

      for(;i>0;--i){

         for(j=110;j>0;--j);

      }

    }

    /**

      在数码管上显示对应的值

    **/

    void display(uchar Num)

    {

      P0=NumTable[Num];

      delay_1ms(1);

      P0=0;      //送完段选信号后,进行消影的处理

    }

     

    /**

      控制数码管显示后3位,并分解计数值

    **/

    void DisplayNumByOrder(ulong Value){

         low=0; mid=0; high=0;  display(0);        

          low=1; mid=0; high=0;  display(0);               

          low=0; mid=1; high=0;  display(0);

         low=1; mid=1; high=0;  display(Value%100000/10000);

         low=0; mid=0; high=1;  display(Value%10000/1000);

         low=1; mid=0; high=1;  display(Value%1000/100);

         low=0; mid=1; high=1;  display(Value%100/10);

         low=1; mid=1; high=1;  display(Value%10);

    }

     

    void init(){    //初始化定时器T1和串口

      SCON =0x50;  //设置串口工作方式1,并打开接收中断

      TMOD =0x20;  //设置T1工作方式2

      PCON =0x00;  //设置SMOD为串口工作方式1

      TL1 =0xf4;      

      TH1 =0xf4;     //2400bps(11.0592MHZ的晶振)

      TR1 =1;      //开启时钟

      ES =1;           //开启串口中断允许

      EA =1;           //开启中断总允许

    }

    /**

      发送数据

    **/

    void SendData(uchar value){

      SBUF=value;

      while(!TI);

      TI=0;

    }

     

    int main(){

     

      init();//初始化数据

      while(1){

         if(1==Received_Flag){//当单片机收到该数据后,将其送到数码管显示

             ES=0;//将串口接收总中断关闭,因为发送数据的时候,往缓冲区内写数据也会引发串口接收中断。

             //ProcessData();

             ES=1;

             Received_Flag=0;

         }

         //在此数据前加上一序号然后连同此数据一起发送至计算机,当序号超过255时归零。

         DisplayNumByOrder(NumToDisplay);   //在数码管上显示

      }

      return0;

    }

     

    //========函数区结束============================================

     

     

    //========中断函数区============================================

     

    /**

      串口接收中断

    **/

    void ser_received() interrupt 4

    {

      if(RI ==1){//接收到触发中断

         RI=0;//RI=1代表缓冲区内有数据,清零以便等待下次数据到来

         Data_Received=(uchar)SBUF;  //从缓冲区内读取数据

         Received_Flag=1;  //设置已经接收到数据

         if(DecodeCount==0){

             NumToDisplay=Data_Received;

             ++DecodeCount;

         }else{

             NumToDisplay =(NumToDisplay <<8)| Data_Received;//相当于原来的数乘以8,然后+现在的数

             DecodeCount++;

             if(DecodeCount ==3)                  //0..65536要接收6位的16进制

                DecodeCount =0;

         }

         P1=~P1;

         ReceiveCount++;

      }

    }

    //========中断函数区结束==========================================

     

    扩展题目:

    1.      实现单片机双机通信,实现单片机甲发送一个信息给单片机乙,同时在数码管上显示出来,单片机乙收到信息后,回复OK给单片机甲。

     

    //甲机

     

       

    #include <reg51.h>

    #define uchar unsigned char

    #define uint unsigned int

    #define ulong unsigned long

    /**

    题目要求:2400bps从计算机发送任一字节数据,当单片机收到该数据后,将其送到数码管显示,在此数据前加上一序号然后连同此数据一起发送至计算机,当序号超过255时归零。

    **/

    /**

    步骤

    接线方式:

    1P0接数码管J12,实现段选

    2、译码器和数码管位选输入短接,J15+J16

    3P2用来控制译码器的输入

    4P1是串口接收中断的指示,P1+JP1

    5、本实验使用的晶振是11.0592

    **/

    //=========全局变量区============================================

    sbit high=P2^4;

    sbit mid=P2^3;

    sbit low=P2^2;

    uint code NumTable[]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f,0x77,0x7c,0x39,0x5e,0x79,0x71};//数字的编码

     

    uint Received_Flag=0;//用来标志是否接收到信号

    uchar ReceiveCount,Data_Received=0;//ReceiveCount是接受的条数,接收到的数据

    uchar code table[]="index ";

    //=========全局变量区结束========================================

     

     

     

    //========函数区开始============================================

    /**

        延时

    **/

    void delay_1ms(uint x){

        uint i=x;

        uint j;

        for(;i>0;--i){

           for(j=110;j>0;--j);

        }

    }

    /**

        在数码管上显示对应的值

    **/

    void display(uchar Num)

    {

        P0=NumTable[Num];

        delay_1ms(1);

        P0=0;      //送完段选信号后,进行消影的处理

    }

     

    /**

        控制数码管显示后3位,并分解计数值

    **/

    void DisplayNumByOrder(uint Value){

           low=0; mid=0; high=0;  display(0);        

            low=1; mid=0; high=0;  display(0);               

            low=0; mid=1; high=0;  display(0);

           low=1; mid=1; high=0;  display(0);

           low=0; mid=0; high=1;  display(0);

           low=1; mid=0; high=1;  display(Value%1000/100);

           low=0; mid=1; high=1;  display(Value%100/10);

           low=1; mid=1; high=1;  display(Value%10);

    }

     

    void init(){      //初始化定时器T1和串口

        SCON =0x50;  //设置串口工作方式1,并打开接收中断

        TMOD =0x20;  //设置T1工作方式2

        PCON =0x00;  //设置SMOD为串口工作方式1

        TL1 =0xf4;      

        TH1 =0xf4;     //2400bps(11.0592MHZ的晶振)

        TR1 =1;      //开启时钟

        ES =1;           //开启串口中断允许

        EA =1;           //开启中断总允许

    }

    /**

        发送数据

    **/

    void SendData(uchar value){

        SBUF=value;

        while(!TI);

        TI=0;

    }

     

    int main(){

     

        init();//初始化数据

        SendData(0x00);//发送数据

        SendData(0x01);

        SendData(0x01);

        while(1){

           if(1==Received_Flag){//当单片机收到该数据后,将其送到数码管显示

               ES=0;//将串口接收总中断关闭,因为发送数据的时候,往缓冲区内写数据也会引发串口接收中断。

              

               ES=1;

               Received_Flag=0;

           }

           //在此数据前加上一序号然后连同此数据一起发送至计算机,当序号超过255时归零。

           DisplayNumByOrder(Data_Received);  //在数码管上显示

        }

        return0;

    }

     

    //========函数区结束============================================

     

     

    //========中断函数区============================================

     

    /**

        串口接收中断

    **/

    void ser_received() interrupt 4

    {

        RI=0;//RI=1代表缓冲区内有数据,清零以便等待下次数据到来

        Data_Received=(uchar)SBUF;  //从缓冲区内读取数据

        Received_Flag=1;  //设置已经接收到数据

        P1=~P1;

        ReceiveCount++;

    }

     

    //========中断函数区结束==========================================

     

     

     

     

    //乙机

    #include <reg51.h>

    #define uchar unsigned char

    #define uint unsigned int

    #define ulong unsigned long

    /**

    题目要求:  16进制发送一个0-65536之间的任一数,当单片机收到后在数码管上动态显示出来,波特率自定。

    **/

    /**

    步骤

    接线方式:

    1P0接数码管J12,实现段选

    2、译码器和数码管位选输入短接,J15+J16

    3P2用来控制译码器的输入

    4P1是串口接收中断的指示,P1+JP1

    5、本实验使用的晶振是11.0592

    **/

    //=========全局变量区============================================

    sbit high=P2^4;

    sbit mid=P2^3;

    sbit low=P2^2;

    uint code NumTable[]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f,0x77,0x7c,0x39,0x5e,0x79,0x71};//数字的编码

     

    uint Received_Flag=0;//用来标志是否接收到信号

    uchar ReceiveCount,DecodeCount,Data_Received=0;//ReceiveCount是已经接收的条数,DecodeCount是已经解析的数目,Data_Received是接收到的数据

    ulong NumToDisplay=0;

    //=========全局变量区结束========================================

     

     

     

    //========函数区开始============================================

    /**

        延时

    **/

    void delay_1ms(uint x){

        uint i=x;

        uint j;

        for(;i>0;--i){

           for(j=110;j>0;--j);

        }

    }

    /**

        在数码管上显示对应的值

    **/

    void display(uchar Num)

    {

        P0=NumTable[Num];

        delay_1ms(1);

        P0=0;      //送完段选信号后,进行消影的处理

    }

     

    /**

        控制数码管显示后3位,并分解计数值

    **/

    void DisplayNumByOrder(ulong Value){

           low=0; mid=0; high=0;  display(0);        

            low=1; mid=0; high=0;  display(0);               

            low=0; mid=1; high=0;  display(0);

           low=1; mid=1; high=0;  display(Value%100000/10000);

           low=0; mid=0; high=1;  display(Value%10000/1000);

           low=1; mid=0; high=1;  display(Value%1000/100);

           low=0; mid=1; high=1;  display(Value%100/10);

           low=1; mid=1; high=1;  display(Value%10);

    }

     

    void init(){      //初始化定时器T1和串口

        SCON =0x50;  //设置串口工作方式1,并打开接收中断

        TMOD =0x20;  //设置T1工作方式2

        PCON =0x00;  //设置SMOD为串口工作方式1

        TL1 =0xf4;      

        TH1 =0xf4;     //2400bps(11.0592MHZ的晶振)

        TR1 =1;      //开启时钟

        ES =1;           //开启串口中断允许

        EA =1;           //开启中断总允许

    }

    /**

        发送数据

    **/

    void SendData(uchar value){

        SBUF=value;

        while(!TI);

        TI=0;

    }

     

    int main(){

     

        init();//初始化数据

        while(1){

           if(1==Received_Flag){//当单片机收到该数据后,将其送到数码管显示

               ES=0;//将串口接收总中断关闭,因为发送数据的时候,往缓冲区内写数据也会引发串口接收中断。

               SendData(‘o’);

    SendData(‘k’);

               ES=1;

               Received_Flag=0;

           }

           //在此数据前加上一序号然后连同此数据一起发送至计算机,当序号超过255时归零。

           DisplayNumByOrder(NumToDisplay);   //在数码管上显示

        }

        return0;

    }

     

    //========函数区结束============================================

     

     

    //========中断函数区============================================

     

    /**

        串口接收中断

    **/

    void ser_received() interrupt 4

    {

        if(RI ==1){//接收到触发中断

           RI=0;//RI=1代表缓冲区内有数据,清零以便等待下次数据到来

           Data_Received=(uchar)SBUF;  //从缓冲区内读取数据

           Received_Flag=1;  //设置已经接收到数据

           if(DecodeCount==0){

               NumToDisplay=Data_Received;

               ++DecodeCount;

           }else{

               NumToDisplay =(NumToDisplay <<8)| Data_Received;//相当于原来的数乘以8,然后+现在的数

               DecodeCount++;

               if(DecodeCount ==3)                  //0..65536要接收6位的16进制

                  DecodeCount =0;

           }

           P1=~P1;

           ReceiveCount++;

        }

    }

    //========中断函数区结束==========================================

     

  • 相关阅读:
    SQLServer和Access数据传输简单总结
    Session 详解
    SQL日志文件过大问题的解决方法
    如何删除表中的重复记录?
    HDOJ 3711 Binary Number
    HDOJ 2022
    活动选择问题
    浮点数的比较
    HDOJ 2037
    找最长递增子数列
  • 原文地址:https://www.cnblogs.com/kissazi2/p/3174420.html
Copyright © 2011-2022 走看看