电动车霍尔转把检测程序

电动车霍尔转把检测程序
电动车霍尔转把检测程序

电动车霍尔转把检测程序

//转把电压控制,IO端口电压最大是5V,STM是8位AD采样最大可达2的8次等于255 //根据5V对应于255相应算出

//4.1V对应于210;

//1.5V对应于77;

//0.9V对应于46;

//0.2V对应于11;

#include

#include

typedef unsigned int WORD;

unsigned char Time_1ms = 0;//1ms

unsigned char Time_10ms = 0;//10ms

unsigned char Time_50ms = 0;//50ms

unsigned int Time_500ms2 = 0;//500ms

unsigned char Time_500ms = 0;//500ms

unsigned char waitingwork_flag = 0;//等待工作标志

unsigned char alarm_flag = 0;//报警标志

unsigned char state = 0;//工作状态标志

unsigned int state_400ms = 0;//400ms

unsigned int handerbarAD = 0;//转把采样数据

unsigned char key = 0;//按键

unsigned char key_count = 0;//按下次数

unsigned char flag=0;//转把插入标志,等待转把转动

void Init_CLK(void);//初始化函数

void Init_isr_t1(void);//定时器初始化函数

void Init_isr_t0(void);//定时器初始化函数

void isr_t1(void);

void Init_ADC(void);//adc初始化函数

void waitingwork(void);

void handerbar_rotate(void);//转把转动函数

void ad_sample(void);//ad采样函数

//void Init_Time1_PWM(void);//pwm初始化函数

void delay_1ms(int a);//1ms延时函数

void Delay(WORD n);

void Init_PWM0(void);

void Init_PWM0(void)//PWM0初始化函数

{

CCON=0;

CMOD=0x04;//T0溢出做为PWM时钟

CL=0x00;

CH=0x00;

CCAP0L=0xBA;

CCAP0H=0xBA;

CCAPM0=0x42;

// CR=1;到报警时去起动P3^5口PWM0输出

}

void Init_CLK(void)//端口及AUXR初始化函数

{

// 000: fCPU=fMASTER

// CLK_CKDIVR &= ~0x10;

//io口初始化

AUXR=0x80;//定时器0-1T,定时器2-12T

P1M1=0x03;//0b00000011;//P1^0为开漏,P1^1为准双向,其余为推挽输出; PC_DDR=0x00;//PC端口输入

P1M0=0xFD;//0b11111101;0XFD

P1ASF=0x01;//P1口为模拟功能

//P1端口置初值

P1=0x03;//0b00000011; //P1^0为AD,P1^1为按键,P1^2为红灯,P1^3为第二绿灯,P1^4为第1绿灯,P1^5为接通三极管,p1^6为报警;PC_DDR |= 0b11111111;

//PD端口3,4,5,6位为输入,PD其他端口为输出

//PD_DDR |= 0b10000111;

P3M1=0x7F;

P3M0=0x80;

P3=0x00;

//PC_CR1 = 0XFF;//推挽输出

// PD_CR1 = 0b10010111;//3,5,6位悬浮输入,4为上拉输入

//端口清零

//PCODR_ODR4 = 0;//红灯

//PCODR_ODR5 = 0;//第二绿灯

// PCODR_ODR6 = 0;//第一绿灯

}

//5201=13.25MHz,8MHz,定时1ms;

void Init_isr_t1(void)//定时器1初始化函数

{

Time_1ms=0;

TR1=0;

TMOD=0X10;

TH1=0XFB;

TL1=0XB1;

EA=1;

ET1=1;

TR1=1; //起动定时器

}

// TIM4_CR1=0x00;

// TIM4_IER=0x01;//Update Interrupt enabled

// TIM4_EGR=0x00;

// TIM4_PSCR=6;//64分频

//TIM4_ARR=125;

//TIM4_ARR=250;

// TIM4_CR1|=0X01;//cen=1;打开定时器

void Init_isr_t0(void)//定时器0初始化函数做为PWM0的时钟{

TR0=0;

TMOD=0x02|0x10;

TH0=0xCB;//TH0=0xFB;

TH0=0xCB;//TH0=0xFB;

//TR0=1;

}

void Init_ADC (void)//ADC初始化

{

ADC_DA TA=0;

ADC_CONTR=ADC_POWER|ADC_SPEEDL|ADC_CHS0; Delay(2);

}

//void Init_ADC(void)

