add examples
This commit is contained in:
parent
96b2bc9dcc
commit
a89f877252
108
examples/ADC/ADC.C
Normal file
108
examples/ADC/ADC.C
Normal file
@ -0,0 +1,108 @@
|
||||
|
||||
/********************************** (C) COPYRIGHT *******************************
|
||||
* File Name : ADC.C
|
||||
* Author : WCH
|
||||
* Version : V1.0
|
||||
* Date : 2017/01/20
|
||||
* Description : CH554 ADC采样时钟设置,ADC通道设置函数,电压比较模式设置
|
||||
*******************************************************************************/
|
||||
|
||||
#include "..\Public\CH554.H"
|
||||
#include "..\Public\Debug.H"
|
||||
#include "ADC.H"
|
||||
#include "stdio.h"
|
||||
|
||||
#pragma NOAREGS
|
||||
|
||||
#define ADC_INTERRUPT 1
|
||||
|
||||
/*******************************************************************************
|
||||
* Function Name : ADCInit(UINT8 div)
|
||||
* Description : ADC采样时钟设置,模块开启,中断开启
|
||||
* Input : UINT8 div 时钟设置
|
||||
1 慢 384个Fosc
|
||||
0 快 96个Fosc
|
||||
* Output : None
|
||||
* Return : None
|
||||
*******************************************************************************/
|
||||
void ADCInit(UINT8 div)
|
||||
{
|
||||
ADC_CFG &= ~bADC_CLK | div;
|
||||
ADC_CFG |= bADC_EN; //ADC电源使能
|
||||
#if ADC_INTERRUPT
|
||||
ADC_IF = 0; //清空中断
|
||||
IE_ADC = 1; //使能ADC中断
|
||||
#endif
|
||||
}
|
||||
|
||||
/*******************************************************************************
|
||||
* Function Name : ADC_ChannelSelect(UINT8 ch)
|
||||
* Description : ADC采样启用
|
||||
* Input : UINT8 ch 采用通道
|
||||
* Output : None
|
||||
* Return : 成功 SUCCESS
|
||||
失败 FAIL
|
||||
*******************************************************************************/
|
||||
UINT8 ADC_ChannelSelect(UINT8 ch)
|
||||
{
|
||||
if(ch == 0){ADC_CHAN1 =0;ADC_CHAN0=0;P1_DIR_PU &= ~bAIN0;} //AIN0
|
||||
else if(ch == 1){ADC_CHAN1 =0;ADC_CHAN0=1;P1_DIR_PU &= ~bAIN1;} //AIN1
|
||||
else if(ch == 2){ADC_CHAN1 =1;ADC_CHAN0=0;P1_DIR_PU &= ~bAIN2;} //AIN2
|
||||
else if(ch == 3){ADC_CHAN1 =1;ADC_CHAN0=1;P3_DIR_PU &= ~bAIN3;} //AIN3
|
||||
else return FAIL;
|
||||
return SUCCESS;
|
||||
}
|
||||
|
||||
/*******************************************************************************
|
||||
* Function Name : VoltageCMPModeInit()
|
||||
* Description : 电压比较器模式初始化
|
||||
* Input : UINT8 fo 正向端口 0\1\2\3
|
||||
UINT8 re 反向端口 1\3
|
||||
* Output : None
|
||||
* Return : 成功 SUCCESS
|
||||
失败 FAIL
|
||||
*******************************************************************************/
|
||||
UINT8 VoltageCMPModeInit(UINT8 fo,UINT8 re)
|
||||
{
|
||||
ADC_CFG |= bCMP_EN; //电平比较电源使能
|
||||
if(re == 1){
|
||||
if(fo == 0) {ADC_CHAN1 =0;ADC_CHAN0=0;CMP_CHAN =0;} //AIN0和AIN1
|
||||
else if(fo == 2) {ADC_CHAN1 =1;ADC_CHAN0=0;CMP_CHAN =0;} //AIN2和AIN1
|
||||
else if(fo == 3) {ADC_CHAN1 =1;ADC_CHAN0=1;CMP_CHAN =0; } //AIN3和AIN1
|
||||
else return FAIL;
|
||||
}
|
||||
else if(re == 3){
|
||||
if(fo == 0) {ADC_CHAN1 =0;ADC_CHAN0=0;CMP_CHAN =0;} //AIN0和AIN1
|
||||
else if(fo == 1) {ADC_CHAN1 =0;ADC_CHAN0=1;CMP_CHAN =0;} //AIN1和AIN1
|
||||
else if(fo == 2) {ADC_CHAN1 =1;ADC_CHAN0=0;CMP_CHAN =0;} //AIN2和AIN1
|
||||
else return FAIL;
|
||||
}
|
||||
else return FAIL;
|
||||
#if ADC_INTERRUPT
|
||||
CMP_IF = 0; //清空中断
|
||||
IE_ADC = 1; //使能ADC中断
|
||||
#endif
|
||||
|
||||
return SUCCESS;
|
||||
}
|
||||
|
||||
#if ADC_INTERRUPT
|
||||
/*******************************************************************************
|
||||
* Function Name : ADCInterrupt(void)
|
||||
* Description : ADC 中断服务程序
|
||||
*******************************************************************************/
|
||||
void ADCInterrupt( void ) interrupt INT_NO_ADC using 1 //ADC中断服务程序,使用寄存器组1
|
||||
{
|
||||
if(ADC_IF == 1) //ADC完成中断
|
||||
{
|
||||
// UserData = ADC_DATA; //取走ADC采样数据
|
||||
ADC_IF = 0; //清空ADC中断标志
|
||||
}
|
||||
if(CMP_IF == 1) //电压比较完成中断
|
||||
{
|
||||
// UserData = ADC_CTRL&0x80 >> 7); //保存比较器结果
|
||||
CMP_IF = 0; //清空比较器完成中断
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
34
examples/ADC/ADC.H
Normal file
34
examples/ADC/ADC.H
Normal file
@ -0,0 +1,34 @@
|
||||
|
||||
#define ADC_INTERRUPT 1
|
||||
|
||||
/*******************************************************************************
|
||||
* Function Name : ADCClkSet(UINT8 div)
|
||||
* Description : ADC采样时钟设置,模块开启,中断开启
|
||||
* Input : UINT8 div 时钟设置
|
||||
0 慢 384个Fosc
|
||||
1 快 96个Fosc
|
||||
* Output : None
|
||||
* Return : None
|
||||
*******************************************************************************/
|
||||
void ADCInit(UINT8 div);
|
||||
|
||||
/*******************************************************************************
|
||||
* Function Name : ADC_ChannelSelect(UINT8 ch)
|
||||
* Description : ADC采样通道设置
|
||||
* Input : UINT8 ch 采用通道0-3
|
||||
* Output : None
|
||||
* Return : 成功 SUCCESS
|
||||
失败 FAIL 通道设置超出范围
|
||||
*******************************************************************************/
|
||||
UINT8 ADC_ChannelSelect(UINT8 ch);
|
||||
|
||||
/*******************************************************************************
|
||||
* Function Name : VoltageCMPModeInit()
|
||||
* Description : 电压比较器模式初始化
|
||||
* Input : UINT8 fo 正向端口 0\1\2\3
|
||||
UINT8 re 反向端口 1\3
|
||||
* Output : None
|
||||
* Return : 成功 SUCCESS
|
||||
失败 FAIL
|
||||
*******************************************************************************/
|
||||
UINT8 VoltageCMPModeInit(UINT8 fo,UINT8 re);
|
52
examples/ADC/Main.C
Normal file
52
examples/ADC/Main.C
Normal file
@ -0,0 +1,52 @@
|
||||
|
||||
/********************************** (C) COPYRIGHT *******************************
|
||||
* File Name : Main.C
|
||||
* Author : WCH
|
||||
* Version : V1.0
|
||||
* Date : 2017/01/20
|
||||
* Description : CH544 ADC初始化,ADC中断和查询方式采集演示示例
|
||||
*******************************************************************************/
|
||||
#include "..\Public\CH554.H"
|
||||
#include "..\Public\Debug.H"
|
||||
#include "ADC.H"
|
||||
#include "stdio.h"
|
||||
#include <string.h>
|
||||
|
||||
#pragma NOAREGS
|
||||
|
||||
void main( )
|
||||
{
|
||||
UINT16 i;
|
||||
UINT16 j = 0;
|
||||
CfgFsys( ); //CH554时钟选择配置
|
||||
mDelaymS(20);
|
||||
mInitSTDIO( ); //串口0初始化
|
||||
printf("start ...\n");
|
||||
|
||||
ADCInit( 0 ); //ADC时钟配置,0(96clk) 1(384clk),ADC模块开启
|
||||
|
||||
#if ADC_INTERRUPT //ADC中断方式
|
||||
EA = 1;
|
||||
while(1)
|
||||
{
|
||||
for(i=0;i<4;i++){
|
||||
printf("AIN%02x ",(UINT16)i); //ADC采样通道打印显示,调试用
|
||||
ADC_ChannelSelect( i ); //ADC采样电源开启和通道设置,i(0-3)表示采样通道
|
||||
ADC_START = 1; //开始采样,采样完成进入中断
|
||||
mDelayuS(30); //等待采集完成才能切换至下一通道
|
||||
}
|
||||
}
|
||||
#else
|
||||
while(1) //ADC 查询方式
|
||||
{
|
||||
for(i=0;i<4;i++){
|
||||
printf("AIN%02x ",(UINT16)i);
|
||||
ADC_ChannelSelect( i ); //ADC采样初始化
|
||||
ADC_START = 1; //开始采样,采样完成进入中断
|
||||
while(ADC_START); //ADC_START变为0时,表示采样完成
|
||||
printf("DATA: %02x\n",(UINT16)ADC_DATA);
|
||||
mDelaymS(100); //模拟单片机干其他事
|
||||
}
|
||||
}
|
||||
#endif
|
||||
}
|
374
examples/CH554.uvproj
Normal file
374
examples/CH554.uvproj
Normal file
@ -0,0 +1,374 @@
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="no" ?>
|
||||
<Project xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="project_proj.xsd">
|
||||
|
||||
<SchemaVersion>1.1</SchemaVersion>
|
||||
|
||||
<Header>### uVision Project, (C) Keil Software</Header>
|
||||
|
||||
<Targets>
|
||||
<Target>
|
||||
<TargetName>Target 1</TargetName>
|
||||
<ToolsetNumber>0x0</ToolsetNumber>
|
||||
<ToolsetName>MCS-51</ToolsetName>
|
||||
<TargetOption>
|
||||
<TargetCommonOption>
|
||||
<Device>SST89C54</Device>
|
||||
<Vendor>SST</Vendor>
|
||||
<Cpu>IRAM(0-0xFF) IROM(0-0x3FFF) CLOCK(33000000)</Cpu>
|
||||
<FlashUtilSpec></FlashUtilSpec>
|
||||
<StartupFile>"LIB\STARTUP.A51" ("Standard 8051 Startup Code")</StartupFile>
|
||||
<FlashDriverDll></FlashDriverDll>
|
||||
<DeviceId>2932</DeviceId>
|
||||
<RegisterFile>REG52.H</RegisterFile>
|
||||
<MemoryEnv></MemoryEnv>
|
||||
<Cmp></Cmp>
|
||||
<Asm></Asm>
|
||||
<Linker></Linker>
|
||||
<OHString></OHString>
|
||||
<InfinionOptionDll></InfinionOptionDll>
|
||||
<SLE66CMisc></SLE66CMisc>
|
||||
<SLE66AMisc></SLE66AMisc>
|
||||
<SLE66LinkerMisc></SLE66LinkerMisc>
|
||||
<SFDFile></SFDFile>
|
||||
<UseEnv>0</UseEnv>
|
||||
<BinPath></BinPath>
|
||||
<IncludePath></IncludePath>
|
||||
<LibPath></LibPath>
|
||||
<RegisterFilePath></RegisterFilePath>
|
||||
<DBRegisterFilePath></DBRegisterFilePath>
|
||||
<TargetStatus>
|
||||
<Error>0</Error>
|
||||
<ExitCodeStop>0</ExitCodeStop>
|
||||
<ButtonStop>0</ButtonStop>
|
||||
<NotGenerated>0</NotGenerated>
|
||||
<InvalidFlash>1</InvalidFlash>
|
||||
</TargetStatus>
|
||||
<OutputDirectory>.\</OutputDirectory>
|
||||
<OutputName>CH554DEMO</OutputName>
|
||||
<CreateExecutable>1</CreateExecutable>
|
||||
<CreateLib>0</CreateLib>
|
||||
<CreateHexFile>1</CreateHexFile>
|
||||
<DebugInformation>1</DebugInformation>
|
||||
<BrowseInformation>1</BrowseInformation>
|
||||
<ListingPath>.\</ListingPath>
|
||||
<HexFormatSelection>0</HexFormatSelection>
|
||||
<Merge32K>0</Merge32K>
|
||||
<CreateBatchFile>0</CreateBatchFile>
|
||||
<BeforeCompile>
|
||||
<RunUserProg1>0</RunUserProg1>
|
||||
<RunUserProg2>0</RunUserProg2>
|
||||
<UserProg1Name></UserProg1Name>
|
||||
<UserProg2Name></UserProg2Name>
|
||||
<UserProg1Dos16Mode>0</UserProg1Dos16Mode>
|
||||
<UserProg2Dos16Mode>0</UserProg2Dos16Mode>
|
||||
<nStopU1X>0</nStopU1X>
|
||||
<nStopU2X>0</nStopU2X>
|
||||
</BeforeCompile>
|
||||
<BeforeMake>
|
||||
<RunUserProg1>0</RunUserProg1>
|
||||
<RunUserProg2>0</RunUserProg2>
|
||||
<UserProg1Name></UserProg1Name>
|
||||
<UserProg2Name></UserProg2Name>
|
||||
<UserProg1Dos16Mode>0</UserProg1Dos16Mode>
|
||||
<UserProg2Dos16Mode>0</UserProg2Dos16Mode>
|
||||
</BeforeMake>
|
||||
<AfterMake>
|
||||
<RunUserProg1>0</RunUserProg1>
|
||||
<RunUserProg2>0</RunUserProg2>
|
||||
<UserProg1Name></UserProg1Name>
|
||||
<UserProg2Name></UserProg2Name>
|
||||
<UserProg1Dos16Mode>0</UserProg1Dos16Mode>
|
||||
<UserProg2Dos16Mode>0</UserProg2Dos16Mode>
|
||||
</AfterMake>
|
||||
<SelectedForBatchBuild>0</SelectedForBatchBuild>
|
||||
<SVCSIdString></SVCSIdString>
|
||||
</TargetCommonOption>
|
||||
<CommonProperty>
|
||||
<UseCPPCompiler>0</UseCPPCompiler>
|
||||
<RVCTCodeConst>0</RVCTCodeConst>
|
||||
<RVCTZI>0</RVCTZI>
|
||||
<RVCTOtherData>0</RVCTOtherData>
|
||||
<ModuleSelection>0</ModuleSelection>
|
||||
<IncludeInBuild>1</IncludeInBuild>
|
||||
<AlwaysBuild>0</AlwaysBuild>
|
||||
<GenerateAssemblyFile>0</GenerateAssemblyFile>
|
||||
<AssembleAssemblyFile>0</AssembleAssemblyFile>
|
||||
<PublicsOnly>0</PublicsOnly>
|
||||
<StopOnExitCode>3</StopOnExitCode>
|
||||
<CustomArgument></CustomArgument>
|
||||
<IncludeLibraryModules></IncludeLibraryModules>
|
||||
<BankNo>65535</BankNo>
|
||||
</CommonProperty>
|
||||
<DllOption>
|
||||
<SimDllName>S8051.DLL</SimDllName>
|
||||
<SimDllArguments></SimDllArguments>
|
||||
<SimDlgDll>DP51.DLL</SimDlgDll>
|
||||
<SimDlgDllArguments>-pSST5X</SimDlgDllArguments>
|
||||
<TargetDllName>S8051.DLL</TargetDllName>
|
||||
<TargetDllArguments></TargetDllArguments>
|
||||
<TargetDlgDll>TP51.DLL</TargetDlgDll>
|
||||
<TargetDlgDllArguments>-pSST5X</TargetDlgDllArguments>
|
||||
</DllOption>
|
||||
<DebugOption>
|
||||
<OPTHX>
|
||||
<HexSelection>0</HexSelection>
|
||||
<HexRangeLowAddress>0</HexRangeLowAddress>
|
||||
<HexRangeHighAddress>0</HexRangeHighAddress>
|
||||
<HexOffset>0</HexOffset>
|
||||
<Oh166RecLen>16</Oh166RecLen>
|
||||
</OPTHX>
|
||||
<Simulator>
|
||||
<UseSimulator>1</UseSimulator>
|
||||
<LoadApplicationAtStartup>1</LoadApplicationAtStartup>
|
||||
<RunToMain>1</RunToMain>
|
||||
<RestoreBreakpoints>1</RestoreBreakpoints>
|
||||
<RestoreWatchpoints>1</RestoreWatchpoints>
|
||||
<RestoreMemoryDisplay>1</RestoreMemoryDisplay>
|
||||
<RestoreFunctions>1</RestoreFunctions>
|
||||
<RestoreToolbox>1</RestoreToolbox>
|
||||
<LimitSpeedToRealTime>0</LimitSpeedToRealTime>
|
||||
</Simulator>
|
||||
<Target>
|
||||
<UseTarget>0</UseTarget>
|
||||
<LoadApplicationAtStartup>1</LoadApplicationAtStartup>
|
||||
<RunToMain>0</RunToMain>
|
||||
<RestoreBreakpoints>1</RestoreBreakpoints>
|
||||
<RestoreWatchpoints>1</RestoreWatchpoints>
|
||||
<RestoreMemoryDisplay>1</RestoreMemoryDisplay>
|
||||
<RestoreFunctions>0</RestoreFunctions>
|
||||
<RestoreToolbox>1</RestoreToolbox>
|
||||
<RestoreTracepoints>0</RestoreTracepoints>
|
||||
</Target>
|
||||
<RunDebugAfterBuild>0</RunDebugAfterBuild>
|
||||
<TargetSelection>-1</TargetSelection>
|
||||
<SimDlls>
|
||||
<CpuDll></CpuDll>
|
||||
<CpuDllArguments></CpuDllArguments>
|
||||
<PeripheralDll></PeripheralDll>
|
||||
<PeripheralDllArguments></PeripheralDllArguments>
|
||||
<InitializationFile></InitializationFile>
|
||||
</SimDlls>
|
||||
<TargetDlls>
|
||||
<CpuDll></CpuDll>
|
||||
<CpuDllArguments></CpuDllArguments>
|
||||
<PeripheralDll></PeripheralDll>
|
||||
<PeripheralDllArguments></PeripheralDllArguments>
|
||||
<InitializationFile></InitializationFile>
|
||||
<Driver></Driver>
|
||||
</TargetDlls>
|
||||
</DebugOption>
|
||||
<Utilities>
|
||||
<Flash1>
|
||||
<UseTargetDll>0</UseTargetDll>
|
||||
<UseExternalTool>0</UseExternalTool>
|
||||
<RunIndependent>0</RunIndependent>
|
||||
<UpdateFlashBeforeDebugging>0</UpdateFlashBeforeDebugging>
|
||||
<Capability>0</Capability>
|
||||
<DriverSelection>-1</DriverSelection>
|
||||
</Flash1>
|
||||
<Flash2></Flash2>
|
||||
<Flash3>"" ()</Flash3>
|
||||
<Flash4></Flash4>
|
||||
</Utilities>
|
||||
<Target51>
|
||||
<Target51Misc>
|
||||
<MemoryModel>2</MemoryModel>
|
||||
<RTOS>0</RTOS>
|
||||
<RomSize>2</RomSize>
|
||||
<DataHold>0</DataHold>
|
||||
<XDataHold>0</XDataHold>
|
||||
<UseOnchipRom>0</UseOnchipRom>
|
||||
<UseOnchipArithmetic>0</UseOnchipArithmetic>
|
||||
<UseMultipleDPTR>0</UseMultipleDPTR>
|
||||
<UseOnchipXram>0</UseOnchipXram>
|
||||
<HadIRAM>1</HadIRAM>
|
||||
<HadXRAM>0</HadXRAM>
|
||||
<HadIROM>1</HadIROM>
|
||||
<Moda2>0</Moda2>
|
||||
<Moddp2>0</Moddp2>
|
||||
<Modp2>0</Modp2>
|
||||
<Mod517dp>0</Mod517dp>
|
||||
<Mod517au>0</Mod517au>
|
||||
<Mode2>0</Mode2>
|
||||
<useCB>0</useCB>
|
||||
<useXB>0</useXB>
|
||||
<useL251>0</useL251>
|
||||
<useA251>0</useA251>
|
||||
<Mx51>0</Mx51>
|
||||
<ModC812>0</ModC812>
|
||||
<ModCont>0</ModCont>
|
||||
<Lp51>0</Lp51>
|
||||
<useXBS>0</useXBS>
|
||||
<ModDA>0</ModDA>
|
||||
<ModAB2>0</ModAB2>
|
||||
<Mx51P>0</Mx51P>
|
||||
<hadXRAM2>0</hadXRAM2>
|
||||
<uocXram2>0</uocXram2>
|
||||
<ModC2>0</ModC2>
|
||||
<ModH2>0</ModH2>
|
||||
<Mdu_R515>0</Mdu_R515>
|
||||
<Mdu_F120>0</Mdu_F120>
|
||||
<Psoc>0</Psoc>
|
||||
<hadIROM2>0</hadIROM2>
|
||||
<ModSmx2>0</ModSmx2>
|
||||
<cBanks>0</cBanks>
|
||||
<xBanks>0</xBanks>
|
||||
<OnChipMemories>
|
||||
<RCB>
|
||||
<Type>0</Type>
|
||||
<StartAddress>0x0</StartAddress>
|
||||
<Size>0xffff</Size>
|
||||
</RCB>
|
||||
<RXB>
|
||||
<Type>0</Type>
|
||||
<StartAddress>0x0</StartAddress>
|
||||
<Size>0x0</Size>
|
||||
</RXB>
|
||||
<Ocm1>
|
||||
<Type>0</Type>
|
||||
<StartAddress>0x0</StartAddress>
|
||||
<Size>0x0</Size>
|
||||
</Ocm1>
|
||||
<Ocm2>
|
||||
<Type>0</Type>
|
||||
<StartAddress>0x0</StartAddress>
|
||||
<Size>0x0</Size>
|
||||
</Ocm2>
|
||||
<Ocm3>
|
||||
<Type>0</Type>
|
||||
<StartAddress>0x0</StartAddress>
|
||||
<Size>0x0</Size>
|
||||
</Ocm3>
|
||||
<Ocr1>
|
||||
<Type>0</Type>
|
||||
<StartAddress>0x0</StartAddress>
|
||||
<Size>0x0</Size>
|
||||
</Ocr1>
|
||||
<Ocr2>
|
||||
<Type>0</Type>
|
||||
<StartAddress>0x0</StartAddress>
|
||||
<Size>0x0</Size>
|
||||
</Ocr2>
|
||||
<Ocr3>
|
||||
<Type>0</Type>
|
||||
<StartAddress>0x0</StartAddress>
|
||||
<Size>0x0</Size>
|
||||
</Ocr3>
|
||||
<IRO>
|
||||
<Type>1</Type>
|
||||
<StartAddress>0x0</StartAddress>
|
||||
<Size>0x4000</Size>
|
||||
</IRO>
|
||||
<IRA>
|
||||
<Type>0</Type>
|
||||
<StartAddress>0x0</StartAddress>
|
||||
<Size>0x100</Size>
|
||||
</IRA>
|
||||
<XRA>
|
||||
<Type>0</Type>
|
||||
<StartAddress>0x0</StartAddress>
|
||||
<Size>0x0</Size>
|
||||
</XRA>
|
||||
<XRA512>
|
||||
<Type>0</Type>
|
||||
<StartAddress>0x0</StartAddress>
|
||||
<Size>0x0</Size>
|
||||
</XRA512>
|
||||
<IROM512>
|
||||
<Type>0</Type>
|
||||
<StartAddress>0x0</StartAddress>
|
||||
<Size>0x0</Size>
|
||||
</IROM512>
|
||||
</OnChipMemories>
|
||||
</Target51Misc>
|
||||
<C51>
|
||||
<RegisterColoring>0</RegisterColoring>
|
||||
<VariablesInOrder>0</VariablesInOrder>
|
||||
<IntegerPromotion>1</IntegerPromotion>
|
||||
<uAregs>0</uAregs>
|
||||
<UseInterruptVector>1</UseInterruptVector>
|
||||
<Fuzzy>3</Fuzzy>
|
||||
<Optimize>8</Optimize>
|
||||
<WarningLevel>2</WarningLevel>
|
||||
<SizeSpeed>1</SizeSpeed>
|
||||
<ObjectExtend>1</ObjectExtend>
|
||||
<ACallAJmp>0</ACallAJmp>
|
||||
<InterruptVectorAddress>0</InterruptVectorAddress>
|
||||
<VariousControls>
|
||||
<MiscControls></MiscControls>
|
||||
<Define></Define>
|
||||
<Undefine></Undefine>
|
||||
<IncludePath></IncludePath>
|
||||
</VariousControls>
|
||||
</C51>
|
||||
<Ax51>
|
||||
<UseMpl>0</UseMpl>
|
||||
<UseStandard>1</UseStandard>
|
||||
<UseCase>0</UseCase>
|
||||
<UseMod51>0</UseMod51>
|
||||
<VariousControls>
|
||||
<MiscControls></MiscControls>
|
||||
<Define></Define>
|
||||
<Undefine></Undefine>
|
||||
<IncludePath></IncludePath>
|
||||
</VariousControls>
|
||||
</Ax51>
|
||||
<Lx51>
|
||||
<useFile>0</useFile>
|
||||
<linkonly>0</linkonly>
|
||||
<UseMemoryFromTarget>1</UseMemoryFromTarget>
|
||||
<CaseSensitiveSymbols>0</CaseSensitiveSymbols>
|
||||
<WarningLevel>2</WarningLevel>
|
||||
<DataOverlaying>1</DataOverlaying>
|
||||
<OverlayString></OverlayString>
|
||||
<MiscControls></MiscControls>
|
||||
<DisableWarningNumbers></DisableWarningNumbers>
|
||||
<LinkerCmdFile></LinkerCmdFile>
|
||||
<Assign></Assign>
|
||||
<ReserveString></ReserveString>
|
||||
<CClasses></CClasses>
|
||||
<UserClasses></UserClasses>
|
||||
<CSection></CSection>
|
||||
<UserSection></UserSection>
|
||||
<CodeBaseAddress></CodeBaseAddress>
|
||||
<XDataBaseAddress></XDataBaseAddress>
|
||||
<PDataBaseAddress></PDataBaseAddress>
|
||||
<BitBaseAddress></BitBaseAddress>
|
||||
<DataBaseAddress></DataBaseAddress>
|
||||
<IDataBaseAddress></IDataBaseAddress>
|
||||
<Precede></Precede>
|
||||
<Stack></Stack>
|
||||
<CodeSegmentName></CodeSegmentName>
|
||||
<XDataSegmentName></XDataSegmentName>
|
||||
<BitSegmentName></BitSegmentName>
|
||||
<DataSegmentName></DataSegmentName>
|
||||
<IDataSegmentName></IDataSegmentName>
|
||||
</Lx51>
|
||||
</Target51>
|
||||
</TargetOption>
|
||||
<Groups>
|
||||
<Group>
|
||||
<GroupName>Source Group 1</GroupName>
|
||||
<Files>
|
||||
<File>
|
||||
<FileName>Debug.C</FileName>
|
||||
<FileType>1</FileType>
|
||||
<FilePath>.\Public\Debug.C</FilePath>
|
||||
</File>
|
||||
<File>
|
||||
<FileName>USBHOST.C</FileName>
|
||||
<FileType>1</FileType>
|
||||
<FilePath>.\USB\USB_LIB\USBHOST.C</FilePath>
|
||||
</File>
|
||||
<File>
|
||||
<FileName>EXAM1.C</FileName>
|
||||
<FileType>1</FileType>
|
||||
<FilePath>.\USB\U_DISK\EXAM1\EXAM1.C</FilePath>
|
||||
</File>
|
||||
</Files>
|
||||
</Group>
|
||||
</Groups>
|
||||
</Target>
|
||||
</Targets>
|
||||
|
||||
</Project>
|
65
examples/DataFlash/DataFlash.C
Normal file
65
examples/DataFlash/DataFlash.C
Normal file
@ -0,0 +1,65 @@
|
||||
|
||||
/********************************** (C) COPYRIGHT *******************************
|
||||
* File Name : DataFlash.C
|
||||
* Author : WCH
|
||||
* Version : V1.0
|
||||
* Date : 2017/01/20
|
||||
* Description : CH554 DataFlash字节读写函数定义
|
||||
*******************************************************************************/
|
||||
|
||||
#include "..\Public\CH554.H"
|
||||
#include "..\Public\Debug.H"
|
||||
#include "DataFlash.H"
|
||||
|
||||
/*******************************************************************************
|
||||
* Function Name : WriteDataFlash(UINT8 Addr,PUINT8 buf,UINT8 len)
|
||||
* Description : DataFlash写
|
||||
* Input : UINT8 Addr,PUINT16 buf,UINT8 len
|
||||
* Output : None
|
||||
* Return : UINT8 i 返回写入长度
|
||||
*******************************************************************************/
|
||||
UINT8 WriteDataFlash(UINT8 Addr,PUINT8 buf,UINT8 len)
|
||||
{
|
||||
UINT8 i;
|
||||
SAFE_MOD = 0x55;
|
||||
SAFE_MOD = 0xAA; //进入安全模式
|
||||
GLOBAL_CFG |= bDATA_WE; //使能DataFlash写
|
||||
SAFE_MOD = 0; //退出安全模式
|
||||
ROM_ADDR_H = DATA_FLASH_ADDR >> 8;
|
||||
Addr <<= 1;
|
||||
for(i=0;i<len;i++)
|
||||
{
|
||||
ROM_ADDR_L = Addr + i*2;
|
||||
ROM_DATA_L = *(buf+i);
|
||||
if ( ROM_STATUS & bROM_ADDR_OK ) { // 操作地址有效
|
||||
ROM_CTRL = ROM_CMD_WRITE; // 写入
|
||||
}
|
||||
if((ROM_STATUS ^ bROM_ADDR_OK) > 0) return i; // 返回状态,0x00=success, 0x02=unknown command(bROM_CMD_ERR)
|
||||
}
|
||||
SAFE_MOD = 0x55;
|
||||
SAFE_MOD = 0xAA; //进入安全模式
|
||||
GLOBAL_CFG &= ~bDATA_WE; //开启DataFlash写保护
|
||||
SAFE_MOD = 0; //退出安全模式
|
||||
return i;
|
||||
}
|
||||
|
||||
/*******************************************************************************
|
||||
* Function Name : ReadDataFlash(UINT8 Addr,UINT8 len,PUINT8 buf)
|
||||
* Description : 读DataFlash
|
||||
* Input : UINT8 Addr UINT8 len PUINT8 buf
|
||||
* Output : None
|
||||
* Return : UINT8 i 返回写入长度
|
||||
*******************************************************************************/
|
||||
UINT8 ReadDataFlash(UINT8 Addr,UINT8 len,PUINT8 buf)
|
||||
{
|
||||
UINT8 i;
|
||||
ROM_ADDR_H = DATA_FLASH_ADDR >> 8;
|
||||
Addr <<= 1;
|
||||
for(i=0;i<len;i++){
|
||||
ROM_ADDR_L = Addr + i*2; //Addr必须为偶地址
|
||||
ROM_CTRL = ROM_CMD_READ;
|
||||
// if ( ROM_STATUS & bROM_CMD_ERR ) return( 0xFF ); // unknown command
|
||||
*(buf+i) = ROM_DATA_L;
|
||||
}
|
||||
return i;
|
||||
}
|
18
examples/DataFlash/DataFlash.H
Normal file
18
examples/DataFlash/DataFlash.H
Normal file
@ -0,0 +1,18 @@
|
||||
|
||||
/*******************************************************************************
|
||||
* Function Name : WriteDataFlash(UINT16 Addr,PUINT8 buf,UINT8 len)
|
||||
* Description : DataFlashĐ´
|
||||
* Input : UINT16 AddrŁŹPUINT16 buf,UINT8 len
|
||||
* Output : None
|
||||
* Return :
|
||||
*******************************************************************************/
|
||||
UINT8 WriteDataFlash(UINT8 Addr,PUINT8 buf,UINT8 len);
|
||||
|
||||
/*******************************************************************************
|
||||
* Function Name : ReadDataFlash(UINT8 Addr,UINT8 len,PUINT8 buf)
|
||||
* Description : śÁDataFlash
|
||||
* Input : UINT16 Addr PUINT8 buf
|
||||
* Output : None
|
||||
* Return : UINT8 l
|
||||
*******************************************************************************/
|
||||
UINT8 ReadDataFlash(UINT8 Addr,UINT8 len,PUINT8 buf);
|
44
examples/DataFlash/Main.C
Normal file
44
examples/DataFlash/Main.C
Normal file
@ -0,0 +1,44 @@
|
||||
|
||||
/********************************** (C) COPYRIGHT *******************************
|
||||
* File Name : Main.C
|
||||
* Author : WCH
|
||||
* Version : V1.0
|
||||
* Date : 2017/01/20
|
||||
* Description : CH554 DataFlash字节读写演示示例
|
||||
写 DataFlash 数据区域,向目标地址写入单字节数据
|
||||
读 DataFlash 数据区域,从目标地址读取单字节数据
|
||||
*******************************************************************************/
|
||||
|
||||
#include "..\Public\CH554.H"
|
||||
#include "..\Public\Debug.H"
|
||||
#include "DataFlash.H"
|
||||
#include "stdio.h"
|
||||
#include <string.h>
|
||||
|
||||
void main( )
|
||||
{
|
||||
UINT8 i,m,len;
|
||||
UINT16 j = 0;
|
||||
CfgFsys( ); //CH554时钟选择配置
|
||||
mDelaymS(20);
|
||||
mInitSTDIO( ); //串口0初始化
|
||||
printf("start ...\n");
|
||||
|
||||
while(1){
|
||||
for(i=0;i<128;i++){ //循环写入128字节
|
||||
len = WriteDataFlash(i,&i,1); //向DataFlash区域偏移地址i写入i
|
||||
if(len != 1){
|
||||
printf("Write Err 次 = %02x,m = %02x\n",j,(UINT16)m); //写出错打印
|
||||
}
|
||||
}
|
||||
for(i=0;i<128;i++){ //读DataFlash区域偏移地址i并校验
|
||||
len = ReadDataFlash(i,1,&m);
|
||||
if((len != 1) ||(m != i)){
|
||||
printf("Read Err 次 = %02x, = %02x,addr =%02x ,值= %02x\n",j,(UINT16)(i*2),(UINT16)ROM_DATA_L,(UINT16)m);
|
||||
} //读校验出错打印
|
||||
}
|
||||
printf("$$OK %02x \n",j);
|
||||
j++;
|
||||
mDelaymS(100);
|
||||
}
|
||||
}
|
118
examples/GPIO/GPIO.C
Normal file
118
examples/GPIO/GPIO.C
Normal file
@ -0,0 +1,118 @@
|
||||
|
||||
/********************************** (C) COPYRIGHT *******************************
|
||||
* File Name : GPIO.C
|
||||
* Author : WCH
|
||||
* Version : V1.0
|
||||
* Date : 2017/01/20
|
||||
* Description : CH554 IO 设置接口函数和GPIO中断函数
|
||||
*******************************************************************************/
|
||||
|
||||
#include "..\Public\CH554.H"
|
||||
#include "..\Public\Debug.H"
|
||||
#include "GPIO.H"
|
||||
#include "stdio.h"
|
||||
|
||||
#pragma NOAREGS
|
||||
|
||||
/*******************************************************************************
|
||||
* Function Name : Port1Cfg()
|
||||
* Description : 端口1配置
|
||||
* Input : Mode 0 = 浮空输入,无上拉
|
||||
1 = 推挽输入输出
|
||||
2 = 开漏输入输出,无上拉
|
||||
3 = 类51模式,开漏输入输出,有上拉,内部电路可以加速由低到高的电平爬升
|
||||
,UINT8 Pin (0-7)
|
||||
* Output : None
|
||||
* Return : None
|
||||
*******************************************************************************/
|
||||
void Port1Cfg(UINT8 Mode,UINT8 Pin)
|
||||
{
|
||||
switch(Mode){
|
||||
case 0:
|
||||
P1_MOD_OC = P1_MOD_OC & ~(1<<Pin);
|
||||
P1_DIR_PU = P1_DIR_PU & ~(1<<Pin);
|
||||
break;
|
||||
case 1:
|
||||
P1_MOD_OC = P1_MOD_OC & ~(1<<Pin);
|
||||
P1_DIR_PU = P1_DIR_PU | (1<<Pin);
|
||||
break;
|
||||
case 2:
|
||||
P1_MOD_OC = P1_MOD_OC | (1<<Pin);
|
||||
P1_DIR_PU = P1_DIR_PU & ~(1<<Pin);
|
||||
break;
|
||||
case 3:
|
||||
P1_MOD_OC = P1_MOD_OC | (1<<Pin);
|
||||
P1_DIR_PU = P1_DIR_PU | (1<<Pin);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/*******************************************************************************
|
||||
* Function Name : Port3Cfg()
|
||||
* Description : 端口3配置
|
||||
* Input : Mode 0 = 浮空输入,无上拉
|
||||
1 = 推挽输入输出
|
||||
2 = 开漏输入输出,无上拉
|
||||
3 = 类51模式,开漏输入输出,有上拉,内部电路可以加速由低到高的电平爬升
|
||||
,UINT8 Pin (0-7)
|
||||
* Output : None
|
||||
* Return : None
|
||||
*******************************************************************************/
|
||||
void Port3Cfg(UINT8 Mode,UINT8 Pin)
|
||||
{
|
||||
switch(Mode){
|
||||
case 0:
|
||||
P3_MOD_OC = P3_MOD_OC & ~(1<<Pin);
|
||||
P3_DIR_PU = P3_DIR_PU & ~(1<<Pin);
|
||||
break;
|
||||
case 1:
|
||||
P3_MOD_OC = P3_MOD_OC & ~(1<<Pin);
|
||||
P3_DIR_PU = P3_DIR_PU | (1<<Pin);
|
||||
break;
|
||||
case 2:
|
||||
P3_MOD_OC = P3_MOD_OC | (1<<Pin);
|
||||
P3_DIR_PU = P3_DIR_PU & ~(1<<Pin);
|
||||
break;
|
||||
case 3:
|
||||
P3_MOD_OC = P3_MOD_OC | (1<<Pin);
|
||||
P3_DIR_PU = P3_DIR_PU | (1<<Pin);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/*******************************************************************************
|
||||
* Function Name : GPIOInterruptCfg()
|
||||
* Description : GPIO中断配置
|
||||
* Input : None
|
||||
* Output : None
|
||||
* Return : None
|
||||
*******************************************************************************/
|
||||
void GPIOInterruptCfg()
|
||||
{
|
||||
GPIO_IE &= ~bIE_IO_EDGE; //高/低电平触发
|
||||
// GPIO_IE |= bIE_IO_EDGE; //上升/下降触发
|
||||
// GPIO_IE |= bIE_RXD1_LO; //RXD1低电平或下降沿触发
|
||||
GPIO_IE |= bIE_P1_5_LO | bIE_P1_4_LO | bIE_P1_3_LO | bIE_RST_HI;
|
||||
//P15\P14\P13低电平触发;RST高电平触发
|
||||
// GPIO_IE |= bIE_P3_1_LO; //P31低电平或下降沿触发
|
||||
// GPIO_IE |= bIE_RXD0_LO; //RXD0低电平或下降沿触发
|
||||
IE_GPIO = 1; //GPIO中断开启
|
||||
}
|
||||
|
||||
#ifdef GPIO_INTERRUPT
|
||||
/*******************************************************************************
|
||||
* Function Name : GPIOInterrupt(void)
|
||||
* Description : GPIO 中断服务程序
|
||||
*******************************************************************************/
|
||||
void GPIOInterrupt( void ) interrupt INT_NO_GPIO using 1 //GPIO中断服务程序,使用寄存器组1
|
||||
{
|
||||
#ifdef DE_PRINTF
|
||||
printf("GPIO_STATUS: %02x\n",(UINT16)(PIN_FUNC&bIO_INT_ACT));
|
||||
#endif
|
||||
}
|
||||
#endif
|
||||
|
25
examples/GPIO/GPIO.H
Normal file
25
examples/GPIO/GPIO.H
Normal file
@ -0,0 +1,25 @@
|
||||
|
||||
#define GPIO_INTERRUPT 1
|
||||
|
||||
/*******************************************************************************
|
||||
* Function Name : Port1Cfg()
|
||||
* Description : 端口1配置
|
||||
* Input : Mode 0 = 浮空输入,无上拉
|
||||
1 = 推挽输入输出
|
||||
2 = 开漏输入输出,无上拉
|
||||
3 = 类51模式,开漏输入输出,有上拉,内部电路可以加速由低到高的电平爬升
|
||||
,UINT8 Pin (0-7)
|
||||
* Output : None
|
||||
* Return : None
|
||||
*******************************************************************************/
|
||||
void Port1Cfg(UINT8 Mode,UINT8 Pin);
|
||||
void Port3Cfg(UINT8 Mode,UINT8 Pin);
|
||||
|
||||
/*******************************************************************************
|
||||
* Function Name : GPIOInterruptCfg()
|
||||
* Description : GPIO中断配置
|
||||
* Input : None
|
||||
* Output : None
|
||||
* Return : None
|
||||
*******************************************************************************/
|
||||
void GPIOInterruptCfg();
|
39
examples/GPIO/Main.C
Normal file
39
examples/GPIO/Main.C
Normal file
@ -0,0 +1,39 @@
|
||||
|
||||
/********************************** (C) COPYRIGHT *******************************
|
||||
* File Name : Main.C
|
||||
* Author : WCH
|
||||
* Version : V1.0
|
||||
* Date : 2017/01/20
|
||||
* Description : GPIO 设置与使用和GPIO中断使用示例
|
||||
*******************************************************************************/
|
||||
#include "..\Public\CH554.H"
|
||||
#include "..\Public\Debug.H"
|
||||
#include "GPIO.H"
|
||||
#include "stdio.h"
|
||||
#include <string.h>
|
||||
|
||||
#pragma NOAREGS
|
||||
|
||||
void main( )
|
||||
{
|
||||
UINT16 j = 0;
|
||||
CfgFsys( ); //CH554时钟选择配置
|
||||
mDelaymS(20);
|
||||
mInitSTDIO( ); //串口0初始化
|
||||
printf("start ...\n");
|
||||
|
||||
#if GPIO_INTERRUPT
|
||||
GPIOInterruptCfg(); //GPIO中断配置函数
|
||||
EA = 1;
|
||||
printf("Run");
|
||||
while(1){
|
||||
printf(".");
|
||||
mDelaymS(50);
|
||||
}
|
||||
#endif
|
||||
Port1Cfg(3,4); //P14设置成类51双向模式
|
||||
while(1){
|
||||
SCS = ~SCS;
|
||||
mDelaymS(50);
|
||||
}
|
||||
}
|
44
examples/IAP/CH554IAPDemo.C
Normal file
44
examples/IAP/CH554IAPDemo.C
Normal file
@ -0,0 +1,44 @@
|
||||
|
||||
/********************************** (C) COPYRIGHT ******************************
|
||||
* File Name : CH554IAPDemo.C
|
||||
* Author : WCH
|
||||
* Version : V1.0
|
||||
* Date : 2017/01/20
|
||||
* Description : 上电运行后P17LED灯闪烁,当检测“EnableIAP”脚为低电平后,将从用户程序跳转至BOOT,通过BOOT升级用户程序
|
||||
*******************************************************************************/
|
||||
#include "./Public/CH554.H"
|
||||
#include "./Public/Debug.H"
|
||||
|
||||
sbit EnableIAP = P1^6;
|
||||
#define BOOT_ADDR 0x3800
|
||||
|
||||
#pragma NOAREGS
|
||||
|
||||
/*******************************************************************************
|
||||
* Function Name : main
|
||||
* Description : 主函数
|
||||
* :
|
||||
* Input : None
|
||||
* Output : None
|
||||
* Return : None
|
||||
*******************************************************************************/
|
||||
typedef void( *pTaskFn)( void );
|
||||
|
||||
pTaskFn tasksArr[1];
|
||||
|
||||
void main( void )
|
||||
{
|
||||
UINT16 i=0;
|
||||
while(1){
|
||||
SCK = ~SCK; //P17闪烁
|
||||
mDelaymS(50);
|
||||
if(EnableIAP == 0){ //P16引脚检测到低电平跳转
|
||||
break;
|
||||
}
|
||||
}
|
||||
EA = 0; //关闭总中断,必加
|
||||
tasksArr[0] = BOOT_ADDR;
|
||||
mDelaymS( 100 );
|
||||
(tasksArr[0])( ); //跳至BOOT升级程序,使用ISP工具升级
|
||||
while(1);
|
||||
}
|
56
examples/PWM/Main.C
Normal file
56
examples/PWM/Main.C
Normal file
@ -0,0 +1,56 @@
|
||||
|
||||
/********************************** (C) COPYRIGHT *******************************
|
||||
* File Name : Main.C
|
||||
* Author : WCH
|
||||
* Version : V1.0
|
||||
* Date : 2017/01/20
|
||||
* Description : CH554 PWM初始化,占空比设置,PWM默认电平设置
|
||||
支持中断方式修改PWM占空比
|
||||
*******************************************************************************/
|
||||
|
||||
#include "..\Public\CH554.H"
|
||||
#include "..\Public\Debug.H"
|
||||
#include "PWM.H"
|
||||
#include "stdio.h"
|
||||
|
||||
#pragma NOAREGS
|
||||
|
||||
main( )
|
||||
{
|
||||
CfgFsys( ); //CH554时钟选择配置
|
||||
mDelaymS(5); //配置时钟后,建议延时稳定时钟
|
||||
mInitSTDIO( ); //串口0初始化
|
||||
printf("start ...\n");
|
||||
|
||||
P1_MOD_OC &= ~(bPWM1 | bPWM2); //设置PWM引脚为推挽输出
|
||||
P1_DIR_PU |= bPWM1 | bPWM2;
|
||||
|
||||
SetPWMClk(4); //PWM时钟配置 ,4分频
|
||||
ForceClearPWMFIFO( ); //强制清除PWM FIFO和COUNT
|
||||
CancleClearPWMFIFO( ); //取消清除PWM FIFO和COUNT
|
||||
PWM1OutEnable( ); //允许PWM1输出
|
||||
PWM2OutEnable( ); //允许PWM2输出
|
||||
|
||||
PWM1OutPolarHighAct( ); //PWM1输出默认低,高有效
|
||||
PWM2OutPolarLowAct( ); //PWM2输出默认高,低有效
|
||||
|
||||
#if PWM_INTERRUPT
|
||||
PWMInterruptEnable();
|
||||
EA = 1;
|
||||
SetPWM1Dat(0x10);
|
||||
SetPWM2Dat(0x40);
|
||||
while(1);
|
||||
#endif
|
||||
SetPWM1Dat(0x10); //占空比0x10/256
|
||||
SetPWM2Dat(0x40);
|
||||
while(1){
|
||||
if(PWM_CTRL&bPWM_IF_END){
|
||||
PWM_CTRL |= bPWM_IF_END; //清除PWM中断
|
||||
SetPWM1Dat(0x10);
|
||||
SetPWM2Dat(0x40);
|
||||
#ifdef DE_PRINTF
|
||||
printf("PWM_CYC_END %02X\n",(UINT16)PWM_CTRL);
|
||||
#endif
|
||||
}
|
||||
}
|
||||
}
|
42
examples/PWM/PWM.C
Normal file
42
examples/PWM/PWM.C
Normal file
@ -0,0 +1,42 @@
|
||||
/********************************** (C) COPYRIGHT *******************************
|
||||
* File Name : PWM.C
|
||||
* Author : WCH
|
||||
* Version : V1.0
|
||||
* Date : 2017/01/20
|
||||
* Description : CH554 PWM中断使能和中断处理
|
||||
*******************************************************************************/
|
||||
|
||||
#include "..\Public\CH554.H"
|
||||
#include "..\Public\Debug.H"
|
||||
#include "PWM.H"
|
||||
#include "stdio.h"
|
||||
|
||||
#pragma NOAREGS
|
||||
|
||||
#if PWM_INTERRUPT
|
||||
/*******************************************************************************
|
||||
* Function Name : PWMInterruptEnable()
|
||||
* Description : PWM中断使能
|
||||
* Input : None
|
||||
* Output : None
|
||||
* Return : None
|
||||
*******************************************************************************/
|
||||
void PWMInterruptEnable()
|
||||
{
|
||||
PWM_CTRL |= bPWM_IF_END | bPWM_IE_END; //清除PWM中断,使能PWM中断
|
||||
IE_PWMX = 1;
|
||||
}
|
||||
|
||||
/*******************************************************************************
|
||||
* Function Name : PWMInterrupt(void)
|
||||
* Description : PWM中断服务程序
|
||||
*******************************************************************************/
|
||||
void PWMInterrupt( void ) interrupt INT_NO_PWMX using 1 //PWM1&2中断服务程序,使用寄存器组1
|
||||
{
|
||||
PWM_CTRL |= bPWM_IF_END; //清除PWM中断
|
||||
SetPWM1Dat(0x10);
|
||||
SetPWM2Dat(0x40);
|
||||
// printf("PWM_CTRL %02X\n",(UINT16)PWM_CTRL); //开启可以用于查看是否进入中断
|
||||
}
|
||||
#endif
|
||||
|
27
examples/PWM/PWM.H
Normal file
27
examples/PWM/PWM.H
Normal file
@ -0,0 +1,27 @@
|
||||
|
||||
#define PWM_INTERRUPT 1
|
||||
|
||||
#if PWM_INTERRUPT
|
||||
extern void PWMInterruptEnable(); //PWM中断使能
|
||||
#endif
|
||||
|
||||
#define SetPWMClk(CK_SE) (PWM_CK_SE = CK_SE) //分频,默认时钟Fsys
|
||||
|
||||
#define SetPWM1Dat(dat) (PWM_DATA1 = dat) //设置PWM输出占空比
|
||||
#define SetPWM2Dat(dat) (PWM_DATA2 = dat)
|
||||
|
||||
#define PWM1PINAlter( ) {PIN_FUNC |= bPWM1_PIN_X;} //PWM映射脚P30
|
||||
#define PWM2PINAlter( ) {PIN_FUNC |= bPWM2_PIN_X;} //PWM映射脚P31
|
||||
|
||||
#define ForceClearPWMFIFO( ) {PWM_CTRL |= bPWM_CLR_ALL;} //强制清除PWM FIFO和COUNT
|
||||
#define CancleClearPWMFIFO( ) {PWM_CTRL &= ~bPWM_CLR_ALL;} //取消清除PWM FIFO和COUNT
|
||||
|
||||
#define PWM1OutEnable() (PWM_CTRL |= bPWM1_OUT_EN) //允许PWM1输出
|
||||
#define PWM2OutEnable() (PWM_CTRL |= bPWM2_OUT_EN) //允许PWM2输出
|
||||
#define DsiablePWM1Out() (PWM_CTRL &= ~bPWM1_OUT_EN) //关闭PWM1输出
|
||||
#define DisablePWM2Out() (PWM_CTRL &= ~bPWM2_OUT_EN) //关闭PWM2输出
|
||||
|
||||
#define PWM1OutPolarHighAct()(PWM_CTRL &= ~bPWM1_POLAR) //PWM1输出默认低,高有效
|
||||
#define PWM2OutPolarHighAct()(PWM_CTRL &= ~bPWM2_POLAR) //PWM2输出默认低,高有效
|
||||
#define PWM1OutPolarLowAct() (PWM_CTRL |= bPWM1_POLAR) //PWM1输出默认高,低有效
|
||||
#define PWM2OutPolarLowAct() (PWM_CTRL |= bPWM2_POLAR) //PWM2输出默认高,低有效
|
1217
examples/Public/CH554.H
Normal file
1217
examples/Public/CH554.H
Normal file
File diff suppressed because it is too large
Load Diff
271
examples/Public/Debug.C
Normal file
271
examples/Public/Debug.C
Normal file
@ -0,0 +1,271 @@
|
||||
/********************************** (C) COPYRIGHT *******************************
|
||||
* File Name : Debug.C
|
||||
* Author : WCH
|
||||
* Version : V1.0
|
||||
* Date : 2017/01/20
|
||||
* Description : CH554 DEBUG Interface
|
||||
CH554主频修改、延时函数定义
|
||||
串口0和串口1初始化
|
||||
串口0和串口1的收发子函数
|
||||
看门狗初始化
|
||||
*******************************************************************************/
|
||||
|
||||
#include "CH554.H"
|
||||
#include "Debug.H"
|
||||
|
||||
/*******************************************************************************
|
||||
* Function Name : CfgFsys( )
|
||||
* Description : CH554时钟选择和配置函数,默认使用Fsys 6MHz,FREQ_SYS可以通过
|
||||
CLOCK_CFG配置得到,公式如下:
|
||||
Fsys = (Fosc * 4/(CLOCK_CFG & MASK_SYS_CK_SEL);具体时钟需要自己配置
|
||||
* Input : None
|
||||
* Output : None
|
||||
* Return : None
|
||||
*******************************************************************************/
|
||||
void CfgFsys( )
|
||||
{
|
||||
// SAFE_MOD = 0x55;
|
||||
// SAFE_MOD = 0xAA;
|
||||
// CLOCK_CFG |= bOSC_EN_XT; //使能外部晶振
|
||||
// CLOCK_CFG &= ~bOSC_EN_INT; //关闭内部晶振
|
||||
SAFE_MOD = 0x55;
|
||||
SAFE_MOD = 0xAA;
|
||||
// CLOCK_CFG = CLOCK_CFG & ~ MASK_SYS_CK_SEL | 0x07; // 32MHz
|
||||
// CLOCK_CFG = CLOCK_CFG & ~ MASK_SYS_CK_SEL | 0x06; // 24MHz
|
||||
// CLOCK_CFG = CLOCK_CFG & ~ MASK_SYS_CK_SEL | 0x05; // 16MHz
|
||||
CLOCK_CFG = CLOCK_CFG & ~ MASK_SYS_CK_SEL | 0x04; // 12MHz
|
||||
// CLOCK_CFG = CLOCK_CFG & ~ MASK_SYS_CK_SEL | 0x03; // 6MHz
|
||||
// CLOCK_CFG = CLOCK_CFG & ~ MASK_SYS_CK_SEL | 0x02; // 3MHz
|
||||
// CLOCK_CFG = CLOCK_CFG & ~ MASK_SYS_CK_SEL | 0x01; // 750KHz
|
||||
// CLOCK_CFG = CLOCK_CFG & ~ MASK_SYS_CK_SEL | 0x00; // 187.5MHz
|
||||
SAFE_MOD = 0x00;
|
||||
}
|
||||
|
||||
/*******************************************************************************
|
||||
* Function Name : mDelayus(UNIT16 n)
|
||||
* Description : us延时函数
|
||||
* Input : UNIT16 n
|
||||
* Output : None
|
||||
* Return : None
|
||||
*******************************************************************************/
|
||||
void mDelayuS( UINT16 n ) // 以uS为单位延时
|
||||
{
|
||||
#ifdef FREQ_SYS
|
||||
#if FREQ_SYS <= 6000000
|
||||
n >>= 2;
|
||||
#endif
|
||||
#if FREQ_SYS <= 3000000
|
||||
n >>= 2;
|
||||
#endif
|
||||
#if FREQ_SYS <= 750000
|
||||
n >>= 4;
|
||||
#endif
|
||||
#endif
|
||||
while ( n ) { // total = 12~13 Fsys cycles, 1uS @Fsys=12MHz
|
||||
++ SAFE_MOD; // 2 Fsys cycles, for higher Fsys, add operation here
|
||||
#ifdef FREQ_SYS
|
||||
#if FREQ_SYS >= 14000000
|
||||
++ SAFE_MOD;
|
||||
#endif
|
||||
#if FREQ_SYS >= 16000000
|
||||
++ SAFE_MOD;
|
||||
#endif
|
||||
#if FREQ_SYS >= 18000000
|
||||
++ SAFE_MOD;
|
||||
#endif
|
||||
#if FREQ_SYS >= 20000000
|
||||
++ SAFE_MOD;
|
||||
#endif
|
||||
#if FREQ_SYS >= 22000000
|
||||
++ SAFE_MOD;
|
||||
#endif
|
||||
#if FREQ_SYS >= 24000000
|
||||
++ SAFE_MOD;
|
||||
#endif
|
||||
#if FREQ_SYS >= 26000000
|
||||
++ SAFE_MOD;
|
||||
#endif
|
||||
#if FREQ_SYS >= 28000000
|
||||
++ SAFE_MOD;
|
||||
#endif
|
||||
#if FREQ_SYS >= 30000000
|
||||
++ SAFE_MOD;
|
||||
#endif
|
||||
#if FREQ_SYS >= 32000000
|
||||
++ SAFE_MOD;
|
||||
#endif
|
||||
#endif
|
||||
-- n;
|
||||
}
|
||||
}
|
||||
|
||||
/*******************************************************************************
|
||||
* Function Name : mDelayms(UNIT16 n)
|
||||
* Description : ms延时函数
|
||||
* Input : UNIT16 n
|
||||
* Output : None
|
||||
* Return : None
|
||||
*******************************************************************************/
|
||||
void mDelaymS( UINT16 n ) // 以mS为单位延时
|
||||
{
|
||||
while ( n ) {
|
||||
#ifdef DELAY_MS_HW
|
||||
while ( ( TKEY_CTRL & bTKC_IF ) == 0 );
|
||||
while ( TKEY_CTRL & bTKC_IF );
|
||||
#else
|
||||
mDelayuS( 1000 );
|
||||
#endif
|
||||
-- n;
|
||||
}
|
||||
}
|
||||
|
||||
/*******************************************************************************
|
||||
* Function Name : CH554UART0Alter()
|
||||
* Description : CH554串口0引脚映射,串口映射到P0.2和P0.3
|
||||
* Input : None
|
||||
* Output : None
|
||||
* Return : None
|
||||
*******************************************************************************/
|
||||
void CH554UART0Alter()
|
||||
{
|
||||
PIN_FUNC |= bUART0_PIN_X; //串口映射到P1.2和P1.3
|
||||
}
|
||||
|
||||
/*******************************************************************************
|
||||
* Function Name : mInitSTDIO()
|
||||
* Description : CH554串口0初始化,默认使用T1作UART0的波特率发生器,也可以使用T2
|
||||
作为波特率发生器
|
||||
* Input : None
|
||||
* Output : None
|
||||
* Return : None
|
||||
*******************************************************************************/
|
||||
void mInitSTDIO( )
|
||||
{
|
||||
UINT32 x;
|
||||
UINT8 x2;
|
||||
|
||||
SM0 = 0;
|
||||
SM1 = 1;
|
||||
SM2 = 0; //串口0使用模式1
|
||||
//使用Timer1作为波特率发生器
|
||||
RCLK = 0; //UART0接收时钟
|
||||
TCLK = 0; //UART0发送时钟
|
||||
PCON |= SMOD;
|
||||
x = 10 * FREQ_SYS / UART0_BUAD / 16; //如果更改主频,注意x的值不要溢出
|
||||
x2 = x % 10;
|
||||
x /= 10;
|
||||
if ( x2 >= 5 ) x ++; //四舍五入
|
||||
|
||||
TMOD = TMOD & ~ bT1_GATE & ~ bT1_CT & ~ MASK_T1_MOD | bT1_M1; //0X20,Timer1作为8位自动重载定时器
|
||||
T2MOD = T2MOD | bTMR_CLK | bT1_CLK; //Timer1时钟选择
|
||||
TH1 = 0-x; //12MHz晶振,buad/12为实际需设置波特率
|
||||
TR1 = 1; //启动定时器1
|
||||
TI = 1;
|
||||
REN = 1; //串口0接收使能
|
||||
}
|
||||
|
||||
/*******************************************************************************
|
||||
* Function Name : CH554UART0RcvByte()
|
||||
* Description : CH554UART0接收一个字节
|
||||
* Input : None
|
||||
* Output : None
|
||||
* Return : SBUF
|
||||
*******************************************************************************/
|
||||
UINT8 CH554UART0RcvByte( )
|
||||
{
|
||||
while(RI == 0); //查询接收,中断方式可不用
|
||||
RI = 0;
|
||||
return SBUF;
|
||||
}
|
||||
|
||||
/*******************************************************************************
|
||||
* Function Name : CH554UART0SendByte(UINT8 SendDat)
|
||||
* Description : CH554UART0发送一个字节
|
||||
* Input : UINT8 SendDat;要发送的数据
|
||||
* Output : None
|
||||
* Return : None
|
||||
*******************************************************************************/
|
||||
void CH554UART0SendByte(UINT8 SendDat)
|
||||
{
|
||||
SBUF = SendDat; //查询发送,中断方式可不用下面2条语句,但发送前需TI=0
|
||||
while(TI ==0);
|
||||
TI = 0;
|
||||
}
|
||||
|
||||
/*******************************************************************************
|
||||
* Function Name : UART1Setup()
|
||||
* Description : CH554串口1初始化
|
||||
* Input : None
|
||||
* Output : None
|
||||
* Return : None
|
||||
*******************************************************************************/
|
||||
void UART1Setup( )
|
||||
{
|
||||
U1SM0 = 0; //UART1选择8位数据位
|
||||
U1SMOD = 1; //快速模式
|
||||
U1REN = 1; //使能接收
|
||||
SBAUD1 = 0 - FREQ_SYS/16/UART1_BUAD;
|
||||
}
|
||||
|
||||
/*******************************************************************************
|
||||
* Function Name : CH554UART1RcvByte()
|
||||
* Description : CH554UART1接收一个字节
|
||||
* Input : None
|
||||
* Output : None
|
||||
* Return : SBUF
|
||||
*******************************************************************************/
|
||||
UINT8 CH554UART1RcvByte( )
|
||||
{
|
||||
while(U1RI == 0); //查询接收,中断方式可不用
|
||||
U1RI = 0;
|
||||
return SBUF1;
|
||||
}
|
||||
|
||||
/*******************************************************************************
|
||||
* Function Name : CH554UART1SendByte(UINT8 SendDat)
|
||||
* Description : CH554UART1发送一个字节
|
||||
* Input : UINT8 SendDat;要发送的数据
|
||||
* Output : None
|
||||
* Return : None
|
||||
*******************************************************************************/
|
||||
void CH554UART1SendByte(UINT8 SendDat)
|
||||
{
|
||||
SBUF1 = SendDat; //查询发送,中断方式可不用下面2条语句,但发送前需TI=0
|
||||
while(U1TI ==0);
|
||||
U1TI = 1;
|
||||
}
|
||||
|
||||
/*******************************************************************************
|
||||
* Function Name : CH554WDTModeSelect(UINT8 mode)
|
||||
* Description : CH554看门狗模式选择
|
||||
* Input : UINT8 mode
|
||||
0 timer
|
||||
1 watchDog
|
||||
* Output : None
|
||||
* Return : None
|
||||
*******************************************************************************/
|
||||
void CH554WDTModeSelect(UINT8 mode)
|
||||
{
|
||||
SAFE_MOD = 0x55;
|
||||
SAFE_MOD = 0xaa; //进入安全模式
|
||||
if(mode){
|
||||
GLOBAL_CFG |= bWDOG_EN; //启动看门狗复位
|
||||
}
|
||||
else GLOBAL_CFG &= ~bWDOG_EN; //启动看门狗仅仅作为定时器
|
||||
SAFE_MOD = 0x00; //退出安全模式
|
||||
WDOG_COUNT = 0; //看门狗赋初值
|
||||
}
|
||||
|
||||
/*******************************************************************************
|
||||
* Function Name : CH554WDTFeed(UINT8 tim)
|
||||
* Description : CH554看门狗定时时间设置
|
||||
* Input : UINT8 tim 看门狗复位时间设置
|
||||
00H(6MHz)=2.8s
|
||||
80H(6MHz)=1.4s
|
||||
* Output : None
|
||||
* Return : None
|
||||
*******************************************************************************/
|
||||
void CH554WDTFeed(UINT8 tim)
|
||||
{
|
||||
WDOG_COUNT = tim; //看门狗计数器赋值
|
||||
}
|
46
examples/Public/Debug.H
Normal file
46
examples/Public/Debug.H
Normal file
@ -0,0 +1,46 @@
|
||||
/* 调试 */
|
||||
/* 提供printf子程序和延时函数 */
|
||||
|
||||
#ifndef __DEBUG_H__
|
||||
#define __DEBUG_H__
|
||||
|
||||
//定义函数返回值
|
||||
#ifndef SUCCESS
|
||||
#define SUCCESS 0
|
||||
#endif
|
||||
#ifndef FAIL
|
||||
#define FAIL 0xFF
|
||||
#endif
|
||||
|
||||
//定义定时器起始
|
||||
#ifndef START
|
||||
#define START 1
|
||||
#endif
|
||||
#ifndef STOP
|
||||
#define STOP 0
|
||||
#endif
|
||||
|
||||
#ifndef DE_PRINTF
|
||||
#define DE_PRINTF 0
|
||||
#endif
|
||||
#define FREQ_SYS 12000000 //系统主频12MHz
|
||||
#ifndef UART0_BUAD
|
||||
#define UART0_BUAD 57600
|
||||
#define UART1_BUAD 57600
|
||||
#endif
|
||||
|
||||
void CfgFsys( ); //CH554时钟选择和配置
|
||||
void mDelayuS( UINT16 n ); // 以uS为单位延时
|
||||
void mDelaymS( UINT16 n ); // 以mS为单位延时
|
||||
void CH554UART0Alter(); //CH554串口0引脚映射到P0.2/P0.3
|
||||
void mInitSTDIO( ); //T1作为波特率发生器
|
||||
UINT8 CH554UART0RcvByte( ); //CH554 UART0查询方式接收一个字节
|
||||
void CH554UART0SendByte(UINT8 SendDat); //CH554UART0发送一个字节
|
||||
|
||||
void UART1Setup( ); //
|
||||
UINT8 CH554UART1RcvByte( ); //CH554 UART1查询方式接收一个字节
|
||||
void CH554UART1SendByte(UINT8 SendDat); //CH554UART1发送一个字节
|
||||
|
||||
void CH554WDTModeSelect(UINT8 mode); //CH554看门狗模式设置
|
||||
void CH554WDTFeed(UINT8 tim); //CH554看门狗喂狗
|
||||
#endif
|
60
examples/SPI/MainMaster.C
Normal file
60
examples/SPI/MainMaster.C
Normal file
@ -0,0 +1,60 @@
|
||||
|
||||
/********************************** (C) COPYRIGHT *******************************
|
||||
* File Name : MainMaster.C
|
||||
* Author : WCH
|
||||
* Version : V1.0
|
||||
* Date : 2017/01/20
|
||||
* Description : CH554 SPI主机和CH376通讯,发送CH376测试命令,CH376取反返回
|
||||
*******************************************************************************/
|
||||
#include "..\Public\CH554.H"
|
||||
#include "..\Public\Debug.H"
|
||||
#include "SPI.H"
|
||||
#include "stdio.h"
|
||||
#include <string.h>
|
||||
|
||||
/*硬件接口定义*/
|
||||
/******************************************************************************
|
||||
使用CH554 硬件SPI接口
|
||||
CH554 DIR
|
||||
P1.4 <==> SCS
|
||||
P1.5 <==> MOSI
|
||||
P1.6 <==> MISO
|
||||
P1.7 <==> SCK
|
||||
*******************************************************************************/
|
||||
|
||||
|
||||
void main()
|
||||
{
|
||||
UINT8 ret,i=0;
|
||||
CfgFsys( );
|
||||
mDelaymS(5); //调整主频,建议稍加延时等待内部时钟稳定
|
||||
mInitSTDIO( ); //串口0初始化
|
||||
printf("start ...\n");
|
||||
|
||||
SPIMasterModeSet(3); //SPI主机模式设置,模式3
|
||||
SPI_CK_SET(2); //2分频,最快
|
||||
// #ifdef SPI0Interrupt
|
||||
// CH554SPIInterruptInit(); //SPI中断初始化
|
||||
// EA = 1; //使能全局中断
|
||||
// #endif
|
||||
while(1)
|
||||
{
|
||||
SCS = 0;
|
||||
CH554SPIMasterWrite(0x06); //CH554和CH376通讯,CH376测试命令
|
||||
mDelayuS(2); //测试命令,会收到CH376取反返回的数据
|
||||
CH554SPIMasterWrite(i);
|
||||
mDelayuS(2);
|
||||
ret = CH554SPIMasterRead(); //接收CH376返回的数据
|
||||
SCS = 1;
|
||||
if(ret != (i^0xff))
|
||||
{
|
||||
printf("Err: %02X %02X \n",(UINT16)i,(UINT16)ret); //如果不等于发送数据的取反,打印错误信息
|
||||
}
|
||||
mDelaymS(50);
|
||||
i = i+1;
|
||||
if((i%40)==0)
|
||||
{
|
||||
printf("success %02x\n",(UINT16)i); //每成功40次打印一次
|
||||
}
|
||||
}
|
||||
}
|
57
examples/SPI/MainSlave.C
Normal file
57
examples/SPI/MainSlave.C
Normal file
@ -0,0 +1,57 @@
|
||||
|
||||
/********************************** (C) COPYRIGHT *******************************
|
||||
* File Name : MainSlave.C
|
||||
* Author : WCH
|
||||
* Version : V1.0
|
||||
* Date : 2017/01/20
|
||||
* Description : CH554 SPI设备例子演示,连接SPI主机进行数据收发,主机获取设备的数据取反
|
||||
然后发送给设备
|
||||
*******************************************************************************/
|
||||
#include "..\Public\CH554.H"
|
||||
#include "..\Public\Debug.H"
|
||||
#include "SPI.H"
|
||||
#include "stdio.h"
|
||||
#include "string.h"
|
||||
|
||||
/*硬件接口定义*/
|
||||
/******************************************************************************
|
||||
使用CH554 硬件SPI接口
|
||||
CH554 DIR
|
||||
P1.4 <==> SCS
|
||||
P1.5 <==> MOSI
|
||||
P1.6 <==> MISO
|
||||
P1.7 <==> SCK
|
||||
*******************************************************************************/
|
||||
|
||||
|
||||
void main()
|
||||
{
|
||||
UINT8 ret,i=0;
|
||||
CfgFsys( );
|
||||
mDelaymS(5); //修改系统主频,建议稍加延时等待主频稳定
|
||||
|
||||
mInitSTDIO( ); //串口0初始化
|
||||
printf("start ...\n");
|
||||
|
||||
SPISlvModeSet( ); //SPI从机模式设置
|
||||
// #if SPI0Interrupt
|
||||
// CH554SPIInterruptInit(); //SPI中断初始化
|
||||
// EA = 1; //使能全局中断
|
||||
// #endif
|
||||
while(1)
|
||||
{
|
||||
CH554SPISlvWrite(i); //SPI等待主机把数据取走
|
||||
mDelayuS(2);
|
||||
ret = CH554SPISlvRead(); //读取SPI主机的数据
|
||||
if(ret != (i^0xff))
|
||||
{
|
||||
printf("Err: %02X %02X \n",(UINT16)i,(UINT16)ret); //主机取反返回,如果值错误,打印错误数据
|
||||
}
|
||||
mDelaymS(10);
|
||||
i = i+1;
|
||||
if((i%40)==0) //每成功40次打印一次
|
||||
{
|
||||
printf("success %02x\n",(UINT16)i);
|
||||
}
|
||||
}
|
||||
}
|
141
examples/SPI/SPI.C
Normal file
141
examples/SPI/SPI.C
Normal file
@ -0,0 +1,141 @@
|
||||
|
||||
/********************************** (C) COPYRIGHT *******************************
|
||||
* File Name : SPI.C
|
||||
* Author : WCH
|
||||
* Version : V1.0
|
||||
* Date : 2017/01/20
|
||||
* Description : CH554 SPI主、从模式接口函数
|
||||
注:片选有效时,从机会自动加载SPI0_S_PRE的预置值到发送移位缓冲区,所以最好可以在片选
|
||||
有效前向SPI0_S_PRE寄存器写入预发值,或者在主机端丢弃首个接收字节,发送时注意主机会先
|
||||
取走SPI0_S_PRE里面的值产生一个S0_IF_BYTE中断。
|
||||
如果片选从无效到有效,从机首先进行发送的话,最好把输出的首字节放到SPI0_S_PRE寄存器中;
|
||||
如果已经处于片选有效的话,数据数据使用SPI0_DATA就可以
|
||||
*******************************************************************************/
|
||||
|
||||
#include "..\Public\CH554.H" //调试信息打印
|
||||
#include "..\Public\Debug.H"
|
||||
#include "SPI.H"
|
||||
|
||||
#pragma NOAREGS
|
||||
|
||||
/*******************************************************************************
|
||||
* Function Name : SPIMasterModeSet( UINT8 mode )
|
||||
* Description : SPI主机模式初始化
|
||||
* Input : UINT8 mode
|
||||
* Output : None
|
||||
* Return : None
|
||||
*******************************************************************************/
|
||||
void SPIMasterModeSet(UINT8 mode)
|
||||
{
|
||||
SPI0_SETUP &= ~bS0_MODE_SLV; //Master模式
|
||||
if(mode == 0){
|
||||
SPI0_CTRL = SPI0_CTRL & ~(bS0_MST_CLK | bS0_CLR_ALL) | bS0_MOSI_OE | bS0_SCK_OE;//模式0
|
||||
}
|
||||
else if(mode == 3){
|
||||
SPI0_CTRL = SPI0_CTRL & ~bS0_CLR_ALL | bS0_MST_CLK | bS0_MOSI_OE | bS0_SCK_OE;//模式3
|
||||
}
|
||||
SPI0_CTRL &= ~bS0_MISO_OE;
|
||||
P1_MOD_OC &= 0x0F;
|
||||
P1_DIR_PU |= 0xB0; //SCS,MOSI,SCK设推挽输出
|
||||
P1_DIR_PU &= 0xBF; //MISO设浮空输入
|
||||
}
|
||||
|
||||
/*******************************************************************************
|
||||
* Function Name : CH554SPIInterruptInit()
|
||||
* Description : CH554SPI中断初始化
|
||||
* Input : None
|
||||
* Output : None
|
||||
* Return : None
|
||||
*******************************************************************************/
|
||||
void CH554SPIInterruptInit()
|
||||
{
|
||||
//IP_EX |= bIP_SPI0; //SPI0中断优先级设置
|
||||
SPI0_SETUP |= bS0_IE_FIFO_OV | bS0_IE_BYTE; //使能接收1字节中断,使能FIFO溢出中断
|
||||
SPI0_CTRL |= bS0_AUTO_IF; //自动清S0_IF_BYTE中断标志
|
||||
SPI0_STAT |= 0xff; //清空SPI0中断标志
|
||||
#ifdef SPI_Interrupt
|
||||
IE_SPI0 = 1; //使能SPI0中断
|
||||
#endif
|
||||
}
|
||||
|
||||
/*******************************************************************************
|
||||
* Function Name : CH554SPIMasterWrite(UINT8 dat)
|
||||
* Description : CH554硬件SPI写数据,主机模式
|
||||
* Input : UINT8 dat 数据
|
||||
* Output : None
|
||||
* Return : None
|
||||
*******************************************************************************/
|
||||
void CH554SPIMasterWrite(UINT8 dat)
|
||||
{
|
||||
SPI0_DATA = dat;
|
||||
while(S0_FREE == 0); //等待传输完成
|
||||
//如果bS0_DATA_DIR为1,此处可以直接读取一个字节的数据用于快速读写
|
||||
}
|
||||
|
||||
/*******************************************************************************
|
||||
* Function Name : CH554SPIMasterRead( )
|
||||
* Description : CH554硬件SPI0读数据,主机模式
|
||||
* Input : None
|
||||
* Output : None
|
||||
* Return : UINT8 ret
|
||||
*******************************************************************************/
|
||||
UINT8 CH554SPIMasterRead()
|
||||
{
|
||||
SPI0_DATA = 0xff;
|
||||
while(S0_FREE == 0);
|
||||
return SPI0_DATA;
|
||||
}
|
||||
|
||||
/*******************************************************************************
|
||||
* Function Name : SPISlvModeSet( )
|
||||
* Description : SPI从机模式初始化
|
||||
* Input : None
|
||||
* Output : None
|
||||
* Return : None
|
||||
*******************************************************************************/
|
||||
void SPISlvModeSet( )
|
||||
{
|
||||
SPI0_SETUP |= bS0_MODE_SLV; //Slv模式
|
||||
SPI0_CTRL = SPI0_CTRL & ~( bS0_CLR_ALL | bS0_MOSI_OE | bS0_MISO_OE | bS0_SCK_OE) | bS0_AUTO_IF;//读写FIFO,自动清S0_IF_BYTE标志
|
||||
P1_MOD_OC &= 0x0F;
|
||||
P1_DIR_PU &= 0x0F; //SCS,MOSI,SCK,MISO全设置浮空输入
|
||||
}
|
||||
|
||||
/*******************************************************************************
|
||||
* Function Name : CH554SPISlvWrite(UINT8 dat)
|
||||
* Description : CH554硬件SPI写数据,从机模式
|
||||
* Input : UINT8 dat 数据
|
||||
* Output : None
|
||||
* Return : None
|
||||
*******************************************************************************/
|
||||
void CH554SPISlvWrite(UINT8 dat)
|
||||
{
|
||||
while(S0_IF_BYTE);
|
||||
S0_IF_BYTE = 0;
|
||||
SPI0_DATA = dat;
|
||||
}
|
||||
|
||||
/*******************************************************************************
|
||||
* Function Name : CH554SPISlvRead( )
|
||||
* Description : CH554硬件SPI0读数据,从机模式
|
||||
* Input : None
|
||||
* Output : None
|
||||
* Return : UINT8 ret
|
||||
*******************************************************************************/
|
||||
UINT8 CH554SPISlvRead()
|
||||
{
|
||||
while(S0_IF_BYTE);
|
||||
S0_IF_BYTE = 0;
|
||||
return SPI0_DATA;
|
||||
}
|
||||
|
||||
#if SPI_Interrupt
|
||||
/*******************************************************************************
|
||||
* Function Name : ADCInterrupt(void)
|
||||
* Description : ADC 中断服务程序
|
||||
*******************************************************************************/
|
||||
void SPIInterrupt( void ) interrupt INT_NO_SPI0 using 1 //SPI中断服务程序,使用寄存器组1
|
||||
{
|
||||
}
|
||||
#endif
|
||||
|
67
examples/SPI/SPI.H
Normal file
67
examples/SPI/SPI.H
Normal file
@ -0,0 +1,67 @@
|
||||
|
||||
// #define SPI_INTERRUPT 1
|
||||
|
||||
#define SPI_CK_SET( n ) (SPI0_CK_SE = n) //SPI时钟设置函数
|
||||
|
||||
/*******************************************************************************
|
||||
* Function Name : SPIMasterModeSet( UINT8 mode )
|
||||
* Description : SPI主机模式初始化
|
||||
* Input : UINT8 mode
|
||||
* Output : None
|
||||
* Return : None
|
||||
*******************************************************************************/
|
||||
void SPIMasterModeSet(UINT8 mode);
|
||||
|
||||
/*******************************************************************************
|
||||
* Function Name : CH554SPIInterruptInit()
|
||||
* Description : CH554SPI中断初始化
|
||||
* Input : None
|
||||
* Output : None
|
||||
* Return : None
|
||||
*******************************************************************************/
|
||||
void CH554SPIInterruptInit();
|
||||
|
||||
/*******************************************************************************
|
||||
* Function Name : CH554SPIMasterWrite(UINT8 dat)
|
||||
* Description : CH554硬件SPI写数据,主机模式
|
||||
* Input : UINT8 dat 数据
|
||||
* Output : None
|
||||
* Return : None
|
||||
*******************************************************************************/
|
||||
void CH554SPIMasterWrite(UINT8 dat);
|
||||
|
||||
/*******************************************************************************
|
||||
* Function Name : CH554SPIMasterRead( )
|
||||
* Description : CH554硬件SPI0读数据,主机模式
|
||||
* Input : None
|
||||
* Output : None
|
||||
* Return : UINT8 ret
|
||||
*******************************************************************************/
|
||||
UINT8 CH554SPIMasterRead();
|
||||
|
||||
/*******************************************************************************
|
||||
* Function Name : SPISlvModeSet( )
|
||||
* Description : SPI从机模式初始化
|
||||
* Input : None
|
||||
* Output : None
|
||||
* Return : None
|
||||
*******************************************************************************/
|
||||
void SPISlvModeSet( );
|
||||
|
||||
/*******************************************************************************
|
||||
* Function Name : CH554SPISlvWrite(UINT8 dat)
|
||||
* Description : CH554硬件SPI写数据,从机模式
|
||||
* Input : UINT8 dat 数据
|
||||
* Output : None
|
||||
* Return : None
|
||||
*******************************************************************************/
|
||||
void CH554SPISlvWrite(UINT8 dat);
|
||||
|
||||
/*******************************************************************************
|
||||
* Function Name : CH554SPISlvRead( )
|
||||
* Description : CH554硬件SPI0读数据,从机模式
|
||||
* Input : None
|
||||
* Output : None
|
||||
* Return : UINT8 ret
|
||||
*******************************************************************************/
|
||||
UINT8 CH554SPISlvRead();
|
76
examples/Timer/Main.C
Normal file
76
examples/Timer/Main.C
Normal file
@ -0,0 +1,76 @@
|
||||
|
||||
/********************************** (C) COPYRIGHT *******************************
|
||||
* File Name : Main.C
|
||||
* Author : WCH
|
||||
* Version : V1.0
|
||||
* Date : 2017/01/20
|
||||
* Description : CH554 Time 初始化、定时器、计数器赋值,T2捕捉功能等
|
||||
定时器中断处理
|
||||
*******************************************************************************/
|
||||
#include "..\Public\CH554.H"
|
||||
#include "..\Public\Debug.H"
|
||||
#include "Timer.H"
|
||||
#include "stdio.h"
|
||||
|
||||
#pragma NOAREGS
|
||||
|
||||
UINT8 FLAG;
|
||||
UINT16 Cap[8] = {0};
|
||||
|
||||
main( )
|
||||
{
|
||||
CfgFsys( ); //CH554时钟选择配置
|
||||
mDelaymS(5); //修改主频,建议稍加延时等待主频稳定
|
||||
mInitSTDIO( ); //串口初始化
|
||||
printf("start ...\n");
|
||||
|
||||
|
||||
#ifdef T0_INT
|
||||
printf("T0 Test ...\n");
|
||||
mTimer0Clk12DivFsys(); //T0定时器时钟设置
|
||||
mTimer_x_ModInit(0,2); //T0 定时器模式设置
|
||||
mTimer_x_SetData(0,0x5555); //T0定时器赋值
|
||||
mTimer0RunCTL(1); //T0定时器启动
|
||||
ET0 = 1; //T0定时器中断开启
|
||||
EA = 1;
|
||||
while(1);
|
||||
#endif
|
||||
|
||||
#ifdef T1_INT
|
||||
printf("T1 Test ...\n");
|
||||
mTimer1Clk12DivFsys(); //T1定时器时钟设置
|
||||
mTimer_x_ModInit(1,2); //T1 定时器模式设置
|
||||
mTimer_x_SetData(1,0xEEEE); //T1定时器赋值
|
||||
mTimer1RunCTL(1); //T1定时器启动
|
||||
ET1 = 1; //T1定时器中断开启
|
||||
EA = 1;
|
||||
while(1);
|
||||
#endif
|
||||
|
||||
|
||||
#ifdef T2_INT
|
||||
printf("T2 Test ...\n");
|
||||
mTimer2ClkFsys(); //T2定时器时钟设置
|
||||
mTimer_x_ModInit(2,0); //T2 定时器模式设置
|
||||
mTimer_x_SetData(2,0xAAAA); //T2定时器赋值
|
||||
mTimer2RunCTL(1); //T2定时器启动
|
||||
ET2 = 1; //T2定时器中断开启
|
||||
EA = 1;
|
||||
while(1);
|
||||
#endif
|
||||
|
||||
|
||||
#ifdef T2_CAP
|
||||
printf("T2_CAP Test ...\n");
|
||||
mTimer2ClkFsys(); //T2定时器时钟设置
|
||||
mTimer_x_SetData(2,0); //T2 定时器模式设置捕捉模式
|
||||
CAP2Init(1); //T2 CAP2设置,任意沿捕捉
|
||||
CAP1Init(1); //T2 CAP2设置,任意沿捕捉
|
||||
mTimer2RunCTL(1); //T2定时器启动
|
||||
ET2 = 1; //T2定时器中断开启
|
||||
EA = 1;
|
||||
while(1);
|
||||
#endif
|
||||
|
||||
while(1);
|
||||
}
|
153
examples/Timer/Timer.C
Normal file
153
examples/Timer/Timer.C
Normal file
@ -0,0 +1,153 @@
|
||||
|
||||
/********************************** (C) COPYRIGHT *******************************
|
||||
* File Name : Timer.C
|
||||
* Author : WCH
|
||||
* Version : V1.0
|
||||
* Date : 2017/01/20
|
||||
* Description : CH554 Time 初始化、定时器、计数器赋值、T2捕捉功能开启函数等
|
||||
定时器中断函数
|
||||
*******************************************************************************/
|
||||
#include "..\Public\CH554.H"
|
||||
#include "..\Public\Debug.H"
|
||||
#include "Timer.H"
|
||||
#include "stdio.h"
|
||||
|
||||
#pragma NOAREGS
|
||||
|
||||
/*******************************************************************************
|
||||
* Function Name : mTimer_x_ModInit(UINT8 x ,UINT8 mode)
|
||||
* Description : CH554定时计数器x模式设置
|
||||
* Input : UINT8 mode,Timer模式选择
|
||||
0:模式0,13位定时器,TLn的高3位无效
|
||||
1:模式1,16位定时器
|
||||
2:模式2,8位自动重装定时器
|
||||
3:模式3,两个8位定时器 Timer0
|
||||
3:模式3,Timer1停止
|
||||
* Output : None
|
||||
* Return : 成功 SUCCESS
|
||||
失败 FAIL
|
||||
*******************************************************************************/
|
||||
UINT8 mTimer_x_ModInit(UINT8 x ,UINT8 mode)
|
||||
{
|
||||
if(x == 0){TMOD = TMOD & 0xf0 | mode;}
|
||||
else if(x == 1){TMOD = TMOD & 0x0f | (mode<<4);}
|
||||
else if(x == 2){RCLK = 0;TCLK = 0;CP_RL2 = 0;} //16位自动重载定时器
|
||||
else return FAIL;
|
||||
return SUCCESS;
|
||||
}
|
||||
|
||||
/*******************************************************************************
|
||||
* Function Name : mTimer_x_SetData(UINT8 x,UINT16 dat)
|
||||
* Description : CH554Timer0 TH0和TL0赋值
|
||||
* Input : UINT16 dat;定时器赋值
|
||||
* Output : None
|
||||
* Return : None
|
||||
*******************************************************************************/
|
||||
void mTimer_x_SetData(UINT8 x,UINT16 dat)
|
||||
{
|
||||
UINT16 tmp;
|
||||
tmp = 65536 - dat;
|
||||
if(x == 0){TL0 = tmp & 0xff;TH0 = (tmp>>8) & 0xff;}
|
||||
else if(x == 1){TL1 = tmp & 0xff;TH1 = (tmp>>8) & 0xff;}
|
||||
else if(x == 2){
|
||||
RCAP2L = TL2 = tmp & 0xff; //16位自动重载定时器
|
||||
RCAP2H = TH2 = (tmp>>8) & 0xff;
|
||||
}
|
||||
}
|
||||
|
||||
/*******************************************************************************
|
||||
* Function Name : CAP2Init(UINT8 mode)
|
||||
* Description : CH554定时计数器2 T2EX引脚捕捉功能初始化
|
||||
UINT8 mode,边沿捕捉模式选择
|
||||
0:T2ex从下降沿到下一个下降沿
|
||||
1:T2ex任意边沿之间
|
||||
3:T2ex从上升沿到下一个上升沿
|
||||
* Input : None
|
||||
* Output : None
|
||||
* Return : None
|
||||
*******************************************************************************/
|
||||
void CAP2Init(UINT8 mode)
|
||||
{
|
||||
RCLK = 0;
|
||||
TCLK = 0;
|
||||
C_T2 = 0;
|
||||
EXEN2 = 1;
|
||||
CP_RL2 = 1; //启动T2ex的捕捉功能
|
||||
T2MOD |= mode << 2; //边沿捕捉模式选择
|
||||
}
|
||||
|
||||
/*******************************************************************************
|
||||
* Function Name : CAP1Init(UINT8 mode)
|
||||
* Description : CH554定时计数器2 T2引脚捕捉功能初始化T2
|
||||
UINT8 mode,边沿捕捉模式选择
|
||||
0:T2ex从下降沿到下一个下降沿
|
||||
1:T2ex任意边沿之间
|
||||
3:T2ex从上升沿到下一个上升沿
|
||||
* Input : None
|
||||
* Output : None
|
||||
* Return : None
|
||||
*******************************************************************************/
|
||||
void CAP1Init(UINT8 mode)
|
||||
{
|
||||
RCLK = 0;
|
||||
TCLK = 0;
|
||||
CP_RL2 = 1;
|
||||
C_T2 = 0;
|
||||
T2MOD = T2MOD & ~T2OE | (mode << 2) | bT2_CAP1_EN; //使能T2引脚捕捉功能,边沿捕捉模式选择
|
||||
}
|
||||
|
||||
#ifdef T0_INT
|
||||
/*******************************************************************************
|
||||
* Function Name : mTimer0Interrupt()
|
||||
* Description : CH554定时计数器0定时计数器中断处理函数
|
||||
*******************************************************************************/
|
||||
void mTimer0Interrupt( void ) interrupt INT_NO_TMR0 using 1 //timer0中断服务程序,使用寄存器组1
|
||||
{ //方式3时,TH0使用Timer1的中断资源
|
||||
SCK = ~SCK;
|
||||
// mTimer_x_SetData(0,0x0000); //非自动重载方式需重新给TH0和TL0赋值
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef T1_INT
|
||||
/*******************************************************************************
|
||||
* Function Name : mTimer1Interrupt()
|
||||
* Description : CH554定时计数器0定时计数器中断处理函数
|
||||
*******************************************************************************/
|
||||
void mTimer1Interrupt( void ) interrupt INT_NO_TMR1 using 2 //timer1中断服务程序,使用寄存器组2
|
||||
{ //方式3时,Timer1停止
|
||||
SCK = ~SCK;
|
||||
// mTimer_x_SetData(1,0x0000); //非自动重载方式需重新给TH1和TL1赋值
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef T2_INT
|
||||
/*******************************************************************************
|
||||
* Function Name : mTimer2Interrupt()
|
||||
* Description : CH554定时计数器0定时计数器中断处理函数
|
||||
*******************************************************************************/
|
||||
void mTimer2Interrupt( void ) interrupt INT_NO_TMR2 using 3 //timer2中断服务程序,使用寄存器组3
|
||||
{
|
||||
mTimer2RunCTL( 0 ); //关定时器
|
||||
#ifdef T2_CAP
|
||||
if(EXF2) //T2ex电平变化中断中断标志
|
||||
{
|
||||
SCK = ~SCK; //P17电平指示监控
|
||||
Cap[FLAG++] = RCAP2; //T2EX
|
||||
printf("RCAP2 %04x \n",RCAP2);
|
||||
EXF2 = 0; //清空T2ex捕捉中断标志
|
||||
}
|
||||
if(CAP1F) //T2电平捕捉中断标志
|
||||
{
|
||||
Cap[FLAG++] = T2CAP1; //T2;
|
||||
printf("T2CAP1 %04x \n",T2CAP1);
|
||||
CAP1F = 0; //清空T2捕捉中断标志
|
||||
}
|
||||
#endif
|
||||
if(TF2)
|
||||
{
|
||||
TF2 = 0; //清空定时器2溢出中断
|
||||
SCK = ~SCK; //P17电平指示监控
|
||||
}
|
||||
mTimer2RunCTL( 1 ); //开定时器
|
||||
}
|
||||
#endif
|
92
examples/Timer/Timer.H
Normal file
92
examples/Timer/Timer.H
Normal file
@ -0,0 +1,92 @@
|
||||
|
||||
|
||||
// #define T0_INT 1 //T中断开启
|
||||
#define T1_INT 1
|
||||
// #define T2_INT 1
|
||||
// #define T2_CAP 1
|
||||
|
||||
extern UINT8 FLAG;
|
||||
extern UINT16 Cap[8];
|
||||
|
||||
//CH554 Timer0时钟选择
|
||||
//bTMR_CLK同时影响Timer0&1&2,使用时要注意 (除定时使用标准时钟)
|
||||
#define mTimer0Clk12DivFsys( ) (T2MOD &= ~bT0_CLK) //定时器,时钟=Fsys/12 T0标准时钟
|
||||
#define mTimer0ClkFsys( ) (T2MOD |= bTMR_CLK | bT0_CLK) //定时器,时钟=Fsys
|
||||
#define mTimer0Clk4DivFsys( ) (T2MOD &= ~bTMR_CLK;T2MOD |= bT0_CLK) //定时器,时钟=Fsys/4
|
||||
#define mTimer0CountClk( ) (TMOD |= bT0_CT) //计数器,T0引脚的下降沿有效
|
||||
|
||||
//CH554 Timer0 开始(SS=1)/结束(SS=0)
|
||||
#define mTimer0RunCTL( SS ) (TR0 = SS ? START : STOP)
|
||||
|
||||
|
||||
#define mTimer1Clk12DivFsys( ) (T2MOD &= ~bT1_CLK) //定时器,时钟=Fsys/12 T1标准时钟
|
||||
#define mTimer1ClkFsys( ) (T2MOD |= bTMR_CLK | bT1_CLK) //定时器,时钟=Fsys
|
||||
#define mTimer1Clk4DivFsys( ) (T2MOD &= ~bTMR_CLK;T2MOD |= bT1_CLK) //定时器,时钟=Fsys/4
|
||||
#define mTimer1CountClk( ) (TMOD |= bT1_CT) //计数器,T0引脚的下降沿有效
|
||||
|
||||
//CH554 Timer1 开始(SS=1)/结束(SS=0)
|
||||
#define mTimer1RunCTL( SS ) (TR1 = SS ? START : STOP)
|
||||
|
||||
|
||||
#define mTimer2Clk12DivFsys( ) {T2MOD &= ~(bTMR_CLK | bT2_CLK);C_T2 = 0;} //定时器,时钟=Fsys/12 T2标准时钟
|
||||
#define mTimer2ClkFsys( ) {T2MOD |= (bTMR_CLK | bT2_CLK);C_T2=0;} //定时器,时钟=Fsys
|
||||
#define mTimer2Clk4DivFsys( ) {T2MOD &= ~bTMR_CLK;T2MOD |= bT2_CLK;C_T2 = 0;}//定时器,时钟=Fsys/4
|
||||
#define mTimer2CountClk( ) {C_T2 = 1;} //计数器,T2引脚的下降沿有效
|
||||
|
||||
//CH554 Timer2 开始(SS=1)/结束(SS=0)
|
||||
#define mTimer2RunCTL( SS ) {TR2 = SS ? START : STOP;}
|
||||
#define mTimer2OutCTL( ) (T2MOD |= T2OE) //T2输出 频率TF2/2
|
||||
#define CAP1Alter( ) (PIN_FUNC |= bT2_PIN_X;) //CAP1由P10 映射到P14
|
||||
#define CAP2Alter( ) (PIN_FUNC |= bT2EX_PIN_X;) //CAP2由P11 映射RST
|
||||
|
||||
/*******************************************************************************
|
||||
* Function Name : mTimer_x_ModInit(UINT8 x ,UINT8 mode)
|
||||
* Description : CH554定时计数器x模式设置
|
||||
* Input : UINT8 mode,Timer模式选择
|
||||
0:模式0,13位定时器,TLn的高3位无效
|
||||
1:模式1,16位定时器
|
||||
2:模式2,8位自动重装定时器
|
||||
3:模式3,两个8位定时器 Timer0
|
||||
3:模式3,Timer1停止
|
||||
UINT8 x 定时器 0 1 2
|
||||
* Output : None
|
||||
* Return : 成功 SUCCESS
|
||||
失败 FAIL
|
||||
*******************************************************************************/
|
||||
UINT8 mTimer_x_ModInit(UINT8 x ,UINT8 mode);
|
||||
|
||||
/*******************************************************************************
|
||||
* Function Name : mTimer_x_SetData(UINT8 x,UINT16 dat)
|
||||
* Description : CH554Timer
|
||||
* Input : UINT16 dat;定时器赋值
|
||||
UINT8 x 定时器 0 1 2
|
||||
* Output : None
|
||||
* Return : None
|
||||
*******************************************************************************/
|
||||
void mTimer_x_SetData(UINT8 x,UINT16 dat);
|
||||
|
||||
/*******************************************************************************
|
||||
* Function Name : CAP2Init(UINT8 mode)
|
||||
* Description : CH554定时计数器2 T2EX引脚捕捉功能初始化
|
||||
UINT8 mode,边沿捕捉模式选择
|
||||
0:T2ex从下降沿到下一个下降沿
|
||||
1:T2ex任意边沿之间
|
||||
3:T2ex从上升沿到下一个上升沿
|
||||
* Input : None
|
||||
* Output : None
|
||||
* Return : None
|
||||
*******************************************************************************/
|
||||
void CAP2Init(UINT8 mode);
|
||||
|
||||
/*******************************************************************************
|
||||
* Function Name : CAP1Init(UINT8 mode)
|
||||
* Description : CH554定时计数器2 T2引脚捕捉功能初始化T2
|
||||
UINT8 mode,边沿捕捉模式选择
|
||||
0:T2ex从下降沿到下一个下降沿
|
||||
1:T2ex任意边沿之间
|
||||
3:T2ex从上升沿到下一个上升沿
|
||||
* Input : None
|
||||
* Output : None
|
||||
* Return : None
|
||||
*******************************************************************************/
|
||||
void CAP1Init(UINT8 mode);
|
59
examples/TouchKey/Main.C
Normal file
59
examples/TouchKey/Main.C
Normal file
@ -0,0 +1,59 @@
|
||||
|
||||
/********************************** (C) COPYRIGHT *******************************
|
||||
* File Name : Main.C
|
||||
* Author : WCH
|
||||
* Version : V1.0
|
||||
* Date : 2017/01/20
|
||||
* Description : CH554 触摸按键中断和查询方式进行采集并报告当前采样通道按键状态,包含初始化和按键采样等演示函数
|
||||
*******************************************************************************/
|
||||
#include "..\Public\CH554.H"
|
||||
#include "..\Public\Debug.H"
|
||||
#include "TouchKey.H"
|
||||
#include "stdio.h"
|
||||
|
||||
#pragma NOAREGS
|
||||
|
||||
main( )
|
||||
{
|
||||
UINT8 i;
|
||||
CfgFsys( ); //CH554时钟选择配置
|
||||
mDelaymS(5); //修改主频建议稍加延时等待芯片供电稳定
|
||||
mInitSTDIO( ); //串口0初始化
|
||||
printf("start ...\n");
|
||||
|
||||
P1_DIR_PU &= 0x0C; //所有触摸通道设置为浮空输入,用不到的通道可以不设置
|
||||
TouchKeyQueryCyl2ms(); //TouchKey查询周期2ms
|
||||
GetTouckKeyFreeBuf(); //获取采样基准值
|
||||
#if DE_PRINTF
|
||||
for(i=KEY_FIRST;i<(KEY_LAST+1);i++) //打印采样基准值
|
||||
{
|
||||
printf("Channel %02x base sample %04x\n",(UINT16)i,KeyFree[i]);
|
||||
}
|
||||
#endif
|
||||
|
||||
#if INTERRUPT_TouchKey
|
||||
EA = 1;
|
||||
while(1)
|
||||
{
|
||||
if(KeyBuf) //key_buf非0,表示检测到按键按下
|
||||
{
|
||||
printf("INT TouchKey Channel %02x \n",(UINT16)KeyBuf); //打印当前按键状态通道
|
||||
KeyBuf = 0; //清除按键按下标志
|
||||
mDelaymS(100); //延时无意义,模拟单片机做按键处理
|
||||
}
|
||||
mDelaymS(100); //延时无意义,模拟单片机干其他事
|
||||
}
|
||||
#else
|
||||
while(1)
|
||||
{
|
||||
TouchKeyChannelQuery(); //查询触摸按键状态
|
||||
if(KeyBuf) //key_buf非0,表示检测到按键按下
|
||||
{
|
||||
printf("Query TouchKey Channel %02x \n",(UINT16)KeyBuf); //打印当前按键状态通道
|
||||
KeyBuf = 0; //清除按键按下标志
|
||||
mDelaymS(100); //延时无意义,模拟单片机做按键处理
|
||||
}
|
||||
mDelaymS(100); //延时无意义,模拟单片机干其他事
|
||||
}
|
||||
#endif
|
||||
}
|
120
examples/TouchKey/TouchKey.C
Normal file
120
examples/TouchKey/TouchKey.C
Normal file
@ -0,0 +1,120 @@
|
||||
|
||||
/********************************** (C) COPYRIGHT *******************************
|
||||
* File Name : TouchKey.C
|
||||
* Author : WCH
|
||||
* Version : V1.0
|
||||
* Date : 2017/01/20
|
||||
* Description : CH554 触摸按键采样间隔设置、通道选择和切换和中断处理函数
|
||||
*******************************************************************************/
|
||||
|
||||
#include "..\Public\CH554.H"
|
||||
#include "..\Public\Debug.H"
|
||||
#include "TouchKey.H"
|
||||
#include "stdio.h"
|
||||
|
||||
#pragma NOAREGS
|
||||
|
||||
UINT16 KeyFree[KEY_LAST-KEY_FIRST+1]; //触摸空闲值存储,用于比较按键状态,如果采样值小于基准值表明按键按下
|
||||
UINT8V KeyBuf; //触摸按键状态,为0表示无按键,非0表示当前检测按键被按下
|
||||
|
||||
/*******************************************************************************
|
||||
* Function Name : GetTouckKeyFreeBuf()
|
||||
* Description : 获取触摸按键空间状态键值
|
||||
* Input : None
|
||||
* Output : None
|
||||
* Return : None
|
||||
*******************************************************************************/
|
||||
void GetTouckKeyFreeBuf()
|
||||
{
|
||||
UINT8 i,j;
|
||||
UINT8 TmpSum = 0;
|
||||
KeyBuf = 0; //初始化设置为无按键状态
|
||||
for(i=KEY_FIRST;i<(KEY_LAST+1);i++)
|
||||
{
|
||||
j = KEY_BASE_SAMPLE_TIME; //采多次求平均值作为采样参考
|
||||
TKEY_CTRL = (TKEY_CTRL & 0xF8 | i)+1; //设置采样通道
|
||||
while(j--)
|
||||
{
|
||||
while((TKEY_CTRL&bTKC_IF) == 0); //bTKC_IF变为1时,本周期采样完成
|
||||
TmpSum += TKEY_DAT&0x0F; //采样值稳定,取低4位就够了
|
||||
}
|
||||
KeyFree[i] = TKEY_DAT&0x07F0 + TmpSum/5; //保存采样值
|
||||
}
|
||||
#if INTERRUPT_TouchKey
|
||||
IE_TKEY = 1; //使能Touch_Key中断
|
||||
#endif
|
||||
}
|
||||
|
||||
/*******************************************************************************
|
||||
* Function Name : TouchKeyChannelSelect(UINT8 ch)
|
||||
* Description : 触摸按键通道选择
|
||||
* Input : UINT8 ch 采用通道
|
||||
0~5 分别代表采样通道
|
||||
* Output : None
|
||||
* Return : 成功 SUCCESS
|
||||
失败 FAIL 不支持的通道
|
||||
*******************************************************************************/
|
||||
UINT8 TouchKeyChannelSelect(UINT8 ch)
|
||||
{
|
||||
if(ch < 6)
|
||||
{
|
||||
TKEY_CTRL = (TKEY_CTRL & 0xF8 | ch)+1;
|
||||
return SUCCESS;
|
||||
}
|
||||
return FAIL;
|
||||
}
|
||||
|
||||
#if INTERRUPT_TouchKey
|
||||
/*******************************************************************************
|
||||
* Function Name : TouchKeyInterrupt(void)
|
||||
* Description : Touch_Key 中断服务程序
|
||||
*******************************************************************************/
|
||||
void TouchKeyInterrupt( void ) interrupt INT_NO_TKEY using 1 //Touch_Key中断服务程序,使用寄存器组1
|
||||
{
|
||||
UINT8 ch;
|
||||
UINT16 KeyData;
|
||||
|
||||
KeyData = TKEY_DAT; //保持87us,尽快取走
|
||||
ch = TKEY_CTRL&7; //获取当前采样通道
|
||||
if ( ch > KEY_LAST ){
|
||||
TKEY_CTRL = TKEY_CTRL & 0xF8 | KEY_FIRST; //从首通道开始采样
|
||||
}
|
||||
else
|
||||
{
|
||||
TKEY_CTRL ++; //切换至下一个采样通道
|
||||
}
|
||||
if ( KeyData < (KeyFree[ch-KEY_FIRST] - KEY_ACT) ) //如条件满足,代表按键按下
|
||||
{
|
||||
KeyBuf=ch; //可以在此处进行按键动作处理或者置标志通知main进行处理
|
||||
}
|
||||
}
|
||||
#else
|
||||
/*******************************************************************************
|
||||
* Function Name : TouchKeyChannelQuery()
|
||||
* Description : 触摸按键通道状态查询
|
||||
* Input : None
|
||||
* Output : None
|
||||
* Return : None
|
||||
*******************************************************************************/
|
||||
void TouchKeyChannelQuery()
|
||||
{
|
||||
UINT8 ch;
|
||||
UINT16 KeyData;
|
||||
|
||||
while((TKEY_CTRL&bTKC_IF) == 0); //bTKC_IF变为1时,本周期采样完成
|
||||
KeyData = TKEY_DAT; //保持87us,尽快取走
|
||||
ch = TKEY_CTRL&7; //获取当前采样通道
|
||||
if ( ch > KEY_LAST ){
|
||||
TKEY_CTRL = TKEY_CTRL & 0xF8 | KEY_FIRST; //从首通道开始采样
|
||||
}
|
||||
else
|
||||
{
|
||||
TKEY_CTRL ++; //切换至下一个采样通道
|
||||
}
|
||||
if ( KeyData < (KeyFree[ch-KEY_FIRST] - KEY_ACT) ) //如条件满足,代表按键按下
|
||||
{
|
||||
KeyBuf=ch; //可以在此处进行按键动作处理或者置标志通知main进行处理
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
49
examples/TouchKey/TouchKey.H
Normal file
49
examples/TouchKey/TouchKey.H
Normal file
@ -0,0 +1,49 @@
|
||||
|
||||
#define INTERRUPT_TouchKey 0 //开启TouchKey中断方式
|
||||
|
||||
#define KEY_FIRST 0 //采样起始通道
|
||||
#define KEY_LAST 3 //采样结束通道
|
||||
#define KEY_ACT 20 //按键按下,通道采样值减小,该值减小,灵敏度高,该值增大,灵敏度低
|
||||
#define KEY_BASE_SAMPLE_TIME 5 //采样基准值采样次数,为了取到稳定的通道基准值
|
||||
|
||||
extern UINT16 KeyFree[KEY_LAST-KEY_FIRST+1]; //触摸空闲值存储,用于比较按键状态,如果采样值小于基准值表明按键按下
|
||||
extern UINT8V KeyBuf; //触摸按键状态,为0表示无按键,为1表示当前检测按键被按下
|
||||
|
||||
#define TouchKeyOFF() {TKEY_CTRL &= 0xF8;} //关闭电容检测,仅作1ms或者2ms定时中断
|
||||
#define TouchKeyON_NoChannel() {TKEY_CTRL = TKEY_CTRL & 0xF8 | 7;} //开启电容检测,但是不连接通道
|
||||
#define TouchKeyQueryCyl1ms() {TKEY_CTRL &= ~bTKC_2MS;} //触摸按键采样周期设置1ms
|
||||
#define TouchKeyQueryCyl2ms() {TKEY_CTRL |= bTKC_2MS;} //触摸按键采样周期设置2ms
|
||||
|
||||
/*******************************************************************************
|
||||
* Function Name : TouchKeyChannelSelect(UINT8 ch)
|
||||
* Description : 触摸按键通道选择
|
||||
* Input : UINT8 ch 采用通道
|
||||
0: 关闭电容检测,仅作1ms或者2ms定时中断
|
||||
1~6 分别代表采样通道
|
||||
7: 开启电容检测,但是不连接通道
|
||||
* Output : None
|
||||
* Return : 成功 SUCCESS
|
||||
失败 FAIL
|
||||
*******************************************************************************/
|
||||
UINT8 TouchKeyChannelSelect(UINT8 ch);
|
||||
|
||||
/*******************************************************************************
|
||||
* Function Name : GetTouckKeyFreeBuf()
|
||||
* Description : 获取触摸按键空间状态键值
|
||||
* Input : None
|
||||
* Output : None
|
||||
* Return : None
|
||||
*******************************************************************************/
|
||||
void GetTouckKeyFreeBuf();
|
||||
|
||||
#if !INTERRUPT_TouchKey
|
||||
/*******************************************************************************
|
||||
* Function Name : TouchKeyChannelQuery()
|
||||
* Description : 触摸按键通道状态查询
|
||||
* Input : None
|
||||
* Output : None
|
||||
* Return : None
|
||||
*******************************************************************************/
|
||||
void TouchKeyChannelQuery();
|
||||
#endif
|
||||
|
450
examples/USB/Device/CompatibilityHID.C
Normal file
450
examples/USB/Device/CompatibilityHID.C
Normal file
@ -0,0 +1,450 @@
|
||||
|
||||
/********************************** (C) COPYRIGHT *******************************
|
||||
* File Name :CompatibilityHID.C
|
||||
* Author : WCH
|
||||
* Version : V1.0
|
||||
* Date : 2017/01/20
|
||||
* Description : CH554模拟HID兼容设备,支持中断上下传,支持设置全速,低速
|
||||
*******************************************************************************/
|
||||
|
||||
#include "./Public/CH554.H"
|
||||
#include "./Public/Debug.H"
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
|
||||
#define Fullspeed 1
|
||||
#ifdef Fullspeed
|
||||
#define THIS_ENDP0_SIZE 64
|
||||
#else
|
||||
#define THIS_ENDP0_SIZE DEFAULT_ENDP0_SIZE
|
||||
#endif
|
||||
UINT8X Ep0Buffer[8<(THIS_ENDP0_SIZE+2)?8:(THIS_ENDP0_SIZE+2)] _at_ 0x0000; //端点0 OUT&IN缓冲区,必须是偶地址
|
||||
UINT8X Ep2Buffer[128<(2*MAX_PACKET_SIZE+4)?128:(2*MAX_PACKET_SIZE+4)] _at_ 0x0044;//端点2 IN&OUT缓冲区,必须是偶地址
|
||||
UINT8 SetupReq,SetupLen,Ready,Count,FLAG,UsbConfig;
|
||||
PUINT8 pDescr; //USB配置标志
|
||||
USB_SETUP_REQ SetupReqBuf; //暂存Setup包
|
||||
#define UsbSetupBuf ((PUSB_SETUP_REQ)Ep0Buffer)
|
||||
|
||||
sbit Ep2InKey = P1^5; //K1按键
|
||||
#pragma NOAREGS
|
||||
/*设备描述符*/
|
||||
UINT8C DevDesc[18] = {0x12,0x01,0x10,0x01,0x00,0x00,0x00,THIS_ENDP0_SIZE,
|
||||
0x31,0x51,0x07,0x20,0x00,0x00,0x00,0x00,
|
||||
0x00,0x01
|
||||
};
|
||||
UINT8C CfgDesc[41] =
|
||||
{
|
||||
0x09,0x02,0x29,0x00,0x01,0x01,0x04,0xA0,0x23, //配置描述符
|
||||
0x09,0x04,0x00,0x00,0x02,0x03,0x00,0x00,0x05, //接口描述符
|
||||
0x09,0x21,0x00,0x01,0x00,0x01,0x22,0x22,0x00, //HID类描述符
|
||||
0x07,0x05,0x82,0x03,THIS_ENDP0_SIZE,0x00,0x18, //端点描述符
|
||||
0x07,0x05,0x02,0x03,THIS_ENDP0_SIZE,0x00,0x18, //端点描述符
|
||||
};
|
||||
/*字符串描述符 略*/
|
||||
|
||||
/*HID类报表描述符*/
|
||||
UINT8C HIDRepDesc[ ] =
|
||||
{
|
||||
0x06, 0x00,0xff,
|
||||
0x09, 0x01,
|
||||
0xa1, 0x01, //集合开始
|
||||
0x09, 0x02, //Usage Page 用法
|
||||
0x15, 0x00, //Logical Minimun
|
||||
0x26, 0x00,0xff, //Logical Maximun
|
||||
0x75, 0x08, //Report Size
|
||||
0x95, THIS_ENDP0_SIZE, //Report Counet
|
||||
0x81, 0x06, //Input
|
||||
0x09, 0x02, //Usage Page 用法
|
||||
0x15, 0x00, //Logical Minimun
|
||||
0x26, 0x00,0xff, //Logical Maximun
|
||||
0x75, 0x08, //Report Size
|
||||
0x95, THIS_ENDP0_SIZE, //Report Counet
|
||||
0x91, 0x06, //Output
|
||||
0xC0
|
||||
};
|
||||
// unsigned char code LangDes[]={0x04,0x03,0x09,0x04}; //语言描述符
|
||||
// unsigned char code SerDes[]={
|
||||
// 0x28,0x03,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
|
||||
// 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
|
||||
// 0x00,0x00,0x00,0x00,0x00,0x49,0x00,0x43,0x00,0x42,
|
||||
// 0x00,0x43,0x00,0x31,0x00,0x00,0x00,0x00,0x00,0x00
|
||||
// }; //字符串描述符
|
||||
|
||||
UINT8X UserEp2Buf[64]; //用户数据定义
|
||||
|
||||
/*******************************************************************************
|
||||
* Function Name : USBDeviceInit()
|
||||
* Description : USB设备模式配置,设备模式启动,收发端点配置,中断开启
|
||||
* Input : None
|
||||
* Output : None
|
||||
* Return : None
|
||||
*******************************************************************************/
|
||||
void USBDeviceInit()
|
||||
{
|
||||
IE_USB = 0;
|
||||
USB_CTRL = 0x00; // 先设定USB设备模式
|
||||
#ifndef Fullspeed
|
||||
UDEV_CTRL |= bUD_LOW_SPEED; //选择低速1.5M模式
|
||||
#else
|
||||
UDEV_CTRL &= ~bUD_LOW_SPEED; //选择全速12M模式,默认方式
|
||||
#endif
|
||||
UEP2_DMA = Ep2Buffer; //端点2数据传输地址
|
||||
UEP2_3_MOD |= bUEP2_TX_EN; //端点2发送使能
|
||||
UEP2_3_MOD |= bUEP2_RX_EN; //端点2接收使能
|
||||
UEP2_3_MOD &= ~bUEP2_BUF_MOD; //端点2收发各64字节缓冲区
|
||||
UEP2_CTRL = bUEP_AUTO_TOG | UEP_T_RES_NAK | UEP_R_RES_ACK; //端点2自动翻转同步标志位,IN事务返回NAK,OUT返回ACK
|
||||
UEP0_DMA = Ep0Buffer; //端点0数据传输地址
|
||||
UEP4_1_MOD &= ~(bUEP4_RX_EN | bUEP4_TX_EN); //端点0单64字节收发缓冲区
|
||||
UEP0_CTRL = UEP_R_RES_ACK | UEP_T_RES_NAK; //OUT事务返回ACK,IN事务返回NAK
|
||||
|
||||
USB_DEV_AD = 0x00;
|
||||
UDEV_CTRL = bUD_PD_DIS; // 禁止DP/DM下拉电阻
|
||||
USB_CTRL = bUC_DEV_PU_EN | bUC_INT_BUSY | bUC_DMA_EN; // 启动USB设备及DMA,在中断期间中断标志未清除前自动返回NAK
|
||||
UDEV_CTRL |= bUD_PORT_EN; // 允许USB端口
|
||||
USB_INT_FG = 0xFF; // 清中断标志
|
||||
USB_INT_EN = bUIE_SUSPEND | bUIE_TRANSFER | bUIE_BUS_RST;
|
||||
IE_USB = 1;
|
||||
}
|
||||
|
||||
/*******************************************************************************
|
||||
* Function Name : Enp2BlukIn()
|
||||
* Description : USB设备模式端点2的批量上传
|
||||
* Input : None
|
||||
* Output : None
|
||||
* Return : None
|
||||
*******************************************************************************/
|
||||
void Enp2BlukIn( )
|
||||
{
|
||||
memcpy( Ep2Buffer+MAX_PACKET_SIZE, UserEp2Buf, sizeof(UserEp2Buf)); //加载上传数据
|
||||
UEP2_T_LEN = THIS_ENDP0_SIZE; //上传最大包长度
|
||||
UEP2_CTRL = UEP2_CTRL & ~ MASK_UEP_T_RES | UEP_T_RES_ACK; //有数据时上传数据并应答ACK
|
||||
while(UEP2_CTRL&UEP_T_RES_ACK); //等待传输完成
|
||||
}
|
||||
|
||||
/*******************************************************************************
|
||||
* Function Name : DeviceInterrupt()
|
||||
* Description : CH559USB中断处理函数
|
||||
*******************************************************************************/
|
||||
void DeviceInterrupt( void ) interrupt INT_NO_USB using 1 //USB中断服务程序,使用寄存器组1
|
||||
{
|
||||
UINT8 len,i;
|
||||
if(UIF_TRANSFER) //USB传输完成标志
|
||||
{
|
||||
switch (USB_INT_ST & (MASK_UIS_TOKEN | MASK_UIS_ENDP))
|
||||
{
|
||||
case UIS_TOKEN_IN | 2: //endpoint 2# 端点批量上传
|
||||
UEP2_T_LEN = 0; //预使用发送长度一定要清空
|
||||
// UEP1_CTRL ^= bUEP_T_TOG; //如果不设置自动翻转则需要手动翻转
|
||||
UEP2_CTRL = UEP2_CTRL & ~ MASK_UEP_T_RES | UEP_T_RES_NAK; //默认应答NAK
|
||||
break;
|
||||
case UIS_TOKEN_OUT | 2: //endpoint 2# 端点批量下传
|
||||
if ( U_TOG_OK ) // 不同步的数据包将丢弃
|
||||
{
|
||||
len = USB_RX_LEN; //接收数据长度,数据从Ep2Buffer首地址开始存放
|
||||
for ( i = 0; i < len; i ++ )
|
||||
{
|
||||
Ep2Buffer[MAX_PACKET_SIZE+i] = Ep2Buffer[i] ^ 0xFF; // OUT数据取反到IN由计算机验证
|
||||
}
|
||||
UEP2_T_LEN = len;
|
||||
UEP2_CTRL = UEP2_CTRL & ~ MASK_UEP_T_RES | UEP_T_RES_ACK; // 允许上传
|
||||
}
|
||||
break;
|
||||
case UIS_TOKEN_SETUP | 0: //SETUP事务
|
||||
len = USB_RX_LEN;
|
||||
if(len == (sizeof(USB_SETUP_REQ)))
|
||||
{
|
||||
SetupLen = UsbSetupBuf->wLengthL;
|
||||
if(UsbSetupBuf->wLengthH || SetupLen > 0x7F )
|
||||
{
|
||||
SetupLen = 0x7F; // 限制总长度
|
||||
}
|
||||
len = 0; // 默认为成功并且上传0长度
|
||||
SetupReq = UsbSetupBuf->bRequest;
|
||||
if ( ( UsbSetupBuf->bRequestType & USB_REQ_TYP_MASK ) != USB_REQ_TYP_STANDARD )/*HID类命令*/
|
||||
{
|
||||
switch( SetupReq )
|
||||
{
|
||||
case 0x01: //GetReport
|
||||
break;
|
||||
case 0x02: //GetIdle
|
||||
break;
|
||||
case 0x03: //GetProtocol
|
||||
break;
|
||||
case 0x09: //SetReport
|
||||
break;
|
||||
case 0x0A: //SetIdle
|
||||
break;
|
||||
case 0x0B: //SetProtocol
|
||||
break;
|
||||
default:
|
||||
len = 0xFF; /*命令不支持*/
|
||||
break;
|
||||
}
|
||||
}
|
||||
else //标准请求
|
||||
{
|
||||
switch(SetupReq) //请求码
|
||||
{
|
||||
case USB_GET_DESCRIPTOR:
|
||||
switch(UsbSetupBuf->wValueH)
|
||||
{
|
||||
case 1: //设备描述符
|
||||
pDescr = DevDesc; //把设备描述符送到要发送的缓冲区
|
||||
len = sizeof(DevDesc);
|
||||
break;
|
||||
case 2: //配置描述符
|
||||
pDescr = CfgDesc; //把设备描述符送到要发送的缓冲区
|
||||
len = sizeof(CfgDesc);
|
||||
break;
|
||||
case 0x22: //报表描述符
|
||||
pDescr = HIDRepDesc; //数据准备上传
|
||||
len = sizeof(HIDRepDesc);
|
||||
Ready = 1; //如果有更多接口,该标准位应该在最后一个接口配置完成后有效
|
||||
break;
|
||||
default:
|
||||
len = 0xff; //不支持的命令或者出错
|
||||
break;
|
||||
}
|
||||
if ( SetupLen > len )
|
||||
{
|
||||
SetupLen = len; //限制总长度
|
||||
}
|
||||
len = SetupLen >= THIS_ENDP0_SIZE ? THIS_ENDP0_SIZE : SetupLen;//本次传输长度
|
||||
memcpy(Ep0Buffer,pDescr,len); //加载上传数据
|
||||
SetupLen -= len;
|
||||
pDescr += len;
|
||||
break;
|
||||
case USB_SET_ADDRESS:
|
||||
SetupLen = UsbSetupBuf->wValueL; //暂存USB设备地址
|
||||
break;
|
||||
case USB_GET_CONFIGURATION:
|
||||
Ep0Buffer[0] = UsbConfig;
|
||||
if ( SetupLen >= 1 )
|
||||
{
|
||||
len = 1;
|
||||
}
|
||||
break;
|
||||
case USB_SET_CONFIGURATION:
|
||||
UsbConfig = UsbSetupBuf->wValueL;
|
||||
break;
|
||||
case 0x0A:
|
||||
break;
|
||||
case USB_CLEAR_FEATURE: //Clear Feature
|
||||
if ( ( UsbSetupBuf->bRequestType & USB_REQ_RECIP_MASK ) == USB_REQ_RECIP_ENDP )// 端点
|
||||
{
|
||||
switch( UsbSetupBuf->wIndexL )
|
||||
{
|
||||
case 0x82:
|
||||
UEP2_CTRL = UEP2_CTRL & ~ ( bUEP_T_TOG | MASK_UEP_T_RES ) | UEP_T_RES_NAK;
|
||||
break;
|
||||
case 0x81:
|
||||
UEP1_CTRL = UEP1_CTRL & ~ ( bUEP_T_TOG | MASK_UEP_T_RES ) | UEP_T_RES_NAK;
|
||||
break;
|
||||
case 0x02:
|
||||
UEP2_CTRL = UEP2_CTRL & ~ ( bUEP_R_TOG | MASK_UEP_R_RES ) | UEP_R_RES_ACK;
|
||||
break;
|
||||
default:
|
||||
len = 0xFF; // 不支持的端点
|
||||
break;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
len = 0xFF; // 不是端点不支持
|
||||
}
|
||||
break;
|
||||
case USB_SET_FEATURE: /* Set Feature */
|
||||
if( ( UsbSetupBuf->bRequestType & 0x1F ) == 0x00 ) /* 设置设备 */
|
||||
{
|
||||
if( ( ( ( UINT16 )UsbSetupBuf->wValueH << 8 ) | UsbSetupBuf->wValueL ) == 0x01 )
|
||||
{
|
||||
if( CfgDesc[ 7 ] & 0x20 )
|
||||
{
|
||||
/* 设置唤醒使能标志 */
|
||||
}
|
||||
else
|
||||
{
|
||||
len = 0xFF; /* 操作失败 */
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
len = 0xFF; /* 操作失败 */
|
||||
}
|
||||
}
|
||||
else if( ( UsbSetupBuf->bRequestType & 0x1F ) == 0x02 ) /* 设置端点 */
|
||||
{
|
||||
if( ( ( ( UINT16 )UsbSetupBuf->wValueH << 8 ) | UsbSetupBuf->wValueL ) == 0x00 )
|
||||
{
|
||||
switch( ( ( UINT16 )UsbSetupBuf->wIndexH << 8 ) | UsbSetupBuf->wIndexL )
|
||||
{
|
||||
case 0x82:
|
||||
UEP2_CTRL = UEP2_CTRL & (~bUEP_T_TOG) | UEP_T_RES_STALL;/* 设置端点2 IN STALL */
|
||||
break;
|
||||
case 0x02:
|
||||
UEP2_CTRL = UEP2_CTRL & (~bUEP_R_TOG) | UEP_R_RES_STALL;/* 设置端点2 OUT Stall */
|
||||
break;
|
||||
case 0x81:
|
||||
UEP1_CTRL = UEP1_CTRL & (~bUEP_T_TOG) | UEP_T_RES_STALL;/* 设置端点1 IN STALL */
|
||||
break;
|
||||
default:
|
||||
len = 0xFF; /* 操作失败 */
|
||||
break;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
len = 0xFF; /* 操作失败 */
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
len = 0xFF; /* 操作失败 */
|
||||
}
|
||||
break;
|
||||
case USB_GET_STATUS:
|
||||
Ep0Buffer[0] = 0x00;
|
||||
Ep0Buffer[1] = 0x00;
|
||||
if ( SetupLen >= 2 )
|
||||
{
|
||||
len = 2;
|
||||
}
|
||||
else
|
||||
{
|
||||
len = SetupLen;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
len = 0xff; //操作失败
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
len = 0xff; //包长度错误
|
||||
}
|
||||
if(len == 0xff)
|
||||
{
|
||||
SetupReq = 0xFF;
|
||||
UEP0_CTRL = bUEP_R_TOG | bUEP_T_TOG | UEP_R_RES_STALL | UEP_T_RES_STALL;//STALL
|
||||
}
|
||||
else if(len <= THIS_ENDP0_SIZE) //上传数据或者状态阶段返回0长度包
|
||||
{
|
||||
UEP0_T_LEN = len;
|
||||
UEP0_CTRL = bUEP_R_TOG | bUEP_T_TOG | UEP_R_RES_ACK | UEP_T_RES_ACK;//默认数据包是DATA1,返回应答ACK
|
||||
}
|
||||
else
|
||||
{
|
||||
UEP0_T_LEN = 0; //虽然尚未到状态阶段,但是提前预置上传0长度数据包以防主机提前进入状态阶段
|
||||
UEP0_CTRL = bUEP_R_TOG | bUEP_T_TOG | UEP_R_RES_ACK | UEP_T_RES_ACK;//默认数据包是DATA1,返回应答ACK
|
||||
}
|
||||
break;
|
||||
case UIS_TOKEN_IN | 0: //endpoint0 IN
|
||||
switch(SetupReq)
|
||||
{
|
||||
case USB_GET_DESCRIPTOR:
|
||||
len = SetupLen >= THIS_ENDP0_SIZE ? THIS_ENDP0_SIZE : SetupLen; //本次传输长度
|
||||
memcpy( Ep0Buffer, pDescr, len ); //加载上传数据
|
||||
SetupLen -= len;
|
||||
pDescr += len;
|
||||
UEP0_T_LEN = len;
|
||||
UEP0_CTRL ^= bUEP_T_TOG; //同步标志位翻转
|
||||
break;
|
||||
case USB_SET_ADDRESS:
|
||||
USB_DEV_AD = USB_DEV_AD & bUDA_GP_BIT | SetupLen;
|
||||
UEP0_CTRL = UEP_R_RES_ACK | UEP_T_RES_NAK;
|
||||
break;
|
||||
default:
|
||||
UEP0_T_LEN = 0; //状态阶段完成中断或者是强制上传0长度数据包结束控制传输
|
||||
UEP0_CTRL = UEP_R_RES_ACK | UEP_T_RES_NAK;
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case UIS_TOKEN_OUT | 0: // endpoint0 OUT
|
||||
len = USB_RX_LEN;
|
||||
if(SetupReq == 0x09)
|
||||
{
|
||||
if(Ep0Buffer[0])
|
||||
{
|
||||
printf("Light on Num Lock LED!\n");
|
||||
}
|
||||
else if(Ep0Buffer[0] == 0)
|
||||
{
|
||||
printf("Light off Num Lock LED!\n");
|
||||
}
|
||||
}
|
||||
UEP0_T_LEN = 0; //虽然尚未到状态阶段,但是提前预置上传0长度数据包以防主机提前进入状态阶段
|
||||
UEP0_CTRL = UEP_R_RES_ACK | UEP_T_RES_ACK;//默认数据包是DATA0,返回应答ACK
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
UIF_TRANSFER = 0; //写0清空中断
|
||||
}
|
||||
if(UIF_BUS_RST) //设备模式USB总线复位中断
|
||||
{
|
||||
UEP0_CTRL = UEP_R_RES_ACK | UEP_T_RES_NAK;
|
||||
UEP1_CTRL = bUEP_AUTO_TOG | UEP_R_RES_ACK;
|
||||
UEP2_CTRL = bUEP_AUTO_TOG | UEP_R_RES_ACK | UEP_T_RES_NAK;
|
||||
USB_DEV_AD = 0x00;
|
||||
UIF_SUSPEND = 0;
|
||||
UIF_TRANSFER = 0;
|
||||
UIF_BUS_RST = 0; //清中断标志
|
||||
}
|
||||
if (UIF_SUSPEND) //USB总线挂起/唤醒完成
|
||||
{
|
||||
UIF_SUSPEND = 0;
|
||||
if ( USB_MIS_ST & bUMS_SUSPEND ) //挂起
|
||||
{
|
||||
#ifdef DE_PRINTF
|
||||
printf( "zz" ); //睡眠状态
|
||||
#endif
|
||||
while ( XBUS_AUX & bUART0_TX )
|
||||
{
|
||||
; //等待发送完成
|
||||
}
|
||||
SAFE_MOD = 0x55;
|
||||
SAFE_MOD = 0xAA;
|
||||
WAKE_CTRL = bWAK_BY_USB | bWAK_RXD0_LO; //USB或者RXD0有信号时可被唤醒
|
||||
PCON |= PD; //睡眠
|
||||
SAFE_MOD = 0x55;
|
||||
SAFE_MOD = 0xAA;
|
||||
WAKE_CTRL = 0x00;
|
||||
}
|
||||
}
|
||||
else { //意外的中断,不可能发生的情况
|
||||
USB_INT_FG = 0xFF; //清中断标志
|
||||
// printf("UnknownInt N");
|
||||
}
|
||||
}
|
||||
|
||||
main()
|
||||
{
|
||||
UINT8 i;
|
||||
CfgFsys( ); //CH559时钟选择配置
|
||||
mDelaymS(5); //修改主频等待内部晶振稳定,必加
|
||||
mInitSTDIO( ); //串口0初始化
|
||||
#ifdef DE_PRINTF
|
||||
printf("start ...\n");
|
||||
#endif
|
||||
for(i=0; i<64; i++) //准备演示数据
|
||||
{
|
||||
UserEp2Buf[i] = i;
|
||||
}
|
||||
USBDeviceInit(); //USB设备模式初始化
|
||||
EA = 1; //允许单片机中断
|
||||
UEP1_T_LEN = 0; //预使用发送长度一定要清空
|
||||
UEP2_T_LEN = 0; //预使用发送长度一定要清空
|
||||
FLAG = 0;
|
||||
Ready = 0;
|
||||
while(1)
|
||||
{
|
||||
if(Ready&& (Ep2InKey==0))
|
||||
{
|
||||
Enp2BlukIn( );
|
||||
mDelaymS( 100 );
|
||||
}
|
||||
mDelaymS( 100 ); //模拟单片机做其它事
|
||||
}
|
||||
}
|
514
examples/USB/Device/CompositeKM.C
Normal file
514
examples/USB/Device/CompositeKM.C
Normal file
@ -0,0 +1,514 @@
|
||||
|
||||
/********************************** (C) COPYRIGHT *******************************
|
||||
* File Name :CompositeKM.C
|
||||
* Author : WCH
|
||||
* Version : V1.0
|
||||
* Date : 2017/01/20
|
||||
* Description : CH559模拟USB复合设备,键鼠,支持类命令
|
||||
*******************************************************************************/
|
||||
|
||||
#include "./Public/CH554.H"
|
||||
#include "./Public/Debug.H"
|
||||
#include <string.h>
|
||||
#include <stdio.h>
|
||||
|
||||
#define THIS_ENDP0_SIZE DEFAULT_ENDP0_SIZE
|
||||
|
||||
UINT8X Ep0Buffer[8<(THIS_ENDP0_SIZE+2)?8:(THIS_ENDP0_SIZE+2)] _at_ 0x0000; //端点0 OUT&IN缓冲区,必须是偶地址
|
||||
UINT8X Ep1Buffer[64<(MAX_PACKET_SIZE+2)?64:(MAX_PACKET_SIZE+2)] _at_ 0x000a; //端点1 IN缓冲区,必须是偶地址
|
||||
UINT8X Ep2Buffer[64<(MAX_PACKET_SIZE+2)?64:(MAX_PACKET_SIZE+2)] _at_ 0x0050; //端点2 IN缓冲区,必须是偶地址
|
||||
UINT8 SetupReq,SetupLen,Ready,Count,FLAG,UsbConfig;
|
||||
PUINT8 pDescr; //USB配置标志
|
||||
USB_SETUP_REQ SetupReqBuf; //暂存Setup包
|
||||
sbit Ep2InKey = P1^5;
|
||||
#define UsbSetupBuf ((PUSB_SETUP_REQ)Ep0Buffer)
|
||||
#define DEBUG 0
|
||||
#pragma NOAREGS
|
||||
/*设备描述符*/
|
||||
UINT8C DevDesc[18] = {0x12,0x01,0x10,0x01,0x00,0x00,0x00,0x08,
|
||||
0x3d,0x41,0x07,0x21,0x00,0x00,0x00,0x00,
|
||||
0x00,0x01
|
||||
};
|
||||
UINT8C CfgDesc[59] =
|
||||
{
|
||||
0x09,0x02,0x3b,0x00,0x02,0x01,0x00,0xA0,0x32, //配置描述符
|
||||
0x09,0x04,0x00,0x00,0x01,0x03,0x01,0x01,0x00, //接口描述符,键盘
|
||||
0x09,0x21,0x11,0x01,0x00,0x01,0x22,0x3e,0x00, //HID类描述符
|
||||
0x07,0x05,0x81,0x03,0x08,0x00,0x0a, //端点描述符
|
||||
0x09,0x04,0x01,0x00,0x01,0x03,0x01,0x02,0x00, //接口描述符,鼠标
|
||||
0x09,0x21,0x10,0x01,0x00,0x01,0x22,0x34,0x00, //HID类描述符
|
||||
0x07,0x05,0x82,0x03,0x04,0x00,0x0a //端点描述符
|
||||
};
|
||||
/*字符串描述符*/
|
||||
/*HID类报表描述符*/
|
||||
UINT8C KeyRepDesc[62] =
|
||||
{
|
||||
0x05,0x01,0x09,0x06,0xA1,0x01,0x05,0x07,
|
||||
0x19,0xe0,0x29,0xe7,0x15,0x00,0x25,0x01,
|
||||
0x75,0x01,0x95,0x08,0x81,0x02,0x95,0x01,
|
||||
0x75,0x08,0x81,0x01,0x95,0x03,0x75,0x01,
|
||||
0x05,0x08,0x19,0x01,0x29,0x03,0x91,0x02,
|
||||
0x95,0x05,0x75,0x01,0x91,0x01,0x95,0x06,
|
||||
0x75,0x08,0x26,0xff,0x00,0x05,0x07,0x19,
|
||||
0x00,0x29,0x91,0x81,0x00,0xC0
|
||||
};
|
||||
UINT8C MouseRepDesc[52] =
|
||||
{
|
||||
0x05,0x01,0x09,0x02,0xA1,0x01,0x09,0x01,
|
||||
0xA1,0x00,0x05,0x09,0x19,0x01,0x29,0x03,
|
||||
0x15,0x00,0x25,0x01,0x75,0x01,0x95,0x03,
|
||||
0x81,0x02,0x75,0x05,0x95,0x01,0x81,0x01,
|
||||
0x05,0x01,0x09,0x30,0x09,0x31,0x09,0x38,
|
||||
0x15,0x81,0x25,0x7f,0x75,0x08,0x95,0x03,
|
||||
0x81,0x06,0xC0,0xC0
|
||||
};
|
||||
/*鼠标数据*/
|
||||
UINT8 HIDMouse[4] = {0x0,0x0,0x0,0x0};
|
||||
/*键盘数据*/
|
||||
UINT8 HIDKey[8] = {0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0};
|
||||
|
||||
/*******************************************************************************
|
||||
* Function Name : USBDeviceInit()
|
||||
* Description : USB设备模式配置,设备模式启动,收发端点配置,中断开启
|
||||
* Input : None
|
||||
* Output : None
|
||||
* Return : None
|
||||
*******************************************************************************/
|
||||
void USBDeviceInit()
|
||||
{
|
||||
IE_USB = 0;
|
||||
USB_CTRL = 0x00; // 先设定USB设备模式
|
||||
UEP2_DMA = Ep2Buffer; //端点2数据传输地址
|
||||
UEP2_3_MOD = UEP2_3_MOD & ~bUEP2_BUF_MOD | bUEP2_TX_EN; //端点2发送使能 64字节缓冲区
|
||||
UEP2_CTRL = bUEP_AUTO_TOG | UEP_T_RES_NAK; //端点2自动翻转同步标志位,IN事务返回NAK
|
||||
UEP0_DMA = Ep0Buffer; //端点0数据传输地址
|
||||
UEP4_1_MOD &= ~(bUEP4_RX_EN | bUEP4_TX_EN); //端点0单64字节收发缓冲区
|
||||
UEP0_CTRL = UEP_R_RES_ACK | UEP_T_RES_NAK; //OUT事务返回ACK,IN事务返回NAK
|
||||
UEP1_DMA = Ep1Buffer; //端点1数据传输地址
|
||||
UEP4_1_MOD = UEP4_1_MOD & ~bUEP1_BUF_MOD | bUEP1_TX_EN; //端点1发送使能 64字节缓冲区
|
||||
UEP1_CTRL = bUEP_AUTO_TOG | UEP_T_RES_NAK; //端点1自动翻转同步标志位,IN事务返回NAK
|
||||
|
||||
USB_DEV_AD = 0x00;
|
||||
UDEV_CTRL = bUD_PD_DIS; // 禁止DP/DM下拉电阻
|
||||
USB_CTRL = bUC_DEV_PU_EN | bUC_INT_BUSY | bUC_DMA_EN; // 启动USB设备及DMA,在中断期间中断标志未清除前自动返回NAK
|
||||
UDEV_CTRL |= bUD_PORT_EN; // 允许USB端口
|
||||
USB_INT_FG = 0xFF; // 清中断标志
|
||||
USB_INT_EN = bUIE_SUSPEND | bUIE_TRANSFER | bUIE_BUS_RST;
|
||||
IE_USB = 1;
|
||||
}
|
||||
/*******************************************************************************
|
||||
* Function Name : Enp1IntIn()
|
||||
* Description : USB设备模式端点1的中断上传
|
||||
* Input : None
|
||||
* Output : None
|
||||
* Return : None
|
||||
*******************************************************************************/
|
||||
void Enp1IntIn( )
|
||||
{
|
||||
memcpy( Ep1Buffer, HIDKey, sizeof(HIDKey)); //加载上传数据
|
||||
UEP1_T_LEN = sizeof(HIDKey); //上传数据长度
|
||||
UEP1_CTRL = UEP1_CTRL & ~ MASK_UEP_T_RES | UEP_T_RES_ACK; //有数据时上传数据并应答ACK
|
||||
}
|
||||
/*******************************************************************************
|
||||
* Function Name : Enp2IntIn()
|
||||
* Description : USB设备模式端点2的中断上传
|
||||
* Input : None
|
||||
* Output : None
|
||||
* Return : None
|
||||
*******************************************************************************/
|
||||
void Enp2IntIn( )
|
||||
{
|
||||
memcpy( Ep2Buffer, HIDMouse, sizeof(HIDMouse)); //加载上传数据
|
||||
UEP2_T_LEN = sizeof(HIDMouse); //上传数据长度
|
||||
UEP2_CTRL = UEP2_CTRL & ~ MASK_UEP_T_RES | UEP_T_RES_ACK; //有数据时上传数据并应答ACK
|
||||
}
|
||||
/*******************************************************************************
|
||||
* Function Name : DeviceInterrupt()
|
||||
* Description : CH559USB中断处理函数
|
||||
*******************************************************************************/
|
||||
void DeviceInterrupt( void ) interrupt INT_NO_USB using 1 //USB中断服务程序,使用寄存器组1
|
||||
{
|
||||
UINT8 len;
|
||||
if(UIF_TRANSFER) //USB传输完成标志
|
||||
{
|
||||
switch (USB_INT_ST & (MASK_UIS_TOKEN | MASK_UIS_ENDP))
|
||||
{
|
||||
case UIS_TOKEN_IN | 2: //endpoint 2# 中断端点上传
|
||||
UEP2_T_LEN = 0; //预使用发送长度一定要清空
|
||||
// UEP1_CTRL ^= bUEP_T_TOG; //如果不设置自动翻转则需要手动翻转
|
||||
UEP2_CTRL = UEP2_CTRL & ~ MASK_UEP_T_RES | UEP_T_RES_NAK; //默认应答NAK
|
||||
break;
|
||||
case UIS_TOKEN_IN | 1: //endpoint 1# 中断端点上传
|
||||
UEP1_T_LEN = 0; //预使用发送长度一定要清空
|
||||
// UEP2_CTRL ^= bUEP_T_TOG; //如果不设置自动翻转则需要手动翻转
|
||||
UEP1_CTRL = UEP1_CTRL & ~ MASK_UEP_T_RES | UEP_T_RES_NAK; //默认应答NAK
|
||||
FLAG = 1; /*传输完成标志*/
|
||||
break;
|
||||
case UIS_TOKEN_SETUP | 0: //SETUP事务
|
||||
len = USB_RX_LEN;
|
||||
if(len == (sizeof(USB_SETUP_REQ)))
|
||||
{
|
||||
SetupLen = UsbSetupBuf->wLengthL;
|
||||
if(UsbSetupBuf->wLengthH || SetupLen > 0x7F )
|
||||
{
|
||||
SetupLen = 0x7F; // 限制总长度
|
||||
}
|
||||
len = 0; // 默认为成功并且上传0长度
|
||||
SetupReq = UsbSetupBuf->bRequest;
|
||||
if ( ( UsbSetupBuf->bRequestType & USB_REQ_TYP_MASK ) != USB_REQ_TYP_STANDARD )/* HID类命令 */
|
||||
{
|
||||
switch( SetupReq )
|
||||
{
|
||||
case 0x01://GetReport
|
||||
break;
|
||||
case 0x02://GetIdle
|
||||
break;
|
||||
case 0x03://GetProtocol
|
||||
break;
|
||||
case 0x09://SetReport
|
||||
break;
|
||||
case 0x0A://SetIdle
|
||||
break;
|
||||
case 0x0B://SetProtocol
|
||||
break;
|
||||
default:
|
||||
len = 0xFF; /*命令不支持*/
|
||||
break;
|
||||
}
|
||||
}
|
||||
else
|
||||
{//标准请求
|
||||
switch(SetupReq) //请求码
|
||||
{
|
||||
case USB_GET_DESCRIPTOR:
|
||||
switch(UsbSetupBuf->wValueH)
|
||||
{
|
||||
case 1: //设备描述符
|
||||
pDescr = DevDesc; //把设备描述符送到要发送的缓冲区
|
||||
len = sizeof(DevDesc);
|
||||
break;
|
||||
case 2: //配置描述符
|
||||
pDescr = CfgDesc; //把设备描述符送到要发送的缓冲区
|
||||
len = sizeof(CfgDesc);
|
||||
break;
|
||||
case 0x22: //报表描述符
|
||||
if(UsbSetupBuf->wIndexL == 0) //接口0报表描述符
|
||||
{
|
||||
pDescr = KeyRepDesc; //数据准备上传
|
||||
len = sizeof(KeyRepDesc);
|
||||
}
|
||||
else if(UsbSetupBuf->wIndexL == 1) //接口1报表描述符
|
||||
{
|
||||
pDescr = MouseRepDesc; //数据准备上传
|
||||
len = sizeof(MouseRepDesc);
|
||||
Ready = 1; //如果有更多接口,该标准位应该在最后一个接口配置完成后有效
|
||||
}
|
||||
else
|
||||
{
|
||||
len = 0xff; //本程序只有2个接口,这句话正常不可能执行
|
||||
}
|
||||
break;
|
||||
default:
|
||||
len = 0xff; //不支持的命令或者出错
|
||||
break;
|
||||
}
|
||||
if ( SetupLen > len )
|
||||
{
|
||||
SetupLen = len; //限制总长度
|
||||
}
|
||||
len = SetupLen >= 8 ? 8 : SetupLen; //本次传输长度
|
||||
memcpy(Ep0Buffer,pDescr,len); //加载上传数据
|
||||
SetupLen -= len;
|
||||
pDescr += len;
|
||||
break;
|
||||
case USB_SET_ADDRESS:
|
||||
SetupLen = UsbSetupBuf->wValueL; //暂存USB设备地址
|
||||
break;
|
||||
case USB_GET_CONFIGURATION:
|
||||
Ep0Buffer[0] = UsbConfig;
|
||||
if ( SetupLen >= 1 )
|
||||
{
|
||||
len = 1;
|
||||
}
|
||||
break;
|
||||
case USB_SET_CONFIGURATION:
|
||||
UsbConfig = UsbSetupBuf->wValueL;
|
||||
break;
|
||||
case 0x0A:
|
||||
break;
|
||||
case USB_CLEAR_FEATURE: //Clear Feature
|
||||
if ( ( UsbSetupBuf->bRequestType & USB_REQ_RECIP_MASK ) == USB_REQ_RECIP_ENDP )// 端点
|
||||
{
|
||||
switch( UsbSetupBuf->wIndexL )
|
||||
{
|
||||
case 0x82:
|
||||
UEP2_CTRL = UEP2_CTRL & ~ ( bUEP_T_TOG | MASK_UEP_T_RES ) | UEP_T_RES_NAK;
|
||||
break;
|
||||
case 0x81:
|
||||
UEP1_CTRL = UEP1_CTRL & ~ ( bUEP_T_TOG | MASK_UEP_T_RES ) | UEP_T_RES_NAK;
|
||||
break;
|
||||
case 0x01:
|
||||
UEP1_CTRL = UEP1_CTRL & ~ ( bUEP_R_TOG | MASK_UEP_R_RES ) | UEP_R_RES_ACK;
|
||||
break;
|
||||
default:
|
||||
len = 0xFF; // 不支持的端点
|
||||
break;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
len = 0xFF; // 不是端点不支持
|
||||
}
|
||||
break;
|
||||
case USB_SET_FEATURE: /* Set Feature */
|
||||
if( ( UsbSetupBuf->bRequestType & 0x1F ) == 0x00 ) /* 设置设备 */
|
||||
{
|
||||
if( ( ( ( UINT16 )UsbSetupBuf->wValueH << 8 ) | UsbSetupBuf->wValueL ) == 0x01 )
|
||||
{
|
||||
if( CfgDesc[ 7 ] & 0x20 )
|
||||
{
|
||||
/* 设置唤醒使能标志 */
|
||||
}
|
||||
else
|
||||
{
|
||||
len = 0xFF; /* 操作失败 */
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
len = 0xFF; /* 操作失败 */
|
||||
}
|
||||
}
|
||||
else if( ( UsbSetupBuf->bRequestType & 0x1F ) == 0x02 ) /* 设置端点 */
|
||||
{
|
||||
if( ( ( ( UINT16 )UsbSetupBuf->wValueH << 8 ) | UsbSetupBuf->wValueL ) == 0x00 )
|
||||
{
|
||||
switch( ( ( UINT16 )UsbSetupBuf->wIndexH << 8 ) | UsbSetupBuf->wIndexL )
|
||||
{
|
||||
case 0x82:
|
||||
UEP2_CTRL = UEP2_CTRL & (~bUEP_T_TOG) | UEP_T_RES_STALL;/* 设置端点2 IN STALL */
|
||||
break;
|
||||
case 0x02:
|
||||
UEP2_CTRL = UEP2_CTRL & (~bUEP_R_TOG) | UEP_R_RES_STALL;/* 设置端点2 OUT Stall */
|
||||
break;
|
||||
case 0x81:
|
||||
UEP1_CTRL = UEP1_CTRL & (~bUEP_T_TOG) | UEP_T_RES_STALL;/* 设置端点1 IN STALL */
|
||||
break;
|
||||
default:
|
||||
len = 0xFF; //操作失败
|
||||
break;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
len = 0xFF; //操作失败
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
len = 0xFF; //操作失败
|
||||
}
|
||||
break;
|
||||
case USB_GET_STATUS:
|
||||
Ep0Buffer[0] = 0x00;
|
||||
Ep0Buffer[1] = 0x00;
|
||||
if ( SetupLen >= 2 )
|
||||
{
|
||||
len = 2;
|
||||
}
|
||||
else
|
||||
{
|
||||
len = SetupLen;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
len = 0xff; //操作失败
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
len = 0xff; //包长度错误
|
||||
}
|
||||
if(len == 0xff)
|
||||
{
|
||||
SetupReq = 0xFF;
|
||||
UEP0_CTRL = bUEP_R_TOG | bUEP_T_TOG | UEP_R_RES_STALL | UEP_T_RES_STALL;//STALL
|
||||
}
|
||||
else if(len <= 8) //上传数据或者状态阶段返回0长度包
|
||||
{
|
||||
UEP0_T_LEN = len;
|
||||
UEP0_CTRL = bUEP_R_TOG | bUEP_T_TOG | UEP_R_RES_ACK | UEP_T_RES_ACK;//默认数据包是DATA1,返回应答ACK
|
||||
}
|
||||
else
|
||||
{
|
||||
UEP0_T_LEN = 0; //虽然尚未到状态阶段,但是提前预置上传0长度数据包以防主机提前进入状态阶段
|
||||
UEP0_CTRL = bUEP_R_TOG | bUEP_T_TOG | UEP_R_RES_ACK | UEP_T_RES_ACK;//默认数据包是DATA1,返回应答ACK
|
||||
}
|
||||
break;
|
||||
case UIS_TOKEN_IN | 0: //endpoint0 IN
|
||||
switch(SetupReq)
|
||||
{
|
||||
case USB_GET_DESCRIPTOR:
|
||||
len = SetupLen >= 8 ? 8 : SetupLen; //本次传输长度
|
||||
memcpy( Ep0Buffer, pDescr, len ); //加载上传数据
|
||||
SetupLen -= len;
|
||||
pDescr += len;
|
||||
UEP0_T_LEN = len;
|
||||
UEP0_CTRL ^= bUEP_T_TOG; //同步标志位翻转
|
||||
break;
|
||||
case USB_SET_ADDRESS:
|
||||
USB_DEV_AD = USB_DEV_AD & bUDA_GP_BIT | SetupLen;
|
||||
UEP0_CTRL = UEP_R_RES_ACK | UEP_T_RES_NAK;
|
||||
break;
|
||||
default:
|
||||
UEP0_T_LEN = 0; //状态阶段完成中断或者是强制上传0长度数据包结束控制传输
|
||||
UEP0_CTRL = UEP_R_RES_ACK | UEP_T_RES_NAK;
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case UIS_TOKEN_OUT | 0: // endpoint0 OUT
|
||||
len = USB_RX_LEN;
|
||||
if(SetupReq == 0x09)
|
||||
{
|
||||
if(Ep0Buffer[0])
|
||||
{
|
||||
printf("Light on Num Lock LED!\n");
|
||||
}
|
||||
else if(Ep0Buffer[0] == 0)
|
||||
{
|
||||
printf("Light off Num Lock LED!\n");
|
||||
}
|
||||
}
|
||||
UEP0_T_LEN = 0; //虽然尚未到状态阶段,但是提前预置上传0长度数据包以防主机提前进入状态阶段
|
||||
UEP0_CTRL = UEP_R_RES_ACK | UEP_T_RES_ACK;//默认数据包是DATA0,返回应答ACK
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
UIF_TRANSFER = 0; //写0清空中断
|
||||
}
|
||||
if(UIF_BUS_RST) //设备模式USB总线复位中断
|
||||
{
|
||||
UEP0_CTRL = UEP_R_RES_ACK | UEP_T_RES_NAK;
|
||||
UEP1_CTRL = bUEP_AUTO_TOG | UEP_R_RES_ACK;
|
||||
UEP2_CTRL = bUEP_AUTO_TOG | UEP_R_RES_ACK | UEP_T_RES_NAK;
|
||||
USB_DEV_AD = 0x00;
|
||||
UIF_SUSPEND = 0;
|
||||
UIF_TRANSFER = 0;
|
||||
UIF_BUS_RST = 0; //清中断标志
|
||||
}
|
||||
if (UIF_SUSPEND) //USB总线挂起/唤醒完成
|
||||
{
|
||||
UIF_SUSPEND = 0;
|
||||
if ( USB_MIS_ST & bUMS_SUSPEND ) //挂起
|
||||
{
|
||||
#if DEBUG
|
||||
printf( "zz" ); //睡眠状态
|
||||
#endif
|
||||
while ( XBUS_AUX & bUART0_TX ); //等待发送完成
|
||||
SAFE_MOD = 0x55;
|
||||
SAFE_MOD = 0xAA;
|
||||
WAKE_CTRL = bWAK_BY_USB | bWAK_RXD0_LO; //USB或者RXD0有信号时可被唤醒
|
||||
PCON |= PD; //睡眠
|
||||
SAFE_MOD = 0x55;
|
||||
SAFE_MOD = 0xAA;
|
||||
WAKE_CTRL = 0x00;
|
||||
}
|
||||
}
|
||||
else { //意外的中断,不可能发生的情况
|
||||
USB_INT_FG = 0xFF; //清中断标志
|
||||
// printf("UnknownInt N");
|
||||
}
|
||||
}
|
||||
void HIDValueHandle()
|
||||
{
|
||||
UINT8 i;
|
||||
i = getkey( );
|
||||
printf( "%c", (UINT8)i );
|
||||
switch(i)
|
||||
{
|
||||
//鼠标数据上传示例
|
||||
case 'L': //左键
|
||||
HIDMouse[0] = 0x01;
|
||||
Enp2IntIn();
|
||||
HIDMouse[0] = 0;
|
||||
break;
|
||||
case 'R': //右键
|
||||
HIDMouse[0] = 0x02;
|
||||
Enp2IntIn();
|
||||
HIDMouse[0] = 0;
|
||||
break;
|
||||
//键盘数据上传示例
|
||||
case 'A': //A键
|
||||
FLAG = 0;
|
||||
HIDKey[2] = 0x04; //按键开始
|
||||
Enp1IntIn();
|
||||
HIDKey[2] = 0; //按键结束
|
||||
while(FLAG == 0)
|
||||
{
|
||||
; /*等待上一包传输完成*/
|
||||
}
|
||||
Enp1IntIn();
|
||||
break;
|
||||
case 'P': //P键
|
||||
FLAG = 0;
|
||||
HIDKey[2] = 0x13;
|
||||
Enp1IntIn();
|
||||
HIDKey[2] = 0; //按键结束
|
||||
while(FLAG == 0)
|
||||
{
|
||||
; /*等待上一包传输完成*/
|
||||
}
|
||||
Enp1IntIn();
|
||||
break;
|
||||
case 'Q': //Num Lock键
|
||||
FLAG = 0;
|
||||
HIDKey[2] = 0x53;
|
||||
Enp1IntIn();
|
||||
HIDKey[2] = 0; //按键结束
|
||||
while(FLAG == 0)
|
||||
{
|
||||
; /*等待上一包传输完成*/
|
||||
}
|
||||
Enp1IntIn();
|
||||
break;
|
||||
default: //其他
|
||||
UEP1_CTRL = UEP1_CTRL & ~ MASK_UEP_T_RES | UEP_T_RES_NAK; //默认应答NAK
|
||||
UEP2_CTRL = UEP2_CTRL & ~ MASK_UEP_T_RES | UEP_T_RES_NAK; //默认应答NAK
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
main()
|
||||
{
|
||||
CfgFsys( ); //CH559时钟选择配置
|
||||
mDelaymS(5); //修改主频等待内部晶振稳定,必加
|
||||
mInitSTDIO( ); //串口0初始化
|
||||
#ifdef DE_PRINTF
|
||||
printf("start ...\n");
|
||||
#endif
|
||||
USBDeviceInit(); //USB设备模式初始化
|
||||
EA = 1; //允许单片机中断
|
||||
UEP1_T_LEN = 0; //预使用发送长度一定要清空
|
||||
UEP2_T_LEN = 0; //预使用发送长度一定要清空
|
||||
FLAG = 0;
|
||||
Ready = 0;
|
||||
while(1)
|
||||
{
|
||||
if(Ready)
|
||||
{
|
||||
HIDValueHandle();
|
||||
}
|
||||
if(Ready&&(Ep2InKey == 0)){
|
||||
#ifdef DE_PRINTF //读取芯片ID号
|
||||
printf("ID0 = %02x %02x \n",(UINT16)*(PUINT8C)(0x3FFA),(UINT16)*(PUINT8C)(0x3FFB));
|
||||
printf("ID1 = %02x %02x \n",(UINT16)*(PUINT8C)(0x3FFC),(UINT16)*(PUINT8C)(0x3FFD));
|
||||
printf("ID2 = %02x %02x \n",(UINT16)*(PUINT8C)(0x3FFE),(UINT16)*(PUINT8C)(0x3FFF));
|
||||
#endif
|
||||
mDelaymS( 100 );
|
||||
}
|
||||
mDelaymS( 100 ); //模拟单片机做其它事
|
||||
}
|
||||
}
|
335
examples/USB/Device/VendorDefinedDev.C
Normal file
335
examples/USB/Device/VendorDefinedDev.C
Normal file
@ -0,0 +1,335 @@
|
||||
|
||||
/********************************** (C) COPYRIGHT *******************************
|
||||
* File Name : VendorDefinedDev.C
|
||||
* Author : WCH
|
||||
* Version : V1.0
|
||||
* Date : 2017/01/20
|
||||
* Description : CH554模拟USB Module(CH554),厂商自定义接口设备,需要安装驱动,
|
||||
驱动搜索CH37XDRV或者安装ISPTool会自动安装该设备类驱动,该设备类除了控制传输外,还是直插端点2批量上下传和端点1
|
||||
中断上传,可以通过372DEBUG.EXE获取其他USB调试工具进行收发数据演示
|
||||
|
||||
*******************************************************************************/
|
||||
|
||||
#include "./Public/CH554.H"
|
||||
#include "./Public/Debug.H"
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
|
||||
#define THIS_ENDP0_SIZE DEFAULT_ENDP0_SIZE
|
||||
|
||||
// 设备描述符
|
||||
UINT8C MyDevDescr[] = { 0x12, 0x01, 0x10, 0x01,
|
||||
0xFF, 0x80, 0x55, THIS_ENDP0_SIZE,
|
||||
0x48, 0x43, 0x37, 0x55, // 厂商ID和产品ID
|
||||
0x00, 0x01, 0x01, 0x02,
|
||||
0x00, 0x01 };
|
||||
// 配置描述符
|
||||
UINT8C MyCfgDescr[] = { 0x09, 0x02, 0x27, 0x00, 0x01, 0x01, 0x00, 0x80, 0x32,
|
||||
0x09, 0x04, 0x00, 0x00, 0x03, 0xFF, 0x80, 0x55, 0x00,
|
||||
0x07, 0x05, 0x82, 0x02, 0x40, 0x00, 0x00,
|
||||
0x07, 0x05, 0x02, 0x02, 0x40, 0x00, 0x00,
|
||||
0x07, 0x05, 0x81, 0x03, 0x40, 0x00, 0x00 };
|
||||
// 语言描述符
|
||||
UINT8C MyLangDescr[] = { 0x04, 0x03, 0x09, 0x04 };
|
||||
// 厂家信息
|
||||
UINT8C MyManuInfo[] = { 0x0E, 0x03, 'w', 0, 'c', 0, 'h', 0, '.', 0, 'c', 0, 'n', 0 };
|
||||
// 产品信息
|
||||
UINT8C MyProdInfo[] = { 0x0C, 0x03, 'C', 0, 'H', 0, '5', 0, '5', 0, '4', 0 };
|
||||
|
||||
UINT8 UsbConfig = 0; // USB配置标志
|
||||
|
||||
UINT8X Ep0Buffer[THIS_ENDP0_SIZE+2 >= MAX_PACKET_SIZE ? MAX_PACKET_SIZE : THIS_ENDP0_SIZE+2]; // OUT&IN
|
||||
UINT8X Ep1Buffer[MAX_PACKET_SIZE]; // IN
|
||||
UINT8X Ep2Buffer[2*MAX_PACKET_SIZE]; // OUT+IN
|
||||
|
||||
#define UsbSetupBuf ((PUSB_SETUP_REQ)Ep0Buffer)
|
||||
|
||||
#pragma NOAREGS
|
||||
|
||||
void USB_DeviceInterrupt( void ) interrupt INT_NO_USB using 1 /* USB中断服务程序,使用寄存器组1 */
|
||||
{
|
||||
UINT8 i, len;
|
||||
static UINT8 SetupReqCode, SetupLen;
|
||||
static PUINT8 pDescr;
|
||||
if ( UIF_TRANSFER ) { // USB传输完成
|
||||
if ( U_IS_NAK ) { // not enable for this example
|
||||
// switch ( USB_INT_ST & ( MASK_UIS_TOKEN | MASK_UIS_ENDP ) ) { // 分析操作令牌和端点号
|
||||
// case UIS_TOKEN_OUT | 2: // endpoint 2# 批量端点下传
|
||||
// break;
|
||||
// case UIS_TOKEN_IN | 2: // endpoint 2# 批量端点上传
|
||||
// break;
|
||||
// case UIS_TOKEN_IN | 1: // endpoint 1# 中断端点上传
|
||||
// break;
|
||||
// default:
|
||||
// break;
|
||||
// }
|
||||
}
|
||||
else {
|
||||
switch ( USB_INT_ST & ( MASK_UIS_TOKEN | MASK_UIS_ENDP ) ) { // 分析操作令牌和端点号
|
||||
case UIS_TOKEN_OUT | 2: // endpoint 2# 批量端点下传
|
||||
if ( U_TOG_OK ) { // 不同步的数据包将丢弃
|
||||
// UEP2_CTRL ^= bUEP_R_TOG; // 已自动翻转
|
||||
len = USB_RX_LEN;
|
||||
for ( i = 0; i < len; i ++ ) {
|
||||
Ep2Buffer[MAX_PACKET_SIZE+i] = Ep2Buffer[i] ^ 0xFF; // OUT数据取反到IN由计算机验证
|
||||
}
|
||||
UEP2_T_LEN = len;
|
||||
UEP2_CTRL = UEP2_CTRL & ~ MASK_UEP_T_RES | UEP_T_RES_ACK;// 允许上传
|
||||
}
|
||||
break;
|
||||
case UIS_TOKEN_IN | 2: // endpoint 2# 批量端点上传
|
||||
// UEP2_CTRL ^= bUEP_T_TOG; // 已自动翻转
|
||||
UEP2_CTRL = UEP2_CTRL & ~ MASK_UEP_T_RES | UEP_T_RES_NAK; // 暂停上传
|
||||
break;
|
||||
case UIS_TOKEN_IN | 1: // endpoint 1# 中断端点上传
|
||||
// UEP1_CTRL ^= bUEP_T_TOG; // 已自动翻转
|
||||
UEP1_CTRL = UEP1_CTRL & ~ MASK_UEP_T_RES | UEP_T_RES_NAK; // 暂停上传
|
||||
break;
|
||||
case UIS_TOKEN_SETUP | 0: // endpoint 0# SETUP
|
||||
len = USB_RX_LEN;
|
||||
if ( len == sizeof( USB_SETUP_REQ ) ) { // SETUP包长度
|
||||
SetupLen = UsbSetupBuf->wLengthL;
|
||||
if ( UsbSetupBuf->wLengthH || SetupLen > 0x7F ) SetupLen = 0x7F;// 限制总长度
|
||||
len = 0; // 默认为成功并且上传0长度
|
||||
SetupReqCode = UsbSetupBuf->bRequest;
|
||||
if ( ( UsbSetupBuf->bRequestType & USB_REQ_TYP_MASK ) != USB_REQ_TYP_STANDARD ) { /* 非标准请求 */
|
||||
len = 0xFF;
|
||||
}
|
||||
else { // 标准请求
|
||||
switch( SetupReqCode ) { // 请求码
|
||||
case USB_GET_DESCRIPTOR:
|
||||
switch( UsbSetupBuf->wValueH ) {
|
||||
case 1: // 设备描述符
|
||||
pDescr = (PUINT8)( &MyDevDescr[0] );
|
||||
len = sizeof( MyDevDescr );
|
||||
break;
|
||||
case 2: // 配置描述符
|
||||
pDescr = (PUINT8)( &MyCfgDescr[0] );
|
||||
len = sizeof( MyCfgDescr );
|
||||
break;
|
||||
case 3: // 字符串描述符
|
||||
switch( UsbSetupBuf->wValueL ) {
|
||||
case 1:
|
||||
pDescr = (PUINT8)( &MyManuInfo[0] );
|
||||
len = sizeof( MyManuInfo );
|
||||
break;
|
||||
case 2:
|
||||
pDescr = (PUINT8)( &MyProdInfo[0] );
|
||||
len = sizeof( MyProdInfo );
|
||||
break;
|
||||
case 0:
|
||||
pDescr = (PUINT8)( &MyLangDescr[0] );
|
||||
len = sizeof( MyLangDescr );
|
||||
break;
|
||||
default:
|
||||
len = 0xFF; // 不支持的字符串描述符
|
||||
break;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
len = 0xFF; // 不支持的描述符类型
|
||||
break;
|
||||
}
|
||||
if ( SetupLen > len ) SetupLen = len; // 限制总长度
|
||||
len = SetupLen >= THIS_ENDP0_SIZE ? THIS_ENDP0_SIZE : SetupLen; // 本次传输长度
|
||||
memcpy( Ep0Buffer, pDescr, len ); /* 加载上传数据 */
|
||||
SetupLen -= len;
|
||||
pDescr += len;
|
||||
break;
|
||||
case USB_SET_ADDRESS:
|
||||
SetupLen = UsbSetupBuf->wValueL; // 暂存USB设备地址
|
||||
break;
|
||||
case USB_GET_CONFIGURATION:
|
||||
Ep0Buffer[0] = UsbConfig;
|
||||
if ( SetupLen >= 1 ) len = 1;
|
||||
break;
|
||||
case USB_SET_CONFIGURATION:
|
||||
UsbConfig = UsbSetupBuf->wValueL;
|
||||
break;
|
||||
case USB_CLEAR_FEATURE:
|
||||
if ( ( UsbSetupBuf->bRequestType & USB_REQ_RECIP_MASK ) == USB_REQ_RECIP_ENDP ) { // 端点
|
||||
switch( UsbSetupBuf->wIndexL ) {
|
||||
case 0x82:
|
||||
UEP2_CTRL = UEP2_CTRL & ~ ( bUEP_T_TOG | MASK_UEP_T_RES ) | UEP_T_RES_NAK;
|
||||
break;
|
||||
case 0x02:
|
||||
UEP2_CTRL = UEP2_CTRL & ~ ( bUEP_R_TOG | MASK_UEP_R_RES ) | UEP_R_RES_ACK;
|
||||
break;
|
||||
case 0x81:
|
||||
UEP1_CTRL = UEP1_CTRL & ~ ( bUEP_T_TOG | MASK_UEP_T_RES ) | UEP_T_RES_NAK;
|
||||
break;
|
||||
case 0x01:
|
||||
UEP1_CTRL = UEP1_CTRL & ~ ( bUEP_R_TOG | MASK_UEP_R_RES ) | UEP_R_RES_ACK;
|
||||
break;
|
||||
default:
|
||||
len = 0xFF; // 不支持的端点
|
||||
break;
|
||||
}
|
||||
}
|
||||
else len = 0xFF; // 不是端点不支持
|
||||
break;
|
||||
case USB_GET_INTERFACE:
|
||||
Ep0Buffer[0] = 0x00;
|
||||
if ( SetupLen >= 1 ) len = 1;
|
||||
break;
|
||||
case USB_GET_STATUS:
|
||||
Ep0Buffer[0] = 0x00;
|
||||
Ep0Buffer[1] = 0x00;
|
||||
if ( SetupLen >= 2 ) len = 2;
|
||||
else len = SetupLen;
|
||||
break;
|
||||
default:
|
||||
len = 0xFF; // 操作失败
|
||||
#ifdef DE_PRINTF
|
||||
printf("ErrEp0ReqCode=%02X\n",(UINT16)SetupReqCode);
|
||||
#endif
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
len = 0xFF; // SETUP包长度错误
|
||||
#ifdef DE_PRINTF
|
||||
printf("ErrEp0ReqSize\n");
|
||||
#endif
|
||||
}
|
||||
if ( len == 0xFF ) { // 操作失败
|
||||
SetupReqCode = 0xFF;
|
||||
UEP0_CTRL = bUEP_R_TOG | bUEP_T_TOG | UEP_R_RES_STALL | UEP_T_RES_STALL; // STALL
|
||||
}
|
||||
else if ( len <= THIS_ENDP0_SIZE ) { // 上传数据或者状态阶段返回0长度包
|
||||
UEP0_T_LEN = len;
|
||||
UEP0_CTRL = bUEP_R_TOG | bUEP_T_TOG | UEP_R_RES_ACK | UEP_T_RES_ACK; // 默认数据包是DATA1
|
||||
}
|
||||
else { // 下传数据或其它
|
||||
UEP0_T_LEN = 0; // 虽然尚未到状态阶段,但是提前预置上传0长度数据包以防主机提前进入状态阶段
|
||||
UEP0_CTRL = bUEP_R_TOG | bUEP_T_TOG | UEP_R_RES_ACK | UEP_T_RES_ACK; // 默认数据包是DATA1
|
||||
}
|
||||
break;
|
||||
case UIS_TOKEN_IN | 0: // endpoint 0# IN
|
||||
switch( SetupReqCode ) {
|
||||
case USB_GET_DESCRIPTOR:
|
||||
len = SetupLen >= THIS_ENDP0_SIZE ? THIS_ENDP0_SIZE : SetupLen; // 本次传输长度
|
||||
memcpy( Ep0Buffer, pDescr, len ); /* 加载上传数据 */
|
||||
SetupLen -= len;
|
||||
pDescr += len;
|
||||
UEP0_T_LEN = len;
|
||||
UEP0_CTRL ^= bUEP_T_TOG; // 翻转
|
||||
break;
|
||||
case USB_SET_ADDRESS:
|
||||
USB_DEV_AD = USB_DEV_AD & bUDA_GP_BIT | SetupLen;
|
||||
UEP0_CTRL = UEP_R_RES_ACK | UEP_T_RES_NAK;
|
||||
break;
|
||||
default:
|
||||
UEP0_T_LEN = 0; // 状态阶段完成中断或者是强制上传0长度数据包结束控制传输
|
||||
UEP0_CTRL = UEP_R_RES_ACK | UEP_T_RES_NAK;
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case UIS_TOKEN_OUT | 0: // endpoint 0# OUT
|
||||
switch( SetupReqCode ) {
|
||||
// case download:
|
||||
// if ( U_TOG_OK ) { // 不同步的数据包将丢弃
|
||||
// UEP0_CTRL ^= bUEP_R_TOG; // 翻转
|
||||
// //获取下传数据;
|
||||
// //UEP0_CTRL = UEP0_CTRL & bUEP_R_TOG | bUEP_T_TOG | UEP_R_RES_ACK | UEP_T_RES_ACK; // 预置上传0长度数据包DATA1以防主机提前进入状态阶段
|
||||
// }
|
||||
// break;
|
||||
case USB_GET_DESCRIPTOR:
|
||||
default:
|
||||
if ( U_TOG_OK ) { // 不同步的数据包将丢弃
|
||||
// if ( USB_RX_LEN ) control_status_error;
|
||||
// else control_ok; // 收到0长度包表示控制读操作/上传OK
|
||||
}
|
||||
// else control_status_error;
|
||||
UEP0_CTRL = UEP_R_RES_ACK | UEP_T_RES_NAK; // 准备下一控制传输
|
||||
break;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
UIF_TRANSFER = 0; // 清中断标志
|
||||
}
|
||||
else if ( UIF_BUS_RST ) { // USB总线复位
|
||||
UEP0_CTRL = UEP_R_RES_ACK | UEP_T_RES_NAK;
|
||||
UEP1_CTRL = bUEP_AUTO_TOG | UEP_R_RES_ACK;
|
||||
UEP2_CTRL = bUEP_AUTO_TOG | UEP_R_RES_ACK | UEP_T_RES_NAK;
|
||||
USB_DEV_AD = 0x00;
|
||||
UIF_SUSPEND = 0;
|
||||
UIF_TRANSFER = 0;
|
||||
UIF_BUS_RST = 0; // 清中断标志
|
||||
}
|
||||
else if ( UIF_SUSPEND ) { // USB总线挂起/唤醒完成
|
||||
UIF_SUSPEND = 0;
|
||||
if ( USB_MIS_ST & bUMS_SUSPEND ) { // 挂起
|
||||
#ifdef DE_PRINTF
|
||||
printf( "zz" ); // 睡眠状态
|
||||
#endif
|
||||
while ( XBUS_AUX & bUART0_TX ); // 等待发送完成
|
||||
SAFE_MOD = 0x55;
|
||||
SAFE_MOD = 0xAA;
|
||||
WAKE_CTRL = bWAK_BY_USB | bWAK_RXD0_LO; // USB或者RXD0有信号时可被唤醒
|
||||
PCON |= PD; // 睡眠
|
||||
SAFE_MOD = 0x55;
|
||||
SAFE_MOD = 0xAA;
|
||||
WAKE_CTRL = 0x00;
|
||||
}
|
||||
else { // 唤醒
|
||||
}
|
||||
}
|
||||
else { // 意外的中断,不可能发生的情况
|
||||
|
||||
USB_INT_FG = 0xFF; // 清中断标志
|
||||
}
|
||||
}
|
||||
|
||||
/*******************************************************************************
|
||||
* Function Name : InitUSB_Device()
|
||||
* Description : USB设备模式配置,设备模式启动,收发端点配置,中断开启
|
||||
* Input : None
|
||||
* Output : None
|
||||
* Return : None
|
||||
*******************************************************************************/
|
||||
void InitUSB_Device( void ) // 初始化USB设备
|
||||
{
|
||||
IE_USB = 0;
|
||||
USB_CTRL = 0x00; // 先设定模式
|
||||
UEP4_1_MOD = bUEP1_TX_EN; // 端点1上传IN
|
||||
UEP2_3_MOD = bUEP2_RX_EN | bUEP2_TX_EN; // 端点2下传OUT和上传IN
|
||||
UEP0_DMA = Ep0Buffer;
|
||||
UEP1_DMA = Ep1Buffer;
|
||||
UEP2_DMA = Ep2Buffer;
|
||||
UEP0_CTRL = UEP_R_RES_ACK | UEP_T_RES_NAK;
|
||||
UEP1_CTRL = bUEP_AUTO_TOG | UEP_R_RES_ACK;
|
||||
UEP2_CTRL = bUEP_AUTO_TOG | UEP_R_RES_ACK | UEP_T_RES_NAK;
|
||||
USB_DEV_AD = 0x00;
|
||||
UDEV_CTRL = bUD_PD_DIS; // 禁止DP/DM下拉电阻
|
||||
USB_CTRL = bUC_DEV_PU_EN | bUC_INT_BUSY | bUC_DMA_EN; // 启动USB设备及DMA,在中断期间中断标志未清除前自动返回NAK
|
||||
UDEV_CTRL |= bUD_PORT_EN; // 允许USB端口
|
||||
USB_INT_FG = 0xFF; // 清中断标志
|
||||
USB_INT_EN = bUIE_SUSPEND | bUIE_TRANSFER | bUIE_BUS_RST;
|
||||
IE_USB = 1;
|
||||
}
|
||||
|
||||
main( ) {
|
||||
UINT8 i;
|
||||
CfgFsys();
|
||||
mDelaymS(5); //修改主频,稍加延时等待主频稳定
|
||||
mInitSTDIO( ); /* 初始化串口0为了让计算机通过串口监控演示过程 */
|
||||
#ifdef DE_PRINTF
|
||||
printf( "Start @ChipID=%02X\n", (UINT16)CHIP_ID );
|
||||
#endif
|
||||
InitUSB_Device( );
|
||||
EA = 1;
|
||||
while ( 1 ) {
|
||||
i = getkey( );
|
||||
printf( "%c", (UINT8)i );
|
||||
if ( i >= '0' && i <= 'z' ) {
|
||||
memcpy( Ep1Buffer, (PUINT8C)(i-'0'), MAX_PACKET_SIZE ); /* 加载上传数据 */
|
||||
UEP1_T_LEN = i-'0' > 8 ? 8 : i-'0';
|
||||
UEP1_CTRL = UEP1_CTRL & ~ MASK_UEP_T_RES | UEP_T_RES_ACK;
|
||||
}
|
||||
}
|
||||
}
|
256
examples/USB/Host/USBHostHUB_KM.C
Normal file
256
examples/USB/Host/USBHostHUB_KM.C
Normal file
@ -0,0 +1,256 @@
|
||||
|
||||
/********************************** (C) COPYRIGHT *******************************
|
||||
* File Name : USBHostHUB_KM.C
|
||||
* Author : WCH
|
||||
* Version : V1.0
|
||||
* Date : 2017/01/20
|
||||
* Description :
|
||||
USB host example for CH554, start USB device under DP/DM and HP/HM port
|
||||
USB主机应用例子,初始化和枚举USB端口连接的设备,同时支持最多1个USB设备,支持一级外部HUB,
|
||||
可以操作USB键鼠和HUB,包含HID类命令处理
|
||||
如果需要操作U盘,请参考U_DISK文件夹下的例子
|
||||
支持简单USB打印机操作,没有处理USB打印机类命令
|
||||
*******************************************************************************/
|
||||
|
||||
#include "..\..\Public\CH554.H"
|
||||
#include "..\..\Public\Debug.H"
|
||||
#include "..\USB_LIB\USBHOST.H"
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
|
||||
#pragma NOAREGS
|
||||
|
||||
/*获取设备描述符*/
|
||||
UINT8C SetupGetDevDescr[] = { USB_REQ_TYP_IN, USB_GET_DESCRIPTOR, 0x00, USB_DESCR_TYP_DEVICE, 0x00, 0x00, sizeof( USB_DEV_DESCR ), 0x00 };
|
||||
|
||||
/*获取配置描述符*/
|
||||
UINT8C SetupGetCfgDescr[] = { USB_REQ_TYP_IN, USB_GET_DESCRIPTOR, 0x00, USB_DESCR_TYP_CONFIG, 0x00, 0x00, 0x04, 0x00 };
|
||||
|
||||
/*设置USB地址*/
|
||||
UINT8C SetupSetUsbAddr[] = { USB_REQ_TYP_OUT, USB_SET_ADDRESS, USB_DEVICE_ADDR, 0x00, 0x00, 0x00, 0x00, 0x00 };
|
||||
|
||||
/*设置USB配置*/
|
||||
UINT8C SetupSetUsbConfig[] = { USB_REQ_TYP_OUT, USB_SET_CONFIGURATION, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
|
||||
|
||||
/*设置USB接口配置*/
|
||||
UINT8C SetupSetUsbInterface[] = { USB_REQ_RECIP_INTERF, USB_SET_INTERFACE, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
|
||||
|
||||
/*清除端点STALL*/
|
||||
UINT8C SetupClrEndpStall[] = { USB_REQ_TYP_OUT | USB_REQ_RECIP_ENDP, USB_CLEAR_FEATURE, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
|
||||
|
||||
/*获取HUB描述符*/
|
||||
UINT8C SetupGetHubDescr[] = { HUB_GET_HUB_DESCRIPTOR, HUB_GET_DESCRIPTOR, 0x00, USB_DESCR_TYP_HUB, 0x00, 0x00, sizeof( USB_HUB_DESCR ), 0x00 };
|
||||
|
||||
/*获取HID设备报表描述符*/
|
||||
UINT8C SetupGetHIDDevReport[] = { 0x81, USB_GET_DESCRIPTOR, 0x00, USB_DESCR_TYP_REPORT, 0x00, 0x00, 0x41, 0x00 };
|
||||
|
||||
/*打印机类命令*/
|
||||
UINT8C XPrinterReport[] = { 0xA1, 0, 0x00, 0, 0x00, 0x00, 0xF1, 0x03 };
|
||||
|
||||
UINT8X UsbDevEndp0Size; //* USB设备的端点0的最大包尺寸 */
|
||||
UINT8X RxBuffer[ MAX_PACKET_SIZE ] _at_ 0x0000 ; // IN, must even address
|
||||
UINT8X TxBuffer[ MAX_PACKET_SIZE ] _at_ 0x0040 ; // OUT, must even address
|
||||
|
||||
UINT8 Set_Port = 0;
|
||||
|
||||
_RootHubDev xdata ThisUsbDev; //ROOT口
|
||||
_DevOnHubPort xdata DevOnHubPort[HUB_MAX_PORTS]; // 假定:不超过1个外部HUB,每个外部HUB不超过HUB_MAX_PORTS个端口(多了不管)
|
||||
|
||||
bit RootHubId; // 当前正在操作的root-hub端口号:0=HUB0,1=HUB1
|
||||
bit FoundNewDev;
|
||||
|
||||
main( )
|
||||
{
|
||||
UINT8 i, s, len, endp;
|
||||
UINT16 loc;
|
||||
CfgFsys( );
|
||||
mDelaymS(5); //修改主频,等待时钟稳定
|
||||
mInitSTDIO( ); //为了让计算机通过串口监控演示过程
|
||||
printf( "Start @ChipID=%02X\n", (UINT16)CHIP_ID );
|
||||
InitUSB_Host( );
|
||||
FoundNewDev = 0;
|
||||
printf( "Wait Device In\n" );
|
||||
while ( 1 )
|
||||
{
|
||||
s = ERR_SUCCESS;
|
||||
if ( UIF_DETECT ){ // 如果有USB主机检测中断则处理
|
||||
UIF_DETECT = 0; // 清中断标志
|
||||
s = AnalyzeRootHub( ); // 分析ROOT-HUB状态
|
||||
if ( s == ERR_USB_CONNECT ) FoundNewDev = 1;
|
||||
}
|
||||
if ( FoundNewDev ){ // 有新的USB设备插入
|
||||
FoundNewDev = 0;
|
||||
mDelaymS( 200 ); // 由于USB设备刚插入尚未稳定,故等待USB设备数百毫秒,消除插拔抖动
|
||||
s = EnumAllRootDevice( ); // 枚举所有ROOT-HUB端口的USB设备
|
||||
if ( s != ERR_SUCCESS ){
|
||||
printf( "EnumAllRootDev err = %02X\n", (UINT16)s );
|
||||
}
|
||||
}
|
||||
if ( RI == 0 ) continue;
|
||||
i = getkey( );
|
||||
printf( "%c", (UINT8)i );
|
||||
if ( i == 'E'){ // 每隔一段时间,通常是100mS到1000mS,对外部HUB的端口进行一下枚举,单片机有空时做
|
||||
s = EnumAllHubPort( ); // 枚举所有ROOT-HUB端口下外部HUB后的二级USB设备
|
||||
if ( s != ERR_SUCCESS ){ // 可能是HUB断开了
|
||||
printf( "EnumAllHubPort err = %02X\n", (UINT16)s );
|
||||
}
|
||||
}
|
||||
switch( i ){ // 模拟主观请求,对某USB设备进行操作
|
||||
case 'M': // 用定时模拟主观需求,需要操作鼠标
|
||||
loc = SearchTypeDevice( DEV_TYPE_MOUSE ); // 在ROOT-HUB以及外部HUB各端口上搜索指定类型的设备所在的端口号
|
||||
if ( loc != 0xFFFF ){ // 找到了,如果有两个MOUSE如何处理?
|
||||
printf( "Query Mouse @%04X\n", loc );
|
||||
i = (UINT8)( loc >> 8 );
|
||||
len = (UINT8)loc;
|
||||
SelectHubPort( len ); // 选择操作指定的ROOT-HUB端口,设置当前USB速度以及被操作设备的USB地址
|
||||
endp = len ? DevOnHubPort[len-1].GpVar : ThisUsbDev.GpVar; // 中断端点的地址,位7用于同步标志位
|
||||
if ( endp & USB_ENDP_ADDR_MASK ){ // 端点有效
|
||||
s = USBHostTransact( USB_PID_IN << 4 | endp & 0x7F, endp & 0x80 ? bUH_R_TOG | bUH_T_TOG : 0, 0 );// CH554传输事务,获取数据,NAK不重试
|
||||
if ( s == ERR_SUCCESS ){
|
||||
endp ^= 0x80; // 同步标志翻转
|
||||
if ( len ) DevOnHubPort[len-1].GpVar = endp; // 保存同步标志位
|
||||
else ThisUsbDev.GpVar = endp;
|
||||
len = USB_RX_LEN; // 接收到的数据长度
|
||||
if ( len ) {
|
||||
printf("Mouse data: ");
|
||||
for ( i = 0; i < len; i ++ ){
|
||||
printf("x%02X ",(UINT16)(RxBuffer[i]) );
|
||||
}
|
||||
printf("\n");
|
||||
}
|
||||
}
|
||||
else if ( s != ( USB_PID_NAK | ERR_USB_TRANSFER ) ) {
|
||||
printf("Mouse error %02x\n",(UINT16)s); // 可能是断开了
|
||||
}
|
||||
}
|
||||
else {
|
||||
printf("Mouse no interrupt endpoint\n");
|
||||
}
|
||||
SetUsbSpeed( 1 ); // 默认为全速
|
||||
}
|
||||
break;
|
||||
case 'K': // 用定时模拟主观需求,需要操作键盘
|
||||
loc = SearchTypeDevice( DEV_TYPE_KEYBOARD ); // 在ROOT-HUB以及外部HUB各端口上搜索指定类型的设备所在的端口号
|
||||
if ( loc != 0xFFFF ){ // 找到了,如果有两个KeyBoard如何处理?
|
||||
printf( "Query Keyboard @%04X\n", loc );
|
||||
i = (UINT8)( loc >> 8 );
|
||||
len = (UINT8)loc;
|
||||
SelectHubPort( len ); // 选择操作指定的ROOT-HUB端口,设置当前USB速度以及被操作设备的USB地址
|
||||
endp = len ? DevOnHubPort[len-1].GpVar : ThisUsbDev.GpVar; // 中断端点的地址,位7用于同步标志位
|
||||
printf("%02X ",endp);
|
||||
if ( endp & USB_ENDP_ADDR_MASK ){ // 端点有效
|
||||
s = USBHostTransact( USB_PID_IN << 4 | endp & 0x7F, endp & 0x80 ? bUH_R_TOG | bUH_T_TOG : 0, 0 );// CH554传输事务,获取数据,NAK不重试
|
||||
if ( s == ERR_SUCCESS ){
|
||||
endp ^= 0x80; // 同步标志翻转
|
||||
if ( len ) DevOnHubPort[len-1].GpVar = endp; // 保存同步标志位
|
||||
else ThisUsbDev.GpVar = endp;
|
||||
len = USB_RX_LEN; // 接收到的数据长度
|
||||
if ( len ){
|
||||
SETorOFFNumLock(RxBuffer);
|
||||
printf("keyboard data: ");
|
||||
for ( i = 0; i < len; i ++ ){
|
||||
printf("x%02X ",(UINT16)(RxBuffer[i]) );
|
||||
}
|
||||
printf("\n");
|
||||
}
|
||||
}
|
||||
else if ( s != ( USB_PID_NAK | ERR_USB_TRANSFER ) ){
|
||||
printf("keyboard error %02x\n",(UINT16)s); // 可能是断开了
|
||||
}
|
||||
}
|
||||
else{
|
||||
printf("keyboard no interrupt endpoint\n");
|
||||
}
|
||||
SetUsbSpeed( 1 ); // 默认为全速
|
||||
}
|
||||
break;
|
||||
case 'H': //操作HUB
|
||||
loc = SearchTypeDevice( DEV_TYPE_KEYBOARD ); // 在ROOT-HUB以及外部HUB各端口上搜索指定类型的设备所在的端口号
|
||||
if ( loc != 0xFFFF ){ // 找到了,如果有两个KeyBoard如何处理?
|
||||
printf( "Query Keyboard @%04X\n", loc );
|
||||
i = (UINT8)( loc >> 8 );
|
||||
len = (UINT8)loc;
|
||||
SelectHubPort( len ); // 选择操作指定的ROOT-HUB端口,设置当前USB速度以及被操作设备的USB地址
|
||||
endp = len ? DevOnHubPort[len-1].GpVar : ThisUsbDev.GpVar; // 中断端点的地址,位7用于同步标志位
|
||||
printf("%02X ",endp);
|
||||
if ( endp & USB_ENDP_ADDR_MASK ){ // 端点有效
|
||||
s = USBHostTransact( USB_PID_IN << 4 | endp & 0x7F, endp & 0x80 ? bUH_R_TOG | bUH_T_TOG : 0, 0 );// CH554传输事务,获取数据,NAK不重试
|
||||
if ( s == ERR_SUCCESS ){
|
||||
endp ^= 0x80; // 同步标志翻转
|
||||
if ( len ) DevOnHubPort[len-1].GpVar = endp; // 保存同步标志位
|
||||
else ThisUsbDev.GpVar = endp;
|
||||
len = USB_RX_LEN; // 接收到的数据长度
|
||||
if ( len ) {
|
||||
//SETorOFFNumLock(RxBuffer);
|
||||
printf("keyboard data: ");
|
||||
for ( i = 0; i < len; i ++ ){
|
||||
printf("x%02X ",(UINT16)(RxBuffer[i]) );
|
||||
}
|
||||
printf("\n");
|
||||
}
|
||||
}
|
||||
else if ( s != ( USB_PID_NAK | ERR_USB_TRANSFER ) ){
|
||||
printf("keyboard error %02x\n",(UINT16)s); // 可能是断开了
|
||||
}
|
||||
}
|
||||
else printf("keyboard no interrupt endpoint\n");
|
||||
}
|
||||
for(i=0; i<2; i++) {
|
||||
if((ThisUsbDev.DeviceStatus == ROOT_DEV_SUCCESS)&&(ThisUsbDev.DeviceType == USB_DEV_CLASS_HUB)){
|
||||
SelectHubPort( 0 ); // 选择操作指定的ROOT-HUB端口,设置当前USB速度以及被操作设备的USB地址
|
||||
endp = ThisUsbDev.GpVar1; // 中断端点的地址,位7用于同步标志位
|
||||
if ( endp & USB_ENDP_ADDR_MASK ){ // 端点有效
|
||||
s = USBHostTransact( USB_PID_IN << 4 | endp & 0x7F, endp & 0x80 ? bUH_R_TOG | bUH_T_TOG : 0, 0 );// CH554传输事务,获取数据,NAK不重试
|
||||
if ( s == ERR_SUCCESS ) {
|
||||
endp ^= 0x80; // 同步标志翻转
|
||||
ThisUsbDev.GpVar1 = endp; // 保存同步标志位
|
||||
len = USB_RX_LEN; // 接收到的数据长度
|
||||
if ( len ){
|
||||
EnumHubPort();
|
||||
for ( i = 0; i < len; i ++ ){
|
||||
printf("x%02X ",(UINT16)(RxBuffer[i]) );
|
||||
}
|
||||
printf("\n");
|
||||
}
|
||||
}
|
||||
else if ( s != ( USB_PID_NAK | ERR_USB_TRANSFER ) ) {
|
||||
printf("HUB error %02x\n",(UINT16)s); // 可能是断开了
|
||||
}
|
||||
}
|
||||
else printf("HUB %02d no interrupt endpoint\n",i);
|
||||
}
|
||||
else printf("ROOTHUB %02d not HUB\n",i);
|
||||
}
|
||||
break;
|
||||
case 'P': //操作USB打印机
|
||||
if(TIN0 == 0){ //P10为低,开始打印
|
||||
memset(TxBuffer,0,sizeof(TxBuffer));
|
||||
TxBuffer[0]=0x1B;TxBuffer[1]=0x40;TxBuffer[2]=0x1D;TxBuffer[3]=0x55;TxBuffer[4]=0x42;TxBuffer[5]=0x02;TxBuffer[6]=0x18;TxBuffer[7]=0x1D;
|
||||
TxBuffer[8]=0x76;TxBuffer[9]=0x30;TxBuffer[10]=0x00;TxBuffer[11]=0x30;TxBuffer[12]=0x00;TxBuffer[13]=0x18;
|
||||
loc = SearchTypeDevice( USB_DEV_CLASS_PRINTER ); // 在ROOT-HUB以及外部HUB各端口上搜索指定类型的设备所在的端口号
|
||||
if ( loc != 0xFFFF ){ // 找到了,如果有两个打印机如何处理?
|
||||
printf( "Query Printer @%04X\n", loc );
|
||||
i = (UINT8)( loc >> 8 );
|
||||
len = (UINT8)loc;
|
||||
SelectHubPort( len ); // 选择操作指定的ROOT-HUB端口,设置当前USB速度以及被操作设备的USB地址
|
||||
endp = len ? DevOnHubPort[len-1].GpVar : ThisUsbDev.GpVar; // 端点的地址,位7用于同步标志位
|
||||
printf("%02X ",endp);
|
||||
if ( endp & USB_ENDP_ADDR_MASK ){ // 端点有效
|
||||
UH_TX_LEN = 64; // 默认无数据故状态阶段为IN
|
||||
s = USBHostTransact( USB_PID_OUT << 4 | endp & 0x7F, endp & 0x80 ? bUH_R_TOG | bUH_T_TOG : 0, 0xffff );// CH554传输事务,获取数据,NAK重试
|
||||
if ( s == ERR_SUCCESS ){
|
||||
endp ^= 0x80; // 同步标志翻转
|
||||
memset(TxBuffer,0,sizeof(TxBuffer));
|
||||
UH_TX_LEN = 64; // 默认无数据故状态阶段为IN
|
||||
s = USBHostTransact( USB_PID_OUT << 4 | endp & 0x7F, endp & 0x80 ? bUH_R_TOG | bUH_T_TOG : 0, 0xffff );// CH554传输事务,获取数据,NAK重试
|
||||
}
|
||||
else if ( s != ( USB_PID_NAK | ERR_USB_TRANSFER ) ) printf("Printer error %02x\n",(UINT16)s); // 可能是断开了
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
0
.gitignore → keil/.gitignore
vendored
0
.gitignore → keil/.gitignore
vendored
Loading…
Reference in New Issue
Block a user