UART之一:读写操作及package组合
2009-12-15 22:19
176 查看
Universal Asynchronous Receiver/Transmitter,通用异步接收/发送装置,其过程为:CPU先把准备写入串行设备的数据放到UART的寄存器(临时内存块)中,再通过FIFO(First Input First Output,先入先出队列)传送到串行设备,从串行设备接收数据也是如此,先缓存到FIFO中再给CPU。
(1)下面举例来说明常用的底层UART器件通讯的写法:硬件上除了在要将RXD跟TXD对应起来,还要加上拉电压跟限流电阻。以一个遥控器同时控制模拟电视跟LG高频头为例,一般的通讯都有写入跟读取,我们省略了读取数据。对高频头的控制全部都是通过写入一组数据来控制的,比如上下左右操作,设置OSD语言,静音等状态。制定协议格式如下:
StartCode(0xfc)+Length(0x02)+~Length(0xfd)+Data1+Data2+ChecSum+StopCode(0xf3).
所以我们定义用一个数组就可以定义一个指令,以此类推,不同的指令不同的DATA码。如:
Const U8 DVB_MuteKey[]=
{
0x07, //Command Length for write use,表示有7个字节要写入
0xfc, // StartCode
0x02, // Length
0xfd, //~Length
0x01,0x03,0x04 // Data1, Data2, ChecSum
0xf3 // StopCode
};
那么UART的基础写指令如下:
void DVB_RS232_WRITE(U8 *DData)
{
U8 i;
U16 j;
for(i=1;i<=DData[0];i++)
{
while(TXEND_URSTS2!=1); //如果发送状态没有准备好就一直等待
for(j=0;j<1000;j++);//for delay
TDATA_URTDAT2=DData[i]; //丢数据到发送寄存器
}
while(TXEND_URSTS2!=1);
}
此处UART的写操作是查询来做的,上面就是发送指令过程中检测到发送完成后,就将下一个字节继续丢到发送缓冲区中,否则等待。
由于是将遥控指令转发给高频头,所以需要将遥控码先转成高频头的指令名,再通过查找高频头的指令名来发送对应的指令数据。先定义一个结构体:
typedef struct
{
U8 keynum;
const U8 *command;
}DVB_COM_COMMAND;
用这个结构体来完成所有指令和指令数据码的对应关系,所以定义一个数组。如:
const DVB_COM_COMMAND command_tab[]=
{
{DVBT_NUM0, NUM0_KEY}, //前者是指令名,后者是指令码数组名
{DVBT_NUM1, NUM1_KEY},
{DVBT_MUTE, DVB_MuteKey },
……………
};
在遥控转发前先检测这指令发给DVBT是否有效,如果有效就返回,无效再继续给ATV处理。如下:
signed DVB_T_SET_Comd(U8 key)
{
U8 i;
signed ret=WRONG;
U8 counter= sizeof(command_tab)/sizeof(DVB_COM_COMMAND);
for(i=0;i<counter;i++)
{
if(command_tab[i].keynum==key)
{
DVB_RS232_WRITE(command_tab[i].command);
ret=TRUE;
break;
}
}
return ret;
}
(2)以上是简单的快捷的操作方式。当然对于较复杂的通讯,都要定义一定的指令格式,这个时候为了便于结构化编程的目的,使用了结构体来。如:
typedef struct Data_format_s
{
UINT8 Cmd1; //first command
UINT8 Cmd2; //second command
UINT16 CmdLen;//command length
UINT16 CRCCode;//CRC code
UINT16 Pos; //corresponding position
UINT8 EepData[16];
UINT8 Stop;
}Data_format_t; //25 bytes
读写都要按照这个结构体的统一格式来操作,包括发送指令和接收。
(3)更复杂的操作,比如指令码捆绑特定操作函数的,可用结构体来把查表操作和对应的函数联系起来,如:
typedef void(*pfunc)(UINT32);
typedef struct
{
UserHPC_IR_type keynum; //按键值
const UINT8 * command; //按键指令码
pfunc pfunction; //按键的操作,比如换台
}Ins_Command;
同时为了避免通讯死,需要加时延控制,超时即退出,当然也可采用重发来对应答来计数,一般来讲发出数据后就应该等待接受应答,发送若干次后没有应答即返回通讯失败。
(1)下面举例来说明常用的底层UART器件通讯的写法:硬件上除了在要将RXD跟TXD对应起来,还要加上拉电压跟限流电阻。以一个遥控器同时控制模拟电视跟LG高频头为例,一般的通讯都有写入跟读取,我们省略了读取数据。对高频头的控制全部都是通过写入一组数据来控制的,比如上下左右操作,设置OSD语言,静音等状态。制定协议格式如下:
StartCode(0xfc)+Length(0x02)+~Length(0xfd)+Data1+Data2+ChecSum+StopCode(0xf3).
所以我们定义用一个数组就可以定义一个指令,以此类推,不同的指令不同的DATA码。如:
Const U8 DVB_MuteKey[]=
{
0x07, //Command Length for write use,表示有7个字节要写入
0xfc, // StartCode
0x02, // Length
0xfd, //~Length
0x01,0x03,0x04 // Data1, Data2, ChecSum
0xf3 // StopCode
};
那么UART的基础写指令如下:
void DVB_RS232_WRITE(U8 *DData)
{
U8 i;
U16 j;
for(i=1;i<=DData[0];i++)
{
while(TXEND_URSTS2!=1); //如果发送状态没有准备好就一直等待
for(j=0;j<1000;j++);//for delay
TDATA_URTDAT2=DData[i]; //丢数据到发送寄存器
}
while(TXEND_URSTS2!=1);
}
此处UART的写操作是查询来做的,上面就是发送指令过程中检测到发送完成后,就将下一个字节继续丢到发送缓冲区中,否则等待。
由于是将遥控指令转发给高频头,所以需要将遥控码先转成高频头的指令名,再通过查找高频头的指令名来发送对应的指令数据。先定义一个结构体:
typedef struct
{
U8 keynum;
const U8 *command;
}DVB_COM_COMMAND;
用这个结构体来完成所有指令和指令数据码的对应关系,所以定义一个数组。如:
const DVB_COM_COMMAND command_tab[]=
{
{DVBT_NUM0, NUM0_KEY}, //前者是指令名,后者是指令码数组名
{DVBT_NUM1, NUM1_KEY},
{DVBT_MUTE, DVB_MuteKey },
……………
};
在遥控转发前先检测这指令发给DVBT是否有效,如果有效就返回,无效再继续给ATV处理。如下:
signed DVB_T_SET_Comd(U8 key)
{
U8 i;
signed ret=WRONG;
U8 counter= sizeof(command_tab)/sizeof(DVB_COM_COMMAND);
for(i=0;i<counter;i++)
{
if(command_tab[i].keynum==key)
{
DVB_RS232_WRITE(command_tab[i].command);
ret=TRUE;
break;
}
}
return ret;
}
(2)以上是简单的快捷的操作方式。当然对于较复杂的通讯,都要定义一定的指令格式,这个时候为了便于结构化编程的目的,使用了结构体来。如:
typedef struct Data_format_s
{
UINT8 Cmd1; //first command
UINT8 Cmd2; //second command
UINT16 CmdLen;//command length
UINT16 CRCCode;//CRC code
UINT16 Pos; //corresponding position
UINT8 EepData[16];
UINT8 Stop;
}Data_format_t; //25 bytes
读写都要按照这个结构体的统一格式来操作,包括发送指令和接收。
(3)更复杂的操作,比如指令码捆绑特定操作函数的,可用结构体来把查表操作和对应的函数联系起来,如:
typedef void(*pfunc)(UINT32);
typedef struct
{
UserHPC_IR_type keynum; //按键值
const UINT8 * command; //按键指令码
pfunc pfunction; //按键的操作,比如换台
}Ins_Command;
同时为了避免通讯死,需要加时延控制,超时即退出,当然也可采用重发来对应答来计数,一般来讲发出数据后就应该等待接受应答,发送若干次后没有应答即返回通讯失败。
相关文章推荐
- hdfs——hadoop文件读写操作
- 【原创】.NET读写Excel工具Spire.Xls使用(4)对数据操作与控制
- Python基础知识——Python中的读写操作read()和write()
- [学习笔记]Java 中对文件的读写操作之比较
- C语言文件读写操作总结
- Python 线程和 redis 简单读写操作应用
- python操作Excel读写(使用xlrd和xlrt)
- sqlserver 2005 xml字段的读写操作
- C#文件读写追加创建目录,判断目录是否存在等操作
- Android 学习笔记 文本文件的读写操作
- sqlserver2005 xml字段的读写操作
- 如何完成.Net下XML文档的读写操作[转载]
- QTP中实现对文本文件(txt)的读写操作
- python 操作excel 读写同一个文件
- Java 文件任意位置读写操作(首尾读写都可以)
- paip.erlang 文本文件读写操作attilax总结
- python学习笔记——文件读写操作
- [转]C#文件读写及相关操作
- Openwrt使用lua进行串口通信读写操作
- MFC文件读写操作