標(biāo)題:
我的STM32單片機(jī)項(xiàng)目經(jīng)驗(yàn)(加力器報(bào)警器)
[打印本頁]
作者:
51黑黑黑
時(shí)間:
2016-2-23 17:56
標(biāo)題:
我的STM32單片機(jī)項(xiàng)目經(jīng)驗(yàn)(加力器報(bào)警器)
以前為了解決單位實(shí)際需要制作了加力器報(bào)警器,其中里面的控制器是采用STM32單片機(jī),這次去沈陽面試單片機(jī)崗位這個(gè)項(xiàng)目很適合做介紹,我把這個(gè)項(xiàng)目的過程介紹下。加力器是汽車中剎車系統(tǒng)的一部分,加力器是用氣體頂動(dòng)油液來完成加倍力量帶動(dòng)剎車片的。加力器的氣活塞容易在運(yùn)動(dòng)中卡死,本報(bào)警作用就是在卡住時(shí)報(bào)警提示司機(jī)。
工作原理:
1.定義一個(gè)數(shù)組 u16 distance_l[2] = {0,0};作用是先后采集的兩次ADC數(shù)據(jù)存儲(chǔ)在這個(gè)數(shù)組中,其中ADC經(jīng)過了取平均數(shù),冒泡排序等濾波方法。
2.在主函數(shù)中首先對(duì)系統(tǒng)時(shí)鐘,ADC,led,定時(shí)器初始化,然后完成一個(gè)超限報(bào)警功能,就是油液漏油氣活塞沒有阻力超過正常值時(shí)報(bào)警的功能。本程序采用函數(shù)模塊化編程,調(diào)用了一個(gè)返回超限標(biāo)志的函數(shù)bool isOverrun(distance_l[0]);這個(gè)函數(shù)傳入ADC數(shù)據(jù)如果超限就返回一個(gè)超限標(biāo)志值。
3.接著完成返回剎車中標(biāo)志函數(shù) bool isBrake_state(distance_l[0]);因?yàn)橹挥性诓葎x車狀態(tài)下才需要檢測,所有控制需要知道是否踩剎車了,調(diào)用了返回剎車中標(biāo)志函數(shù)傳入了ADC數(shù)據(jù)中就可以返回是否是踩剎車狀態(tài)。
4.然后調(diào)用警報(bào)函數(shù)voidAlarm_dispose(bool lim_l, bool lim_r, bool lock);需要傳入3個(gè)值,兩個(gè)超限標(biāo)志值,一個(gè)活塞被卡標(biāo)志位,這幾個(gè)標(biāo)志位任何一個(gè)成立就完成報(bào)警。
5.定時(shí)器中斷服務(wù)程序是關(guān)鍵,定時(shí)器2的功能是控制蜂鳴器報(bào)警的,定時(shí)器3中斷服務(wù)程序完成任務(wù)有,調(diào)用氣活塞是否被卡函數(shù)voidStuck(void);
在采集數(shù)據(jù)方面首先采集了300個(gè)數(shù)據(jù),然后采用了冒泡排序去掉了一個(gè)最高值和一個(gè)最值,再取平均數(shù)完成軟件濾波的,濾波程序如下:
void filter(u8 ch)
{
int count,i,j;
for ( count=0; count
{
value_buf[count]=Get_Adc(ch); //采集數(shù)據(jù)
}
for (j=0;j
{
for(i = 0; i < N-j; i++)
{
if ( value_buf[i] >value_buf[i+1] )
{
temp =value_buf[i];
value_buf[i] = value_buf[i+1];
value_buf[i+1] = temp;
}
}
}
sum = 0;
for(count = 1;count < N-1; count++)
sum += value_buf[count];
sum = sum / (N - 2);
// sum = sum;
}
主函數(shù)程序如下:
#include
#include "sys.h"
#include "usart.h"
#include "delay.h"
#include "led.h"
#include "key.h"
#include "exti.h"
#include "wdg.h"
#include "timer.h"
#include "adc.h"
#include "alarm.h"
#define LIM 5 //卡住判斷參數(shù)
u16 distance_l[2] = {0,0}; //卡住比較數(shù)組
u16 distance_r[2] = {0,0};
u8 i = 0; //采集數(shù)據(jù)計(jì)數(shù)變量
bool brake_state_l, brake_state_r; //剎車狀態(tài)標(biāo)志位
bool lock_alarm_l, lock_alarm_r, lock_alarm; //卡住報(bào)警標(biāo)志位
u16 value_buf[N]; //濾波求平均緩存
u32 sum; //濾波求平均總和緩存
u16 temp; //濾波求排序緩存
void Stuck(void); //判斷是否活塞卡住
int main(void)
{
bool lim_alarm_l, lim_alarm_r; //超限警報(bào)標(biāo)志位
Stm32_Clock_Init(9); //系統(tǒng)時(shí)鐘設(shè)置
delay_init(72); //延時(shí)初始化
uart_init(72,9600); //串口1初始化
LED_Init();
Adc_Init();
Timer2_Init(5000,7199); //定時(shí)報(bào)警
Timer3_Init(2000,7199); //定時(shí)采集ADC
// Timer4_Init(5000,7199); //定時(shí)打印
while(1)
{
lim_alarm_l = isOverrun(distance_l[0]); //返回超限標(biāo)志
lim_alarm_r = isOverrun(distance_r[0]);
brake_state_l = isBrake_state(distance_l[0]); //返回剎車中標(biāo)志
brake_state_r = isBrake_state(distance_r[0]);
//報(bào)警處理函數(shù)
Alarm_dispose(lim_alarm_l, lim_alarm_r, lock_alarm);
}
}
void TIM2_IRQHandler(void)
{
if(TIM2->SR&0X0001) //溢出中斷
{
BUZZER = 0;
delay_ms(100);
BUZZER = 1;
}
TIM2->SR&=~(1<<0); //清除中斷標(biāo)志位
}
void TIM3_IRQHandler(void)
{
if(TIM3->SR&0X0001)//溢出中斷
{
if( (lock_alarm_l || lock_alarm_r) && (brake_state_l|| brake_state_r) )
lock_alarm = 1;
if( (brake_state_l == 0) &&(brake_state_r == 0))
lock_alarm = 0;
Stuck(); //數(shù)據(jù)采集后判斷是否活塞卡住
}
TIM3->SR&=~(1<<0); //清除中斷標(biāo)志位
}
void Stuck(void)
{
filter(ADC_CH0);
distance_l[i] = sum;
delay_ms(20);
filter(ADC_CH1);
distance_r[i] = sum;
i++;
if(i > 1) //采集了兩組數(shù)據(jù)后判斷一次是否卡住
{
i = 0;
if( ( (distance_l[1]-distance_l[0]) < LIM) && ((distance_l[1]-distance_l[0]) > -50) )
lock_alarm_l = 1;
if( ( (distance_r[1]-distance_r[0]) < LIM) && ((distance_r[1]-distance_r[0]) > -50) )
lock_alarm_r = 1;
printf("%d\n",distance_l[1]-distance_l[0]);
// printf("%d\n",distance_r[1]-distance_r[0]);
}
}
void TIM4_IRQHandler(void)
{
if(TIM4->SR&0X0001) //溢出中斷
{
// printf("a1= %d\n",sum);
// printf("a1= %d,a2= %d\n",adc_l, adc_r);
// printf("a1 %d, d1 %d, %d\n",adc_l, distance_l[0],distance_l[1]);
// printf("a2 %d, d2 %d, %d\n",adc_r, distance_r[0],distance_r[1]);
// printf("%b, %b\n",lock_alarm_l, lock_alarm_r );
}
TIM4->SR&=~(1<<0); //清除中斷標(biāo)志位
}
歡迎光臨 (http://www.torrancerestoration.com/bbs/)
Powered by Discuz! X3.1