51单片机at89c52,用C语言编写程序,PC 端通过串口(STC-ISP 的串口助手)向开发板发送字符串(字符串以’*’字 母结尾,字符数小于 40,波特率 4800),把该字符串显示到 LCD1602 上,第二 次输入的字符串将替换之前的显示,如果字符数大于 16 则滚动显示,串口的数 据传送采用中断方式编程。
时间: 2024-03-04 08:54:09 浏览: 151
好的,这是一个较为复杂的问题,需要逐步实现。以下是一个基本框架,您可以根据自己的需要进行修改和调整:
1. 首先,您需要配置51单片机的串口和LCD1602的读写引脚。具体的引脚配置需要参考开发板的原理图或手册。
2. 然后,您需要编写51单片机的中断服务函数,用于接收从串口接收到的数据。在中断服务函数中,您需要判断是否接收到了完整的字符串(即以’*’结尾),如果是,则将该字符串存储在一个数组中。
3. 接下来,您需要编写一个函数,用于在LCD1602上显示字符串。如果字符串长度小于16,则直接显示;如果长度大于16,则需要进行滚动显示。在滚动显示时,您可以使用定时器中断来定时更新LCD1602的显示内容。
4. 最后,您需要在主函数中,初始化串口、LCD1602和定时器,并启动中断。然后进入一个无限循环,不断地等待中断服务函数接收到完整的字符串,并调用显示函数显示在LCD1602上。
需要注意的是,这只是一个基本框架,具体的实现方式可能会因为硬件环境、编译器版本等因素而有所不同。因此,在实际开发中,您需要根据自己的情况进行调整和修改。
相关问题
代码,51单片机at89c52,用C语言编写程序,PC 端通过串口(STC-ISP 的串口助手)向开发板发送字符串(字符串以’*’字 母结尾,字符数小于 40,波特率 4800),把该字符串显示到 LCD1602 上,第二 次输入的字符串将替换之前的显示,如果字符数大于 16 则滚动显示,串口的数 据传送采用中断方式编程。
以下是一个基本的代码,可以实现您所需的功能。需要注意的是,由于硬件环境和编译器版本的不同,具体实现方式可能会有所不同,您需要根据自己的情况进行调整和修改。
```c
#include<reg52.h>
#include<intrins.h> // _nop_() 函数的头文件
#define uchar unsigned char
#define uint unsigned int
sbit RS = P0^0; // LCD1602 的 RS 引脚
sbit RW = P0^1; // LCD1602 的 RW 引脚
sbit EN = P0^2; // LCD1602 的 EN 引脚
uchar data recv_buf[40]; // 存储接收到的字符串
uchar data display_buf[17]; // LCD1602 显示的字符串
uchar data recv_len = 0; // 接收到的字符串的长度
bit flag = 0; // 标记是否接收到完整的字符串
void init_serial() // 初始化串口
{
TMOD = 0x20; // 设置定时器1为模式2
TH1 = 0xfd; // 波特率4800,定时器1初值为0xfd
TL1 = 0xfd;
TR1 = 1; // 启动定时器1
SM0 = 0; // 串口工作方式1:8位数据,无校验位,1位停止位
SM1 = 1;
REN = 1; // 允许串口接收
EA = 1; // 打开总中断
ES = 1; // 打开串口中断
}
void init_lcd() // 初始化LCD1602
{
RS = 0; // 发送命令
RW = 0;
EN = 1;
_nop_(); // 延时
EN = 0;
_nop_();
_nop_();
EN = 1;
_nop_();
EN = 0;
_nop_();
_nop_();
EN = 1;
_nop_();
EN = 0;
_nop_();
_nop_();
P0 = 0x38; // 设置工作模式:8位数据,双行显示,5x7点阵字符
EN = 1;
_nop_();
EN = 0;
_nop_();
_nop_();
P0 = 0x0c; // 设置显示模式:开显示,光标不显示,不闪烁
EN = 1;
_nop_();
EN = 0;
_nop_();
_nop_();
P0 = 0x01; // 清屏
EN = 1;
_nop_();
EN = 0;
_nop_();
_nop_();
P0 = 0x06; // 设定输入方式:光标自动右移,不移动屏幕
EN = 1;
_nop_();
EN = 0;
_nop_();
_nop_();
}
void display_str(uchar *str) // 在LCD1602上显示字符串
{
uchar i;
P0 = 0x80; // 光标移动到第一行第一列
RS = 0; // 发送命令
RW = 0;
EN = 1;
_nop_(); // 延时
EN = 0;
_nop_();
_nop_();
for (i = 0; i < 16; i++) // 清空显示缓存
{
display_buf[i] = ' ';
}
for (i = 0; i < 16 && str[i] != '\0'; i++) // 复制字符串到显示缓存
{
display_buf[i] = str[i];
}
for (i = 0; i < 16; i++) // 显示缓存中的内容
{
P0 = display_buf[i];
RS = 1; // 发送数据
RW = 0;
EN = 1;
_nop_();
EN = 0;
_nop_();
_nop_();
}
}
void scroll_display() // 滚动显示
{
uchar i, j;
for (i = 0; i <= recv_len - 16; i++) // 从接收缓存中复制16个字符到显示缓存
{
for (j = 0; j < 16; j++)
{
display_buf[j] = recv_buf[i + j];
}
display_str(display_buf); // 在LCD1602上显示
for (j = 0; j < 200; j++); // 延时,控制滚动速度
}
}
void serial_isr() interrupt 4 using 1 // 串口中断服务函数
{
uchar ch;
if (RI) // 接收中断
{
RI = 0;
ch = SBUF; // 读取接收到的数据
if (ch == '*') // 判断是否接收到完整的字符串
{
recv_buf[recv_len] = '\0'; // 字符串末尾加上'\0'
flag = 1; // 标记接收到完整的字符串
}
else if (recv_len < 40) // 将接收到的字符存储到接收缓存中
{
recv_buf[recv_len] = ch;
recv_len++;
}
}
}
void main()
{
init_serial(); // 初始化串口
init_lcd(); // 初始化LCD1602
while (1)
{
if (flag) // 如果接收到了完整的字符串
{
flag = 0;
recv_len = 0;
if (strlen(recv_buf) > 16) // 如果字符串长度大于16,则滚动显示
{
scroll_display();
}
else // 否则直接显示
{
display_str(recv_buf);
}
}
}
}
```
希望这个代码能够对您有所帮助。如果您有任何问题或疑问,请随时问我。
阅读全文