회원가입 ID/PW 찾기
AA
아크마님이 만드신 라인트레이서를 보고 구현해 봤는데...

스위치를 없애고 adc값을 받아 lcd에 표시해주고 모터를 구동할려고 하고 있습니다.

아크마님이 주신 소스를 보고 아무리 소스수정을 해도 머가 먼지 잘모르겠습니다...

어느부분을 지워야할지 잘모르겠네요.........

대충이라도 조금 알려주세요 A포트: 발광 B포트: LCD D포트: 모터 F포트: 수광

AVR128 사용중입니다....간단하게라도 좀 알려주세요

 #include <mega128.h>

// Alphanumeric LCD Module functions
#asm
   .equ __lcd_port=0x18 ;PORTB
#endasm
#include <lcd.h>  
#include <delay.h>
#include <stdio.h>
#include <stdlib.h>
#include "acc.h"
#include "handle.h"
 

#define TRUE  1
#define FALSE  0
  
#define TIMER0_32PRESCALE_VALUE 2   // (1/16MHz)*32*1000000

#define SENSOR_ON_TIME   40  // 40us 후에 센서를 끔.
#define SENSOR_OFF_TIME  70  // 트리거 신호의 주기 = 240us


#define FULL_STEP   3/*2상*/  /* 1-2상여자 = 7 */
#define ZERO    0
#define RIGHT  1
#define LEFT  2
#define BOTH  3   

#define FORWARD  0x03  /* 모터 방향 설정 bit1=왼쪽, bit0=오른쪽 */

#define MOTOR_PORT    PORTD

#define SPEED_LIMIT  300
#define SPEED_START  0

#define motor_disable()  MOTOR_PORT = 0x00
#define enable()            #asm("sei") 
#define disable()           #asm("cli") 


#define sen_on()  PORTA=0x18
#define sen_off()  PORTA=0x00


#define SENSOR_MODE_ON  1
#define SENSOR_MODE_OFF  2

#define SENSOR_ADJUST   50   

#define LEFT2  1
#define LEFT1   2
#define LEFT0   3

#define RIGHT2  6
#define RIGHT1  5
#define RIGHT0  4

#define LIGHT 0
#define COMPARE 1
#define MODE LIGHT
 
#define HANDLE_RATE_CUR  70
#define HANDLE_RATE_OLD     30

typedef  unsigned char byte;
typedef  unsigned int word;
typedef  unsigned long dword;

        
byte mode; 
byte buzzer_flag;  
 
// sensor part
 
byte sensor_mode; 
word sensor_input[6];
word sensor_border; // 비교기식일때 on/off 경계선
int sensor_adjust; // 광량식일때 좌우 대칭 센서 보정
byte sensor_cnt=0;


// motor part
const byte r_phase_table[] = {0x50, 0x60, 0xA0, 0x90};
const byte l_phase_table[] = {0x05, 0x06, 0x0A, 0x09};  

byte step_status;    // 주행 방향
word speed_limit; // 최고 제한속도
word time_r,time_l; // 타이머 주기
word acc_index;
byte l_phase_index, r_phase_index; // 상 인덱스
 
// adjust
int handle_adjust=0; 
long handle_adjust_cur=0;
long handle_adjust_old=150;
int handle_gain=4;
  
// general part
byte lcd_buf[16];

word i,j;

void port_init(void)
{     
 // External SRAM page configuration:
 //              -              / 0000h - 7FFFh
 // Lower page wait state(s): None
 // Upper page wait state(s): None
 // MCUCR=0x80;// set PC7 as output. PC7 is A15 and is used to enable nCE of SRAM.
 // XMCRA=0x00;
 
 MCUCR=0x00;// set PC7 as output. PC7 is A15 and is used to enable nCE of SRAM.
 XMCRA=0x00;
 
 DDRA = 0x18;
 DDRB = 0xff; // lcd, dummy led
 DDRD = 0xff; // step motor output 
 DDRE = 0x08;    // joystick switch input, buzzer output(PORTE3)
 DDRF = 0x00; // sensor input
 
 
 SFIOR=0x00;
}
 
