草庐IT

K210项目实战(口罩检测系统和垃圾分类系统)

我与nano 2023-04-09 原文

在前面我学习了使用K210训练模型做目标检测,然后也学会了使用K210做串口通信,学完之后我就把K210丢在箱子里吃灰了,因为学校疫情原因,两年一届的电赛很遗憾不能参加了,然后我就想拿他做个口罩检测系统(检测到没戴口罩可以语言提醒),这个真的好简单,哈哈哈,接下来加点难度,做个垃圾分类系统,半天就做好了。哈哈哈,希望想做这两个项目的各位看了这篇博客也能很快的做出来,加油。

基于K210的口罩检测系统

K210垃圾分类

文章目录

前言

做项目,参加比赛才能真正的学到东西,将理论应用于实践,一起加油,一起进步。

一、前提准备

1.32单片机(这里我使用的是zet6最小系统板和c8t6)
2.K210(什么型号都可以)
3.SYN6288语音播报模块
4.舵机
5.垃圾桶
Keil5软件和Maixpy软件

二、项目实战

1.口罩检测系统

1.模型

相信大家看完我的第一篇博客,口罩检测的模型已经训练出来了,大家按照我上一篇介绍的脱机运行烧录到自己的K210里,这时脱机检测就可以运行了。
如下图

2.发送数据

如果大家还不会串口通信可以看我的博客,里面详细介绍了关于K210的串口通信部分,相信大家看完后就可以将masks,un_masks。数据发送到电脑上了。
如下图

3.SYN6288语音播报模块

这个便是这个项目第二个重要的部分了,通过单片机接收到数据,然后发送给语音播报模块,语音播报模块处理数据,播报出相应的语音。在这里因为只有两个标签,我没有处理字符串,直接用的接收到字符长度来判断的,所以我用了很短的时间就做出来了。
.c文件如下

#include "syn6288.h"
#include "usart.h"
#include "string.h"
#include "delay.h"


//Music:Ñ¡Ôñ±³¾°ÒôÀÖ¡£0:ÎÞ±³¾°ÒôÀÖ£¬1~15£ºÑ¡Ôñ±³¾°ÒôÀÖ
void SYN_FrameInfo(u8 Music, u8 *HZdata)
{
  /****************ÐèÒª·¢Ë͵ÄÎı¾**********************************/
  unsigned  char  Frame_Info[50];
  unsigned  char  HZ_Length;
  unsigned  char  ecc  = 0;  			//¶¨ÒåУÑé×Ö½Ú
  unsigned  int i = 0;
  HZ_Length = strlen((char*)HZdata); 			//ÐèÒª·¢ËÍÎı¾µÄ³¤¶È

  /*****************Ö¡¹Ì¶¨ÅäÖÃÐÅÏ¢**************************************/
  Frame_Info[0] = 0xFD ; 			//¹¹ÔìÖ¡Í·FD
  Frame_Info[1] = 0x00 ; 			//¹¹ÔìÊý¾ÝÇø³¤¶ÈµÄ¸ß×Ö½Ú
  Frame_Info[2] = HZ_Length + 3; 		//¹¹ÔìÊý¾ÝÇø³¤¶ÈµÄµÍ×Ö½Ú
  Frame_Info[3] = 0x01 ; 			//¹¹ÔìÃüÁî×Ö£ººÏ³É²¥·ÅÃüÁî
  Frame_Info[4] = 0x01 | Music << 4 ; //¹¹ÔìÃüÁî²ÎÊý£º±³¾°ÒôÀÖÉ趨

  /*******************УÑéÂë¼ÆËã***************************************/
  for(i = 0; i < 5; i++)   				//ÒÀ´Î·¢Ë͹¹ÔìºÃµÄ5¸öÖ¡Í·×Ö½Ú
  {
    ecc = ecc ^ (Frame_Info[i]);		//¶Ô·¢Ë͵Ä×Ö½Ú½øÐÐÒì»òУÑé
  }

  for(i = 0; i < HZ_Length; i++)   		//ÒÀ´Î·¢ËÍ´ýºÏ³ÉµÄÎı¾Êý¾Ý
  {
    ecc = ecc ^ (HZdata[i]); 				//¶Ô·¢Ë͵Ä×Ö½Ú½øÐÐÒì»òУÑé
  }
  /*******************·¢ËÍÖ¡ÐÅÏ¢***************************************/
  memcpy(&Frame_Info[5], HZdata, HZ_Length);
  Frame_Info[5 + HZ_Length] = ecc;
  USART3_SendString(Frame_Info, 5 + HZ_Length + 1);
}


/***********************************************************
* Ãû    ³Æ£º YS_SYN_Set(u8 *Info_data)
* ¹¦    ÄÜ£º Ö÷º¯Êý	³ÌÐòÈë¿Ú
* Èë¿Ú²ÎÊý£º *Info_data:¹Ì¶¨µÄÅäÖÃÐÅÏ¢±äÁ¿
* ³ö¿Ú²ÎÊý£º
* ˵    Ã÷£º±¾º¯ÊýÓÃÓÚÅäÖã¬Í£Ö¹ºÏ³É¡¢ÔÝÍ£ºÏ³ÉµÈÉèÖà £¬Ä¬Èϲ¨ÌØÂÊ9600bps¡£
* µ÷Ó÷½·¨£ºÍ¨¹ýµ÷ÓÃÒѾ­¶¨ÒåµÄÏà¹ØÊý×é½øÐÐÅäÖá£
**********************************************************/
void YS_SYN_Set(u8 *Info_data)
{
  u8 Com_Len;
  Com_Len = strlen((char*)Info_data);
  USART3_SendString(Info_data, Com_Len);
}

不知道为什么从keil5粘贴过来变成了乱码,你粘贴到keil5是没有问题的
.h文件如下

#ifndef __SYN6288_H
#define __SYN6288_H

#include "sys.h"


void SYN_FrameInfo(u8 Music, u8 *HZdata);
void YS_SYN_Set(u8 *Info_data);

#endif


