单片机学习小组
直播中

fansz

8年用户 1217经验值
擅长:制造/封装
私信 关注

怎样去设计一种基于STM32L151C6单片机的智能垃圾桶呢

怎样去设计一种基于STM32L151C6单片机的智能垃圾桶呢?怎样去编写其程序代码?

回帖(1)

温益浪

2022-2-28 15:09:36
本项目运用STM32L151C6系列单片机实现智能垃圾桶,每天的7 点--9 点,12 点--14 点,18 点--20 点工作。

        实现功能:在设置时间段内实现有人员靠近垃圾桶时,自动开盖等待垃圾的投放,人员离开,等待3秒关盖操作。

        硬件构成分为电池充电模块,电池供电和太阳能供电自动切换,mcu控制模块,电机正反转模块,以及红外测距模块。



    下图为整体硬件原理图参考。





操作说明










         软件功能用到RTC时钟,定时器,硬件IIC读取红外距离,普通IO口,串口。

        板载硬件初始化程序展示:



/***********************************************
调用方式:bsp_init(void)
返回值:
函数说明:系统函数初始化,使用外部晶振32M,
                                        串口1,115200,N,8,1
                                        默认RTC时钟为2021年,1月1日,12:00:00
************************************************/
void bsp_init(void)
{
        USART_Configuration(115200);       //串口1初始化      
        User_Shell_Init(User_Shell_WriteT);//shell命令初始化
        //USARTx_DMA_Config();                                                         //串口DMA搬运初始化
        IIC_Init();                                                                                                 //硬件IIC初始化
        exti_init();                                                                                   //外部中断停止信号1
        exti_init2();                                                                                         //外部中断停止信号2
        Tim_Init(999,1599);                                                          //定时器6以20hz计时
        Tim2_Init(999,1599);
        LED_Init();                                                                                                 //系统运行LED初始化
        MGPIO_Init();                                                                                   //电机正反转IO
        printf("RXT");
        RTC_Configuration();                                                         //RTC设置
        SetRTC(21,1,1,12,00,00);                                          //设置时间:21年 1月 1日12点00分00秒
        RtcInit();                                                                                                 //RTC初始化
}

RTC时钟通过shell命令修改对应时间

/***********************************************
调用方式:void RTC_write(char *test)
返回值:
函数说明:shell模式,串口写入RTC时间
************************************************/

void RTC_write(char *test)
{
        int str_len=strlen(test);
        int str_off=0;
        int str_num=0;
        int double_buffer[10];
        printf("RTC_write!rn");         
               
                memset((char*)double_buffer,0,sizeof(double_buffer));
                while(str_off                         int str_off_cur=0;
                        int scan_ret=sscanf(test+str_off,"%d%n",double_buffer+str_num,&str_off_cur);
                                        if(scan_ret != 1 || str_num> 4  ){
                                                break;
                                        }
                                        str_off+=str_off_cur+1;
                                        str_num += 1;
                        }
                        RTC_Configuration();//RTC设置
                        SetRTC(double_buffer[0],double_buffer[1],double_buffer[2],double_buffer[3],double_buffer[4],double_buffer[5]); //设置时间:19年 6月 2日16点15分58秒
                        if(double_buffer[3]>24 || double_buffer[4] > 60 ||double_buffer[5]>60){
                                printf("设置RTC时间错误rn");
                                double_buffer[0] = 21;
                                double_buffer[1] = 1;
                                double_buffer[2] = 1;
                                double_buffer[3] = 0;
                                double_buffer[4] = 0;
                                double_buffer[5] = 0;
                        }
                        else{
                                printf("设置RTC时间为:20%d/%d/%d -- %02d:%02d:%02d",double_buffer[0],double_buffer[1],double_buffer[2],double_buffer[3],double_buffer[4],double_buffer[5]);
                                RTC_Configuration();//RTC设置
                                SetRTC(double_buffer[0],double_buffer[1],double_buffer[2],double_buffer[3],double_buffer[4],double_buffer[5]); //设置时间:2021/01/01/00/00/00
                                printf("设置RTC时间成功!rn");
                                printf("Write Success:%drn",str_num);//成功写入次数
                        }
}
SHELL_EXPORT_CMD(
SHELL_CMD_PERMISSION(0)|SHELL_CMD_TYPE(SHELL_TYPE_CMD_FUNC)|SHELL_CMD_DISABLE_RETURN,
RTC_write, RTC_write, RTC_write!);
主函数

