Kod: Markera allt
varvtal
for(int i; i < varvtal;i+100)
{
g_hundra++;
if (g_hundra>9)
{
g_tusen++;
g_hundra=0;
}
}
Kod: Markera allt
varvtal
for(int i; i < varvtal;i+100)
{
g_hundra++;
if (g_hundra>9)
{
g_tusen++;
g_hundra=0;
}
}
Kod: Markera allt
signal(sig_pin_change1)
{
cli();
new_event=1;
sei();
}
signal(sig_output_compare1a)
{
Cli();
irpmCount++;
irpmCount2++;
sei();
}
Kod: Markera allt
// Blinky.c
#include <inttypes.h>
#include <avr/delay.h>
#include <avr/io.h>
#include <avr/interrupt.h>
#include <stdlib.h>
#include "LCD.h"
#include <avr/signal.h>
#define pinb_mask ((1<<PINB7))
// för att identifiera knapparna
#define menu 5
#define go 6
#define stop 7
#define plus 8
#define minus 9
#define badcommand 17
#define sens_int 18 // sensorinterrupt
#define on 15
#define off 16
int irpmShow; // uppdateringsfrekvens
int iTriggerCount;
int timer;
int timer2;
int irpmCount;
int irpmCount2;
int irpmCount_old;
int irpmCalc;
char new_event;
int irpmnumb;
char g_tusental ;
char g_hundratal;
char g_tiotal;
void uppdateLcd(void);
void init(void);
void OSCCAL_calibration(void);
void twelveOn(int p);
void rpmShow(void);
void RTC_init(void);
int main (void)
{
init();
while(1)
{
if((irpmCount>21)&(timer == 1))
{
timer=0;
twelveOn(off);
}
else
{
}
if(new_event==1) // gå in här om vi har fått in ett interrupt
{
if(iTriggerCount >= 5) // sätter på spänning var 3dje puls
{
irpmCount =0;
twelveOn(on); // 12 volt
rpmShow(); // program som skriver in varvtalet
iTriggerCount = 0;
timer=1;
new_event =0; // interruptet är klart
}
else
{
iTriggerCount++;
new_event =0;
}
}
else
{
_delay_loop_2(1);
}
}
return 1;
}
SIGNAL(SIG_PIN_CHANGE1)
{
cli();
new_event =1;
sei();
}
void twelveOn(int p) // 12 volt
{
if(p==on)
{
PORTB = ((PORTB)|(1<<PINB4));//kör bara ut signalen till motorn på PINB6
_delay_loop_2(1);
}
else
{
PORTB = ((PORTB)&~(1<<PINB4));//kör bara ut signalen till motorn på PINB6
_delay_loop_2(1);
}
}
void rpmShow(void) // skriver ut varvtalet
{
if (irpmShow > 50)
{
if(irpmnumb >= 1) // räknar medelvärdet på flera varv 0 = 1 varv 1=2 osv
{
g_tiotal=0;
g_hundratal = 0;
g_tusental =0;
irpmCalc =(116000)/irpmCount2; // finns det något smartare sätt för denna ???
/**
*for(int i=0;i < irpmCalc;i=i+100) // den här tar för länge
*{
* g_hundratal++;
* if(g_hundratal>9)
* {
* g_hundratal = 0;
* g_tusental++;
*
* }
*
*}
*/
irpmCalc /=10;
g_tiotal = irpmCalc%10;
irpmCalc /=10;
g_hundratal=irpmCalc%10;
irpmCalc/=10;
g_tusental=irpmCalc%10;
uppdateLcd();
irpmShow=0;
irpmnumb =0;
irpmCount2 =0;
}
else
{
irpmnumb++;
_delay_loop_2(1);
}
}
else
{
irpmShow++;
_delay_loop_2(1);
irpmCount2 =0;
}
}
/* ISR som skall exekvera var xxxmillisekund*/
SIGNAL(SIG_OUTPUT_COMPARE1A)
{
cli();
irpmCount++;
irpmCount2++;
sei();
}
void init(void)
{
irpmnumb =0;
new_event =0;
irpmShow=0;
// set PORTD for output
DDRD = (0xFF);
//set portb for input
DDRB = ((1<<PINB4)|(1<<PINB5));
// pullup on the pinns we will use
PORTB |= ((pinb_mask));
//enable pin change interrupt on PORTB
PCMSK1 = pinb_mask|(1<<PINB7);
EIFR = (1<<6)|(1<<7);
EIMSK = (1<<6)|(1<<7);
DDRB = ((1<<PINB4)|(1<<PINB5));
PORTB=(0xFF&~(1<<PINB4)&~(1<<PINB5)&~(1<<PINB7));
OSCCAL_calibration(); // set internal clock to 8 MHZ
RTC_init();
iTriggerCount=0;
// initialize the LCD
LCD_Init();
g_hundratal = 7;
g_tusental =7 ;
uppdateLcd();
}
void uppdateLcd(void)
{
LCD_putc(0,g_tusental +'0'); /* Skriv till LDC-minnet på sifferplats nr 0 */
/* variabeln g_sekund + asciikoden för noll blir motsvarande sekund i asciikod */
LCD_putc(1,g_hundratal + '0');
/* variabeln g_tiondel + asciikoden för noll blir motsvarande tiondel i asciikod */
LCD_putc(2,g_tiotal+'0');
LCD_putc(3,'0');
/* Updatera LCD */
LCD_UpdateRequired();
}
//32,768 kHz crystal as reference
//Behöver ej kommenteras
void OSCCAL_calibration(void)
{
unsigned char calibrate = 0;//FALSE;
int temp;
unsigned char tempL;
//CLKPR = (1<<CLKPCE); // set Clock Prescaler Change Enable obs bortkommenterad
// set prescaler = 1, Inter RC 8Mhz / 1 = 8Mhz
//CLKPR = (1<<CLKPS1) | (1<<CLKPS0); bortkommenterad för att komma till 8 mhz
TIMSK2 = 0; //disable OCIE2A and TOIE2
ASSR = (1<<AS2); //select asynchronous operation of timer2 (32,768kHz)
OCR2A = 100; // set timer2 compare value obs ändrad för att komma till 8 mhz
TIMSK0 = 0; // delete any interrupt sources
TCCR1B = (1<<CS10); // start timer1 with no prescaling
TCCR2A = (1<<CS20); // start timer2 with no prescaling
while((ASSR & 0x01) | (ASSR & 0x04)); //wait for TCN2UB and TCR2UB to be cleared
// wait for external crystal to stabilise
for(int i = 0; i < 10; i++)
_delay_loop_2(30000);
while(!calibrate)
{
cli(); // mt __disable_interrupt(); // disable global interrupt
TIFR1 = 0xFF; // delete TIFR1 flags
TIFR2 = 0xFF; // delete TIFR2 flags
TCNT1H = 0; // clear timer1 counter
TCNT1L = 0;
TCNT2 = 0; // clear timer2 counter
while ( !(TIFR2 && (1<<OCF2A)) ); // wait for timer2 compareflag
TCCR1B = 0; // stop timer1
sei(); // __enable_interrupt(); // enable global interrupt
if ( (TIFR1 && (1<<TOV1)) )
{
temp = 0xFFFF; // if timer1 overflows, set the temp to 0xFFFF
}
else
{ // read out the timer1 counter value
tempL = TCNT1L;
temp = TCNT1H;
temp = (temp << 8);
temp += tempL;
}
if (temp > 6250)
{
OSCCAL--; // the internRC oscillator runs to fast, decrease the OSCCAL
}
else if (temp < 6120)
{
OSCCAL++; // the internRC oscillator runs to slow, increase the OSCCAL
}
else
calibrate = 1;//TRUE; // the interRC is correct
TCCR1B = (1<<CS10); // start timer1
}
}
void RTC_init(void)
{
cli();
TCCR1A = 0; //
TCCR1B = (1<<WGM12)|(1<<CS10); // kör på 8 bits prescaling @ 8 mhz
OCR1A = 100; // ett timerinterrupt varje xxx
TIMSK1 = (1<<OCIE1A); //lokalt interrupt
// Global interrupt enable
sei();
}