AVR & ATmega

Motion Controller(Atmega128) 기본 Program

EP 기술연구소 2007. 11. 4. 20:07

/****************************************************************************
  Project : Motion Controller
  Version : 1.0
  Date    : 2007-10-17 10:59오후
  Author  : JW Park(kornanp@empal.com)
  Company : EPIANICS Co., Ltd (Electronic Utopia)
  Comments:
  
  Chip type           : ATmega128
  Program type        : Application
  Clock frequency     : 16.000000 MHz
  Memory model        : Small
  External SRAM size  : 0
  Data Stack size     : 1024
  
  Note :
   1.
****************************************************************************/
#include <Mega128.h>
#include <stdio.h>  // Standard Input/Output functions

#include "PipeCut.h"   // Header file of Pipe Cutting machine control
#include "PipeCut_sub.c"  // Subroutine of Pipe Cutting machine control
#include "LoadCtl.c"   // Magnet switch & Micro switch sensing check
#include "ADC_control.c"  // AD Converter control Routine
#include "CharLCD_Control.c" // LCD Module control routine (Charicter LCD)
#include "E2p_2402.C"  // Eeprom Control

/*==========================================
// External Interrupt 0 service routine
============================================*/
interrupt [EXT_INT0] void ext_int0_isr(void)
{
 // Place your code here

}

/*==========================================
// USART0 Receiver interrupt service routine
============================================*/
#define RXB8 1
#define TXB8 0
#define UPE 2
#define OVR 3
#define FE 4
#define UDRE 5
#define RXC 7

#define FRAMING_ERROR (1<<FE)
#define PARITY_ERROR (1<<UPE)
#define DATA_OVERRUN (1<<OVR)
#define DATA_REGISTER_EMPTY (1<<UDRE)
#define RX_COMPLETE (1<<RXC)

// USART0 Receiver buffer
#define RX_BUFFER_SIZE0 8
char rx_buffer0[RX_BUFFER_SIZE0];
unsigned char rx_wr_index0,rx_rd_index0,rx_counter0;
// This flag is set on USART0 Receiver buffer overflow
bit rx_buffer_overflow0;

// USART0 Receiver interrupt service routine
#pragma savereg-
interrupt [USART0_RXC] void uart0_rx_isr(void)
{
 char status,data;
#asm
    push r26
    push r27
    push r30
    push r31
    in   r26,sreg
    push r26
#endasm
 status=UCSR0A;
 data=UDR0;
 if ((status & (FRAMING_ERROR | PARITY_ERROR | DATA_OVERRUN))==0){
  rx_buffer0[rx_wr_index0]=data;
  if (++rx_wr_index0 == RX_BUFFER_SIZE0) rx_wr_index0=0;
  if (++rx_counter0 == RX_BUFFER_SIZE0){
   rx_counter0=0;
   rx_buffer_overflow0=1;
  };
 };
#asm
    pop  r26
    out  sreg,r26
    pop  r31
    pop  r30
    pop  r27
    pop  r26
#endasm
}
#pragma savereg+

#ifndef _DEBUG_TERMINAL_IO_
// Get a character from the USART0 Receiver buffer
#define _ALTERNATE_GETCHAR_
#pragma used+
char getchar(void)
{
 char data;
 while (rx_counter0==0);
 data=rx_buffer0[rx_rd_index0];
 if (++rx_rd_index0 == RX_BUFFER_SIZE0) rx_rd_index0=0;
#asm("cli")
 --rx_counter0;
#asm("sei")
 return data;
}
#pragma used-
#endif

//===== USART0 Transmitter interrupt service routine
// USART0 Transmitter buffer
#define TX_BUFFER_SIZE0 8
char tx_buffer0[TX_BUFFER_SIZE0];
unsigned char tx_wr_index0,tx_rd_index0,tx_counter0;

// USART0 Transmitter interrupt service routine
#pragma savereg-
interrupt [USART0_TXC] void uart0_tx_isr(void)
{
#asm
    push r26
    push r27
    push r30
    push r31
    in   r26,sreg
    push r26
#endasm
 if(tx_counter0){
  --tx_counter0;
  UDR0=tx_buffer0[tx_rd_index0];
  if (++tx_rd_index0 == TX_BUFFER_SIZE0) tx_rd_index0=0;
 };
#asm
    pop  r26
    out  sreg,r26
    pop  r31
    pop  r30
    pop  r27
    pop  r26
#endasm
}
#pragma savereg+

