Danger
sunt pt atmega 16 dar merge inspirat de aici
1
#include <ioavr.h>
#include <inavr.h>
#include "myprint.h"
/*
1.Sa se calculeze si afiseze pe serial in format x.xxx frecventa WatchDog cu WDP2-0:100.
*/
#define FRECV 4021232
#define WDCYCLES 262144
__no_init unsigned int count;
__no_init unsigned int ovfs;
#pragma vector=TIMER1_OVF_vect
__interrupt void overflow() {
++ovfs;
}
int main() {
if (MCUCSR & (1 << WDRF)) {
unsigned long cycles = ((unsigned long)ovfs << 16) | count;
unsigned long period = cycles * 1000000000LL / FRECV; // ns
unsigned long wd_period = period / WDCYCLES; // ns
unsigned long wd_freq = 1000000L / wd_period; // kHz
USART_initialize(BAUD_RATE);
unsigned long mii = wd_freq / 1000;
unsigned long rest = wd_freq % 1000;
USART_transmit(mii + '0');
USART_transmit('.');
integerTransmit(3, &rest);
USART_transmit('\n');
USART_transmit('\r');
}
MCUCSR = 0; // pune pe 0 flagurile de RESET (care nu se reseteaza la fiecare reset)
__enable_interrupt();
TIMSK |= (1 << TOIE1);
ovfs = 0;
asm("WDR");
WDTCR |= (1 << WDE) | (1 << WDP2);
TCCR1B |= (1 << CS10);
while(1) {
count = TCNT1;
}
}
2
#include <ioavr.h>
#include <inavr.h>
/*
2.Implementati un generator de semnal dreptunghiular cu frecventa de 5Hz,
cu factor de umplere de 66%, implementare cu watchdog.
*/
__no_init int state;
int main() {
if (state == 0 || state == 1) {
PORTC |= (1 << PC0); // PC0 are rezistenta de pull-up externa
state++;
} else {
PORTC &= ~(1 << PC0);
state = 0;
}
DDRC |= (1 << PC0);
asm("WDR");
WDTCR |= (1 << WDE) | (1 << WDP1);
while(1);
}3.
#include <ioavr.h>
#include <inavr.h>
#include "myprint.h"
/*
3.Generati un semnal de 1kHz cu factor de umplere care variaza crescator si descrescator,
cu pasi de 5%, intre 5 si 95 % la fiecare 2 secunde si transmitera factorului de umplere pe serial.
*/
#define FRECV 4006424
unsigned int novfs = 0;
unsigned int duty = 5;
unsigned int direction = 0;
unsigned int flag = 0;
#pragma vector = TIMER0_COMP_vect
__interrupt void compare_match() {
TIMSK &= ~(1 << OCIE0);
TCCR0 &= ~(1 << WGM01);
flag = 1;
}
#pragma vector = TIMER0_OVF_vect
__interrupt void overflow() {
++novfs;
// 2s / (256 * 1024 * 1000000 / FRECV) = 30.5157
if (novfs == 30) {
OCR0 = 142;
TCCR0 |= (1 << WGM01);
TIMSK |= (1 << OCIE0);
novfs = 0;
}
}
int main() {
USART_initialize(BAUD_RATE);
// TOP = FRECV / 1kHz - 1
OCR1A = 4005;
// CMP = (TOP + 1) * 0.05 - 1
OCR1B = 199;
//pin de iesire a semnalului de 1 kHz
DDRD |= (1 << PD4);
//pin de iesire a semnalului de perioada 2 sec
DDRC |= (1 << PC0);
PORTC &= ~(1 << PC0);
__enable_interrupt();
TIMSK |= (1 << TOIE0);
TCCR0 |= (1 << CS02) | (1 << CS00);
TCCR1A |= (1 << WGM11) | (1 << WGM10) | (1 << COM1B1);
TCCR1B |= (1 << CS10) | (1 << WGM12) | (1 << WGM13);
while(1) {
if (flag) {
flag = 0;
if (duty == 5) {
direction = 0;
} else if (duty == 95) {
direction = 1;
}
if (direction) {
duty -= 5;
} else {
duty += 5;
}
OCR1B = (unsigned long)duty * 4021 / 100 - 1;
PORTC ^= (1 << PC0);
integerTransmit(2, &duty);
USART_transmit('\n');
USART_transmit('\r');
}
}
}
4
#include <ioavr.h>
#include <inavr.h>
#include "myprint.h"
/*
4.Calculati si transmiteti pe seriala in formatul XX.XX secunde timpul de la ultima apasare a butonului reset de pe placa.
*/
#define FRECV 4006424
__no_init unsigned long long novfs;
__no_init unsigned int count;
#pragma vector = TIMER1_OVF_vect
__interrupt void overflow() {
++novfs;
}
void main() {
if ((MCUCSR & (1 << EXTRF))) {
unsigned long long cicli = (novfs << 16) | count;
unsigned long long period = cicli * 1000 / FRECV; // ms
novfs = 0;
count = 0;
unsigned int sec = period / 1000;
unsigned int rest = period % 1000;
USART_initialize(BAUD_RATE);
integerTransmit(2, &sec);
USART_transmit('.');
integerTransmit(2, &rest);
USART_transmit('\n');
USART_transmit('\r');
}
MCUCSR = 0; // pune pe 0 flagurile de RESET (care nu se reseteaza la fiecare reset)
__enable_interrupt();
TIMSK |= (1 << TOIE1);
TCNT1 = count;
TCCR1B |= (1 << CS10);
while(1) {
count = TCNT1;
}
}5
#include <ioavr.h>
#include <inavr.h>
#include "myprint.h"
/*
7.Se citesc din terminal doua nr 0xXXXX si 0xYYYY.
Sa se calculeze si sa se afiseze pe seriala CRC-ul zonei de memorie flash
dintre adresa 0xXXXX si 0xYYYY.
*/
#define CRC32 0x04C11DB7 //normal - MSBF
//#define CRC32 0xEDB88320 //inversed - LSBF
//#define CRC16 0x1021 //normal - MSBF
#define CRC16 0x8408 //inversed - LSBF
enum BitOrder { LSBF, MSBF };
unsigned long crc32(unsigned long polinom32, unsigned long init_val_32, unsigned int adr_start,unsigned int len, enum BitOrder ord)
{
//variabile pe 32 biti
unsigned long crc = init_val_32;
unsigned long data = 0;
while( len-- )
{
int i; //se extrage un octet din memoria flash
data = *(__flash char *)adr_start;
if (ord == MSBF) //opþiunea cu shiftare spre MSB
{ //octetul extras este shiftat pânã la cel mai semnificativ bit
data <<= 24;
crc ^= data;
adr_start++;
for( i = 0; i < 8; ++i )
{ //se verificã dacã cel mai semnificativ bit este 1
if( crc & 0x80000000 )
crc = (crc << 1) ^ polinom32;
else
crc = crc << 1;
}
}
else //opþiunea cu shiftare spre LSB
//parametrul polinom32 al funcþiei trebuie sã aibã biþii inversaþi în prealabil
{
crc ^= data;
adr_start++;
for( i = 0; i < 8; ++i )
{ //se verificã dacã cel mai puþin semnificativ bit este 1
if( crc & 0x00000001 )
crc = (crc >> 1) ^ polinom32;
else
crc = crc >> 1;
}
}
}
return crc;
//return ~crc; //complement fata de 1
//return -crc; //complement fata de 2
}
#define FRECV 4006424
unsigned char decode(char c) {
if (c >= 'A' && c <= 'F') {
return c - 'A' + 10;
}
if (c >= '0' && c <= '9') {
return c - '0';
}
return 0;
}
unsigned int read_address() {
unsigned int adr = 0;
// Skip 0x
USART_receive();
USART_receive();
char c = USART_receive();
adr |= decode(c);
c = USART_receive();
adr = (adr << 4) | decode(c);
c = USART_receive();
adr = (adr << 4) | decode(c);
c = USART_receive();
adr = (adr << 4) | decode(c);
return adr;
}
int main() {
USART_initialize(BAUD_RATE);
unsigned int start_adr = read_address();
unsigned int end_adr = read_address();
unsigned long crc = crc32(CRC32, 0, start_adr, end_adr - start_adr, MSBF);
hexadecimalTransmit(8, &crc);
}6
#include <ioavr.h>
#include <inavr.h>
#include "myprint.h"
/*
8.Generati un semnal de 2,5 Khz cu precizie de 2%, sa aiba factorul de umblere initial de 5% si
sa urce/scada cu 3% de la 5% la 95% in 2 secunde.
*/
#define FRECV 4006424
unsigned int novfs = 0;
unsigned int duty = 5;
unsigned int direction = 0;
unsigned int flag = 0;
#pragma vector = TIMER0_COMP_vect
__interrupt void compare_match() {
TIMSK &= ~(1 << OCIE0);
TCCR0 &= ~(1 << WGM01);
flag = 1;
}
#pragma vector = TIMER0_OVF_vect
__interrupt void overflow() {
++novfs;
// 2s / (256 * 1024 * 1000000 / FRECV) = 30.5157
if (novfs == 30) {
OCR0 = 142;
TCCR0 |= (1 << WGM01);
TIMSK |= (1 << OCIE0);
novfs = 0;
}
}
int main() {
USART_initialize(BAUD_RATE);
// TOP = FRECV / 2.5kHz - 1
OCR1A = 1601;
// CMP = (TOP + 1) * 0.05 - 1
OCR1B = 47;
//pin de iesire a semnalului de 1 kHz
DDRD |= (1 << PD4);
//pin de iesire a semnalului de perioada 2 sec
DDRC |= (1 << PC0);
PORTC &= ~(1 << PC0);
__enable_interrupt();
TIMSK |= (1 << TOIE0);
TCCR0 |= (1 << CS02) | (1 << CS00);
TCCR1A |= (1 << WGM11) | (1 << WGM10) | (1 << COM1B1);
TCCR1B |= (1 << CS10) | (1 << WGM12) | (1 << WGM13);
while(1) {
if (flag) {
flag = 0;
if (duty == 5) {
direction = 0;
} else if (duty == 95) {
direction = 1;
}
if (direction) {
duty -= 3;
} else {
duty += 3;
}
OCR1B = (unsigned long)duty * 1602 / 100 - 1;
PORTC ^= (1 << PC0);
}
}
}
7
#include <iom16.h>
#include <inavr.h>
/*
9.Sa se implementeze un generator de frecventa cu ajutorului Watchdog Timer. Frecventa sa fie in jurul valorii de 12Hz si factor de umplere de 20% !
*/
__no_init int state;
void main()
{
asm("WDR");
if(state == 0)
{
PORTD |= (1 << PD6);
state = 1; // 1x perioada
}
else
{
WDTCR |= (1 << WDP1); // 4x perioada
PORTD &= ~(1 << PD6);
state = 0;
}
WDTCR |= (1 << WDE);
DDRD |= (1 << PD6);
while(1);
}
8
count extern
#include <ioavr.h>
#include <inavr.h>
#define FRECV 4006672
#include "usart.h"
#include "myprint.h"
__no_init unsigned int count;
void main() {
USART_initialize(BAUD_RATE);
if (MCUCSR & (1 << EXTRF))
{
count++;
integerTransmit(3, &count);
USART_transmit('\n');
USART_transmit('\r');
}
else
{
if (MCUCSR & (1 << JTRF))
{
count = 0;
}
}
MCUCSR = 0;
while(1);
}
9
#include "myprint.h"
#define CRC16 0x1021 //normal - MSBF
//#define CRC16 0x8408 //inversed - LSBF
enum BitOrder { LSBF, MSBF };
unsigned int crc16(unsigned int polinom16, unsigned int init_val_16, unsigned int adr_start,unsigned int len, enum BitOrder ord)
{
unsigned int crc = init_val_16;
unsigned int data = 0;
while( len-- ) {
unsigned int i;
//se extrage valoarea unui octet de la adresa de start
//din memoria flash
data = *(__flash char *)adr_start;
if ( ord == MSBF ) //opþiunea cu shiftare spre MSB
{
//octetul este shiftat la stânga pentru a se alinia
//cu polinomul generator
data <<= 8;
//datele sunt "transferate" în rezultat
crc ^= data;
adr_start++;
//pentru biþii de date se face XOR cu polinomul generator,
//daca bitul cel mai semnificativ este 1 sau se shifteaza datele
//la stânga, dacã bitul cel mai semnificativ este 0
for( i = 0; i < 8; ++i ) {
//se verificã dacã bitul cel mai semnificativ este 1
if( crc & 0x8000 )
crc = (crc << 1) ^ polinom16;
else
crc = crc << 1;
}
}
else
//opþiunea cu shiftare spre LSB
//parametrul polinom16 al funcþiei trebuie sã aibã biþii inversaþi în
//prealabil
{
crc ^= data;
adr_start++;
//se verificã bitul cel mai putin semnificativ .i dacã
//acesta este 1 se face XOR cu polinomul generator,
// altfel datele sunt shiftate la dreapta
for( i = 0; i < 8; ++i ) {
//se verificã daca cel mai puþin semnificativ bit este 1
if( crc & 0x0001 )
crc = (crc >> 1) ^ polinom16;
else
crc = crc >> 1;
}
}
}
return crc;
}
unsigned char min(unsigned char x, unsigned char y) {
if (x < y)
return x;
else
return y;
}
char antet[] = "CRC16 ADR[";
char mid[] = " - ";
char subsol[] = "] ";
#define RET_INSTRUCTION 0x9508
void main() {
USART_initialize(BAUD_RATE);
unsigned int start_adr = ((unsigned int)min) << 1;
unsigned int current_adr = start_adr;
unsigned int instruction;
do {
instruction = *(__flash unsigned int *)current_adr;
current_adr += 2;
} while(instruction != RET_INSTRUCTION);
do {
instruction = *(__flash unsigned int *)current_adr;
current_adr += 2;
} while(instruction != RET_INSTRUCTION);
unsigned int crc = crc16(CRC16, 0, start_adr, current_adr - start_adr, MSBF);
characterTransmit(sizeof(antet), antet);
paddedHexadecimalTransmit(4, &start_adr);
characterTransmit(sizeof(mid), mid);
paddedHexadecimalTransmit(4, ¤t_adr);
characterTransmit(sizeof(subsol), subsol);
paddedHexadecimalTransmit(4, &crc);
USART_transmit('\r');
USART_transmit('\n');
}10
pwm 20 khx
#include <ioavr.h>
#include <inavr.h>
#include "myprint.h"
#define FRECV 4006424
unsigned int novfs = 0;
unsigned int duty = 5;
unsigned int direction = 0;
unsigned int flag = 0;
#pragma vector = TIMER0_COMP_vect
__interrupt void compare_match() {
TIMSK &= ~(1 << OCIE0);
TCCR0 &= ~(1 << WGM01);
flag = 1;
}
#pragma vector = TIMER0_OVF_vect
__interrupt void overflow() {
++novfs;
// 1s / (256 * 1024 * 1000000 / FRECV) = 15.28329
if (novfs == 15) {
// (256 * 0.2839) - 1 = 71.5234
OCR0 = 71;
TCCR0 |= (1 << WGM01);
TIMSK |= (1 << OCIE0);
novfs = 0;
}
}
int main() {
USART_initialize(BAUD_RATE);
// TOP = FRECV / 1kHz - 1
OCR1A = 199;
// CMP = (TOP + 1) * 0.05 - 1
OCR1B = 9;
//pin de iesire a semnalului de 1 kHz
DDRD |= (1 << PD4);
//pin de iesire a semnalului de perioada 2 sec
DDRC |= (1 << PC0);
PORTC &= ~(1 << PC0);
__enable_interrupt();
TIMSK |= (1 << TOIE0);
TCCR0 |= (1 << CS02) | (1 << CS00);
TCCR1A |= (1 << WGM11) | (1 << WGM10) | (1 << COM1B1);
TCCR1B |= (1 << CS10) | (1 << WGM12) | (1 << WGM13);
while(1) {
if (flag) {
flag = 0;
if (duty == 5) {
direction = 0;
} else if (duty == 95) {
direction = 1;
}
if (direction) {
duty -= 1;
} else {
duty += 1;
}
OCR1B = (unsigned long)duty * 199 / 100 - 1;
PORTC ^= (1 << PC0);
/*integerTransmit(2, &duty);
USART_transmit('\n');
USART_transmit('\r');*/
}
}
}
11
crc
#include <iom16.h>
#include <inavr.h>
#include "myprint.h"
#define CRC16 0x1021 //normal - MSBF
//#define CRC16 0x8408 //inversed - LSBF
enum BitOrder { LSBF, MSBF };
unsigned int crc16(unsigned int polinom16, unsigned int init_val_16, char *adr_start,
unsigned int len, enum BitOrder ord)
{
unsigned int crc = init_val_16;
unsigned int data = 0;
while( len-- ) {
unsigned int i;
//se extrage valoarea unui octet de la adresa de start
//din memoria flash
data = *adr_start;
if ( ord == MSBF ) //opþiunea cu shiftare spre MSB
{
//octetul este shiftat la stânga pentru a se alinia
//cu polinomul generator
data <<= 8;
//datele sunt "transferate" în rezultat
crc ^= data;
adr_start++;
//pentru biþii de date se face XOR cu polinomul generator,
//daca bitul cel mai semnificativ este 1 sau se shifteaza datele
//la stânga, dacã bitul cel mai semnificativ este 0
for( i = 0; i < 8; ++i ) {
//se verificã dacã bitul cel mai semnificativ este 1
if( crc & 0x8000 )
crc = (crc << 1) ^ polinom16;
else
crc = crc << 1;
}
}
else
//opþiunea cu shiftare spre LSB
//parametrul polinom16 al funcþiei trebuie sã aibã biþii inversaþi în
//prealabil
{
crc ^= data;
adr_start++;
//se verificã bitul cel mai putin semnificativ .i dacã
//acesta este 1 se face XOR cu polinomul generator,
// altfel datele sunt shiftate la dreapta
for( i = 0; i < 8; ++i ) {
//se verificã daca cel mai puþin semnificativ bit este 1
if( crc & 0x0001 )
crc = (crc >> 1) ^ polinom16;
else
crc = crc >> 1;
}
}
}
return crc;
}
const char *msg = " CRC16 ";
void main()
{
USART_initialize(BAUD_RATE);
char sir[32];
int read = 0;
do {
sir[read] = USART_receive();
++read;
} while(sir[read - 1] != '@' && read < 32);
// Scoatem terminatorul de sir
--read;
unsigned int crc = crc16(CRC16, 0, sir, read, MSBF);
int i;
for (i = 0; i < read; ++i) {
USART_transmit(sir[i]);
}
characterTransmit(7, (void *)msg);
hexadecimalTransmit(4, &crc);
}12
watch dog toggle led
#include <ioavr.h>
#include <inavr.h>
#include "myprint.h"
#define FRECV 4021232
#define WDCYCLES 262144
__no_init unsigned int count;
__no_init unsigned int ovfs;
__no_init int led;
int main() {
if (MCUCSR & (1 << WDRF)) {
if (led) {
led = 0;
PORTC &= ~(1 << PC0);
} else {
led = 1;
PORTC |= (1 << PC0);
}
DDRC |= (1 << PC0);
}
MCUCSR = 0; // pune pe 0 flagurile de RESET (care nu se reseteaza la fiecare reset)
__watchdog_reset();
WDTCR |= (1 << WDE) | (1 << WDP1);
while(1);
}