打印

STM32F4控制步进电机、键盘、数码管、压力传感器、蜂鸣器

[复制链接]
379|0
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
考哥|  楼主 | 2018-7-6 14:24 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
最近要做一个新项目,外面写代码又太贵,天天逼着自己学着写,本来基本是小白,硬是花了一个月时间把代码和硬件都做出来了,今天全部程序写完在开发板上调试好了,pcb也发出去打板,给大家分享一下,写的很冗杂,也请大佬们多多指点。

功能是stm32f4控制8个按键,分为两组,每组包括档位键、启动键、暂停键。十个档位,按下档位键时数码管上显示出当前的档位,按下启动键时,键盘锁开启,步进电机1启动,按下暂停键时,步进电机停止。当压力传感器1的压力大于设定值时,电机1自动停止,
切换到电机2运行(运行速度为2号档位键设置的速度),当压力传感器2达到限制时,电机2停止,蜂鸣器报警,说的有点乱,直接上代码了

main.c
#include "sys.h"
#include "delay.h"
#include "pwm.h"
#include "KEY.h"
#include "TM1638.h"
#include "TM1638_2.h"
#include "HX711.h"
#include "HX711B.h"
#include "usart.h"
#include "led.h"
#include "PWM2.h"
#include "BEEP.h"


const unsigned int seg[10]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f};                 //不带小数点           0-9
const unsigned int seg2[10]={0xbf,0x86,0xdb,0xcf,0xe6,0xed,0xfd,0x87,0xff,0xef};         //带小数点                   0.-9.
const unsigned int location[8]={0xc0,0xc2,0xc4,0xc6,0xc8,0xca,0xcc,0xce};          //段码
const unsigned int location2[8]={0xc1,0xc3,0xc5,0xc7,0xc9,0xcb,0xcd,0xcf};
const u8 table_tmp[8] = {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00};  //显示缓冲区


