⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 251.c

📁 卡车仪表的单片机程序
💻 C
📖 第 1 页 / 共 2 页
字号:
//ICC-AVR application builder : 2008-7-3 10:08:15
// Target : M8
// Crystal: 4.0000Mhz

#include <iom8v.h>
#include <macros.h>
#include "spi.h"
#include "lcd.h"
#include "EEPROM.h"

#define uchar unsigned char
#define unint unsigned int

//Global
#define MaxAngle 2880
#define RefreshFreq 10
#define ClockwiseMotor  0x80 //00000001

//Speed
#define SpeedAvgSamples 4
#define MaxSpeed 140
#define PoleNum 16
#define Timer1Unit 2e-6
#define Timer1UnitMaxSpeed 202

//N
#define NAvgSamples 4
#define MaxN 4000
#define PulseFreqper100Rpm 30 
#define MaxNPulse  (MaxN*PulseFreqper100Rpm/100/RefreshFreq) //1200Hz=120Pulses

//Small meter
#define VoltageMotorBias 2 //AD0<-->MOTOR_BIT(2);
#define VoltageAvgSamples 4



void motor(void);
void Calculate(void);
void MileageSaving(void);
void MileageLoding(void);
void Parallel(void);

void LCDDecoding(void);
void ParallelOutput(void);
void KeyMileageCurrentClear(void);
void AlarmCalculate(void);

//GLOBAL VARIABLES
//SIGNALS
uchar MotorBlocked = 0;
uchar CalculateBlocked = 0;
uchar ParallelBlocked = 0;
uchar Timer0Div = 0;
uchar MileageSaveBlocked = 1;

//For speed calculation
uchar TimeIntervalRefreshed = 0;
uchar SpeedUltraLow = 1;
unsigned long int TimeInterval = 100000*5;
unsigned long int TimeIntervalAvg = 100000*5;
//For N calculation
unint NPulseCnt = 0;
unint NPulse = 0;
unint NPulseAvg = 0;

//Small meters
uchar ADCCurrentChannel = 0;
unint Voltage[6]={0,0,0,0,0,0};
unint VoltageAvg[6]={0,0,0,0,0,0};
uchar VoltageRefreshed[6]={0,0,0,0,0,0};
#include "251SmallMeterDataTable.h"

//Mileage
unsigned long int mileage = 0,MileageCurrent = 0;
unint MileagePulseCnt = 0;
uchar MileageSaved = 1;


//MOTOR POSITION
SpeedMotorCurrent = MaxAngle; //for initialize
SpeedMotorSetting = 0; 
NMotorCurrent = MaxAngle;
NMotorSetting = 0;
unint VoltageMotorSetting[6] = {0,0,0,0,0,0};
unint VoltageMotorCurrent[6] = {MaxAngle,MaxAngle,MaxAngle,MaxAngle,MaxAngle,MaxAngle};

//Parallel Output
unint ParallelOutputCmd;

//LCD
uchar LCDContent[13] = {0,1,2,3,4,5,6,8,8,7,8,9,10};

//Alarm
#define ThresholdOil	  166
#define ThresholdTemp	  186
#define ThresholdOilP	  145
#define ThresholdAir	  339
#define ThresholdVoltL	  300
#define ThresholdVoltH	  450
#define AlarmLedOil		  5
#define AlarmLedTemp  	  7
#define AlarmLedOilP  	  6
#define AlarmLedAir1  	  8
#define AlarmLedAir2  	  9
#define AlarmLedVoltL  	  10
#define AlarmLedVoltH  	  11
const unint SpeedAlarm[4] = {
 (Timer1UnitMaxSpeed*MaxSpeed/20),
 (Timer1UnitMaxSpeed*MaxSpeed/40),
 (Timer1UnitMaxSpeed*MaxSpeed/60),
 (Timer1UnitMaxSpeed*MaxSpeed/100)};
const uchar SpeedAlarmOut[4] = {
 2,
 3,
 4,
 1}; 


void port_init(void)
{
 PORTB = 0x84;
 DDRB  = 0xef;
 PORTC = 0x00; //m103 output only
 DDRC  = 0x40;
 PORTD = 0xA0;
 DDRD  = 0x23;
}

//TIMER0 initialize - prescale:8
// WGM: 0) Normal, TOP=0xFFFF
// desired value: 0.05Sec
// actual value:  0.05Sec (0.0%)
// Generate 0.1s event. For calculating & N meter counting 
void timer0_init(void)
{
 TCCR0 = 0x00; //sto
 TCNT0 = 0x3D; //setup
 TCCR0 = 0x05; //start Timer
}


//TIMER1 initialize - prescale:8
// WGM: 0) Normal, TOP=0xFFFF
// 1.0485s Overflow
// actual value:  0.100Sec (0.0%)
// For speed meter time counting
void timer1_init(void)
{
 TCCR1B = 0x00; //stop
 TCNT1H = 0x00; //setup
 TCNT1L = 0x00;
 OCR1AH = 0xC3;
 OCR1AL = 0x50;
 OCR1BH = 0xC3;
 OCR1BL = 0x50;
 ICR1H  = 0xC3;
 ICR1L  = 0x50;
 TCCR1A = 0x00;
 TCCR1B = 0x03; //start Timer
}



//TIMER2 initialize - prescale:32
// WGM: Normal
// desired value: 1KHz
// actual value:  1.000KHz (0.0%)
// for motor
void timer2_init(void)
{
 TCCR2 = 0x00; //stop
 ASSR  = 0x00; //set async mode
 TCNT2 = 0x83; //setup
 OCR2  = 0x7D;
 TCCR2 = 0x03; //start
}

//Watchdog initialize
// prescale: 1024K
void watchdog_init(void)
{
 WDR(); //this prevents a timout on enabling
 WDTCR = 0x0E; //WATCHDOG ENABLED - dont forget to issue WDRs
}

//==========================================================
//=======================ISR==============================
//==========================================================

#pragma interrupt_handler timer2_ovf_isr:5
void timer2_ovf_isr(void)
{
 TCNT2 = 0x83; //reload counter value
 //unblock motor
 MotorBlocked = 0;
 WDR();
}

#pragma interrupt_handler timer1_ovf_isr:9
void timer1_ovf_isr(void)
{
 TimeInterval = 100000*5;
 TimeIntervalRefreshed = 1;
 SpeedUltraLow = 1; 
 if(!MileageSaved)
 {
   MileageSaveBlocked = 0; //Start Mileage Saving 
   MileageSaved = 1;
 }
}

#pragma interrupt_handler timer0_ovf_isr:10
void timer0_ovf_isr(void)
{
 //TIMER1 has overflowed
 TCNT0 = 0x3D; //reload counter 
 
 Timer0Div++;
 if(Timer0Div>=2)   //Divid by 2
 {
   Timer0Div = 0;
   //speed motor is not controled by timer0
 
   //N motor pulse count
   NPulse = NPulseCnt;
   NPulseCnt = 0;
   
   //Wake up calculating
   CalculateBlocked = 0;
   ParallelBlocked = 0;
 }
}

//SPI initialize
// clock rate: 250000hz
void spi_init(void)
{
 SPCR = 0x51; //setup SPI
 SPSR = 0x00; //setup SPI
}

//ADC initialize
// Conversion time: 104uS
void adc_setmux(uchar channel)
{
   if(channel>5)
     channel = 0;
   ADMUX &= BIT(7)|BIT(6)|BIT(5)|BIT(4);
   ADMUX |= channel;
}

void adc_init(void)
{
 ADCSR = 0x00; //disable adc
 ADMUX = 0x40; //select adc input 0, select AVCC=VREF 
 ACSR  = 0x80;
 ADCSR = 0xED; //ADEN=1,ADSC=1(start),ADFR=1(freerun),ADIE(interrupt enable)=1 32div
}

#pragma interrupt_handler adc_isr:15
void adc_isr(void)
{
 //1. conversion complete, read value (int) using...
 Voltage[ADCCurrentChannel]=ADCL;            //Read 8 low bits first (important)
 Voltage[ADCCurrentChannel]|=(int)ADCH << 8; //read 2 high bits and shift into top byte //
 VoltageRefreshed[ADCCurrentChannel] = 1;

 //2. NextChannel
 ++ADCCurrentChannel;
 if(ADCCurrentChannel>5)
   ADCCurrentChannel = 0; 
 
 //3.Set MUX
 adc_setmux(ADCCurrentChannel+1);
 //4.CLEAR INTERUPT FLAG ADIF
 ADCSR |= BIT(ADIF);
}

#pragma interrupt_handler int0_isr:2
void int0_isr(void)//speed
{
 //external interupt on INT0
 //1.Read Interval
 CLI();
 if(SpeedUltraLow)
   SpeedUltraLow = 0;
 else if (!(TIFR&BIT(TOV1)))
 {
   TimeInterval = TCNT1;
   TimeIntervalRefreshed = 1;
 }
 
 //Mileage Counting
 MileagePulseCnt++;
 if (MileagePulseCnt>=998)
 {
   mileage++;
   MileageCurrent++;
   MileageSaved = 0;
   MileagePulseCnt = 0;
 }

 //clear Timer
 TCNT1H = 0;
 TCNT1L = 0;
}

#pragma interrupt_handler int1_isr:3
void int1_isr(void)
{
 //external interupt on INT1
 NPulseCnt++;
 if(NPulseCnt>MaxNPulse)
   NPulseCnt = MaxNPulse; //Limit
}

//call this routine to initialize all peripherals
void init_devices(void)
{
 //stop errant interrupts until set up
 CLI(); //disable all interrupts
 port_init();
 //timer1_init();
 timer2_init();
 spi_init();
 //adc_init();

 MCUCR = 0x0F;
 GICR  = 0x00;
 TIMSK = 0x45; //timer interrupt sources
 SEI(); //re-enable interrupts
 //all peripherals are now initialized
}

void main(void)
{
 //Initiate port,timer2,spi& others
 init_devices();//port&timer2 for motor control
 ParallelOutputCmd = 0x00;
 ParallelOutput();
 MileageLoding();
 init_lcd();

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -