Sample codes for XMEGA

Go To Last Post
27 posts / 0 new
Author
Message
#1
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

I will put some sample codes for XMEGA, based on the attached schematic file. The codes are written in IAR, but can be simply converted to AVR-GCC.

Attachment(s): 

Ozhan KD
Knowledge is POWER

Last Edited: Tue. Mar 15, 2011 - 02:42 PM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

1-Blinking LED:

#include 
#include 

void main( void )
{
  PORTE_DIRSET=PIN0_bm;
  PORTF_DIRSET=PIN0_bm;
  PORTE_OUTSET=PIN0_bm;
  PORTF_OUTSET=PIN0_bm;

 while(1)
 {       
  __delay_cycles(1000000);  // Wait for 1000000 cycles
  PORTE_OUTTGL=PIN0_bm; 
 }
}

Ozhan KD
Knowledge is POWER

Last Edited: Tue. Mar 15, 2011 - 04:55 PM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

2-Led Chaser:

#include 
#include 

void main( void )
{
 unsigned char  led=1;
 PORTE_DIR=PIN7_bm|PIN6_bm|PIN5_bm|PIN4_bm|PIN3_bm|PIN2_bm|PIN1_bm|PIN0_bm;
 PORTF_DIR = PIN0_bm;
 PORTF_OUT = PIN0_bm;

 while(1)
 {      
  PORTE_OUT = led;      
  __delay_cycles(200000);  // Wait for 200000 cycles       
  if (!(led <<= 1)) led=1;      
 }
}

Ozhan KD
Knowledge is POWER

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

3-Simple clock (starts from 00:00:00 to 23:59:59):

#include  
#include    
// 7segment codes
unsigned char __flash bcd_7seg[10]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f};

//----------------------------------------

void main()
{
 PORTE_DIR=PIN7_bm|PIN6_bm|PIN5_bm|PIN4_bm|PIN3_bm|PIN2_bm|PIN1_bm|PIN0_bm;
 PORTF_DIR=PIN6_bm|PIN5_bm|PIN4_bm|PIN3_bm|PIN2_bm|PIN1_bm|PIN0_bm;         
 TCC0_INTCTRLA=TC_OVFINTLVL_LO_gc;
 TCC0_PER=999;   // overflow time = 1 ms
 TCC0_CTRLA=TC_CLKSEL_DIV2_gc; // Prescaler = 2
 PMIC_CTRL=PMIC_LOLVLEN_bm;
 __enable_interrupt();   
 while(1);
}         

//---------------------------------------

// TCC0 overflow interrupt routine

#pragma vector= TCC0_OVF_vect    
__interrupt void TCC0_overflow(void)
{
 static unsigned char second=0;
 static unsigned char minute=0;
 static unsigned char hour=0; 
 static unsigned int x1000=0;
 static unsigned char select=0x02;
 PORTF_OUTCLR=PIN6_bm|PIN5_bm|PIN4_bm|PIN3_bm|PIN2_bm|PIN1_bm;
 
 switch (select)
 {
  case 0x02:  
   PORTE_OUT=bcd_7seg[second%10];
   break;  
  case 0x04:  
   PORTE_OUT=bcd_7seg[second/10];
   break;  
  case 0x08:  
   PORTE_OUT=bcd_7seg[minute%10];
   break;  
  case 0x10:  
   PORTE_OUT=bcd_7seg[minute/10];
   break;   
  case 0x20:  
   PORTE_OUT=bcd_7seg[hour%10];
   break;  
  case 0x40:  
   PORTE_OUT=bcd_7seg[hour/10];             
 }
 if(select==8||select==32) PORTE_OUTSET=128;// Turn on dotpoint
 PORTF_OUTSET=select;
 select <<= 1;
 if(select==0x80) select=0x02;
 // Check for 1 second
 if (++x1000 == 1000)
 {
  x1000=0;  
  if(++second == 60)
  { 
   second=0;  
   if(++minute == 60)
   {
    minute=0;    
    if(++hour == 24) hour=0;
   }
  }
 }
}

Ozhan KD
Knowledge is POWER

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

cool, what's the schematic for?

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

GordonFreeman wrote:
what's the schematic for?

The schematic is for my own made evaluation board.

Attachment(s): 

Ozhan KD
Knowledge is POWER

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

4- 5 digit(16 bit) Event counter:

// Input pulse applies to PC0(Falling edge)
// Low level on PC1 resets counter
#include  
#include    
// 7segment codes
unsigned char __flash bcd_7seg[]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f};

//----------------------------------------

void main()
{
 PORTE_DIR=PIN7_bm|PIN6_bm|PIN5_bm|PIN4_bm|PIN3_bm|PIN2_bm|PIN1_bm|PIN0_bm;
 PORTF_DIRSET=PIN5_bm|PIN4_bm|PIN3_bm|PIN2_bm|PIN1_bm;         
 PORTC_PIN0CTRL=PORT_OPC_PULLUP_gc|PORT_ISC_FALLING_gc;
 PORTC_PIN1CTRL=PORT_OPC_PULLUP_gc;
 TCC0_INTCTRLA=TC_OVFINTLVL_LO_gc;
 TCC0_PER=999;   // overflow time = 1 ms
 TCC0_CTRLA=TC_CLKSEL_DIV2_gc; // Prescaler = 2
 PMIC_CTRL=PMIC_LOLVLEN_bm; 
 EVSYS_CH0MUX=EVSYS_CHMUX_PORTC_PIN0_gc;
 TCC1_CTRLA=TC_CLKSEL_EVCH0_gc;  // Event channel 0 is the Clock source of TCC1
 __enable_interrupt();   
 while(1);
}         

//---------------------------------------

// TCC0 overflow interrupt routine

