本项目运用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);
}
}
}
本项目运用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);
}
}
}
举报