void tlcd_init(void)
{
 // LCD module initialization
 lcd_init(8);  
 lcd_gotoxy(0,0);
 lcd_putsf("tracer");
 lcd_gotoxy(0,1);
 lcd_putsf("akma 1.1");      
}
    
  
byte adc_on = FALSE;                       
#define ADC_VREF_TYPE 0x40
//ADC initialize
// Conversion time: 1uS
void adc_init(void)
{
 ADCSRA = 0x00; //disable adc
  ADMUX = 0x00; //select adc input 0
  ACSR  = 0x80;
  //ADCSRA = 0x89;   // 1us 검은색 수광은 이것도 되는데..
  ADCSRA = 0x8E; // 이러케 하면 adc가 먼저 win
 
  for(i=0;i<6;i++)
 {
  sensor_input[i]=0;
    }
}
void display_handle()
{

   sprintf(lcd_buf, "handle");
   lcd_gotoxy(0,0);
      lcd_puts(lcd_buf);
 
   sprintf(lcd_buf, "%8d", handle_adjust);
      lcd_gotoxy(0,1);
      lcd_puts(lcd_buf);
         delay_ms(1000);

}
 
void display_sensor()
{
  for(i=0;i<8;i+=2)
  { 
   sprintf(lcd_buf, "%d : %4d", i, sensor_input[i]);
   lcd_gotoxy(0,0);
      lcd_puts(lcd_buf);
 
   sprintf(lcd_buf, "%d : %4d",i+1, sensor_input[i+1]);
      lcd_gotoxy(0,1);
      lcd_puts(lcd_buf);
         delay_ms(1000);
  }
}

void display_sensor_compare()

 if( sensor_input[LEFT2] > sensor_border)
  {  
    lcd_buf[0] = '1';
 }else
 {
   lcd_buf[0] = '0';
 }
 
 if( sensor_input[LEFT1] > sensor_border)
 {  
    lcd_buf[1] = '1';
 }else
 {
   lcd_buf[1] = '0';
 }
 
 if( sensor_input[LEFT0] > sensor_border)
 {  
    lcd_buf[2] = '1';
 }else
 {
   lcd_buf[2] = '0';
 } 
 
     if( sensor_input[RIGHT0] > sensor_border)
 {  
    lcd_buf[3] = '1';
 }else
 {
   lcd_buf[3] = '0';
 } 
 
 if( sensor_input[RIGHT1] > sensor_border)
 {  
    lcd_buf[4] = '1';
 }else
 {
   lcd_buf[4] = '0';
 } 

 if( sensor_input[RIGHT2] > sensor_border)
 {  
    lcd_buf[5] = '1';
 }else
 {
   lcd_buf[5] = '0';
 } 
 
 lcd_gotoxy(0,1);
 lcd_puts(lcd_buf);
      
 sprintf(lcd_buf, "compare ");
 lcd_gotoxy(0,0);
 lcd_puts(lcd_buf);
  
 delay_ms(500);
 
}
 
 
// 광량식
void auto_detect()
{  
 long sensor_temp = 0;
                             
   TCNT0 = 0xff; 
 TCCR0 = 0x03; //start timer, prescale 32   
 TIMSK = 0x01; //timer 0 interupt
 enable(); // interrupt enable
 
   for(i=0;i<2;i++)
   {
     delay_ms(50);   // 센서값을 읽을 시간을 벌어줌 
  sensor_temp = (long)sensor_temp + (long)(sensor_input[1]+sensor_input[2]+sensor_input[3]-sensor_input[4]-sensor_input[5]-sensor_input[6]);
    } 
        
    sensor_adjust = (int)(sensor_temp/2);
 
 lcd_gotoxy(0,0);
 lcd_putsf("auto    ");
 
 lcd_gotoxy(0,1);
 lcd_putsf("detect  ");
 delay_ms(200);
 
 
 sprintf(lcd_buf, "adjust ");
  lcd_gotoxy(0,0);
  lcd_puts(lcd_buf);
   
 sprintf(lcd_buf, "%8d", sensor_adjust);
  lcd_gotoxy(0,1);
  lcd_puts(lcd_buf);
  delay_ms(300); 
  
   sensor_adjust = -20;//(int)(sensor_temp/10);
  
}      

//비교식
void auto_detect_compare()
{  
 long sensor_temp = 0;
                             
   TCNT0 = 0xff; 
 TCCR0 = 0x03; //start timer, prescale 32   
 TIMSK = 0x01; //timer 0 interupt
 enable(); // interrupt enable
 
   for(i=0;i<10;i++)
   {
     delay_ms(100);   // 센서값을 읽을 시간을 벌어줌 
  for(j=1;j<7;j++)    // 1,2,3센서(white) vs 4,5,6센서(black)
      sensor_temp += sensor_input[j];
    } 
   
    sensor_border = (word)((float)sensor_temp/(float)60 /* 6x10 */);
      
 lcd_gotoxy(0,0);
 lcd_putsf("auto    ");
 
 lcd_gotoxy(0,1);
 lcd_putsf("detect  ");
 delay_ms(200);
 
 
 sprintf(lcd_buf, "border ");
  lcd_gotoxy(0,0);
  lcd_puts(lcd_buf);
   
 sprintf(lcd_buf, "%8d", sensor_border);
  lcd_gotoxy(0,1);
  lcd_puts(lcd_buf);
  delay_ms(1000); 
}
 

void system_init(void)
{
 disable();       

 port_init();
 //센서를 보호하기 위해 부팅하자마자 바로 꺼준다..점등식으로만 써야하므로..
 sen_off();
 //시끄러우니 일단 끄자..

 tlcd_init();
 motor_disable();  
 adc_init();
 delay_ms(1); 
 sensor_mode = SENSOR_MODE_OFF;
 
 enable();  
}    


void start_motor(void)
{
    disable();
  
 step_status = BOTH;
 
 l_phase_index = r_phase_index = 0;
 speed_limit = SPEED_LIMIT; 
 acc_index = SPEED_START; 

 OCR1AH = (acc_tbl[acc_index]>>8)&0xff;   // register high byte
 OCR1AL = acc_tbl[acc_index]&0xff;       // register low byte
 
 OCR3AH = (acc_tbl[acc_index]>>8)&0xff;   // register high byte
 OCR3AL = acc_tbl[acc_index]&0xff;       // register low byte
 
 TCCR1B = 0x09;          //clock/1
 TCCR3B = 0x09;          //clock/1
     
 TIMSK = 0x11;
 ETIMSK = 0x10;
 
 enable();
}  
   
void beep(void)
{
 buzzer_flag =1;
 delay_ms(100);
 buzzer_flag =0;
 delay_ms(100);
}
 


void cal_trim(void)
{
  handle_adjust_cur =(long)( (((long)handle_adjust_old*(long)HANDLE_RATE_OLD) + (long)(sensor_input[1]+sensor_input[2]+sensor_input[3]-sensor_input[4]-sensor_input[5]-sensor_input[6]-sensor_adjust)*(long)HANDLE_RATE_CUR ) / (long)100);
    handle_adjust_old = handle_adjust_cur;
   handle_adjust=(int)(handle_adjust_cur*(int)handle_gain);
  
   //범위를 넘으면 시스템이 죽으므로 처리
  if(handle_adjust > 60)
   handle_adjust = 60;
 
  if(handle_adjust < -60)
   handle_adjust = -60;     

}  

void cal_trim_compare(void)
{
  if( sensor_input[LEFT2] > sensor_border)
  {  
    handle_adjust = 12;
 }
 else if( sensor_input[RIGHT2] > sensor_border)
 {
   handle_adjust = 12;
 }
 else if( sensor_input[LEFT1] > sensor_border)
 {
   handle_adjust = 8;
 }
 else if( sensor_input[RIGHT1] > sensor_border)
 {
     handle_adjust = -8;
 } 
 else if( sensor_input[LEFT0] > sensor_border)
 {
  handle_adjust = 4;
 }
 else if( sensor_input[RIGHT0] > sensor_border)
 {
  handle_adjust = -4;
 }else
 {
  handle_adjust = 1;
 }
 
 handle_adjust= (word)((float)handle_adjust * (float)handle_gain); 
      
}