#pragma vector= TCC0_OVF_vect    
__interrupt void TCC0_overflow(void)
{
 unsigned char DIGIT[5];
 unsigned int TIMER_value;
 unsigned char i; 
 static unsigned char select=0;
 if (!(PORTC_IN & PIN1_bm)) TCC1_CNT=0;//Reset counter
 TIMER_value=TCC1_CNT; 
 for (i=0;i<5;i++)
 {  
  DIGIT[i]=TIMER_value%10;
  TIMER_value/=10;
 } 
 PORTF_OUTCLR=PIN6_bm|PIN5_bm|PIN4_bm|PIN3_bm|PIN2_bm|PIN1_bm; 
 PORTE_OUT=bcd_7seg[DIGIT[select]]; 
 PORTF_OUTSET=1<<(select+1); 
 if(++select==5) select=0; 
}

Ozhan KD
Knowledge is POWER

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

The next codes will be based on Atmel libraries.

Ozhan KD
Knowledge is POWER

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

5- Keyboard codes display on 7segments from right to left. 12 push buttons defined as 0-9 , space and "-".

main:

#include  
#include "KEY_7SEG.h"

void main() 
{
 unsigned char key_code=nokey_code; 
 unsigned char old_key_code=nokey_code;  
 unsigned char DIGITS[6]={0,0,0,0,0,0}; 
 unsigned char i=0;
 init_7seg();
 init_key(); 
 __enable_interrupt();
 show_7seg(DIGITS,0x00,0x00);   
 while(1)
 {  
  key_code=get_key();
  if (key_code!= old_key_code)
  {		   
   old_key_code=key_code; 
   if (key_code!=nokey_code)
   {  
    DIGITS[i]=key_code;    
    i++;
    if (i==6) i=0;
    show_7seg(DIGITS,0x00,0x00);        
   } 
  }
 }
}	

KEY_7SEG.c is a library for using keyboard and 7segments.

#include "KEY_7SEG.h"
#include "TC_driver.h"
#include "port_driver.h"
unsigned char __flash bcd_7seg[]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f,0x00,0x40};	
unsigned char __flash code[]={0x88,0x30,0x28,0x24,0x22,0x50,0x48,0x44,0x42,0x90,0x84,0x82};
volatile bool _20_ms_flag=false;
volatile unsigned char DIGITS_[6];
volatile unsigned char dot_points_;
volatile unsigned char LEDS_;

//--------------------------------------------------------------

void init_7seg(void)
{ 
 PORT_SetPinsAsOutput( &PORTE, 0xFF );
 PORT_SetPinsAsOutput( &PORTF, 0x7F ); 
 TC0_ConfigClockSource( &TCD0, TC_CLKSEL_DIV1_gc );
 TC0_SetOverflowIntLevel( &TCD0, TC_OVFINTLVL_LO_gc );
 TC_SetPeriod( &TCD0, 1999 ); 	// 1 msec = (1999+1)/2MHZ
 PMIC_CTRL=PMIC_LOLVLEN_bm;    	//set low level interrupt enable 
}

//--------------------------------------------------------------

void init_key(void)
{
 PORT_ConfigurePins( &PORTA,0xFE,false,false,PORT_OPC_PULLDOWN_gc,PORT_ISC_BOTHEDGES_gc ); 
}

//--------------------------------------------------------------

void show_7seg(unsigned char DIGITS[],unsigned char dot_points ,unsigned char LEDS)
{
 unsigned char i;
 for(i=0;i<6;i++) DIGITS_[i]=DIGITS[i];
 dot_points_=dot_points;
 LEDS_=LEDS;
}  

//--------------------------------------------------------------

unsigned char get_key(void)
{
 static unsigned char key_code=nokey_code; 
 unsigned char variable , i;
 if(!_20_ms_flag) return key_code;
 _20_ms_flag=false; 
 PORT_SetDirection( &PORTA,0XE0 );	// ROWs=OUT  COLUMNs=IN  
 PORT_SetOutputValue( &PORTA,0XE0 );	// ROWs=1
 delay_us(10); // delay for signal stablization
 variable=(PORTA_IN & 0X1E);
 PORT_SetDirection( &PORTA,0X1E );	// ROWs=IN  COLUMNs=OUT
 PORT_SetOutputValue( &PORTA,0X1E );	// COLUMNs=1
 delay_us(10);
 variable |=(PORTA_IN & 0XE0);
 for(i=0;i<12;i++)
 {
  if(variable==code[i])
  {  
   key_code=i;     
   break;
  } 
  else key_code=nokey_code;	     
 }
 return key_code;
}

//--------------------------------------------------------------

ISR(TCD0_OVF_vect)

{ 
 static unsigned char x20=0;
 static unsigned char select=0; 
 unsigned char dot_point;

 PORT_ClearPins( &PORTF,0X7F );
 if(select)
 {  
  dot_point=((dot_points_&(1<<(select-1))) ? 0x80 : 0x00); 
  PORTE_OUT=bcd_7seg[DIGITS_[select-1]]|dot_point;
 }
 else PORTE_OUT=LEDS_;    
 PORTF_OUTSET=1<<(select); 
 if(++select==7) select=0; 
 if (++x20==20)
 {
  _20_ms_flag=true;
  x20=0;
 }
} 
 

KEY_7SEG.h

#include  "avr_compiler.h"

#define nokey_code 12
void init_7seg(void);
void show_7seg(unsigned char DIGITS[] ,unsigned char,unsigned char );
void init_key(void);
unsigned char get_key(void);

Note: avr_compiler.h,TC_driver.c,TC_driver.h,port_driver.c and port_driver.h can be obtained from XMEGA application notes (atmel.com/xmega).

Ozhan KD
Knowledge is POWER

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

6- Internal temprature sensor readout in celsius:

#include "avr_compiler.h"
#include "adc_driver.h"
#include "KEY_7SEG.h"

volatile unsigned int adc_sample[64];
volatile bool new_adc=false;
volatile unsigned char index=0;

void main(void)
{
 unsigned char DIGITS[6]={0,0,0,0,blank_code,blank_code}; 
 unsigned long temp, temp85; 
 unsigned char i; 
 ADC_CalibrationValues_Load(&ADCA);
 temp85=(SP_ReadCalibrationByte( PROD_SIGNATURES_START + TEMPSENSE1_offset )<<8) 
 + SP_ReadCalibrationByte( PROD_SIGNATURES_START + TEMPSENSE0_offset ) ;
 ADC_ConvMode_and_Resolution_Config(&ADCA, ADC_ConvMode_Unsigned, ADC_RESOLUTION_12BIT_gc);
 ADC_Prescaler_Config(&ADCA, ADC_PRESCALER_DIV512_gc);
 ADC_Reference_Config(&ADCA, ADC_REFSEL_INT1V_gc);
 ADC_TempReference_Enable(&ADCA);
 ADC_Ch_InputMode_and_Gain_Config(&ADCA.CH0,ADC_CH_INPUTMODE_INTERNAL_gc,ADC_DRIVER_CH_GAIN_NONE);
 ADC_Ch_InputMux_Config(&ADCA.CH0, ADC_CH_MUXINT_TEMP_gc, 0);
 ADC_Ch_Interrupts_Config(&ADCA.CH0, ADC_CH_INTMODE_COMPLETE_gc, ADC_CH_INTLVL_LO_gc);
 PMIC.CTRL |= PMIC_LOLVLEX_bm;
 ADC_Enable(&ADCA);
 ADC_Wait_8MHz(&ADCA);
 init_7seg();
 __enable_interrupt();
 show_7seg(DIGITS,0x00,0x00);  
 ADC_Ch_Conversion_Start(&ADCA.CH0);

 while(1)
 {  
  if(new_adc&&(index==0))
  {
   new_adc=false; 
   temp=0;
   for(i=0;i<64;i++) temp+=adc_sample[i]; // 64 Samples average
   temp>>=6;      
   temp=((3580U*(temp-200U))/(temp85-200U));
   if(temp<2730U)
   { 
    temp=2730U-temp;
    DIGITS[4]= minus_code;
   }
   else
   { 
    temp-=2730U;
    DIGITS[4]= blank_code;
   }
   for (i=0;i<4;i++)
   {  
    DIGITS[i]=temp%10;
    temp/=10;
   }   
   show_7seg(DIGITS,0x02,0x00);  
  }   
 }  
}

ISR(ADCA_CH0_vect)
{
 adc_sample
=ADC_ResultCh_GetWord(&ADCA.CH0); new_adc=true; ADC_Ch_Conversion_Start(&ADCA.CH0); if(++index==64)index=0; }

Note: adc_driver.c, adc_driver.h and adc_driver_asm.s90 are new Atmel libraries in this code. 2 lines must be added to KEY_7SEG.h:

#include  "avr_compiler.h"

#define nokey_code 12
#define blank_code 10
#define minus_code 11
void init_7seg(void);
void show_7seg(unsigned char DIGITS[] ,unsigned char,unsigned char );
void init_key(void);
unsigned char get_key(void);

Ozhan KD
Knowledge is POWER

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

7- Quadrature encoder readout:

// 5000 ppr quadrature encoder outputs connected to PC5 and PC6
// 7segments show encoder relative position
// Pressing any key resets counter

#include "avr_compiler.h"
#include "KEY_7SEG.h"

void main()
{
 unsigned char DIGITS[6]={0,0,0,0,0,blank_code};  
 unsigned int TIMER_value;
 unsigned char i;
 PORTC_PIN5CTRL=PORT_ISC_LEVEL_gc; // QDPH0
 PORTC_PIN6CTRL=PORT_ISC_LEVEL_gc; // QDPH90
 init_7seg();
 init_key(); 
 __enable_interrupt();
 show_7seg(DIGITS,0x00,0x00);
 TCC1_PER=19999;
 EVSYS_CH0MUX=EVSYS_CHMUX_PORTC_PIN5_gc;
 EVSYS_CH0CTRL=EVSYS_QDEN_bm|EVSYS_DIGFILT_2SAMPLES_gc;
 TCC1_CTRLD=TC_EVACT_QDEC_gc|TC_EVSEL_CH0_gc;
 TCC1_CTRLA=TC_CLKSEL_DIV1_gc;
 while(1)
 {
  if(get_key()!=nokey_code) TCC1_CNT=0;// Reset
  TIMER_value=TCC1_CNT;
  for (i=0;i<5;i++)
  {  
   DIGITS[i]=TIMER_value%10;
   TIMER_value/=10;
  }
 show_7seg(DIGITS,0x00,0x00);  
 }  
}         

Ozhan KD
Knowledge is POWER

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

8- PWM generation for DC motor control,...
There are 3 push buttons as Up,Down and Start/Stop.Up and down are for duty cycle change and Start/Stop is for activation/deactivation of PWM output. 7segments display the current compare value.KEY_7SEG_1.c is a modified version of KEY_7SEG.c for the repeat action of up/down keys.

main:

// PWM generation on PC5 for DC motor speed control

#include "avr_compiler.h"
#include "KEY_7SEG_1.h"
#include "port_driver.h"
#include "TC_driver.h"
#define up 1
#define down 2
#define start_stop 3
#define stimer1_value 40
#define stimer2_value 2
volatile extern unsigned char stimer1;
volatile extern unsigned char stimer2;

