单片机串口发送一组8个数据,偏偏第2个数据错误,其他数据都对,请问是怎么回事?,真的好奇怪,定时发送一组8个数据,但串口助手结果是前两个数据均为第一个数据,后面数据都正常发送,这是怎么回事?要发送的是一组8个数据是:
uchar send[8]={0x01,0x03,0x00,0x00,0x00,0x01,0x84,0x0A};//发送一组八个数据
然而接收到的却是:0x01,0x01,0x00,0x00,0x00,0x01,0x84,0x0A,第一个数据发送了两遍,然后开始发送第三,四位数据…
这是发送部分的程序:
for(i=0;i<8;i++)
{
SBUF=send[ i];//发送数据
while(!TI);
TI=0;//清除数据传送标志
}
然后我改了一下
for(i=0;i<8;i++)
{
SBUF=send[ i];//发送数据
while(!TI);
TI=0;//清除数据传送标志
}
它应该显示第二,三位数据,也就是03 00 ,但结果却是03 03 ,这是为啥?
以下为完整程序:我用了ds1302时钟模块,second就是秒,已经设置好了
#include <stc12c5a.h>
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <math.h>
#include <intrins.h>
#include”ds1302.h”
#define uchar unsigned char
#define uint unsigned int
uchar rec[9];//接收
uchar send[8]={0x01,0x03,0x00,0x00,0x00,0x01,0x84,0x0A};//发送一组8个数据
uchar num=0;
void init();// 初始化函数
void UART_1send();
void UART_1interrupt();
int flag2;//接收标志位
int i;
void delay(uint z)//延时函数1ms
{
uint x,y;
for(x=z;x>0;x–);
for(y=110;y>0;y–);
}
void init() //系统初始化
{
TMOD |=0X20;//定时器T1,方式2,波特率由PCON寄存器的SMOD决定
SCON=0x50; //REN RI TI,RI为0,TI为0
//串行口1方式1 SCON是串行口1的串行控制寄存器,REN为1,允许接收
PCON=0x00;//各工作方式波特率加倍
TH1=0xfD;//9600bps@11.0592
TL1=0xfD;
TR1=1; //定时器1中断打开
EA=1;//cpu总中断允许位,1为开放中断
ES=1;// 1允许串行口中断
}
void main()
{
flag2=0;
init();//初始化
while(1)
{
delay(1000);
UART_1send(); //串口发送
}
}
void UART_1send() //串口发送函数
{
uchar i;
delay(500);
if(flag2==0) //如果标志位flag2=0,则发送
{
for(i=0;i<8;i++)
{
SBUF=send[ i];//风向数据
while(!TI);
TI=0;//清除数据传送标志
}
flag2=1;
}
},
//以下代码在WQX-15开发板上,使用STC15W4K核心板调试串口1,晶振30M,波特率9600。
bit Uart1_Flag=1;
u8 code Uart1_Up_Symbol_Buffer[30]={“\r\n温度: 遥控解码: 超声波:mm”};
u8 xdata Uart1_Up_Num_Buffer[10];
//*********************************《人人学会单片机》视频教程,祁绪电子2020-05
//串口初始化,配置定时器&波特率。STC15W,30M晶振,9600.
//*********************************《人人学会单片机》视频教程,祁绪电子2020-05
void Uart1_Init()
{
SM0=0;
SM1=1;
REN=1;
//SCON|=0x50;
PCON&=0x3f;
AUXR|=0x01;
AUXR|=0X14;
T2H=0xfc;
T2L=0xf3;
ES=1;
}
//*********************************《人人学会单片机》视频教程,祁绪电子2020-05
//串口发送函数。主函数调用,或者串口发送完中断后马上调用
//*********************************《人人学会单片机》视频教程,祁绪电子2020-05
void Uart1_Up_Data_Drive()
{
static u8 xdata count=0;
if(Uart1_Flag) //标志允许,发送一个字节
{
Uart1_Flag=0; //标志位翻转,只允许发送一个字节
count++; //字节编号增加。
switch(count)
{
case 1 : SBUF=Uart1_Up_Symbol_Buffer[0];break; //发送汉字的ASCII
case 2 : SBUF=Uart1_Up_Symbol_Buffer[1];break;
case 3 : SBUF=Uart1_Up_Symbol_Buffer[2];break;
case 4 : SBUF=Uart1_Up_Symbol_Buffer[3];break;
case 5 : SBUF=Uart1_Up_Symbol_Buffer[4];break;
case 6 : SBUF=Uart1_Up_Symbol_Buffer[5];break;
case 7 : SBUF=Uart1_Up_Symbol_Buffer[6];break;
case 8 : SBUF=Uart1_Up_Num_Buffer[0];break; //发送数值 温度
case 9 : SBUF=Uart1_Up_Num_Buffer[1];break;
case 10 :SBUF=Uart1_Up_Num_Buffer[2];break;
case 11 :SBUF=Uart1_Up_Num_Buffer[3];break;
case 12 : SBUF=Uart1_Up_Symbol_Buffer[7];break; //发送汉字的ASCII
case 13 : SBUF=Uart1_Up_Symbol_Buffer[8];break;
case 14 : SBUF=Uart1_Up_Symbol_Buffer[9];break;
case 15 : SBUF=Uart1_Up_Symbol_Buffer[10];break;
case 16 : SBUF=Uart1_Up_Symbol_Buffer[11];break;
case 17 : SBUF=Uart1_Up_Symbol_Buffer[12];break;
case 18 : SBUF=Uart1_Up_Symbol_Buffer[13];break;
case 19 : SBUF=Uart1_Up_Symbol_Buffer[14];break;
case 20 : SBUF=Uart1_Up_Symbol_Buffer[15];break;
case 21 : SBUF=Uart1_Up_Symbol_Buffer[16];break;
case 22 : SBUF=Uart1_Up_Symbol_Buffer[17];break;
case 23 : SBUF=Uart1_Up_Num_Buffer[5];break; //发送数值 遥控
case 24 : SBUF=Uart1_Up_Num_Buffer[6];break;
case 25 : SBUF=Uart1_Up_Symbol_Buffer[18];break;//发送汉字的ASCII
case 26 : SBUF=Uart1_Up_Symbol_Buffer[19];break;
case 27 : SBUF=Uart1_Up_Symbol_Buffer[20];break;
case 28 : SBUF=Uart1_Up_Symbol_Buffer[21];break;
case 29 : SBUF=Uart1_Up_Symbol_Buffer[22];break;
case 30 : SBUF=Uart1_Up_Symbol_Buffer[23];break;
case 31 : SBUF=Uart1_Up_Symbol_Buffer[24];break;
case 32 : SBUF=Uart1_Up_Symbol_Buffer[25];break;
case 33 : SBUF=Uart1_Up_Symbol_Buffer[26];break;
case 34 : SBUF=Uart1_Up_Num_Buffer[7];break; //发送数值 超声波
case 35 : SBUF=Uart1_Up_Num_Buffer[8];break;
case 36 : SBUF=Uart1_Up_Num_Buffer[9];break;
case 37 : SBUF=Uart1_Up_Symbol_Buffer[27];break;//发送汉字的ASCII
case 38 : SBUF=Uart1_Up_Symbol_Buffer[28];break;
case 39 :count=0;break;//最后一步 没有发送字节,串口TI不会置1,所以不再发送
}
}
}
//*********************************《人人学会单片机》视频教程,祁绪电子2020-05
//串口中断,接收一个字节,马上发送N个字节,发送数组显示到电脑
//*********************************《人人学会单片机》视频教程,祁绪电子2020-05
void Uart1_Routine() interrupt 4
{
static char Uart1_ser_n=0; //用于接收计数
if(RI) //如果接收到一个字节
{
RI=0; //标志位清除
Uart1_Flag=1; //串口发送允许
if(SBUF==0x7f)//9600波特率 //判断连续多个0x7f
{
Uart1_ser_n++; //判断连续多个0x7f
if(Uart1_ser_n>=10) //判断连续多个0x7f
{
Uart1_ser_n=0; //清0
IAP_CONTR|=0xe0; //执行自动软复位,可以做调试用
}
}
}
if(TI) //如果上一个字节发送完成了
{
TI=0; //标志位清除
Uart1_Flag=1; //串口发送允许
Uart1_Up_Data_Drive(); //执行串口发送下一个字节
}
},这么长时间你还搞不出头绪,今天有兴致,把以前给你改写的示例程序补充标准验证码程序,经实物验证无误。可以直接使用到实物,记得转485。你再玩不转就无语了。
风向仪.zip (17.26 KB, 下载次数: 2)
,串口通讯注意工作频率,非波特率整倍工作频率会得到一定百分比固定误码率。,地板说的有道理,看看你用的晶振是不是11.0592M的倍数。