CH341A作为并口使用的时候,使用那个API控制IO其输出是带锁存的?

icon_rar.gifEXAM.rar

你好,使用CH341A的过程中遇到一些问题,请教如下:)


  1.  CH341A作为并口(同步串口)使用的时候,使用那个API控制IO其输出是带锁存的(无需外部加锁存芯片)?


2. EXAM.C 下面这个例子作为并口(同步串口)使用的时候,CH341A和TLC1549之间,CH341A输出引脚是否需要加锁存器电路? CH341A输入引脚是否需要加245隔离?  还是说CH341AheadTLC1549之间直连就可以了?


/* ********************************************************************************************** */

/* 用UIO通用I/O位流命令实现自定义的同步串行接口 */


/* UIO方式共可以使用8个I/O引脚D7-D0,最多可以8个输入或者6个输出

   上位机以字节流控制CH341对最终位流进行输入和输出,有4种基本操作和1个结束操作:

#definemCH341A_CMD_UIO_STM_IN0x00// UIO接口的命令流:输入数据D7-D0

#definemCH341A_CMD_UIO_STM_DIR0x40// UIO接口的命令流:设定I/O方向D5-D0,位5-位0为方向数据

#definemCH341A_CMD_UIO_STM_OUT0x80// UIO接口的命令流:输出数据D5-D0,位5-位0为数据

#definemCH341A_CMD_UIO_STM_US0xC0// UIO接口的命令流:以微秒为单位延时,位5-位0为延时值

#definemCH341A_CMD_UIO_STM_END0x20// UIO接口的命令流:命令包提前结束


   例子:操作10位ADC芯片TLC1549,其时序为非标准

   连线: CH341_D0 <-> TLC1549_CS, CH341_D1 <-> TLC1549_IO_CLK, CH341_D7 <-> TLC1549_DOUT

   下面是用UIO通用I/O位流命令实现的任意波形,参考下图波形(选择等宽的中文字体时才能看出)

         ______                                                                        ____________

  D0/out       |______________________________________________________________________|            |_________   TLC1549_CS#

         ____     ___    ___    ___    ___    ___    ___    ___    ___    ___    ___    Delay 24uS    ___

  D1/out     |___| 1 |__| 2 |__| 3 |__| 4 |__| 5 |__| 6 |__| 7 |__| 8 |__| 9 |__| 10|________________| 1 |__|   TLC1549_I/O_CLOCK


  D7/in  ------| A9  |  A8  |  A7  |  A6  |  A5  |  A4  |  A3  |  A2  |  A1  |  A0  |__/-----------| B9  | B8   TLC1549_DATA_OUT


   相应的源程序如下 */


BOOLWINAPITLC1549_ReadADC(  // 读取TLC1549的ADC结果

ULONGiIndex,  // 指定CH341设备序号

PULONGoLastADC )  // 指向一个双字单元,返回读出的上次ADC的结果

{

#defineTLC1549_MAX_BIT10// 10位ADC

UCHARmBuffer[ mCH341_PACKET_LENGTH * 2 ];

ULONGi, j, mLength;

i = 0;

mBuffer[ i++ ] = mCH341A_CMD_UIO_STREAM;  // 命令码

mBuffer[ i++ ] = mCH341A_CMD_UIO_STM_OUT | 0x01;  // default status: D0=1, D1=0, CS#=HIGH, I/O_CLOCK=LOW

mBuffer[ i++ ] = mCH341A_CMD_UIO_STM_DIR | 0x03;  // D0 output, D1 output, other input

mBuffer[ i++ ] = mCH341A_CMD_UIO_STM_OUT | 0x00;  // D0=0, CS#=LOW

for ( j = 0; j < 8; j ++ ) {  // input 8 bit

mBuffer[ i++ ] = mCH341A_CMD_UIO_STM_OUT | 0x02;  // D1=1, I/O_CLOCK=HIGH

mBuffer[ i++ ] = mCH341A_CMD_UIO_STM_IN;  // input 1 byte from D7-D0, input A9,A8,A7,A6,A5,A4,A3,A2

mBuffer[ i++ ] = mCH341A_CMD_UIO_STM_OUT | 0x00;  // D1=0, I/O_CLOCK=LOW

}

mBuffer[ i++ ] = mCH341A_CMD_UIO_STM_END;  // 当前命令包提前结束,因为一个包放不下,所以分成两个包

i = mCH341_PACKET_LENGTH;

mBuffer[ i++ ] = mCH341A_CMD_UIO_STREAM;  // 命令码

for ( j = 0; j < TLC1549_MAX_BIT - 2; j ++ ) {  // input 2 bit

mBuffer[ i++ ] = mCH341A_CMD_UIO_STM_OUT | 0x02;  // D1=1, I/O_CLOCK=HIGH

mBuffer[ i++ ] = mCH341A_CMD_UIO_STM_IN;  // input 1 byte from D7-D0, input A1,A0

mBuffer[ i++ ] = mCH341A_CMD_UIO_STM_OUT | 0x00;  // D1=0, I/O_CLOCK=LOW

}

mBuffer[ i++ ] = mCH341A_CMD_UIO_STM_OUT | 0x01;  // D0=1, CS#=HIGH

mBuffer[ i++ ] = mCH341A_CMD_UIO_STM_US | 24;  // delay 24uS,实际上这个延时完全不需要,因为USB传输每1mS一次,下次传输是在1mS之后

mBuffer[ i++ ] = mCH341A_CMD_UIO_STM_END;  // 当前命令包提前结束

mLength = 0;

j = CH341WriteRead( iIndex, i, mBuffer, 8, 2, &mLength, mBuffer );  // 执行数据流命令,先输出再输入,执行两次输入,每次最多8字节

*oLastADC = 0;

if ( j ) {

if ( mLength == TLC1549_MAX_BIT ) {  // 输入长度正确

for ( i = 0; i < TLC1549_MAX_BIT; i ++ ) {  // 将每字节的位7合并为10位ADC结果数据

*oLastADC = ( *oLastADC << 1 ) | ( mBuffer[ i ] >> 7 );  // 位7移到位0

}

return( TRUE );

}

}

return( FALSE );

}