//{

// ADC_CSR=0x00;//选择通道

/// ADC_CR1=0x00;//fADC = fMASTER/2

//ADC_CR2=0x08;//数据右对齐

//ADC_CR1|=0x01;//打开ADC电源

//}

//void Init_Time1_PWM(void)//蜂鸣器初始化函数,2k的PWM方波

//{

//cen=0;Auto-reload preload enable;Counter used as up-counter

// TIM1_CR1=0x80;

// TIM1_CR2=0x00;//Capture/compare register are not preloaded

// TIM1_RCR=0x00;//Repetition counter value 0;

// TIM1_PSCRH=0X00;//2分频。必须先写高位,再写低位

// TIM1_PSCRL=0X01;

//

//装载值为2000

// TIM1_ARRH=0X07;

// TIM1_ARRL=0Xd0;//pwm频率2k

// TIM1_CCMR1=0x00;//OC1M:011 CC1S:输出

// TIM1_CCMR2=0x00;//OC1M:011 CC1S:输出

// TIM1_CCMR3=0x68;//OC1M:011 CC1S:输出

// TIM1_CCER2=0x00;

// TIM1_CCER1=0x00;

// TIM1_CCR3H=0X03;//必须先写高位,再写地位

// TIM1_CCR3L=0Xe8;//占空比为50%

//TIM1_DTR=0x00;//死区时间

// TIM1_BKR|=0x80;//打开输出使能

// TIM1_CR1|= 0x01;//cen=1;打开定时器

//

//}

void ad_sample(void)//AD采样

{

static unsigned int a=0;

//static unsigned int b=0;//static unsigned int b=0;

ADC_CONTR=ADC_POWER|ADC_SPEEDL|ADC_CHS0|ADC_START;//ADC_CONTR=0XA 8

_nop_();

_nop_();

_nop_();

_nop_();

while(!(ADC_CONTR&ADC_FLAG));

// ADC_CONTR&=~ADC_START ;//关AD转换

ADC_CONTR&=~ADC_FLAG;//清AD转换结束标志

ADC_CONTR= ADC_CONTR|ADC_START;//ADC_CONTR=0XA8 _nop_();

_nop_();

_nop_();

_nop_();

while(!(ADC_CONTR&ADC_FLAG));

//ADC_CONTR&=~ADC_START ;//关AD转换

ADC_CONTR&=~ADC_FLAG;//清AD转换结束标志

//AD采样,判断电压是否升高

//选择通道AIN4

// SET_Channel(ADC_CSR,4);

// ADC_CR1|=0x01;//启动AD采样

// while(ADIS_OK);//采样结束

// ADENDFLAG();//AD采样标志位清零

// ADC_CR1|=0x01;//启动AD采样

// while(ADIS_OK);//采样结束

// ADENDFLAG();//AD采样标志位清零

//对采样到的数据进行滤波

if(a>ADC_DA TA)

{

//当原数据比当前数据大5以上,当做抖动处理,否则计数

if((a-ADC_DA TA)<2)

{

handerbarAD=ADC_DA TA;

}

a = ADC_DA TA;

}

else if(a<=ADC_DA TA)

{

//当前数据比原数据大5以上,当做抖动处理,否则计数

if((ADC_DA TA-a)<=2)

{

handerbarAD=ADC_DA TA;

}

a = ADC_DA TA;

}

}

//定时器1中断服务程序

void isr_t1(void) interrupt T1_INTNO

{

TH1=0XFB; //TH1=0XFB; //重置初值

TL1=0XB1;//TL1=0XAF; //重置初值

Time_1ms=1; //置1ms到标志

//@far @interrupt void TIME4_ISR(void)

//{

// TIM4_SR&=~(0x01);

// Time_1ms = 1;

}

void Delay(WORD n)//延时函数

{

WORD x;

while(n--)

{

x=5000;

while(x--);

}

}

//主函数

main()

