我们从2011年坚守至今,只想做存粹的技术论坛。  由于网站在外面,点击附件后要很长世间才弹出下载,请耐心等待,勿重复点击不要用Edge和IE浏览器下载,否则提示不安全下载不了

 找回密码
 立即注册
搜索
查看: 739|回复: 13

stm32打靶系统

[复制链接]

该用户从未签到

34

主题

12

回帖

0

积分

二级逆天

积分
0

终身成就奖

发表于 2020-11-23 08:45:57 | 显示全部楼层 |阅读模式
#include "sys.h"
#include "delay.h"
#include "usart.h"
#include "led.h"               
#include "lcd.h"  
#include "key.h"   
#include "tpad.h"  
#include "exti.h"   
#include "usmart.h"
#include "ov7670.h"
#include "ov7725.h"
#include "hsi.h"
//ALIENTEK精英STM32F103开发板 实验33
//摄像头实验 实验
//技术支持:www.openedv.com
//广州市星翼电子科技有限公司

//传感器名字宏定义
#define  OV7725 1
#define  OV7670 2

//由于OV7725传感器安装方式原因,OV7725_WINDOW_WIDTH相当于LCD的高度,OV7725_WINDOW_HEIGHT相当于LCD的宽度
//注意:此宏定义只对OV7725有效
#define  OV7725_WINDOW_WIDTH        320 // <=320
#define  OV7725_WINDOW_HEIGHT        240 // <=240
#define min3v(v1, v2, v3)   ((v1)>(v2)? ((v2)>(v3)?(v3)v2))(v1)>(v3)?(v3)v1)))//
#define max3v(v1, v2, v3)   ((v1)<(v2)? ((v2)<(v3)?(v3)v2))(v1)<(v3)?(v3)v1)))//


const u8*LMODE_TBL[6]={"Auto","Sunny","Cloudy","Office","Home","Night"};//6种光照模式        
const u8*EFFECTS_TBL[7]={"Normal","Negative","B&W","Redish","Greenish","Bluish","Antique"};    //7种特效
extern u8 ov_sta;    //在exit.c里 面定义
extern u8 ov_frame;    //在timer.c里面定义
extern unsigned int shunxu[5][6];
extern u16 n;
extern u16 t;
extern u16 keyc;
u16 color0;   //refresh函数颜色顺序判断
u32 h,s2,l;
u16 get_date;
u8 shu=2;
u32 find_x,find_y;

u16 pwm_x=200;
u16 pwm_y=200;                                       //pwm占空比
u16 target_x=120;
u16 target_y=160;                                    //目标位置
float Kp_x=0.18,Ki_x=0.01;                                                         //pid参数
float Kp_y=0.18,Ki_y=0.01;                                                         //pid参数

int Bias_x, Last_bias_x;                                                //定义目标频率
int Bias_y, Last_bias_y;                                                //定义目标频率  

u32 sum_x=0,sum_y=0,i_xy = 0,n_i;
u16 X,Y;    //靶子实际坐标

u8 key;

COLOR_RGB Rgb;     
COLOR_HSL Hsl1;
RESULT Resu;
TARGET_CONDI Condition={0,200,0,34,20,30,40,40,320,240};
void refresh(u16 color);
static void ReadColor(u16 x,u16 y,COLOR_RGB *Rgb)
{
     unsigned short C16;
  C16 = LCD_ReadPoint(x,y);
    Rgb->red   =     (unsigned char)((C16&0xf800)>>8);
    Rgb->green =     (unsigned char)((C16&0x07e0)>>3);
    Rgb->blue  =     (unsigned char)((C16&0x001f)<<3);
}
static void RGBtoHSL(const COLOR_RGB *Rgb, COLOR_HSL *Hsl)
{
  int maxVal,minVal,difVal;
    int r  = Rgb->red;
    int g  = Rgb->green;
  int b  = Rgb->blue;
    int h,s2,l;
    maxVal = max3v(r, g, b);
    minVal = min3v(r, g, b);
   
    difVal = maxVal-minVal;
   
    //计算亮度
    l = (maxVal+minVal)*240/255/2;
    if(maxVal == minVal)//若r=g=b
    {
        h = 0;
        s2 = 0;
    }
    else
    {
        //计算色调
        if(maxVal==r)
        {
            if(g>=b)
                h = 40*(g-b)/(difVal);
            else
                h = 40*(g-b)/(difVal) + 240;
        }
        else if(maxVal==g)
            h = 40*(b-r)/(difVal) + 80;
        else if(maxVal==b)
            h = 40*(r-g)/(difVal) + 160;
        //计算饱和度
        if(l == 0)
            s2 = 0;
        else if(l<=120)
            s2 = (difVal)*240/(maxVal+minVal);
        else
            s2 = (difVal)*240/(511 - (maxVal+minVal));
    }
    Hsl->hue =        (unsigned char)(((h>240)? 240 : ((h<0)?0:h)));
    Hsl->saturation = (unsigned char)(((s2>240)? 240 : ((s2<0)?0:s2)));
    Hsl->luminance =  (unsigned char)(((l>240)? 240 : ((l<0)?0:l)));
}

