完善资料让更多小伙伴认识你,还能领取20积分哦, 立即完善>
STM32F4 PS2手柄移植HAL库,利用Cube进行设置
请按以下步骤进行 配置GPIO D0 input D1 output D2 output D3 output 详见下图 然后配置工程文件生成格式 生成MDK文件并用keil打开 下载下面链接的文件并开始移植 将文件内的delay.c sys.c ps2.c misc.c 进行移植 移植过程如下: 1.将delay.c sys.c ps2.c misc.c 四个文件放置在cube生成的MDK-ARM文件夹内; 2…将delay.h sys.h ps2.h misc.h 四个文件放置在cube生成的Inc文件夹 3. 在keil里面填入这几个.c文件 4.编译即可通过 code: // ps2.c #include "stm32f4xx_hal.h" #include "misc.h" #include "ps2.h" #include "gpio.h" #define DELAY_TIME delay_us(5); volatile int PS2_LX,PS2_LY,PS2_RX,PS2_RY,PS2_KEY; // uint16_t Handkey; uint8_t Comd[2]={0x01,0x42}; //开始命令。请求数据 uint8_t Data[9]={0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00};//数据存储数组 uint16_t MASK[]={ PSB_SELECT, PSB_L3, PSB_R3 , PSB_START, PSB_PAD_UP, PSB_PAD_RIGHT, PSB_PAD_DOWN, PSB_PAD_LEFT, PSB_L2, PSB_R2, PSB_L1, PSB_R1 , PSB_GREEN, PSB_RED, PSB_BLUE, PSB_PINK }; //按键值与按键明 //向手柄发送命令 void PS2_Cmd(uint8_t CMD) { volatile uint16_t ref=0x01; Data[1] = 0; for(ref=0x01;ref<0x0100;ref<<=1) { if(ref&CMD) { DO_H; //输出一位控制位 } else DO_L; CLK_H; //时钟拉高 DELAY_TIME; CLK_L; DELAY_TIME; CLK_H; if(DI) Data[1] = ref|Data[1]; } delay_us(16); } //判断是否为红灯模式 0x41=模拟绿灯 0x73=模拟红灯 //返回值;0,红灯模式 // 其他,其他模式 uint8_t PS2_RedLight(void) { CS_L; PS2_Cmd(Comd[0]); //开始命令 PS2_Cmd(Comd[1]); //请求数据 CS_H; if( Data[1] == 0X73) return 0 ; else return 1; } //读取手柄数据 void PS2_ReadData(void) { volatile uint8_t byte=0; volatile uint16_t ref=0x01; CS_L; PS2_Cmd(Comd[0]); //开始命令 PS2_Cmd(Comd[1]); //请求数据 for(byte=2;byte<9;byte++) //开始接受数据 { for(ref=0x01;ref<0x100;ref<<=1) { CLK_H; DELAY_TIME; CLK_L; DELAY_TIME; CLK_H; if(DI) Data[byte] = ref|Data[byte]; } delay_us(16); } CS_H; } //对读出来的PS2的数据进行处理 只处理了按键部分 默认数据是红灯模式 只有一个按键按下时 //按下为0, 未按下为1 uint8_t PS2_DataKey() { uint8_t index; PS2_ClearData(); PS2_ReadData(); Handkey=(Data[4]<<8)|Data[3]; //这是16个按键 按下为0, 未按下为1 for(index=0;index<16;index++) { if((Handkey&(1<<(MASK[index]-1)))==0) return index+1; } return 0; //没有任何按键按下 } //得到一个摇杆的模拟量 范围0~256 uint8_t PS2_AnologData(uint8_t button) { return Data[button]; } //清除数据缓冲区 void PS2_ClearData() { uint8_t a; for(a=0;a<9;a++) Data[a]=0x00; } //void delay_init(uint8_t SYSCLK) //{ // SysTick->CTRL&=0xfffffffb;//bit2清空,选择外部时钟 HCLK/8 // fac_us=SYSCLK/8; //} //void delay_us(uint32_t nus) //{ // uint32_t temp; // SysTick->LOAD=nus*fac_us; //时间加载 // SysTick->VAL=0x00; //清空计数器 // SysTick->CTRL=0x01 ; //开始倒数 // do // { // temp=SysTick->CTRL; // } // while(temp&0x01&&!(temp&(1<<16)));//等待时间到达 // SysTick->CTRL=0x00; //关闭计数器 // SysTick->VAL =0X00; //清空计数器 //} //short poll void PS2_ShortPoll(void) { CS_L; delay_us(16); PS2_Cmd(0x01); PS2_Cmd(0x42); PS2_Cmd(0X00); PS2_Cmd(0x00); PS2_Cmd(0x00); CS_H; delay_us(16); } //进入设置 void PS2_EnterConfing(void) { CS_L; delay_us(16); PS2_Cmd(0x01); PS2_Cmd(0x43); PS2_Cmd(0X00); PS2_Cmd(0x01); PS2_Cmd(0x00); PS2_Cmd(0X00); PS2_Cmd(0X00); PS2_Cmd(0X00); PS2_Cmd(0X00); CS_H; delay_us(16); } //发送模式设置 void PS2_TurnOnAnalogMode(void) { CS_L; PS2_Cmd(0x01); PS2_Cmd(0x44); PS2_Cmd(0X00); PS2_Cmd(0x01); //analog=0x01;digital=0x00 软件设置发送模式 PS2_Cmd(0x03); //Ox03锁存设置,即不可通过按键“MODE”设置模式。 //0xEE不锁存软件设置,可通过按键“MODE”设置模式。 PS2_Cmd(0X00); PS2_Cmd(0X00); PS2_Cmd(0X00); PS2_Cmd(0X00); CS_H; delay_us(16); } //振动设置 void PS2_VibrationMode(void) { CS_L; delay_us(16); PS2_Cmd(0x01); PS2_Cmd(0x4D); PS2_Cmd(0X00); PS2_Cmd(0x00); PS2_Cmd(0X01); CS_H; delay_us(16); } //完成并保存配置 void PS2_ExitConfing(void) { CS_L; delay_us(16); PS2_Cmd(0x01); PS2_Cmd(0x43); PS2_Cmd(0X00); PS2_Cmd(0x00); PS2_Cmd(0x5A); PS2_Cmd(0x5A); PS2_Cmd(0x5A); PS2_Cmd(0x5A); PS2_Cmd(0x5A); CS_H; delay_us(16); } //手柄配置初始化 void PS2_SetInit(void) { PS2_ShortPoll(); PS2_ShortPoll(); PS2_ShortPoll(); PS2_EnterConfing(); //进入配置模式 PS2_TurnOnAnalogMode(); //“红绿灯”配置模式,并选择是否保存 //PS2_VibrationMode(); //开启震动模式 PS2_ExitConfing(); //完成并保存配置 } /****************************************************** Function: void PS2_Vibration(u8 motor1, u8 motor2) Description: 手柄震动函数, Calls: void PS2_Cmd(u8 CMD); Input: motor1:右侧小震动电机 0x00关,其他开 motor2:左侧大震动电机 0x40~0xFF 电机开,值越大 震动越大 ******************************************************/ void PS2_Vibration(uint8_t motor1, uint8_t motor2) { CS_L; delay_us(16); PS2_Cmd(0x01); //开始命令 PS2_Cmd(0x42); //请求数据 PS2_Cmd(0X00); PS2_Cmd(motor1); PS2_Cmd(motor2); PS2_Cmd(0X00); PS2_Cmd(0X00); PS2_Cmd(0X00); PS2_Cmd(0X00); CS_H; delay_us(16); } //读取手柄信息 void PS2_Receive (void) { PS2_LX=PS2_AnologData(PSS_LX); PS2_LY=PS2_AnologData(PSS_LY); PS2_RX=PS2_AnologData(PSS_RX); PS2_RY=PS2_AnologData(PSS_RY); PS2_KEY=PS2_DataKey(); } // ps2.h #ifndef __PS2_H__ #define __PS2_H__ #include "stm32f4xx_hal.h" #include "sys.h" #define DI PDin(0) #define DO_H PDout(1)=1 #define DO_L PDout(1)=0 #define CS_H PDout(2)=1 #define CS_L PDout(2)=0 #define CLK_H PDout(3)=1 #define CLK_L PDout(3)=0 //These are our button constants #define PSB_SELECT 1 #define PSB_L3 2 #define PSB_R3 3 #define PSB_START 4 #define PSB_PAD_UP 5 #define PSB_PAD_RIGHT 6 #define PSB_PAD_DOWN 7 #define PSB_PAD_LEFT 8 #define PSB_L2 9 #define PSB_R2 10 #define PSB_L1 11 #define PSB_R1 12 #define PSB_GREEN 13 #define PSB_RED 14 #define PSB_BLUE 15 #define PSB_PINK 16 #define PSB_TRIANGLE 13 #define PSB_CIRCLE 14 #define PSB_CROSS 15 #define PSB_SQUARE 26 //These are stick values #define PSS_RX 5 //右摇杆X轴数据 #define PSS_RY 6 #define PSS_LX 7 #define PSS_LY 8 extern uint8_t Data[9]; extern uint16_t MASK[16]; extern uint16_t Handkey; void PS2_Init(void); uint8_t PS2_RedLight(void);//判断是否为红灯模式 void PS2_ReadData(void); void PS2_Cmd(uint8_t CMD); // uint8_t PS2_DataKey(void); //键值读取 uint8_t PS2_AnologData(uint8_t button); //得到一个摇杆的模拟量 void PS2_ClearData(void); //清除数据缓冲区 void delay_init(uint8_t SYSCLK); void delay_us(uint32_t nus); void PS2_ShortPoll(void);//short poll void PS2_EnterConfing(void);//进入设置 void PS2_TurnOnAnalogMode(void);//保存并完成设置 void PS2_VibrationMode(void); void PS2_ExitConfing(void);//保存并完成设置 void PS2_SetInit(void);//手柄设置初始化 void PS2_Vibration(uint8_t motor1 ,uint8_t motor2); #endif ; // sys.c #include "sys.h" // //******************************************************************************** //修改说明 //无 // //THUMB指令不支持汇编内联 //采用如下方法实现执行汇编指令WFI __asm void WFI_SET(void) { WFI; } //关闭所有中断(但是不包括fault和NMI中断) __asm void INTX_DISABLE(void) { CPSID I BX LR } //开启所有中断 __asm void INTX_ENABLE(void) { CPSIE I BX LR } //设置栈顶地址 //addr:栈顶地址 __asm void MSR_MSP(uint32_t addr) { MSR MSP, r0 //set Main Stack value BX r14 } // ps2.h #ifndef __SYS_H #define __SYS_H #include "stm32f4xx.h" #include "delay.h" #include "ps2.h" #define SYSTEM_SUPPORT_OS 0 //定义系统文件夹是否支持UCOS extern volatile int PS2_LX,PS2_LY,PS2_RX,PS2_RY,PS2_KEY; //位带操作,实现51类似的GPIO控制功能 //具体实现思想,参考< //IO口操作宏定义 #define BITBAND(addr, bitnum) ((addr & 0xF0000000)+0x2000000+((addr &0xFFFFF)<<5)+(bitnum<<2)) #define MEM_ADDR(addr) *((volatile unsigned long *)(addr)) #define BIT_ADDR(addr, bitnum) MEM_ADDR(BITBAND(addr, bitnum)) //IO口地址映射 #define GPIOA_ODR_Addr (GPIOA_BASE+20) //0x40020014 #define GPIOB_ODR_Addr (GPIOB_BASE+20) //0x40020414 #define GPIOC_ODR_Addr (GPIOC_BASE+20) //0x40020814 #define GPIOD_ODR_Addr (GPIOD_BASE+20) //0x40020C14 #define GPIOE_ODR_Addr (GPIOE_BASE+20) //0x40021014 #define GPIOF_ODR_Addr (GPIOF_BASE+20) //0x40021414 #define GPIOG_ODR_Addr (GPIOG_BASE+20) //0x40021814 #define GPIOH_ODR_Addr (GPIOH_BASE+20) //0x40021C14 #define GPIOI_ODR_Addr (GPIOI_BASE+20) //0x40022014 #define GPIOA_IDR_Addr (GPIOA_BASE+16) //0x40020010 #define GPIOB_IDR_Addr (GPIOB_BASE+16) //0x40020410 #define GPIOC_IDR_Addr (GPIOC_BASE+16) //0x40020810 #define GPIOD_IDR_Addr (GPIOD_BASE+16) //0x40020C10 #define GPIOE_IDR_Addr (GPIOE_BASE+16) //0x40021010 #define GPIOF_IDR_Addr (GPIOF_BASE+16) //0x40021410 #define GPIOG_IDR_Addr (GPIOG_BASE+16) //0x40021810 #define GPIOH_IDR_Addr (GPIOH_BASE+16) //0x40021C10 #define GPIOI_IDR_Addr (GPIOI_BASE+16) //0x40022010 拉姆轮的底盘代码 |
|
|
|
//
//IO口操作,只对单一的IO口! //确保n的值小于16! #define PAout(n) BIT_ADDR(GPIOA_ODR_Addr,n) //输出 #define PAin(n) BIT_ADDR(GPIOA_IDR_Addr,n) //输入 #define PBout(n) BIT_ADDR(GPIOB_ODR_Addr,n) //输出 #define PBin(n) BIT_ADDR(GPIOB_IDR_Addr,n) //输入 #define PCout(n) BIT_ADDR(GPIOC_ODR_Addr,n) //输出 #define PCin(n) BIT_ADDR(GPIOC_IDR_Addr,n) //输入 #define PDout(n) BIT_ADDR(GPIOD_ODR_Addr,n) //输出 #define PDin(n) BIT_ADDR(GPIOD_IDR_Addr,n) //输入 #define PEout(n) BIT_ADDR(GPIOE_ODR_Addr,n) //输出 #define PEin(n) BIT_ADDR(GPIOE_IDR_Addr,n) //输入 #define PFout(n) BIT_ADDR(GPIOF_ODR_Addr,n) //输出 #define PFin(n) BIT_ADDR(GPIOF_IDR_Addr,n) //输入 #define PGout(n) BIT_ADDR(GPIOG_ODR_Addr,n) //输出 #define PGin(n) BIT_ADDR(GPIOG_IDR_Addr,n) //输入 #define PHout(n) BIT_ADDR(GPIOH_ODR_Addr,n) //输出 #define PHin(n) BIT_ADDR(GPIOH_IDR_Addr,n) //输入 #define PIout(n) BIT_ADDR(GPIOI_ODR_Addr,n) //输出 #define PIin(n) BIT_ADDR(GPIOI_IDR_Addr,n) //输入 //以下为汇编函数 void WFI_SET(void); //执行WFI指令 void INTX_DISABLE(void);//关闭所有中断 void INTX_ENABLE(void); //开启所有中断 void MSR_MSP(uint32_t addr); //设置堆栈地址 #include #include #include #include #include #include #endif // misc.c #include "stm32f4xx_hal.h" #include "misc.h" /* Cortex M3 Delay functions */ static __IO uint32_t TimingDelay = 0; void Delay(__IO uint32_t nTime) { TimingDelay = nTime; while(TimingDelay != 0); } void TimingDelay_Decrement(void) { if (TimingDelay != 0x00) { TimingDelay--; } } /* STM32F10x TIM helper functions */ TIM_Direction TIM_ReadDirection(TIM_TypeDef* TIMx) { return (TIMx->CR1 & TIM_CR1_DIR); } void SysTick_CLKSourceConfig(uint32_t SysTick_CLKSource) { /* Check the parameters */ assert_param(IS_SYSTICK_CLK_SOURCE(SysTick_CLKSource)); if (SysTick_CLKSource == SysTick_CLKSource_HCLK) { SysTick->CTRL |= SysTick_CLKSource_HCLK; } else { SysTick->CTRL &= SysTick_CLKSource_HCLK_Div8; } } // misc.h #ifndef __STM32F10X_MISC_H__ #define __STM32F10X_MISC_H__ #include "stm32f4xx_hal.h" /* Cortex M3 bit banding macros */ #define BITBAND_SRAM_REF 0x20000000 #define BITBAND_SRAM_BASE 0x22000000 #define BITBAND_SRAM(ptr,n) ((volatile uint32_t*)((BITBAND_SRAM_BASE + (((uint32_t)ptr)-BITBAND_SRAM_REF)*32 + (n*4)))) #define BITBAND_PERI_REF 0x40000000 #define BITBAND_PERI_BASE 0x42000000 #define BITBAND_PERI(ptr,n) ((volatile uint32_t*)((BITBAND_PERI_BASE + (((uint32_t)ptr)-BITBAND_PERI_REF)*32 + (n*4)))) #define SysTick_CLKSource_HCLK_Div8 ((uint32_t)0xFFFFFFFB) #define SysTick_CLKSource_HCLK ((uint32_t)0x00000004) /* Cortex M3 Delay functions */ void TimingDelay_Decrement(void); void Delay(__IO uint32_t nTime); void SysTick_CLKSourceConfig(uint32_t SysTick_CLKSource); /* STM32F10x GPIO helper functions */ #define GPIO_ToggleBit(port, pin) GPIO_WriteBit(port, pin, (BitAction) (1-GPIO_ReadOutputDataBit(port, pin))) /* STM32F10x TIM helper functions */ typedef enum {UP = 0, DOWN = 1} TIM_Direction; TIM_Direction TIM_ReadDirection(TIM_TypeDef* TIMx); #endif // delay.c #include "delay.h" #include "misc.h" #include "sys.h" // //如果使用OS,则包括下面的头文件(以ucos为例)即可. #if SYSTEM_SUPPORT_OS #include "includes.h" //支持OS时,使用 #endif // static uint8_t fac_us=0; //us延时倍乘数 static uint16_t fac_ms=0; //ms延时倍乘数,在os下,代表每个节拍的ms数 #if SYSTEM_SUPPORT_OS //如果SYSTEM_SUPPORT_OS定义了,说明要支持OS了(不限于UCOS). #ifdef OS_CRITICAL_METHOD //OS_CRITICAL_METHOD定义了,说明要支持UCOSII #define delay_osrunning OSRunning //OS是否运行标记,0,不运行;1,在运行 #define delay_ostickspersec OS_TICKS_PER_SEC //OS时钟节拍,即每秒调度次数 #define delay_osintnesting OSIntNesting //中断嵌套级别,即中断嵌套次数 #endif //支持UCOSIII #ifdef CPU_CFG_CRITICAL_METHOD //CPU_CFG_CRITICAL_METHOD定义了,说明要支持UCOSIII #define delay_osrunning OSRunning //OS是否运行标记,0,不运行;1,在运行 #define delay_ostickspersec OSCfg_TickRate_Hz //OS时钟节拍,即每秒调度次数 #define delay_osintnesting OSIntNestingCtr //中断嵌套级别,即中断嵌套次数 #endif //us级延时时,关闭任务调度(防止打断us级延迟) void delay_osschedlock(void) { #ifdef CPU_CFG_CRITICAL_METHOD //使用UCOSIII OS_ERR err; OSSchedLock(&err); //UCOSIII的方式,禁止调度,防止打断us延时 #else //否则UCOSII OSSchedLock(); //UCOSII的方式,禁止调度,防止打断us延时 #endif } //us级延时时,恢复任务调度 void delay_osschedunlock(void) { #ifdef CPU_CFG_CRITICAL_METHOD //使用UCOSIII OS_ERR err; OSSchedUnlock(&err); //UCOSIII的方式,恢复调度 #else //否则UCOSII OSSchedUnlock(); //UCOSII的方式,恢复调度 #endif } //调用OS自带的延时函数延时 //ticks:延时的节拍数 void delay_ostimedly(u32 ticks) { #ifdef CPU_CFG_CRITICAL_METHOD OS_ERR err; OSTimeDly(ticks,OS_OPT_TIME_PERIODIC,&err);//UCOSIII延时采用周期模式 #else OSTimeDly(ticks); //UCOSII延时 #endif } //systick中断服务函数,使用OS时用到 void SysTick_Handler(void) { if(delay_osrunning==1) //OS开始跑了,才执行正常的调度处理 { OSIntEnter(); //进入中断 OSTimeTick(); //调用ucos的时钟服务程序 OSIntExit(); //触发任务切换软中断 } } #endif //初始化延迟函数 //当使用OS的时候,此函数会初始化OS的时钟节拍 //SYSTICK的时钟固定为AHB时钟的1/8 //SYSCLK:系统时钟频率 void delay_init(uint8_t SYSCLK) { #if SYSTEM_SUPPORT_OS //如果需要支持OS. u32 reload; #endif SysTick_CLKSourceConfig(SysTick_CLKSource_HCLK_Div8); fac_us=SYSCLK/8; //不论是否使用OS,fac_us都需要使用 #if SYSTEM_SUPPORT_OS //如果需要支持OS. reload=SYSCLK/8; //每秒钟的计数次数 单位为M reload*=1000000/delay_ostickspersec; //根据delay_ostickspersec设定溢出时间 //reload为24位寄存器,最大值:16777216,在168M下,约合0.7989s左右 fac_ms=1000/delay_ostickspersec; //代表OS可以延时的最少单位 SysTick->CTRL|=SysTick_CTRL_TICKINT_Msk; //开启SYSTICK中断 SysTick->LOAD=reload; //每1/delay_ostickspersec秒中断一次 SysTick->CTRL|=SysTick_CTRL_ENABLE_Msk; //开启SYSTICK #else fac_ms=(uint16_t)fac_us*1000; //非OS下,代表每个ms需要的systick时钟数 #endif } #if SYSTEM_SUPPORT_OS //如果需要支持OS. //延时nus //nus:要延时的us数. //nus:0~204522252(最大值即2^32/fac_us@fac_us=21) void delay_us(u32 nus) { u32 ticks; u32 told,tnow,tcnt=0; u32 reload=SysTick->LOAD; //LOAD的值 ticks=nus*fac_us; //需要的节拍数 delay_osschedlock(); //阻止OS调度,防止打断us延时 told=SysTick->VAL; //刚进入时的计数器值 while(1) { tnow=SysTick->VAL; if(tnow!=told) { if(tnow told=tnow; if(tcnt>=ticks)break; //时间超过/等于要延迟的时间,则退出. } }; delay_osschedunlock(); //恢复OS调度 } //延时nms //nms:要延时的ms数 //nms:0~65535 void delay_ms(u16 nms) { if(delay_osrunning&&delay_osintnesting==0)//如果OS已经在跑了,并且不是在中断里面(中断里面不能任务调度) { if(nms>=fac_ms) //延时的时间大于OS的最少时间周期 { delay_ostimedly(nms/fac_ms); //OS延时 } nms%=fac_ms; //OS已经无法提供这么小的延时了,采用普通方式延时 } delay_us((u32)(nms*1000)); //普通方式延时 } #else //不用ucos时 //延时nus //nus为要延时的us数. //注意:nus的值,不要大于798915us(最大值即2^24/fac_us@fac_us=21) void delay_us(uint32_t nus) { uint32_t temp; SysTick->LOAD=nus*fac_us; //时间加载 SysTick->VAL=0x00; //清空计数器 SysTick->CTRL|=SysTick_CTRL_ENABLE_Msk ; //开始倒数 do { temp=SysTick->CTRL; }while((temp&0x01)&&!(temp&(1<<16))); //等待时间到达 SysTick->CTRL&=~SysTick_CTRL_ENABLE_Msk; //关闭计数器 SysTick->VAL =0X00; //清空计数器 } //延时nms //注意nms的范围 //SysTick->LOAD为24位寄存器,所以,最大延时为: //nms<=0xffffff*8*1000/SYSCLK //SYSCLK单位为Hz,nms单位为ms //对168M条件下,nms<=798ms void delay_xms(uint16_t nms) { uint32_t temp; SysTick->LOAD=(uint32_t)nms*fac_ms; //时间加载(SysTick->LOAD为24bit) SysTick->VAL =0x00; //清空计数器 SysTick->CTRL|=SysTick_CTRL_ENABLE_Msk ; //开始倒数 do { temp=SysTick->CTRL; }while((temp&0x01)&&!(temp&(1<<16))); //等待时间到达 SysTick->CTRL&=~SysTick_CTRL_ENABLE_Msk; //关闭计数器 SysTick->VAL =0X00; //清空计数器 } //延时nms //nms:0~65535 void delay_ms(uint16_t nms) { uint8_t repeat=nms/540; //这里用540,是考虑到某些客户可能超频使用, //比如超频到248M的时候,delay_xms最大只能延时541ms左右了 uint16_t remain=nms%540; while(repeat) { delay_xms(540); repeat--; } if(remain)delay_xms(remain); } #endif // delay.h #ifndef __DELAY_H #define __DELAY_H #include "misc.h" // void delay_init(uint8_t SYSCLK); void delay_ms(uint16_t nms); void delay_us(uint32_t nus); #endif // main.c /* USER CODE BEGIN Header */ /** ****************************************************************************** * @file : main.c * @brief : Main program body ****************************************************************************** * @attention * *
* All rights reserved. |
|
|
|
只有小组成员才能发言,加入小组>>
调试STM32H750的FMC总线读写PSRAM遇到的问题求解?
1771 浏览 1 评论
X-NUCLEO-IHM08M1板文档中输出电流为15Arms,15Arms是怎么得出来的呢?
1619 浏览 1 评论
1070 浏览 2 评论
STM32F030F4 HSI时钟温度测试过不去是怎么回事?
724 浏览 2 评论
ST25R3916能否对ISO15693的标签芯片进行分区域写密码?
1673 浏览 2 评论
1935浏览 9评论
STM32仿真器是选择ST-LINK还是选择J-LINK?各有什么优势啊?
728浏览 4评论
STM32F0_TIM2输出pwm2后OLED变暗或者系统重启是怎么回事?
567浏览 3评论
593浏览 3评论
stm32cubemx生成mdk-arm v4项目文件无法打开是什么原因导致的?
551浏览 3评论
小黑屋| 手机版| Archiver| 电子发烧友 ( 湘ICP备2023018690号 )
GMT+8, 2024-12-22 10:59 , Processed in 0.708912 second(s), Total 46, Slave 40 queries .
Powered by 电子发烧友网
© 2015 bbs.elecfans.com
关注我们的微信
下载发烧友APP
电子发烧友观察
版权所有 © 湖南华秋数字科技有限公司
电子发烧友 (电路图) 湘公网安备 43011202000918 号 电信与信息服务业务经营许可证:合字B2-20210191 工商网监 湘ICP备2023018690号