Friday, 14 July 2017

ATMEGA16A

20220503.2

ATMEGA16A

====================
Equipment and Tools:
1  PC
2  Internet access
3  An IDE  (IAR Embedded Workbench)
4  USBASP
5  ATMEGA16A
 PCB with socket 
7  A breadboard, connectors, pins etc.

====================
Notes:
1  Knowledge in C language is assumed.
2  Installing the driver for the USBASP may be troublesome.
3  The USBASP may be used with the AVRDUDESS software.
====================
Set up:
Download and install the IDE.
Download and read the USBASP-UG (User Guide), from ProtoStack.
Plug the USBASP to the PC.
Install the driver as described in the guide.
Download, install and test AVRDUDESS.   
 
Insert the ATMEGA16A onto the board.
Connect the board to the USBASP.
Check the circuit using  AVRDUDESS to detect the chip.
         


====================
Programming:
Launch the IAR Embedded Workbench.
Create a New (Empty) Project in the folder. (P16)
In the ‘Options’, select ATmega16 as the processor and ‘Other’ for the Linker Output.
Type in a program, name it as main.c and add it to the project.
Always save the program file.
Make, and check that an output file P16.a19 has been produced.
Flash the file into the ATMEGA16 through the AVRDUDESS. 
See(Verify) that the ATMEGA16 runs according to the program.
====================
Starting examples:
AT00a     To test program compilation and downloading.
AT00b     To keep the microcontroller within user control.
AT01LEDa    To turn on the LED connected to PortA bit 0.
AT01LEDb    To turn off the LED connected to PortA bit 0.
AT01LEDt    To toggle the LED connected to PortA bit 0.    

//  AT00a

int main( void )
{
  return 0;
}

//  AT00b

int main( void )
{
  while(1);
}

//  AT01LEDa    Set Port A bit 0

#include <iom16.h>

int main( void )
{
  PORTA |= 0x01 ;       // set Bit 0 
  DDRA  |= 0x01 ;       // Bit 0 Output
  
  while(1);
}

//  AT01LEDb    Clear Port A bit 0

#include <iom16.h>

int main( void )
{
  PORTA &= ~0x01 ;      // clear Bit 0 
  DDRA  |= 0x01 ;       // Bit 0 Output
  
  while(1);
}

//  AT01LEDt    Toggle Port A bit 0 

#include <iom16.h>

int main( void )
{
  int i;
  
  PORTA &= ~0x01 ;      // clear Bit 0 
  DDRA  |= 0x01 ;       // Bit 0 Output
  
  while(1){
    for(i=0;i<=30000;i++){;}    // Do not exceed 32767
    PORTA |= 0x01 ;             // set Bit 0 
    for(i=0;i<=30000;i++){;}  
    PORTA &= ~0x01 ;            // clear Bit 0 
  }
}

20220503.2


T21     Timer 2. 
T22     Timer 2 Interrupt.

====================
Fuses:

Reference:   AVR Tutorial:   http://www.ladyada.net/learn/avr/avrdude.html
                    AVR Fuse Calculator:   http://www.engbedded.com/fusecalc/

Change the clock to 8 MHz by  AVRDUDE –c usbasp –p m16 –U lfuse:w:0xe4:m
After the clock change, T15 would blink very fast, T21 does not seem to work.


====================
Further notes on the programming examples:


T16     To blink the LED at 8 MHz.
T23     Timer 2 Interrupt at 8 MHz.

T30     LCD 1602     8-pin operation

               ATMEGA16           LCD 1602
               all 8 Port D bits      all 8 Data bits
               Port A bit 1             RS
               Port A bit 0             E
                                               W/R connect to Ground
                                               Vo connect to Ground through a 1-k resistor 
T31     LCD 1602.
               ATMEGA16           LCD 1602
               Port D bits 7,6,5,4  Data bits 7,6,5,4
               Port A bit 1             RS
               Port A bit 0             E
                                               W/R connect to Ground
                                               Vo connect to Ground through a 1-k resistor



====================
Programming examples:
==========
// T10.c

int main(){
 
  return 0;
}

==========
// T11.c

int main(){
 
  while(1);
}
==========
// T12.c
#include <iom16.h>

int main(){
 
  PORTA = 0x01 ;        // Bit 0 set (Off)
  DDRA  = 0x01 ;        // Bit 0 Output
 
  while(1);
}
==========
// T13.c
#include <iom16.h>