void main()
{ 
 unsigned char key_code=nokey_code;
 unsigned char old_key_code=nokey_code; 
 unsigned char DIGITS[6]={0,0,0,blank_code,blank_code,blank_code}; 
 unsigned char i=0;
 unsigned char PWM_value=0;
 unsigned char temp;
 bool start_stop_f=false;
 PORT_SetPinAsOutput(&PORTC,PIN5_bp);
 TC_SetPeriod(&TCC1,254); // 254 is due to XMEGA hardware bug!!
 TC1_ConfigWGM(&TCC1,TC_WGMODE_SS_gc); 
 init_7seg();
 init_key(); 
 __enable_interrupt();
 show_7seg(DIGITS,0x00,0x00);      
 while(1)
 {  
  key_code=get_key();
  if (key_code==nokey_code) old_key_code=key_code; 
  else
  {  
   switch(key_code)
   {  
    case up:
    { 
     if (old_key_code!=up)
     {
      if (PWM_value!=255) PWM_value++;
      stimer1=stimer1_value;
      stimer2=stimer2_value;
      old_key_code=up;      
     }
     else
     {
      if (stimer1==0 && stimer2==0)
      {
       if (PWM_value!=255) PWM_value++;
       stimer2=stimer2_value;       
      }  
     }    
     break;
    }    
    
    case down:
    { 
     if (old_key_code!=down)
     {
      if (PWM_value!=0) PWM_value--;
      stimer1=stimer1_value;
      stimer2=stimer2_value;
      old_key_code=down;      
     }
     else
     {
      if (stimer1==0 && stimer2==0)
      {
       if (PWM_value!=0) PWM_value--;
       stimer2=stimer2_value;
      }  
     }
    break;      
    }
    case start_stop:
    {
     if (old_key_code!=start_stop)
     {
      old_key_code=start_stop;       
      if (start_stop_f==false)
      {
       TC1_EnableCCChannels(&TCC1,TC1_CCBEN_bm);
       TC1_ConfigClockSource(&TCC1,TC_CLKSEL_DIV1_gc);
       start_stop_f=true;
      } 
      else
      {
       TC1_DisableCCChannels(&TCC1,TC1_CCBEN_bm);
       TC1_ConfigClockSource(&TCC1,TC_CLKSEL_OFF_gc);
       start_stop_f=false;
      }  
     }  
    }      
   }   
  }  
  
  TC_SetCompareB(&TCC1,temp=PWM_value);
  for(i=0;i<3;i++)
  {  
    DIGITS[i]=temp%10;
    temp/=10;
  }
  show_7seg(DIGITS,0x00,start_stop_f?0x01:0x00); 
 }
}	
#include "KEY_7SEG_1.h"
#include "TC_driver.h"
#include "port_driver.h"
unsigned char __flash bcd_7seg[]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f,0x00,0x40};	
unsigned char __flash code[]={0x88,0x30,0x28,0x24,0x22,0x50,0x48,0x44,0x42,0x90,0x84,0x82};
volatile bool _20_ms_flag=false;
volatile unsigned char DIGITS_[6];
volatile unsigned char dot_points_;
volatile unsigned char LEDS_;
volatile unsigned char stimer1;
volatile unsigned char stimer2;

//--------------------------------------------------------------

void init_7seg(void)
{ 
 PORT_SetPinsAsOutput( &PORTE, 0xFF );
 PORT_SetPinsAsOutput( &PORTF, 0x7F ); 
 TC0_ConfigClockSource( &TCD0, TC_CLKSEL_DIV1_gc );
 TC0_SetOverflowIntLevel( &TCD0, TC_OVFINTLVL_LO_gc );
 TC_SetPeriod( &TCD0, 1999 ); 	// 1 msec = (1999+1)/2MHZ
 PMIC_CTRL=PMIC_LOLVLEN_bm;    	//set low level interrupt enable 
}

//--------------------------------------------------------------

void init_key(void)
{
 PORT_ConfigurePins( &PORTA,0xFE,false,false,PORT_OPC_PULLDOWN_gc,PORT_ISC_BOTHEDGES_gc ); 
}

//--------------------------------------------------------------

void show_7seg(unsigned char DIGITS[],unsigned char dot_points ,unsigned char LEDS)
{
 unsigned char i;
 for(i=0;i<6;i++) DIGITS_[i]=DIGITS[i];
 dot_points_=dot_points;
 LEDS_=LEDS;
}  

//--------------------------------------------------------------

unsigned char get_key(void)
{
 static unsigned char key_code=nokey_code; 
 unsigned char variable , i;
 if(!_20_ms_flag) return key_code;
 _20_ms_flag=false; 
 PORT_SetDirection( &PORTA,0XE0 );	// ROWs=OUT  COLUMNs=IN  
 PORT_SetOutputValue( &PORTA,0XE0 );	// ROWs=1
 delay_us(10); // delay for signal stablization
 variable=(PORTA_IN & 0X1E);
 PORT_SetDirection( &PORTA,0X1E );	// ROWs=IN  COLUMNs=OUT
 PORT_SetOutputValue( &PORTA,0X1E );	// COLUMNs=1
 delay_us(10);
 variable |=(PORTA_IN & 0XE0);
 for(i=0;i<12;i++)
 {
  if(variable==code[i])
  {  
   key_code=i;     
   break;
  } 
  else key_code=nokey_code;	     
 }
 return key_code;
}

//--------------------------------------------------------------

ISR(TCD0_OVF_vect)

{ 
 static unsigned char x20=0;
 static unsigned char select=0; 
 unsigned char dot_point;

 PORT_ClearPins( &PORTF,0X7F );
 if(select)
 {  
  dot_point=((dot_points_&(1<<(select-1))) ? 0x80 : 0x00); 
  PORTE_OUT=bcd_7seg[DIGITS_[select-1]]|dot_point;
 }
 else PORTE_OUT=LEDS_;    
 PORTF_OUTSET=1<<(select); 
 if(++select==7) select=0; 
 if (++x20==20)
 {
  _20_ms_flag=true;
  x20=0;
  if (stimer1!=0) --stimer1;
  if (stimer2!=0) --stimer2;
 }
} 
 

