找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 2683|回复: 1
打印 上一主题 下一主题
收起左侧

智能循迹小车主程序

[复制链接]
跳转到指定楼层
楼主
ID:314559 发表于 2018-5-7 17:37 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式

#include <iom16v.h>
#include <macros.h>
#define uchar unsigned char
#define uint  unsigned int

/******************************************************************************/
/********************************宏定义***************************************/
/******************************************************************************/
#define H595DDR_OUT    DDRC |=BIT(0)|BIT(1)|BIT(2)|BIT(3)|BIT(4)|BIT(5)|BIT(6)
#define H595CTL       PORTC    //高低高平
#define H595_SER_H    H595CTL |= BIT(PC6) //数据              
#define H595_SER_L    H595CTL &= ~BIT(PC6)                                          
#define H595_RCK_H    H595CTL |= BIT(PC5) //副寄存器时钟                        
#define H595_RCK_L    H595CTL &= ~BIT(PC5)
#define H595_SCK_H    H595CTL |= BIT(PC4) //主时钟                        
#define H595_SCK_L    H595CTL &= ~BIT(PC4)

#define H595DDR_OUT1    DDRD |=BIT(0)|BIT(1)|BIT(2)
#define H595CTL1       PORTD    //高低高平
#define H595_SER1_H    H595CTL1 |= BIT(PD0) //数据              
#define H595_SER1_L    H595CTL1 &= ~BIT(PD0)                                          
#define H595_RCK1_H    H595CTL1 |= BIT(PD1) //副寄存器时钟                        
#define H595_RCK1_L    H595CTL1 &= ~BIT(PD1)
#define H595_SCK1_H    H595CTL1 |= BIT(PD2) //主时钟                        
#define H595_SCK1_L    H595CTL1 &= ~BIT(PD2)


#define SEG_1_H       H595CTL |= BIT(PC0)//数码管四个位选端
#define SEG_1_L       H595CTL &= ~BIT(PC0)
#define SEG_2_H       H595CTL |= BIT(PC1)
#define SEG_2_L       H595CTL &= ~BIT(PC1)
#define SEG_3_H       H595CTL |= BIT(PC2)
#define SEG_3_L       H595CTL &= ~BIT(PC2)
#define SEG_4_H       H595CTL |= BIT(PC3)
#define SEG_4_L       H595CTL &= ~BIT(PC3)

#define BACK1_ON           PORTB |= BIT(PD3)     //前后//转向档瓶刂?               
#define BACK1_OFF          PORTB &= ~BIT(PD3)
#define BACK2_ON           PORTB |= BIT(PD4)                          
#define BACK2_OFF          PORTB &= ~BIT(PD4)
/******************************************************************************/
/**********************************end*****************************************/
/******************************************************************************/


uint count,ppp,count1,voltage;
uchar angle_flag1,angle_flag2=0;
uchar anglel,angleh;
uint i=0;
uchar sudu=0x40;
uchar AD_num1,AD_num=0;
static uchar black_flag;
static uchar online;
uint AD_get[8]={0,0,0,0,0,0,0,0};
uint AD_min[8]={0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff};
uint AD_max[8]={0,0,0,0,0,0,0,0};
uint AD_read[8]={0,0,0,0,0,0,0,0};
static uchar weiseg[4] = {0xfe,0xfd,0xfb,0xf7};
static uchar state[]={4,12,8,10,26,58,18,48,32,33,1,65,64,128};
static uchar shushow[11]={   
                           0xFA,/*0*/
                           0x60,/*1*/
                           0xDC,/*2*/
                           0xF4,/*3*/
                           0x66,/*4*/
                           0xB6,/*5*/
                           0xBE,/*6*/
                           0xE0,/*7*/
                           0xFE,/*8*/
                           0xF6,/*9*/
                           0x00

                          };
static uchar taple[] = {
                          0xff,
                                                  0xe7,
                                                  0xc3,
                                                  0x81,
                                                  0x00,
                                                  0x18,
                                                  0x3c,
                                                  0x7e,
                                                  0xff,
                                                  0xaa,
                                                  0x55
                                           };
static uint  smg[11]  = {
                          1,
                          12,
                                                  123,
                                                  1234,
                                                  2345,
                                                  3456,
                                                  4567,
                                                  5678,
                                                  6789,
                                                  9123,
                                                  3210       
                                            };