主函数部分如下

		 if(len==6)
            {
					TIM_SetCompare2(TIM4, 1910);		
					SYN_FrameInfo(0, "[v7][m1][t5]ÇëÄúÕýÈ·Åå´÷¿ÚÕÖ");
          delay_ms(8000);
		      delay_ms(8000);
		      delay_ms(8000);
					delay_ms(8000);
							TIM_SetCompare2(TIM4, 1850);	
            }	
						 if(len==5)
            {
							TIM_SetCompare4(TIM4, 1930);	
					SYN_FrameInfo(0, "[v7][m1][t5]ÄúÒÑÅå´÷¿ÚÕÖ");
         delay_ms(8000);
		      delay_ms(8000);
		      delay_ms(8000);
							delay_ms(2000);

到这里整个项目就算完成了,当你真正学会了K210之后你就会发现真的好简单。
完整的工程代码和K210代码需要的话可以在下面留下你的邮箱,我会发到你的邮箱里。
我也将完整的32代码和K210文件上传到了我的资源里,需要的也可以自行下载。

2.垃圾分类系统

1.模型

同样你需要做垃圾分类,你就要训练垃圾的模型,还需要不同种类,这里我放上标注好的图片链接,大家可以自行训练。(不会的可以看我主页链接)

链接:https://pan.baidu.com/s/1K6qbEQZ97PcyMWcgTCq1hw
提取码:qhnx
训练好之后,将模型烧录进sd卡,让K210进行脱机运行,检测一下垃圾模型是不是对的。
如下图

2.串口通信数据处理部分

又到了串口通信部分,大家可以看我主页另外一篇博客,这里我不过多赘述了。和上面一样。

3.SYN6288语音播报模块

同上,代码如下
.c
(这里就是很简单的32定时器配置)

#include "timer.h"

u16 t=0;
void TIM2_Int_Init(u16 arr,u16 psc)
{
   TIM_TimeBaseInitTypeDef  TIM_TimeBaseStructure;
	NVIC_InitTypeDef NVIC_InitStructure;

	RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2, ENABLE); //ʱÖÓʹÄÜ
	
	//¶¨Ê±Æ÷TIM3³õʼ»¯
	TIM_TimeBaseStructure.TIM_Period = 999; //ÉèÖÃÔÚÏÂÒ»¸ö¸üÐÂʼþ×°Èë»î¶¯µÄ×Ô¶¯ÖØ×°ÔؼĴæÆ÷ÖÜÆÚµÄÖµ	
	TIM_TimeBaseStructure.TIM_Prescaler =71; //ÉèÖÃÓÃÀ´×÷ΪTIMxʱÖÓÆµÂʳýÊýµÄÔ¤·ÖƵֵ
	TIM_TimeBaseStructure.TIM_ClockDivision = TIM_CKD_DIV1; //ÉèÖÃʱÖÓ·Ö¸î:TDTS = Tck_tim
	TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;  //TIMÏòÉϼÆÊýģʽ
	TIM_TimeBaseInit(TIM2, &TIM_TimeBaseStructure); //¸ù¾ÝÖ¸¶¨µÄ²ÎÊý³õʼ»¯TIMxµÄʱ¼ä»ùÊýµ¥Î»
 
	TIM_ITConfig(TIM2,TIM_IT_Update,ENABLE ); //ʹÄÜÖ¸¶¨µÄTIM3ÖжÏ,ÔÊÐí¸üÐÂÖжÏ

	//ÖжÏÓÅÏȼ¶NVICÉèÖÃ
	NVIC_InitStructure.NVIC_IRQChannel = TIM2_IRQn;  //TIM3ÖжÏ
	NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;  //ÏÈÕ¼ÓÅÏȼ¶0¼¶
	NVIC_InitStructure.NVIC_IRQChannelSubPriority = 3;  //´ÓÓÅÏȼ¶3¼¶
	NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; //IRQͨµÀ±»Ê¹ÄÜ
	NVIC_Init(&NVIC_InitStructure);  //³õʼ»¯NVIC¼Ä´æÆ÷


	TIM_Cmd(TIM2, DISABLE);  //ʹÄÜTIMx		  //ÏȹرÕ			 
}
//¶¨Ê±Æ÷3ÖжϷþÎñ³ÌÐò
void TIM2_IRQHandler(void)   //TIM3ÖжÏ
{
	if (TIM_GetITStatus(TIM2, TIM_IT_Update) != RESET)  //¼ì²éTIM3¸üÐÂÖжϷ¢ÉúÓë·ñ
		{
			t++;
			TIM_ClearITPendingBit(TIM2, TIM_IT_Update  );  //Çå³ýTIMx¸üÐÂÖжϱêÖ¾ 
		}
}