Note:According to recent bug of XMEGA, TCC1.PER=254 (instead of 255).

Ozhan KD
Knowledge is POWER

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

9- AT24Cxx serial eeprom read/write.
12 push buttons defined as 0-9, eeprom_read and eeprom_write. By pressing eeprom_write, 7segment digits will save to eeprom and pressing eeprom_read restores saved digits.

Important note: 2 external 3.3K pullup resistors must be added to hardware on PC0&PC1.

#include "avr_compiler.h"
#include "twi_master_driver.h"
#include "KEY_7SEG.h"
#define SLAVE_ADDRESS    0x50
#define CPU_SPEED       2000000
#define BAUDRATE	100000
#define TWI_BAUDSETTING TWI_BAUD(CPU_SPEED, BAUDRATE)
#define eeprom_read 10
#define eeprom_write 11

TWI_Master_t twiMaster;    /*!< TWI master module. */
unsigned char EEPROM_Address_Data[8]={0,0,0,0,0,0,0,0}; 

void main(void)
{	
 unsigned char key_code=nokey_code; 
 unsigned char old_key_code=nokey_code;  
 unsigned char DIGITS[6]={0,0,0,0,0,0};  
 unsigned char i=0,j; 
 /* Initialize TWI master. */
 TWI_MasterInit(&twiMaster,&TWIC,TWI_MASTER_INTLVL_LO_gc,TWI_BAUDSETTING);
 init_7seg();
 init_key(); 
 __enable_interrupt(); 

 TWI_MasterWriteRead(&twiMaster,SLAVE_ADDRESS,&EEPROM_Address_Data[0],2,0);
 while (twiMaster.status != TWIM_STATUS_READY);
 TWI_MasterWriteRead(&twiMaster,SLAVE_ADDRESS,&DIGITS[0],0,6);
 while (twiMaster.status != TWIM_STATUS_READY);
 for(j=0;j<6;j++)DIGITS[j]=twiMaster.readData[j];
 show_7seg(DIGITS,0x00,0x00);  

 while(1)
 {
  key_code=get_key();  
  if (key_code!= old_key_code)
  {		   
   old_key_code=key_code; 
   if (key_code!=nokey_code)
   {
    if (key_code==eeprom_read)
    {
     TWI_MasterWriteRead(&twiMaster,SLAVE_ADDRESS,&EEPROM_Address_Data[0],2,0);
     while (twiMaster.status != TWIM_STATUS_READY);
     TWI_MasterWriteRead(&twiMaster,SLAVE_ADDRESS,&DIGITS[0],0,6);
     while (twiMaster.status != TWIM_STATUS_READY);
     for(j=0;j<6;j++)DIGITS[j]=twiMaster.readData[j];
     show_7seg(DIGITS,0x00,0x00);  
    } 
    else if (key_code==eeprom_write)
    {
     for(j=0;j<6;j++)EEPROM_Address_Data[j+2]=DIGITS[j];
     TWI_MasterWriteRead(&twiMaster,SLAVE_ADDRESS,&EEPROM_Address_Data[0],8,0);
     while (twiMaster.status != TWIM_STATUS_READY);     
    }  
     
    else
    { 
     DIGITS[i]=key_code;
     i++;
     if (i==6) i=0;
     show_7seg(DIGITS,0x00,0x00);      
    }
   } 
  }
 } 
}

/*! TWIC Master Interrupt vector. */
ISR(TWIC_TWIM_vect)
{
 TWI_MasterInterruptHandler(&twiMaster);
}


Ozhan KD
Knowledge is POWER

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Ozhan KD
Knowledge is POWER

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

11- Character LCD library:
Attached file contains a modified version of available libraries. LCD 4bit data and control lines can be selected from every I/O pin. For LCD busy interval, both status check and delay methods are supported. New fonts can also be defined.

Attachment(s): 

Ozhan KD
Knowledge is POWER

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

12- Frequency meter:

This code measures and displays integer part of input frequency applied to PC2 and is based on a per-second measurement. I have tested the code up to 16MHz for input frequency. The frequency is displayed on a character LCD, using lcd_0.c library (previous post).

// Frequency meter version 1.0
// Input: PC2
// Output frequency is displayed on 4x20 LCD

#include "avr_compiler.h"
#include "lcd_0.h"
#include "TC_driver.h"
__flash char ff[]="f=00000000";
char chr[]={'0','1','2','3','4','5','6','7','8','9'};

