사용 장비 : avr28
공학하는 여자입니당.. C언어도 겨우겨우 했는뎅 avr은 너무 어렵네영
빨간색 부분만 해석좀요 부탁드려요 ㅠ 보기 쉽게 줄로 쳐놨어용 부탁점영
학생이라서 돈이 별루 없습니다.
원하시다면 소정의 돈은 드릴수 있어요 ㅠ
키버튼과 LCD, 모터를 이용하였구요
모니터에는 문자 출력되구..
키버튼을 누르면 모터큰거(이름이 서브말구.. 뭐였더라 ; 오늘배워서 잘..)왼쪽 오른쪽 돌기도하고 그러거든요 ㅠㅠ
몰라서 혼나기만 하구...
#include <avr/io.h>
#include <avr/interrupt.h>
#include <stdio.h>
-----------------------------------------------------------------------------------------------------------------------
#define MOTOR_CW (PORTE &= 0xFB)
#define MOTOR_CCW (PORTE |= 0x04)
#define MOTOR_STOP (PORTE &= 0xFD)
#define MOTOR_ENABLE (PORTE |= 0x02)
#define FREQ_CLK10 160000 // clock 10 16Mhz/100
#define PRESCALE 64
#define FREQ_REFER 1000 // 1Khz(1msec)
------------------------------------------------------------------------------------------------------------------------
#define LCD_RS_1 (PORTG |= 0x01)
#define LCD_RS_0 (PORTG &= 0xFE)
#define LCD_RW_1 (PORTG |= 0x02)
#define LCD_RW_0 (PORTG &= 0xFD)
#define EN_1 (PORTG |= 0x04)
#define EN_0 (PORTG &= 0xFB)
#define NoKey 0xff
unsigned char KeyValue = 0xff;
void us_delay(unsigned int us_time)
{
unsigned int i;
for(i=0; i<us_time; i++) // 4 cycle +
{
asm("PUSH R0"); // 2 cycle +
asm("POP R0"); // 2 cycle +
asm("PUSH R0"); // 2 cycle +
asm("POP R0"); // 2 cycle + =12 cycle for 11.0592MHZ
asm("PUSH R0"); // 2 cycle +
asm("POP R0"); // 2 cycle = 16 cycle = 1us for 16MHz
}
}
void ms_delay(unsigned int ms_time)
{
unsigned int i;
for(i=0; i<ms_time;i++)
us_delay(1000);
}
void E_Pulse(void)
{
EN_1;
us_delay(100);
EN_0;
}
void LCD_init(void)
{
ms_delay(40);
PORTC = 0x38; // Function Set
E_Pulse();
us_delay(40);
PORTC = 0x0c; // DisPlay ON/OFF Control
us_delay(40);
E_Pulse();
PORTC = 0x01; // Display Clear
ms_delay(2);
E_Pulse();
PORTC = 0x06; // Entry Mode Set
E_Pulse();
}
void Write_Char(unsigned char buf)
{
LCD_RS_1;
LCD_RW_0;
PORTC=buf;
E_Pulse();
}
void LCD_Disp(char x,char y)
{
LCD_RS_0;
LCD_RW_0;
if(y == 0)
PORTC = x + 0x80;
else if(y==1)
PORTC = x + 0xc0;
E_Pulse();
}
/*
void LCD_Write1(char x, char y,char *str1)
{
LCD_Disp(x,y);
//while(*str1)
Write_Char(*str1);
}*/
void LCD_Write(char x, char y,char *str)
{
LCD_Disp(x,y);
while(*str)
Write_Char(*str++);
}
void LCD_Write_char(char x, char y, unsigned char ch)
{
LCD_Disp(x,y);
Write_Char(ch);
}
void KeyOut(char ot)
{
PORTA=ot;
}
char KeyIn(void)
{
unsigned char Nibble;
Nibble=(PINA & 0xf0)>>4;
Nibble=Nibble & 0x0f;
return Nibble;
}
void KeyScan(void)
{
unsigned char key=0, key_cnt;
unsigned char OTkey=0xfe, KeyBuff;
KeyBuff=NoKey;
for (key_cnt=0;key_cnt<4;key_cnt++)
{
KeyOut(OTkey);
key=KeyIn();
if(key==0x0e)
KeyBuff=0+key_cnt;
else if(key==0x0d)
KeyBuff=4+key_cnt;
else if(key==0x0b)
KeyBuff=8+key_cnt;
else if(key==0x07)
KeyBuff=12+key_cnt;
OTkey=(OTkey<<1)+1;
}
if(KeyBuff != NoKey)
KeyValue = KeyBuff;
}
-----------------------------------------------------------------------------------------------------------------------------
// motor control
void initStepMotor(void)
{
TCCR3A = 0xAA; // COM3A[1:0] = 10. 비교일치시 클리어
// TOP 셋
// WGM3[3:0] = 1010, Phase correct PWM mode
// TOP값은 ICR 레지스터가 결정
TCCR3B = 0x13;
ICR3 = 249; // 최고값 250(2msec)
OCR3A = 90; // 최저값 (duty rate 결정, 클수록 커짐)
// OC3A를 출력을 설정(PE3)
}
void CtrlStepMotor(unsigned int speed)
{
if(speed >= 150)
speed = 150;
ICR3 = (FREQ_CLK10 / (2*PRESCALE*2*speed))*60;
// 200Hz/100 // RPM 단위로 환산
}
void initPort()
{
DDRA = 0x0f; // keypad 제어
DDRC = 0xff; // LCD 데이터
DDRG = 0xff; // LCD 제어
DDRE = 0xff; // 모터펄스, 방향 인에이블
}
int main(void)
{
char strBuff[20]={0};
int speed = 0;
initPort();
LCD_init();
initStepMotor();
-----------------------------------------------------------------------------------------------------------------------------
sprintf(strBuff,"Welcome");
LCD_Write(0,0,strBuff);
ms_delay(500);
sprintf(strBuff,"Step Motor");
LCD_Write(0,0,strBuff);
sprintf(strBuff," ");
LCD_Write(0,1,strBuff);
-----------------------------------------------------------------------------------------------------------------------------
while(1)
{
KeyScan();
if(KeyValue == 0)
{
MOTOR_STOP;
}
else if(KeyValue == 1)
{
MOTOR_ENABLE;
}
else if(KeyValue == 2)
{
MOTOR_CCW;
}
else if(KeyValue == 3)
{
MOTOR_CW;
}
else if(KeyValue == 4)
{
speed =40;
CtrlStepMotor(speed);
}
else if(KeyValue == 5)
{
speed =60;
CtrlStepMotor(speed);
}
else if(KeyValue == 6)
{
speed =80;
CtrlStepMotor(speed);
}
else if(KeyValue == 7)
{
speed =100;
CtrlStepMotor(speed);
}
if(PORTE & 0x04)
sprintf(strBuff,"Dir = CCW:%3drpm", speed);
else
sprintf(strBuff,"DIr = CW : %3drpm", speed);
LCD_Write(0,1,strBuff);
}
return 0;
}
-----------------------------------------------------------------------------------------------------------------------------
스펙시트를 참고하셔서 특정 레지스터가 어떤 기능을 하고 이런 값일때는 요런 설정이다 뭐 정도는 스스로 찾아보셔야 할거 같은데요;;;
위에 분 말씀데로 스펙시트를 참고하셔야 하지만 일단은 제가 아는 내용만 설명 드릴께요
모터는 스테핑 모터를 사용하시는거 같습니다.
그리고 아래 내용은 스테핑 모터를 사용하는데 필요한 입,출력 포트를 정의한 내용이고요
#define MOTOR_CW (PORTE &= 0xFB) --> 모터를 Clock wise 즉 시계 방향으로 회전 시킬때 사용하는 포트 정의
#define MOTOR_CCW (PORTE |= 0x04) --> 모터를 Count Clock wise 즉 반시계 방향으로 회전 시킬때 사용하는 포트 정의
#define MOTOR_STOP (PORTE &= 0xFD) --> 모터를 정지 시키기 위한 포트 정의
#define MOTOR_ENABLE (PORTE |= 0x02) --> 모터 제어를 사용하기 위한 enable 포트 정의
#define FREQ_CLK10 160000 // clock 10 16Mhz/100 --> 스테핑 모터는 펄스 즉 주파수로 작동을 합니다. 그거에 대한 정의입니다. 모터 스펙을 참고하시면 될거 같습니다.
#define PRESCALE 64 --> 이것은 기억이 가물가물 하네요 죄송합니다. ^^;
#define FREQ_REFER 1000 // 1Khz(1msec) --> 요것두 기억이 잘~~ ^^;
저두 배워가는 입장이라서 고수분들 제가 알고 있는게 맞는가요?