您好,操作CH341的GPIO请参考如下函数:

CH341SetOutput

CH341GetInput

如下为测试用例:

icon_rar.gifCH341PAR_IO.zip



补充:如上为控制GPIO的例子,如果是并口是无法锁存的。


感谢答复,这个例子我有,看了还是有疑问。


我现在要实现的操作几乎和exam.c里的例子/* 用UIO通用I/O位流命令实现自定义的同步串行接口 */  完全一样。要用341的几个IO(D0~D7)去实现外部传感器的非标准同步串口(时钟,数据,EN),传感器是hmc6301. 

因此我最关心的是例子/* 用UIO通用I/O位流命令实现自定义的同步串行接口 */ (就是我原贴中的问题2)是否需要外部锁存?即调用UIO相关的API的时候是否需要外部锁存。UIO的操作是属于GPIO操作还是并口操作。


GPIO操作我已经用CH341Set_D5_D0 实现过了,这个的确不需要外部锁存,但是拼凑复杂的时序的时候编程效率很低。/* 用UIO通用I/O位流命令实现自定义的同步串行接口 */这个例子非常完美。但是我不清楚这个操作是否属于GPIO操作,是否需要外部锁存,以及这个例子作为输入IO的时候是否需要245做buffer?



/* ********************************************************************************************** */

/* 用UIO通用I/O位流命令实现自定义的同步串行接口 */


/* UIO方式共可以使用8个I/O引脚D7-D0,最多可以8个输入或者6个输出

   上位机以字节流控制CH341对最终位流进行输入和输出,有4种基本操作和1个结束操作:

#definemCH341A_CMD_UIO_STM_IN0x00// UIO接口的命令流:输入数据D7-D0

#definemCH341A_CMD_UIO_STM_DIR0x40// UIO接口的命令流:设定I/O方向D5-D0,位5-位0为方向数据

#definemCH341A_CMD_UIO_STM_OUT0x80// UIO接口的命令流:输出数据D5-D0,位5-位0为数据

#definemCH341A_CMD_UIO_STM_US0xC0// UIO接口的命令流:以微秒为单位延时,位5-位0为延时值

#definemCH341A_CMD_UIO_STM_END0x20// UIO接口的命令流:命令包提前结束


   例子:操作10位ADC芯片TLC1549,其时序为非标准

   连线: CH341_D0 <-> TLC1549_CS, CH341_D1 <-> TLC1549_IO_CLK, CH341_D7 <-> TLC1549_DOUT

   下面是用UIO通用I/O位流命令实现的任意波形,参考下图波形(选择等宽的中文字体时才能看出)

         ______                                                                        ____________

  D0/out       |______________________________________________________________________|            |_________   TLC1549_CS#

         ____     ___    ___    ___    ___    ___    ___    ___    ___    ___    ___    Delay 24uS    ___

  D1/out     |___| 1 |__| 2 |__| 3 |__| 4 |__| 5 |__| 6 |__| 7 |__| 8 |__| 9 |__| 10|________________| 1 |__|   TLC1549_I/O_CLOCK


  D7/in  ------| A9  |  A8  |  A7  |  A6  |  A5  |  A4  |  A3  |  A2  |  A1  |  A0  |__/-----------| B9  | B8   TLC1549_DATA_OUT


   相应的源程序如下 */


