登录  | 立即注册

游客您好!登录后享受更多精彩

扫一扫,访问微社区

QQ登录

只需一步,快速开始

开启左侧

[寒假笔记] UART串口通信

[复制链接]
发表于 2021-1-22 20:10:17 | 显示全部楼层 |阅读模式
学习笔记
学习科目: 单片机
学习安排: 复习熟悉开发板后,开始学习新的课程。
开始时间: 2021-01-22
结束时间: 2021-01-29
本帖最后由 机械学院杨义驰 于 2021-1-29 20:58 编辑

2021-01-22

  今天主要学习了解了串口通信的基本原理,了解了USB串口等串口电路的工作原理。
  其次,也通过学习了解了起始位与停止位在通信中的作用。
# include<reg52.h>


sbit PIN_RXD = P3^0;
sbit PIN_TXD = P3^1;


bit RxdOrTxd = 0;
bit RxdEnd = 0;
bit TxdEnd = 0;
unsigned char RxdBuf = 0;
unsigned char TxdBuf = 0;


void ConfigUART(unsigned int baud);
void StartTXD(unsigned char dat);
void StartRXD();


void main()
{
    EA = 1;
        ConfigUART(9600);


        while (1)
        {
            while (PIN_RXD);
                StartRXD();
                while (!RxdEnd);
                StartTXD(RxdBuf+1);
                while (!TxdEnd);
        }
}


void ConfigUART(unsigned int baud)
{
    TMOD &= 0xF0;
        TMOD |= 0x02;
        TH0 = 256 - (32768000/12)/baud;
}


void StartRXD()
{
    TH0 = 256 - ((256-TH0)>>1);
        ET0 = 1;
        TR0 = 1;
        RxdEnd = 0;
        RxdOrTxd = 0;
}


void StartTXD(unsigned char dat)
{
    TxdBuf = dat;
        TL0 = TH0;
        ET0 = 1;
        TR0 = 1;
        PIN_TXD = 0;
        TxdEnd = 0;
        RxdOrTxd = 1;
}


void InterruptTimer0() interrupt 1
{
    static unsigned char cnt = 0;


        if (RxdOrTxd)
        {
            cnt++;
                if (cnt <= 8)
                {
                    PIN_TXD = TxdBuf & 0x01;
                        TxdBuf >>= 1;
                }
                else if (cnt == 9)
                {
                    PIN_TXD = 1;
                }
                else
                {
                    cnt = 0;
                        TR0 = 0;
                        TxdEnd = 1;
                }
        }
        else
        {
            if (cnt == 0)
                {
                    if (!PIN_RXD)
                        {
                            RxdBuf = 0;
                                cnt++;
                        }
                        else
                        {
                            TR0 = 0;
                        }
                }
                else if (cnt <= 8)
                {
                    RxdBuf >>= 1;
                        if (PIN_RXD)
                        {
                            RxdBuf |= 0x80;
                        }
                        cnt++;
                }
                else
                {
                    cnt = 0;
                        TR0 = 0;
                        if (PIN_TXD)
                        {
                            RxdEnd = 1;
                        }
                }
        }
}



2021-1-24

昨天所写的程序在实际操作中存在许多的问题,如:电脑上所接收到的数据并非“发送数据+1”、只能发送接收一次数据等。
经过电路、程序等多方向的排除,问题仍是没有解决,最后锁定在晶振上,可能是由于“(32768000/12)baud”的结果为小数而非整数,有待于进一步的学习。
今天接着往下学习了:
      1.通信的三种基本类型:单工、半双工、全双工。
      2.UART模块介绍
       其中UART模块只能用T1定时器进行定时,且其重载值由固定的公式进行讲算,并注意使用“ES”使能串口中断。

2021-1-25
今天继续学习串口通信:
# include<reg52.h>


void ConfigUART(unsigned int baud);


void main()
{
    ConfigUART(9600);


        while(1)
        {
            while(!RI);
                RI = 0;
                SBUF = SBUF + 1;
                while(!TI);
                TI = 0;
        }
}


void ConfigUART(unsigned int baud)
{
    SCON = 0x50;
        TMOD &= 0x0F;
    TMOD |= 0x20;
        TH1 = 256 - (32768000/12/32)/baud;
        TL1 = TH1;
        TR1 = 1;
        ET1 = 0;
}




经过改进得:
# include<reg52.h>


void ConfigUART(unsigned int baud);


void main()
{
    EA = 1;
        ConfigUART(9600);
        while(1);
}


void ConfigUART(unsigned int baud)
{
    SCON = 0x50;
        TMOD &= 0x0F;
        TMOD |= 0x20;
        TH1 = 256 - (32768000/12/32)/baud;
        TL1 = TH1;
        TR1 = 1;
        ET1 = 0;
        ES = 1;
}


void InterruptUART() interrupt 4
{
    if(RI)
        {
            RI = 0;
                SBUF = SBUF + 1;
        }
        if(TI)
        {
            TI = 0;
        }
}
课后作业:
  用UART串口来控制流水灯的启停:
# include<reg52.h>


sbit ENLED = P1^1;


unsigned char RxdByte = 0;
unsigned char T0RH = 0;
unsigned char T0RL = 0;


void ConfigTimer0(unsigned int ms);
void ConfigUART(unsigned int baud);
void StartLed();
void StopLed();


void main()
{
    EA = 1;
        ENLED = 0;


        ConfigTimer0(1);
        ConfigUART(9600);


        while(1)
        {
            if(RxdByte == 1)
                {
                    StartLed();
                }
                if(RxdByte == 0)
                {
                    StopLed();
                }
        }
}


void ConfigTimer0(unsigned int ms)
{
    unsigned long tmp = 0;


        tmp = 3276800 / 12;
        tmp = (3276800 * ms) / 1000;
        tmp = 65536 - tmp;
        tmp = tmp + 13;
        T0RH = (unsigned char)(tmp >> 8);
        T0RL = (unsigned char)tmp;
        TH0 = T0RH;
        TL0 = T0RL;
        TMOD &= 0xF0;
        TMOD |= 0x01;
}


void ConfigUART(unsigned int baud)
{
    SCON = 0x50;
        TMOD &= 0x0F;
        TMOD |= 0x20;
        TH1 = 256 - (32768000 / 12 / 32) / baud;
        TL1 = TH1;
        ET1 = 0;
        ES  = 1;
        TR1 = 1;
}


void StartLed()
{
    P2 = (P2 & 0xF8) | 6;
        ET0 = 1;
        TR0 = 1;
}


void StopLed()
{
    ET0 = 0;
        TR0 = 0;
}


void FlowLed()
{
    static unsigned char cnt = 0;
    static unsigned int flag1s = 0;


        flag1s++;
        if(flag1s == 1000)
        {
            P0 = ~(0x80 >> cnt);
                cnt++;
                if(cnt >= 8)
                {
                    cnt = 0;
                }
        }
}


void InterruptTimer0() interrupt 1
{
    TH0 = T0RH;
        TL0 = T0RL;
        FlowLed();
}


void InterruptUART() interrupt 4
{
    if(RI)
        {
            RI = 0;
                RxdByte = SBUF;
                SBUF = RxdByte;
        }
        if(TI)
        {
            TI = 0;
        }
}




好懒~~不想说~~~
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

Powered by Discuz! X3.4

Copyright © 2001-2020, Tencent Cloud.

快速回复 返回顶部 返回列表