STM32 USB HOST控制GXR程控电阻

1 简介

GXR系列高精度程控电阻,可通过USB串口进行控制,内部USB转串口采用的CH340芯片,将USB连到电脑即可进行命令控制,但在某些情况下需要用单片机进行自动控制时,可以将GXR的USB口接到具有USB接口的单片机,通过单片机进行控制。本文以STM32F4为例,将STM32F4配置为USB HOST,与CH340通信,从而控制GXR程控电阻。

一个长得很像电阻的0.01%精度程控电阻-优快云博客

2 方法

2.1 生成基础工程

打开CubeMX,选择芯片为STM32F405RGT6。配置一个串口用于调试打印,配置USB_FS接口,模式为Host_Only,开启USB中断。

然后选择Middleware,开启USB_HOST,选择class为Virtual Port Com,调试阶段可以选择DEBUG_LEVEL为3,打印所有调试信息,调试完成再将DEBUG_LEVEL改为0,关闭调试打印。

回到system配置,开启SWD接口。

时钟选择外部晶体。

切换到时钟配置页,修改晶体频率为8MHz。

生成工程,生成后编译器选择V6版本,可大幅提高编译效率;优化等级调整为0,避免前期调试优化错误。

生成的工程无法直接访问CH340,需要进行如下修改。

2.2 修改 usbh_cdc.h文件

将宏定义 USB_CDC_CLASS 的值修改为 0xFF。

2.3 修改usbh_cdc.c文件

1)修改函数 USBH_CDC_InterfaceInit 中两处USBH_FindInterface调用参数:

第一处:

//  interface = USBH_FindInterface(phost, COMMUNICATION_INTERFACE_CLASS_CODE,

//                                   ABSTRACT_CONTROL_MODEL, COMMON_AT_COMMAND);

interface = USBH_FindInterface(phost, 0xFF, 0x01, 0x02);

第二处:

//  interface = USBH_FindInterface(phost, DATA_INTERFACE_CLASS_CODE,

//                                   RESERVED, NO_CLASS_SPECIFIC_PROTOCOL_CODE);

  interface = USBH_FindInterface(phost, 0xFF,

                                   0x01, VENDOR_SPECIFIC);

2)修改函数 USBH_CDC_ClassRequest ,将GetLineCoding 改为 SetLineCoding:

//  status = GetLineCoding(phost, &CDC_Handle->LineCoding);

status = SetLineCoding(phost, &CDC_Handle->LineCoding);

3)修改函数 SetLineCoding ,在return上面新增两行波特率控制:

phost->Control.setup.d8[0] = 0x000ca140; //gxdaq add

phost->Control.setup.d8[1] = 0x0000cc03; //gxdaq add

3)修改main.c文件

最后修改main,添加串口重定向和USB通信测试。

1)添加头文件和外部变量:

#include <stdio.h>

#include "usbh_cdc.h"



extern USBH_HandleTypeDef hUsbHostFS;

2)串口重定向,arm V6编译器的串口重定向代码(V5编译器的有点区别,网上很多分享的,如STM32 printf 方法重定向到串口UART - Milton - 博客园):

/* ------------------通过重定向将printf函数映射到串口1上-------------------*/

#if !defined(__MICROLIB)

//#pragma import(__use_no_semihosting)

__asm (".global __use_no_semihosting\n\t");

void _sys_exit(int x) //避免使用半主机模式

{

  x = x;

}

//__use_no_semihosting was requested, but _ttywrch was

void _ttywrch(int ch)

{

    ch = ch;

}



FILE __stdout;



#endif



#if defined ( __GNUC__ ) && !defined (__clang__)

#define PUTCHAR_PROTOTYPE int __io_putchar(int ch)

#else

#define PUTCHAR_PROTOTYPE int fputc(int ch, FILE *f)

#endif

PUTCHAR_PROTOTYPE

{

  /* 实现串口发送一个字节数据的函数 */

while((USART1->SR&0X40)==0);

USART1->DR = (uint8_t) ch;     

  return ch;

}

3)变量定义,用于USB收发控制:

unsigned char recv_buf[100]={0};

uint32_t count  = 0;

4)修改main函数中while(1),2秒设置一次电阻值,并且将接收到信息打印出来:

