如何驱动51单片机串口(uart通信)

如何驱动51单片机串口(uart通信)

使用51单片机上uart通信的驱动程序,软件特性可以在proteus上仿真,使用51单片机定时器T1溢出率做uart波特率时基,采用12MHz晶振,uart波特率采用4800。下面直接上代码:

uart驱动接口

uart模块向外提供的接口,主要是用于初始化uart和发送数据的接口。

void uart_init(void);  // 初始化串口
void uart_deinit(void);  // 串口去初始化
void uart_send_data(u8 dat);  // 串口发送
void uart_send_num(s32 num);  // 串口发送数字
void uart_send_str(string str);  // 串口发送字符串
u32 uart_str_to_num(string str);  // 字符串转数字
void test_uart(void);  // uart测试代码

初始化uart

51单片机采用12MHz晶振,设置uart异步通信,无校验,停止位1位,波特率4800。定时器工作在方式二,计时溢出后自动重载初值。

/*******************************************************************************
* 函 数 名         : uart_init
* 函数功能         : 初始化串口
* 输    入         : void
* 输    出         : void
* 说    名         : none
*******************************************************************************/
void uart_init(void)  // 初始化串口
{
    SCON = 0x50;  // 设置为工作方式1
    TMOD |= 0x20;  // 设置计数器工作方式2
    PCON = 0x80;  // 波特率加倍
    TH1 = 0xf3;   // 计数器初始值设置,波特率4800
    TL1 = 0xf3;
    IE |= 0x90;   // 打开接收中断
    TR1 = 1;  // 打开计数器
}

uart发送数据

uart发送一个字节的数据。此函数接口是实现发送字符串和数字的基础。

/*******************************************************************************
* 函 数 名         : uart_send_data
* 函数功能         : 串口发送
* 输    入         : dat:待发数据
* 输    出         : void
* 说    名         : none
*******************************************************************************/
void uart_send_data(u8 dat)  // 串口发送
{
    SBUF = dat;          // 将数据放入到发送寄存器
    while(!TI);          // 等待发送数据完成
    TI = 0;              // 清除发送完成标志位
}

uart发送数字

uart发送数字,现将数字编码为ascii码,在通过uart_send_data接口送出。

/*******************************************************************************
* 函 数 名         : uart_send_num
* 函数功能         : 串口发送数字
* 输    入         : num:数字
* 输    出         : void
* 说    名         : none
*******************************************************************************/
void uart_send_num(s32 num)  // 串口发送数字
{
    u8 i;
    u8 dat[10] = { 0 };  // 不能使用malloc

    if (num < 0) {
        uart_send_data('-');
        num = -num;
    }
    for (i = 0; num; i++) {
        dat[i] = (num % 10 + '0');
        num /= 10;
    }
    for (; i; i--) {
        uart_send_data(dat[i - 1]);
    }
}

uart发送字符串

依次调用uart_send_data即可。

/*******************************************************************************
* 函 数 名         : uart_send_str
* 函数功能         : 串口发送字符串
* 输    入         : str:字符串
* 输    出         : void
* 说    名         : none
*******************************************************************************/
void uart_send_str(string str)  // 串口发送字符串
{
    for (; (*str) != '\0'; str++) {
        uart_send_data(*str);
    }
}

字符串转数字

将字符串装换为数字返回。

/*******************************************************************************
* 函 数 名         : uart_str_to_num
* 函数功能         : 字符串转数字
* 输    入         : str:字符串
* 输    出         : u32:转换结果
* 说    名         : none
*******************************************************************************/
u32 uart_str_to_num(string str)  // 字符串转数字
{
    u32 num = 0;

    for (; (*str) != '\0'; str++) {
        if (((*str) >= '0') && ((*str) <= '9')) {
            num = num * 10 + ((*str) - '0');
        } else {
            break;
        }
    }

    return num;
}

附录 - uart驱动(uart.h)

#ifndef __UART_H__
#define __UART_H__

#include "include.h"

#define START_MARK ':'   // 指令结束标记

void uart_init(void);  // 初始化串口
void uart_deinit(void);  // 串口去初始化
void uart_send_data(u8 dat);  // 串口发送
void uart_send_num(s32 num);  // 串口发送数字
void uart_send_str(string str);  // 串口发送字符串
void uart_send_time(void);  // 串口发送本地时间
u32 uart_str_to_num(string str);  // 字符串转数字
void test_uart(void);  // uart测试代码

#endif

附录 - uart驱动(uart.c)

#include <reg52.h>
#include "uart.h"
#include "lcd1602.h"
#include "clock.h"

