C51用GY39的串口工作模式CT连RX,DR连TX,且用LCD1602显示代码
时间: 2024-05-06 18:15:28 浏览: 79
以下是基于C51和GY39的串口工作模式CT连RX,DR连TX,且用LCD1602显示代码的示例程序:
```
#include <reg52.h>
#include <intrins.h>
#include "lcd1602.h" // LCD1602驱动程序头文件
#define RX_BUFFER_SIZE 64 // 接收缓存大小
#define TX_BUFFER_SIZE 64 // 发送缓存大小
sbit RX = P1^0; // 定义RX引脚
sbit TX = P1^1; // 定义TX引脚
unsigned char rx_buffer[RX_BUFFER_SIZE]; // 接收缓存数组
unsigned char tx_buffer[TX_BUFFER_SIZE]; // 发送缓存数组
unsigned char rx_index = 0; // 接收缓存索引
unsigned char tx_index = 0; // 发送缓存索引
bit rx_flag = 0; // 接收完成标志
bit tx_flag = 0; // 发送完成标志
void init_serial() // 初始化串口
{
TMOD |= 0x20; // 定时器1工作在模式2(8位自动重装载计数器)
TH1 = 0xFD; // 波特率9600,使用11.0592MHz晶振
TL1 = 0xFD;
SCON = 0x50; // 启用串口,使能接收
TR1 = 1; // 启动定时器1
ES = 1; // 使能串口中断
EA = 1; // 使能总中断
}
void send_byte(unsigned char byte) // 发送一个字节
{
if(!tx_flag) // 如果发送完成标志为0
{
tx_buffer[tx_index++] = byte; // 将字节放入发送缓存
if(tx_index >= TX_BUFFER_SIZE) // 如果发送缓存已满
{
tx_index = 0; // 重置发送缓存索引
}
tx_flag = 1; // 设置发送完成标志为1
TI = 1; // 启动发送中断
}
}
void send_string(unsigned char *str) // 发送一个字符串
{
while(*str) // 遍历字符串
{
send_byte(*str++); // 发送每个字节
}
}
void clear_rx_buffer() // 清空接收缓存
{
rx_flag = 0; // 设置接收完成标志为0
rx_index = 0; // 重置接收缓存索引
memset(rx_buffer, 0, RX_BUFFER_SIZE); // 清空接收缓存数组
}
void clear_tx_buffer() // 清空发送缓存
{
tx_flag = 0; // 设置发送完成标志为0
tx_index = 0; // 重置发送缓存索引
memset(tx_buffer, 0, TX_BUFFER_SIZE); // 清空发送缓存数组
}
void serial_isr() interrupt 4 // 串口中断服务程序
{
if(RI) // 如果接收中断发生
{
RI = 0; // 清除接收中断标志
if(rx_index < RX_BUFFER_SIZE) // 如果接收缓存未满
{
rx_buffer[rx_index++] = SBUF; // 将接收到的字节放入接收缓存
}
if(rx_index == RX_BUFFER_SIZE) // 如果接收缓存已满
{
rx_flag = 1; // 设置接收完成标志为1
}
}
if(TI) // 如果发送中断发生
{
TI = 0; // 清除发送中断标志
if(tx_index < TX_BUFFER_SIZE) // 如果发送缓存未空
{
SBUF = tx_buffer[tx_index++]; // 发送发送缓存中的下一个字节
}
if(tx_index == 0) // 如果发送缓存已空
{
tx_flag = 0; // 设置发送完成标志为0
}
}
}
void main()
{
init_lcd(); // 初始化LCD1602
init_serial(); // 初始化串口
while(1)
{
if(rx_flag) // 如果接收完成标志为1
{
lcd_clear(); // 清屏
lcd_puts(rx_buffer); // 在LCD1602上显示接收到的字符串
clear_rx_buffer(); // 清空接收缓存
}
}
}
```
在程序中,我们定义了两个缓存数组rx_buffer和tx_buffer,分别用于接收和发送数据。在串口中断服务程序中,接收到的字节放入接收缓存数组中,而发送缓存数组中的字节则依次发送。
在主程序中,我们首先调用init_lcd()和init_serial()函数,分别用于初始化LCD1602和串口。然后,在一个无限循环中,如果接收完成标志为1,则在LCD1602上显示接收到的字符串并清空接收缓存。
需要注意的是,在发送数据时,我们先将字节放入发送缓存数组中,而不是直接发送。这是因为串口发送数据需要一定时间,如果直接发送,可能会导致数据丢失。因此,我们需要使用发送缓存来保证数据的完整性。
阅读全文