1.8串行通信

2017-07-11  本文已影响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;         //清楚发送完毕标志位,已便于下次发送
    }
}
上一篇 下一篇

猜你喜欢

热点阅读