while (1)

  {

    /* USER CODE END WHILE */

    MX_USB_HOST_Process();



    /* USER CODE BEGIN 3 */

  HAL_Delay(1);

           count++;

           if((count%2000) == 0)

           {

                    USBH_CDC_Transmit(&hUsbHostFS,(uint8_t*)"set 10k\r\n",9);

           }

           if(USBH_CDC_Receive(&hUsbHostFS,recv_buf,100)==USBH_OK)

           {

                    if(recv_buf[0]!=0)

                    {

                             printf("%s",recv_buf);

                             for(int i = 0; i < 100; i++)

                             {

                                       recv_buf[i] = 0;

                             }

                    }

           }

  }

串口打印如下:

通过上述修改即可实现单片机USB HOST控制GXR程控电阻,便于实现自动控制。

示例工程:https://download.youkuaiyun.com/download/bingwueyi/89931191

STM32 HOST USB代码 u8 USH_User_App(void) { u32 total,free; u8 res=0; Show_Str(30,140,200,16,"É豸Á¬½Ó³É¹¦!.",16,0); res=exf_getfree("2:",&total,&free); if(res==0) { POINT_COLOR=BLUE;//ÉèÖÃ×ÖÌåΪÀ¶É« LCD_ShowString(30,160,200,16,16,"FATFS OK!"); LCD_ShowString(30,180,200,16,16,"U Disk Total Size: MB"); LCD_ShowString(30,200,200,16,16,"U Disk Free Size: MB"); LCD_ShowNum(174,180,total>>10,5,16); //ÏÔʾUÅÌ×ÜÈÝÁ¿ MB LCD_ShowNum(174,200,free>>10,5,16); } while(HCD_IsDeviceConnected(&USB_OTG_Core))//É豸Á¬½Ó³É¹¦ { LED1=!LED1; delay_ms(200); } POINT_COLOR=RED;//ÉèÖÃ×ÖÌåΪºìÉ« Show_Str(30,140,200,16,"É豸Á¬½ÓÖÐ...",16,0); LCD_Fill(30,160,239,220,WHITE); return res; } int main(void) { u8 t; NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);//ÉèÖÃϵͳÖжÏÓÅÏȼ¶·Ö×é2 delay_init(168); //³õʼ»¯ÑÓʱº¯Êý uart_init(115200); //³õʼ»¯´®¿Ú²¨ÌØÂÊΪ115200 LED_Init(); //³õʼ»¯ÓëLEDÁ¬½ÓµÄÓ²¼þ½Ó¿Ú KEY_Init(); //°´¼ü LCD_Init(); //³õʼ»¯LCD W25QXX_Init(); //SPI FLASH³õʼ»¯ usmart_dev.init(84); //³õʼ»¯USMART my_mem_init(SRAMIN); //³õʼ»¯ÄÚ²¿ÄÚ´æ³Ø exfuns_init(); //ΪfatfsÏà¹Ø±äÁ¿ÉêÇëÄÚ´æ piclib_init(); //³õʼ»¯»­Í¼ f_mount(fs[0],"0:",1); //¹ÒÔØSD¿¨ f_mount(fs[1],"1:",1); //¹ÒÔØSD¿¨ f_mount(fs[2],"2:",1); //¹ÒÔØUÅÌ POINT_COLOR=RED; while(font_init()) //¼ì²é×Ö¿â { LCD_ShowString(60,50,200,16,16,"Font Error!"); delay_ms(200); LCD_Fill(60,50,240,66,WHITE);//Çå³ýÏÔʾ delay_ms(200); } Show_Str(30,50,200,16,"̽Ë÷ÕßSTM32F407¿ª·¢°å",16,0); Show_Str(30,70,200,16,"USB UÅÌʵÑé",16,0); Show_Str(30,90,200,16,"2014Äê7ÔÂ22ÈÕ",16,0); Show_Str(30,110,200,16,"ÕýµãÔ­×Ó@ALIENTEK",16,0); Show_Str(30,140,200,16,"É豸Á¬½ÓÖÐ...",16,0); //³õʼ»¯USBÖ÷»ú USBH_Init(&USB_OTG_Core,USB_OTG_FS_CORE_ID,&USB_Host,&USBH_MSC_cb,&USR_Callbacks); while(1) { USBH_Process(&USB_OTG_Core, &USB_Host); delay_ms(1); t++; if(t==200) { LED0=!LED0; t=0; } } }
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值