最近实验PC通过串口与单片机通信,要求如下代码开头所说,但是通信过程中在按键的同时lcd与PC的串口助手同时出现了多余信息,请高手指教。
另外,我想在单片机接收到8个字符后自动发送8个字符,请问程序能如何设计呢?
/********************************************************************
- * 文件名 : 串口接收试验.c
- * 描述 : 该程序从串口接收数据,通过1602LCD显示数据。在LCD的第一行显示出来,
- 当数据过多时(超过16个字符),LCD第一行将会被覆盖。显示完成之后通过按键
- 发送字符串到PC。程序使用两个中断,分别是串口中断与外部的按键中断
- ***********************************************************************/
- #include
- #include
#define uchar unsigned char
- #define uint unsigned int
- uchar key_s, key_v;
- uint COUNT = 0;
void Time0_Init(void);
- void writedata(void);
- /*LED_Buffer[16]用来存储串口发送的数据,com_dat用来记录串口发送的个数*/
- uchar LED_Buffer[16], *q, com_dat; //从串口接收的数据
//这三个引脚参考资料
- sbit E=P2^7; //1602使能引脚
- sbit RW=P2^6; //1602读写引脚
- sbit RS=P2^5; //1602数据/命令选择引脚
- sbit K1 = P3^2;//字符串发送按钮
/********************************************************************
- * 名称 : Delay(uint del)
- * 功能 : 延时10ms * del
- * 输入 : 无
- * 输出 : 无
- ***********************************************************************/
- void Delay(uint del)
- {
- uint i,j;
- for(i=0; i
for(j=0; j<1827; j++)
- ;
- }
/********************************************************************
- * 名称 : delay()
- * 功能 : 延时,延时时间大概为140US。
- * 输入 : 无
- * 输出 : 无
- ***********************************************************************/
- void delay()
- {
- int i,j;
- for(i=0; i<=10; i++)
- for(j=0; j<=2; j++)
- ;
- }
/********************************************************************
- * 名称 : enable(uchar del)
- * 功能 : 1602命令函数
- * 输入 : 输入的命令值
- * 输出 : 无
- ***********************************************************************/
- void enable(uchar del)
- {
- P0 = del;
- RS = 0;
- RW = 0;
- E = 0;
- delay();
- E = 1;
- delay();
- }
/********************************************************************
- * 名称 : write(uchar del)
- * 功能 : 1602写数据函数
- * 输入 : 需要写入1602的数据
- * 输出 : 无
- ***********************************************************************/
- void write(uchar del)
- {
- P0 = del;
- RS = 1;
- RW = 0;
- E = 0;
- delay();
- E = 1;
- delay();
- }
/********************************************************************
- * 名称 : L1602_init()
- * 功能 : 1602初始化,请参考1602的资料
- * 输入 : 无
- * 输出 : 无
- ***********************************************************************/
- void L1602_init(void)
- {
- enable(0x01);
- enable(0x38);
- enable(0x0c);
- enable(0x06);
- enable(0xd0);
- }
/********************************************************************
- * 名称 : L1602_char(uchar hang,uchar lie,char sign)
- * 功能 : 改变液晶中某位的值,如果要让第一行,第五个字符显示"b" ,调用该函数如下
- L1602_char(1,5,'b')
- * 输入 : 行,列,需要输入1602的数据
- * 输出 : 无
- ***********************************************************************/
- void L1602_char(uchar hang,uchar lie,char sign)
- {
- uchar a;
- if(hang == 1) a = 0x80;
- if(hang == 2) a = 0xc0;
- a = a + lie - 1;
- enable(a);
- write(sign);
- }
/********************************************************************
- * 名称 : L1602_string(uchar hang,uchar lie,uchar *p)
- * 功能 : 改变液晶中某位的值,如果要让第一行,第五个字符开始显示"ab cd ef" ,调用该函数如下
- L1602_string(1,5,"ab cd ef;")
- * 输入 : 行,列,需要输入1602的数据
- * 输出 : 无
- ***********************************************************************/
- void L1602_string(uchar hang,uchar lie,uchar *p)
- {
- uchar a;
- if(hang == 1) a = 0x80;
- if(hang == 2) a = 0xc0;
- a = a + lie - 1;
- enable(a);
- while(1)
- {
- if(*p == '\0')
- break;
- write(*p);
- p++;
- }
- }
/********************************************************************
- * 名称 : Com_Int()
- * 功能 : 串口中断子函数
- * 输入 : 无
- * 输出 : 无
- ***********************************************************************/
- void Com_Int(void) interrupt 4
- {
- EA = 0;
- if(RI == 1) //当硬件接收到一个数据时,RI会置位
- {
- LED_Buffer[com_dat] = SBUF; //把从串口读出的数存到数组
- RI = 0; //标志位清0
- com_dat++;
- if(com_dat == 16)
- com_dat = 0; //当com_dat = 16时,清0,防止数组溢出
- }
- EA = 1;
- }
/********************************************************************
- * 名称 : Com_Init()
- * 功能 : 串口初始化,晶振11.0592,波特率9600,使能了串口中断
- * 输入 : 无
- * 输出 : 无
- ***********************************************************************/
- void Com_Init(void)
- {
- TMOD = 0x20; //定时器工作在定时器1的方式2
- PCON = 0x00; //不倍频
- SCON = 0x50; //串口工作在方式1,并且启动串行接收
- TH1 = 0xFd; //设置波特率 9600
- TL1 = 0xFd;
- TR1 = 1; //启动定时器1
- ES = 1; //开串口中断
- EA = 1; //开总中断
- }
void writedata()
- {
- uchar i = 0;
- uint j = 0;
- uchar code Buf1[] = "abcdefgh"; //所要发送的数据
- uchar *p;
p = Buf1;
- while(1)
- {
- SBUF = *p;
- while(!TI) //如果发送完毕,硬件会置位TI
- {
- _nop_();
- }
- p++;
- if(*p == '\0')
- break; //在每个字符串的最后,会有一个'\0'
- TI = 0; //TI清零
- }
- }
void Outside_Init(void)
- {
- EX0 = 1; //开外部中断0
- IT0 = 1; //负边沿触发
- EA = 1; //开总中断
- }
void Outside_Int1(void) interrupt 0 using 1
- {
- if(K1 == 0)
- {
- Delay(2);
- if(K1 == 0)
- writedata();
- }
- }
void Main()
- {
- uchar i = 0, com_dat = 0;
- L1602_init();
- Delay(100);
- Com_Init();
- Outside_Init();
- P2 = 0x00;
- while(1)
- {
- q = LED_Buffer;
- L1602_string(1,1,q);
- com_dat = 0;
- Delay(10);
- }
- }
-