#ifndef _DEBUG_TERMINAL_IO_
// Write a character to the USART0 Transmitter buffer
#define _ALTERNATE_PUTCHAR_
#pragma used+
void putchar(char c)
{
 while (tx_counter0 == TX_BUFFER_SIZE0);
#asm("cli")
 if (tx_counter0 || ((UCSR0A & DATA_REGISTER_EMPTY)==0)){
  tx_buffer0[tx_wr_index0]=c;
  if (++tx_wr_index0 == TX_BUFFER_SIZE0) tx_wr_index0=0;
  ++tx_counter0;
 }
 else UDR0=c;
#asm("sei")
}
#pragma used-
#endif

/*==========================================
//========== USART1 Receiver buffer
============================================*/
#define RX_BUFFER_SIZE1 8
char rx_buffer1[RX_BUFFER_SIZE1];
unsigned char rx_wr_index1,rx_rd_index1,rx_counter1;
// This flag is set on USART1 Receiver buffer overflow
bit rx_buffer_overflow1;

// USART1 Receiver interrupt service routine
#pragma savereg-
interrupt [USART1_RXC] void uart1_rx_isr(void)
{
 char status,data;
#asm
    push r26
    push r27
    push r30
    push r31
    in   r26,sreg
    push r26
#endasm
 status=UCSR1A;
 data=UDR1;
 if((status & (FRAMING_ERROR | PARITY_ERROR | DATA_OVERRUN))==0){
  rx_buffer1[rx_wr_index1]=data;
  if (++rx_wr_index1 == RX_BUFFER_SIZE1) rx_wr_index1=0;
  if (++rx_counter1 == RX_BUFFER_SIZE1){
   rx_counter1=0;
   rx_buffer_overflow1=1;
  };
 };
#asm
    pop  r26
    out  sreg,r26
    pop  r31
    pop  r30
    pop  r27
    pop  r26
#endasm
}
#pragma savereg+

// Get a character from the USART1 Receiver buffer
#pragma used+
char getchar1(void)
{
 char data;
 while (rx_counter1==0);
 data=rx_buffer1[rx_rd_index1];
 if (++rx_rd_index1 == RX_BUFFER_SIZE1) rx_rd_index1=0;
#asm("cli")
 --rx_counter1;
#asm("sei")
 return data;
}
#pragma used-
// USART1 Transmitter buffer
#define TX_BUFFER_SIZE1 8
char tx_buffer1[TX_BUFFER_SIZE1];
unsigned char tx_wr_index1,tx_rd_index1,tx_counter1;

//===== USART1 Transmitter interrupt service routine
#pragma savereg-
interrupt [USART1_TXC] void uart1_tx_isr(void)
{
#asm
    push r26
    push r27
    push r30
    push r31
    in   r26,sreg
    push r26
#endasm
 if(tx_counter1){
  --tx_counter1;
  UDR1=tx_buffer1[tx_rd_index1];
  if(++tx_rd_index1 == TX_BUFFER_SIZE1) tx_rd_index1=0;
 };
#asm
    pop  r26
    out  sreg,r26
    pop  r31
    pop  r30
    pop  r27
    pop  r26
#endasm
}
#pragma savereg+

// Write a character to the USART1 Transmitter buffer
#pragma used+
void putchar1(char c)
{
 while (tx_counter1 == TX_BUFFER_SIZE1);
#asm("cli")
 if (tx_counter1 || ((UCSR1A & DATA_REGISTER_EMPTY)==0)){
  tx_buffer1[tx_wr_index1]=c;
  if (++tx_wr_index1 == TX_BUFFER_SIZE1) tx_wr_index1=0;
  ++tx_counter1;
 }
 else UDR1=c;
#asm("sei")
}
#pragma used-

/*==========================================
// Timer 0 overflow interrupt service routine
============================================*/
// Timer0 Overflow time = 250uSec (TCNT0 = 192)
interrupt [TIM0_OVF] void timer0_ovf_isr(void)
{
/*
 #asm
     push r26
     push r27
     push r28
     push r29
     push r30
     push r31
     in   r26,sreg
     push r26
 #endasm
*/
 //TCNT0 = 128; // 500uSec Timer
 TCNT0 = 192;  // 250 uSec timer
/*
 #asm
     pop  r26
     out  sreg,r26
     pop  r31
     pop  r30
     pop  r29
     pop  r28
     pop  r27
     pop  r26
 #endasm
*/
}

