Linux与单片机串口通信

   近期要做一个机械臂的小项目,作为ROS和MoveIt的实践平台,上位机和工控机之间暂定为串口通信。
上位机:Ubuntu18.04虚拟机
工控机:STC89C51,编程环境为keil5
   由于选择了早已过时的C51作为下位机,互联网上并没有太多相关资料,因此串口通讯的程序由STM32的串口改写而来。
在改写的过程中出现许多莫名其妙的BUG,记录在此博客。

运行ROS串口发送节点后异常中断

具体原因为串口为开放权限,解决方案如图:

在这里插入图片描述

栈溢出问题

(未及时截图,找不到具体错误信息。但错误代码从中出现了Stack
  许多帖子出现栈溢出都是在TCP传输环节,即传输数据过大。但本次栈溢出问题原因是发送缓存数组在传输数据变更(加长)后定义未及时变更导致了在为缓存数组赋值时溢出。

catkin_make报错:函数未定义的引用

  1. 工作空间下同名功能包替换时最好删除builddevel两个文件夹中原有功能包编译结果;
  2. 在更改函数实现的同时函数调用及声明应同步更新;

ERROR L107: ADDRESS SPACE OVERFLOW

  此运行错误为工控机在keil环境下报错,错误原因为单片机内存溢出(md,单片机的内存果然是和房价一样的存在)
  具体出现该问题原因是串口调试调用了两次“printf”,一次占用2K内存,让本不富裕的C51雪上加霜。可使用串口用直接输出来代替printf输出运行信息来改进程序。另外目前工控机的程序还少,许多博客都有写到大型工程不可避免的出现内存溢出问题,可通过指定变量的内存空间来改进。

串口实验总结

程序组织

程序组织注意两点:时序波特率
  严格来说波特率也是时序的组成部分,即一个数据包中两位数据间发送间隔(个人理解)我所使用的STC89C52单片机的烧写软件提供波特率计算工具,可以直接受用。但有一点要注意:在设定波特率前要了解单片机的型号及始时钟信息有些单片机是到不了115200的,所以比较推荐的是9600的波特率。(你尽可以不信,但我已经为它浪费了几小时了)
  时序主要指两个数据包之间的发送间隔,要综合考量数据收发和该段指令执行的时间来制定。具体到本项目即各轴输出PWM的执行时间。
  另外还有多位16进制的数据打包发送和字符串发送的问题。前者采用数据头+数据长+数据内容+循环校验位+数据尾打包发送来解决;后者采用了C语言共用体的结构,具体可查其他博客。

程序重点部分分享如下:

串口接收中断:

	void send_data() interrupt 4 //串口接收中断
{
	if(RI==1)
 	 {
		//testRece4 = UART_ReceiveData();
	  //usart_send(testRece4);
		 
		usartReceiveOneData(&testRece1,&testRece2,&testRece3,&testRece4);
		usart_send(testRece4);
		
	 }
	 if(TI==1)
		 //usart_send(testRece4);
		 TI = 0;//通过软件的方式置零
}

串口发送字符串:

void USART_Send_String(unsigned char *p,unsigned short int sendSize)
{ 
	static int length =0;
	while(length<sendSize)
	{   
		
		while( *p!=0 );
		
		*p = SBUF;
		while(!TI);
		TI=0;    		
		p++;
		length++;
	}
	length =0;
}

(具体工程有些长,可私信分享交流,但PWM不行)
我是绝对不会说我最开始想用直流减速电机做机械臂的,绝对不会

串口调试

串口调试的过程主要是检验收发是否正常,故可采用发送刚接收到的字符的放法来调试。

Logo

华为开发者空间,是为全球开发者打造的专属开发空间,汇聚了华为优质开发资源及工具,致力于让每一位开发者拥有一台云主机,基于华为根生态开发、创新。

更多推荐