STM32f103使用模擬并口與CH376S通信。使用CMD11_CHECK_EXIST測試返回0x57

硬件:買的CH376S模塊。

1:5V供電采用并口方式。

2:測試晶振起振了。

3:上電RST和RST#都是低電平。與手冊不符合。25腳? RST? 輸出? 電源上電復(fù)位和外部復(fù)位輸出,高電平有效,26腳? RST#? 輸出? 電源上電復(fù)位和外部復(fù)位輸出,低電平有效。

軟件:


#if ( CH375_PORT_MODE==2 || CH375_PORT_MODE==3 )


//DATAPORT: B0~B7

//WR: B8

//CS: B9

//A0: B10

//RD: B11

//INT: C13


#define CH375_WR? ? ? ? ? ? ? ? ? ? ? PBout(8)

#define CH375_CS? ? ? ? ? ? ? ? ? ? ? PBout(9)

#define CH375_A0? ? ? ? ? ? ? ? ? ? ? PBout(10)

#define CH375_RD? ? ? ? ? ? ? ? ? ? ? PBout(11)

#define CH375_DATA_DIR_IN()? ? ? ? ? ?GPIOB->CRL = 0x44444444

#define CH375_DATA_DIR_OUT()? ? ? ? ? GPIOB->CRL = 0x33333333

#define CH375_DATA_DAT_OUT( mCmd )? ? GPIOB->ODR = (GPIOB->ODR & 0xFF00) | (uint8_t)mCmd

#define CH375_DATA_DAT_IN( )? ? ? ? ? (uint8_t)GPIOB->IDR


//CH375寫命令函數(shù)

void xWriteCH375Cmd( UINT8 mCmd )

{

CH375_DATA_DAT_OUT( mCmd );? /* 向CH376的并口輸出數(shù)據(jù) */

CH375_DATA_DIR_OUT( );? /* 設(shè)置并口方向為輸出 */

CH375_A0 = 1;

CH375_CS = 0;

CH375_WR = 0;? /* 輸出有效寫控制信號, 寫CH376芯片的命令端口 */

CH375_WR = 0;? /* 該操作無意義,僅作延時,CH376要求讀寫脈沖寬度大于40nS */

CH375_WR = 1;? /* 輸出無效的控制信號, 完成操作CH376芯片 */

CH375_CS = 1;

CH375_A0 = 0;

CH375_DATA_DIR_IN( );? /* 禁止數(shù)據(jù)輸出 */

delay_us(2);

}

//CH375寫數(shù)據(jù)函數(shù)

void xWriteCH375Data( UINT8 mData )

{

CH375_DATA_DAT_OUT( mData );? /* 向CH376的并口輸出數(shù)據(jù) */

CH375_DATA_DIR_OUT( );? /* 設(shè)置并口方向為輸出 */

CH375_A0 = 0;

CH375_CS = 0;

CH375_WR = 0;? /* 輸出有效寫控制信號, 寫CH376芯片的數(shù)據(jù)端口 */

CH375_WR = 0;? /* 該操作無意義,僅作延時,CH376要求讀寫脈沖寬度大于40nS */

CH375_WR = 1;? /* 輸出無效的控制信號, 完成操作CH376芯片 */

CH375_CS = 1;

CH375_DATA_DIR_IN( );? /* 禁止數(shù)據(jù)輸出 */

delay_us( 1 );? /* 確保讀寫周期大于0.6uS */

}

//CH375讀數(shù)據(jù)函數(shù)

UINT8 xReadCH375Data( void )

{

UINT8mData;

delay_us( 1 );? /* 確保讀寫周期大于0.6uS */

CH375_DATA_DIR_IN( );? /* 設(shè)置并口方向為輸入 */

CH375_A0 = 0;

CH375_CS = 0;

CH375_RD = 0;? /* 輸出有效讀控制信號, 讀CH376芯片的數(shù)據(jù)端口 */

CH375_RD = 0;? /* 該操作無意義,僅作延時 */

mData = CH375_DATA_DAT_IN( );? /* 從CH376的并口輸入數(shù)據(jù) */

CH375_RD = 1;

CH375_CS = 1;? /* 輸出無效的控制信號, 完成操作CH376芯片 */

return( mData );

}


void CH375_Init( void )

{

GPIO_InitTypeDef GPIO_InitStructure;

RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB|RCC_APB2Periph_GPIOC, ENABLE);

GPIO_InitStructure.GPIO_Pin = 0x0FFF;

GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;

GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;

GPIO_Init(GPIOB, &GPIO_InitStructure);