/*==========================================
// Timer 1 overflow interrupt service routine
============================================*/
//Timer1 = 200uSec Timer
interrupt [TIM1_OVF] void timer1_ovf_isr(void)
{
 #asm
     push r26
     push r27
     push r28
     push r29
     push r30
     push r31
     in   r26,sreg
     push r26
 #endasm
 // 16.0MHz/64 = 250KHz,
 // 250/(0xFFFF - X ) = 1mSec, X= 0xFF00 (x=0xff08)
 // 250/(0xFFFF - X ) = .25mSec, X= 0xFF00 (x=0xff08)
 TCNT1H = 0xFF;
 TCNT1L = 0xCF;  // 200uSec Timer

 if((mSec1Counter--) <= 0){
  mSec1Flag = 1;
  mSec1Counter = 4;
 }
 if((mSec1Counter==2) | (mSec1Counter==4)) mSec0_5Flag = 1;
 
 // Buzzer Output control
 if(BuzOnFlag) BuzOut = 1; //BuzOut = ~ BuzOut;
 else BuzOut = 0;
  
 #asm
     pop  r26
     out  sreg,r26
     pop  r31
     pop  r30
     pop  r29
     pop  r28
     pop  r27
     pop  r26
 #endasm
}
/*==========================================
// ADC interrupt service routine
============================================*/
interrupt [ADC_INT] void adc_isr(void)
{
 //unsigned char adc_data;
 #asm
     in   r26,sreg
     push r26
 #endasm
 // Place your code here
 Test(); 
 AD_Buffer[AD_Channel] += ADCW;
 ADCW = 0;     // AD Converter Register Clear
 if(AD_Channel == 3) AD_Flag = 1;
  
 #asm
     pop  r26
     out  sreg,r26
 #endasm
}

/*==========================================
// Declare your global variables here
==========================================*/
void main(void)
{
// Declare your local variables here

 PortInit();  // Input/Output Ports initialization
 TimerInit();

 // External Interrupt(s) initialization
 EICRA=0x03;
 EICRB=0x00;
 EIMSK=0x01;
 EIFR=0x01;

 // USART0 initialization
 UCSR0A=0x00;
 UCSR0B=0xD8; // Receiver: on, Transmitter: on
 UCSR0C=0x06; // USART0 Mode: Asynchronous, Communication Parameters: 8 Data, 1 Stop, No Parity
 UBRR0H=0x00;
 UBRR0L=0x19; // USART0 Baud rate: 38400
 
 // USART1 initialization
 UCSR1A=0x00;
 UCSR1B=0xD8; // Receiver: on, Transmitter: on
 UCSR1C=0x06; // USART1 Mode: Asynchronous, Communication Parameters: 8 Data, 1 Stop, No Parity
 UBRR1H=0x00;
 UBRR1L=0x44; // USART1 Baud rate: 14400
 
 // Analog Comparator initialization
 ACSR=0x80;  // Analog Comparator Output: Off
 SFIOR=0x00;  // Analog Comparator Input Capture by Timer/Counter 1: Off
 
 // ADC initialization
 ADMUX = ADC_VREF_TYPE; // ADC Clock frequency: 125.000 kHz
 ADCSRA=0x8F;   // bit7(ADC Enable), bit3(ADC Interrupt enable), bit2-bit0 : division 128
 SFIOR&=0xEF;
 
 // Data Initial
 Init_LCD();   // LCD Module Initial
 LCD_InitDisp();  // Power on First display
 BuzOn(2);
 // Global enable interrupts
 #asm("sei")
 
 while(1){
  // Place your code here
  if(mSec1Flag){
   TimerCheck();  // Timer count control
   LoadControl();  //PORTC = LoadReg[IO_Channel];  // Load data output
   
   if(BuzFlag) BuzTimeCtl();
  }
  if(AD_Flag) ADConverter();
  if(mSec250Flag){
   mSec250Flag = 0;
   LCD_Disp();
  }
  // Main Program end
 }
}