int main(void)
{
        u8 KEY_NUM=0;        //初始化档位1值
        u8 KEY2_NUM=0;       //初始化档位2值
        u8 KEY_FLAG=0;        //按键标志位
        float Weight = 0;    //初始化压力值
        float Weight2 = 0;    //初始化压力值
        
        KEY_Init();          //初始化与按键连接的硬件端口
        Driver_Init();                         //电机1初始化
        Driver_Init2();      //电机2初始化
        BEEP_Init();                 //初始化蜂鸣器端口
  uart_init(115200);         //串口初始化波特率为115200
        NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);//设置系统中断优先级分组2
        delay_init(168);     //初始化延时函数
        display_Init();      //数码管1显示初始化
        display2_Init();      //数码管2显示初始化
        Init_Hx711();        //初始化压力读取
        Get_Maopi();         //去除压力干扰
        Init_Hx711B();        //初始化压力B读取
        Get_MaopiB();         //去除压力B干扰
        delay_ms(1);        
        
                                TM1638_Display(location[0],seg[0]);            //初始数码管1显示状态
                    TM1638_Display(location[1],seg[0]);
                    TM1638_Display(location[2],seg2[0]);
                          TM1638_Display(location[3],seg2[0]);
                                TM1638_Display(location[4],seg2[8]);            
                    TM1638_Display(location[5],seg2[8]);
                    TM1638_Display(location[6],seg2[8]);
                          TM1638_Display(location[7],seg2[8]);
                                
                                TM1638_2_Display(location[0],seg[0]);            //初始数码管2显示状态
                    TM1638_2_Display(location[1],seg[0]);
                    TM1638_2_Display(location[2],seg2[0]);
                          TM1638_2_Display(location[3],seg2[0]);
                                TM1638_2_Display(location[4],seg2[8]);            
                    TM1638_2_Display(location[5],seg2[8]);
                    TM1638_2_Display(location[6],seg2[8]);
                          TM1638_2_Display(location[7],seg2[8]);        
                                
                                
   while(1)
         {
          Weight = Get_Weight();
          Weight = (float)Weight/1000.0f;
          printf("%0.3f
",Weight);              //串口显示重量
          delay_ms(1);
                  if(Weight>10)
                   {
        TIM3_PWM_Init(1-1 ,84-1);               
        TIM2_PWM_Init (5000/KEY_NUM ,84-1);               
                   }
          Weight2 = Get_WeightB();
          Weight2 = (float)Weight2/1000.0f;
          printf("%0.3f
",Weight2);              //串口显示重量
          delay_ms(1);
                  if(Weight2>10)
                   {
                                display_Init(); //数码管显示初始化
                     TM1638_Display(location[0],0X80);
                    TM1638_Display(location[1],seg[(KEY_NUM*5)/10]);
                    TM1638_Display(location[2],seg2[(KEY_NUM*5)%10]);
                          TM1638_Display(location[3],seg2[0]);
                          TM1638_Display(location[4],0X39);            //压力显示C
                          TM1638_Display(location[5],0X0f);            //电池显示        .mh/h
                                TM1638_Display(location[6],0X64);            //注射完毕
                                TM1638_Display(location[7],0X0C);            //暂停
        TIM2_PWM_Init(1-1 ,84-1);
        BEEP=1;                                 
                   }                        
                  if(S1==0||P1==0||D1==0||D2==1)
             {
                    delay_ms(10);//去抖动
                     if(D1==0&&KEY_FLAG==0)                 //档位按键
                      {        
                             KEY_NUM++;
                              if(KEY_NUM >=10)
                               {
              KEY_NUM=0;                        
                               }
                              display_Init(); //数码管显示初始化
                              TM1638_Display(location[0],0X80);            //显示小数点
                        TM1638_Display(location[1],seg[(KEY_NUM*5)/10]);
                        TM1638_Display(location[2],seg2[(KEY_NUM*5)%10]);
                              TM1638_Display(location[3],seg2[0]);
                              TM1638_Display(location[4],0X39);            //压力显示C
                              TM1638_Display(location[5],0X0f);            //电池显示.mh/h

                       }
                      else if(S1 ==0&&KEY_FLAG==0)    //启动键
                       {
                              display_Init(); //数码管显示初始化
                              TM1638_Display(location[0],0X80);
                        TM1638_Display(location[1],seg[(KEY_NUM*5)/10]);
                        TM1638_Display(location[2],seg2[(KEY_NUM*5)%10]);
                              TM1638_Display(location[3],seg2[0]);
                                    TM1638_Display(location[4],0X39);            //压力显示C
                              TM1638_Display(location[5],0X0f);            //电池显示.mh/h
                              TM1638_Display(location[7],0X70);            //运行箭头
                              TIM3_PWM_Init(40/KEY_NUM ,84-1);
                                                KEY_FLAG=1;
                       }  
                      else if(P1==0)  //暂停键
                       {
                              display_Init(); //数码管显示初始化
                         TM1638_Display(location[0],0X80);
                        TM1638_Display(location[1],seg[(KEY_NUM*5)/10]);
                        TM1638_Display(location[2],seg2[(KEY_NUM*5)%10]);
                              TM1638_Display(location[3],seg2[0]);
                              TM1638_Display(location[4],0X39);            //压力显示C
                              TM1638_Display(location[5],0X0f);            //电池显示        .mh/h               
                                    TM1638_Display(location[7],0X0C);            //暂停
                              TIM3_PWM_Init(1-1 ,84-1);
            TIM2_PWM_Init(1-1 ,84-1);
            BEEP=0;
            KEY_FLAG =0;                                                
                       }        
                                         else if(D2==1) //档位2
                                         {
                             KEY2_NUM++;
                              if(KEY2_NUM >=10)
                               {
              KEY2_NUM=0;                        
                               }
                              display2_Init(); //数码管显示初始化
                              TM1638_2_Display(location[0],0X80);            //显示小数点
                        TM1638_2_Display(location[1],seg[(KEY2_NUM*5)/10]);
                        TM1638_2_Display(location[2],seg2[(KEY2_NUM*5)%10]);
                              TM1638_2_Display(location[3],seg2[0]);
                              TM1638_2_Display(location[4],0X39);            //压力显示C
                              TM1638_2_Display(location[5],0X0f);            //电池显示.mh/h
                                         }
               }
       }
}


步进电机

#include "pwm.h"
#include "usart.h"




void Driver_Init(void)
{
        GPIO_InitTypeDef  GPIO_InitStructure;

        RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOC, ENABLE);//使能GPIOC时钟

        GPIO_InitStructure.GPIO_Pin = GPIO_Pin_5|GPIO_Pin_4; //ENA使能 DIR方向对应引脚
        GPIO_InitStructure.GPIO_Mode = GPIO_Mode_OUT;//普通输出模式
        GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;//推挽输出
        GPIO_InitStructure.GPIO_Speed = GPIO_Speed_100MHz;//100M
        GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP;//上拉
        GPIO_Init(GPIOC, &GPIO_InitStructure);//初始化GPIOA5.4
        
        GPIO_SetBits(GPIOC,GPIO_Pin_4);//PC2输出高 顺时针方向  DIR
        GPIO_ResetBits(GPIOC,GPIO_Pin_5);//PC1输出低 使能输出  ENA
}




