您的位置:首页 > 其它

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;

同时为了避免通讯死,需要加时延控制,超时即退出,当然也可采用重发来对应答来计数,一般来讲发出数据后就应该等待接受应答,发送若干次后没有应答即返回通讯失败。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: