目录
Write a C program to control a pan-tilt camera through the serial port
Write a C function that uses Timer 1 Overflow Interrupt to create a delay of n seconds.
Use delay() to produce square waves of period 4s and 10s on PB.0 and PB.1.
Describe an interrupt-driven approach that uses Timer 1 CTC mode to invert port B every 5 seconds.
Lab Exam Code
/*
* 333PracExam.c
*
* Created: 9/11/2020 12:35:55 AM
* Author : Zhao Hangji
*/
/*
* Question Description: Write a C program for the ATmega16 that repeatedly gets an input from the user and inverts LEDs on the STK500 board.
* General steps: 1) Write function to read from keypad to PORTB(0~9,#).
* 2) Write function to create a delay of n second. Set the delay to 1 second in main function.
* 3) Use while(1) loop and two if() structures to invert LED3 every n second and invert LED4 every 4n seconds.
* 4) In the while(1) loop , let i++ and then reset the i to enable the LED will repeatedly reverted.
* Hardware connection: 1)the 4-by-3 keypad is connected to PORTB.
* 2)the 8 LEDs (LED0, LED1, ..., LED7) are connected to PORTD
*/
/*
* Problem & Solution: 1) Q:The User don not press keypad, but the LED is on or repeatedly inverted.
* Possible reason: PORTB = 0x00 turn OFF all LEDs initially
* 2) Q:The delay time is not correct.
* Possible reason: After use Timer1 create a delay of n second, in the main function the delay needs to be set to 1 second.
*/
#include <avr/io.h> // AVR header file for all registers/pins
#include <avr/interrupt.h> // AVR header file for interrupt
volatile int overflow_count;
//Function to read from keypad
unsigned char read_keypad(){
unsigned char key; // key press
unsigned char portb_value; //to store input value to PortB
//Array to make assuming the keypad more efficient
unsigned char keypad_col_bit[3]={6,5,4};
unsigned char keypad_row_bit[4]={3,2,1,0};
unsigned char keypad_key[3][4]={
{'1','4','7','*'},{'2','5','8','0'},{'3','6','9','#'}};
unsigned char col;
unsigned char row;
//configure portB
DDRB = 0b11110000;//PortB pins 0-3 for input and pins 4-7 for output
key=0;
for (col=1;col<=3;col++){
//Send binary ZERO to corresponding port B pin for the column
PORTB = ~(1<<(keypad_col_bit[col-1]));
//Create a short delay
asm volatile("nop");
asm volatile("nop");
portb_value =PINB;
for(row=1;row<=4;row++){
if ((portb_value&(1<<(keypad_row_bit[row-1]))) ==0)
key=keypad_key[col-1][row-1];
}
}
return key;
}
ISR(TIMER1_OVF_vect){ // handler for Timer1 overflow interrupt
overflow_count++; // increment overflow count
}
// Function to initialise Timer 1 & interrupt
void init_timer1(void){
TCCR1A = 0b00000000; // normal mode
TCCR1B = 0b00000001; // no prescaler, internal clock
TIMSK = 0b00000100; // enable Timer 1 overflow interrupt
sei(); // enable interrupt subsystem globally
}
//Function to create a delay of n second
void delay(int n){
int overflow_limit;
overflow_limit = n * 15; // limit: 15 overflows = 15 × 2 16 μs = 1s
overflow_count = 0; // reset overflow count
TCNT1 = 0; // reset Timer 1
while (overflow_count <= overflow_limit){;} // loop until n seconds
}
//Main Function
int main(void){
unsigned char output_value = 0x00;
unsigned char n,i=0; // temporary variable
DDRB = 0x00; // set PORTB for input
DDRD = 0xFF; // set PORTD for output
PORTB = 0x00; // turn OFF all LEDs initially
init_timer1(); // initialise Timer 1 & interrupt
n=read_keypad();
while (1){ // main loop
delay(1); // delay 1 second
i++; // increment time
if ((i % n) == 0)
output_value ^= 0b00001000; // invert bit D.3 every n seconds
if ((i % (n*4)) == 0)
output_value ^= 0b00010000; // invert bit D.4 every 4*n seconds
PORTD = output_value; // output to port B
if (i >= 20) // reset time variable
i = 0;
}
return 0;
}
7
Lecture
/* File: led.c
Description: Simple C program for the ATMEL AVR uC (ATmega16 chip)
It lets user turn on LEDs by pressing the switches on STK500 board
*/
#include <avr/io.h> // AVR header file for all registers/pins
int main(void){
unsigned char i; // temporary variable
DDRA = 0x00; // set PORTA for input
DDRB = 0xFF; // set PORTB for output
PORTB = 0x00; // turn ON all LEDs initially
while(1){
// Read input from PORTA.
// port A will be connected to the 8 switches
i = PINA;
// Send output to PORTB.
// port B will be connected to the 8 LEDs
PORTB = i;
}
return 1;
}
Tut
Write and test a C function for the Atmel AVR to check if an 8-bit integer input n is a prime number.
// prime.c : main program to test the is_prime function
#include <avr/io.h> // AVR header file
unsigned char is_prime(unsigned char n){
unsigned char result, i; // result = 1 if n is a prime, 0 otherwise
switch (n){
case 0:
case 1:
result = 0; // when n = 0, 1
break;
case 2:
result = 1; // when n = 2: it is a prime
break;
default: // when n > 2
result = 1; // initial return value
for (i = 2; i < n; i++){
if (n % i == 0){
result = 0;
break;
}
}
}
return result; // return result
}
int main(void){
unsigned char n, result;
n = 13; // any integer input
result = is_prime(n); // call function
DDRB = 0xFF; // set PORTB for output
PORTB = (result)?0x00:0xFF; // turn on LEDs if prime, off otherwise
while (1) {}; // infinite loop
return 1;
}
Lab
read_keypad() display_7led()
// ECTE333 - Spring session
// Written by Zhao Hangji [hz888@uowmail.edu.au]
#include <avr/io.h> // avr header file for IO ports
unsigned char read_keypad();
void display_7led(unsigned char a);
//Main Function to read from keypad and display on led
int main(){
unsigned char a;
while(1){
a=read_keypad();
display_7led(a);
}
}
//Function to read from keypad
unsigned char read_keypad(){
unsigned char key; // key press
unsigned char porta_value; //to store input value to PortA
//Array to make assuming the keypad more efficient
unsigned char keypad_col_bit[3]={6,5,4};
unsigned char keypad_row_bit[4]={3,2,1,0};
unsigned char keypad_key[3][4]={
{'1','4','7','*'},{'2','5','8','0'},{'3','6','9','#'}};
unsigned char col;
unsigned char row;
//configure portA
DDRA = 0b11110000;//PortA pins 0-3 for input and pins 4-7 for output
key=0;
for (col=1;col<=3;col++){
//Send binary ZERO to corresponding port A pin for the column
PORTA = ~(1<<(keypad_col_bit[col-1]));
//Create a short delay
asm volatile("nop");
asm volatile("nop");
porta_value =PINA;
for(row=1;row<=4;row++){
if ((porta_value&(1<<(keypad_row_bit[row-1]))) ==0)
key=keypad_key[col-1][row-1];
}
}
return key;
}
//Function to display PORTA to led
void display_7led(unsigned char a){
switch (a){
case '0':PORTA = 0b00111111;
break;
case '1' :PORTA = 0b00000110;
break;
case '2':PORTA = 0b01011011;
break;
case '3':PORTA = 0b01001111;
break;
case '4':PORTA = 0b01100110;
break;
case '5':PORTA = 0b01101101;
break;
case '6':PORTA = 0b01111101;
break;
case '7':PORTA = 0b00000111;
break;
case '8':PORTA = 0b01111111;
break;
case '9':PORTA = 0b01101111;
break;
default:
PORTA = 0b00000000;
}
}
8
Lecture
#include <avr/io.h>
#include <stdio.h>
int serial_send(char c, FILE *stream){
// Wait until UDRE flag is set to logic 1
while ((UCSRA & (1 << UDRE)) == 0x00){;}
UDR = c; // Write character to UDR for transmission
return 0;
}
int serial_receive(FILE *stream){
// Wait until RXC flag is set to logic 1
while ((UCSRA & (1 << RXC)) == 0x00){;}
return UDR; // Read the received character from UDR
}
int main(void){
unsigned int a;
// … Code to initialise baudrate, TXD, RXD, and so on is not shown here
// Initialise the standard IO handlers
stdout = fdevopen(serial_send, NULL);
stdin = fdevopen(NULL, serial_receive);
// Start using printf, scanf as usual
while (1){
printf(“\n\rEnter a = ");
scanf(“%d”, &a); printf(“%d”, a);
}
}
#include <avr/io.h>
void delay(void){
for (int i = 0; i < 1000; i++)
for (int j = 0; j < 100; j++)
asm volatile("nop");
}
void serial_init(void){
UCSRA = 0b00000010; // double speed, disable multi-proc
UCSRB = 0b00011000; // enable Tx and Rx, disable interrupts
UCSRC = 0b10000110; // asyn mode, no parity, 1 stop bit, 8 data bits
// In double-speed mode, UBRR = Fclock/(8xbaud rate) - 1
UBRRH = 0; UBRRL = 12; // baud rate 9600bps, assuming 1MHz clock
}
void serial_send(unsigned char data){
while ((UCSRA & (1 << UDRE)) == 0){;} // wait until UDRE flag = 1
UDR = data; // write character to UDR for transmission
}
int main(void) {
serial_init(); // initialise USART
while (1){
for (int i = 0; i < 10; i++){ // rotate left 10 times
serial_send('4');
delay();
}
for (int i = 0; i < 10; i++){ // rotate right 10 times
serial_send('6');
delay();
}
}
}

最低0.47元/天 解锁文章
638

被折叠的 条评论
为什么被折叠?



