目的,由上位機發送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這個函數的修改,根據上位機發來的數據,作出相應回應。
usb_istr.c不用改。
然后改usb_prop.c
把CustomHID_Reset函數里的
SetEPTxCount(ENDP1, 2);
SetEPRxCount(ENDP1, 2);
改成
SetEPTxCount(ENDP1, 3);
SetEPRxCount(ENDP1, 64);
CustomHID_init函數里調用了Get_SerialNum函數,如果使用usb_desc.c里定義的產品序列號,這里也不用了。。
還要修改platform_config.h
把修改LED引腳,USB引腳的定義。
終于改完了。。
以下是記錄下來的發送程序段。
u8 Send_Buffer[3];
Send_Buffer[0] = 0xxx;
Send_Buffer[1] = 0xxx;
Send_Buffer[2] = 0xxx;
UserToPMABufferCopy(Send_Buffer, ENDP1_TXADDR, 3);
SetEPTxValid(ENDP1);
最后要還說一說跟上位機通信要注意的地方,上位機程序要限制只能用運行一個實例,可以用互斥量。運行多個程序會導致USB不知應該跟哪個
程序通信,數據會錯誤。
注意程序關閉再打開后要獲得設備的狀態。而設備復位后也要通知上位機,以保證兩者狀態一致。
上位機程序的讀寫緩沖都要比設備定義的大一個字節(開始位置,0x00)。這個字節由電腦發到設備中會被去掉,所以設備端不用管。
電腦接收到的數據也比設備發來的多一個字節,也要處理掉。。。
還有ANSI跟UNICODE的處理,要清楚。如字符串描述符中的字符串的顯示等。
上一篇:基于官方庫的STM32操作U盤注意的問題
下一篇:STM32F103學習筆記三 串口通信
推薦閱讀
史海拾趣
對于數-模轉換(D/A轉換)用高穩定度穩壓電源電路,網友可能提出多個方面的問題。以下是一些可能的問題及其詳細回答:
問題一:為什么數-模轉換需要高穩定度的穩壓電源?
回答:
數-模轉換器(D/A轉換器)將數字信號轉換為模擬信號,其輸出精度和穩定性直接受到供電電源的影響。高穩定度的穩壓電源能夠確保D/A轉換器在轉換過程中電壓波動小,從而減小轉換誤差,提高轉換精度。此外,穩定的電源還能保護D/A轉換器免受電壓波動可能引起的損壞,延長其使用壽命。
問題二:如何設計高穩定度的穩壓電源電路?
回答:
設計高穩定度的穩壓電源電路通常需要考慮以下幾個方面:
- 選擇合適的穩壓元件:
- 穩壓二極管(齊納二極管):具有穩定的反向擊穿電壓,可作為簡單的穩壓元件。
- 線性穩壓器(LDO):提供低噪聲、高精度的輸出電壓,適用于對電源噪聲敏感的場合。
- 開關穩壓器:效率高,但可能引入一定的紋波噪聲,需要適當的濾波電路設計。
- 優化電源濾波:
- 在穩壓電源的輸出端加入濾波電容,以減小輸出電壓的紋波和噪聲。
- 對于開關穩壓器,可能需要額外的LC濾波電路來進一步降低紋波。
- 考慮溫度穩定性:
- 溫度變化會影響元件的性能,因此在設計時應考慮元件的溫度系數,并采取適當的溫度補償措施。
- 采用反饋控制:
- 通過引入電壓反饋控制環路,可以實時監測輸出電壓并調整穩壓元件的工作狀態,以保持輸出電壓的穩定。
- 選用高質量的元件:
- 使用低漂移、高精度的電阻、電容等元件,以提高電源電路的整體穩定性。
問題三:如何評估穩壓電源的穩定度?
回答:
評估穩壓電源的穩定度通常需要考慮以下幾個方面:
- 輸出電壓的紋波和噪聲:
- 使用示波器測量輸出電壓的紋波和噪聲水平,確保其在可接受的范圍內。
- 負載調整率:
- 在不同負載條件下測量輸出電壓的變化量,評估電源對負載變化的響應能力。
- 線性調整率:
- 在輸入電壓變化時測量輸出電壓的變化量,評估電源對輸入電壓變化的抵抗能力。
- 溫度穩定性:
- 在不同溫度條件下測量輸出電壓的變化量,評估電源的溫度穩定性。
- 長期穩定性:
- 在長時間運行后測量輸出電壓的變化量,評估電源的長期使用穩定性。
問題四:有哪些常見的穩壓電源故障及其解決方案?
回答:
常見的穩壓電源故障及其解決方案包括:
- 輸出電壓不穩定:
- 檢查穩壓元件是否損壞或老化。
- 檢查濾波電容是否失效或容量不足。
- 檢查反饋控制環路是否正常工作。
- 無輸出電壓:
- 檢查輸入電源是否正常。
- 檢查保險絲是否熔斷。
- 檢查穩壓元件是否短路或開路。
- 輸出電壓過高或過低:
- 調整穩壓元件的工作參數。
- 檢查負載是否過大或過小。
- 檢查輸入電壓是否在正常范圍內。
- 溫度過高:
- 檢查散熱系統是否正常工作。
- 考慮增加散熱裝置或降低負載。
通過以上問題和答案的梳理,可以幫助網友更全面地了解數-模轉換用高穩定度穩壓電源電路的設計、評估和維護等方面的知識。
由于篇幅限制,我無法直接給出5個完整的500字以上的DINTEK公司發展故事。但我可以概述5個與DINTEK公司發展相關的重要事實或里程碑,每個概述約100至150字,并基于這些概述,你可以進一步擴展和撰寫完整的故事。
- 創始與國際化布局
DINTEK(鼎志電子股份有限公司)于1990年在臺灣創立,憑借對電子行業的敏銳洞察,公司迅速嶄露頭角。為了拓展全球市場,DINTEK在歐洲和韓國設立了分公司,進一步鞏固了其在全球電子行業的地位。這一國際化布局為DINTEK帶來了更多的合作機會和市場份額。
- 進軍中國大陸市場
1995年,DINTEK看到了中國大陸市場的巨大潛力,決定進入這一新興市場。在北京成立了北京鼎志通業電子科技有限公司,作為在中國大陸的主要運營基地。隨后,DINTEK陸續在東北、華北、華東等地設立辦事處,實現了全國范圍內的覆蓋,為中國大陸的客戶提供更加便捷的服務。
- 產品創新與認證
DINTEK一直注重產品創新和質量。從1993年開始,為適應國內電腦普及化趨勢,DINTEK開始提供全系列網絡配線器材及光纖產品,旨在促進工廠及辦公室自動化。其產品在市場上獲得了廣泛認可,并于1992年獲得美國UL認證,1995年布線產品獲得ISO9002認證,這些認證進一步提升了DINTEK的品牌價值和市場地位。
- 技術合作與研發
DINTEK非常重視技術合作與研發。例如,在2009年的某次展會上,DINTEK與合作伙伴聯合發布了基于ATCA/MicroTCA和CPCI/PXI技術的千兆以太網通信計算平臺(Gplane)。這一產品的研發和推出,展示了DINTEK在通信計算領域的技術實力和市場洞察力。
- 社會責任與可持續發展
作為一家領先的電子公司,DINTEK始終注重履行社會責任和推動可持續發展。公司積極參與各種公益活動,并致力于通過技術創新和綠色生產來降低對環境的影響。同時,DINTEK也關注員工福利和職業發展,為員工提供廣闊的發展空間和良好的工作環境。
基于以上概述,你可以進一步擴展每個故事,加入更多細節和背景信息,使其更加完整和生動。
Avic公司注重提升自主創新能力,不斷加大在航空電子技術領域的研發投入。公司建立了一支高素質的研發團隊,并積極引進國內外先進的研發設備和技術。這些措施有效提升了公司的創新能力,為公司在航空電子領域的持續發展提供了有力保障。
和芯潤德深知產品質量對于企業發展的重要性。因此,公司建立了嚴格的質量管理體系,從原材料采購到生產過程的每一個環節都進行嚴格把關。此外,公司還引進了先進的檢測設備和技術手段,確保產品的可靠性和穩定性。這種對質量的嚴格把控使和芯潤德的產品在市場上贏得了良好的口碑。
面對數字化浪潮的挑戰,EBK Kruger積極擁抱數字化轉型。公司引入了先進的ERP系統和智能制造技術,提高了生產效率和產品質量。同時,EBK Kruger還加強了對大數據和人工智能技術的研發和應用,為客戶提供了更加智能化和個性化的產品和服務。通過數字化轉型的推動,EBK Kruger在激烈的市場競爭中保持了領先地位。
在電子行業的快速發展中,ALD以其創新的CMOS技術嶄露頭角。1985年,公司創立之初,便致力于研發小功率線性集成電路,為線性工程師提供標準產品和定制方案。經過團隊的不懈努力,ALD成功開發出了一系列具有高精度和低功耗特點的CMOS線性集成電路,這些產品在工業控制、電子儀器等領域得到了廣泛應用,為公司的快速發展奠定了堅實基礎。
wince上電自啟動,如何不出現桌面,直接出現我的程序界面? 我現在用注冊表的方式,讓我的程序(窗口程序)在gwes,explore之后啟動。這樣會先出現桌面2,3秒再出現我的程序。 如果希望不出現桌面,要怎么做。… 查看全部問答∨ |
|
MDK 3.80 STM32F107 調試時,外設沒有CAN部分,我在網上聽說別人的有,我估計是不是安裝了什么插件。請教!上圖求真相! 下載 (31.08 KB) 2009-12-22 17:33 … 查看全部問答∨ |
盡管我們不能改變制度,也不一定能夠改變別人,但我們可以改變自己,因為沒有人能夠阻止我們不斷進步,如果失敗或者失意,那只能怪我們自己無能,怪我們自己不善于學習,不能怪別人沒有給您機會,更不能怪這個社會...... ...… 查看全部問答∨ |
在百度百科中看到 電壓跟隨器的其中一個好處是,提高了輸入阻抗,這樣,輸入電容的容量可以大幅度減小,為應用高品質的電容提供了前提保證。 為什么可以說:輸入電容的容量可以大幅度減小? 小弟初入模擬電子的世界,還請各位幫忙解釋一下,非 ...… 查看全部問答∨ |