//更新LCD显示(OV7725)
void OV7725_camera_refresh(void)
{
    u32 i,j;
     u16 color;     
    if(ov_sta)//有帧中断更新
    {
        LCD_Scan_Dir(U2D_L2R);        //从上到下,从左到右  
        LCD_Set_Window((lcddev.width-OV7725_WINDOW_WIDTH)/2,(lcddev.height-OV7725_WINDOW_HEIGHT)/2,OV7725_WINDOW_WIDTH,OV7725_WINDOW_HEIGHT);//将显示区域设置到屏幕中央
        if(lcddev.id==0X1963)LCD_Set_Window((lcddev.width-OV7725_WINDOW_WIDTH)/2,(lcddev.height-OV7725_WINDOW_HEIGHT)/2,OV7725_WINDOW_HEIGHT,OV7725_WINDOW_WIDTH);//将显示区域设置到屏幕中央
        LCD_WriteRAM_Prepare();     //开始写入GRAM   
        OV7725_RRST=0;                //开始复位读指针
        OV7725_RCK_L;
        OV7725_RCK_H;
        OV7725_RCK_L;
        OV7725_RRST=1;                //复位读指针结束
        OV7725_RCK_H;
        for(i=0;i<OV7725_WINDOW_HEIGHT;i++)
        {
            for(j=0;j<OV7725_WINDOW_WIDTH;j++)
            {
                OV7725_RCK_L;
                color=GPIOC->IDR&0XFF;    //读数据
                OV7725_RCK_H;
                color<<=8;  
                OV7725_RCK_L;
                color|=GPIOC->IDR&0XFF;    //读数据
                OV7725_RCK_H;
                LCD->LCD_RAM=color;  
            }
        }
        shu++;
         ov_sta=0;                    //清零帧中断标记
        ov_frame++;
        LCD_Scan_Dir(DFT_SCAN_DIR);    //恢复默认扫描方向
    }
}

//更新LCD显示(OV7670)   
int main(void)
{        
     u8 i=0;        
    u8 msgbuf[15];//消息缓存区
    u8 tm=0;
    u8 lightmode=0,effect=0;
    s8 saturation=0,brightness=0,contrast=0;   
     Stm32_Clock_Init(9);        //系统时钟设置
    uart_init(72,115200);        //串口初始化为115200
    delay_init(72);                    //延时初始化
     usmart_dev.init(72);        //初始化USMART        
     LED_Init();                      //初始化与LED连接的硬件接口
    KEY_Init();                    //初始化按键
    LCD_Init();                       //初始化LCD  
    EXTIX_Init();             //初始化外部中断输入
    TPAD_Init(6);                //触摸按键初始化
  TIM3_PWM_Init(3999,359);
     POINT_COLOR=RED;            //设置字体为红色
    LCD_ShowString(30,50,200,16,16,"WarShip STM32");   
    LCD_ShowString(30,70,200,16,16,"OV7725_OV7670 TEST");   
    LCD_ShowString(30,90,200,16,16,"ATOM@ALIENTEK");
    LCD_ShowString(30,110,200,16,16,"2017/11/1");
    LCD_ShowString(30,130,200,16,16,"KEY0ight Mode");
    LCD_ShowString(30,150,200,16,16,"KEY1:Saturation");
    LCD_ShowString(30,170,200,16,16,"KEY2:Brightness");
    LCD_ShowString(30,190,200,16,16,"KEY_UP:Contrast");
    LCD_ShowString(30,210,200,16,16,"TPAD:Effects");     
  LCD_ShowString(30,230,200,16,16,"OV7725_OV7670 Init...");      
    while(1)//初始化OV7725_OV7670
    {
        if(OV7725_Init()==0)
        {
            LCD_ShowString(30,230,200,16,16,"OV7725 Init OK       ");
            while(1)
            {
                key=KEY_Scan(0);
                if(key==KEY0_PRES)
                {
                    OV7725_Window_Set(OV7725_WINDOW_WIDTH,OV7725_WINDOW_HEIGHT,0);//QVGA模式输出
                    i=0;
                    break;
                }else if(key==KEY1_PRES)
                {
                    OV7725_Window_Set(OV7725_WINDOW_WIDTH,OV7725_WINDOW_HEIGHT,1);//VGA模式输出
                    i=0;
                    break;
                }
                i++;
                if(i==100)LCD_ShowString(30,250,210,16,16,"KEY0VGA  KEY1:VGA"); //闪烁显示提示信息
                if(i==200)
                {   
                    LCD_Fill(30,250,210,250+16,WHITE);
                    i=0;
                }
                delay_ms(5);
            }               
            OV7725_Light_Mode(lightmode);
            OV7725_Color_Saturation(saturation);
            OV7725_Brightness(brightness);
            OV7725_Contrast(contrast);
            OV7725_Special_Effects(effect);
            OV7725_CS=0;
            break;
        }else if(OV7670_Init()==0)
        {
            LCD_ShowString(30,230,200,16,16,"OV7670 Init OK       ");
            delay_ms(1500);            
            OV7670_Light_Mode(lightmode);
            OV7670_Color_Saturation(saturation);
            OV7670_Brightness(brightness);
            OV7670_Contrast(contrast);
            OV7670_Special_Effects(effect);
            OV7670_Window_Set(12,176,240,320);//设置窗口
            OV7670_CS=0;
            break;
        }else
        {
            LCD_ShowString(30,230,200,16,16,"OV7725_OV7670 Error!!");
            delay_ms(200);
            LCD_Fill(30,230,239,246,WHITE);
            delay_ms(200);
        }
    }

    TIM6_Int_Init(9999,7199);            //10Khz计数频率,1秒钟中断                                      
    EXTI8_Init();                        //使能外部中断8,捕获帧中断            
    LCD_Clear(BLACK);
     while(1)
    {   
          key=KEY_Scan(0);//不支持连按
      if(t)
            {   
                        switch(keyc)
                        {
                            case 1:
                                refresh(keyc-1);
                            printf("1");
                            break;
                            case 2:
                                refresh(keyc-1);
                            printf("2");
                            break;
                            case 3:
                                printf("error!");
                       }        
              }                        
              else
                        LED1=0;
//           OV7725_camera_refresh();
//                      TIM3->CCR1=200+70;
//                TIM3->CCR2=200+75;   

                                                                        if(tm)
                                                                        {
                                                                            LCD_ShowString((lcddev.width-240)/2+30,(lcddev.height-320)/2+60,200,16,16,msgbuf);
                                                                            tm--;
                                                                        }
                                                                        i++;
                                                                        if(i==15)//DS0闪烁.
                                                                        {
                                                                            i=0;
                                                                            LED0=!LED0;
                                                                        }
    }
}   


void refresh(u16 color)
{
            if(shu==3)
        {
                shu=0;      
       for(find_y=0;find_y<320;find_y=find_y +4)//寻找测试点
         {
                for(find_x=0;find_x<240;find_x=find_x +4)  //y轴先固定,扫描x轴
                    {
                    get_date=LCD_ReadPoint(find_x,find_y);   
                    ReadColor(find_x,find_y,&Rgb);  //输入一个点,分别获得颜色值
                    RGBtoHSL(&Rgb,&Hsl1);//   rgb转化为色调,亮度,对比度        
                        if(((Hsl1.hue>=shunxu[color][0])&&(Hsl1.hue<=shunxu[color][1]))&&((Hsl1.saturation>=shunxu[color][2])&&(Hsl1.saturation<=shunxu[color][3]))&&((Hsl1.luminance>=shunxu[color][4])&&(Hsl1.luminance<=shunxu[color][5]))) //????   
                                {
                                     sum_x = sum_x+find_x ;
                                     sum_y = sum_y+find_y ;
                                     i_xy++;  //每找到一个点累加一次
                                     n_i=i_xy;
                                        X=sum_x /n_i;           ////得到目标x轴坐标
                                        Y=sum_y /n_i;      ////得到目标y轴坐标
                                   printf("%d \n",color);
                    //                printf("x:%d y:%d\n",find_x,find_y);            
                                }
//                        if(((find_x==120)&&(find_y==160)))
//                printf("h:%d s:%d l:%d\n",Hsl1.hue,Hsl1.saturation,Hsl1.luminance);

                            }
              }
                             if(((sum_x==0)&&(sum_y==0)))    //如果扫描不到对象,保持舵机静止
                             {
                                 X=120;Y=160;
                             }
         
                POINT_COLOR=BLACK;        
                LCD_Draw_Circle( X,Y,20);          //画圆标注
                //x轴pid            
                Bias_x=target_x-X;                        //计算偏差
                pwm_x+=(Ki_x*(Bias_x-Last_bias_x)+Kp_x*Bias_x);   //增量式PI控制器
                if(pwm_x>=400)pwm_x=400;
                if(pwm_x<=0)pwm_x=0;
                Last_bias_x=Bias_x;                       //保存上一次偏差
                //y轴pid
                Bias_y=target_y-Y;                        //计算偏差
                pwm_y+=(Ki_y*(Bias_y-Last_bias_y)+Kp_y*Bias_y);   //增量式PI控制器
                Last_bias_y=Bias_y;                       //保存上一次偏差
                if(pwm_y>=400)pwm_y=400;
                if(pwm_y<=0)pwm_y=0;
                //改变占空比         
                TIM3->CCR1=pwm_x+70;
                TIM3->CCR2=pwm_y+75;
                             
//                if(((target_x<121)&&(target_x>119)&&(target_y<161)&&(target_y>159)))   
//                {
//                    delay_ms(2000);
//                    keyc++;                        
//                }
                //清零         
                sum_x =0;
                sum_y =0;
                i_xy =0;            

     }
                    OV7725_camera_refresh();  //摄像头刷新
}

