Here is a functioning code, through Atmel Studio 6 on a Micro Controller Atmega3
ID: 3765564 • 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
/*
Frequency of Pulse Width Modulation PWM :
PWM Period = { ( PR2) + 1 ] + 4 + TOSC
When PR2 = 255, and
FOSC = 40
then PWM Frequency = 1000000 / ( ( 256 ) * 4 * ( 25) ) = 39.06 Kilo Hertz
The following code can be used inside the program to calculate the PWM Frequency
double pwnFreq = 0.0;
int pr2 = 255, fosc = 40;
pwmFreq = 1000000 / ( ( 256 ) * 4 * (1000 / fosc ) );
// PWM can also be calculated by placing bit zero of the duty in the Least Significant Bit Register ( 4th bit)
CCPICON_4 = PW0
// and then the subsequent bits 5 will hold PW1, temp will hold PW shifted twice and so on
*/
Related Questions
drjack9650@gmail.com
Navigate
Integrity-first tutoring: explanations and feedback only — we do not complete graded work. Learn more.