void AD_control();
void angle_control();
void set_angle(uchar agh,uchar agl);
void display(uint shuzhi);
void delay1(int k) ;
void set595(uchar s2);
void led_line(uchar s2);
/*******************************************************************************/
//////////////////////////////中断初始化函数/////////////////////////////////////
/*******************************************************************************/       
/******************************************************************************

                           端口初始化函数

******************************************************************************/                               
void port_init(void)
{
    DDRA  = 0x00;
    PORTB = 0x00;
    DDRB  = 0xff;
    PORTC = 0x0F;
    DDRC  = 0x7F;
    PORTD = 0x00;
    DDRD  = 0xff;
    H595DDR_OUT ;
    H595DDR_OUT1;
}
/******************************************************************************

                             AD初始化函数

******************************************************************************/
void adc_init(void)
{
ADCSRA        = 0x00;        //禁止AD转换
ADMUX        = 0x60;
SFIOR |= 0x00;
ACSR        = 0x80; //禁止模拟比较器
ADCSRA        = 0xEE;
}


/**********************定时T1初始化******************************

  模式:8位相位修正PWM模式
  舵角控制: OCR1AL=0XCA时,左最大,0XD0时,中间位置,0XD7时右转最大
  系统时钟:内部8MHZ,经256分频得61.275HZPWM频率

****************************************************************/

//定时T1初始化
void timer1_init(void)
{
TCCR1B = 0x00;//停止定时器
TIMSK |= 0x18;//中断允许
TCNT1H = 0x00;
TCNT1L = 0x00;//初始值
OCR1AH = 0x00;
OCR1AL = 0xC9;//匹配A值(C8-D0-DA)
OCR1BH = 0x00;
OCR1BL = 0x09;//匹配B值
TCCR1A = 0xf1;
// TCCR1B = 0x04;//启动定时器
TCCR1B = 0x04;//启动定时器
}

/******************************************************************************

                             串口初始化函数

******************************************************************************/
void uart0_init(void)
{
UCSRB = 0x00; //disable while setting baud rate
UCSRA = 0x00;
UCSRC = BIT(URSEL) | 0x06;
UBRRL = 0x67;
UBRRH = 0x00;//set baud rate hi
UCSRB = 0x98;
}
/**********************************END****************************************/



/*****************************************************************************/
///////////////////////////////中断处理函数////////////////////////////////////
/*****************************************************************************/



void uart0_tx_isr( char x)
{
  while(!(UCSRA&0x20));
  UDR=x;
}
unsigned int adc_calc(void)
{
//计算实际电压
unsigned long value=0;
value = ADCL>>6;                 //首先读低位
value|=(int)ADCH << 2; //然后读高位
voltage = value;
return voltage;
}
/*************************************************
       中断接受,同时发送接受到的内容
**************************************************/
#pragma interrupt_handler uart0_rx_isr:12
void uart0_rx_isr(void)
{
  unsigned char x;
  CLI();
  x=UDR;
  uart0_tx_isr(x);
  SEI();
}

#pragma interrupt_handler adc_isr:15
void adc_isr(void)//转换完成后中断处理
{
   uchar back_flag;
   AD_num++;
   ADMUX++;
   if(AD_num>7)
    {
      AD_num = 0;
          ADMUX        = 0x60;
    }
   voltage=adc_calc();
   AD_get[AD_num1]=voltage;

/*********************************AD转换值处理*****************************************/

/*  AD_min[AD_num1]=(AD_get[AD_num1]<AD_min[AD_num1]) ? AD_min[AD_num1]:AD_get[AD_num1];
   AD_max[AD_num1]=(AD_get[AD_num1]>AD_max[AD_num1]) ? AD_max[AD_num1]:AD_get[AD_num1];
   AD_read[AD_num1]= (AD_min[AD_num1]+ AD_max[AD_num1])*3/4 ;
   if(AD_get[AD_num1]>AD_read[AD_num1])
    {
         back_flag|=BIT(i);
     black_flag=back_flag;  
        } */
/********************************此部分有待证实*****************************************/
   AD_num1++;
   if(AD_num1>7)
   AD_num1=0;
}
/**************************************************/
/////////////////定时器T1匹配中断A服务程序/////////
/**************************************************/
#pragma interrupt_handler timer1_compa_isr:7
void timer1_compa_isr(void)
{
CLI();
if(angle_flag1==1)
  {
    angle_flag1=0;
    OCR1AH = angleh;
    OCR1AL = anglel;
  }
  SEI();
}
//定时器T1匹配中断B服务程序
#pragma interrupt_handler timer1_compb_isr:8
void timer1_compb_isr(void)
{
CLI();
if(angle_flag2==1)
  {
    angle_flag2=0;
    OCR1BH = 0x00;
    OCR1BL = sudu;
  }
  SEI();
}


/******************************************************************************/
///////////////////////////time delay funtion///////////////////////////////////
/******************************************************************************/