//TIM3_CH1 PWM部分初始化
//PWM输出初始化
//arr:自动重装值
//psc:时钟预分频数
void TIM3_PWM_Init(u32 arr,u32 psc)
{                                                         
        
        
        GPIO_InitTypeDef GPIO_InitStructure;
        TIM_TimeBaseInitTypeDef  TIM_TimeBaseStructure;
        TIM_OCInitTypeDef  TIM_OCInitStructure;
        
        RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM3,ENABLE);          //TIM3时钟使能   
        RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOA, ENABLE);         //使能PORTA时钟        
        
        GPIO_PinAFConfig(GPIOA,GPIO_PinSource6,GPIO_AF_TIM3); //GPIOA6复用为定时器3
        
        GPIO_InitStructure.GPIO_Pin = GPIO_Pin_6;           //GPIOA6
        GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;        //复用功能
        GPIO_InitStructure.GPIO_Speed = GPIO_Speed_100MHz;        //速度100MHz
        GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;      //推挽复用输出
        GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP;        //上拉
        GPIO_Init(GPIOA,&GPIO_InitStructure);              //初始化PA6
         
        TIM_TimeBaseStructure.TIM_Prescaler=psc;  //定时器分频
        TIM_TimeBaseStructure.TIM_CounterMode=TIM_CounterMode_Up; //向上计数模式
        TIM_TimeBaseStructure.TIM_Period=arr;   //自动重装载值
        TIM_TimeBaseStructure.TIM_ClockDivision=TIM_CKD_DIV1;
        
        TIM_TimeBaseInit(TIM3,&TIM_TimeBaseStructure);//初始化定时器3
        
        //初始化TIM3  Channel1 PWM模式         
        TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM1; //选择定时器模式:TIM脉冲宽度调制模式2
         TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable; //比较输出使能
        TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_Low; //输出极性:TIM输出比较极性低
        TIM_OC1Init(TIM3, &TIM_OCInitStructure);  //根据T指定的参数初始化外设TIM3 OC1

        TIM_OC1PreloadConfig(TIM3, TIM_OCPreload_Enable);  //使能TIM14在CCR1上的预装载寄存器

  TIM_ARRPreloadConfig(TIM3,ENABLE);//ARPE使能
        TIM_SetCompare1 (TIM3,2);             //占空比
        
        TIM_Cmd(TIM3, ENABLE);  //使能TIM3

                                                                                 
}  

数码管


#include"TM1638.h"
#include "stm32f4xx.h"

extern unsigned int seg[10];                 
extern unsigned int seg2[10];                 
extern unsigned int location[8];
extern unsigned int location2[8];
extern  u8 table_tmp[8];

void Delay(vu32 nCount)
{
  for(; nCount != 0; nCount--);
}


/*****************************
        发送函数(不分命令、数据)
*****************************/
void SendDATA1638(unsigned int edata)
{
  unsigned int i=0;
        GPIO_ResetBits(GC,STB);           //STB=0;
        for(i=0;i<8;i++)
        {
          Delay(100);                   //100ns
          GPIO_ResetBits(GC,CLK);          //CLK=0;
          if(edata&0x01)         
          {
             GPIO_SetBits(GC,DIO);          //DIO=1;
                 Delay(200);          //200ns
          }
          else
          {
             GPIO_ResetBits(GC,DIO);        //DIO=0
                 Delay(200);         //200ns
          }
          Delay(100);                         //100ns
          GPIO_SetBits(GC,CLK);                 //CLK=1;
          edata>>=1;
        }
}




/***********************************
  数据显示函数(只适用固定地址模式)
************************************/
void TM1638_Display(unsigned int address,unsigned int number)
{
         GPIO_SetBits(GC,STB);
   SendDATA1638(address);
         Delay(100);           //1μs
         SendDATA1638(number);
         Delay(100);           //1μs
         GPIO_SetBits(GC,STB);
         Delay(100);           //1μs
}




