本帖最后由 Cool_Breeze 于 2022-4-24 21:51 编辑
到现在还是不能完全理解串口波特率计算公式。
[C] 纯文本查看 复制代码 #include<reg52.h>
#include<intrins.h>
typedef unsigned char u8;
typedef unsigned int u16;
sbit SER = P3^4;
sbit ORCLK = P3^5;
sbit SRCLK = P3^6;
sbit LED3 = P2^2;
sbit LED1 = P2^0;
sbit LED2 = P2^1;
void delay(u16 i){
while(i--);
}
// 256 - (11059200 / 12 * (2^1[2^SMOD]/32)[0.0625] / 19200(波特率))
// u8 BPS = 0XFD; // 波特率 19200
static u8 BPS = 256 - 57600 / 19200;
u8 Record[16]; // 收到数据命令缓存区
u8 RIndex = 0; // 缓冲区下标
u8 Gan[] = {0x00, 0x40, 0xff, 0x49, 0x49, 0xff, 0x40, 0x00};
// 以换行符为命令结束标志
// 有返回 1
// 无返回 0
u8 CheckActionFlag(void){
u8 i;
for (i=0; i<16; i++){
if (Record[i] == 0X0A) return 1;
}
return 0;
}
// 判断字符串相等
// 相等返回 1
// 不相等返回 0
u8 Equal(const char *s1, const char *s2, u8 count){
u8 i = 0;
while(i<count){
if (*(s1++) != *(s2++)) return 0;
i++;
}
return 1;
}
// 匹配命令做出相应动作
// 成功返回 1
// 失败返回 0
u8 MatchAction(void){
u8 i;
u8 f = 0;
if (Equal(Record, "LED1", 4)){
LED1 = ~LED1; f = 1;
}
else if (Equal(Record, "LED2", 4)){
LED2 = ~LED2; f = 1;
}
for (i=0; i<16; i++, Record[i] = 0X00); // 清空缓冲区
RIndex = 0; // 回到开始
return f ? 1:0;
}
// 发送字符串
void Send(const char *dat, u8 count){
u8 i = 0;
ES = 0; // 关闭串口中断,使发送数据一次性完成
for (i=0; i<count; i++){
SBUF = *(dat+i);
while (!TI);
TI = 0;
}
SBUF = 0X0A;
while (!TI);
TI = 0;
ES = 1; // 开启串口中断
}
// t0计时器初始化
void Timer0Init(void){
TMOD |= 0x01;
TH0 = 0x3C;
TL0 = 0xB0;
ET0 = 1;
EA = 1;
TR0 = 1;
}
// t1计时器初始化
void Timer1Init(void){
TMOD |= 0x20; // 定时器工作方式 0010 2 : GATE 0 软件启动定时器 C/T 0 计时模式 M1 1 M0 0 工作方式 2
TH1 = BPS; // 自动填充数值
TL1 = BPS; // 设置定时器溢出值 每溢出一次就发送一个 bit
//ET1 = 1; // 关闭计时器的中断,因为用不到,提高效率(开启后反而影响单片机性能)
EA = 1; // 中断中开关
TR1 = 1; // 启动定时 1
}
// 串口初始化
void UsartInit(void){
Timer1Init();
SCON = 0X50; // SM0 0 SM1 10位异步收发器(8位数据位)方式 1 SM2 0 REN 1 软件设置接收数据
PCON |= 0X80; // 波特率倍增 SMOD = 1( 2 / 32 ) SMOD = 0( 2 / 64 )
ES = 1; // 串口中断开
EA = 1;
}
// 向芯片发送数据
void HC595SendByte(u8 dat){
u8 i;
SRCLK = 0;
ORCLK = 0;
for(i=0; i<8; i++){
SER = dat >> 7;
dat <<= 1;
SRCLK = 1;
_nop_(); // wait ic move bit
_nop_();
SRCLK = 0;
}
ORCLK = 1;
_nop_();
_nop_();
ORCLK = 0;
}
void main(){
u8 i;
Timer0Init();
UsartInit();
while (1){
for (i=1; i<9; i++){
switch(i){
case 1: P0 = 0x7f;break;
case 2: P0 = 0xbf;break;
case 3: P0 = 0xdf;break;
case 4: P0 = 0xef;break;
case 5: P0 = 0xf7;break;
case 6: P0 = 0xfb;break;
case 7: P0 = 0xfd;break;
case 8: P0 = 0xfe;break;
}
HC595SendByte(Gan[i-1]);
delay(100);
HC595SendByte(0x00); // off led
delay(10);
}
if (CheckActionFlag()){
if(MatchAction()){
Send("OK", 2);
}
}
}
}
// t0中断处理器
void Timer0B() interrupt 1{
static u8 ms50 = 0;
TH0 = 0x3C;
TL0 = 0xB0;
ms50++;
if (ms50 == 20){
ms50 = 0;
LED3 = ~LED3;
}
}
// 串口中断处理器
void UsartProcess() interrupt 4{
if (RIndex >= 16) RIndex = 0;
Record[RIndex] = SBUF;
while (!RI);
RI = 0;
RIndex++;
} |