51单片机串口通信

发布时间:2026/7/21 22:47:14
51单片机串口通信 串口发送功能的实现一、配置SCON串行口控制寄存器1.REN:允许/禁止串口接收控制位2.SM00、SM11选择通讯方式一3.TI0、RI0发送接收中断标志位每次发送后必须手动清零二、配置PCON电源控制寄存器SMOD:波特率选择位SMOD1使方式一二三波特率加倍默认为0波特率越低 越稳定、越抗干扰、越不容易出错但速度越慢三、配置定时器串口发送时中断不需要配置只需要配置定时器1并选择波特率串口需要八位自动重装不再是十六位65535因为十六位要每次赋初值会占用时间导致误差串口通信要双八位更精准计数值变为0-255256次计数255后还要加一位才溢出1.在这里我们先对特殊功能寄存器TMOD高四位清零低四位置默认TMOD0x0F再设置高四位GATE0C/~T0M1、M010八位重装模式TMOD|0x202.然后再设置定时器初值和是否倍速波特率这里选倍速也就是PCON | 0x80然后我们这里是八位自动重装模式不需要每次溢出重新赋初值只需要把高低位都设置成我们的初值就好TL10xF4;TH10xF4;波特率计算我们这里初值为0xF4,换算为十进制就是244256-24412也就是每次溢出经过12次计数12个1.085us每次溢出时间12*1.08506944413.020833328溢出率1/每次溢出时间0.07680000003145728MHZ注意我们这里是波特率倍速所以不用除2直接除16就好波特率溢出率/164800.00000196608HZ≈4800HZ是不是几乎没有误差如果是12MHZ晶振就会算出是4807.69MHZ,而且波特率越高误差就会越大3.ET10;禁止定时器中断这里不需要4.TR11:启动定时器1void Uart1_Init(void) //4800bps11.0592MHz { PCON | 0x80; //使能波特率倍速位SMOD SCON 0x50; //8位数据,可变波特率 AUXR 0xBF; //定时器时钟12T模式 AUXR 0xFE; //串口1选择定时器1为波特率发生器 TMOD 0x0F; //设置定时器模式 TMOD | 0x20; //设置定时器模式 TL1 0xF4; //设置定时初始值 TH1 0xF4; //设置定时重载值 ET1 0; //禁止定时器中断 TR1 1; //定时器1开始计时 }当然也可以使用STC-ISP的波特率计算器自动生成初始化代码连配置都省了四、串口发送函数我们直接将数据写入SBUF即可在写入后加上whlie判断检测发送是否完成防止一直发送卡住在发送后手动将发送标志位TI清零//串口发送一个字节数据范围0-255 void UART_SendByte(unsigned char Byte) { SBUFByte; //写入SBUF实现数据发送 while(TI0); //发送结束检测防卡死 TI0; //发送检测位清零 }五、主函数调用当我们需要连续发送信息时在while循环中调用的时候要每次发送后延时否则会由于发送过快发送错误信息比如从66变为99要想控制信息发送速度也可以通过延时函数粗略控制void main() { Uartl Init (); //初始化 while(1) { UART_SendByte (0x66); //串口发送函数 Delay100; //延时防止连续发送过快产生发送乱码 } }程序编译烧录后打开串口选择HEX模式可以看到如果我们选择文本模式那么显示的就会是数字编码后也就是字符原本的样子六、串口发送模块化串口发送可以模块化为.c.h文件方便以后调用记得养成注释的好习惯但是接下来讲的接收中断依赖于串口中断和主函数耦合性较强就没法模块化了串口接收功能的实现一、串口初始化其他都和发送一样只需要改动几个点1.确保串口接收使能位为打开状态SCON的第四位置1也就是让SCON0x50其实我们在发送时也是打开的这里就不用改了2.打开串口中断EA1(启动中断总开关),ES1(打开串口中断)void Uart1_Init(void) //4800bps11.0592MHz { PCON | 0x80; //使能波特率倍速位SMOD SCON 0x50; //8位数据,可变波特率 AUXR 0xBF; //定时器时钟12T模式 AUXR 0xFE; //串口1选择定时器1为波特率发生器 TMOD 0x0F; //设置定时器模式 TMOD | 0x20; //设置定时器模式 TL1 0xF4; //设置定时初始值 TH1 0xF4; //设置定时重载值 ET1 0; //禁止定时器中断 TR1 1; //定时器1开始计时 EA1; ES1; //接收数据需要开启中断 }二、中断函数我们在技术手册查询到中断号小尾巴为interrupt 4那中断函数我们命名为void UART_Routine()interrupt 4函数名可以随便起只要带上空格中断号小尾巴就是中断函数啦主函数空循环即可这样我们就实现了电脑命令控制LED了void UART_Routine() interrupt 4 //中断函数头 { if(RI1) //发送完成进入后续 { P2SBUF; //使用串口写入SBUF的数据控制LED发送需要手动写入SBUF,接收时电脑会直接写入不需要我们操作 UART_SendByte(SBUF); //在中断里将串口收到的数据发出 RI0; //将接收检测位手动置零发送位我们在函数中置零就好啦 } }