51单片机

51单片机是一种经典的8位微控制器,广泛应用于各种嵌入式系统开发中。它具有结构简单、可靠性高、价格低廉等特点,深受工程师和电子爱好者的喜爱。

51单片机的核心是一个8位的CPU,能够执行多种指令,完成数据处理和逻辑运算。它通常拥有多个I/O口,可用于连接外部设备,如传感器、显示器和驱动器等。这些I/O口既可以作为输入端,也可以作为输出端,具有较高的灵活性。

此外,51单片机还集成了多种功能模块,如定时器、中断系统和串行通信接口等。定时器可用于实现定时任务和计数功能;中断系统可以提高系统的响应速度和实时性;串行通信接口则方便与其他设备进行数据交换。

51单片机的开发环境相对成熟,有大量的开发工具和学习资料可供选择。它适用于多种应用场景,如家电控制、工业自动化、智能仪表等领域。无论是初学者入门学习,还是工程师进行项目开发,51单片机都是一个非常不错的选择。

串口介绍

概念

51单片机(如AT89C51、STC89C52等)通常内置一个全双工的串行通信接口(UART),用于与其他设备进行串行通信。

主要特性

  1. 工作模式

    • 模式0:同步移位寄存器模式(常用于扩展I/O)

    • 模式1:8位UART,波特率可变(最常用)

    • 模式2:9位UART,波特率固定

    • 模式3:9位UART,波特率可变

  2. 波特率

    • 常用波特率:1200, 2400, 4800, 9600, 19200, 38400, 57600, 115200等

    • 波特率由定时器1(通常)产生

硬件连接

51单片机串口引脚:
TXD(P3.1) -> 连接其他设备的RXD
RXD(P3.0) -> 连接其他设备的TXD
GND       -> 连接其他设备的GND

寄存器配置

  1. SCON寄存器:串口控制寄存器

  2. PCON寄存器:电源控制寄存器(包含波特率加倍位SMOD)

  3. 定时器1:用于波特率发生器

基本代码示例

#include <reg52.h>

void UART_Init(unsigned int baud) {
    TMOD = 0x20;    // 定时器1工作于模式2(8位自动重装)
    TH1 = 256 - (11059200/12/32)/baud; // 计算定时器重装值
    TL1 = TH1;
    TR1 = 1;        // 启动定时器1
    
    SM0 = 0;        // 串口工作模式1
    SM1 = 1;
    REN = 1;        // 允许接收
    EA = 1;         // 开总中断
    ES = 1;         // 开串口中断
}

void UART_SendByte(unsigned char dat) {
    SBUF = dat;
    while(!TI);     // 等待发送完成
    TI = 0;         // 清除发送中断标志
}

void UART_Interrupt() interrupt 4 {
    if(RI) {
        RI = 0;     // 清除接收中断标志
        // 处理接收到的数据(SBUF中)
    }
}

void main() {
    UART_Init(9600); // 初始化串口,波特率9600
    
    while(1) {
        UART_SendByte('A'); // 发送字符'A'
        // 其他操作...
    }
}

常见应用

  1. 与PC通信(通常需要USB转TTL模块)

  2. 单片机之间的通信

  3. 与蓝牙/WiFi模块通信

  4. 与GPS模块通信

  5. 与GSM模块通信

注意事项

  1. 确保通信双方的波特率设置一致

  2. 注意电平匹配(51是TTL电平,与RS232设备通信需要电平转换)

  3. 长距离通信建议使用RS485等差分信号

  4. 多设备通信时注意协议设计(如MODBUS)

proteus 串口仿真电路图 

#include <REGX52.H>

#include <REGX52.H>

void UartInit()		//9600bps@11.0592MHz
{
	PCON &= 0x7F;		//设置波特率不倍速
	SCON = 0x50;		//设置为8位数据,可变波特率
	TMOD &= 0x0F;		//清除定时器1模式位
	TMOD |= 0x20;		//设定定时器1为8位自动重装方式
	TL1 = 0xFD;			//设定定时初值
	TH1 = 0xFD;			//设定定时器重装值
	TR1 = 1;			//启动定时器1
	ET1 = 0;        	//禁止定时器1中断
	EA=1;				//开启总中断
	ES=1;				//开启串口中断
}

void UartSend(unsigned char byte) //发送函数
{
	SBUF = byte; //将要发送的数据写入SBUF
	while(TI == 0); //等待发送完成
	TI = 0; //发送完成后清零TI
}

// 串口发送字符串函数
void UART_SendString(char *str) {
    while (*str) { // 遍历字符串
        SBUF = *str++; // 将当前字符发送到串口缓冲区
        while (!TI);   // 等待发送完成
        TI = 0;        // 清除发送完成标志
    }
}
void UART_ISR() interrupt 4 //串口接收中断服务程序
{
	if(RI==1) //如果接收到数据
	{
		UartSend(SBUF); //将接收到的数据发送出去
		RI=0; //清零RI
	}
}

int main()
{
	UartInit(); //初始化串口
	UART_SendString("send message!!!");
	while(1)
	{
	
	}
}

实验现象

Logo

智能硬件社区聚焦AI智能硬件技术生态,汇聚嵌入式AI、物联网硬件开发者,打造交流分享平台,同步全国赛事资讯、开展 OPC 核心人才招募,助力技术落地与开发者成长。

更多推荐