int main(){
 
  PORTA = 0x00 ;        // Bit 0 clear (ON)
  DDRA  = 0x01 ;        // Bit 0 Output
 
  while(1);
}
==========
// T14.c
#include <iom16.h>

int main(){
 
  PORTA &= ~(1<<0) ;    // Bit 0 clear (ON)
  DDRA  |= 1<<0 ;       // Bit 0 Output

  while(1);
}
==========
// T15.c
#include <iom16.h>

int main(){
  int i ;
 
  PORTA &= ~(1<<0) ;    // Bit 0 clear (ON)
  DDRA  |= 1<<0 ;       // Bit 0 Output

  while(1){
    PORTA |= 1<<0 ;             // Bit 0 set (Off)
    for(i=0;i<=30000;i++){ ; }  // Software delay
    PORTA &= ~(1<<0) ;          // Bit 0 clear (ON)
    for(i=0;i<=30000;i++){ ; }  // Software delay
  }

  // while(1);
}
==========

// T16.c      8 MHz
#include <iom16.h>

int main(){
  int i,j ;
 
  PORTA &= ~(1<<0) ;    // Bit 0 clear (ON)
  DDRA  |= 1<<0 ;       // Bit 0 Output

  while(1){
    PORTA |= 1<<0 ;             // Bit 0 set (Off)
    for(i=0;i<=200;i++){for(j=0;j<=1000;j++);}  // Software delay
    PORTA &= ~(1<<0) ;          // Bit 0 clear (ON)
    for(i=0;i<=200;i++){for(j=0;j<=1000;j++);}  // Software delay
  }

  // while(1);
}
==========
// T21.c
#include <iom16.h>

int main(){
 
  PORTA &= ~(1<<0) ;    // Bit 0 clear (ON)
  DDRA  |= 1<<0 ;       // Bit 0 Output

  TCCR0 = 0x05 ;        // T0 ON, clk/1024

  while(1){
    if( TCNT0>=0x20 )   PORTA &= ~(1<<0) ;    // Bit 0 clear (ON)
                else    PORTA |= 1<<0 ;       // Bit 0 set (Off)
  }

  // while(1);
}
==========
// T22.c
#include <iom16.h>
#include <intrinsics.h>

int i;

int main(){
 
  PORTA &= ~(1<<0) ;    // Bit 0 clear (ON)
  DDRA  |= 1<<0 ;       // Bit 0 Output

  __disable_interrupt();
  TCCR0 = 0x05 ;        // T0 ON, clk/1024
  TIMSK |= 0x01 ;       // 0x01 is TOIE0
  __enable_interrupt();

  i = 0 ;

  while(1);     // Wait for interrupts
}

// Interrupt handler for TCNT0 Overflow
#pragma vector=TIMER0_OVF_vect
__interrupt void TOV0_Handler(void)
{
  i++ ;
  if(i<=5) PORTA &= ~(1<<0) ;    // Bit 0 clear (ON)
     else  PORTA |= 1<<0 ;       // Bit 0 set (Off)
  if(i==7) i = 0 ;
}
==========    
// T23.c      8 MHz
#include <iom16.h>
#include <intrinsics.h>

int i;

int main(){
 
  PORTA &= ~(1<<0) ;    // Bit 0 clear (ON)
  DDRA  |= 1<<0 ;       // Bit 0 Output

  __disable_interrupt();
  TCCR0 = 0x05 ;        // T0 ON, clk/1024
  TIMSK |= 0x01 ;       // 0x01 is TOIE0
  __enable_interrupt();

  i = 0 ;

  while(1);     // Wait for interrupts
}

// Interrupt handler for TCNT0 Overflow
#pragma vector=TIMER0_OVF_vect
__interrupt void TOV0_Handler(void)
{
  i++ ;
  if(i<=50) PORTA &= ~(1<<0) ;    // Bit 0 clear (ON)
      else  PORTA |= 1<<0 ;       // Bit 0 set (Off)
  if(i==70) i = 0 ;
}
==========

// T30.c      LCD 1602    8-pin(8-bit) mode
#include <iom16.h>
#include <intrinsics.h>
void LCD_E(int K);

