二进制数组不像字符串一样有结束标志,不能直接用发送数组的函数发送,
作如下修改就可以了(仿真输出结果见代码后面的图):
#include<reg52h>//注意:110592M晶振 波特率9600sbit key1=P2^0;
sbit key2=P2^1;
unsigned char code J50_2[ ]={0X00,0X00,0XFF,0X09,0X09,0XFF,0XFF,0X4B,0X22,0X01,0X03,0X01,0X0A,0X0A,0X7C,0X00}; //如何发送出去
unsigned char code J50_3[ ]={0X00,0X00,0XFF,0X09,0X09,0XFF,0XFF,0XAC,0X22,0X02,0X03,0X01,0X0A,0X0A,0X1A,0X00}; //如何发送出去
unsigned char code String1[ ]={"Test 1 Pass !\r\n"};
unsigned char code String2[ ]={"Test 2 Pass !\r\n"};
/
函数功能:延时若干毫秒
/
void delayms(unsigned int ms)
{
unsigned int i;
while(ms--)
for(i=0;i<600;i++);
}
/
函数功能:向PC发送一个字节数据
/
void SendByte(unsigned char dat)
{
SBUF=dat;
while(TI==0);
TI=0;
}
/
函数功能:向PC发字符串
/
void SendStr(unsigned char str) //第2种发送字符串函数
{
while(str!=0)
{
SendByte(str);
str++;
delayms(1); //延时 N ms
}
}
/
函数功能:向串口发n个字节数据
/
void SendnBytes(unsigned char str,unsigned int n) //发送n个字节函数
{
while(n--!=0)
{
SendByte(str);
str++;
delayms(1); //延时 N ms
}
}
/
函数功能:串口初始化
/
void UartInit(void)
{
SCON=0x50; //串口工作方式1,8位UART,波特率可变
TH2=0xFF;
TL2=0xFD; //波特率:115200 晶振=110592MHz
RCAP2H=0xFF;
RCAP2L=0xFD; //16位自动再装入值
TCLK=1;
RCLK=1;
C_T2=0;
EXEN2=0; //波特率发生器工作方式
TR2=1 ; //定时器2开始
}
/
函数功能:主函数
/
void main(void)
{
UartInit();
SendStr("How are you!\r\n");
while(1)
{
//SendStr(J50_2); //发送不成功
SendnBytes(J50_2,sizeof(J50_2)); //发送成功
if(key1==0)
{
P1=0xFE;
SendStr(String1); //发送数据
delayms(10); //10ms发送一次数据
P1=0XFF;
delayms(10);
}
//SendStr(J50_3); //发送不成功
SendnBytes(J50_3,sizeof(J50_3)); //发送成功
if(key2==0)
{
P1=0xFD;
SendStr(String2); //发送数据
delayms(10); //10ms发送一次数据
P1=0XFF;
delayms(10);
}
}
}
#include "reg2h"
#include <intrinsH>
typedef unsigned char uchar;
typedef unsigned int uint;
bit busy;
bit Flag;
uchar GetC;
void InitUART(void);
void SendData(uchar dat);
void SendString(uchar s);
void main()
{
uchar i;
InitUART();
SendString("Uart Test !\r\n");
while(1)
{
for(i=0;i<100;i++)
SendData(i);
}
}
/----------------------------
UART1初始化
-----------------------------/
void InitUART(void)
{
SCON = 0x50; //8位可变波特率
TMOD = 0x20; //定时器1为模式2(8位自动重载)
TL1 = 0xFD; //设置波特率重装值
TH1 = 0xFD;
TR1 = 1; //定时器1开始工作
ES = 1; //使能串口中断
EA = 1;
}
/----------------------------
UART 中断服务程序
-----------------------------/
void Uart() interrupt 4 using 1
{
if (RI)
{
RI = 0; //清除RI位
GetC = SBUF; //P0显示串口数据
Flag=1;
}
if (TI)
{
TI = 0; //清除TI位
busy = 0; //清忙标志
}
}
/----------------------------
发送串口数据
----------------------------/
void SendData(uchar dat)
{
while (busy); //等待前面的数据发送完成
busy = 1;
SBUF = dat; //写数据到UART数据寄存器
}
/----------------------------
发送字符串
----------------------------/
void SendString(uchar s)
{
while (s) //检测字符串结束标志
{
SendData(s++); //发送当前字符
}
}
我现在就给你写个,
unsigned char n;
unsigned char tab[20]; 定义一个有20个元素的数组,其中每个元素是1BYTY
即8位2进制数。
for(n=0;n<20;n++) 做一个20次的循环
{
ES=0; 关闭串口中断,以免误进入中断程序,当然没有中断程序的话可以不关闭
SBUF=tab[n]; 把数组tab[20]中的数据依次装入串口发送寄存器;
while(!TI); 等待发送,
TI=0; 发送完1BYTE后,清除发送中断标志位,这里是采用查询法,也可以用
} 中断法
看来你是个初学者
希望对你有帮助!
ROS节点程序运行过程中需要获取机器人的传感器信息和发送控制指令,因此不可避免要与机器人进行通信,常见的通讯方式有串口、CAN和网口等,其中串口最为普遍。
ROS通过自带的 serial 包连接串口设备,进行串口通信,需要提前安装 serial 包:
sudo apt-get install ros-melodic-serial
串口通信根据数据传输方向可以分为 串口发送 和 串口接收 。
通过串口发送数据时,需要明确发送机制,常见的发送机制有:
定时发送是通过设定定时器,以 固定频率 发送数据包;
触发条件发送是通过条件判断语句,判断某个标志位或某个事件发生后,再发送数据包,特点是 频率不固定 。
发送数据分为两个步骤:
由此可知buffer数据结构需要可同时被这两个步骤访问,buffer需要为全局变量。
首先根据通信协议定义buffer中的帧头、帧尾等固定内容,然后接收别的Topic,获取待发送数据,把获取的数据填入到协议的数据段,最后根据数据段计算校验码。
1 订阅发送数据的Topic
serial_sub = nhsubscribe("/joy", 10, &DecodeFrame::serial_sub_callback,this);
2 根据Topic填入数据段和校验
1 创建定时回调函数
首先需要创建一个定时器,设定发送频率,并指定回调函数名称
write_rs232_timer = nhcreateTimer(ros::Duration(001), &DecodeFrame::CB_write_rs232_Cycle, this);
2 通过 serial 将buffer数据写入串口设备
实例化串口对象,并打开串口
发送数据到串口设备上
注意1:发送数据节点挂掉
若发送数据Topic的节点挂掉后,由于buffer是全局变量,buffer的数据段会一直是上一帧的数据,不会再改变,为避免上述情况,在将数据写入串口设备后, 将数据段清零。
注意2:joystick包发送机制
在使用PS3/PS4、Xbox手柄时,使用ros-melodic-joy包获取摇杆数据,手柄的遥杆或者按键如果一直处于同一位置(初始零位和最大值)只会发送一帧数据,不会连续发送, 只有当摇杆数据变化时,才会发送数据。
因此使用 rostopic hz /joy 会显示没有msg信息传输,所以串口程序不会进回调函数获取发送数据,但是数值确实是一直保持的, 所以就不能将数据段清零。
触发条件发送与定时发送相比的最大不同之处在于发送频率不同,不需要设置定时器,在满足条件后直接将数据写入串口即可。
程序采用了查询式发送,for(i=0;i<6;i++) {SendChar(askconfig[i]); },共发送了6个字符。
再去查询收到否。
这种方法,就是有问题的,发送6个字符时,就可能收到了好几个字符,而没有及时保存,完全可能丢失信息。
应该采用中断方式接收;发送,也可以用查询,也可以用中断。
方法弄清楚了,程序就容易编写、调试了。
#include <AT89X51h>
#define uchar unsigned char
#define uint unsigned int
uchar idata trdata[]={'8','9','S','5','1',0x0d,0,0x00};
uchar idata trdata1[]={'R','I','C','H','M','C','U',0x0d,0,0x00};
main()
{
uchar i;
uint j;
SCON= 0x40; //串口方式1
PCON=0; //SMOD=0
REN=1; //允许接收
TMOD= 0x20; //定时器1定时方式2
TH1= 0xe6; //12MHz 1200波特率
TL1= 0xe6;
TR1= 1; //启动定时器
while(1)
{
i=0;
while(trdata[i]!=0x00)
{
SBUF=trdata[i];
while(TI==0);
TI=0;
i++;
}
for (j=0;j<50000;j++);
i=0;
while(trdata1[i]!=0x00)
{
SBUF=trdata1[i];
while(TI==0);
TI=0;
i++;
}
for (j=0;j<50000;j++);
}
}
你用的是AVR单片机吧,这种单片机里面是没有串口接收FIFO的,所以每次只能是接收一个字节数据,否则接收寄存器就溢出了,想接收多个字节指令,就需要你把每次接到的数据一次次串起来,在程序里组装这些数据然后存储
1 字符和字节的关系
一个字符占用1个字节存储单元。
2 字节变量和字节变量指针
pd: 是一个字符型指针变量(存储的是某个字符内存地址)
pd: 是间接寻址(代表的是 某个字符 不是字符的地址)
3 UartPutChar(pd) 与void UartPutChar(uint8 d)
UartPutChar(pd) 中 pd 是把字符变量 传给UartPutChar( )这个函数
注意,如果是 UartPutChar(pd) 那就错了啊
========================================
hzm_888@163com
如果有不详细的地方,请继续提问!
软件开发(VB / VC++/PLC/组态软件)、单片机设计
松下伺服 PLC:
松下伺服:
MHMD082G1U+MCDHT3520
MHMD042G1U+MBDHT2510
西门子 触摸屏 PLC 变频器:
CPU224 CPU226 CPU313 CPU314 CPU315, SMART 1000
PRO-FACE触摸屏:
三菱 PLC: FX1N FX2N /
以上就是关于单片机串口发送数组,程序如下,请帮忙修改!!!全部的内容,包括:单片机串口发送数组,程序如下,请帮忙修改!!!、求助:单片机通过串口连续发送数据0-99的c程序、求一个51串口发送数组程序等相关内容解答,如果想了解更多相关内容,可以关注我们,你们的支持是我们更新的动力!
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)