第11章-UART串口通信
总结:串口收+发,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;
}
}