void main()
{ 
 unsigned char i; 
 unsigned long Timer32=0;
 unsigned long Temp32;
 // Set RC32M as clock source 
 OSC_CTRL|=OSC_RC32MEN_bm;
 while(!(OSC_STATUS & OSC_RC32MRDY_bm));
 CCP=CCP_IOREG_gc;
 CLK_CTRL=CLK_SCLKSEL_RC32M_gc;
 LCDInit();   
 
 // PC2 is input pin 
 PORTC_PIN2CTRL=PORT_OPC_PULLDOWN_gc|PORT_ISC_RISING_gc;
 // PC0 as multiplexer input for event channel0
 EVSYS_CH0MUX=EVSYS_CHMUX_PORTC_PIN2_gc;
 // TCC0 overflow as multiplexer input for event channel 1.
 EVSYS_CH1MUX=EVSYS_CHMUX_TCC0_OVF_gc;
 // TCD0 overflow as multiplexer input for event channel 2.
 EVSYS_CH2MUX=EVSYS_CHMUX_TCD0_OVF_gc;
 // Configure TCC0 and TCC1 for input capture with event channel 2 as trigger 
 TC_SetPeriod(&TCC0,0XFFFF);
 TC_SetPeriod(&TCC1,0XFFFF);
 TC0_EnableCCChannels(&TCC0,TC0_CCAEN_bm);
 TC1_EnableCCChannels(&TCC1,TC0_CCAEN_bm);
 TC0_ConfigInputCapture(&TCC0,TC_EVSEL_CH2_gc);
 TC1_ConfigInputCapture(&TCC1,TC_EVSEL_CH2_gc);
 // Enable event delay on TCC1
 TC_EnableEventDelay(&TCC1);
 // Select event channel 0 as clock source for TCC0
 TC0_ConfigClockSource(&TCC0,TC_CLKSEL_EVCH0_gc);
 // Select event channel 1 as clock source for TCC1
 TC1_ConfigClockSource(&TCC1,TC_CLKSEL_EVCH1_gc); 
 // Period and interrupt level for TCD0
 TC_SetPeriod(&TCD0,31249);	// 1 sec = 1024*(31249+1)/32MHZ 
 // Clock source of TCD0
 TC0_ConfigClockSource(&TCD0,TC_CLKSEL_DIV1024_gc); 
 LCDGotoXY(0,0);
 LCDStringFlash(ff); 
 while(1)
 {
  while(!(TC_GetOverflowFlag(&TCD0))); 
  TC_ClearOverflowFlag(&TCD0);
  Temp32=Timer32;
  Timer32=TCC1_CCA;
  Timer32<<=16;
  Timer32+=TCC0_CCA;
  Temp32=Timer32-Temp32;  
 
  for(i=0;i<8;i++)
  {
   LCDGotoXY(9-i,0); 
   LCDSendData(chr[Temp32%10]); 
   Temp32/=10;
  }
 }  
}

Ozhan KD
Knowledge is POWER

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

13- ks108 based GLCD:

This code displays "XMEGA" on a ks108 based 128x64 GLCD.

#include 
#include 

#define lcd_data PORTE_OUT
#define E_Low() PORTF_OUTCLR=PIN0_bm
#define E_High() PORTF_OUTSET=PIN0_bm
#define RS_Low() PORTF_OUTCLR=PIN2_bm
#define RS_High() PORTF_OUTSET=PIN2_bm
#define RST_Low() PORTF_OUTCLR=PIN3_bm
#define RST_High() PORTF_OUTSET=PIN3_bm
#define CS1_Low() PORTF_OUTCLR=PIN4_bm
#define CS1_High() PORTF_OUTSET=PIN4_bm
#define CS2_Low() PORTF_OUTCLR=PIN5_bm
#define CS2_High() PORTF_OUTSET=PIN5_bm

void glcd_init(void);
void lcd_dataout(unsigned char data);
void lcd_command(unsigned char command);
void set_page_left(unsigned char page);
void set_page_right(unsigned char page);
void set_y_left(unsigned char y);
void set_y_right(unsigned char y);
    
unsigned char __flash xmega[512]={
0x00,0x00,0x00,0x00,0x00,0x00,0x30,0xF0,0xF0,0xF0,0xE0,0x80,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x80,0xE0,0xF0,0xF0,0xF0,0x30,0x00,0x00,0x00,0x00,0xF0,0xF0,0xF0,
0xF0,0xF0,0xE0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xE0,0xF0,0xF0,
0xF0,0xF0,0xF0,0x00,0x00,0x00,0x00,0x00,0xF0,0xF0,0xF0,0xF0,0x70,0x70,0x70,0x70,
0x70,0x70,0x70,0x70,0x70,0x70,0x70,0x70,0x70,0x70,0x00,0x00,0x00,0x00,0x00,0x00,
0x80,0xC0,0xE0,0xE0,0xE0,0xF0,0x70,0x70,0x70,0x70,0x70,0xF0,0xE0,0xE0,0xE0,0xC0,
0x80,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xC0,0xF0,0xF0,
0xF0,0xF0,0xF0,0xF0,0xC0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x03,0x0F,0x1F,0x3F,0xFE,0xF8,0xF0,
0xF8,0xFE,0x3F,0x1F,0x0F,0x03,0x01,0x00,0x00,0x00,0x00,0x00,0x00,0xFF,0xFF,0xFF,
0xFF,0x7F,0xFF,0xFF,0xF8,0xC0,0x00,0x00,0x00,0x00,0xC0,0xF8,0xFF,0xFF,0x7F,0xFF,
0xFF,0xFF,0xFF,0x00,0x00,0x00,0x00,0x00,0xFF,0xFF,0xFF,0xFF,0xE0,0xE0,0xE0,0xE0,
0xE0,0xE0,0xE0,0xE0,0xE0,0xE0,0xE0,0xE0,0x00,0x00,0x00,0x00,0x00,0xF0,0xFE,0xFF,
0xFF,0x0F,0x03,0x01,0x00,0x00,0x00,0x00,0x00,0x80,0x80,0x80,0x80,0x81,0x83,0x8F,
0x8F,0x8F,0x8E,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xC0,0xF0,0xFE,0xFF,0x7F,0x1F,
0x03,0x03,0x1F,0x7F,0xFF,0xFE,0xF0,0xC0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x80,0xE0,0xF0,0xF8,0xFE,0x3F,0x1F,0x0F,0x03,
0x0F,0x1F,0x3F,0xFE,0xF8,0xF0,0xE0,0x80,0x00,0x00,0x00,0x00,0x00,0xFF,0xFF,0xFF,
0xFF,0x00,0x03,0x1F,0xFF,0xFF,0xFE,0xF0,0xF0,0xFE,0xFF,0xFF,0x1F,0x03,0x00,0xFF,
0xFF,0xFF,0xFF,0x00,0x00,0x00,0x00,0x00,0xFF,0xFF,0xFF,0xFF,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x07,0x3F,0x7F,
0xFF,0xF8,0xE0,0xC0,0x80,0x80,0x00,0x00,0x00,0x03,0x03,0x83,0x83,0xC3,0xF3,0xFF,
0xFF,0xFF,0xFF,0x00,0x00,0x00,0x00,0xC0,0xF0,0xFE,0xFF,0x7F,0x3F,0x3B,0x38,0x38,
0x38,0x38,0x38,0x38,0x3B,0x3F,0x7F,0xFF,0xFE,0xF0,0xC0,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x06,0x07,0x07,0x07,0x03,0x01,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x01,0x03,0x07,0x07,0x07,0x06,0x00,0x00,0x00,0x07,0x07,0x07,
0x07,0x00,0x00,0x00,0x00,0x07,0x07,0x07,0x07,0x07,0x07,0x00,0x00,0x00,0x00,0x07,
0x07,0x07,0x07,0x00,0x00,0x00,0x00,0x00,0x07,0x07,0x07,0x07,0x07,0x07,0x07,0x07,
0x07,0x07,0x07,0x07,0x07,0x07,0x07,0x07,0x07,0x07,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x01,0x03,0x03,0x03,0x07,0x07,0x07,0x07,0x07,0x07,0x07,0x03,0x03,0x01,0x07,
0x07,0x07,0x07,0x00,0x00,0x00,0x06,0x07,0x07,0x07,0x03,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x03,0x07,0x07,0x07,0x06,0x00,0x00,0x00,0x00,
};
	