void TIM6_IRQHandler(void)
{                                       
    if(TIM6->SR&0X0001)//溢出中断
    {                    
        printf("frame:%dfps\r\n",ov_frame);    //打印帧率
        ov_frame=0;                                                               
    }                  
    TIM6->SR&=~(1<<0);//清除中断标志位         
}
回复

使用道具 举报

  • TA的每日心情
    开心
    2024-9-12 14:20
  • 签到天数: 60 天

    [LV.6]常住居民II

    2

    主题

    1015

    回帖

    1849

    积分

    二级逆天

    积分
    1849

    终身成就奖

    QQ
    发表于 2020-11-23 08:49:39 | 显示全部楼层
    回复

    使用道具 举报

  • TA的每日心情
    难过
    3 天前
  • 签到天数: 81 天

    [LV.6]常住居民II

    0

    主题

    3710

    回帖

    7451

    积分

    二级逆天

    积分
    7451

    终身成就奖特殊贡献奖原创先锋奖优秀斑竹奖

    发表于 2020-11-23 08:50:06 | 显示全部楼层
    回复

    使用道具 举报

    该用户从未签到

    4

    主题

    581

    回帖

    0

    积分

    二级逆天

    积分
    0

    终身成就奖

    发表于 2020-11-23 08:51:04 | 显示全部楼层
    回复

    使用道具 举报

  • TA的每日心情
    开心
    4 小时前
  • 签到天数: 107 天

    [LV.6]常住居民II

    5

    主题

    6751

    回帖

    1万

    积分

    三级逆天

    积分
    14185

    终身成就奖特殊贡献奖原创先锋奖

    发表于 2020-11-23 08:52:29 | 显示全部楼层
    回复

    使用道具 举报

    该用户从未签到

    1

    主题

    833

    回帖

    0

    积分

    二级逆天

    积分
    0

    终身成就奖优秀斑竹奖

    发表于 2020-11-23 08:53:02 | 显示全部楼层
    回复

    使用道具 举报

  • TA的每日心情
    开心
    4 天前
  • 签到天数: 58 天

    [LV.5]常住居民I

    51

    主题

    3830

    回帖

    2973

    积分

    二级逆天

    积分
    2973

    终身成就奖特殊贡献奖原创先锋奖优秀斑竹奖

    QQ
    发表于 2020-11-23 09:00:57 | 显示全部楼层
    回复

    使用道具 举报

  • TA的每日心情
    擦汗
    昨天 10:19
  • 签到天数: 106 天

    [LV.6]常住居民II

    1

    主题

    5349

    回帖

    7667

    积分

    二级逆天

    积分
    7667

    终身成就奖特殊贡献奖原创先锋奖优秀斑竹奖

    发表于 2020-11-23 09:03:51 | 显示全部楼层
    回复

    使用道具 举报

    该用户从未签到

    1

    主题

    4703

    回帖

    5

    积分

    二级逆天

    积分
    5

    终身成就奖特殊贡献奖原创先锋奖优秀斑竹奖

    发表于 2020-11-23 15:36:21 | 显示全部楼层
    回复

    使用道具 举报

  • TA的每日心情
    开心
    2024-9-7 09:00
  • 签到天数: 2 天

    [LV.1]初来乍到

    0

    主题

    4981

    回帖

    3456

    积分

    二级逆天

    积分
    3456

    终身成就奖社区居民优秀斑竹奖

    QQ
    发表于 2020-11-23 18:18:16 | 显示全部楼层
    谢谢分享stm32打靶系统
    回复

    使用道具 举报

    您需要登录后才可以回帖 登录 | 立即注册

    本版积分规则

    论坛开启做任务可以
    额外奖励金币快速赚
    积分升级了


    Copyright ©2011-2024 NTpcb.com All Right Reserved.  Powered by Discuz! (NTpcb)

    本站信息均由会员发表,不代表NTpcb立场,如侵犯了您的权利请发帖投诉

    平平安安
    TOP
    快速回复 返回顶部 返回列表