PWM 제어로 할려구 하는데요.
PWM은 PE3
en은 PE1
dir은 PE2 이렇게 연결했습니다.
밑에 써놓은 것은 정회전입니다.
DDRE = 0xFF;
TCCR3A = 0b10101010;
TCCR3B = 0b00011010;
TCNT3 = 0;
ICR3 = 1000;
PORTE=0b00000010;
OCR3A = 2000;
그래서 역방향으로 할려면 빨간색인 부분을 바꿔야 될 것 같아서
제 생각대로 바꿔봤는데 잘 안바뀌네요;;;
여기서 어떻게 해야 역방향으로 돌까요 ㅠㅠ
(모터 드라이버는 http://www.devicemart.co.kr/mart7/mall.php?cat=017012005&query=view&no=15731 입니다.)
듀티비를 쪽을 참고해보세요
이상하네요..... 역회전이 안되네요..... 정지해버려요.....
다른 방법 없을 까요?
만약 정회전이 정상적으로 되고 있다면 역회전도 무리없이 되야 할텐데...
소스코드를 전부다 올려 보시죠..
#include <avr/io.h>
#include <string.h>
// Address MAP
#define LCD_EN (*(volatile unsigned char *)0x8000)
#define LCD_WRITE (*(volatile unsigned char *)0x8002)
#define ENC1_DATA (*(volatile unsigned char *)0x8010)
#define ENC1_CNTL (*(volatile unsigned char *)0x8011)
#define ENC2_DATA (*(volatile unsigned char *)0x8020)
#define ENC2_CNTL (*(volatile unsigned char *)0x8021)
// LCD Control Params
#define LINE1 0x00 //LCD_DISPLAY_LINE1
#define LINE2 0x40 //LCD_DISPLAY_LINE2
// 7166 Control Params
#define MASTER_RESET 0x20 // master reset command
#define INPUT_SETUP 0x48 // setup counter input mode
#define QUAD_X1 0xC1 // quadrature multiplier to 1
#define QUAD_X2 0xC2 // quadrature multiplier to 2
#define QUAD_X4 0xC3 // quadrature multiplier to 4
#define ADDR_RESET 0x01 // reset address pointer
#define LATCH_CNTL 0x02 // latch counter
#define CNTL_RESET 0x04 // reset counter
#define PRESET_CNTL 0x08 // transfer preset to counter
#define OUTPUT_SETUP 0x80
void delay_us(unsigned char);
void delay_ms(unsigned int);
void FunctionSet();
void DisplayOnOffControl();
void DisplayClear();
void EntryModeSet();
void DisplayChar(unsigned char);
void DisplayString(unsigned char *);
void SetLCDAddress(unsigned char);
void DisplayInt(unsigned int);
void InitEncoder();
void PresetEncoder( unsigned char channel, unsigned char c3, unsigned char c2, unsigned char c1);
unsigned long ReadEncoder( unsigned char channel );
int main(void)
{
MCUCR = 0x80;
XMCRA = 0x40;
XMCRB = 0x80;
// LCD 초기화
FunctionSet(); // CPU와의 Interface를 4bit로 할것인지/8bit로 할 것인지 결정
DisplayOnOffControl(); // Display를 On
DisplayClear(); // 화면을 지우는 것
EntryModeSet(); // 화면 출력 방식 결정
delay_us(200);
SetLCDAddress(LINE1);
DisplayString("PROGRAM");
SetLCDAddress(LINE2);
DisplayString("STARTED");
// 7166 초기화
InitEncoder();
PresetEncoder( 1, 0x10, 0x00, 0x00 ); // Preset 0x100000
PresetEncoder( 2, 0x10, 0x00, 0x00 ); // Preset 0x100000
DDRE = 0xFF;
PORTE = 0x00;
//Timer setting
TCCR3A = 0b10101010;
TCCR3B = 0b00011010;
TCNT3 = 0;
ICR3 = 1000;
PORTE = 0b00000010;
OCR3A = 2000;
while(1){
}
}
void InitEncoder( void )
{
ENC1_CNTL = MASTER_RESET;
ENC1_CNTL = OUTPUT_SETUP;
ENC1_CNTL = INPUT_SETUP;
ENC1_CNTL = QUAD_X4;
ENC1_CNTL = CNTL_RESET;
ENC1_CNTL = ADDR_RESET;
ENC2_CNTL = MASTER_RESET;
ENC2_CNTL = OUTPUT_SETUP;
ENC2_CNTL = INPUT_SETUP;
ENC2_CNTL = QUAD_X4;
ENC2_CNTL = CNTL_RESET;
ENC2_CNTL = ADDR_RESET;
}
void PresetEncoder( unsigned char channel, unsigned char c3, unsigned char c2, unsigned char c1)
{
if( channel == 1 ) {
ENC1_CNTL = ADDR_RESET;
ENC1_DATA = c1;
ENC1_DATA = c2;
ENC1_DATA = c3;
ENC1_CNTL = PRESET_CNTL;
}
else if(channel == 2) {
ENC2_CNTL = ADDR_RESET;
ENC2_DATA = c1;
ENC2_DATA = c2;
ENC2_DATA = c3;
ENC2_CNTL = PRESET_CNTL;
}
}
unsigned long ReadEncoder( unsigned char channel )
{
long position=0;
if( channel == 1 ) {
ENC1_CNTL = LATCH_CNTL;
ENC1_CNTL = ADDR_RESET;
position = (unsigned long)ENC1_DATA;
position += (unsigned long)ENC1_DATA << 8;
position += (unsigned long)ENC1_DATA << 16;
}
else if( channel == 2 ) {
ENC2_CNTL = LATCH_CNTL;
ENC2_CNTL = ADDR_RESET;
position = (unsigned long)ENC2_DATA;
position += (unsigned long)ENC2_DATA << 8;
position += (unsigned long)ENC2_DATA << 16;
}
return position;
}
void DisplayInt( unsigned int cnt )
{
unsigned char c1, c2, c3, c4, tmp;
c4 = cnt/1000; // c4 = 1
c3 = (cnt % 1000)/100; // c3 = (245)/100 = 2
tmp = cnt % 100; // tmp = 45
c2 = tmp/10;
c1 = tmp%10;
DisplayChar(c4+48);
DisplayChar(c3+0x30);
DisplayChar(c2+0x30);
DisplayChar(c1+0x30);
}
void delay_us(unsigned char time_us)
{
register unsigned char i;
for(i=0;i<time_us;i++) // 4 cycles
{
asm volatile("PUSH R0"); // 2 cycles
asm volatile("POP R0"); // 2 cycles
asm volatile("PUSH R0"); // 2 cycles;
asm volatile("POP R0"); // 2 cycles;
asm volatile("PUSH R0"); // 2 cycles;
asm volatile("POP R0"); // 2 cycles;
}
}
void delay_ms(unsigned int time_ms)
{
register unsigned int i;
for(i=0;i<time_ms;i++)
{
delay_us(250);
delay_us(250);
delay_us(250);
delay_us(250);
}
}
void DisplayChar(unsigned char c)
{
LCD_WRITE = c;
delay_us(50);
}
void DisplayString(unsigned char* s)
{
unsigned char i, j;
i = 0;
j = strlen(s);
for(i=0;i<j;i++) {
DisplayChar(s[i]);
}
}
void SetLCDAddress(unsigned char mode)
{
LCD_EN = (0x80 | mode);
delay_us(50);
}
void FunctionSet()
{
delay_us(40);
LCD_EN = 0x38;
}
void DisplayOnOffControl()
{
delay_us(40);
LCD_EN = 0x0c;
}
void DisplayClear()
{
delay_us(40);
LCD_EN = 0x01;
}
void EntryModeSet()
{
delay_ms(2);
LCD_EN = 0x06;
delay_us(40);
}
왜...이럴까요?ㅜ
수정하다 보니 제가 잘못한 점을 알아서 이제 역회전으로 돌기 시작했어요
감사합니다. 신경써주셔서ㅜ^^