标题:
C51单片机串口调试求助
[打印本页]
作者:
guan1989
时间:
2020-5-23 16:34
标题:
C51单片机串口调试求助
目前在学习串口收发数据,目的是接收命令,根据命令修改数组内的值并发送出去,主要有下面两个疑问
1、串口调试有没有好的方法可以在线仿真,能够看到变量值的每步变化,我尝试用了proteus仿真,串口调试助手发送数据,程序进不了串口中断;
2、我写了下面一段程序,tmp[]数组接收的是串口调试助手发来的命令ASCII码。红色这句修改数组的值出了问题,接收到的ASCII码0-b转换成16进制的0-11,作为数组的下标赋值给b,接收到的ASCII码1 、2、4、8转换成16进制
(tmp[2]-0x30),赋值给数组buzzer_value '
'。但是实际每次
buzzer_value '
'都为0X00;后面发送的b 、
(tmp[2]-0x30)的值又是对的,不知道中间有什么问题。
我尝试把b改成数字下标或者把
tmp[2]-0x30改成具体的十六进制数,结果都是对的。
if((tmp[1]>='0')&&(tmp[1]<='9'))
b=tmp[1]-0X30;
else
b=tmp[1]-0X51;
buzzer_value '[ b ]'=(tmp[2]-0x30);
a=0;
while(a<12)
{
SBUF = buzzer_value[a]; //SUBF接受/发送缓冲器(又叫串行通信特殊功能寄存器)
while(!TI); // 等特数据传送 (TI发送中断标志)
TI = 0; // 清除数据传送标志
a++; // 下一个字符
}
SBUF = b;
//SUBF接受/发送缓冲器(又叫串行通信特殊功能寄存器)
while(!TI); // 等特数据传送 (TI发送中断标志)
TI = 0; // 清除数据传送标志
SBUF = tmp[2]-0X30;
//SUBF接受/发送缓冲器(又叫串行通信特殊功能寄存器)
while(!TI); // 等特数据传送 (TI发送中断标志)
TI = 0; // 清除数据传送标志
int_tmp();
b=0;
作者:
guan1989
时间:
2020-5-23 16:39
发帖出来的buzzer_value '[ b ]'不加引号不能显示[]和里面的b
作者:
guan1989
时间:
2020-5-23 21:00
本帖最后由 guan1989 于 2020-5-23 21:02 编辑
//串口通讯实验
//这里写好程序 下载到单片机里
//直接 用下载软件的串口助手 以16进制 发送 8A 会接收到 我爱单片机
//此程序虽然很少 但是它有着串口通讯和接收的所有功能
//需要用串口的朋友只要用它改改就可以实现自己想要的效果
#include "stc8.h"
unsigned char data key_value[14]={0,0,0,0,0,0,0,0,0,0,0,0,0,0}; //实时存储按键按下标志位:LED1,LED2,LED3...LED10,test,mute,,LED_ALARM,buzzer;用于显示和通讯
unsigned char data key_alarm[12]={1,1,1,1,1,1,1,1,1,1,1,1}; //按键按下是否生效标志位:LED1,LED2,...lLED10,test,mute
unsigned char data buzzer_value[12]={1,1,2,4,8,1,1,1,1,1,1,1};//1表示2秒1鸣,2表示1秒1鸣、4表示1秒2鸣、8表示长鸣
/*
命令A11,表示key_alarm[0]=1;A10,表示key_alarm[0]=0;返回key_alarm[12]
命令B11,表示buzzer_value[1]=1;B10,表示buzzer_value[1]=0;返回buzzer_value[12]
命令KEY,返回key_value[14]
*/
unsigned char tmp[4]; //存储接收到的值;
unsigned char ucreceive_num=0;
void main()
{
// P3M0 |= 0x03 ;
// P3M1 &=0xfc ; //uart1推挽输出,需限流电阻
SCON |= 0x50; //REN=1允许串行接受状态,串口工作模式2
TMOD= 0x20; //定时器工作方式2 8位 自动重装载定时器 实现波特率
AUXR=0X40; //开启1T模式
TH1 =TL1= 0xDC; // 设置波特率为9600 公式 TH1=256-(11059200/32/9600)=256-36=220 0xDC
// 设置波特率为9600 公式 TH1=256-(22118400/32/9600)=256-72=184 0xB8
// 如有不明白请查 STC8手册上有详细说明
TR1 = 1; //开启定时器1
ES = 1; //开串口中断
EA = 1; // 开总中断
while(1)
{
}
}
/***********************************************
*函数名称:Uart1_SendChar
*功 能:串口1发送单个字符函数
*入口参数:Udat:欲发送的数据
*返 回 值:无
*备 注:无
************************************************/
void int_tmp()
{
ucreceive_num=0;
tmp[0]=0x00;
tmp[1]=0x00;
tmp[2]=0x00;
}
/***********************************************
*函数名称:Uart1_SendChar
*功 能:串口1发送单个字符函数
*入口参数:Udat:欲发送的数据
*返 回 值:无
*备 注:无
************************************************/
void ISP_Check()
{
unsigned char a;
unsigned char c;
switch(tmp[0])
{
case 'K' :
if((tmp[1]=='E')&&(tmp[2]=='Y'))
{
ES= 0;
a=0;
while(a<14)
{
SBUF = key_value[a]; //SUBF接受/发送缓冲器(又叫串行通信特殊功能寄存器)
while(!TI); // 等特数据传送 (TI发送中断标志)
TI = 0; // 清除数据传送标志
a++; // 下一个字符
}
int_tmp();
}
break;
case 'A' :
if( ( ((tmp[1]>='0')&&(tmp[1]<='9')) || ((tmp[1]>='a')&&(tmp[1]<='b')) ) &&( (tmp[2]=='0') || (tmp[2]=='1') ))
{
ES= 0;
if((tmp[1]>='0')&&(tmp[1]<='9'))
c=tmp[1]-0X30;
else
c=tmp[1]-0X51;
key_alarm[c] = (tmp[2]-0x30);
a=0;
while(a<12)
{
SBUF = key_alarm[a]; //SUBF接受/发送缓冲器(又叫串行通信特殊功能寄存器)
while(!TI); // 等特数据传送 (TI发送中断标志)
TI = 0; // 清除数据传送标志
a++; // 下一个字符
}
SBUF = c; //SUBF接受/发送缓冲器(又叫串行通信特殊功能寄存器)
while(!TI); // 等特数据传送 (TI发送中断标志)
TI = 0; // 清除数据传送标志
SBUF = tmp[2]-0x30; //SUBF接受/发送缓冲器(又叫串行通信特殊功能寄存器)
while(!TI); // 等特数据传送 (TI发送中断标志)
TI = 0; // 清除数据传送标志
int_tmp();
}
break;
case 'B' :
if( ( ((tmp[1]>='0')&&(tmp[1]<='9')) || ((tmp[1]>='a')&&(tmp[1]<='b')) ) &&( (tmp[2]=='1') || (tmp[2]=='2') ||(tmp[2]=='4') ||(tmp[2]=='8') ))
{
ES= 0;
if((tmp[1]>='0')&&(tmp[1]<='9'))
c=tmp[1]-0X30;
else
c=tmp[1]-0X51;
buzzer_value[c] = (tmp[2]-0x30);
a=0;
while(a<12)
{
SBUF = buzzer_value[a]; //SUBF接受/发送缓冲器(又叫串行通信特殊功能寄存器)
while(!TI); // 等特数据传送 (TI发送中断标志)
TI = 0; // 清除数据传送标志
a++; // 下一个字符
}
SBUF = c; //SUBF接受/发送缓冲器(又叫串行通信特殊功能寄存器)
while(!TI); // 等特数据传送 (TI发送中断标志)
TI = 0; // 清除数据传送标志
SBUF = tmp[2]-0x30; //SUBF接受/发送缓冲器(又叫串行通信特殊功能寄存器)
while(!TI); // 等特数据传送 (TI发送中断标志)
TI = 0; // 清除数据传送标志
int_tmp();
c=0;
}
break;
default :
ES=0;
int_tmp();
}
ES=1;
}
void Serial_int(void) interrupt 4 using 1
{
if (RI)
{
tmp[ucreceive_num] = SBUF;
ucreceive_num++;
ISP_Check();
if(ucreceive_num==3)
int_tmp();
RI = 0;
}
}
复制代码
源代码见附件
作者:
wulin
时间:
2020-5-24 07:51
楼主这不是串口通讯问题,是数据解析问题。
作者:
guan1989
时间:
2020-5-24 16:05
wulin 发表于 2020-5-24 07:51
楼主这不是串口通讯问题,是数据解析问题。
死活找不到原因
作者:
guan1989
时间:
2020-5-24 16:16
wulin 发表于 2020-5-24 07:51
楼主这不是串口通讯问题,是数据解析问题。
请问有什么方向的解决思路
作者:
guan1989
时间:
2020-5-24 16:50
wulin 发表于 2020-5-24 07:51
楼主这不是串口通讯问题,是数据解析问题。
if((tmp[1]>='0')&&(tmp[1]<='9'))
b=tmp[1]-0X30;
else
b=tmp[1]-0X51;
buzzer_value '[ b ]'=(tmp[2]-0x30);
复制代码
我把上面一段修改了下,如下图。
buzzer_value '[ b ]'=(tmp[2]-0x30);这一句分解成了case,结果是正确的,但是原理不是很懂,是不是编译器的编译过程有问题。
{
ES= 0;
if((tmp[1]>='0')&&(tmp[1]<='9'))
{
switch(tmp[2])
{
case'1':buzzer_value[tmp[1]-0X30] =1;break;
case'2':buzzer_value[tmp[1]-0X30] =2;break;
case'4':buzzer_value[tmp[1]-0X30] =4;break;
case'8':buzzer_value[tmp[1]-0X30] =8;break;
}
}
else
{
switch(tmp[2])
{
case'1':buzzer_value[tmp[1]-0X57] =1;break;
case'2':buzzer_value[tmp[1]-0X57] =2;break;
case'4':buzzer_value[tmp[1]-0X57] =4;break;
case'8':buzzer_value[tmp[1]-0X57] =8;break;
}
}
复制代码
欢迎光临 (http://www.51hei.com/bbs/)
Powered by Discuz! X3.1