电动车霍尔转把检测程序
电动车霍尔转把检测程序
//转把电压控制,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)右括号
}