{

unsigned char b=0;

unsigned char a=0;

unsigned char c=0;

unsigned char d=0;

unsigned char e=0;

unsigned char f=0;

unsigned char g=0;

unsigned char i=0;

//初始化

// DisableISR;

Init_CLK();//端口初始化

Init_isr_t1();//定时器1初始化,名称不一定要与中断服务程序相同Init_ADC();//ADC初始化

// Init_Time1_PWM();

TR1=1;//启动定时器

Init_isr_t0();

Init_PWM0(); // Init_Time1_PWM();

// EnableISR;

WDT_CONTR=0x20;//启动看门狗并清零看门狗定时器

while (1)

{

P15= 1;//三极管导通

waitingwork_flag=1;

if(Time_1ms)//1ms时间片

{

WDT_CONTR=0x10;//清零看门狗定时器

Time_1ms=0;

Time_50ms++;

Time_10ms++;

Time_500ms2++;

if(Time_500ms2++>=500)//程序运行指示

{

Time_500ms2=0;

P17=~P17;

}

if(401>state_400ms&&state_400ms>0)

{

state_400ms++;

}

if(Time_10ms>=10)

{

Time_10ms = 0;

ad_sample();//AD采样

//************************************************************************* *******

if(waitingwork_flag==1&&state == 0)//转把插入状态,插入

{

flag=0;

//0.2v<转把电压<1.0V,第一绿灯亮,0.2V

//0.2V对应于41,0.9V对应186

if(handerbarAD>11&&handerbarAD<=46)

{

//第一绿灯亮

a++;

b=0;

if(a >= 30)

{

a=0;

if(alarm_flag==0)

{

P14=1;//点亮一绿灯

state = 1;

}

}

}

else if(handerbarAD>46)

{ //大于0.9v红灯亮

// red_flag=1;

b++;

a=0;

if(b >= 50)

{

b=0;

P12=1;//点亮红灯

alarm_flag=1;//置报警状态标志

}

}

else if(handerbarAD<=11)//小于0.2V灯不亮

{

a=0;

b=0;

state_400ms=0;

P12=0;

P13=0;

P14=0;

alarm_flag=0;

CR=0;//TIM1_CCER2=0X00;

P16=0;

}

}

else if(waitingwork_flag==1&&state == 1)//转把转动状态

{

if(handerbarAD<=11)//如果转动时突然拔掉,跳入插入状态

{

state=0;

}

else if(state_400ms<400&&state_400ms>0)

{

if(handerbarAD>=210)

//当state_400ms小于0.5s,handerbarAD大于4.1V

//846对应于4.1V

{

f++;

c=0;

d=0;

if(f >=10)

{

f=0;

state_400ms=0;

P13=1;

//PCODR_ODR5=1;//第二绿灯亮

P12=0;//

PCODR_ODR4=0;//关红灯

CR=0; //P16=0 ; //TIM1_CCER2=0x00;//关报警

P16=0 ;

}

}

else if(handerbarAD<210)

{f=0;}

}

//当state_400ms大于0.5s,转把还没达到4.1V

else if(state_400ms>=400)

{

if(handerbarAD<210)

{

c++;

if(c >=10)

{

c=0;

P12=1;// PCODR_ODR4=1;//红灯亮

CR=1;//P16=1; //TIM1_CCER2=0x01;//蜂鸣器报警

TR0=1;

P16=1;

}

else

if(handerbarAD>210)

{c=0;}

}

}

//1.5V对应77(310);

else if(handerbarAD>=77)//当转把AD电压大于1.5V,开始0.5秒jishi

{

d++;

if(flag == 0&&d == 10)//转把插入与d=10

{

d = 0;

flag = 1;

state_400ms = 1;

}

}

else if(handerbarAD<77)//当小于1.5V,将d清零

{

d=0;

}

}

//按键处理

key=P11;//key=PDIDR_IDR4;

if(key == 0)

{

key_count++;

if(key_count>=3)

{

key_count=0;

if(key == 0)

{

state=0;

state_400ms=0;

P11=0;// PCODR_ODR4=0;

P12=0;//PCODR_ODR5=0;

P13=0;//PCODR_ODR6=0;

alarm_flag=0;

CR=0;//

P16=0;//TIM1_CCER2=0X00;

P16=0;

}

}

}

//**************************************************************************

}//10ms时间片右括号

if(Time_50ms>=50)

{

Time_50ms=0;

Time_500ms++;

//guoliutest();//过流每50ms检测一次

if(Time_500ms>=10)

{

Time_500ms=0;

if(alarm_flag)

{

CL=0x00;

CH=0x00;

CR=~CR;//P16=~P16; //TIM1_CCER2

=1-TIM1_CCER2;

TR0=1;//~TR0;

P16=~P16;

}

}

}

}//1ms时间片右括号

}//wile(1)右括号

}

相关主题
相关文档
最新文档