BASIC4MCU | 질문게시판 | 아트메가 코드에 대해서 질문하겠습니다!
페이지 정보
작성자 어테일 작성일2018-09-02 01:30 조회7,015회 댓글0건본문
#include <avr/io.h>
#include <stdio.h>
#include <avr/signal.h>
#include <avr/interrupt.h>
#include <avr/pgmspace.h>
#include <avr/eeprom.h>
#include <avr/wdt.h>
#define BV(bit) (1<<(bit)) /* bit processing */
#define cbi(reg,bit) reg &= ~(BV(bit))
#define sbi(reg,bit) reg |= (BV(bit))
#define MOTOR_ON sbi(PORTG,0)
#define MOTOR_OFF cbi(PORTG,0)
volatile unsigned int value,wg,wg2,H,M,L,HC,MC,LC;
volatile unsigned char k,count,i,step,en;
volatile unsigned char data232[8]; // 총8개의 패킷을 저장할 공간을 설정 232
volatile unsigned char j=0;
volatile unsigned char int_f=0, command_f=0;
void MCU_initialize(void) { /* initialize ATmege128 MCU */
MCUCR = 0x00; // enable external memory and I/O
XMCRA = 0x44; // 0x1100-0x7FFF=1 wait, 0x8000-0xFFFF=0 wait
XMCRB = 0x80; // enable bus keeper, use PC0-PC7 as address
DDRA = 0xFF;
PORTA = 0x00;
DDRB = 0xFF;
PORTB = 0xFF;
DDRC = 0xFF; // PC7-PC4 = output
PORTC = 0x00;
DDRD = 0x00; // PORTD = output
PORTD = 0x00;
DDRE = 0x80; // PE5-PE0 = output, PE7-PE6 = input
PORTE = 0x00;
DDRF = 0x00; // PORTF = input
PORTF = 0x00;
DDRG = 0xff; // PORTG = output
PORTG = 0x02;
}
//------------------------------------------------------------------------------
void Delay_us(unsigned int time_us) /* time delay for us */
{ register unsigned int i;
for(i = 0; i < time_us; i++) // 4 cycle +
{ asm volatile(" PUSH R0 "); // 2 cycle +
asm volatile(" POP R0 "); // 2 cycle +
asm volatile(" PUSH R0 "); // 2 cycle +
asm volatile(" POP R0 "); // 2 cycle +
asm volatile(" PUSH R0 "); // 2 cycle +
asm volatile(" POP R0 "); // 2 cycle = 16 cycle = 1 us for 16MHz
}
}
//------------------------------------------------------------------------------
void Delay_ms(unsigned int time_ms) /* time delay for 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 LCD_command(unsigned char command) /* write a command(instruction) to text LCD */
{
PORTC = 0x00; // E = 0, Rs = 0
PORTA = command; // output command
PORTC = 0x01; // E = 1
Delay_us(1);
PORTC = 0x00; // E = 0
Delay_us(50);
}
//------------------------------------------------------------------------------
void LCD_data(unsigned char data) /* display a character on text LCD */
{
PORTC = 0x02; // E = 0, Rs = 1
PORTA = data; // output data
PORTC = 0x03; // E = 1
Delay_us(1);
PORTC = 0x02; // E = 0
Delay_us(50);
}
//------------------------------------------------------------------------------
void LCD_string(unsigned char command, unsigned char *string) /* display a string on LCD */
{
LCD_command(command); // start position of string
while(*string != '\0') // display string
{ LCD_data(*string);
string++;
}
}
//------------------------------------------------------------------------------
void LCD_initialize(void) /* initialize text LCD module */
{
PORTC = 0x03; // E = 1, Rs = 1 (dummy write)
PORTC = 0x02; // E = 0, Rs = 1
Delay_ms(2);
LCD_command(0x38); // function set(8 bit, 2 line, 5x7 dot)
LCD_command(0x0C); // display control(display ON, cursor OFF)
LCD_command(0x06); // entry mode set(increment, not shift)
LCD_command(0x01); // clear display
Delay_ms(2);
}
//------------------------------------------------------------------------------
void LCD_d4(int number) { //
unsigned int i, j, k, z;
i = number / 1000;
j = number % 1000;
if(i == 0) {LCD_data(' '); z = 1;} // 0일경우
else {LCD_data(i + '0'); z = 0;} // 값이 있을경우
//---------------------------
k = j / 100;
i = j % 100;
if(z == 0) {LCD_data(k + '0');}
else {
if(k == 0) {LCD_data(' '); z = 1;}
else {LCD_data(k + '0'); z = 0;}
}
//---------------------------
j = i / 10;
k = i % 10;
if(z == 0) {LCD_data(j + '0');}
else {
if(j == 0) {LCD_data(' ');}
else {LCD_data(j + '0');}
}
LCD_data(k + '0');
}
//------------------------------------------------------------------------------
void LCD_d3(int number) { //
unsigned int i, j, k;
i = number / 100; // 10^1
if(i == 0) LCD_data(' '); // 0일경우
else LCD_data(i + '0'); // 값이 있을경우
j = number % 100; // 10^0
//---------------------------
i = j / 10;
LCD_data(i + '0');
k = j % 10;
LCD_data('.');
LCD_data(k + '0');
}
//------------------------------------------------------------------------------
void LCD_d2(int number) { //
unsigned int i, j;
i = number / 10; // 10^1
if(i == 0) LCD_data(' '); // 0일경우
else LCD_data(i + '0'); // 값이 있을경우
j = number % 10; // 10^0
LCD_data(j + '0');
}
//------------------------------------------------------------------------------
void rc1_forward(void) { //서보모터 출력
for ( i=0; i < 80; i++) { // 60 회 펄스 출력
PORTB |= _BV(0); // 서보모터 펄스 hi출력
Delay_us(250);
Delay_us(250);
Delay_us(100);
PORTB &= ~_BV(0); // 서보모터 펄스 low출력
Delay_ms(10);
}
PORTB = 0xFF;
}
//------------------------------------------------------------------------------
void rc1_back(void) { //서보모터 출력
for ( i=0; i < 80; i++) { // 60 회 펄스 출력
PORTB |= _BV(0); // 서보모터 펄스 hi출력
Delay_ms(2);
Delay_us(100);
//Delay_us(150);
PORTB &= ~_BV(0); // 서보모터 펄스 low출력
Delay_ms(10);
}
PORTB = 0xFF;
}
//------------------------------------------------------------------------------
void rc2_forward(void) { //서보모터 출력
for ( i=0; i < 80; i++) { // 60 회 펄스 출력
PORTB |= _BV(5); // 서보모터 펄스 hi출력
Delay_us(250);
Delay_us(250);
//Delay_us(100);
PORTB &= ~_BV(5); // 서보모터 펄스 low출력
Delay_ms(10);
}
PORTB = 0xFF;
}
//------------------------------------------------------------------------------
void rc2_back(void) { //서보모터 출력
for ( i=0; i < 80; i++) { // 60 회 펄스 출력
PORTB |= _BV(5); // 서보모터 펄스 hi출력
Delay_ms(2);
Delay_us(250);
//Delay_us(50);
PORTB &= ~_BV(5); // 서보모터 펄스 low출력
Delay_ms(10);
}
PORTB = 0xFF;
}
//------------------------------------------------------------------------------
void rc3_forward(void) { //서보모터 출력
for ( i=0; i < 80; i++) { // 60 회 펄스 출력
PORTB |= _BV(6); // 서보모fw터 펄스 hi출력
Delay_us(250);
Delay_us(250);
//Delay_us(100);
PORTB &= ~_BV(6); // 서보모터 펄스 low출력
Delay_ms(10);
}
PORTB = 0xFF;
}
//------------------------------------------------------------------------------
void rc3_back(void) { //서보모터 출력
for ( i=0; i < 80; i++) { // 60 회 펄스 출력
PORTB |= _BV(6); // 서보모터 펄스 hi출력
Delay_ms(2);
Delay_us(250);
//Delay_us(50);
PORTB &= ~_BV(6); // 서보모터 펄스 low출력
Delay_ms(10);
}
PORTB = 0xFF;
}
//------------------------------------------------------------------------------
void rc4_forward(void) { //서보모터 출력
for ( i=0; i < 80; i++) { // 60 회 펄스 출력
PORTB |= _BV(7); // 서보모터 펄스 hi출력
Delay_us(250);
Delay_us(250);
//Delay_us(100);
PORTB &= ~_BV(7); // 서보모터 펄스 low출력
Delay_ms(10);
}
PORTB = 0xFF;
}
//------------------------------------------------------------------------------
void rc4_back(void) { //서보모터 출력
for ( i=0; i < 80; i++) { // 60 회 펄스 출력
PORTB |= _BV(7); // 서보모터 펄스 hi출력
Delay_ms(2);
Delay_us(250);
//Delay_us(50);
PORTB &= ~_BV(7); // 서보모터 펄스 low출력
Delay_ms(10);
}
PORTB = 0xFF;
}
//------------------------------------------------------------------------------
/*SIGNAL(SIG_INTERRUPT0) {
}*/
//---------------------------------------수신 -------------------------------------------
//57 W
//32 2
//2E .
//32 2
//0D
//0A
SIGNAL(SIG_UART1_RECV) { // 수신인터럽트 함수
unsigned char value;
value=UDR1; // 수신이 완료되면 데이터를 저장한다
if(value==0x57) { // 되돌아온 신호중 헤더인가?
if(int_f == 0) {
k=0;
data232[k]=value; // 데이터 0에 0x02 값 저장
int_f=1; // 헤더플래그 셋
}
}
if((int_f==1) && (command_f==0)) { // 헤더는 받았으나 아직 나머지 데이터를 못받은경우
data232[k]=value;
if(value==0x2E) { // 소수점인가?
command_f=1; // 명령플래그 셋,
//----------------------------------------------------------------
if(k == 2) { // 1단위
data232[1] = data232[1]&0x0f;
wg2 = 0;
wg2 += data232[1];
wg = wg2;
}
if(k == 3) { // 2단위
data232[1] = data232[1]&0x0f;
data232[2] = data232[2]&0x0f;
wg2 = 0;
wg2 += data232[2];
wg2 += data232[1] * 10;
wg = wg2;
}
if(k == 4) { // 3단위
data232[1] = data232[1]&0x0f;
data232[2] = data232[2]&0x0f;
data232[3] = data232[3]&0x0f;
wg2 = 0;
wg2 += data232[3];
wg2 += data232[2] * 10;
wg2 += data232[1] * 100;
wg = wg2;
}
if(k == 5) { // 4단위
data232[1] = data232[1]&0x0f;
data232[2] = data232[2]&0x0f;
data232[3] = data232[3]&0x0f;
data232[4] = data232[4]&0x0f;
wg2 = 0;
wg2 += data232[4];
wg2 += data232[3] * 10;
wg2 += data232[2] * 100;
wg2 += data232[1] * 1000;
wg = wg2;
}
int_f=0;
command_f=0; // 명령플래그 클리어
LCD_command(0xC8); // LCD 줄 설정
LCD_d4(wg);
//--------------------------------------------------------------
}
k++;
}
}
//------------------------------------------------------------------------------
int main(void) {
MCU_initialize(); // 시스템 초기화
//-----통신 설정--------------------------------------------------------
UBRR1H = 0; // 9600 baud at 16
UBRR1L = 103; // 9600 baud at 16
UCSR1A = 0x00; // asynchronous normal mode
UCSR1B = 0x98; // Rx/Tx enable, 8 data 수신 완료 인터럽트 허용
UCSR1C = 0x06; // no parity, 1 stop, 8 data
//--------PWM 설정 타이머 0를 사용 --------------- 좌우 스피드
TCCR0 = 0x61;
OCR0 = 180; // 기본 설정
//------------------------------------------------
LCD_initialize();
Delay_ms(100);
LCD_string(0x80,"H= M= ");
LCD_string(0xC0,"L= ");
//------기준 무게 설정 ---------------------------
H = 150;
M = 100;
L = 50;
LCD_command(0x82); // LCD 줄 설정
LCD_d4(H);
LCD_command(0x8A); // LCD 줄 설정
LCD_d4(M);
LCD_command(0xC2); // LCD 줄 설정
LCD_d4(L);
rc1_back();
rc2_back();
rc3_back();
rc4_back();
Delay_ms(1000);
Delay_ms(1000);
Delay_ms(1000);
LCD_string(0x80," L= M= H= ");
LCD_string(0xC0,"weight = g ");
HC = 0;
MC = 0;
LC = 0;
LCD_command(0x83); // LCD 줄 설정
LCD_d2(LC);
LCD_command(0x88); // LCD 줄 설정
LCD_d2(MC);
LCD_command(0x8D); // LCD 줄 설정
LCD_d2(HC);
wg = 0;
step = 0;
sei();
do {
if(step == 0) { // 무게 감지 단계
if(wg > 10) { // 10그람 이상되어야 함
count++;
if(count > 30) {
if((wg >= 0) && (wg <= 50)) {step = 1;} // L 이송단계로 이동
else if((wg > 50) && (wg <= 100)) {step = 2;} // M 이송단계로 이동
else if((wg > 100) && (wg <= 150)) {step = 3;} // H 이송단계로 이동
else {step = 3;} // H 이송단계로 이동
rc1_forward();
Delay_ms(1000);
rc1_back();
MOTOR_ON;
}
}
else {
count = 0;
}
}
//---------------------------------
if(step == 1) { // L 이송단계 단계
if(!(PIND & 0x10)) {
MOTOR_OFF;
Delay_ms(1000);
rc2_forward();
Delay_ms(1000);
rc2_back();
LC++;
LCD_command(0x83); // LCD 줄 설정
LCD_d2(LC);
step = 0; // 무게 감지 단계로 이동
}
}
//---------------------------------
if(step == 2) { // M 이송단계 단계
if(!(PIND & 0x20)) {
MOTOR_OFF;
Delay_ms(1000);
rc3_forward();
Delay_ms(1000);
rc3_back();
MC++;
LCD_command(0x88); // LCD 줄 설정
LCD_d2(MC);
step = 0; // 무게 감지 단계로 이동
}
}
//---------------------------------
if(
== 3) { // H 이송단계 단계
if(!(PIND & 0x40)) {
MOTOR_OFF;
Delay_ms(1000);
rc4_forward();
Delay_ms(1000);
rc4_back();
HC++;
LCD_command(0x8D); // LCD 줄 설정
LCD_d2(HC);
step = 0; // 무게 감지 단계로 이동
}
}
//-------------------------------------
if(!(PIND & 0x01)) {
MOTOR_OFF;
do{
Delay_ms(1000);
}while(1);
}
Delay_ms(100);
}while(1);
}
팀 과제로 중량선별기를 제작하고 있습니다. 그런데 중간에 함수로 지정된 부분에서 rc1~4 이 부분에서 hi 출력 low 출력이 이해가 잘 되지 않아서 질문 드립니다. 저런 함수 정의로 모터의 펄스를 줄 수 있나요??
댓글 0
조회수 7,015등록된 댓글이 없습니다.