学习串口调用STC调试接口
之前研究了如何通过串口命令来进行不断电烧录程序,减少了每次烧录测试代码之前需要手动重启mcu的工作量后,调试代码功能舒服多了!接下来进行测试STC的各个调试接口
这块STC已有封装好的库,但是自己再实现一遍,能锻炼能力的同时,加深对串口通信的理解
STC调试接口协议是模态对话框,用着不方便,我直接拿到了对应的html文件
先实现串口通信中的缓存数据模块C_BUFF.h
定义BUFF_DATA的结构体,并实现对其的pop,push,reset,Has_Data,copy的操作
pop:读取1字节数据
push:写入1字节数据
has_data:判断是否有数据
reset:清空数据
cpy:复制一个buff_data的数据到另一个buff_data
#ifndef C_BUFF_H
#define C_BUFF_H
#include "STC\STC8H.h"
#define uchar unsigned char
#define uint unsigned int
//buff_size 必须是2的倍数-1
#define BUFF_SIZE 0x0f
struct BUFF_DATA
{
uchar rptr;
uchar wptr;
char buff;
};
#define BUFF_POP(x,d) d=x.buff;x.rptr&=BUFF_SIZE
#define BUFF_PUSH(x,d) x.buff = d;x.wptr&=BUFF_SIZE
#define BUFF_HAS_DATA(x) (x.rptr != x.wptr)
#define BUFF_RESET(x) x.rptr=0;x.wptr=0
#define BUFF_CPY(src,dest) while(BUFF_HAS_DATA(src)){dest.buff = src.buff;src.rptr&=BUFF_SIZE;dest.wptr&=BUFF_SIZE;}
#define PBUFF_POP(x,d) d=x->buff;x->rptr&=BUFF_SIZE
#define PBUFF_PUSH(x,d) x->buff = d;x->wptr&=BUFF_SIZE
#define PBUFF_HAS_DATA(x) (x->rptr != x->wptr)
#define PBUFF_RESET(x) x->rptr=0;x->wptr=0
#define PBUFF_CPY(src,dest) while(PBUFF_HAS_DATA(src)){dest->buff = src->buff;src->rptr&=BUFF_SIZE;dest->wptr&=BUFF_SIZE;}
#endif //C_BUFF_H 串口通信模块的头文件C_UART.h:
UartSend 是发送1字节的数据
UartSendStr 是发送字符串数据,以\0结尾
UartSendData 是发送指定长度的数据
UartReceived 是接收串口数据,如果返回1,则表示有数据,返回0表示未收到数据,接收的数据储存在str_buff中
#ifndef C_UART_H
#define C_UART_H
#include "C_BUFF.h"
extern struct BUFF_DATA xdata str_buff;
void Delay1ms(void); //@5.5296MHz
void Delay_ms(uint times); //@5.5296MHz
void Uart1_Init(void); //19200bps@5.5296MHz
void UartSend(char dat);
void UartSendStr(const char *p);
void UartSendData(const char *p,uchar len);
bit UartReceived(); //串口接收数据,如果返回1,则表示有数据,返回0表示未收到数据,接收的数据储存在str_buff中
#endif //C_UART_H 串口通信模块的实现:C_UART.c
send_busy 用来判断是否发送繁忙
recv_timeout 用来检测一次数据是否接收完成
uart_buff 是串口数据缓存
str_buff 是接收的数据的缓存
UartReceived中会判断,如果recv_timeout>0,则代表接收到了数据,然后循环将数据存入str_buff中,直到对方发送结束,并返回1代表有数据
#include "C_UART.h"
#include "INTRINS.H"
bit send_busy;
uchar recv_timeout;
struct BUFF_DATA xdata uart_buff,xdata str_buff;
void Delay1ms(void) //@5.5296MHz
{
unsigned char data i, j;
_nop_();
_nop_();
i = 8;
j = 43;
do
{
while (--j);
} while (--i);
}
void Delay_ms(uint times) //@5.5296MHz
{
unsigned char data i, j;
while (times-->0)
{
_nop_();
_nop_();
i = 8;
j = 43;
do
{
while (--j);
} while (--i);
}
}
void Uart1_Isr(void) interrupt 4
{
if (TI)
{
TI = 0;
send_busy = 0;
}
if (RI)
{
RI = 0;
BUFF_PUSH(uart_buff,SBUF);
recv_timeout = 5;
}
}
void Uart1_Init(void) //19200bps@5.5296MHz
{
SCON = 0x50; //8位数据,可变波特率
AUXR &= 0xBF; //定时器时钟12T模式
AUXR &= 0xFE; //串口1选择定时器1为波特率发生器
TMOD &= 0x0F; //设置定时器模式
TL1 = 0xFA; //设置定时初始值
TH1 = 0xFF; //设置定时初始值
ET1 = 0; //禁止定时器中断
TR1 = 1; //定时器1开始计时
ES = 1; //使能串口1中断
EA = 1;
send_busy = 0;
BUFF_RESET(uart_buff);
}
void UartSend(char dat)
{
while(send_busy);
send_busy = 1;
SBUF = dat;
}
void UartSendStr(const char *p)
{
while(*p)
UartSend(*p++);
}
void UartSendData(const char *p,uchar len)
{
while (len-->0)
UartSend(*p++);
}
//串口接收数据,如果返回1,则表示有数据,返回0表示未收到数据,接收的数据储存在str_buff中
bit UartReceived()
{
if(recv_timeout>0)
{
BUFF_RESET(str_buff);
while(recv_timeout>0)
{
BUFF_CPY(uart_buff,str_buff)
recv_timeout--;
Delay1ms();
}
BUFF_PUSH(str_buff,0);
return 1;
}
return 0;
} 主函数中循环接收,并调用UartSendStr处理数据
#include "C_UART.h"
#include "C_STC_TOOLS.h"
#include <STRING.H>
void DealString(char *p)
{
if(strcmp(p,"hello") == 0)
{
UartSendStr("world!");
}
else if(strcmp(p,"reboot") == 0)
{
Delay_ms(1000);
UartSendStr("bye!");
IAP_CONTR = 0x60;
}
else
{
UartSendStr(p);
}
}
void main()
{
Uart1_Init();
UartSendStr("Uart Test!\r\n");
while(1)
{
if(UartReceived())
DealString(str_buff.buff);
Delay1ms();
}
} 现在先测试STC调试接口的 功能1: 在数码管上显示字符串
新建C_STC_TOOLS.h
添加函数void STC_SEG7_ShowString(const char *str);
#ifndef C_STC_TOOLS_H
#define C_STC_TOOLS_H
//功能1: 在数码管上显示字符串
void STC_SEG7_ShowString(const char *str);
#endif //C_STC_TOOLS_H 在C_STC_TOOLS.c中发送对应的数据
先设置8位的头信息,然后复制需要发送的数据,因为数码管只能显示8个数字,所以我们最多复制8字节数据就break,然后将最后一位置0,并调用串口发送
这里一定要调用UartSendData函数,而不是UartSendStr函数,因为UartSendStr会在字符串有'\0'的时候就停止发送,导致实际发送的数据只有 37H 53H 45H 47H 53H
之前我就是犯了这个错误,导致一直不显示
#include "C_STC_TOOLS.h"
#include "C_UART.h"
#define L_BUFF_LEN 64
char xdata stc_buff;
uchar pos;
//功能1: 在数码管上显示字符串
void STC_SEG7_ShowString(const char *str)
{
stc_buff = 0x37;
stc_buff = 0x53;
stc_buff = 0x45;
stc_buff = 0x47;
stc_buff = 0x53;
stc_buff = 0x00;
stc_buff = 0x00;
stc_buff = 0x00;
for(pos=8;pos<16;pos++)
{
if(*str)
stc_buff = *str++;
else
break;
}
stc_buff = 0;
UartSendData(stc_buff,pos+1);
} 主函数中接收串口信息判断,如果是以seg开头,则测试数码管的功能
void DealString(char *p)
{
if(strcmp(p,"hello") == 0)
{
UartSendStr("world!");
}
else if(strcmp(p,"reboot") == 0)
{
Delay_ms(1000);
UartSendStr("bye!");
IAP_CONTR = 0x60;
}
else if(strncmp(p,"seg",3) == 0)
{
STC_SEG7_ShowString(p+3);
}
else
{
UartSendStr(p);
}
}
烧录,打开串口测试,发送seg12.3.3后,能正常在数码管上显示
我发现数据中的.不进行占位,且不管多少'.'连一起就只显示一个'.',如果强制按只发送8位来算,那么无法输出1.2.3.4.5.6.7.8这样的数据,我们得对应修改下STC_SEG7_ShowString的逻辑
页:
[1]
2