Academic Integrity: tutoring, explanations, and feedback — we don’t complete graded work or submit on a student’s behalf.

Here is a functioning code, through Atmel Studio 6 on a Micro Controller Atmega3

ID: 3765563 • Letter: H

Question

Here is a functioning code, through Atmel Studio 6 on a Micro Controller Atmega328p

My reasoning for this question is to use the formula for the freq of Pwm in the data sheet provided on the atmel website. Use that to update the output compare register to change the frequency of 12 of the key inputs below.

#include <avr/io.h>
#include <util/delay.h>

#define FOSC 16000000 // 16 MHz Clock Speed
#define BAUD 9600
#define MYUBRR FOSC/16/BAUD-1

//CPU PIN   ------>       KEYPAD PIN ------>       TYPE           ------> ROW/COL
//------------------------------------------------------------------------------
//PINB0       ------>       PIN 4       ------>       OUTPUT from CPU   ------>   COL 4
//PINB1       ------>       PIN 3       ------>       OUTPUT from CPU   ------>   COL 3
//PINB2       ------>       PIN 2       ------>       OUTPUT from CPU   ------>   COL 2
//PINB3 ------>       PIN 1       ------>       OUTPUT from CPU   ------>   COL 1

//PINC3       ------>       PIN 8       ------>       INPUT with PU   ------>   ROW 4
//PINC2       ------>       PIN 7       ------>       INPUT with PU   ------>   ROW 3
//PINC1       ------>       PIN 6       ------>       INPUT with PU   ------>   ROW 2esssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssss
//PINC0       ------>       PIN 5       ------>       INPUT with PU   ------>   ROW 1
//------------------------------------------------------------------------------


#define COL1       PINB3   //WRITE TO PORTS READ FROM PINS
#define COL2       PINB2   
#define COL3       PINB1  
#define COL4       PINB0  
#define ROW4       PORTC3  
#define ROW3       PORTC2  
#define ROW2       PORTC1  

//Function Prototypes
void InitUART(unsigned char);
void InitGPIO (void);
void USART_Transmit(unsigned char);
#define ROW1       PORTC0

#define DDRB_CFG   0x00 //0b 0000 0000 PINB[0:3] are inputs
#define DDRC_CFG   0x0F //0b 0000 1111 PINC[0:3] are outputs
#define PORTB_CFG 0x0F //0b 0000 1111 PULLUPS on PINB[0:3]


#define ROW1_LOW       0x0E //0b 0000 0111
#define ROW2_LOW       0x0D //0b 0000 1011
#define ROW3_LOW       0x0B //0b 0000 1101
#define ROW4_LOW       0x07 //0b 0000 1110  

#define LOW           0
#define HIGH       1

unsigned char USART_Receive(void);
void SEND_KEYDATA(uint8_t);


void main(void)
{  
   InitUART(MYUBRR);
   InitGPIO();
  
   unsigned char ROW_LOW[] = {ROW1_LOW, ROW2_LOW, ROW3_LOW, ROW4_LOW};

   while(1)
   {
       uint8_t i, j;
      
       for (i=0; i<=3; i++)
       {
           PORTC = ROW_LOW[i];
           j = i;
           SEND_KEYDATA(j);
       }
   }
   }
      
//*********************************************************************************************************************      
//FUNCTIONS************************************************************************************************************
//*********************************************************************************************************************

//INITIALIZE UART
void InitUART( unsigned char ubrr)
{
   UBRR0H = (unsigned char)(ubrr>>8); // Set bits 8 to 11 in Baud Rate Register
   UBRR0L= (unsigned char)ubrr; //Set bits 0 to 7 in Baud Rate Register
  
   UCSR0B = (1<<TXEN0)|(1<<RXEN0); //write a 1 TXEN register to Enable Transmit and 1 to RXEN register to enable Receive

   UCSR0C = (1<<UCSZ00)|(1<<UCSZ01); // Set asynchronous mode and frame format: 8data, 1stop bit
}

//INITIALIZE GPIO PINS
void InitGPIO(void)
{
   DDRB = DDRB_CFG;
   DDRC = DDRC_CFG;
   PORTB = PORTB_CFG;
}

//TRANSMIT DATA (TX PIN)
void USART_Transmit(unsigned char data)
{
   while (!( UCSR0A & (1<<UDRE0)));
   UDR0 = data;
}


//RECIEVE DATA (RX PIN)
unsigned char USART_Receive(void)
{
   while (!(UCSR0A & (1<<RXC0)));
   return UDR0;
}


void SEND_KEYDATA(uint8_t i)
{
   char key;
   if(!(PINB & (1<<COL1))) //check COL1
   {
       _delay_ms(500);
       if (i == 0) key = '1';
       else if (i == 1) key = '2';
       else if (i == 2) key = '3';
       else if (i == 3) key = 'A';
       USART_Transmit(key);
   }
   else if(!(PINB & (1<<COL2))) //check COL2
   {
       _delay_ms(500);
       if (i == 0) key = '4';
       else if (i == 1) key = '5';
       else if (i == 2) key = '6';
       else if (i == 3) key = 'B';
       USART_Transmit(key);
   }
   else if(!(PINB & (1<<COL3))) //check COL3
   {
       _delay_ms(500);
       if (i == 0) key = '7';
       else if (i == 1) key = '8';
       else if (i == 2) key = '9';
       else if (i == 3) key = 'C';
       USART_Transmit(key);
   }
   else if(!(PINB & (1<<COL4))) //check COL4
   {
       _delay_ms(500);
       if (i == 0) key = '*';
       else if (i == 1) key = '0';
       else if (i == 2) key = '#';
       else if (i == 3) key = 'D';
       USART_Transmit(key);
   }

Explanation / Answer

Circuit Diagram

Blinking LED using Atmega32 AVR Microcontroller and Atmel Studio

LEDs are connected to PORTC and current limiting resistors are used to limit current through them. 16 MHz crystal is used to provide clock for the Atmega32 microcontroller and 22pF capacitors are used to stabilize the operation of crystal. The 10µF capacitor and 10K resistor is used to provide Power On Reset (POR) to the device. When the power is switched ON, voltage across capacitor will be zero so the device resets (since reset is active low), then the capacitor charges to VCC and the reset will be disabled. 30th pin (AVCC) of Atmega32 should be connected to VCC if you are using PORTA, since it is the supply voltage pin for PORT A.

Atmel Studio C Program

You have seen that PORT registers are used to write data to ports. Similarly to read data from ports PIN registers are used. It stand for Port Input Register. eg : PIND, PINB

You may like to set or reset individual pins of PORT or DDR registers or to know the status of a specific bit of PIN register. There registers are not bit addressable, so we can’t do it directly but we can do it through program. To make 3ed bit (PC2) of DDRC register low we can use DDRC &= ~(1<<PC2). (1<<PC2) generates the binary number 00000100, which is complemented 11111011 and ANDed with DDRC register, which makes the 3ed bit 0. Similarly DDRC |= (1<<PC2) can be used set the 3ed bit (PC2) of DDRC register and to read  3ed bit (PC2) we can usePINC & (1<<PC2). Similarly we can set or reset each bit of DDR or PORT registers and able to know the logic state of a particular bit of PIN register.

Proteus Simulation

If you haven’t yet started with PROTEUS, please go to this tutorial. Draw the above circuit in PROTEUS and make following setting on the properties of Atmega32.

Atmega32 – Proteus Settings

Hire Me For All Your Tutoring Needs
Integrity-first tutoring: clear explanations, guidance, and feedback.
Drop an Email at
drjack9650@gmail.com
Chat Now And Get Quote