內容包含2019一些大賽題目,以及相關的了解。主要是F題電容的程序實現,采用F4系列單片機,有FDC2214的模塊的原理圖和PCB。分享給大家。
Altium Designer畫的原理圖和PCB圖如下:(51hei附件中可下載工程文件)
51hei.png (46.13 KB, 下載次數: 114)
下載附件
2020-10-19 04:53 上傳
51hei.png (23.62 KB, 下載次數: 78)
下載附件
2020-10-19 04:53 上傳
51hei.png (2.99 KB, 下載次數: 102)
下載附件
2020-10-19 04:53 上傳
單片機源程序如下:
- #include "delay.h"
- #include "sys.h"
- #include "usart.h"
- #include "myiic.h"
- #include "FDC2X2X_CMD.h"
- #include "FDC2214.h"
- #include "led.h"
- #include "key.h"
- #include "oled.h"
- #include "beep.h"
- #include "exti.h"
- #include "24cxx.h"
- #define ROUND_TO_UINT16(x) ((uint16_t)(x)+0.5)>(x)? ((uint16_t)(x)):((uint16_t)(x)+1) //將浮點數x四舍五入為uint16_t
- #define MAX_SIZE 100 //最大容量---紙張數
- #define GAP_MS 50 //校準測量采樣時間間隔
- #define DATA_ACQUIRE_NUMBER 20 //數據采集數
- #define CH 1 //通道數
- #define duty_wideth 0.5 //濾波窗寬度調整系數
- u8 Flag_Work=0,Flag_Calibration=0; //Flag_Work :工作標志位。Flag_Work=0,設備處于待機狀態;Flag_Work=1,設備處于測量狀態。
- float Cap; //Cap :設備兩極板間電容值,屏幕上實時顯示
- int Paper_Number; //Paper_Number:設備最終計算得到的A4紙張數
- __align(4) u8 dtbuf[50]; //打印緩存器 __align(4)
- float Data_Raw[DATA_ACQUIRE_NUMBER],Data_Level[MAX_SIZE],data_acquire[DATA_ACQUIRE_NUMBER];
- //排序函數
- void bubble(float a[],int n)
- {
- int i,j;
- for(i=0; i<n-1; i++)
- {
- for(j=n-1; j>i; j--)
- {
- if(a[j]<a[j-1])
- {
- float t=a[j];
- a[j]=a[j-1];
- a[j-1]=t;
- }
- }
- }
- }
- //短路檢測函數
- void Danger_Test()
- {
- if(Cap<0)
- {
- OLED_ShowString(0,0," Danger !!! ",16);
- BEEP=1;
- }
- }
- //啟動測量函數
- void Start_Measure()
- {
- int i,j,k,index_min=0,counter,sum_effective;
- float variance_high,variance_low,sum_div_sqr,div,div_sqr,sum,baseline,div_min,div_max,high_limit,low_limit,average_effective,data_measure_effective[MAX_SIZE];
- if(Flag_Work==1) //如果KEY1按鍵按下,觸發外部中斷(工作標志位置1),進入此程序,程序進入測量狀態
- {
- LED1=0; //LED1:測量指示燈
- for(i=0; i<DATA_ACQUIRE_NUMBER; i++)
- {
- Cap=FDC2214_read_CHx(CH); //Cap為設備所采的電容值
- data_acquire[i]=Cap;
- delay_ms(GAP_MS);
- }
- bubble(data_acquire,DATA_ACQUIRE_NUMBER);
- for(j=0; j<DATA_ACQUIRE_NUMBER; j++)
- {
- sum+=data_acquire[j];
- }
- baseline=sum/(float)DATA_ACQUIRE_NUMBER;
- div_min=(float)duty_wideth*(baseline-data_acquire[0]);
- div_max=(float)duty_wideth*(data_acquire[DATA_ACQUIRE_NUMBER-1]-baseline);
- high_limit=baseline+div_max;
- low_limit=baseline-div_min;
- counter=0;
- sum_effective=0.0f;
- for(k=0; k<DATA_ACQUIRE_NUMBER; k++)
- {
- Cap=FDC2214_read_CHx(CH);
- delay_ms(GAP_MS);
- if((Cap>low_limit)&&(Cap<high_limit))
- {
- data_measure_effective[counter]=Cap;
- sum_effective+=Cap;
- counter++;
- }
- }
- average_effective=sum_effective/(float)counter;
- for(i=0; i<MAX_SIZE; i++)
- {
- if(average_effective>Data_Level[i])
- break;
- }
- sum_div_sqr=0.0f;
- for(j=0; j<counter; j++)
- {
- div=data_measure_effective[j]-Data_Level[i-1];
- if(div<0)
- div=-div;
- else div=div;
- div_sqr=div*div;
- sum_div_sqr+=div_sqr;
- }
- variance_high=sum_div_sqr/(float)counter;
- for(j=0; j<counter; j++)
- {
- div=data_measure_effective[j]-Data_Level[i];
- if(div<0)
- div=-div;
- else div=div;
- div_sqr=div*div;
- sum_div_sqr+=div_sqr;
- }
- variance_low=sum_div_sqr/(float)counter;
- if(i>=1)
-
- {
- if(variance_high>variance_low)
- index_min=i;
- else
- index_min=i-1;
- }
- Paper_Number=index_min+1; //下標+1得到紙張數
- OLED_ShowNum(0,4,Paper_Number,10,16); //OLED顯示紙張數
- BEEP=1;
- delay_ms(500);
- BEEP=0;
- LED1=1;
- Flag_Work=0; //將工作標志位置0,測試儀進入待機狀態
- }
- }
- //校準函數
- void Calibration()
- {
- int i,j,k,counter;
- float sum,sum_effective,baseline,high_limit,low_limit,div_min,div_max;
- Flag_Calibration=0; //校準標志位,KEY2按鍵置1,相當于確定
- OLED_ShowString(0,0," Calibration ",16);
- for(i=0; i<MAX_SIZE; i++) //循環校準不同數量紙的電容值
- {
- sprintf((char *)dtbuf,"Place %d paper.",i+1);
- OLED_ShowString(0,2,dtbuf,16);
- OLED_ShowString(0,6," Press KEY2 !!!",16);
- while(Flag_Calibration==0)
- {
- Cap=FDC2214_read_CHx(CH);
- sprintf((char *)dtbuf,"Cap:%4.4f pF",Cap);
- OLED_ShowString(0,4,dtbuf,16);
- }
- sum=0;
- for(j=0; j<DATA_ACQUIRE_NUMBER; j++) //采集DATA_ACQUIRE_NUMBER次數據并取平均值存入AT24C02
- {
- Cap=FDC2214_read_CHx(CH);
- Data_Raw[j]=Cap;
- delay_ms(GAP_MS);
- }
- bubble(Data_Raw,DATA_ACQUIRE_NUMBER);
- for(j=0; j<DATA_ACQUIRE_NUMBER; j++)
- {
- sum+=Data_Raw[j];
- }
- baseline=sum/(float)DATA_ACQUIRE_NUMBER;
- div_min=(float)duty_wideth*(baseline-Data_Raw[0]);
- div_max=(float)duty_wideth*(Data_Raw[DATA_ACQUIRE_NUMBER-1]-baseline);
- high_limit=baseline+div_max;
- low_limit=baseline-div_min;
- counter=0;
- sum_effective=0.0f;
- for(k=0; k<DATA_ACQUIRE_NUMBER; k++)
- {
- Cap=FDC2214_read_CHx(CH);
- delay_ms(GAP_MS);
- if((Cap>low_limit)&&(Cap<high_limit))
- {
- sum_effective+=Cap;
- counter++;
- }
- }
- Data_Level[i]=sum_effective/(float)counter;
-
- if(i==0)
- {
- storFloatData DATA_LEVEL= { Data_Level[i] }; //向AT24C02寫入數據
- Storage_WriteFloatNum(4*i,DATA_LEVEL);
- BEEP=1;
- delay_ms(500);
- BEEP=0;
- }
-
- if(i>=1)
- {
- if(Data_Level[i]<Data_Level[i-1])
- {
- storFloatData DATA_LEVEL= { Data_Level[i] }; //向AT24C02寫入數據
- Storage_WriteFloatNum(4*i,DATA_LEVEL);
- BEEP=1;
- delay_ms(500);
- BEEP=0;
- }
- else
- {
- i=i-1;
- BEEP=1;
- delay_ms(200);
- BEEP=0;
- delay_ms(200);
- BEEP=1;
- delay_ms(200);
- BEEP=0;
- }
- }
- Flag_Calibration=0;
- }
- OLED_Clear();
- OLED_ShowString(0,2,"Calibration OK!!",16);
- BEEP=1; //校驗通過后蜂鳴器響2秒
- delay_ms(2000);
- BEEP=0;
- OLED_Clear();
- }
- //循環讀取AT24C02數據函數
- void Read_AT24C02()
- {
- int i;
- for(i=0; i<MAX_SIZE; i++)
- {
- storFloatData DATA=Storage_ReadFloatNum(4*i);
- Data_Level[i]=DATA.value; //錄入到Data_Level數組
- }
- }
- int main()
- {
- delay_init(168); //延時函數初始化
- uart_init(115200); //串口初始化為115200
- LED_Init();
- KEY_Init();
- BEEP_Init();
- OLED_Init();
- EXTIX_Init();
- AT24CXX_Init();
- FDC2214_Init();
- Read_AT24C02(); //上電復位后讀取AT24C02中存儲的紙張數的電容值均值(做比對參考電容值)
- OLED_Clear();
- while(1)
- {
- Cap=FDC2214_read_CHx(CH); //讀取電容值
- //----------OLED第一行顯示內容-------------//
- OLED_ShowString(0,0,"|Paper Counter|",16);
- //----------OLED第二行顯示內容-------------//
- OLED_ShowString(0,2,"----------------",16);
- //----------OLED第三行顯示內容-------------//實時電容值
- sprintf((char *)dtbuf,"Cap:%4.4f",Cap);
- OLED_ShowString(0,4,dtbuf,16);
- OLED_ShowString(112,4,"pF",16);
- //----------OLED第四行顯示內容-------------//紙張數
- OLED_ShowString(0,6,"Number:",16);
- OLED_ShowNum(56,6,Paper_Number,9,16);
- if(Flag_Calibration==1) //如果KEY2鍵按下,觸發中斷進入校準狀態,不能退出(可復位重新開始)
- {
- Calibration(); //校準函數
- Flag_Calibration=0;
- }
- LED0=0; //LED0:待機指示燈--待機狀態常亮
- BEEP=0; //蜂鳴器,待機狀態不響
- Danger_Test(); //短路檢測
- Start_Measure(); //啟動測量
- }
- }
復制代碼
所有資料51hei提供下載:
FDC2214_PCB.zip
(5.44 MB, 下載次數: 99)
2020-10-18 20:32 上傳
點擊文件名下載附件
下載積分: 黑幣 -5
Paper_Counter_V4.0.7z
(330.13 KB, 下載次數: 105)
2020-10-19 04:55 上傳
點擊文件名下載附件
下載積分: 黑幣 -5
|