void TIM3_PWM_Init(u16 arr,u16 psc)//¶à·¶æ»ú¿ØÖÆ£¬¶¨Òå¶ÔÓ¦Òý½Å£¬Ê¹ÄÜÏàӦͨµÀ£¬Ö÷º¯ÊýͬÑùÐèҪʹÄÜÏàӦͨµÀ
{  
	GPIO_InitTypeDef GPIO_InitStructure;
	TIM_TimeBaseInitTypeDef  TIM_TimeBaseStructure;
	TIM_OCInitTypeDef  TIM_OCInitStructure;
	

	RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM3, ENABLE);	//ʹÄܶ¨Ê±Æ÷3ʱÖÓ
 	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB|RCC_APB2Periph_GPIOA , ENABLE);  //ʹÄÜGPIOÍâÉèºÍAFIO¸´Óù¦ÄÜÄ£¿éʱÖÓ
	
	//GPIO_PinRemapConfig(GPIO_PartialRemap_TIM3, ENABLE); //Timer3²¿·ÖÖØÓ³Éä  TIM3_CH2->PB5    
 
   //ÉèÖøÃÒý½ÅΪ¸´ÓÃÊä³ö¹¦ÄÜ,Êä³öTIM3 CH2µÄPWMÂö³å²¨ÐÎ	GPIOB.5
	GPIO_InitStructure.GPIO_Mode=GPIO_Mode_AF_PP; //ÉèÖÃΪ¸´ÓÃÍÆÍìÊä³ö
  GPIO_InitStructure.GPIO_Pin=GPIO_Pin_6|GPIO_Pin_7;
  GPIO_InitStructure.GPIO_Speed=GPIO_Speed_50MHz;
  GPIO_Init(GPIOA,&GPIO_InitStructure);

  GPIO_InitStructure.GPIO_Mode=GPIO_Mode_AF_PP;
  GPIO_InitStructure.GPIO_Pin=GPIO_Pin_0|GPIO_Pin_1;
  GPIO_InitStructure.GPIO_Speed=GPIO_Speed_50MHz;
  GPIO_Init(GPIOB,&GPIO_InitStructure);
	
   //³õʼ»¯TIM3
	TIM_TimeBaseStructure.TIM_Period = arr; //ÉèÖÃÔÚÏÂÒ»¸ö¸üÐÂʼþ×°Èë»î¶¯µÄ×Ô¶¯ÖØ×°ÔؼĴæÆ÷ÖÜÆÚµÄÖµ
	TIM_TimeBaseStructure.TIM_Prescaler =psc; //ÉèÖÃÓÃÀ´×÷ΪTIMxʱÖÓÆµÂʳýÊýµÄÔ¤·ÖƵֵ 
	TIM_TimeBaseStructure.TIM_ClockDivision = 0; //ÉèÖÃʱÖÓ·Ö¸î:TDTS = Tck_tim
	TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;  //TIMÏòÉϼÆÊýģʽ
	TIM_TimeBaseInit(TIM3, &TIM_TimeBaseStructure); //¸ù¾ÝTIM_TimeBaseInitStructÖÐÖ¸¶¨µÄ²ÎÊý³õʼ»¯TIMxµÄʱ¼ä»ùÊýµ¥Î»
	
	//³õʼ»¯TIM3 Channel2 PWMģʽ	
  TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM2; //Ñ¡Ôñ¶¨Ê±Æ÷ģʽ:TIMÂö³å¿í¶Èµ÷ÖÆÄ£Ê½2
 	TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable; //±È½ÏÊä³öʹÄÜ
	TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_High; //Êä³ö¼«ÐÔ:TIMÊä³ö±È½Ï¼«ÐÔ¸ß
	TIM_OC1Init(TIM3, &TIM_OCInitStructure);  //¸ù¾ÝTÖ¸¶¨µÄ²ÎÊý³õʼ»¯ÍâÉèTIM3 OC2

	TIM_OC1PreloadConfig(TIM3, TIM_OCPreload_Enable);  //ʹÄÜTIM3ÔÚCCR2ÉϵÄÔ¤×°ÔØ¼Ä´æÆ÷
 
  TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM2; //Ñ¡Ôñ¶¨Ê±Æ÷ģʽ:TIMÂö³å¿í¶Èµ÷ÖÆÄ£Ê½2
 	TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable; //±È½ÏÊä³öʹÄÜ
	TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_High; //Êä³ö¼«ÐÔ:TIMÊä³ö±È½Ï¼«ÐÔ¸ß
	TIM_OC2Init(TIM3, &TIM_OCInitStructure);  //¸ù¾ÝTÖ¸¶¨µÄ²ÎÊý³õʼ»¯ÍâÉèTIM3 OC2

	TIM_OC2PreloadConfig(TIM3, TIM_OCPreload_Enable);  //ʹÄÜTIM3ÔÚCCR2ÉϵÄÔ¤×°ÔØ¼Ä´æÆ÷
 
  TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM2; //Ñ¡Ôñ¶¨Ê±Æ÷ģʽ:TIMÂö³å¿í¶Èµ÷ÖÆÄ£Ê½2
 	TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable; //±È½ÏÊä³öʹÄÜ
	TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_High; //Êä³ö¼«ÐÔ:TIMÊä³ö±È½Ï¼«ÐÔ¸ß
	TIM_OC3Init(TIM3, &TIM_OCInitStructure);  //¸ù¾ÝTÖ¸¶¨µÄ²ÎÊý³õʼ»¯ÍâÉèTIM3 OC2

	TIM_OC3PreloadConfig(TIM3, TIM_OCPreload_Enable);  //ʹÄÜTIM3ÔÚCCR2ÉϵÄÔ¤×°ÔØ¼Ä´æÆ÷
  
	TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM2; //Ñ¡Ôñ¶¨Ê±Æ÷ģʽ:TIMÂö³å¿í¶Èµ÷ÖÆÄ£Ê½2
 	TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable; //±È½ÏÊä³öʹÄÜ
	TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_High; //Êä³ö¼«ÐÔ:TIMÊä³ö±È½Ï¼«ÐÔ¸ß
	TIM_OC4Init(TIM3, &TIM_OCInitStructure);  //¸ù¾ÝTÖ¸¶¨µÄ²ÎÊý³õʼ»¯ÍâÉèTIM3 OC2

	TIM_OC4PreloadConfig(TIM3, TIM_OCPreload_Enable);  //ʹÄÜTIM3ÔÚCCR2ÉϵÄÔ¤×°ÔØ¼Ä´æÆ÷
 
	TIM_Cmd(TIM3, ENABLE);  //ʹÄÜTIM3
}