void delay1(int k)   //延时
{
     int i;           
     for(i=0;i<k;i++);
}
         


/******************************************************************************/
/*****************************595扫描流水灯函数********************************/
/******************************************************************************/         
void set595(uchar s2)
  {
        uchar mid,j = 0;
        CLI();
        for (j=0;j<8;j++)
    {
          mid=s2&0x01;   
          H595_SCK_L ;
          if (mid == 0)
              H595_SER_L ;
          else
              H595_SER_H;
              NOP();
              H595_SCK_H;
          NOP();
              s2=s2>>1;
         }
         H595_RCK_L ;
     NOP();
         H595_RCK_H;
         SEI();
       
  }
       
void led_line(uchar s2)
  {
         uchar mid,j=0;
         CLI();
         for (j=0;j<8;j++)
     {
           mid=s2&0x01;   
           H595_SCK1_L ;
           if (mid==0)
             H595_SER1_L ;
           else
             H595_SER1_H;
             NOP();
             H595_SCK1_H;
             NOP();
             s2=s2>>1;
         }
         H595_RCK1_L ;
     NOP();
         H595_RCK1_H;
         SEI();
   }
       

       
void display(uint shuzhi)
{
   uchar ge,shi,bai,qian;
   if(shuzhi > 999)
     {
       ge=shuzhi%10;
       shi=shuzhi%100/10;
       bai=shuzhi%1000/100;
       qian=shuzhi/1000;
     }
   else  if(shuzhi>99)
    {
       ge=shuzhi%10;
       shi=shuzhi%100/10;
       bai=shuzhi/100;
       qian=10;
        }
   else if(shuzhi>9)
    {
       ge   = shuzhi%10;
       shi  = shuzhi/10;
       bai  = 10;
       qian = 10;
    }
   else
        {
            ge   = shuzhi;
        shi  = 10;
        bai  = 10;
        qian = 10;
        }  
   set595(shushow[ge]);
   SEG_4_L;
   delay1(200);
   SEG_4_H;

   set595(shushow[shi]);
   SEG_3_L;
   delay1(200);
   SEG_3_H;

   set595(shushow[bai]);
   SEG_2_L;
   delay1(200);
   SEG_2_H;

   set595(shushow[qian]);
   SEG_1_L;
   delay1(200);
   SEG_1_H;
  }

/******************************************************************************/
/**********************************END*****************************************/
/******************************************************************************/





/********************************角度,速度实时处理函数************************/
void set_angle(uchar agh,uchar agl)
  {
     angle_flag1=1;
         angleh=agh;
         anglel=agl;
         
  }
  void set_sudu(uchar sd)
  {
    angle_flag2=1;
        sudu=sd;
  }
/************************************end***************************************/




/*********************坡道处理函数,有待实践证实********************************/
  void set_podao()
  {
    uint ii,iii;
        if(i<100)//上坡
    AD_control();
          else
    if(i>100)//下坡趋势//傍晚100快速50
         {
           for(ii=0;ii<6000;ii++ )
        {
                AD_control();
  switch(black_flag)
  {
   case 4:  set_angle(0x00,0xc8);set_sudu(0xca);BACK2_ON ;break;         //2
   case 6:  set_angle(0x00,0xca);set_sudu(0xca);BACK2_ON ;break;         //12
   case 2 : set_angle(0x00,0xcb);set_sudu(0x9a);BACK2_ON ;break;         //1
   case 10: set_angle(0x00,0xcc);set_sudu(0x9a);BACK2_ON ;break;         //13
   case 8 : set_angle(0x00,0xcd);set_sudu(0x9a);break;         //3  
   case 24: set_angle(0x00,0xce);set_sudu(0x9a);break;         //34
   case 56: set_angle(0x00,0xcf);set_sudu(0x90);break;         //345
   case 16: set_angle(0x00,0xcf);set_sudu(0x90);break;         //4
   case 48: set_angle(0x00,0xd0);set_sudu(0x91);break;         //45   
   case 32: set_angle(0x00,0xd0);set_sudu(0x91);break;         //5
   case 96: set_angle(0x00,0xd1);set_sudu(0x91);break;         //56
   case 64: set_angle(0x00,0xd2);set_sudu(0x91);break;         //6   
   case 65: set_angle(0x00,0xd4);set_sudu(0x91);break;         //06
   case 1: set_angle(0x00,0xd5);set_sudu(0x91);;BACK1_ON ;break;         //0
   case 129: set_angle(0x00,0xd7);set_sudu(0x91);;BACK1_ON ;break;         //07
   case 128: set_angle(0x00,0xd9);set_sudu(0xc1);;BACK1_ON ;break;         //7
  // default:i++;set_angle(0x00,0xd0);break;
   default:set_angle(0x00,0xd0);break;
  }
          }       
           i=0;
        }
  }
