51单片机 - 电子万年历 - uart驱动
本文用于阐述使用51单片机制作万年历过程中的uart通信驱动部分,软件特性可以在proteus上仿真,使用51单片机定时器T1溢出率做uart波特率时基,采用12MHz晶振。51单片机将万年历记录的年/月/日/时/分/秒/毫秒等信息编码为ascii码,通过uart发送到外设,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); // 串口发送字符串
void uart_send_time(void); // 串口发送本地时间
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口接收。
/*******************************************************************************
* 函 数 名 : 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代码(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");
}
转载:https://blog.csdn.net/weixin_44413515/article/details/104501797
查看评论