void TIM4_PWM_Init(u16 arr,u16 psc)
{  
	GPIO_InitTypeDef GPIO_InitStructure;
	TIM_TimeBaseInitTypeDef  TIM_TimeBaseStructure;
	TIM_OCInitTypeDef  TIM_OCInitStructure;
	

	RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM4, ENABLE);	//ʹÄܶ¨Ê±Æ÷3ʱÖÓ
 	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB , ENABLE);  //ʹÄÜGPIOÍâÉèºÍAFIO¸´Óù¦ÄÜÄ£¿éʱÖÓ
	
	//GPIO_PinRemapConfig(GPIO_PartialRemap_TIM3, ENABLE); //Timer3²¿·ÖÖØÓ³Éä  TIM3_CH2->PB5    
 
   //ÉèÖøÃÒý½ÅΪ¸´ÓÃÊä³ö¹¦ÄÜ,Êä³öTIM3 CH2µÄPWMÂö³å²¨ÐÎ	GPIOB.5
	GPIO_InitStructure.GPIO_Mode=GPIO_Mode_AF_PP; //ÉèÖÃΪ¸´ÓÃÍÆÍìÊä³ö
  GPIO_InitStructure.GPIO_Pin=GPIO_Pin_9|GPIO_Pin_6|GPIO_Pin_7|GPIO_Pin_8;
  GPIO_InitStructure.GPIO_Speed=GPIO_Speed_50MHz;
  GPIO_Init(GPIOB,&GPIO_InitStructure);

   //³õʼ»¯TIM3
	TIM_TimeBaseStructure.TIM_Period = arr; //ÉèÖÃÔÚÏÂÒ»¸ö¸üÐÂʼþ×°Èë»î¶¯µÄ×Ô¶¯ÖØ×°ÔؼĴæÆ÷ÖÜÆÚµÄÖµ
	TIM_TimeBaseStructure.TIM_Prescaler =psc; //ÉèÖÃÓÃÀ´×÷ΪTIMxʱÖÓÆµÂʳýÊýµÄÔ¤·ÖƵֵ 
	TIM_TimeBaseStructure.TIM_ClockDivision = 0; //ÉèÖÃʱÖÓ·Ö¸î:TDTS = Tck_tim
	TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;  //TIMÏòÉϼÆÊýģʽ
	TIM_TimeBaseInit(TIM4, &TIM_TimeBaseStructure); //¸ù¾ÝTIM_TimeBaseInitStructÖÐÖ¸¶¨µÄ²ÎÊý³õʼ»¯TIMxµÄʱ¼ä»ùÊýµ¥Î»
	
	//³õʼ»¯TIM3 Channel2 PWMģʽ	
  TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM2; //Ñ¡Ôñ¶¨Ê±Æ÷ģʽ:TIMÂö³å¿í¶Èµ÷ÖÆÄ£Ê½2
 	TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable; //±È½ÏÊä³öʹÄÜ
	TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_High; //Êä³ö¼«ÐÔ:TIMÊä³ö±È½Ï¼«ÐÔ¸ß
	TIM_OC1Init(TIM4, &TIM_OCInitStructure);  //¸ù¾ÝTÖ¸¶¨µÄ²ÎÊý³õʼ»¯ÍâÉèTIM3 OC2

	TIM_OC1PreloadConfig(TIM4, TIM_OCPreload_Enable);  //ʹÄÜTIM3ÔÚCCR2ÉϵÄÔ¤×°ÔØ¼Ä´æÆ÷
 
  TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM2; //Ñ¡Ôñ¶¨Ê±Æ÷ģʽ:TIMÂö³å¿í¶Èµ÷ÖÆÄ£Ê½2
 	TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable; //±È½ÏÊä³öʹÄÜ
	TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_High; //Êä³ö¼«ÐÔ:TIMÊä³ö±È½Ï¼«ÐÔ¸ß
	TIM_OC2Init(TIM4, &TIM_OCInitStructure);  //¸ù¾ÝTÖ¸¶¨µÄ²ÎÊý³õʼ»¯ÍâÉèTIM3 OC2

	TIM_OC2PreloadConfig(TIM4, TIM_OCPreload_Enable);  //ʹÄÜTIM3ÔÚCCR2ÉϵÄÔ¤×°ÔØ¼Ä´æÆ÷
 
  TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM2; //Ñ¡Ôñ¶¨Ê±Æ÷ģʽ:TIMÂö³å¿í¶Èµ÷ÖÆÄ£Ê½2
 	TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable; //±È½ÏÊä³öʹÄÜ
	TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_High; //Êä³ö¼«ÐÔ:TIMÊä³ö±È½Ï¼«ÐÔ¸ß
	TIM_OC3Init(TIM4, &TIM_OCInitStructure);  //¸ù¾ÝTÖ¸¶¨µÄ²ÎÊý³õʼ»¯ÍâÉèTIM3 OC2

	TIM_OC3PreloadConfig(TIM4, TIM_OCPreload_Enable);  //ʹÄÜTIM3ÔÚCCR2ÉϵÄÔ¤×°ÔØ¼Ä´æÆ÷
  
	TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM2; //Ñ¡Ôñ¶¨Ê±Æ÷ģʽ:TIMÂö³å¿í¶Èµ÷ÖÆÄ£Ê½2
 	TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable; //±È½ÏÊä³öʹÄÜ
	TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_High; //Êä³ö¼«ÐÔ:TIMÊä³ö±È½Ï¼«ÐÔ¸ß
	TIM_OC4Init(TIM4, &TIM_OCInitStructure);  //¸ù¾ÝTÖ¸¶¨µÄ²ÎÊý³õʼ»¯ÍâÉèTIM3 OC2

	TIM_OC4PreloadConfig(TIM4, TIM_OCPreload_Enable);  //ʹÄÜTIM3ÔÚCCR2ÉϵÄÔ¤×°ÔØ¼Ä´æÆ÷
 
	TIM_Cmd(TIM4, ENABLE);  //ʹÄÜTIM3
}