void main(void)
{
 unsigned int i;

 PORTE_DIR=PIN7_bm|PIN6_bm|PIN5_bm|PIN4_bm|PIN3_bm|PIN2_bm|PIN1_bm|PIN0_bm;
 PORTF_DIR=PIN5_bm|PIN4_bm|PIN3_bm|PIN2_bm|PIN1_bm|PIN0_bm;
 glcd_init();
 
 set_page_left(0);  
 set_page_right(0);
 set_y_left(0);
 set_y_right(0);
 for(i=0;i<1024;i++)
 {  
  if((i%64)==0) 
  {
   if((i%128)==0) 
   {  
    set_page_left(i/128);
    set_y_left(0);
   }
   else
   {  
    set_page_right(i/128);
    set_y_right(0);
   }
  }
  if(i<512) lcd_dataout(xmega[i]);
  else lcd_dataout(0);
 }
			
 while(1);
}
 
//---------------------------------------------------
	
void glcd_init(void)
{    
 RST_Low();
 __delay_cycles(10000);
 RST_High();
 __delay_cycles(100000);
 
 CS1_High();
 CS2_High();
 lcd_command(0x3e);    // display off
 lcd_command(0x40);    // Y=0
 lcd_command(0xb8);    // page=0
 lcd_command(0xc0);    // display start line=0
 lcd_command(0x3f);    // display on
}
	
//---------------------------------------------------
	
void lcd_command(unsigned char command)
{
 RS_Low();
 lcd_data=command;
 E_High();
 __delay_cycles(10);
 E_Low();
 __delay_cycles(10);	      
}
	   
//---------------------------------------------------
	
void lcd_dataout(unsigned char data)
{
 RS_High();
 lcd_data=data;
E_High();
 __delay_cycles(10);
E_Low();
 __delay_cycles(10);	      
}

//---------------------------------------------------
	
void set_page_left(unsigned char page)
{
 CS1_High();
 CS2_Low();
 lcd_command(0xb8 + page);
}

//---------------------------------------------------
	
void set_page_right(unsigned char page)
{
 CS1_Low();
 CS2_High();
 lcd_command(0xb8 + page);
}

//---------------------------------------------------

void set_y_left(unsigned char y)
{
 CS1_High();
 CS2_Low();
 lcd_command(0x40 + y);
}

//---------------------------------------------------

void set_y_right(unsigned char y)
{
 CS1_Low();
 CS2_High();
 lcd_command(0x40 + y);
}

Ozhan KD
Knowledge is POWER

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

14- Serial RS232 connection to PC:
This code displays received characters from PC on the char lcd and sends keyboard codes to PC (baud rate=9600). I have tested the code by windows hyper terminal.

#include "avr_compiler.h"
#include "lcd_0.h" 
#include "TC_driver.h"
#include "port_driver.h"
unsigned char __flash keycodes[]={0x88,0x30,0x28,0x24,0x22,0x50,0x48,0x44,0x42,0x90,0x84,0x82}; 
char __flash chr[]={'0','1','2','3','4','5','6','7','8','9',' ','-'};

#define nokey_code 12
volatile unsigned char key_code=nokey_code;
void main()
{
 unsigned char old_key_code=nokey_code;  
 unsigned char i=0; 
 PORT_ConfigurePins(&PORTA,0xFE,false,false,PORT_OPC_PULLDOWN_gc,PORT_ISC_BOTHEDGES_gc); 
 TC0_ConfigClockSource(&TCD0,TC_CLKSEL_DIV1_gc);
 TC0_SetOverflowIntLevel(&TCD0,TC_OVFINTLVL_LO_gc);
 TC_SetPeriod(&TCD0,39999);    // 20 msec = (39999+1)/2MHZ
 LCDInit();
 PORTD.DIRSET = PIN3_bm; // TXD0
 USARTD0_CTRLC=USART_CMODE_ASYNCHRONOUS_gc|USART_PMODE_DISABLED_gc|USART_CHSIZE_8BIT_gc; 
 USARTD0_BAUDCTRLA=12; //Baud Rate = 9600
 USARTD0_CTRLB=USART_RXEN_bm|USART_TXEN_bm; 
 PMIC_CTRL=PMIC_LOLVLEN_bm;       //set low level interrupt enable   
 __enable_interrupt(); 
 LCDGotoXY(0,0);  
 while(1)
 {  
  if(USARTD0_STATUS & USART_RXCIF_bm)
  {    
   LCDSendData(USARTD0_DATA); 	// display received data on LCD   
   if(++i==16)
   {
    i=0;
    LCDGotoXY(0,0); 
   }
  }	 
  if (key_code!= old_key_code)
  {         
   old_key_code=key_code;
   if (key_code!=nokey_code)
   {     
    while( !(USARTD0_STATUS & USART_DREIF_bm));	//wait for data register empty
    USARTD0_DATA=chr[key_code];	        //send data to PC
   }
  }
 } 
}

