manhuami2007 发表于 2014-12-26 11:37:44

STM32 Nucleo板方案设计——多媒体控制终端

本帖最后由 manhuami2007 于 2015-1-28 19:22 编辑

我的方案是教室使用的多媒体控制终端,负责切换vga视频源与音频源,控制电脑和投影仪的开关机等功能。下图是系统的示意图,图画的不好,让大家见笑了,嘿嘿。

最近项目比较忙,一直没有时间更新,现在开始更新,先上图。有些线没接,但是肯定都是能用的,每个模块都测试过了。视频就不上传了,感觉有些难录制。
系统的主程序是一直在扫描按键,上面有8个带灯按键分别是总电源关、电脑投影机电源开关、投影机休眠、音视频源切换、静音、音量加、音量减和电脑重启。前四个是需要MCU读取的,和音量有关的3个按键是数字电位器芯片使用的,最后一个重启电脑的按键与主板上的引脚相连。
先说音频板。音频板实现两路音频信号切换,之后与无线麦克的音频信号混合输出到功放模块上,最后到喇叭。而音量的控制是使用MAXIM的数字电位器芯片MAX5457,其带静音与音量控制的按键接口,使用起来很方便。一开始我卡在音频耦合上了,不知道耦合电路怎么画,后来在网上查的就是两路音频信号都接电容之后接在一起就行了,通过实验确实可行。下面是音频的原理图

再说视频板,视频板比较简单,使用模拟开关就行。一开始用的模拟开关封装太小,我的水平还焊不了,就换了个芯片,国产的SGM330A。价钱也便宜不少。VGA信号频率还是很高的,要注意选择合适的模拟开关。原理图如下:

继电器使用松乐的,5v供电,可以控制10A的负载,注意要使三极管工作在饱和区与截止区。

剩下的就是MCU与投影机和电脑的控制与通信了。串口通信我使用的DMA方式。使用DMA通信一定要开中断,即使你中断里什么也不做。如果不开中断的话,你就得讲对应的DMA与UART重置DeInit之后在Init下,具体为什么我也不知道,但是通过观察寄存器和变量状态,不重置也不开中断的话,有个状态为会成为LOCKED,上锁了。会造成50%的丢包率,就是发一个丢一个循环。
在一个就是控制电脑的开关机。这个在网上找资料都找不到,资料很少,大多数都是说通过继电器控制。其实不需要,只用STM32的引脚就行。先说下我的测量数据。主板有电时,电源两引脚间的电压是3.3V,导通时的电流约为0.3mA(不能确定所有的主板都这样)。所以通过讲引脚设置为OD模式,上拉输出就行,想开机就拉低一段时间就行,我设置的拉低时间是500ms,通过实验能正常开机。关机和开机的步骤一样。
硬件说完了,说说软件。前一段时间在网易云课堂上看到孟宁老师讲的软件工程,觉得不错,就模仿着写的代码。先说下我的数据结构吧。
typedef struct
{
char* name;
GPIO_TypeDef* buttonPort;
uint16_t buttonIO;
uint32_t buttonPress;
uint32_t buttonCout;
B_DetectionEnum buttonState;
int (*handle)(uint8_t);
}Button_StateDef;这个数据结构中包括按键消抖需要的状态和相应的按键对用的处理程序。我没有使用按键中断,而是使用的扫描方式。使用状态机进行消抖判断,程序如下:
uint8_t ReturnKey(Button_StateDef*bs)
{
bs->buttonPress = HAL_GPIO_ReadPin(bs->buttonPort,bs->buttonIO);
switch(bs->buttonState)
{
case bDetection1:
    if(bs->buttonPress == BTNBEPRESS)
      bs->buttonState = bDetection2;
    else
      bs->buttonState = bDetection1;
    return B_UNCERTAIN;
case bDetection2:
    if(bs->buttonPress == BTNBEPRESS)
      bs->buttonState = bDetection3;
    else
      bs->buttonState = bDetection1;
    return B_UNCERTAIN;
case bDetection3:
    if(bs->buttonPress == BTNBEPRESS)
    {
      bs->buttonState = bDetection4;
      return B_UNCERTAIN;
    }
    else
    {
      bs->buttonState = bDetection1;
      return PRESS;
    }
case bDetection4:
    if(bs->buttonPress == BTNBEPRESS)
    {
      bs->buttonState = bDetection4;
      bs->buttonCout++ ;
      return B_UNCERTAIN;
    }
    else
    {
      bs->buttonState = bDetection1;
      if(bs->buttonCout >=FIVESECOND)
      {
      bs->buttonCout = 0;
      return LONGLONGPRESS;
      }
      else if(bs->buttonCout >= TWOSECOND)
      {
      bs->buttonCout = 0;
      return LONGPRESS;
      }
      else
      {
      return PRESS;
      }
    }
}
return B_UNCERTAIN;
}然后建立一个按键数组,每20ms扫描一次按键数组,就完成了扫描任务。扫描的程序如下
void ReadKey()
{
int i=0;
uint8_t state;
for(;i<BUTTONx;i++)
{
    state = ReturnKey(Buttons+i);
    if(state != B_UNCERTAIN)
    {
      Buttons.handle(state);
    }
}
}

其它的代码都比较简单就是一些处理函数。
项目到这里已经完成了,但是还是有很多细节需要去优化的。如果有什么不对的地方,希望大家指出来啊。

沐紫 发表于 2014-12-26 14:08:18

沙发,静等分享:)

巅峰残狼 发表于 2014-12-26 16:39:22

挺炫:lol

织梦狼 发表于 2014-12-30 16:06:38

:lol这个不错,其实我也想做。沐紫姐能不能做相同的。

沐紫 发表于 2014-12-30 16:12:19

织梦狼 发表于 2014-12-30 16:06
这个不错,其实我也想做。沐紫姐能不能做相同的。
如果是跟着楼主分享的内容,学着做,可以的,当然这样肯定拿不到开发经费。

如果思路不一样,有你自己的东西,你和楼主各做各的,也有机会拿到开发经费的

万里-363223 发表于 2015-1-7 08:45:24

静等楼主的分享

黑溱郎 发表于 2015-1-7 11:23:40

等待楼主的后续作品。

沐紫 发表于 2015-1-13 17:13:58

楼主被原理图难住了吗?有问题可以来提问哦

manhuami2007 发表于 2015-1-28 19:22:15

沐紫 发表于 2015-1-13 17:13
楼主被原理图难住了吗?有问题可以来提问哦

已经更新了,前段时间时间一直不太充足,所以没有更新,:loveliness:

MouseCat 发表于 2015-3-3 11:28:13

谢谢分享
页: [1]
查看完整版本: STM32 Nucleo板方案设计——多媒体控制终端