.h

#ifndef __TIMER_H
#define __TIMER_H
#include "sys.h"


void TIM2_Int_Init(u16 arr,u16 psc);
void TIM3_Int_Init(u16 arr,u16 psc);
void TIM3_PWM_Init(u16 arr,u16 psc);
void TIM3_Int_Init(u16 arr,u16 psc);
void TIM4_Int_Init(u16 arr,u16 psc);
void TIM4_PWM_Init(u16 arr,u16 psc);
#endif

主函数就是简单的PWM波这里就不过多赘述了。到这里垃圾分类也结束了,需要完整的工程文件可以在下面留下邮箱,大家一起学习。稍后我也会讲工程文件上传,需要的可自行下载。

总结

到这里这篇文章就结束了,学习了K210的模型训练与串口通信,搞了一下口罩检测系统和垃圾分类,做了两个小小的项目练了练手,感觉还不错,哈哈哈。这段时间正在做水果分拣车,等做完之后同样也会写一篇博客记录下来,加油。

有关K210项目实战(口罩检测系统和垃圾分类系统)的更多相关文章

  1. ruby - 如何在 buildr 项目中使用 Ruby 代码? - 2

    如何在buildr项目中使用Ruby?我在很多不同的项目中使用过Ruby、JRuby、Java和Clojure。我目前正在使用我的标准Ruby开发一个模拟应用程序,我想尝试使用Clojure后端(我确实喜欢功能代码)以及JRubygui和测试套件。我还可以看到在未来的不同项目中使用Scala作为后端。我想我要为我的项目尝试一下buildr(http://buildr.apache.org/),但我注意到buildr似乎没有设置为在项目中使用JRuby代码本身!这看起来有点傻,因为该工具旨在统一通用的JVM语言并且是在ruby中构建的。除了将输出的jar包含在一个独特的、仅限ruby​​

  2. ruby-on-rails - 项目升级后 Pow 不会更改 ruby​​ 版本 - 2

    我在我的Rails项目中使用Pow和powifygem。现在我尝试升级我的ruby​​版本(从1.9.3到2.0.0,我使用RVM)当我切换ruby​​版本、安装所有gem依赖项时,我通过运行railss并访问localhost:3000确保该应用程序正常运行以前,我通过使用pow访问http://my_app.dev来浏览我的应用程序。升级后,由于错误Bundler::RubyVersionMismatch:YourRubyversionis1.9.3,butyourGemfilespecified2.0.0,此url不起作用我尝试过的:重新创建pow应用程序重启pow服务器更新战俘

  3. ruby-on-rails - 新 Rails 项目 : 'bundle install' can't install rails in gemfile - 2

    我已经像这样安装了一个新的Rails项目:$railsnewsite它执行并到达:bundleinstall但是当它似乎尝试安装依赖项时我得到了这个错误Gem::Ext::BuildError:ERROR:Failedtobuildgemnativeextension./System/Library/Frameworks/Ruby.framework/Versions/2.0/usr/bin/rubyextconf.rbcheckingforlibkern/OSAtomic.h...yescreatingMakefilemake"DESTDIR="cleanmake"DESTDIR="

  4. ruby - RuntimeError(自动加载常量 Apps 多线程时检测到循环依赖 - 2

    我收到这个错误:RuntimeError(自动加载常量Apps时检测到循环依赖当我使用多线程时。下面是我的代码。为什么会这样?我尝试多线程的原因是因为我正在编写一个HTML抓取应用程序。对Nokogiri::HTML(open())的调用是一个同步阻塞调用,需要1秒才能返回,我有100,000多个页面要访问,所以我试图运行多个线程来解决这个问题。有更好的方法吗?classToolsController0)app.website=array.join(',')putsapp.websiteelseapp.website="NONE"endapp.saveapps=Apps.order("

  5. Ruby 从大范围中获取第 n 个项目 - 2

    假设我有这个范围:("aaaaa".."zzzzz")如何在不事先/每次生成整个项目的情况下从范围中获取第N个项目? 最佳答案 一种快速简便的方法:("aaaaa".."zzzzz").first(42).last#==>"aaabp"如果出于某种原因你不得不一遍又一遍地这样做,或者如果你需要避免为前N个元素构建中间数组,你可以这样写:moduleEnumerabledefskip(n)returnto_enum:skip,nunlessblock_given?each_with_indexdo|item,index|yieldit

  6. 电脑0x0000001A蓝屏错误怎么U盘重装系统教学 - 2

      电脑0x0000001A蓝屏错误怎么U盘重装系统教学分享。有用户电脑开机之后遇到了系统蓝屏的情况。系统蓝屏问题很多时候都是系统bug,只有通过重装系统来进行解决。那么蓝屏问题如何通过U盘重装新系统来解决呢?来看看以下的详细操作方法教学吧。  准备工作:  1、U盘一个(尽量使用8G以上的U盘)。  2、一台正常联网可使用的电脑。  3、ghost或ISO系统镜像文件(Win10系统下载_Win10专业版_windows10正式版下载-系统之家)。  4、在本页面下载U盘启动盘制作工具:系统之家U盘启动工具。  U盘启动盘制作步骤:  注意:制作期间,U盘会被格式化,因此U盘中的重要文件请注

  7. 【鸿蒙应用开发系列】- 获取系统设备信息以及版本API兼容调用方式 - 2

    在应用开发中,有时候我们需要获取系统的设备信息,用于数据上报和行为分析。那在鸿蒙系统中,我们应该怎么去获取设备的系统信息呢,比如说获取手机的系统版本号、手机的制造商、手机型号等数据。1、获取方式这里分为两种情况,一种是设备信息的获取,一种是系统信息的获取。1.1、获取设备信息获取设备信息,鸿蒙的SDK包为我们提供了DeviceInfo类,通过该类的一些静态方法,可以获取设备信息,DeviceInfo类的包路径为:ohos.system.DeviceInfo.具体的方法如下:ModifierandTypeMethodDescriptionstatic StringgetAbiList​()Obt

  8. 微信小程序开发入门与实战(Behaviors使用) - 2

    @作者:SYFStrive @博客首页:HomePage📜:微信小程序📌:个人社区(欢迎大佬们加入)👉:社区链接🔗📌:觉得文章不错可以点点关注👉:专栏连接🔗💃:感谢支持,学累了可以先看小段由小胖给大家带来的街舞👉微信小程序(🔥)目录自定义组件-behaviors    1、什么是behaviors    2、behaviors的工作方式    3、创建behavior    4、导入并使用behavior    5、behavior中所有可用的节点    6、同名字段的覆盖和组合规则总结最后自定义组件-behaviors    1、什么是behaviorsbehaviors是小程序中,用于实现

  9. kvm虚拟机安装centos7基于ubuntu20.04系统 - 2

    需求:要创建虚拟机,就需要给他提供一个虚拟的磁盘,我们就在/opt目录下创建一个10G大小的raw格式的虚拟磁盘CentOS-7-x86_64.raw命令格式:qemu-imgcreate-f磁盘格式磁盘名称磁盘大小qemu-imgcreate-f磁盘格式-o?1.创建磁盘qemu-imgcreate-fraw/opt/CentOS-7-x86_64.raw10G执行效果#ls/opt/CentOS-7-x86_64.raw2.安装虚拟机使用virt-install命令,基于我们提供的系统镜像和虚拟磁盘来创建一个虚拟机,另外在创建虚拟机之前,提前打开vnc客户端,在创建虚拟机的时候,通过vnc

  10. ruby - 在没有基准或时间的情况下用 Ruby 测量用户时间或系统时间 - 2

    因为我现在正在做一些时间测量,我想知道是否可以在不使用Benchmark类或命令行实用程序time的情况下测量用户时间或系统时间。使用Time类只显示挂钟时间,而不显示系统和用户时间,但是我正在寻找具有相同灵active的解决方案,例如time=TimeUtility.now#somecodeuser,system,real=TimeUtility.now-time原因是我有点不喜欢Benchmark,因为它不能只返回数字(编辑:我错了-它可以。请参阅下面的答案。)。当然,我可以解析输出,但感觉不对。*NIX系统的time实用程序也应该可以解决我的问题,但我想知道是否已经在Ruby中实

随机推荐