/*======================
時間:2020.4.29
版本:V1.0
作者:
+++++++++++++++++++++++*/
//(1)關於定時器使用
/*======================
各單片機型號不同*.h文件不同
定時器內添加
ptc.h //NXP單片機一般使用
timer.h //STM單片機一般使用
=======================*/
typedef struct _TP{
//INPUT 輸入
unsigned short task01;
unsigned short task02;
unsigned short task03;
unsigned short task04;
unsigned short task05;
unsigned short task06;
unsigned short task07;
unsigned short task08;
unsigned short task09;
unsigned short task10;
//OUTPUT 輸出
//SYSTEM 系統使用
}TP;
extern TP TP_1ms;
/*======================
各單片機型號不同*.c文件不同
定時器內添加
ptc.c //NXP單片機一般使用
timer.c //STM單片機一般使用
=======================*/
TP TP_1ms;
void RIT_DriverIRQHandler(void) //NXP單片機 TIM1中斷 1ms定時中斷
{
PIT_FLAG_CLEAR; //清除TIMx更新中斷標誌
TP_1ms.task01++;
TP_1ms.task02++;
TP_1ms.task03++;
TP_1ms.task04++;
TP_1ms.task05++;
TP_1ms.task06++;
TP_1ms.task07++;
TP_1ms.task08++;
TP_1ms.task09++;
TP_1ms.task10++;
}
//定時器3中斷服務程序
TP TP_100ms;
void TIM3_IRQHandler(void) //STM32單片機 TIM3中斷 1ms定時中斷
{
if (TIM_GetITStatus(TIM3, TIM_IT_Update) != RESET) //檢查TIM5更新中斷髮生與否
{
TIM_ClearITPendingBit(TIM3, TIM_IT_Update ); //清除TIMx更新中斷標誌
TP_1ms.task01++;
TP_1ms.task02++;
TP_1ms.task03++;
TP_1ms.task04++;
TP_1ms.task05++;
TP_1ms.task06++;
TP_1ms.task07++;
TP_1ms.task08++;
TP_1ms.task09++;
TP_1ms.task10++;
}
}
//(2)關於main主頻運算函數
/*======================
系統主頻計算添加
使用到了TP定時
該功能可用於計算任意函數運行頻率
間接獲取CPU的使用率
=======================*/
//@@----------------系統主頻計算 START-----------------------------------
typedef struct _SYSTEMBWRITE //系統參數列表
{
//INPUT 輸入
int countMain; //主函數變量自加
int countUart; //可用於串口接收頻率計算
//OUTPUT 輸出
int freMainHz; //系統主頻(算什麼函數放什麼函數內)
int freUartHz; //串口主頻(算什麼函數放什麼函數內)
//SYSTEM 系統使用
}SYSTEM_BWRITE;
SYSTEM_BWRITE systemPic;
/*==================================================
函數說明:系統主頻計算函數
變量說明:
*Time 定時器內累加時間
*count 系統自加數
引用說明:
main()
{
while(1)
{
systemPic.freMainHz ++; //系統變量自加
systemPic.freMainHz = calFunctionHz(&TP_1ms.task01, &systemPic.countMain); //計算函數運行頻率
}
}
===================================================*/
int calFunctionHz(unsigned short *Time, int *count) //計算函數運行頻率
{
signed int resultHz; //定義靜態變量,防止每次引用清零
signed int consultm = 100; //每100ms運算一次
if(*Time >= consultm) //
{
resultHz = *count *1000 / *Time; //計算頻率
*Time = 0; //清零標誌位
*count = 0; //計數清零
}
return resultHz; //返回計算結果
}
//@@----------------系統主頻計算 END -----------------------------------
//(3)關於main函數智能車框架
/*======================
各單片機型號不同
1 實際函數名可能不一樣
2 實際變量名可能不一樣
3 根據實際使用情況,有些函數可以不用
=======================*/
int main(void)
{
//--------系統初始化-----START
get_clk(); //打開時鐘頻率
DisableInterrupts; //關閉全部中斷
//ADC各通道初始化
adc_init(ADC1); //ADC初始化
adc_init(ADC2); //ADC初始化
adc_init(ADC3); //ADC初始化
adc_init(ADC4); //ADC初始化
//PWM各通道初始化
ctimer_pwm_init(TIMER1_PWMCH0_A18, 65535, 32768); //初始化定時器1 使用A18引腳 初始化頻率爲17Khz
ctimer_pwm_init(TIMER1_PWMCH1_A20, 65535, 32768); //初始化定時器1 使用A20引腳 初始化頻率爲17Khz
ctimer_pwm_init(TIMER2_PWMCH1_B4, 65535, 32768); //初始化定時器2 使用B4 引腳 初始化頻率爲17Khz
ctimer_pwm_init(TIMER2_PWMCH0_B5, 65535, 32768); //初始化定時器2 使用B5 引腳 初始化頻率爲17Khz
//編碼器初始化
ctimer_count_init(SPEEDL_PIN); //左編碼器初始化
gpio_init(SPEEDL_DIR,GPI,0,PULLUP); //初始化方向IO 且上拉
ctimer_count_init(SPEEDR_PIN); //右編碼器初始化
gpio_init(SPEEDR_DIR,GPI,0,PULLUP); //初始化方向IO 且上拉
//定時器初始化
pit_init_us(1000); //初始化PIT,並設置定時時間(單位爲 微秒) 中斷初始化(1ms)
set_irq_priority(RIT_IRQn,0); //設置優先級,根據自己的需求設置可設置範圍爲 0 - 3
enable_irq(RIT_IRQn); //使能IRQ
//串口初始化
uart_init(USART_0,115200,UART0_TX_A25,UART0_RX_A24);
//IIC初始化MPU6050
mpu_dmp_init();
//OLED屏幕初始化
oledInit();
//--------系統初始化-----END
EnableInterrupts; //使能全部中斷
//++++++++ START WHILE ======
while()
{
//任務 1 獲取 運行頻率
systemPic.freMainHz ++; //系統變量自加
systemPic.countMain = calFunctionHz(&TP_1ms.task01, &systemPic.freMainHz); //計算函數運行頻率
//任務 2 獲取各種數據
//電感。紅外,姿態,速度等
getSensorDataOne(&TP_1ms.task02, 2); //根據實際使用情況,確定時間基數
getSensorDataTwo(&TP_1ms.task03, 2); //根據實際使用情況,確定時間基數
getSensorFilteringInductance(&TP_1ms.task04, 2); //電感數據獲取 濾波處理 >= 採集頻率
getSensorFilteringPosture(&TP_1ms.task05, 2); //姿態數據處理 濾波處理 >= 採集頻率
getSensorFilteringImage(); //圖像數據獲取 濾波處理(本身會有標誌位)
//任務 3 數據融合 決策
dataAnalysisDecision(&TP_1ms.task06,3); //決策層 >= 採集頻率
//任務 4 其他信息處理
dealSensorUart(); //串口數據處理 (本身會有標誌位)
//任務 5 底層控制
sendFeedbackData(&TP_1ms.task07,100); //數據回饋顯示等
motorBottom(&TP_1ms.task07,5); //電機驅動控制 >= 決策頻率
//
}
//++++++++ END WHILE ======
}
//(4)關於部分函數詳解
//@@----------------電感數據相關 START-----------------------------------
typedef struct _DATA_INDUCTANCE //電感數據相關
{
//INPUT 輸入
unsigned short adNewRx; //最新 右 水平 電感值
unsigned short adNewLx; //最新 左 水平 電感值
unsigned short adNewRy; //最新 右 垂直 電感值
unsigned short adNewLy; //最新 左 垂直 電感值
//OUTPUT 輸出
unsigned short adResultRx; //最終 處理後 右 水平 電感值
unsigned short adResultLx; //最終 處理後 左 水平 電感值
unsigned short adResultRy; //最終 處理後 右 垂直 電感值
unsigned short adResultLy; //最終 處理後 左 垂直 電感值
//SYSTEM 系統使用
unsigned short adIn[4]; // 電感值
unsigned short adOut[4]; // 電感值
}DATA_INDUCTANCE;
DATA_INDUCTANCE calInductance;
/*==================================================
函數說明:電感數據相關
變量說明:
*Time 定時器內累加時間
RunCycle 運行週期
引用說明:
main()
{
while(1)
{
getSensorFilteringInductance(&TP_1ms.task04, 2); //電感數據獲取 濾波處理 >= 採集頻率
}
}
===================================================*/
void getSensorFilteringInductance(unsigned short *Time, unsigned short RunCycle); //電感數據獲取 濾波處理 >= 採集頻率
{
if(*Time >= RunCycle) //
{
*Time = 0; //清零標誌位
//數據獲取
calInductance.adNewRx = adc_once(AD_CHN2, ADC_8bit); //右一
calInductance.adNewLx = adc_once(AD_CHN1, ADC_8bit); //左一
calInductance.adNewRy = adc_once(AD_CHN4, ADC_8bit); //右二
calInductance.adNewLy = adc_once(AD_CHN3, ADC_8bit); //左二
calInductance.adIn[0] = calInductance.adNewRx;
calInductance.adIn[1] = calInductance.adNewLx;
calInductance.adIn[2] = calInductance.adNewRy;
calInductance.adIn[3] = calInductance.adNewLy;
//數據濾波
//①平均濾波
//②可以添加其他濾波算法是數據更穩定
//結果
calInductance.adResultRx = calInductance.adOut[0]; //右一
calInductance.adResultLx = calInductance.adOut[1]; //左一
calInductance.adResultRy = calInductance.adOut[2]; //右二
calInductance.adResultLy = calInductance.adOut[3]; //左二
//數據特徵提取
}
}
//@@----------------電感數據相關 END -----------------------------------
#define LINE 4 //行
#define LOW 5 //列
unsigned short adValuHistory[LINE][LOW];
/*************************************************************************
* 函數名稱 abs
* 功能說明: 求絕對值函數
* 參數說明:
* 函數返回: |X|
* 修改時間:
* 備 注:
*************************************************************************/
//數據範圍998-1500--2000
/*
filtering(InCapture.getData, InCapture.getFlag, InCapture.dealData, 9);//遙控器數據濾波
輸入: 998 -- 1500 -- 2000
輸出:
1 比較其他濾波優化算法
2 開機自動找整的實現
3 屏蔽遙控器設置
*/
void filtering(int *getData, int *dealData, char len)
{
short ch, i;
// static int changCH[9];
for(ch==0; ch<len; ch++)
{
unsigned int AD_valu_max = 0;
unsigned int AD_valu_min = 5000;
unsigned int Sum=0;
AD_valu_History[ch][0] = *(getData + ch) ; //原始值相加
for(i=TIME-1;i>=0;i--)
{
AD_valu_History[ch][i+1] = AD_valu_History[ch][i];
Sum += AD_valu_History[ch][i];
if(AD_valu_History[ch][i]>AD_valu_max)
{
AD_valu_max=AD_valu_History[ch][i];
}
if(AD_valu_History[ch][i]<AD_valu_min)
{
AD_valu_min=AD_valu_History[ch][i];
}
}
Sum = Sum - AD_valu_max - AD_valu_min;
// changCH[ch] = Sum/(TIME-2); //次(TIME)滑動平均濾波
*(dealData+ch) = Sum/(TIME-2); //次(TIME)滑動平均濾波
}
//重新安排數組對應關係
}