如上所述,太陽能自動跟蹤系統的軟件部分包含多個模塊,各模塊的啟動和停止由單片機控制。在程序設計時,將這些模塊的入口都安排在主程序中,主程序循環檢測通過串口接收的命令,通過對命令解釋,然后根據命令轉入相應的模塊。程序流程圖如圖3.1。
系統軟件的設計主要是通過C語言編程實現單片機對步進電機控制以及系統狀態的顯示。
系統通電后,首先對LCD,IO端口初始化,然后開中斷,此時系統開始工作,檢測當前太陽位置,直到接收板對準太陽,實現對太陽能全方位跟蹤。系統默認時間是00:00,用戶可以根據當地時間調整系統時間。當陰天時,太陽跟蹤系統檢測不到太陽,為了實現太陽一出來就能自動跟蹤太陽,系統時間每到12:00或18:00(也是太陽落山),系統自動控制接收板與大地垂直,這樣不管太陽在那個位置,接收板都能檢測到太陽。
圖中,啟動后首先進行的初始化包括:對單片機本身的中斷和LCD液晶顯示器等的初始化。
系統采用光敏電阻光強比較法,設計出一種全新的光電轉換裝置,很好的實現了光電轉換。它能夠利用光敏電阻比較法實現對太陽水平、垂直方向的全方位跟蹤,晚上便自動復位。當太陽的水平或垂直位置發生偏移時,D1、D2或D3、D4(另一組控制電路)四個光電管中必有一個受陽光照射,這樣就可確認太陽運動的方向了。控制電路有兩組,電路圖中是其中的一組,另一組電路與此相同。光電管是直接與控制電路連接的,當太陽能板正對太陽時,D1、D2都是高電阻,A、B兩點電壓相等。運放輸出的電壓相同,單片機收到的信號差為零,所以單片機不控制電動機轉動。若陽光發生傾斜,使Dl被陽光射中呈低電阻,則A點電位比B點高,信號經過放大和轉換,則單片機使得電機得電轉動并拖動太陽能板轉動,使太陽能板重新對準太陽。當D1、D2重新轉為高電阻時,電機停轉。若陽光偏轉時使D2被陽光射中則電機反轉。不論哪種情況,電機運動的方向和太陽運動的方向總是一致的.從而達到了跟蹤的目的。當光敏電阻對準陽光時,采用微凋即可使得A、B兩點的電位相等,以提高系統的準確度。
該程序中參數 vol_value_2 是硅光片上面的光敏電阻經過A/D轉換所得的電壓值,參數vol_value_4是硅光片下面的光敏電阻經過A/D轉換所得的電壓值,上段程序是將上下兩個光敏電阻吸收的陽光通過A/D轉換變為電壓后進行比較,從而控制電機的正反轉。
3.3 太陽能板二維角度調整模塊
3.3.1 電機水平轉動控制部分
當通過AD轉換后,單片機得到左右兩邊的輸出電壓,若左右兩邊的輸出電壓不相等時,水平電機控制部分別開始工作,若左邊電壓值比右邊電壓值高且左邊電壓與右邊電壓差的絕對值超過一定的范圍時,電機開始向右轉,反之,若右面電壓比左面電壓大,且左右兩面電壓差的絕對值超過一定范圍后,電機向左轉,否則,電機不轉動。當水平控制結束后,水平轉動停止,垂直轉動開始。
在這個模塊中,超過一定是絕對值是為了避免因為很小的誤差或者一些沒有必要轉動的情況下電機發生轉動,提高了電機的利用效率。
3.3.2 程序設計思想或說明
通過AD轉換得到光敏電阻的電壓值,將左右或上下的電壓值進行比較,根據電壓值的不同進行電機的調整。以電機的水平調整為例,若左面電壓值大于右面電壓值,則表示左面接收的太陽光必右面的多,則電機通過步進電機向右轉,在轉動的同時,左右兩面的電壓也一直還在比較,直到左右兩邊電壓相等或兩面電壓的絕對值在一定的范圍內,電機水平轉動停止。
Main.c #include "msp430x14x.h" #include "adc12.h" #include "move.h" #include "cry1602.h"
unsigned char tishi_horizontal[] = {"HZ:"}; unsigned char tishi_vertical[] = {"VT:"}; unsigned char flag_horizontal_stop = 0; unsigned char flag_vertical_stop = 1; #define jingdu_horizontal 200 //水平精度控制 #define jingdu_vertical 200 //垂直精度控制 void motor_deal_horizontal(); //水平電機控制 void motor_deal_vertical(); //垂直電機控制 void main(void) { WDTCTL = WDTPW + WDTHOLD; P6DIR |= BIT2;P6OUT |= BIT2; //關閉電平轉換 P2DIR = 0xff; P2OUT = 0xf0; P1DIR = 0xff; P1OUT = 0xf0; LcdReset(); //復位1602液晶 DispNChar(0,0,3,tishi_horizontal); //顯示提示信息 DispNChar(0,1,3,tishi_vertical); //顯示提示信息 AD_Start(); while(1) { if((flag_vertical_stop == 1) && (flag_horizontal_stop ==0)) { motor_deal_horizontal(); //flag_vertical_stop = 0; } else if((flag_horizontal_stop == 1) && (flag_vertical_stop == 0)) { motor_deal_vertical(); //flag_horizontal_stop = 0; } else {;} } } void motor_deal_horizontal() //水平電機控制 { extern unsigned int vol_value_1; extern unsigned int vol_value_3; if ((vol_value_1 > vol_value_3 ) && ((vol_value_1 - vol_value_3) >= jingdu_horizontal)) { right_zhuan(1500); AD_Start(); } else if ((vol_value_1 < vol_value_3 ) && ((vol_value_3 - vol_value_1) >= jingdu_horizontal)) { fan_zhuan(1500); AD_Start(); } else { stop(); AD_Start(); flag_horizontal_stop = 1; flag_vertical_stop = 0; } } void motor_deal_vertical() //垂直電機控制 { extern unsigned int vol_value_2; extern unsigned int vol_value_4; if ((vol_value_2 > vol_value_4 ) && ((vol_value_2 - vol_value_4) >= jingdu_vertical)) { fan_zhuan_y(3000); AD_Start(); } else if ((vol_value_2 < vol_value_4 ) && ((vol_value_4 - vol_value_2) >= jingdu_vertical)) { right_zhuan_y(3000); AD_Start(); } else { stop_y(); AD_Start(); flag_vertical_stop = 1; flag_horizontal_stop = 0; } } Move.c #include <msp430x14x.h> typedef unsigned char uchar; typedef unsigned int uint; uchar F_Rotation[4]={0x10,0x20,0x40,0x80};//電機正轉表; uchar B_Rotation[4]={0x80,0x40,0x20,0x10};//電機反轉表 //電機控制模擬端口放在P2口,根據前一次的檢測光強x_before,以及 //當前采集的系統光強x_now,確定電機的轉動方向 void Delay(uint w)//延時程序 { while(--w); } //*************垂直電機控制部分程序****************** void right_zhuan_y(uint sudu) //電機正轉速度為sudu { uint w; for(w=0;w<4;w++) //4相 { P1OUT=~F_Rotation[w]; //正轉時序 Delay(sudu); //速度為sudu } } void fan_zhuan_y(uint sudu) //電機反轉速度為sudu { uint w; for(w=0;w<4;w++) //4相 { P1OUT=~B_Rotation[w]; //正轉時序 Delay(sudu); //速度為sudu } } void stop_y() { P1OUT=0XFF; Delay(10000); P1OUT=0XFF; Delay(10000); }
//*******水平電機控制部分開始************************************ void right_zhuan(uint sudu) //電機正轉速度為sudu { uint w; for(w=0;w<4;w++) //4相 { P2OUT=~F_Rotation[w]; //正轉時序 Delay(sudu); //速度為sudu } } void fan_zhuan(uint sudu) //電機反轉速度為sudu { uint w; for(w=0;w<4;w++) //4相 { P2OUT=~B_Rotation[w]; //正轉時序 Delay(sudu); //速度為sudu } } void stop() { P2OUT=0XFF; Delay(10000); P2OUT=0XFF; Delay(10000); } cry1602.c #include <msp430x14x.h> #include "cry1602.h" typedef unsigned char uchar; typedef unsigned int uint; /**************宏定義***************/ #define DataDir P4DIR #define DataPort P4OUT
全部資料51hei下載地址:
太陽能追蹤系統.zip
(121.28 KB, 下載次數: 68)
2020-4-19 21:59 上傳
點擊文件名下載附件
別人寫的供參考
太陽能自動跟蹤系統.doc
(675 KB, 下載次數: 48)
2020-4-19 21:50 上傳
點擊文件名下載附件
|