BOOLWINAPITLC1549_ReadADC(  // 读取TLC1549的ADC结果

ULONGiIndex,  // 指定CH341设备序号

PULONGoLastADC )  // 指向一个双字单元,返回读出的上次ADC的结果

{

#defineTLC1549_MAX_BIT10// 10位ADC

UCHARmBuffer[ mCH341_PACKET_LENGTH * 2 ];

ULONGi, j, mLength;

i = 0;

mBuffer[ i++ ] = mCH341A_CMD_UIO_STREAM;  // 命令码

mBuffer[ i++ ] = mCH341A_CMD_UIO_STM_OUT | 0x01;  // default status: D0=1, D1=0, CS#=HIGH, I/O_CLOCK=LOW

mBuffer[ i++ ] = mCH341A_CMD_UIO_STM_DIR | 0x03;  // D0 output, D1 output, other input

mBuffer[ i++ ] = mCH341A_CMD_UIO_STM_OUT | 0x00;  // D0=0, CS#=LOW

for ( j = 0; j < 8; j ++ ) {  // input 8 bit

mBuffer[ i++ ] = mCH341A_CMD_UIO_STM_OUT | 0x02;  // D1=1, I/O_CLOCK=HIGH

mBuffer[ i++ ] = mCH341A_CMD_UIO_STM_IN;  // input 1 byte from D7-D0, input A9,A8,A7,A6,A5,A4,A3,A2

mBuffer[ i++ ] = mCH341A_CMD_UIO_STM_OUT | 0x00;  // D1=0, I/O_CLOCK=LOW

}

mBuffer[ i++ ] = mCH341A_CMD_UIO_STM_END;  // 当前命令包提前结束,因为一个包放不下,所以分成两个包

i = mCH341_PACKET_LENGTH;

mBuffer[ i++ ] = mCH341A_CMD_UIO_STREAM;  // 命令码

for ( j = 0; j < TLC1549_MAX_BIT - 2; j ++ ) {  // input 2 bit

mBuffer[ i++ ] = mCH341A_CMD_UIO_STM_OUT | 0x02;  // D1=1, I/O_CLOCK=HIGH

mBuffer[ i++ ] = mCH341A_CMD_UIO_STM_IN;  // input 1 byte from D7-D0, input A1,A0

mBuffer[ i++ ] = mCH341A_CMD_UIO_STM_OUT | 0x00;  // D1=0, I/O_CLOCK=LOW

}

mBuffer[ i++ ] = mCH341A_CMD_UIO_STM_OUT | 0x01;  // D0=1, CS#=HIGH

mBuffer[ i++ ] = mCH341A_CMD_UIO_STM_US | 24;  // delay 24uS,实际上这个延时完全不需要,因为USB传输每1mS一次,下次传输是在1mS之后

mBuffer[ i++ ] = mCH341A_CMD_UIO_STM_END;  // 当前命令包提前结束

mLength = 0;

j = CH341WriteRead( iIndex, i, mBuffer, 8, 2, &mLength, mBuffer );  // 执行数据流命令,先输出再输入,执行两次输入,每次最多8字节

*oLastADC = 0;

if ( j ) {

if ( mLength == TLC1549_MAX_BIT ) {  // 输入长度正确

for ( i = 0; i < TLC1549_MAX_BIT; i ++ ) {  // 将每字节的位7合并为10位ADC结果数据

*oLastADC = ( *oLastADC << 1 ) | ( mBuffer[ i ] >> 7 );  // 位7移到位0

}

return( TRUE );

}

}

return( FALSE );

}




补充一下。 上面UIO操作方式,最后调用的是下面这个API接口,因此其实我的最具体的问题就是,调用这个API在IO口上产生数据的时候是属于“GPIO操作”还是“并口操作”,数据是否需要外部锁存。 :)



BOOLWINAPICH341WriteRead(  // 执行数据流命令,先输出再输入

ULONGiIndex,  // 指定CH341设备序号

ULONGiWriteLength,  // 写长度,准备写出的长度

PVOIDiWriteBuffer,  // 指向一个缓冲区,放置准备写出的数据

ULONGiReadStep,  // 准备读取的单个块的长度, 准备读取的总长度为(iReadStep*iReadTimes)

ULONGiReadTimes,  // 准备读取的次数

PULONGoReadLength,  // 指向长度单元,返回后为实际读取的长度

PVOIDoReadBuffer );  // 指向一个足够大的缓冲区,用于保存读取的数据



只有登录才能回复,可以选择微信账号登录