×
单片机 > 单片机程序设计 > 详情

STM32F103C8T6使用MDK 4.12中Custom_HID的修改方法

发布时间:2020-06-16 发布时间:
|

目的,由上位机发送64字节,设备回应3个字节,功能自定。。

板子使用的是最小核心板,MCU为STM32F103C8T6。
USB的D-和D+分别接到PA11(USBDM)和PA12(USBDP)上,PA12(USBDP)即D+通过跳线使上拉1.5K电阻到VCC(3.3V)。
1:打开MDK4.12,打开
C:KeilARMExamplesSTSTM32F10xUSBLibDemosCustom_HIDproject目录下的Custom_HID项目文件。

2:选择菜单 Project->Options for Target 'STM3210E-EVAL'

在Device选项卡里选择 STM32F103C8。
在Output选项卡里把Create HEX File选上,取消Browse Information。
在C/C++选项卡里的Preprocessor Symbols里的Define: USE_STM3210E_EVAL清除。


3:从Application files组中的文件由上而下逐个修改

第一个是usb_pwr.c

把PowerOn和PowerOff()面里的USB_Cable_Config(ENABLE);和USB_Cable_Config(DISABLE);这两句删除,因为我的板子上没有这个控制电路,
而是通过跳线把USBDP通过1.5K电阻接通到VCC(3.3V)的。


接下来修改hw_config.c


#define ADC1_DR_Address    ((u32)0x4001244C)
u32 ADC_ConvertedValueX = 0;
u32 ADC_ConvertedValueX_1 = 0;
这三句删除,因为我不用ADC,外部中断和DMA,只需要跟上位机通信点亮板上连接到PB0上的一个LED。

所以还要把Set_System函数里的
EXTI_Configuration();
ADC_Configuration();
这两句删除。

把USB_Interrupts_Config函数里的
EXTI9_5 Interrupt
EXTI15_10 Interrupt
DMA1 Channel1 Interrupt
这三个相关的语句都删除。

把USB_Cable_Config整个函数删除。

把GPIO_Configuration里面的
KEY
Tamper
Potentiometer
三个相关的配置语句都删除。
下面的LED配置只配置LED1,用来指示上位机的指令,其它都删除。


EXTI_Configuration
ADC_Configuration
这两个函数整个删除。

加上这句RCC_AHBPeriphClockCmd(RCC_AHBPeriph_CRC, ENABLE); 别忘了开CRC电源。计算序列号要用到的,否则序列号就会变成42949-67295,是0xffffffff,是错误的。

把Get_SerialNum函数的功能改成如下
目的是把96位ID作CRC运算后来做产品的序列号。
可以不要这个函数,只在usb_desc.c里定义序列号。同时其它文件里用到这个函数的地方就要删除。

增加RBIT这个函数,32位位倒置程序,CRC用到的。因为STM32的CRC计算结果跟一般的CRC校验工具计算结果不同,所以要特殊处理。

原始序列号: 39006C065834313149670543
分成三个32位数。每一个32位按位倒置,然后给STM32计算CRC,结果跟0xffffffff异或运算后,再把32位的结果按位倒置。就对了。
39006C06=00111001000000000110110000000110 = 01100000001101100000000010011100 = 6036009C
58343131=01011000001101000011000100110001 = 10001100100011000010110000011010 = 8C8C2C1A
49670543=01001001011001110000010101000011 = 11000010101000001110011010010010 = C2A0E692

STM32的CRC结果跟0xffffffff后为十进制4289354847=FFAA5C5F=11111111101010100101110001011111=倒过来

11111010001110100101010111111111=FA3A55FF


__asm u32 RBIT(u32 value)
{
    rbit r0, r0
    bx lr
}

