欢迎光临散文网 会员登陆 & 注册

第11章-UART串口通信

2023-09-05 23:52 作者:feifeiluan2  | 我要投稿

总结:串口收+发,SCON=0x50;

串口只发送,SCON=0x40;

感谢在宋老师这儿,学会了,定时器,串口,中断等难点

//跟堂作业,软件模拟串口收发
#include <reg52.h>

typedef unsigned char u8;
typedef unsigned int u16;
typedef unsigned long u32;
typedef signed char i8;
typedef signed int i16;
typedef signed long i32;

sbit PIN_RXD = P3 ^ 0;
sbit PIN_TXD = P3 ^ 1;
sbit a = P2 ^ 4;//监视变量,逻辑分析仪抓波用

void ConfigUART(u16 buad);
void StartRXD();
void StartTXD(u8 dat);

bit RxdEnd;
bit TxdEnd;
u8 RxdBuf, TxdBuf;
bit RxdOrTxd = 0; // 0=res;1=sent

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

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

void ConfigUART(u16 buad)
{
    TMOD &= 0xF0; // T0,m2
    TMOD |= 0x02;

    TH0 = 256 - (11059200 / 12) / buad;
    //160
}

void StartRXD()
{
    TL0 = 256 - ((256 - TH0) >> 1) +40;//40是补偿值,通过逻辑分析仪测出来的
    ET0 = TR0 = 1;
    RxdEnd = 0;
    RxdOrTxd = 0;
}

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

void Timer0_ISR(void) interrupt 1
{
    static u8 cnt = 0;

    a=0;//监视变量,逻辑分析仪抓波用//进来拉低
    if (RxdOrTxd)
    {
        // sent
        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 == 0)
            {
                RxdBuf = 0;
                cnt++;
            }
        }
        else if (cnt <= 8)
        {
            RxdBuf >>= 1;
            if (PIN_RXD)
            {
                RxdBuf |= 0x80;
            }
            cnt++;
        }
        else
        {
            cnt = 0;
            TR0 = 0;
            if (PIN_RXD)
            {
                RxdEnd = 1;
            }
        }
    }

    a=1;//监视变量,逻辑分析仪抓波用//出去拉高
}



// 课后作业5和6合并完成
// pc发送hex数字:
// 1=流水灯流动(默认)
// 2=流水灯停止
// 3=蜂鸣器响
// 4=蜂鸣器关闭(默认)

#include <reg52.h>

typedef unsigned char u8;
typedef unsigned int u16;
typedef unsigned long u32;
typedef signed char i8;
typedef signed int i16;
typedef signed long i32;

sbit ADDR3 = P1 ^ 3;
sbit ENLED = P1 ^ 4;
sbit BEEP = P1 ^ 6;

#define SYS_CLK 11059200
#define TIMER_CLK (SYS_CLK / 12)

void ConfigTimer0(u8 ms);
void ConfigUART(u16 buad);

u8 TH0RL, TL0RL;

u8 LedBuf[8] = {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF};
u8 code LedChar[] = {
    0xC0, 0xF9, 0xA4, 0xB0, 0x99, 0x92, 0x82, 0xF8,
    0x80, 0x90, 0x88, 0x83, 0xC6, 0xA1, 0x86, 0x8E};
u8 code LedShift[14] = {0xFE, 0xFD, 0xFB, 0xF7, 0xEF, 0xDF, 0xBF, 0x7F, 0xBF, 0xDF, 0xEF, 0xF7, 0xFB, 0xFD};

bit ReceiveDatFlag = 0;
u8 ReceiveDat = 0;

bit EnLedShiftFlag = 1;
bit EnBeepFlag = 0;
bit Flag200ms = 0;

void main(void)
{
    int i;

    EA = 1;

    ENLED = 0;
    ADDR3 = 1;

    ConfigTimer0(1);
    ConfigUART(9600);

    while (1)
    {
        if (ReceiveDatFlag)
        {
            ReceiveDatFlag = 0;
            switch (ReceiveDat)
            {
            case 1:
                EnLedShiftFlag = 1; // 1=流水灯流动
                break;
            case 2:
                EnLedShiftFlag = 0; // 2=流水灯停止
                break;
            case 3:
                EnBeepFlag = 1; // 3=蜂鸣器响
                break;
            case 4:
                EnBeepFlag = 0; // 4=蜂鸣器关闭
                break;
            default:
                break;
            }
        }

        if (EnLedShiftFlag && Flag200ms)
        {
            Flag200ms = 0;
            LedBuf[6] = LedShift[i];
            if (++i >= 14)
            {
                i = 0;
            }
        }
        else
        {
            Flag200ms = 0;
        }
    }
}

void ConfigTimer0(u8 ms)
{
    u16 tmp;

    TMOD &= 0xF0;
    TMOD |= 0x01;
    tmp = TIMER_CLK * ms / 1000;
    tmp = 65536 - tmp;
    TH0 = TH0RL = (u8)(tmp >> 8);
    TL0 = TL0RL = (u8)tmp;

    ET0 = TR0 = 1;
}

void ConfigUART(u16 buad)
{
    SCON = 0x50;
    TMOD &= 0x0F; // T1
    TMOD |= 0x20;
    TH1 = TL1 = 256 - 11059200 / 12 / 32 / buad;

    ET1 = 0;
    TR1 = 1;

    ES = 1;
}

void LedScan(void)
{
    static u8 i = 0;

    P0 = 0xFF;
    P1 = (P1 & 0xF8) | i;
    P0 = LedBuf[i];
    i++;
    i &= 0x07;
}

void BeepScan(void)
{
    if (EnBeepFlag)
    {
        BEEP = !BEEP;
    }
    else
    {
        BEEP = 1;
    }
}

void Timer0_ISR(void) interrupt 1
{
    static u16 cnt = 0;

    TH0 = TH0RL;
    TL0 = TL0RL;

    if (++cnt >= 500)
    {
        cnt = 0;
        Flag200ms = 1;
    }

    BeepScan();
    LedScan();
}

void UART_ISR(void) interrupt 4
{
    if (RI)
    {
        RI = 0;
        ReceiveDat = SBUF;
        ReceiveDatFlag = 1;
    }
    if (TI)
    {
        TI = 0;
    }
}

第11章-UART串口通信的评论 (共 条)

分享到微博请遵守国家法律