串口实验
- 51单片机串口实验
- 1. 软硬件条件
- 2. 串口实验
- 2.1 单片机与PC 发送字符
- 2.1.1 效果
- 2.1.2 代码
- 2.1.3 优化
- 2.3 串口接收数据(指令控制单片机)
- 2.3.1 非中断方式实现
- 2.3.2 中断方式实现
51单片机串口实验
1. 软硬件条件
- 单片机型号:STC89C52RC
- 开发环境:KEIL4
- 烧录软件串口通信软件:stc-isp
2. 串口实验
实现单片机与PC 串口通信,能够通过PC 输入指令 控制单片机。
2.1 单片机与PC 发送字符
2.1.1 效果
2.1.2 代码
#include "reg52.h"
#include <intrins.h>
sbit testLed = P3^7;
sfr AUXR = 0x8E; // 屏蔽电磁干扰void UartInit(){PCON &= 0x7F; // 不倍速 不倍速甚至可以不用设置SCON = 0x40; // REN 不是能TMOD &= 0x0F;TMOD |= 0x20; // 8位自动重装TL1 = 0xFD; //设定定时初值TH1 = 0xFD; //设定定时器重装值ET1 = 0; // 禁止定时器1溢出申请中断EA = 1;TR1 = 1; //启动定时器1
}
void Delay1000ms() //@11.0592MHz
{unsigned char i, j, k;_nop_();i = 8;j = 1;k = 243;do{do{while (--k);} while (--j);} while (--i);
}
void init(){UartInit();testLed = 1;testLed = 0;Delay1000ms();}void main(){char msg = 'a';init();while(1){SBUF = msg; // 写入缓存区testLed = !testLed;Delay1000ms(); // 延迟用于 为传输数据预留时间}
}
2.1.3 优化
不采用延迟方式,采用标志位判断是否发送成功,并且发送字符串。
#include "reg52.h"
#include <intrins.h>
sbit testLed = P3^7;
sfr AUXR = 0x8E; // 屏蔽电磁干扰void UartInit(){PCON &= 0x7F; // 不倍速 不倍速甚至可以不用设置SCON = 0x40; // REN 不是能TMOD &= 0x0F;TMOD |= 0x20; // 8位自动重装TL1 = 0xFD; //设定定时初值TH1 = 0xFD; //设定定时器重装值ET1 = 0; // 禁止定时器1溢出申请中断EA = 1;ES = 1;TR1 = 1; //启动定时器1
}
void Delay1000ms() //@11.0592MHz
{unsigned char i, j, k;_nop_();i = 8;j = 1;k = 243;do{do{while (--k);} while (--j);} while (--i);
}
void init(){UartInit();testLed = 1;testLed = 0;Delay1000ms();}void sendByte(char msg){SBUF = msg;while(!TI);TI = 0;
}void sendString(char *str){while(*str!='\0'){sendByte(*str);str++;}
}
void main(){init();while(1){sendString("hello world\r\n");testLed = !testLed;Delay1000ms();}
}
2.3 串口接收数据(指令控制单片机)
2.3.1 非中断方式实现
主要时查询法检测RI标志位是否被置1 ,注意软件置0.
#include "reg52.h"
#include <intrins.h>
sbit testLed = P3^7;
sfr AUXR = 0x8E; // 屏蔽电磁干扰
char cmd;void UartInit(){PCON &= 0x7F; // 不倍速 不倍速甚至可以不用设置SCON = 0x50;TMOD &= 0x0F;TMOD |= 0x20; // 8位自动重装TL1 = 0xFD; //设定定时初值TH1 = 0xFD; //设定定时器重装值ET1 = 0; // 禁止定时器1溢出申请中断EA = 1;ES = 1;TR1 = 1; //启动定时器1
}void Delay1000ms() //@11.0592MHz
{unsigned char i, j, k;_nop_();i = 8;j = 1;k = 243;do{do{while (--k);} while (--j);} while (--i);
}void sendByte(char msg){SBUF = msg;while(!TI);TI = 0; // 只是中断标志 但是没有中断函数 则不会触发中断 有中断函数时需要及时置0
}void sendString(char *str){while(*str!='\0'){sendByte(*str);str++;}
}
void init(){UartInit();testLed = 0;Delay1000ms();}void main(){init();while(1){ if(RI){cmd = SBUF;if(cmd == 'o'){testLed = 0;}else if(cmd == 'c'){testLed = 1;}RI= 0;}}
}
2.3.2 中断方式实现
#include "reg52.h"
#include <intrins.h>
#include <string.h>
#define SIZE 3
sbit testLed = P3^7;
sbit testLed2 = P3^6;
sfr AUXR = 0x8E; // 屏蔽电磁干扰
char cmd[SIZE];void UartInit(){PCON &= 0x7F; // 不倍速 不倍速甚至可以不用设置SCON = 0x50;TMOD &= 0x0F;TMOD |= 0x20; // 8位自动重装TL1 = 0xFD; //设定定时初值TH1 = 0xFD; //设定定时器重装值ET1 = 0; // 禁止定时器1溢出申请中断EA = 1;ES = 1;TR1 = 1; //启动定时器1
}void Delay1000ms() //@11.0592MHz
{unsigned char i, j, k;_nop_();i = 8;j = 1;k = 243;do{do{while (--k);} while (--j);} while (--i);
}void sendByte(char msg){SBUF = msg;while(!TI);TI = 0; // 只是中断标志 但是没有中断函数 则不会触发中断 有中断函数时需要及时置0
}void sendString(char *str){while(*str!='\0'){sendByte(*str);str++;}
}void init(){UartInit();testLed = 0;testLed2 = 1;Delay1000ms();}void main(){init();while(1){ sendString("Hello World!\r\n");testLed = !testLed;Delay1000ms();}
}void UartHandler() interrupt 4{static int i = 0;char tmp;if(RI){RI = 0;tmp = SBUF;if(tmp == 'o' || tmp == 'c'||i==SIZE){i = 0;}cmd[i++] = tmp;if(cmd[0] == 'o' && cmd[1] == 'p'){testLed2 = 0;memset(cmd,'\0',SIZE);}if(cmd[0] == 'c' && cmd[1] == 'l'){testLed2 = 1;memset(cmd,'\0',SIZE);}}if(TI);}