/*******************************************************************************
* 函 数 名         : uart_init
* 函数功能         : 初始化串口
* 输    入         : void
* 输    出         : void
* 说    名         : none
*******************************************************************************/
void uart_init(void)  // 初始化串口
{
    SCON = 0x50;  // 设置为工作方式1
    TMOD |= 0x20;  // 设置计数器工作方式2
    PCON = 0x80;  // 波特率加倍
    TH1 = 0xf3;   // 计数器初始值设置,波特率4800
    TL1 = 0xf3;
    IE |= 0x90;   // 打开接收中断
    TR1 = 1;  // 打开计数器
}

/*******************************************************************************
* 函 数 名         : uart_deinit
* 函数功能         : 串口去初始化
* 输    入         : void
* 输    出         : void
* 说    名         : none
*******************************************************************************/
void uart_deinit(void)  // 串口去初始化
{
    TR1 = 0;  // 关闭计数器
    IE &= 0x8f;   // 关闭接收中断
    SCON = 0x00;  // 设置为工作方式1
    TMOD &= 0xdf;
    PCON = 0x00;  // 波特率加倍
    TH1 = 0xf3;   // 计数器初始值设置,波特率4800
    TL1 = 0xf3;
}

/*******************************************************************************
* 函 数 名         : uart_send_data
* 函数功能         : 串口发送
* 输    入         : dat:待发数据
* 输    出         : void
* 说    名         : none
*******************************************************************************/
void uart_send_data(u8 dat)  // 串口发送
{
    SBUF = dat;          // 将数据放入到发送寄存器
    while(!TI);          // 等待发送数据完成
    TI = 0;              // 清除发送完成标志位
}

/*******************************************************************************
* 函 数 名         : uart_send_num
* 函数功能         : 串口发送数字
* 输    入         : num:数字
* 输    出         : void
* 说    名         : none
*******************************************************************************/
void uart_send_num(s32 num)  // 串口发送数字
{
    u8 i;
    u8 dat[10] = { 0 };  // 不能使用malloc

    if (num < 0) {
        uart_send_data('-');
        num = -num;
    }
    for (i = 0; num; i++) {
        dat[i] = (num % 10 + '0');
        num /= 10;
    }
    for (; i; i--) {
        uart_send_data(dat[i - 1]);
    }
}

/*******************************************************************************
* 函 数 名         : uart_send_str
* 函数功能         : 串口发送字符串
* 输    入         : str:字符串
* 输    出         : void
* 说    名         : none
*******************************************************************************/
void uart_send_str(string str)  // 串口发送字符串
{
    for (; (*str) != '\0'; str++) {
        uart_send_data(*str);
    }
}

/*******************************************************************************
* 函 数 名         : uart_send_time
* 函数功能         : 串口发送本地时间
* 输    入         : void
* 输    出         : void
* 说    名         : none
*******************************************************************************/
void uart_send_time(void)  // 串口发送本地时间
{
    uart_send_str("time:\r\n");
    uart_send_num(time.year);
    uart_send_data('-');
    uart_send_num(time.month);
    uart_send_data('-');
    uart_send_num(time.day);
    uart_send_data(' ');
    uart_send_num(time.hour);
    uart_send_data(':');
    uart_send_num(time.miunte);
    uart_send_data(':');
    uart_send_num(time.second);
    uart_send_data(' ');
    uart_send_num(time.ms);
    uart_send_str("ms\r\n");
}

/*******************************************************************************
* 函 数 名         : uart_str_to_num
* 函数功能         : 字符串转数字
* 输    入         : str:字符串
* 输    出         : u32:转换结果
* 说    名         : none
*******************************************************************************/
u32 uart_str_to_num(string str)  // 字符串转数字
{
    u32 num = 0;

    for (; (*str) != '\0'; str++) {
        if (((*str) >= '0') && ((*str) <= '9')) {
            num = num * 10 + ((*str) - '0');
        } else {
            break;
        }
    }

    return num;
}

/*******************************************************************************
* 函 数 名         : uart
* 函数功能         : 接收数据
* 输    入         : void
* 输    出         : void
* 说    名         : none
*******************************************************************************/
void uart(void) interrupt 4  // 接收数据
{
    u8 rec_buf;

    rec_buf = SBUF;  // 接收数据
    RI = 0;              // 清除接收中断标志位
}

/*******************************************************************************
* 函 数 名         : test_uart
* 函数功能         : uart测试代码
* 输    入         : void
* 输    出         : void
* 说    名         : none
*******************************************************************************/
void test_uart(void)  // uart测试代码
{
    uart_init();
    uart_send_num(0x12345678);
    uart_send_str("test_uart\r\n");
    uart_deinit();
    uart_send_str("test_uart\r\n");
    uart_init();
    uart_send_str("test_uart\r\n");
}
发布了24 篇原创文章 · 获赞 53 · 访问量 3962

猜你喜欢

转载自blog.csdn.net/weixin_44413515/article/details/105153103