void  display_Init()
{
  int i;
        
        GPIO_InitTypeDef GPIO_InitStructure;

        RCC_AHB1PeriphClockCmd(  RCC_AHB1Periph_GPIOC , ENABLE);
         GPIO_InitStructure.GPIO_Pin = CLK;
         GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
         GPIO_InitStructure.GPIO_Mode = GPIO_Mode_OUT;
        GPIO_InitStructure.GPIO_OType =GPIO_OType_PP;
        GPIO_Init(GC, &GPIO_InitStructure);

         GPIO_InitStructure.GPIO_Pin = DIO;
         GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
         GPIO_Init(GC, &GPIO_InitStructure);

         GPIO_InitStructure.GPIO_Pin = STB;
         GPIO_InitStructure.GPIO_Mode = GPIO_Mode_OUT;
        GPIO_InitStructure.GPIO_OType =GPIO_OType_PP;
  GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
  GPIO_Init(GC, &GPIO_InitStructure);

         GPIO_SetBits(GC,STB);
   SendDATA1638(openLKM);
         GPIO_SetBits(GC,STB);
         Delay(100);
   SendDATA1638(writefix);
         GPIO_SetBits(GC,STB);
        
         for (i=0;i<8;i++)
      {   
      TM1638_Display(location[7-i],table_tmp);
      }     
}

压力传感器


#include "HX711.h"
#include "delay.h"

long HX711_Buffer = 0;
long Weight_Maopi = 0,Weight_Shiwu = 0;

#define GapValue 430
#define HIGH 1
#define LOW  0
#define HX711_GROUP GPIOB


void digitalWrite(GPIO_TypeDef * GPIO,int pin,int value)
{
        if(value==HIGH)//set 1
        {
                GPIO_SetBits(GPIO,pin);
        }
        if(value==LOW)//reset 0
        {
                GPIO_ResetBits(GPIO,pin);
        }
}

int digitalRead(GPIO_TypeDef * GPIO,int pin)
{
        return GPIO_ReadInputDataBit(GPIO,pin);
}

//****************************************************
//初始化HX711
//****************************************************
void Init_Hx711()
{
        GPIO_InitTypeDef  GPIO_InitStructure;

  RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOB, ENABLE);

  //SCK
  GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0 ;
  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_OUT;
  GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
  GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
  GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_DOWN;
  GPIO_Init(GPIOB, &GPIO_InitStructure);

        GPIO_InitTypeDef  GPIO_InitStructure1;

  RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOB, ENABLE);

  //DOUT
  GPIO_InitStructure1.GPIO_Pin = GPIO_Pin_1 ;
  GPIO_InitStructure1.GPIO_Mode = GPIO_Mode_IN;
  //GPIO_InitStructure1.GPIO_OType = GPIO_OType_OD;
  GPIO_InitStructure1.GPIO_Speed = GPIO_Speed_50MHz;
  GPIO_InitStructure1.GPIO_PuPd = GPIO_PuPd_NOPULL;
  GPIO_Init(GPIOB, &GPIO_InitStructure1);
        RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOB, ENABLE);

}


//****************************************************
//获取毛皮重量
//****************************************************
void Get_Maopi()
{
        Weight_Maopi = HX711_Read();               
}

//****************************************************
//称重
//****************************************************
long Get_Weight()
{
        HX711_Buffer = HX711_Read();
        Weight_Shiwu = HX711_Buffer;
        Weight_Shiwu = Weight_Shiwu - Weight_Maopi;                                //获取实物的AD采样数值。
        Weight_Shiwu = (long)((float)Weight_Shiwu/GapValue);         
        return Weight_Shiwu;
}

//****************************************************
//读取HX711
//****************************************************
unsigned long HX711_Read(void)        //增益128
{
                unsigned long val = 0;
        unsigned char i = 0;

        //判断模块是否准备好
        while(GPIO_ReadInputDataBit(GPIOB,GPIO_Pin_1));
        delay_us(1);   
        //sck 拉低
        GPIO_ResetBits(GPIOB,GPIO_Pin_0);
        //再次判断是否准备好
        while(!GPIO_ReadInputDataBit(GPIOB,GPIO_Pin_1));

        for(i=0;i<24;i++)
        {
                delay_us(100);
                GPIO_SetBits(GPIOB,GPIO_Pin_0);           
                val=val<<1;
                delay_us(1);  
                GPIO_ResetBits(GPIOB,GPIO_Pin_0);           
                if(GPIO_ReadInputDataBit(GPIOB,GPIO_Pin_1))  
                val++;
                delay_us(1);
        }
        GPIO_SetBits(GPIOB,GPIO_Pin_0);
        val = val^0x800000;
        delay_us(1);
        GPIO_ResetBits(GPIOB,GPIO_Pin_0);
        delay_us(1);  
        return val;
}

使用特权

评论回复

相关帖子

发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

461

主题

477

帖子

0

粉丝