void cal_speed(void)
{    
        // 가속 테이블은 140을 기준으로 141~~ 속도를 느리게
        // 0~139는 속도를 빠르게 해준다..   
 step_status = ZERO;
 acc_index++;
 if (acc_index > speed_limit) acc_index = speed_limit;    
 time_l=(word)((acc_tbl[acc_index]*handle[140+handle_adjust])>>8);   
 time_r=(word)((acc_tbl[acc_index]*handle[140-handle_adjust])>>8);
}               

// left motor phase
interrupt [TIM1_COMPA] void timer1_compa_isr(void)
{
 l_phase_index--;
 l_phase_index &= FULL_STEP;
   
   MOTOR_PORT =  r_phase_table[r_phase_index] | l_phase_table[l_phase_index] ;
   
   step_status |= LEFT;
 
  if(step_status == BOTH)
   {  

  #if(MODE==LIGHT)
     cal_trim();
  #elseif(MODE==COMPARE)
    cal_trim_compare();
   #endif
   
     cal_speed();
    
    }
              
  OCR1AH = ( time_l >> 8 ) & 0xff;
 OCR1AL = time_l & 0xff; 
}

// right motor phase
interrupt [TIM3_COMPA] void timer3_compa_isr(void)
{
   r_phase_index++;
 r_phase_index &= FULL_STEP;
 
    MOTOR_PORT =  r_phase_table[r_phase_index] | l_phase_table[l_phase_index] ;
 
 step_status |= RIGHT;
  if(step_status == BOTH)
    {
  #if(MODE==LIGHT)
     cal_trim();
  #elseif(MODE==COMPARE)
    cal_trim_compare();
   #endif
       
     cal_speed();
    }
   
  OCR3AH = ( time_r >> 8 ) & 0xff;
 OCR3AL = time_r & 0xff;  
}

  
// ADC interrupt service routine
interrupt [ADC_INT] void adc_isr(void)
{    
    sensor_input[sensor_cnt]= ADCW; 
 sensor_cnt++;
 if(sensor_cnt>=8) sensor_cnt=0;
 ADMUX =  sensor_cnt; // adc cheannel select               
}
  
// Timer 0 overflow interrupt service routine
interrupt [TIM0_OVF] void timer0_ovf_isr(void)
{    
 TCCR0 = 0x00; 
 if(sensor_mode == SENSOR_MODE_OFF)
 {
         ADCSRA|=0x40; //하얀색 수광용
         sen_on();
       sensor_mode = SENSOR_MODE_ON;
       TCNT0 = (byte)(0xff -  (SENSOR_ON_TIME/TIMER0_32PRESCALE_VALUE));   
      TCCR0 = 0x03; //start timer     
    
 }else if(sensor_mode ==  SENSOR_MODE_ON)
 {       
   //ADCSRA|=0x40; //검정색 수광용
      sen_off();
     
      sensor_mode = SENSOR_MODE_OFF;  
        TCNT0 = (byte)(0xff -  (SENSOR_OFF_TIME/TIMER0_32PRESCALE_VALUE));  
         TCCR0 = 0x03; //start timer          
 }else if(sensor_mode== (SENSOR_MODE_OFF+1))   
  {
            lcd_gotoxy(0,1);
         lcd_putsf("SENSOR");
         disable();
 }
              
}

// Timer 2 overflow interrupt service routine
interrupt [TIM2_OVF] void timer2_ovf_isr(void)
{


}
      

void main(void)
{       
 system_init(); 
 #if(MODE==LIGHT)
    auto_detect();
 #elseif(MODE==COMPARE)
   auto_detect_compare(); 
  #endif
  
   start_motor();  

 enable(); // interrupt enable
 
 while (1)
 { 

          //display_handle();
         //display_sensor();
        //display_sensor_compare();
 }  
}