/************************************end***************************************/




/******************************************************************************/
                                             ///
                        ////                ///
                         ///      ///////////////////                     
                                              ///             ///
                                         ///
                      ////////   /////////////////////
                                      ///
                             //      ///
                            ///    ///          ///
                      //////    /////////////////////
                                                  ////

/******************************************************************************/
void Online(uchar sd)
{
online++;
if(online==10)
{
   online = 0;
   set_sudu(sd);   
}
set_sudu(0x90);
}
void angle_control()
{  

  BACK1_OFF ; //转向灯
  BACK2_OFF ;
switch(black_flag)
  {
  case 4:  set_angle(0x00,0xc8);set_sudu(0xaa);BACK2_ON ;break;         //2
   case 6:  set_angle(0x00,0xcb);set_sudu(0x41);BACK2_ON ;break;         //12
   case 2 : set_angle(0x00,0xcd);set_sudu(0x20);BACK2_ON ;break;         //1
   case 10: set_angle(0x00,0xce);set_sudu(0x15);break;         //13
   case 8 : set_angle(0x00,0xcd);set_sudu(0x10);break;         //3  
   case 24: set_angle(0x00,0xce);set_sudu(0x02);break;         //34
   case 56: set_angle(0x00,0xcf);set_sudu(0x01);break;         //345
   case 16: set_angle(0x00,0xcf);set_sudu(0x01);break;         //4
   case 48: set_angle(0x00,0xd0);set_sudu(0x01);break;         //45   
   case 32: set_angle(0x00,0xd1);set_sudu(0x01);break;         //5
   case 96: set_angle(0x00,0xd1);set_sudu(0x02);break;         //56
   case 64: set_angle(0x00,0xd2);set_sudu(0x10);break;         //6   
   case 65: set_angle(0x00,0xd4);set_sudu(0x15);break;         //06
   case 1:   set_angle(0x00,0xd5);set_sudu(0x20);BACK1_ON;break;         //0
   case 129: set_angle(0x00,0xd7);set_sudu(0x41);BACK1_ON;break;         //07
   case 128: set_angle(0x00,0xd9);set_sudu(0xa1);BACK1_ON;break;         //7
   // case 0:set_sudu(0x5a);BACK1_ON ;break;         //7
   default:i++;set_angle(0x00,0xd0);set_podao();break;
  }

}

void AD_control()
{
uchar i;
uchar back_flag=0;
for(i=0;i<8;i++)
{
   AD_min[i]=(AD_get[i]<AD_min[i]) ? AD_min[i]:AD_get[i];
   AD_max[i]=(AD_get[i]>AD_max[i]) ? AD_max[i]:AD_get[i];
   AD_read[i]= (AD_min[i]+ AD_max[i])*7/10 ;
   if(AD_get[i]>AD_read[i])
    {
         back_flag|=BIT(i);
     black_flag=back_flag;  
        }
}
}

void init_devices(void)
{
   CLI(); //禁止所有中断
   MCUCR  = 0x00;
   MCUCSR = 0x80;//禁止JTAG
   GICR   = 0x00;
   port_init();
   adc_init();
  // uart0_init();
   timer1_init();
  // OSCCAL=0Xff;// 内部8m时钟校正
   SEI();//开全局中断
}




/******************************************************************************/
/********************************MAIN FUNTION**********************************/
/******************************************************************************/
void main()
{  
   uint Count,Count1;
   uchar Count2;
   init_devices();
   while(1)
    {
        Count++;
        if(Count>200)
        {
         Count=0;
        Count1++;
        if(Count1>11)
        Count1=0;
        Count2=Count1;       
        led_line(taple[Count2]);       
        }
          //led_line(Count2);
          display(8888);
          //display(black_flag);
          AD_control();
          angle_control();
        }
}

分享到:  QQ好友和群QQ好友和群 QQ空间QQ空间 腾讯微博腾讯微博 腾讯朋友腾讯朋友
收藏收藏 分享淘帖 顶 踩
回复

使用道具 举报

沙发
ID:379994 发表于 2018-7-27 19:45 | 只看该作者
感谢大佬
回复

使用道具 举报

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

本版积分规则

小黑屋|51黑电子论坛 |51黑电子论坛6群 QQ 管理员QQ:125739409;技术交流QQ群281945664

Powered by 单片机教程网

快速回复 返回顶部 返回列表