#ifdef CH375_INT_WIRE

? ? GPIO_InitStructure.GPIO_Pin = GPIO_Pin_13;?

GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;

? ? GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;//INT

? ? GPIO_Init(GPIOC, &GPIO_InitStructure);

#endif

CH375_CS = 1;

CH375_WR = 1;

CH375_RD = 1;

CH375_A0 = 0;

CH375_DATA_DIR_IN( );? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?/* 設(shè)置并口輸入 */

}


int main(void)

{

unsigned char i,s;

unsigned short len;

delay_init();

USART_Config();

CH375_Init();

printf("start...\n");

// 發(fā)送測試命令?

xWriteCH375Cmd(CMD11_CHECK_EXIST);?

// 發(fā)送測試數(shù)據(jù)?

xWriteCH375Data(0x11);?

// 讀數(shù)據(jù)?

s = xReadCH375Data();?

printf("s:%x\n",s);

spacer.gif


您好,RST引腳是高電平有效,上電是低電平。

取反指令無法得到正確的值,您可以檢查一下接口配置是否正確,并口時序是否正常。


嗯!查看了是STM32引腳配置問題。PB3。PB4默認是調(diào)試腳,需要關(guān)掉。現(xiàn)在是接了鍵盤掃描鍵盤。設(shè)置配置有誤。



chip-id:0x43

mode:1

wait connect...

check rate

low rate

設(shè)備描述符是:12 01 10 01 00 00 00 08 4f 1c 02 00 10 01 01 02 00 01?

09 02 3b 00 02 01 00 a0 31 09 04 00 00 01 03 01 01 00 09 21 10 01 00 01 22 36 00 07 05 81 03 08 00 0a 09 04 01 00 01 03 00 00 00 09 21 10 01 00 01 22 32 00 07 05 82 03 03 00 0a?

set config

set idle

get report

get report descr failed

set idle

set idle failed

get report

get report descr failed

set report

00 00 00 00 00 00 00 00?



設(shè)置配置的大小端數(shù)據(jù)沒有改到。修改了,但是設(shè)置idle有問題。



chip-id:0x43

mode:1

wait connect...

check rate

low rate

設(shè)備描述符是:12 01 10 01 00 00 00 08 4f 1c 02 00 10 01 01 02 00 01?

09 02 3b 00 02 01 00 a0 31 09 04 00 00 01 03 01 01 00 09 21 10 01 00 01 22 36 00 07 05 81 03 08 00 0a 09 04 01 00 01 03 00 00 00 09 21 10 01 00 01 22 32 00 07 05 82 03 03 00 0a?

set config

set idle

get report

05 01 09 06 a1 01 05 08 19 01 29 03 15 00 25 01 75 01 95 03 91 02 95 05 91 01 05 07 19 e0 29 e7 95 08 81 02 75 08 95 01 81 01 19 00 29 91 26 ff 00 95 06 81 00 c0?

set idle

set idle failed

get report

05 0c 09 01 a1 01 85 01 19 00 2a 3c 02 15 00 26 3c 02 95 01 75 10 81 00 c0 05 01 09 80 a1 01 85 02 19 81 29 83 25 01 75 01 95 03 81 02 95 05 81 01 c0?

set report

00 00 00 00 00 00 00 00?



您好,建議先檢查set idle這一步發(fā)的請求是否正確,請求無誤的話,可以檢查一下set idle failed發(fā)生的原因,查看代碼報錯的位置。


你好!請問下掃碼槍需不需要設(shè)置空閑模式了?我沒有設(shè)置掃碼槍空閑模式,現(xiàn)在的問題是讀取掃碼槍數(shù)據(jù)不穩(wěn)定,掃幾次能獲取數(shù)據(jù),然后就不一直獲取不到了。


獲取掃碼槍是全是模式,不能獲取掃碼槍數(shù)據(jù)后,我查看了INT引腳波形就不正常了。


/* 主函數(shù) */

void main()?

{

unsigned char i,s;

unsigned short len;


max_package = MAXSETUPPACK;

mInitSTDIO( );


s = read_id();

printf("chip-id:0x%02x\n",(unsigned short)s);


set_usb_mode( 5 );? /* 設(shè)置USB主機模式, 如果設(shè)備端是CH37X, 那么5和6均可 */

printf("wait connect...\n");

while(1)

{

while ( wait_interrupt()!=USB_INT_CONNECT );? /* 等待設(shè)備端連接上來 */

delayms(200);? ? ? ? ? ? ? ? ? ? /* 等待連接穩(wěn)定 */

/***** 復(fù)位檢測USB設(shè)備速度 *****/

printf("check rate\n");

s = get_freq();

reset_device();

? ? ? ? if( s&0x10 )

{

printf("low rate\n");

set_freq();/* 切換使375B進入低速模式 */

}

else

printf("full rate\n");

delayms(100);? ? ? ? ?//復(fù)位之后,相當(dāng)于重連,必須有延時保證設(shè)備穩(wěn)定

/***** 獲取設(shè)備描述符 *****/

get_descr(0x01);//獲取設(shè)備描述符

max_package = data_buf[7];? //端點0最大包大小


//Request.Req.bmRequestType=0x80;

//Request.Req.bRequest=0x06;

//Request.Req.wValue=0x0001;? ? ? /* 因為51單片機是大端存儲,否則寫成0x0100,下面類似 */

//Request.Req.wIndex=0x0000;

//Request.Req.wLength=0x0800;

//if( SETUP_Transfer(data_buf, &len) == USB_INT_SUCCESS )

//{

//max_package = data_buf[7];? //端點0最大包大小

//Request.Req.wLength=0x1200;

//if( SETUP_Transfer(data_buf, &len) )

//{

//for(i=0; i!=len; i++)

//printf("%02x ",(unsigned int)data_buf[i]);

//printf("\n");

//}

//}

//else?

//printf("get device descr failed\n");

/***** 復(fù)位 *****/

reset_device();

? ? ? ? if( s&0x10 )set_freq();/* 切換使375B進入低速模式 */

delayms(100);? ? ? ? ? ? ? ? ? ?//復(fù)位之后,相當(dāng)于重連,必須有延時保證設(shè)備穩(wěn)定

/***** 設(shè)置地址? *****/

set_addr(5);//設(shè)置地址

/***** 獲取配置描述符 *****/

//get_descr(0x02);//獲取配置描述符

Request.Req.bmRequestType=0x80;

Request.Req.bRequest=0x06;

Request.Req.wValue=0x0002;

Request.Req.wIndex=0x0000;

Request.Req.wLength=0x0400;

if(SETUP_Transfer(data_buf, &len)==USB_INT_SUCCESS)

{

Request.Req_buf[6] = data_buf[2];

Request.Req_buf[7] = data_buf[3];

SETUP_Transfer(data_buf, &len);

for(i=0;i!=len;i++)

printf("%02x ",(unsigned int)data_buf[i]);

printf("\n");

}

else printf("get config descr failed\n");

/***** 分析配置描述符 *****/

parse_config_descr(data_buf);? ?//保存描述符中一些值

/***** 設(shè)置配置 *****/

? ? printf("set config\n");

set_config(config_value);? ? ?//設(shè)置配置

/***** HID類命令 *****/

for(s=0;s

{

printf("set idle\n");

Request.Req.bmRequestType=0x21;

Request.Req.bRequest=0x0A;

Request.Req.wValue=0x0000;

Request.Req.wIndex=0x0000;

Request.Req.wLength=0x0000;

Request.Req_buf[4] = s;

if(SETUP_Transfer(NULL, NULL)!=USB_INT_SUCCESS)

printf("set idle failed\n");

printf("get report\n");

Request.Req.bmRequestType=0x81;

Request.Req.bRequest=0x06;

Request.Req.wValue=0x0022;

Request.Req.wIndex=0x0000;

Request.Req_buf[4] = s;

if(s==0) Request.Req.wLength=0x0000|((unsigned short)(report_descr0_len+0x40)<<8);

else Request.Req.wLength=0x0000|((unsigned short)(report_descr1_len+0x40)<<8);

if(SETUP_Transfer(data_buf, &len)==USB_INT_SUCCESS)

{

for(i=0;i!=len;i++)

printf("%02x ",(unsigned short)data_buf[i]);

printf("\n");

}

else printf("get report descr failed\n");

}

printf("set report\n");//對于鍵盤這一步,是點亮指示燈

Request.Req.bmRequestType=0x21;

Request.Req.bRequest=0x09;

Request.Req.wValue=0x0002;

Request.Req.wIndex=0x0000;

Request.Req.wLength=0x0100;

data_buf[0]=1;

if(SETUP_Transfer(data_buf, &len)!=USB_INT_SUCCESS)

printf("set report failed\n");

/* 設(shè)置對響應(yīng)NAK的重試次數(shù) */

set_retry(3);? //超時重試3次,但收到NAK不重試

/* 獲取數(shù)據(jù) */

endp6_mode=0x80;? //復(fù)位同步標(biāo)志

toggle_recv();

while(1)

{

s = issue_token( endp_int,DEF_USB_PID_IN);

if(s==USB_INT_SUCCESS)

{

toggle_recv();

len = rd_usb_data( data_buf );

for(i=0;i!=len;i++)

printf("%02x ",(unsigned short)data_buf[i]);

printf("\n");

}

}

}

}



您好,您的問題可能出在大小端沒有修改,您可以在SETUP_Transfer函數(shù)前面加個打印,按順序打印Request.Req_buf[]數(shù)組的值,看打印的值是否正確。打印如下所示

for(i=0;i<8;i++)

printf("%02x ",Request.Req_buf[i]);

正確的打印值如下所示:

獲取配置描述符應(yīng)該是:80 06 00 02 00 00 04 00?

set idle應(yīng)該是:21 0a 00 00 s? 00 00 00

get report應(yīng)該是:81 06 00 22 s? 00 00 xx

?set report應(yīng)該是:21 09 00 02 00 00 01 00


你好。我的大小端是改正確了的。我貼的那個是忘了把大小端改過來了。

chip-id:0x43

wait connect...

check rate

full rate

設(shè)備描述符是:12 01 10 01 00 00 00 08 45 01 12 00 00 01 01 02 00 01?

配置描述符是:09 02 22 00 01 01 00 a0 32 09 04 00 00 01 03 01 01 00 09 21 10 01 00 01 22 49 00 07 05 81 03 08 00 05?

start meiju?

80 06 00 02 00 00 04 00 start meiju?

80 06 00 02 00 00 22 00 09 02 22 00 01 01 00 a0 32 09 04 00 00 01 03 01 01 00 09 21 10 01 00 01 22 49 00 07 05 81 03 08 00 05?

set config

set idle

start meiju?

21 0a 00 00 00 00 00 00 set idle failed

get report

start meiju?

81 06 00 22 00 00 00 89 get report descr failed

set report

start meiju?

21 09 00 02 00 00 01 00?












我現(xiàn)在的代碼是這樣的。沒有對掃碼槍設(shè)置set idle 和 那個鍵盤點燈的。就是工作不穩(wěn)定,掃一會兒就死了。就獲取不到掃碼槍數(shù)據(jù)了,請問是不是需要設(shè)置什么東西了?感覺那個設(shè)置不對。

int main(void)

{

unsigned char i,j,s;

unsigned short len;

deviceCode[0] = SEND_DEVICE_CODE_VALUE;

delay_init();

USART_Config();

CH375_Init();

s = read_id();

printf("chip-id:0x%02x\n",(unsigned short)s);


set_usb_mode( 5 );? /* 設(shè)置USB主機模式, 如果設(shè)備端是CH37X, 那么5和6均可 */

printf("wait connect...\n");

while(1){

while (wait_interrupt()!=USB_INT_CONNECT);

delay_ms(500);? ? ? ? ? ? ? ? ? ? /* 等待連接穩(wěn)定 */

/***** 復(fù)位檢測USB設(shè)備速度 *****/

reset_device();

printf("check rate\n");

s = get_freq();

? ? if( s&0x10 )

{

printf("low rate\n");

set_freq();/* 切換使375B進入低速模式 */

}

else

printf("full rate\n");

delay_ms(100);? ? ? ? ?//復(fù)位之后,相當(dāng)于重連,必須有延時保證設(shè)備穩(wěn)定

/***** 獲取設(shè)備描述符 *****/

get_descr(0x01);//獲取設(shè)備描述符

max_package = data_buf[7];? //端點0最大包大小

//Request.Req.bmRequestType=0x80;

//Request.Req.bRequest=0x06;

//Request.Req.wValue=0x0100;? ? ? /* 因為51單片機是大端存儲,否則寫成0x0100,下面類似 */

//Request.Req.wIndex=0x0000;

//Request.Req.wLength=0x0008;

//if( SETUP_Transfer(data_buf, &len) == USB_INT_SUCCESS )

//{

//max_package = data_buf[7];? //端點0最大包大小

//Request.Req.wLength=0x1200;

//if( SETUP_Transfer(data_buf, &len) )

//{

//for(i=0; i!=len; i++)

//printf("%02x ",(unsigned int)data_buf[i]);

//printf("\n");

//}

//}

//else?

//printf("get device descr failed\n");

/***** 復(fù)位 *****/

reset_device();

//? ? if( s&0x10 )set_freq();/* 切換使375B進入低速模式 */

delay_ms(100);? ? ? ? ? ? ? ? ? ?//復(fù)位之后,相當(dāng)于重連,必須有延時保證設(shè)備穩(wěn)定

/***** 設(shè)置地址? *****/

set_addr(5);//設(shè)置地址

/***** 獲取配置描述符 *****/

get_descr(0x02);//獲取配置描述符

Request.Req.bmRequestType=0x80;

Request.Req.bRequest=0x06;

? ? Request.Req.wValue = 0x0200;

Request.Req.wIndex=0x0000;

Request.Req.wLength=0x0004;

if(SETUP_Transfer(data_buf, &len)==USB_INT_SUCCESS)

{

Request.Req_buf[6] = data_buf[2];

Request.Req_buf[7] = data_buf[3];

SETUP_Transfer(data_buf, &len);

for(i=0;i!=len;i++)

printf("%02x ",(unsigned int)data_buf[i]);

printf("\n");

}

else printf("get config descr failed\n");

/***** 分析配置描述符 *****/

parse_config_descr(data_buf);? ?//保存描述符中一些值

/***** 設(shè)置配置 *****/

? ? printf("set config\n");

set_config(config_value);? ? ?//設(shè)置配置

/***** HID類命令 *****/

//for(s=0;s

//{

//printf("set idle\n");

//Request.Req.bmRequestType=0x21;

//Request.Req.bRequest=0x0A;

//Request.Req.wValue=0x0000;

//Request.Req.wIndex=0x0000;

//Request.Req.wLength=0x0000;

//Request.Req_buf[4] = s;

//if(SETUP_Transfer(NULL, NULL)!=USB_INT_SUCCESS)

//printf("set idle failed\n");

//

//printf("get report\n");

//Request.Req.bmRequestType=0x81;

//Request.Req.bRequest=0x06;

//Request.Req.wValue=0x2200;

//Request.Req.wIndex=0x0000;

//Request.Req_buf[4] = s;

//if(s==0) Request.Req.wLength=0x0000|((unsigned short)(report_descr0_len+0x40)<<8);

//else Request.Req.wLength=0x0000|((unsigned short)(report_descr1_len+0x40)<<8);

//

//if(SETUP_Transfer(data_buf, &len)==USB_INT_SUCCESS)

//{

//for(i=0;i!=len;i++)

//printf("%02x ",(unsigned short)data_buf[i]);

//printf("\n");

//}

//else printf("get report descr failed\n");

//}

//printf("set report\n");//對于鍵盤這一步,是點亮指示燈

//Request.Req.bmRequestType=0x21;

//Request.Req.bRequest=0x09;

//Request.Req.wValue=0x0200;

//Request.Req.wIndex=0x0000;

//Request.Req.wLength=0x0001;

//data_buf[0]=1;

//if(SETUP_Transfer(data_buf, &len)!=USB_INT_SUCCESS)

//printf("set report failed\n");

/* 設(shè)置對響應(yīng)NAK的重試次數(shù) */

set_retry(3);? //超時重試3次,但收到NAK不重試

/* 獲取數(shù)據(jù) */

endp6_mode=0x80;? //復(fù)位同步標(biāo)志

toggle_recv();

i = 1;

while(1)

{

s = issue_token( endp_int,DEF_USB_PID_IN);

if(s==USB_INT_SUCCESS)

{

toggle_recv();

len = rd_usb_data(data_buf);

for(j=0;j!=len;j++)

printf("%02x ",(unsigned short)data_buf[j]);

printf("\n");

}


}

}

}



你好!現(xiàn)在新買了個掃碼槍后,發(fā)現(xiàn)使用無線接收,不能設(shè)置空閑模式。使用有線的就完全沒有問題。也沒有出現(xiàn)掃碼死情況了。原來那個掃碼槍是別人設(shè)置的,只能使用無線接收。就出現(xiàn)空閑模式設(shè)置不正確的問題。謝謝你的回復(fù)。


使用不穩(wěn)定有可能是信號不穩(wěn)定,可能跟供電,線材等有關(guān)系。

在USB中斷傳輸中有一個查詢時間,需要按照這個查詢時間來向設(shè)備發(fā)送IN包,進而接收數(shù)據(jù),否則可能丟失數(shù)據(jù),具體的查詢時間需要按照端點描述符設(shè)置。


只有登錄才能回復(fù),可以選擇微信賬號登錄

国产91精品新入口,国产成人综合网在线播放,九热这里只有精品,本道在线观看,美女视频a美女视频,韩国美女激情视频,日本美女pvp视频