댓글 2
  • No Profile
    스위치를 쓰는 소스가 맞나요?
     DDRE = 0x08;    // joystick switch input, buzzer output(PORTE3)
    이 소스가 조이스틱 스위치로부터 입력을 받도록 io를 설정하는겁니다.
    스위치 입력은 구현이 안되어있네요.
    그냥 스위치 안달고 사용하시면 되비다.
  • No Profile

하드웨어 설계 및 개발에 대하여 개발자들이 자유롭게 토론하는 공간입니다.
- Q&A, 자유주재 토론, 관련 정보 공유
- 분야 : 마이크로프로세서 응용, 전기/전자(아날로그/디지털) 회로 설계, C/C++ 프로그래밍, 펌웨어,
         PCB Artwork, 트러블슈팅 등 하드웨어 설계에 관한 전반인 내용
※ 게시글에 맞는 분류를 선택하여 글을 작성해 주시면 쾌적한 사이트 운영에 많은 도움이 됩니다.
※ 하드웨어 인사이트는 회원들간의 거래정보를 게재할 뿐이지, 그 어떤 책임과 의무도 가지지 않습니다.

search
번호 분류 제목 글쓴이 조회 수 날짜
46 개발용역 HOT의뢰:arm으로 펌웨어 개발 해 주실분 있을까요? 땜고수 5178 2010.04.29
45 개발용역 HOT프리랜서 또는 정규직 pic dsp pwm 설계및 개발직모집 연락바랍니다1 요세스키 9423 2010.04.14
44 개발용역 HOT운영자님 및 전문가 여러분께, 개발 관련 문의드립니다.3 랜시스 4430 2010.04.08
43 개발용역 HOTTI C6000 관련 개발 가능하신 분! motionix 4683 2010.02.22
42 개발용역 HOT전력전자 관련한 펨웨어 개발자 모집 합니다. 마정 5274 2010.01.19
41 개발용역 HOTC8051F310으로 Sensorless Motor 제어 프로그램 개발 모젠 5388 2010.01.07
40 개발용역 HOT대학에서 2월까지 모터 구동 아르바이트 하실 분2 남지우 5080 2010.01.07
39 개발용역 HOT하드웨어 설계 및 개발 & 소프트웨어 개발 & PCB 아트웍 해드립니다.5 테나르 9971 2010.01.07
38 개발용역 HOT소프트웨어 알바로 개발 하실분 게시나요5 신지 6877 2009.12.07
37 개발용역 HOTpcb 아트웍 소개1 천사토끼 8652 2009.10.21
36 개발용역 HOT콘덴서 마이크가 AVR16으로 잡는데 신호가 잘 안들어옵니다.5 화니이 4337 2009.08.19
35 개발용역 HOT광센서 LED 기판..이런거 의뢰 가능한가요?4 최대한 3782 2009.08.12
34 개발용역 HOTPCB설계 및 H/W 개발 프리랜서&알바 bobby 6886 2009.08.07
33 개발용역 HOTPCB 설계 (Artwork) take,take,take 3832 2009.07.06
32 개발용역 HOTS/W 개발의뢰 합니다. 전설의교양 4788 2009.07.01
31 개발용역 HOTpads 정규직 채용합니다 세라 3789 2009.06.22
30 개발용역 HOT개발의뢰합니다. 모션맨 3886 2009.06.21
29 개발용역 HOT제작의뢰 합니다. kwanho84 3812 2009.03.23
28 개발용역 HOT프리랜서 혹은 정규직 모십니다. 레컬 4601 2009.03.13
27 개발용역 HOT"저렴한 가격으로, 최고의 품질을!!" ARTWORK 해드립니다!!3 아트비젼 4389 2009.01.29
Prev 1 ... 3 4 5 6 7 8 9 10 11 12 Next
  • 이집트는 나일강의 선물.
    - 헤로도토스
  • * 납포인트 정보 *
  • 글 작성 : 3
  • 댓글 작성 : 1
  • 내 글이 추천받음 : 1
저작권법에 위배되는 콘텐츠는 등록 불가하며, 저작물에 대한 권리는 저작자에게 있습니다.
Copyright 2006-2021 © hardwareis.com, All rights reserved.