?? coder.c
字號:
//中斷方式發(fā)送PWM脈沖,負(fù)脈沖,變化范圍為1MS~2MS。INT0為教練接口輸入負(fù)脈沖,INT1為教練接口2,輸入正脈沖后自動翻轉(zhuǎn),
//外部中斷接口打開上拉。隔離脈沖為500US
//有一個教練允許開關(guān),打開后進入死循環(huán),并允許外部中斷,前提條件是有信號,用定時器0進行信號有無判斷
//定時器1采用比較匹配方式觸發(fā)中斷進行信號發(fā)送
#include <iom8v.h>
#include <macros.h>
#define Uchar unsigned char
#define Uint unsigned int
#define nop() asm("nop")
#define _nop_() asm("nop")
#define PB PORTB
#define PC PORTC
#define PD PORTD
#define IN0 PIND&0x04
#define IN1 PIND&0x08
#define LEDH PB|=0x01
#define LEDL PB&=~0x01
#define BUTTON1 PINB&0x02
#define BUTTON2 PINB&0x04
#define BUTTON3 PINB&0x08
#define BUTTON4 PINB&0x10
#define BUTTON5 PINB&0x20
#define OUTH PD|=0x80
#define OUTL PD&=~0x80
#define LOW_TIME 400
#define SWH_time 900
#define SWL_time 100
Uint ch_time[9]={1000,1000,1000,1000,1000,1000,1000,1000,1000};//輸出用
Uint time[9];//輸出緩存
Uchar ch_counter=0;//通道計數(shù),用來與數(shù)據(jù)采集同步
Uchar input=0;//信號輸入有無標(biāo)志
Uchar train=0;//訓(xùn)練開始表示,防止切換時發(fā)生抖舵
void port_init(void)
{
PORTB = 0x3E;
DDRB = 0x01;
PORTC = 0x00; //m103 output only
DDRC = 0x00;
PORTD = 0x0C;
DDRD = 0x80;
}
//c輸入
//TIMER0 initialize - prescale:1024
// desired value: 1Hz
// actual value: Out of range
void timer0_init(void)
{
TCCR0 = 0x00; //stop
TCNT0 = 0x00 /*INVALID SETTING*/; //set count
//TCCR0 = 0x05; //start timer
}
#pragma interrupt_handler timer0_ovf_isr:10
void timer0_ovf_isr(void)
{
input=0;
train=0;
}
//TIMER1 initialize - prescale:8
// WGM: 0) Normal, TOP=0xFFFF
// desired value: 1Hz
// actual value: Out of range
void timer1_init(void)
{
TCCR1B = 0x00; //stop
TCNT1H = 0x00 /*INVALID SETTING*/; //setup
TCNT1L = 0x00 /*INVALID SETTING*/;
OCR1AH = 0x00 /*INVALID SETTING*/;
OCR1AL = 0x00 /*INVALID SETTING*/;
OCR1BH = 0x00 /*INVALID SETTING*/;
OCR1BL = 0x00 /*INVALID SETTING*/;
ICR1H = 0x00 /*INVALID SETTING*/;
ICR1L = 0x00 /*INVALID SETTING*/;
TCCR1A = 0x00;
TCCR1B = 0x02; //start Timer
}
#pragma interrupt_handler timer1_compa_isr:7
void timer1_compa_isr(void)
{
//compare occured TCNT1=OCR1A//本函數(shù)來自4Vf改裝系統(tǒng),有部分改變
static Uchar output_static=1;//輸出狀態(tài),0代表即將輸出一個低電平,1代表即將輸出一個高電平
//第一次發(fā)信號先發(fā)一個低電平
Uchar counter;//普通計數(shù)器用來拷貝數(shù)據(jù)
output_static=!output_static;
switch(output_static)
{
case 0:OUTH;
TCNT1=0;//定時器清零
OCR1A=LOW_TIME;
if(ch_counter==9)ch_counter=0;//計數(shù)清零同步放行
break;
case 1:OUTL;
TCNT1=0;//定時器清零
OCR1A=ch_time[ch_counter];
if(ch_counter==8)//最后一個高電平是同步電平
{
for(counter=0;counter<=8;counter++)
{
ch_time[counter]=time[counter]+600;
}
}
ch_counter++;
}// switch(output_static)
}//void timer1_compa_isr(void)
//ADC initialize
// Conversion time: 104uS
void adc_init(void)
{
ADCSR = 0x00; //disable adc
ADMUX = 0x00; //select adc input 0
ACSR = 0x80;
ADCSR = 0x86;
}
//Watchdog initialize
// prescale: 32K
void watchdog_init(void)
{
WDR(); //this prevents a timout on enabling
WDTCR = 0x18;
WDTCR = 0x09; //WATCHDOG ENABLED - dont forget to issue WDRs
}
//call this routine to initialize all peripherals
void init_devices(void)
{
//stop errant interrupts until set up
CLI(); //disable all interrupts
port_init();
timer0_init();
timer1_init();
adc_init();
OSCCAL=0xb3;
watchdog_init();
MCUCR = 0x05;
//GICR//中斷開關(guān)應(yīng)在MAIN中用開關(guān)和信號有無控制
GICR = 0x00;
TIMSK = 0x11; //timer interrupt sources
SEI(); //re-enable interrupts
//all peripherals are now initialized
}
#pragma interrupt_handler int0_isr:2
void int0_isr(void)
{
//external interupt on INT0 負(fù)輸入
TCNT0 = 0x00 ;//有信號
input=1;
if(train)//先不忙發(fā)送
switch(IN0)
{
case 0:
OUTL;
break;
case 0x04:
OUTH;
}
}
#pragma interrupt_handler int1_isr:3
void int1_isr(void)
{
//external interupt on INT1 正輸入自動反向
TCNT0 = 0x00 ;//有信號
input=1;
if(train)//先不忙發(fā)送
switch(IN1)
{
case 0:
OUTH;
break;
case 0x08:
OUTL;
}
}
void Putchar (Uchar c)
{
while(!(UCSRA&(1<<UDRE)));
UDR=c;
}
Uint ReadADC (Uchar channel)
{
Uint int1,int2;
ADMUX&=~0x1F;
ADMUX|=channel;
ADCSRA|=0x40;
while(~ADCSRA&0x10){}
ADCSRA|=0x10;
int2=ADCL;
int1=ADCH;
int1<<=8;
return (int1+int2);
}
main()
{
Uint batt;//電量
Uint temp[4];//濾波用
Uint youmen ;//油門緩存
Uchar counter ;//采集計數(shù)
Uchar safe=1,safedelay=0;//油門保護
Uchar warning_frequency;//警告頻率
Uchar warning_counter=0;
Uchar ledonof=0;
Uchar battcheck=1;//檢測電量許可
Uchar checken=200;//等待電壓穩(wěn)定
init_devices();
while(1)
{
for(counter=0;counter<=3;counter++)
{
temp[counter]=ReadADC (counter);
if((temp[counter]>time[counter]+1)||(temp[counter]<time[counter]-1))time[counter]=temp[counter];
}
batt=ReadADC (4);
if(BUTTON1)time[4]=SWL_time;else time[4]=SWH_time;
if(BUTTON2)time[5]=SWL_time;else time[5]=SWH_time;
if(BUTTON3)time[6]=SWL_time;else time[6]=SWH_time;
if(BUTTON4)time[7]=SWL_time;else time[7]=SWH_time;
time[8]=12000-time[0]-time[1]-time[2]-time[3]-time[4]-time[5]-time[6]-time[7];
WDR();
if(safe)
{
youmen=time[2];
time[2]=0;
if(safedelay>3)
{
if(youmen<50)safe=0;
}
else safedelay++;
}
if(!(BUTTON5))
{
TCCR0 = 0x05; //start timer//開始判斷有無信號
GICR = 0xC0;//外中斷開
if (input)
{
TCCR1B = 0x00;//原來的信號發(fā)送關(guān)閉
train=1;//開始訓(xùn)練
ch_counter=0;//等待放行
}
else
{
TCCR1B = 0x02;
train=0;//退出時關(guān)閉訓(xùn)練
////原來的信號發(fā)送打開
}
}//if(!(BUTTON5))
else
{
GICR = 0x00;//外中斷關(guān)
TCCR0 = 0x00;
TCNT0 = 0x00;
train=0;
input=0;
TCCR1B = 0x02;
}
////////////////////////////
if(checken==0)
{
if(battcheck)
{
if(batt<450) //進入報警狀態(tài)
{
if(batt>393) //進入頻閃狀態(tài)
{
warning_frequency=batt-390;
warning_counter++;
if(warning_counter>=warning_frequency)
{
warning_counter=0;
ledonof=!ledonof;
if(ledonof)LEDH;
else LEDL;
}
}
else {LEDH;battcheck=0; }//進入長亮狀態(tài),不允許電壓回升
}
else LEDL; //關(guān)閉
}
}//if(checken==0)
else checken--;
////////////////////////////
while(ch_counter);
}//while(1)
}
?? 快捷鍵說明
復(fù)制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -