美文网首页
1.8串行通信

1.8串行通信

作者: 忘川止 | 来源:发表于2017-07-11 18:38 被阅读0次

    串行和并行

    Paste_Image.png

    异步和同步



    a = SBUF SBUF发送
    SBUF=a SBUF接受 计算机接受

    串行口控制寄存器SCON

    串口中断

    波特率


    不用软件重装,可以定时更短的时间

    举个例子:
    要9600的波特率 方式1


    初值设为FD

    流程

    例子:

    #include<reg52.h>
    #define uchar unsigned char
    #define uint unsigned int
    
    uchar num;
    void delay(uint z)
    {
        uint x,y;
        for(x=z;x>0;x--)
            for(y=114;y>0;y--);
    }
    
    void UART_init()
    {
        TMOD=0x20; //定时器1,工作模式2,八位自动重装
        TH1 = 0xfd;
        TL1 = 0xfd;
        TR1 = 1;
        SM0 = 0;
        SM1 = 1; //工作方式1 10位异步
        REN = 1; //串口允许接受
        
    }
    
    int main()
    {
        UART_init();
        while(1)
        {   
            while(1)
            {
                while(!RI);
                P1 = SBUF;
                RI = 0;
            }
            //SBUF = num; //    串口的发送电脑接受
            /*while(!TI); //查询是否发送完
            TI = 0;
            num++;//从0-256
            delay(500);  */
                
        }
        return 0;
    }
    

    注意发送和接受是真对板子的
    我们写的程序,RI检测是否板子接受完
    P1= SBUF P1接受SBUF的数据

    中断写法:

    #include<reg52.h>
    #define uchar unsigned char
    #define uint unsigned int
    
    uchar num;
    
    void UART_init()
    {
        TMOD=0x20; //定时器1,工作模式2,八位自动重装
        TH1 = 0xfd;
        TL1 = 0xfd;
        TR1 = 1;   //启动T1计时器
        SM0 = 0;
        SM1 = 1; //工作方式1 10位异步
        REN = 1; //串口允许接受
    
        EA = 1;
        ES = 1; //开总中断和串口中断
        
    }
    
    int main()
    {
        UART_init();
        while(1)
        {       
        }
        return 0;
    }
    
    void UART() interrupt 4
    {
        //内部查询优先级是4
        if(RI)
        {
            num = SBUF;     //  接受SBUF
            P1 = SBUF;    //点亮流水灯
            num++;  //+1
            RI = 0; //将RI置0
            SBUF = num; //发送num
            while(!TI)       
            {
                TI = 0;
            }
        }
    }
    

    功能发送一个数 , 加1后返回来

    Paste_Image.png

    SBUF = x 将单片机中的数据x 发送到SBUF

    x = SBUF 单片机接受SBUF

    练习:

    1. 以4800bps从计算机发任意一字节数据,通过数码管以十进制显示

    的形式显示出来。

    #include<reg52.h>
    #define uint unsigned int
    #define uchar unsigned char
    uchar x;
    sbit we = P2^7;
    sbit du = P2^6;
    void delay(uint z)
    {
        uint x,y;
        for(x=z;x>0;x--)
            for(y=114;y>0;y--);
    }
    
    uchar code leddata[]={ 
     
                    0x3F,  //"0"
                    0x06,  //"1"
                    0x5B,  //"2"
                    0x4F,  //"3"
                    0x66,  //"4"
                    0x6D,  //"5"
                    0x7D,  //"6"
                    0x07,  //"7"
                    0x7F,  //"8"
                    0x6F,  //"9"
                    0x77,  //"A"
                    0x7C,  //"B"
                    0x39,  //"C"
                    0x5E,  //"D"
                    0x79,  //"E"
                    0x71,  //"F"
                    0x76,  //"H"
                    0x38,  //"L"
                    0x37,  //"n"
                    0x3E,  //"u"
                    0x73,  //"P"
                    0x5C,  //"o"
                    0x40,  //"-"
                    0x00,  //熄灭
                    0x00  //自定义
     
                             };
    
    void UART_init() 
    {
        TMOD = 0x20;
        TH1 = 0xfa;
        TL1 = 0xfa;
        TR1 = 1;
        SM0 = 0;
        SM1 = 1;
        REN = 1;
    
    }
    
    void display(uchar num)
    {
        uchar bai,shi,ge;
        bai = num / 100; //求模
        shi = num % 100 / 10; //求余100后求出有多少个10 
        ge  = num % 10; //求余
        
        P0 = 0xff;  //清除断码
        we = 1;
        P0 = 0xfe;  //点亮第一位数码管
        we = 0;
    
        du = 1;
        P0 = leddata[bai];  //显示百位
        du = 0;
        delay(1);
    
        P0 = 0xff;  //清除断码
        we = 1;
        P0 = 0xfd;//点亮第二位数码管
        we = 0;
    
        du = 1;
        P0 = leddata[shi];  //显示十位
        du = 0;
        delay(1);
    
        P0 = 0xff;  //清除断码
        we = 1;
        P0 = 0xfb;//点亮第三位数码管
        we = 0;
    
        du = 1;
        P0 = leddata[ge];  //显示各位
        du = 0;
        delay(1);
    }
    
    int main()
    {
        UART_init();
        while(1)
        {
            if(RI)
            {
                RI=0;
            }
            x = SBUF;
            display(x);
        }
    }
    

    2. 把矩阵键盘的键值以2400bps上传到计算机串口助手

    #include <reg52.h>
    
    #define uchar unsigned char
    #define uint  unsigned int
    
    /*1毫秒延时函数*/
    void delay(uint z)  
    {
        uint x,y;
        for(x = z; x > 0; x--)
            for(y = 114; y > 0 ; y--);
    }
    
    /*
    串口初始化函数
    工作模式1 10位异步收发 发送速率2400bps
    */
    void UART_init()  
    {
        TMOD = 0x20;    //T1工作模式2  8位自动重装
        TH1 = 0xf4;
        TL1 = 0xf4;     //比特率2400,计算公式256-11059200/2400/32/12
        TR1 = 1;        //启动T1定时器
        SM0 = 0;
        SM1 = 1;        //串口工作方式1 10位异步
    //  REN = 1;        //串口允许接收
    }
    
    /*
        4*4矩阵键盘扫描函数
        带返回值,返回键值码
    */
    uchar KeyScan()
    {
        uchar cord_l,cord_h;//声明列线和行线的值的储存变量
        P3 = 0xf0;//1111 0000
        if( (P3 & 0xf0) != 0xf0)//判断是否有按键按下
        {
            delay(5);//软件消抖
            if( (P3 & 0xf0) != 0xf0)//判断是否有按键按下
            {
                  cord_l = P3 & 0xf0;// 储存列线值
                  P3 = cord_l | 0x0f;
                  cord_h = P3 & 0x0f;// 储存行线值
                  while( (P3 & 0x0f) != 0x0f );//松手检测
                  return (cord_l + cord_h);//返回键值码
            }   
        }
            
    }
    
    /*
        4*4矩阵键盘键值码处理函数
        返回转换后的键值码
    */
    uchar KeyPro()
    {
        uchar key_value; //存放转换后的按键值
        switch( KeyScan() )
        {
            //第一行键值码
            case 0xee: key_value = 0x01;        break;
            case 0xde: key_value = 0x02;        break;
            case 0xbe: key_value = 0x03;        break;
            case 0x7e: key_value = 0x04;        break;
            
            //第二行键值码
            case 0xed: key_value = 0x05;        break;
            case 0xdd: key_value = 0x06;        break;
            case 0xbd: key_value = 0x07;        break;
            case 0x7d: key_value = 0x08;        break;
    
            //第三行键值码
            case 0xeb: key_value = 0x09;        break;
            case 0xdb: key_value = 0x0a;        break;
            case 0xbb: key_value = 0x0b;        break;
            case 0x7b: key_value = 0x0c;        break;
    
            //第四行键值码
            case 0xe7: key_value = 0x0d;        break;
            case 0xd7: key_value = 0x0e;        break;
            case 0xb7: key_value = 0x0f;        break;
        case 0x77: key_value = 0x10;        break;
        }
        return (key_value);//返回转换后的键值码  
    }
    
    
    void main()
    {
        UART_init();//串口初始化
        while(1)
        {
            SBUF = KeyPro();//调用带返回值的键值码转换函数,把转换后的键值码送入发送SBUF
            while(!TI);     //检测是否发送完毕
            TI = 0;         //清楚发送完毕标志位,已便于下次发送
        }
    }
    

    相关文章

      网友评论

          本文标题:1.8串行通信

          本文链接:https://www.haomeiwen.com/subject/tkjmhxtx.html