位序号 | D7 | D6 | D5 | D4 | D3 | D2 | D1 | D0 |
---|---|---|---|---|---|---|---|---|
位符号 | SM0 | SM1 | SM2 | REN | TB8 | RB8 | TI | RI |
– | 模式 | 模式 | 模式1直接清零 | 使能串口接收 | 模式1接收停止位 | 发送标志位,软件清零 | 接受标志位,软件清0 |
//不能位寻址
位序号 | D7 | D6 | D5 | D4 | D3 | D2 | D1 | D0 |
---|---|---|---|---|---|---|---|---|
位符号 | SM0 | SM1 | SM2 | REN | TB8 | RB8 | TI | RI |
– | 模式 | 模式 | 模式1直接清零 | 使能串口接收 | 模式1接收停止位 | 发送标志位,软件清零 | 接受标志位,软件清0 |
/* SCON */
sbit SM0 = SCON^7;
sbit SM1 = SCON^6;
sbit SM2 = SCON^5;
sbit REN = SCON^4;
sbit TB8 = SCON^3;
sbit RB8 = SCON^2;
sbit TI = SCON^1;
sbit RI = SCON^0;
SCON主要用模式1,的波特率
对应的,要用定时器T1&T2的模式2
TH1 = TL1 = 256 - 晶振值/12/2/16/波特率
(256是TL1的溢出值,12指12个时钟周期,16是硬件因素)
两个SBUF寄存器,分别负责接收和发送缓冲
配置串口为模式1
配置定时器T1为模式2
根据波特率计算TH0&TL0的值
配置PCON&SCON寄存器
打开定时器
UART串口传送数据示意图
挖坑:波特率&TH0是怎么算的?
#include
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 long baud);
void startRXD(void);
void startTXD(unsigned char dat);
void main(void)
{
EA = 1;
configUART(9600);
while(1)
{
while(PIN_RXD);
startRXD();
while(!RxdEnd);
startTXD(RxdBuf+1);
while(!TxdEnd);
}
}
void configUART(unsigned long baud)
{
TMOD &= ~(0xF<<0);
TMOD |= 0x1<<1;
TH0 = 256 - (11059200 / 12) / baud;
}
void startRXD(void)
{
TL0 = 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;
RxdEnd = 0;
RxdOrTxd = 1;
}
void timer0(void) 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_RXD)
{
RxdEnd = 1;
}
}
}
}
#include
void configUART(unsigned long baud);
void main(void)
{
configUART(9600);
while(!RI);
RI = 0;
SBUF = SBUF + 1;
while(!TI);
TI = 0;
}
void configUART(unsigned long baud)
{
SCON = 0x50;
TH1 = 256 - (11059200 / 12 / 2 / 16) / baud;
TL1 = TH1;
TMOD &= ~(0xF<<4);
TMOD |= 0x2<<4;
ET1 = 0;
TR1 = 1;
}
#include
void configUART(unsigned long baud);
void main(void)
{
EA = 1;
configUART(9600);
while(1);
}
void configUART(unsigned long baud)
{
SCON = 0x50;
TH1 = 256 - (11059200 / 12 / 2 / 16) / baud;
TL1 = TH0;
TMOD &= ~(0xF<<4);
TMOD |= 0x2<<4;
ET1 = 0;
ES = 1;
TR1 = 1;
}
void UART(void) interrupt 4
{
if(RI)
{
RI = 0;
SBUF = SBUF + 1;
}
if(TI)
{
TI = 0;
}
}
#include
sbit wei = P2^7;
sbit duan = P2^6;
unsigned char code weitable[6] =
{
~0x20,~0x10,~0x08,~0x04,~0x02,~0x01
};
unsigned char code duantable[16] =
{
0x3F,0x06,0x5B,0x4F,0x66,0x6D,0x7D,0x07,
0x7F,0x6F,0x77,0x7C,0x39,0x5E,0x79,0x71
};
unsigned char ledbuff[6] =
{
0x00,0x00,0x00,0x00,0x00,0x00
};
unsigned char T0RH = 0,T0RL = 0;
unsigned char RxdByte = 0;
void configtimer0(unsigned char ms);
void configUART(unsigned long baud);
void main(void)
{
EA = 1;
configtimer0(1);
configUART(9600);
while(1)
{
ledbuff[0] = duantable[RxdByte & 0x0F];
ledbuff[1] = duantable[RxdByte >> 4];
}
}
void configtimer0(unsigned char ms)
{
unsigned long tmp;
tmp = 11059200 / 12;
tmp = (tmp * ms) / 1000;
tmp = 65536 - tmp;
tmp = tmp + 12;
T0RH = (unsigned char)(tmp>>8);
T0RL = (unsigned char)tmp;
TH0 = T0RH;
TL0 = T0RL;
TMOD &= ~(0xF<<0);
TMOD |= 0x1<<0;
ET0 = 1;
TR0 = 1;
}
void configUART(unsigned long baud)
{
TH1 = 256 - (11059200 / 12 / 2 / 16) / baud;
TL1 = TH0;
SCON = 0x50;
TMOD &= ~(0xF<<4);
TMOD |= 0x2<<4;
ET1 = 0;
ES = 1;
TR1 = 1;
}
void ledscan(void)
{
static unsigned char i = 0;
P0 = 0x00;
duan = 1;
duan = 0;
P0 = weitable[i];
wei = 1;
wei = 0;
P0 = ledbuff[i];
duan = 1;
duan = 0;
if(i<5)
i++;
else
i = 0;
}
void timer0(void) interrupt 1
{
TH0 = T0RH;
TL0 = T0RL;
ledscan();
}
void UART(void) interrupt 4
{
if(RI)
{
RI = 0;
RxdByte = SBUF;
SBUF = RxdByte;
}
if(TI)
{
TI = 0;
}
}