int main(void)
{
        long date,time;//当前UTC时间
//================================================================================================
        bsp_init();//系统初始化
//        RCC_ClocksTypeDef get_rcc_clock;    //获取系统时钟状态
//  RCC_GetClocksFreq(&get_rcc_clock);  //仿真的时候就可以在结构体get_rcc_clock中看见各个外设的时钟了
        /* 检查是否为独立看门狗复位 */
  if (RCC_GetFlagStatus(RCC_FLAG_IWDGRST) != RESET){
    RCC_ClearFlag();                /* 独立看门狗复位 *//*如果一直不喂狗,会一直复位,在1s 时间内喂狗的话,则会持续关闭*/      
  }
  else{
               
   /*不是独立看门狗复位(可能为上电复位或者手动按键复位之类的) */
        }
        //IWDG_Config(IWDG_Prescaler_128 ,625);// IWDG 1s 超时溢出      
IWDG_Feed();//喂狗否则每秒复位

//================================================================================================
        while(1)
        {               
                //printf("1212121");
                IWDG_Feed();//喂狗否则每秒复位
               
                GetRTC(&time,&date);
                float value =Get_IICvalue();

               
                if(((time/10000 >= 0x07) && (time/10000 < 0x09))||((time/10000 >= 0x0C) && (time/10000 < 0x0E))||((time/10000 >= 0x12) && (time/10000 < 0x14))){
                        //if(time%10000/100 <= 1){
                                //在测量范围内时,正转
                                if((value >= Distance_min) && (value <= Distance_max)){
                                                //printf("有效距离: %.2f mmrn",value);
                                                MGPIO_GPIO_1_0();
                                                MGPIO_GPIO_2_1();
                                                if(GPIO_ReadInputDataBit(EXTI_GPIO_PORT_1,EXTI_GPIO_Pin_1) == 0){
//                                                                TIM2_Stop();
//                                                                TIM2_Start();
                                                        if((GPIO_ReadInputDataBit(EXTI_GPIO_PORT_1,EXTI_GPIO_Pin_1) == 0)){
//                                                                TIM2_Stop();
                                                                //printf("转%d::;;;rn",timer_count1);
                                                                //timer_count1 = 0;
                                                                MGPIO_GPIO_1_1();
                                                                MGPIO_GPIO_2_1();
                                                        //printf("电机正转rn");
                                                }
                                                }
                                        }
                                 if((value <= Distance_min) || (value >= Distance_max)){
                                                TIM2_Stop();
                                                TIM2_Start();
                                         if((timer_count1 >= 120) &&((value <= Distance_min) || (value >= Distance_max))){
//                                        while(timer_count1 >= 120){
//                                                TIM2_Stop();
//                                                //printf("电机反转%d::;;;rn",timer_count1);
                                               
                                               
                                                MGPIO_GPIO_1_1();
                                                MGPIO_GPIO_2_0();
               
                                               
                                        if(GPIO_ReadInputDataBit(EXTI_GPIO_PORT_1,EXTI_GPIO_Pin_2) == 0){
                                                if(GPIO_ReadInputDataBit(EXTI_GPIO_PORT_1,EXTI_GPIO_Pin_2) == 0){
                                                        timer_count1 = 0;
                                                        MGPIO_GPIO_1_1();
                                                        MGPIO_GPIO_2_1();
                                                }
                                                        //printf("电机反转rn");
                                                }
                                        }
//                                                      
                                        }
                                }




                if(timer_count >= 10){
      
                        timer_count = 0;
                        ToggleLED();
                        printf("Distance: %.2f mmrn",value);
                        printf("20%d/%d/%d -- %02d:%02d:%02drn",date/10000,date%10000/100,date%100,time/10000,time%10000/100,time%100);

                }
        }
}
举报

更多回帖

发帖
×
20
完善资料,
赚取积分