Skip to content

superleo111/electron_design

Repository files navigation

小车四路电机速度闭环&2023电赛H题不完整final

整体功能实现:基本的stm32的串口(蓝牙)、中断(串口中断、定时溢出\比较中断、外部中断)、定时器(编码器、pwm波输出)的实现、PID控制、ADC、FFT快速傅里叶分解、读引脚高低电平的功能实现工程里面都有,要用的话仔细看注释!!!

要用什么就先看main函数,初始化,看看allheader有没有要改的,调试就多写几个printf。资源可能冲突因此要对整个工程这个工程用keil5编译,输出hex在OBJ文件里面。

小车四路电机速度闭环

这个工程主要有两个部分,一个是备赛的时候准备的四轮小车闭环,用的电机是520带磁编码器的电机,驱动板用的是AT8236双路电机驱动模块,这个模块上面有霍尔信号通道,直接接到单片机编码器TIM的输入即可,可以通过串口输入1 xxxx xxxx xxxx xxxx,转换为四个轮子的速度给定值,一般给个0100表示正转,-100表示反转,一般给100到300跑的都很准,如果是0 0000 0000 0000 0000直接不计算,关掉pwm,这样避免停下来的时候轮子抖动,抖动是因为速度接近0的时候编码器反馈不稳定或者轮子有摩擦。

2023电赛H题 信号分离装置

第二个部分是2023年电赛国赛H题,虽然说是大失败,但是想法和一些东西都是有的,分享给下一届备赛的同学了。

首先是C信号采集1024个数据,丢给fft,用的是stm32官方库函数,然后得到频谱图,就是幅频特性图,然后因为20kHz到100kHz,分辨率为5kHz,因此可以用遍历的方法,把5和其倍数频率附近3个点的幅值相加,大于某个阈值判定为主峰,两个主峰比较好找。正弦波就一个主峰,三角波基频、三倍频、五倍频都有,但是可能出现30k三角,90k正弦的情况,因此判断三角波可以直接找五倍频,但是这个阈值要合理设置,炼丹一下就找出来了,具体逻辑看fft函数

接着用dds合成波形就可以输出,但是这个题最大的难点在于A和A'同频稳定显示,因为生成波形A'用的是单片机的晶振,A是信号发生器的晶振,因此必定出现“同频率不同源”,本质还是频率微小差异,可能就是小数点后几位的频率差异,在示波器上都可以看出来。

解决办法就是就是控制dds的时钟,dds时钟是由单片机TIM给的,这个pwm波精确给定我们没有做出来,但是看到有的组做出来的,想法就是用主从时钟、定时器级联等方法,精确控制pwm波的数量,想法有了但是主从时钟没有搞明白(裂开),最后没有做出来

那怎么自动调?得知道输出的时钟和C信号快了还是慢了,想法是对C进行施密特触发器整型成矩形波,对于整型得到的信号管脚上升沿外部中断,对C周期,C反正最低5kHz,进行测量,但也没有做出来。

用5kHz周期的时间内测量有C的几个脉冲,比如4个,因为我知道5khz的一个周期就是200us内,单片机定时器可以从0计数到n,比如定时器时钟2M,200us就是0-400,接着用一个可变周期定时器(用输出比较中断,到某个数就讲TIM -> CNT = 0),C输入的管脚上升沿触发一个外部中断,这个外部中断打开那个可变定时器,可变周期定时器到400的时候输出比较中断,看如果只计数到3个说明可变周期要长一点,设置成401继续开始上述过程。显然,400这个数越大越精确,因为stm32 pclk2时钟用的是72M,400*36=14400。

1、如果说得到14399,C信号的时钟14400个周期=单片机时钟14399个周期,单片机快,假设单片机TIM时钟72M,给dds的时钟是2MHz的,就是说定时器A36分频,计36输出一次,那么需要另一个定时器B给这个定时器开关,定时器B计数到14399就把A关50周期再打开,应该可以用滴答定时器(delay里面用的那种)。

2、假如最后得到到14450,那么说明C信号的时钟14400个周期=单片机时钟14450个周期,就是单片机的频率低了,慢了,定时器A35分频,会比2M的dds所需时钟快,2.0571MHz,2.0571M*(14400/14450)=2.0500MHz,就是说相对于C信号的时钟来说单片机35分频就是2.05MHz,那么就是说定时器B计数到2M的时候,关停定时器A0.05M个周期的时间

可以看出,单片机快了明显好调整,那么就可以用dds输出的时候,频率控制器写大一点,有一种单片机快的错觉,去降低单片机输出的时钟频率

就是说思路是有了,技术力不够,实现不出来(叹气ε=(´ο`*)))唉)

文件结构

BSP文件夹

  • clkout (clkout.c&clkout.h)

这个文件用于设置单片机的TIM5,用PA0输出pwm波,作为dds的主时钟输入(不是sclk)

  • adc (bsp_adc.c&bsp_adc.h)

初始化PA4作为采样管脚输入

  • DDS (DDS.c&DDS.h)

dds的设置

  • encoder (encoder.c&encoder.h)

初始化TIM2\3\4\5作为编码器模式,编写了读编码器函数,用TIM6定时中断读取编码器的值就是速度值,在中断服务函数中经过PI控制器,计算得到电机控制量,并修改单片机对于电机输出

  • pwm (pwm.c&pwm.h)

初始化TIM8生成pwm波形,使用TIM8四路输出比较通道,得到同频率不同占空比的四路输出给四个轮子的电机,控制四个轮子的速度,方向控制用另外四个管脚

debug的时候先读串口,看编码器反馈正不正常,然后看输入到pid控制器的误差值对不对就行,里面有个-1是根据硬件电路临时调整的,保证负反馈就行

  • exit (exit_bsp.c&exit_bsp.h)

这个文件用于设置PC5管脚的外部中断,上升沿触发中断,中断服务函数现在为空

  • pinread (pinread.c&pinread.h)

读7位拨码开关并转换为二进制值,管脚请自行按需修改

  • uart (bsp_usart.c&bsp_usart.h)

只用了usart1,串口中断,现在是接受到东西并发回去,注释部分是用串口改变四轮转速给定值。scanf和printf都重定义了,可以直接用printf将变量打印在串口中。windows的串口助手记得用\r\n换行。

  • ctl (ctl.c&ctl.h)

这个是pid控制器函数封装,在encoder里面的tim6中断计算的时候使用

  • icm20607、key、LCD、RGB没有用到,别人的例程照搬进工程没有删掉,需要的时候直接调用

DSP文件夹

  • FFT的stm32官方库,在main函数里面调用了

USER文件夹

  • main
  • AllHeader.h

这里有define的一些东西,还有全局变量,还有把所有头文件都放进来了,因为这个头文件几乎!在每个文件里面都Include了,这样找函数就不怕找不到了

About

No description, website, or topics provided.

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published