一种残膜回收机防缠绕挑膜装置的制 一种秧草收获机用电力驱动行走机构

传统串口通信LED屏的网络接口改造的制作方法

2022-10-26 05:24:53 来源:中国专利 TAG:

传统串口通信led屏的网络接口改造
技术领域
1.通讯技术领域。


背景技术:

2.由于以太网通信的流行,目前大多数据采集设备和信息输出设备纷纷改为tcpip包传输的网络设备,使得当前很多正常使用的串口led点阵屏也正面临淘汰,因传统的led屏用串口通过rs232协议通信,通信的距离就10到15米(降低波特率可以适当延长通信距离,但也就20 至 30 米,还得牺牲数据传输的准确率),且速度慢,串口设备多时还要提供额外的串口阵列设备,新的网络通信的led屏传输速度快,可靠,且不存在由于电源共地而引起的噪声干扰和安全隐患。大量的串口led屏丢弃实在可惜,作者提出一套对这种led显示屏切实可用的改造方案,既可以不用对系统软件做修改和调整,还可以继续使用这些性能不错的传统的led屏,只须在led屏上加装一块以太网转串口的电路板,通过umdf虚拟串口驱动,将原来发送到串口的信息转发到以太网,就轻松实现了外围设备的升级改造,为企业赢得了良好的经济效益。。


技术实现要素:

3.原理图见附图1:一、硬件改造,led屏上添加一块以太网转串口的电路板,或直接更换为可接受以太网数据包的控制卡,出于兼容性考虑,我们此次使用的是杨屹的51上网卡,该板cpu为p89c51rd2, p89c51系列单片机是飞利浦公司在兼容mcs-51内核结构的基础上对标准的mcs-51内核进行改进后推出的一个增强型mcs-51单片机系列, 共有1024字节内置ram,64k eeprom,资源非常丰富,再加之电路板外扩了两片cy62256ram芯片,使得ram增加到64k,足以完成ucosii的移植了。该板的网络接口芯片为rtl8019as,兼容ne2000,是由realtek公司出的一款高集成度的以太网控制芯片,具有8/16位总线模式,集成了ieee802.3协议标准的介质访问控制子层(mac)和物理层的性能,内置的双dma通道和fifo完成简单有效的包管理(数据帧的接收和发送)功能,本地dma通道的传输速率高达10mbit/s,支持以太网全双工通信方式,支持utp,aui和bnc自动检测, 支持16 条i/o 基本地址选项和额外i/o地址输入输出完全解码方式,支持存储器瞬时读写,收发可同时达到10mbps的速率,内置16kb的sram,可以方便的与微处理器进行连接。电路原理见附图2、附图3:。
4.51上网卡采用了杨屹的ucos51,是ucos-ii在8051系列单片机上的移植,ucosii由micrium公司提供,是一个可移植、可固化的、可裁剪的、占先式多任务实时内核,它适用于多种微处理器,微控制器和数字处理芯片(已经移植到超过100种以上的微处理器应用中),同时,该系统源代码开放、整洁、一致,注释详尽,适合嵌入式系统开发。该板接收tcpip信息包,翻译成对应的串口信号(如若不清楚串口协议,可以使用bushound 软件跟踪),ucos51内部已经集成了对应芯片的tcpip协议,http协议,串口输出则更简单,使用printf输出即可,由于采用ucosii架构,我们推荐使用serial_send函数,该函数考虑了多任务代码的可
重入性。由此编写代码就显得格外轻松了,只需修改框架中的tcpip.c,部分关键代码,相应的代码如下:void tcp_rcve(uchar xdata * inbuf, uint len){
ꢀꢀꢀ
uchar idata i, j, nr;
ꢀꢀꢀ
uint idata result, header_len, data_len;
ꢀꢀꢀ
tcp_header xdata * tcp;
ꢀꢀꢀ
ip_header xdata * ip;
ꢀꢀꢀ
ulong idata sum;
ꢀꢀꢀ
// ip header is always 20 bytes so message starts at index 34
ꢀꢀꢀ
tcp = (tcp_header xdata *)(inbuf 34);
ꢀꢀꢀ
ip = (ip_header xdata *)(inbuf 14);
ꢀꢀꢀꢀ
// compute tcp checksum including 12 byte pseudoheader
ꢀꢀꢀꢀ
// sum source_ipaddr, dest_ipaddr, and entire tcp message
ꢀꢀꢀꢀ
sum = (ulong)cksum(inbuf 26, 8 len);
ꢀꢀꢀꢀ
// add in the rest of pseudoheader which is
ꢀꢀꢀꢀ
// protocol id and tcp segment length
ꢀꢀꢀꢀ
sum = (ulong)0x0006;
ꢀꢀꢀꢀ
sum = (ulong)len;
ꢀꢀꢀꢀ
// in case there was a carry, add it back around
ꢀꢀꢀꢀ
result = (uint)(sum (sum 》》 16));
ꢀꢀꢀꢀ
if (result != 0xffff)
ꢀꢀꢀꢀ
{
ꢀꢀꢀꢀꢀꢀꢀꢀ
if (debug) serial_send("tcp: error, bad cksum\r");
ꢀꢀꢀꢀꢀꢀꢀꢀ
return;
ꢀꢀꢀ
}
ꢀꢀꢀꢀ
if (debug) serial_send("tcp: msg rcvd with good cksum\r");
ꢀꢀꢀꢀ
// see if message is for http server
ꢀꢀꢀꢀ
if (tcp-》dest_port != http_port)
ꢀꢀꢀꢀꢀꢀꢀ
{
ꢀꢀꢀꢀꢀꢀ
if (debug)
ꢀꢀꢀꢀꢀꢀ
{
ꢀꢀꢀꢀꢀꢀꢀꢀꢀ
serial_send("tcp: error, msg to port ");
ꢀꢀꢀꢀꢀꢀꢀꢀꢀ
memset(text, 0, 10);
ꢀꢀꢀꢀꢀꢀꢀꢀꢀ
itoa(tcp-》dest_port, text, 10);
ꢀꢀꢀꢀꢀꢀꢀꢀꢀ
serial_send(text);
ꢀꢀꢀꢀꢀꢀꢀꢀꢀꢀꢀ
serial_send("\r");
ꢀꢀꢀꢀꢀꢀ
}
ꢀꢀꢀꢀꢀꢀ
tcp_send(flg_rst, 20, no_connection);
ꢀꢀꢀꢀꢀꢀ
return;
ꢀꢀꢀ
}
ꢀꢀꢀ
// capture sender's ip address and port number
ꢀꢀꢀ
sender_ipaddr = ip-》source_ipaddr;
ꢀꢀꢀ
sender_tcpport = tcp-》source_port;
ꢀꢀꢀ
// see if the tcp segment is from someone we are already
ꢀꢀꢀ
// connected to.
ꢀꢀꢀ
for (i=0; i 《 5; i )
ꢀꢀꢀ
{
ꢀꢀꢀꢀꢀꢀ
if ((ip-》source_ipaddr == conxn[i].ipaddr) &&
ꢀꢀꢀꢀꢀꢀꢀꢀꢀ
(tcp-》source_port == conxn[i].port))
ꢀꢀꢀꢀꢀꢀ
{
ꢀꢀꢀꢀꢀꢀꢀꢀꢀ
nr = i;
ꢀꢀꢀꢀꢀꢀꢀꢀꢀ
if (debug) serial_send("tcp: rcvd msg from existing conxn\r");
ꢀꢀꢀꢀꢀꢀꢀꢀꢀ
break;
ꢀꢀꢀꢀꢀꢀ
}
ꢀꢀꢀ
}二、完成了硬件改造后,相应地要调整软件的信息输出。我们使用umdf拟串口驱动把信息输出到以太网:user-mode driver framework(用户模式驱动程序架构,简称umdf),是美国微软公司所提出视窗驱动程序基础(windows driver foundation)的一部分,运行于用户模式(user mode),仅能访问用户地址空间,是核心模式驱动程序框架(kernel-mode driver framework,kmdf)的子集合,因此umdf所提供的函数支持少于kmdf,umdf驱动程序是一个基于com架构的动态链接档(dll),但umdf并不使用com的动态时期运行函数,而使用dllmain,即 dll档的进入点。
[0005]
我们安装的是wdk7.1(wdk8.1大致相同),完成安装后,只需打开queue.cpp,文件位置如图见附图4:之后修改processwritebytes函数,因为访问led屏并不需要回读。
[0006]
void cmyqueue::processwritebytes(
ꢀꢀꢀꢀ
__in_bcount(length) puchar characters,
ꢀꢀꢀꢀ
__in size_t length
ꢀꢀꢀꢀ
){
ꢀꢀꢀꢀ
uchar currentcharacter;
ꢀꢀꢀꢀ
uchar connectstring[] = "\r\nconnect\r\n";
ꢀꢀꢀꢀ
uchar connectstringcch = array_size(connectstring)
ꢀ‑ꢀ
1;
ꢀꢀꢀꢀ
uchar okstring[] = "\r\nok\r\n";
ꢀꢀꢀꢀ
uchar okstringcch = array_size(okstring)
ꢀ‑ꢀ
1;
ꢀꢀꢀꢀ
ushort i,j;
ꢀꢀꢀꢀ
ushort pos;
ꢀꢀꢀꢀ
for (i=0;i《length;i )
ꢀꢀꢀꢀ
{
ꢀꢀꢀꢀꢀꢀꢀꢀ
combuffer_recv[i] = characters[i];
ꢀꢀꢀꢀ
}
ꢀꢀꢀꢀ
if(length《0x21)
ꢀꢀꢀꢀꢀꢀꢀꢀ
for(i=(ushort)length;i《0x21;i ) combuffer_recv[i]=0x20;
ꢀꢀꢀꢀ
for(i=0;i《0x10;i )
ꢀꢀꢀꢀ
{
ꢀꢀꢀꢀꢀꢀꢀꢀ
led1[i]=combuffer_recv[1 i];
ꢀꢀꢀꢀꢀꢀꢀꢀ
led2[i]=combuffer_recv[0x11 i];
ꢀꢀꢀꢀ
}
ꢀꢀꢀꢀ
for(i=0;i《93;i ) ledmess[i]=mled[i];
ꢀꢀꢀꢀ
pos=58;
ꢀꢀꢀꢀ
for(i=0;i《16;i )
ꢀꢀꢀꢀ
{
ꢀꢀꢀꢀꢀꢀꢀꢀ
ledmess[pos i]=led1[i];
ꢀꢀꢀꢀꢀꢀꢀꢀ
ledmess[pos 16 i]=led2[i];
ꢀꢀꢀꢀ
}
ꢀꢀꢀꢀ
crcvalue=calccrc(ledmess 8,82);
ꢀꢀꢀꢀ
ledmess[90]=lobyte(crcvalue);
ꢀꢀꢀꢀ
ledmess[91]=hibyte( crcvalue);
ꢀꢀꢀꢀ
for(i=0,j=0;i《58;i ,j )
ꢀꢀꢀꢀ
{
ꢀꢀꢀꢀꢀꢀꢀꢀ
ledmessout[j]=ledmess[i];
ꢀꢀꢀꢀ
}
ꢀꢀꢀꢀ
for(i=58,j=58;i《90;i ,j )
ꢀꢀꢀꢀ
{
ꢀꢀꢀꢀꢀꢀꢀꢀ
switch(ledmess[i])
ꢀꢀꢀꢀꢀꢀꢀꢀ
{
ꢀꢀꢀꢀꢀꢀꢀꢀ
case 0x5a:
ꢀꢀꢀꢀꢀꢀꢀꢀꢀꢀꢀꢀ
ledmessout[j]=0x5b;//ledmess[i];
ꢀꢀꢀꢀꢀꢀꢀꢀꢀꢀꢀꢀ
ledmessout[j 1]=0x02;
ꢀꢀꢀꢀꢀꢀꢀꢀꢀꢀꢀꢀ
j ;
ꢀꢀꢀꢀꢀꢀꢀꢀꢀꢀꢀꢀ
break;
ꢀꢀꢀꢀꢀꢀꢀꢀ
case 0x5b:
ꢀꢀꢀꢀꢀꢀꢀꢀꢀꢀꢀꢀ
ledmessout[j]=0x5b;//ledmess[i];
ꢀꢀꢀꢀꢀꢀꢀꢀꢀꢀꢀꢀ
ledmessout[j 1]=0x01;
ꢀꢀꢀꢀꢀꢀꢀꢀꢀꢀꢀꢀ
j ;
ꢀꢀꢀꢀꢀꢀꢀꢀꢀꢀꢀꢀ
break;
ꢀꢀꢀꢀꢀꢀꢀꢀ
case 0xa5:
ꢀꢀꢀꢀꢀꢀꢀꢀꢀꢀꢀꢀ
ledmessout[j]=0xa6;//ledmess[i];
ꢀꢀꢀꢀꢀꢀꢀꢀꢀꢀꢀꢀ
ledmessout[j 1]=0x02;
ꢀꢀꢀꢀꢀꢀꢀꢀꢀꢀꢀꢀ
j ;
ꢀꢀꢀꢀꢀꢀꢀꢀꢀꢀꢀꢀ
break;
ꢀꢀꢀꢀꢀꢀꢀꢀ
case 0xa6:
ꢀꢀꢀꢀꢀꢀꢀꢀꢀꢀꢀꢀ
ledmessout[j]=0xa6;//ledmess[i];
ꢀꢀꢀꢀꢀꢀꢀꢀꢀꢀꢀꢀ
ledmessout[j 1]=0x01;
ꢀꢀꢀꢀꢀꢀꢀꢀꢀꢀꢀꢀ
j ;
ꢀꢀꢀꢀꢀꢀꢀꢀꢀꢀꢀꢀ
break;
ꢀꢀꢀꢀꢀꢀꢀꢀ
default:
ꢀꢀꢀꢀꢀꢀꢀꢀꢀꢀꢀꢀ
ledmessout[j]=ledmess[i];
ꢀꢀꢀꢀꢀꢀꢀꢀ
}
ꢀꢀꢀꢀ
}
ꢀꢀꢀꢀ
ledmessoutlen=j 3;
ꢀꢀꢀꢀ
ledmessout[j 0]=ledmess[90];
ꢀꢀꢀꢀ
ledmessout[j 1]=ledmess[91];
ꢀꢀꢀꢀ
ledmessout[j 2]=ledmess[92];
ꢀꢀꢀꢀ
wversionrequested=makeword(2,0);
ꢀꢀꢀꢀ
err=wsastartup(wversionrequested,&wsadata);
ꢀꢀꢀꢀ
if(0!=err)
ꢀꢀꢀꢀ
{
ꢀꢀꢀꢀꢀꢀꢀꢀ
return;
ꢀꢀꢀꢀ
}
ꢀꢀꢀꢀ
if(lobyte(wsadata.wversion)!=2||hibyte(wsadata.wversion)!=0)
ꢀꢀꢀꢀ
{
ꢀꢀꢀꢀꢀꢀꢀꢀ
wsacleanup();
ꢀꢀꢀꢀꢀꢀꢀꢀ
return;
ꢀꢀꢀꢀ
}
ꢀꢀꢀꢀ
sock=socket(af_inet,sock_dgram,0);
ꢀꢀꢀꢀ
bool opt=true;setsockopt(sock,sol_socket,so_broadcast,reinterpret_cast《char far *》(&opt),sizeof(opt));
ꢀꢀꢀꢀ
sockaddr_in addrto;
ꢀꢀꢀꢀ
memset(&addrto,0,sizeof(addrto));
ꢀꢀꢀꢀ
addrto.sin_family=af_inet;
ꢀꢀꢀꢀ
addrto.sin_addr.s_addr=inet_addr(my_ip);
ꢀꢀꢀꢀ
addrto.sin_port=htons(5007);
ꢀꢀꢀꢀ
int nlen =sizeof(addrto);
ꢀꢀꢀꢀ
unsigned int uindex=1;
ꢀꢀꢀꢀ
uindex=uindex;
ꢀꢀꢀꢀ
if(sendto(sock,(char )ledmessout,ledmessoutlen,0,(sockaddr*)&addrto,nlen)==socket_error)
ꢀꢀꢀꢀ
{
ꢀꢀꢀꢀ
}
ꢀꢀꢀꢀ
if(!closesocket(sock))
ꢀꢀꢀꢀ
}
ꢀꢀꢀꢀ
if(!wsacleanup())
ꢀꢀꢀꢀ
{
ꢀꢀꢀꢀ
}
ꢀꢀꢀꢀ
while (length != 0) {
ꢀꢀꢀꢀꢀꢀꢀꢀ
currentcharacter = *(characters );
ꢀꢀꢀꢀꢀꢀꢀꢀ
length
‑‑
;
ꢀꢀꢀꢀꢀꢀꢀꢀ
if(currentcharacter == '\0')
ꢀꢀꢀꢀꢀꢀꢀꢀ
{
ꢀꢀꢀꢀꢀꢀꢀꢀꢀꢀꢀꢀ
continue;
ꢀꢀꢀꢀꢀꢀꢀꢀ
}
ꢀꢀꢀꢀꢀꢀꢀꢀ
m_ringbuffer.write(&currentcharacter, sizeof(currentcharacter));修改完毕后,使用开始菜单windows driver kits/wdk 7600.16385.1/build enviroment/windows7子菜单下x86 checked build environment 选项,进入dos编译环境,选择驱动所在目录,运行build
ꢀ–
icz,完成驱动程序编译,如果代码无错误,会在当前文件夹下生成objchk_wxp_x86/386目录,里面有相应的dll 用户驱动文件和inf 驱动安装文件。安装驱动时,拷贝wudfupdate_01009.dll 和 virtualserial.inf到windows\system32\drivers\umdf文件夹下,运行devcon install virtualserial.inf umdf\virtualserial(升级时则是devcon update virtualserial.inf umdf\virtualserial),系统就会自动安装对应的虚拟串口驱动,运行几次就生成几个虚拟串口,如果有多个功能相同的虚拟串口,windows\system32\drivers\umdf文件夹下可以提供配置文件加以区分,当软件读写这些虚拟串口时,数据将发往由配置文件指定的tcpip端口。
[0007]
这种方法实际应用起来,不仅开发周期短,使用效果也很好。之后如系统软件升级,也非常的方便。
[0008]
结论:这种方法其实不仅可用于升级改造串口led屏,诸如其他的串口设备,甚至其他接口的硬件设备,都可以用类似的方法改造,使我们可以方便的调整计算机的外围设备,由于可以定制驱动程序,主体程序不修改也可以,这大大缩短了升级改造的时间,为企业赢取了效益。需要注意的是ucos ii以源代码的形式发布,是开源软件, 但并不意味着它是免费软件。但是如果你将其用于商业用途,那么你必须通过micrium获得商用许可,下一步要考虑更换成另一免费的嵌入式系统(如freertos、rtx51 lwip)。附图说明:
[0009]
附图1为系统实现原理图;附图2、附图3为低成本串口转以太网电路板原理图;附图4为驱动程序所在的位置。
再多了解一些

本文用于创业者技术爱好者查询,仅供学习研究,如用于商业用途,请联系技术所有人。

发表评论 共有条评论
用户名: 密码:
验证码: 匿名发表

相关文献