ISR(TCD0_OVF_vect)

{ 
 unsigned char variable,i;
 PORT_SetDirection( &PORTA,0XE0 );   // ROWs=OUT  COLUMNs=IN 
 PORT_SetOutputValue( &PORTA,0XE0 );   // ROWs=1
 delay_us(10); // delay for signal stablization
 variable=(PORTA_IN & 0X1E);
 PORT_SetDirection( &PORTA,0X1E );   // ROWs=IN  COLUMNs=OUT
 PORT_SetOutputValue( &PORTA,0X1E );   // COLUMNs=1
 delay_us(10);
 variable |=(PORTA_IN & 0XE0);
 for(i=0;i<12;i++)
 {
  if(variable==keycodes[i])
  { 
   key_code=i;     
   break;
  }
  else key_code=nokey_code;        
 } 
} 

Ozhan KD
Knowledge is POWER

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

15- Oscilloscope display:
This sample code is written in assembly language because of necessary speed for this application. The task is to use an analog oscilloscope for display of 16x16 ascii characters with 8x8 fonts. Channel X of oscilloscope is connected to DACB.CH1 and channel Y to DACB.CH0.
https://www.avrfreaks.net/index.php?module=Freaks%20Academy&func=viewItem&item_type=project&item_id=3058

Attachment(s): 

Ozhan KD
Knowledge is POWER

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

16- Car alarm siren:

// Output: PC5

#include "avr_compiler.h"
#include "TC_driver.h"
__flash unsigned int TCC1_values[]={600,740,880,1020,1160,1300,1440,1580,1720,1860};
void main()
{
 PORTC_DIRSET=PIN5_bm; 
 TC_SetCompareA(&TCC1,600);
 TC1_ConfigWGM(&TCC1,TC_WGMODE_FRQ_gc);
 TC1_EnableCCChannels(&TCC1,TC1_CCBEN_bm);
 TC1_ConfigClockSource(&TCC1,TC_CLKSEL_DIV1_gc);
 TC_SetPeriod(&TCC0,70);
 TC0_ConfigClockSource(&TCC0,TC_CLKSEL_DIV1024_gc);
 TC0_SetOverflowIntLevel( &TCC0, TC_OVFINTLVL_LO_gc ); 
 PMIC_CTRL=PMIC_LOLVLEN_bm;
 __enable_interrupt(); 
 while(1);
}  

ISR(TCC0_OVF_vect)
{
 static unsigned char index=0;
 TC_SetCompareA(&TCC1,TCC1_values
); if(++index==10)index=0; }

Edit:

while(1);

is added.

Ozhan KD
Knowledge is POWER

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Ozhan KD
Knowledge is POWER

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Ozhan KD
Knowledge is POWER

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

New revision of FATFS for XMEGA + new revision of HD44780-based lcd library with 9 size support:

https://www.avrfreaks.net/index.php?module=Freaks%20Academy&func=viewItem&item_type=project&item_id=3418

Ozhan KD
Knowledge is POWER

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

electronic.designer wrote:
12- Frequency meter:

while(1)
{
while(!(TC_GetOverflowFlag(&TCD0)));
TC_ClearOverflowFlag(&TCD0);
Temp32=Timer32;
Timer32=TCC1_CCA;
Timer32<<=16;
Timer32+=TCC0_CCA;
Temp32=Timer32-Temp32;

may i know why you subtract Temp32 from Timer32 ?
can i clear TCC0 & TCC1 instead of subtracting old and new ?

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0
Temp32=Timer32-Temp32;

The timers are running in normal mode. The procedure is based on calculation of New 32bit captured value - Old 32bit captured value after every 1 second. Timer32 is the new captured value and Temp32 is the old captured value. Clearing of TCC1 & TCC0 reduces the result precision. Note that there is an assumption of only one 32bit overflow between 2 successive captures.

Ozhan KD
Knowledge is POWER

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

In PIC16f877A we normally declare output/input pins using TrisB=0x0f but here we used PORTE_DIRSET=PIN0_bm what that means and in pic we can use pins like RB0,RB1 ..etc. here how we can do that need help explain me the program to understand it

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Arulselvan wrote:
here we used PORTE_DIRSET=PIN0_bm what that means

The AVR registers are described in detail in the AVR's datasheet - just as the PIC's features are described in its datasheet.

 

and in pic we can use pins like RB0,RB1 ..etc. here how we can do that need help explain me the program to understand it

See: https://www.avrfreaks.net/commen...

 

 

But, surely, the PIC must be well-supported with its own sample code, examples, etc?

Wouldn't that be a better source than 7-year-old example code for an entirely unrelated chip ... ?

Top Tips:

  1. How to properly post source code - see: https://www.avrfreaks.net/comment... - also how to properly include images/pictures
  2. "Garbage" characters on a serial terminal are (almost?) invariably due to wrong baud rate - see: https://learn.sparkfun.com/tutorials/serial-communication
  3. Wrong baud rate is usually due to not running at the speed you thought; check by blinking a LED to see if you get the speed you expected
  4. Difference between a crystal, and a crystal oscillatorhttps://www.avrfreaks.net/comment...
  5. When your question is resolved, mark the solution: https://www.avrfreaks.net/comment...
  6. Beginner's "Getting Started" tips: https://www.avrfreaks.net/comment...
Last Edited: Wed. Jun 20, 2018 - 07:20 AM