int main(){
  int i ;
 
  PORTA &= ~(1<<0) ;    // Bit 0 clear    E = 0
  DDRA  |= 1<<0 ;       // Bit 0 Output
  PORTA &= ~(1<<1) ;    // Bit 1 clear    RS = 0
  DDRA  |= 1<<1 ;       // Bit 1 Output
  PORTD = 0x00 ;
  DDRD |= 0xFF ;        // 7,6,5,4,3,2,1,0  Output

  PORTA &= ~(1<<1) ;    // Bit 1 clear    RS = 0

  LCD_E(0x30);    // 3 times 0x30
  LCD_E(0x30);    // to ensure LCD is
  LCD_E(0x30);    // into 8-pin mode
  LCD_E(0x38);
 
  LCD_E(0x0F);
  LCD_E(0x06);
  LCD_E(0x01);
  for(i=0;i<=30000;i++);      // Give time for clear screen

  LCD_E(0x80);
 
  PORTA |=  (1<<1) ;    // Bit 1 set    RS = 1
  LCD_E('H');
  LCD_E('a');
  LCD_E('p');
  LCD_E('p');
  LCD_E('y');
  LCD_E(' ');
  LCD_E('B');
  LCD_E('i');
  LCD_E('r');
  LCD_E('t');
  LCD_E('h');
  LCD_E('d');
  LCD_E('a');
  LCD_E('y'); 
 
  PORTA &= ~(1<<1) ;    // Bit 1 clear    RS = 0
  LCD_E(0xC0);

  PORTA |=  (1<<1) ;    // Bit 1 set    RS = 1
  LCD_E('Y');
  LCD_E('o');
  LCD_E('n');
  LCD_E('g');
  LCD_E(' ');
  LCD_E('Y');
  LCD_E('o');
  LCD_E('k');
  LCD_E('e');
  LCD_E(' ');
  LCD_E('K');
  LCD_E('e');
  LCD_E('o');
  LCD_E('w');
  LCD_E(' ');
 
  PORTA &= ~(1<<1) ;    // Bit 1 clear    RS = 0
  LCD_E(0xD3);          // Move out cursor

  while(1);     // Wait for interrupts
}
void LCD_E(int K){
  int i ;
    PORTD = K ;
    for(i=0;i<=1000;i++){ ; }    
    PORTA |=  (1<<0) ;    // Bit 0 set      E = 1
    for(i=0;i<=1000;i++){ ; }
    PORTA &= ~(1<<0) ;    // Bit 0 clear    E = 0
    for(i=0;i<=1000;i++){ ; }
}

==========
// T31.c
#include <iom16.h>
#include <intrinsics.h>
void LCD_E(int K);

int main(){
  unsigned int i ;
 
  PORTA &= ~(1<<0) ;    // Bit 0 clear    E = 0
  DDRA  |= 1<<0 ;       // Bit 0 Output
  PORTA &= ~(1<<1) ;    // Bit 1 clear    RS = 0
  DDRA  |= 1<<1 ;       // Bit 1 Output
  PORTD = 0x00 ;
  DDRD |= 0xF0 ;        // 7,6,5,4  Output

  PORTD = 0x30 ;
  LCD_E(1000);
  PORTD = 0x30 ;
  LCD_E(1000);
  PORTD = 0x30 ;
  LCD_E(1000);
  PORTD = 0x30 ;
  LCD_E(1000);
  PORTD = 0x30 ;
  LCD_E(1000);
  PORTD = 0x20 ;
  LCD_E(1000);
  PORTD = 0x20 ;
  LCD_E(1000);
  PORTD = 0x80 ;
  LCD_E(1000);
 
  PORTD = 0x00 ;
  LCD_E(1000);
  PORTD = 0xF0 ;
  LCD_E(1000);
  PORTD = 0x00 ;
  LCD_E(1000);
  PORTD = 0x60 ;
  LCD_E(1000);
  PORTD = 0x00 ;
  LCD_E(1000);
  PORTD = 0x10 ;
  LCD_E(1000);
  for(i=0;i<=50000;i++);      // Give time for clear screen

  PORTD = 0x80 ;
  LCD_E(1000);
  PORTD = 0x90 ;
  LCD_E(1000);
 
  PORTA |=  (1<<1) ;    // Bit 1 set    RS = 1
  PORTD = 0x51 ;
  LCD_E(1000);
  PORTD = 0x31 ;
  LCD_E(1000);
 
  while(1);     // Wait for interrupts
}
void LCD_E(int K){
  int i ;
    for(i=0;i<=K;i++){ ; }     
    PORTA |=  (1<<0) ;    // Bit 0 set      E = 1
    for(i=0;i<=K;i++){ ; }
    PORTA &= ~(1<<0) ;    // Bit 0 clear    E = 0
    for(i=0;i<=K;i++){ ; }
}

==========    
Continued at ATmega16KCS: ATmega16KCS (esp32kcs.blogspot.com)

No comments:

Post a Comment