void Get_SerialNum(void)
{
  u32 Device_Serial, Device_Serial0, Device_Serial1, Device_Serial2;

  Device_Serial0 = *(u32*)(0x1FFFF7E8);
  Device_Serial0 = RBIT(Device_Serial0);

  Device_Serial1 = *(u32*)(0x1FFFF7EC);
  Device_Serial1 = RBIT(Device_Serial1);

  Device_Serial2 = *(u32*)(0x1FFFF7F0);
  Device_Serial2 = RBIT(Device_Serial2);


  CRC_ResetDR();
  Device_Serial = CRC_CalcCRC(Device_Serial0);
  Device_Serial = CRC_CalcCRC(Device_Serial1);
  Device_Serial = CRC_CalcCRC(Device_Serial2);

  Device_Serial ^= 0xFFFFFFFF;
  Device_Serial = RBIT(Device_Serial);

  if(Device_Serial != 0)
  {
  CustomHID_StringSerial[0] = CUSTOMHID_SIZ_STRING_SERIAL;
  CustomHID_StringSerial[1] = USB_STRING_DESCRIPTOR_TYPE;
  CustomHID_StringSerial[2] = (u8)(Device_Serial/(u32)1000000000)+0x30;
  CustomHID_StringSerial[3] = 0x00;
  CustomHID_StringSerial[4] = (u8)((Device_Serial%(u32)1000000000)/(u32)100000000)+0x30;
  CustomHID_StringSerial[5] = 0x00;
  CustomHID_StringSerial[6] = (u8)((Device_Serial%(u32)100000000)/(u32)10000000)+0x30;
  CustomHID_StringSerial[7] = 0x00;
  CustomHID_StringSerial[8] = (u8)((Device_Serial%(u32)10000000)/(u32)1000000)+0x30;
  CustomHID_StringSerial[9] = 0x00;
  CustomHID_StringSerial[10] = (u8)((Device_Serial%(u32)1000000)/(u32)100000)+0x30;
  CustomHID_StringSerial[11] = 0x00;
  CustomHID_StringSerial[12] = '-';
  CustomHID_StringSerial[13] = 0x00;

  CustomHID_StringSerial[14] = (u8)((Device_Serial%(u32)100000)/(u32)10000)+0x30;
  CustomHID_StringSerial[15] = 0x00;
  CustomHID_StringSerial[16] = (u8)((Device_Serial%(u32)10000)/(u32)1000)+0x30;
  CustomHID_StringSerial[17] = 0x00;
  CustomHID_StringSerial[18] = (u8)((Device_Serial%(u32)1000)/(u32)100)+0x30;
  CustomHID_StringSerial[19] = 0x00;
  CustomHID_StringSerial[20] = (u8)((Device_Serial%(u32)100)/(u32)10)+0x30;
  CustomHID_StringSerial[21] = 0x00;
  CustomHID_StringSerial[22] = (u8)((Device_Serial%(u32)10)/(u32)1)+0x30;
  CustomHID_StringSerial[23] = 0x00;
  }   
}


然后修改对应的 hw_config.h
void USB_Cable_Config (FunctionalState NewState);
void EXTI_Configuration(void);
void ADC_Configuration(void);
把这三条删除。
Get_SerialNum也视情况决定要不要删除。

main.c不动。

接下来修改 stm32f10x_it.c
把u8 Send_Buffer[2]; 这句删除。


extern u32 ADC_ConvertedValueX;
extern u32 ADC_ConvertedValueX_1;
删除。


DMA1_Channel1_IRQHandler
EXTI9_5_IRQHandler
EXTI15_10_IRQHandler
这三个函数清空,是清空里面的内容,保留一个空的函数。

 

接下来改 usb_desc.c
把报告描述符改成自已的:
/* CustomHID_ConfigDescriptor */
const u8 CustomHID_ReportDescriptor[CUSTOMHID_SIZ_REPORT_DESC] =
  {    
    0x05, 0x01,                    // USAGE_PAGE(User define)
    0x09, 0x00,                    // USAGE(User define)
    0xa1, 0x01,                    // COLLECTION (Application)
    0x19, 0x00,                    //   USAGE_MINIMUM(0)
    0x29, 0xFF,                    //   USAGE_MAXIMUM(255)
    0x15, 0x00,                    //   LOGICAL_MINIMUM (0)
    0x25, 0xFF,                    //   LOGICAL_MAXIMUM (255)
    0x75, 0x08,                    //   REPORT_SIZE (8)
    0x95, 0x03,                    //   REPORT_COUNT (3)
    0x81, 0x02,                    //   INPUT (Data,Var,Abs)

    0x05, 0x02,                    // USAGE_PAGE(2)
    0x19, 0x00,                    //   USAGE_MINIMUM (0)
    0x29, 0xFF,                    //   USAGE_MAXIMUM (255)
    0x15, 0x00,                    //   LOGICAL_MINIMUM (0)
    0x25, 0xFF,                    //   LOGICAL_MAXIMUM (255)
    0x95, 0x40,                    //   REPORT_COUNT (8)
    0x75, 0x08,                    //   REPORT_SIZE (64)
    0x91, 0x02,                    //   OUTPUT (Data,Var,Abs)

    0xc0            /*     END_COLLECTION              */

  }; /* CustomHID_ReportDescriptor */


然后更改配置描述符中的输入输出端点的最大包数。输入端点改成3个字节,输出端点改成64字节。


再来改下面三个字符串描述符,使用的是UNICODE格式的,用记事本写好保存为UNICODE格式文件,再用十六进制编辑器打开就看到了。

改完以上的数据,还要更改usb_desc.h里的定义的大小。(注意字节数还包括描述符长度及标识),如上面的报告描述符大小应改成
#define CUSTOMHID_SIZ_REPORT_DESC 37


接下来改usb_endp.c

u8 Receive_Buffer[2];
改成
u8 Receive_Buffer[64]; //因本例中要求上位机发来64字节。

然后是EP1_OUT_Callback这个函数的修改,根据上位机发来的数据,作出


关键字:STM32F103C8T6  MDK  修改方法

『本文转载自网络,版权归原作者所有,如有侵权请联系删除』

热门文章 更多
基于AT91M42800A的LED显示系统设计