?? main.c
字號:
//太陽能帽子 AVR ATMEGA48 驅動程序 2MHZ內部標定時鐘 快速定位雙PWM 恢復值50
//2007年4月10
//溶絲位 時鐘 0010
#include"avr/io.h"
#include"avr/iom48.h"
#include"avr/signal.h"
#include "ad.h"
#include"avr/interrupt.h"
void yanshi(unsigned int x)
{
unsigned int y;
for(y=0;y<x;y++);
}
void shengyin(unsigned char x)
{
unsigned char cishu=0;
unsigned int changdu=0;
for(cishu=0;cishu<x;cishu++)
{
for(changdu=0;changdu<600;changdu++)
{
yanshi(31);
PORTD^=32; //聲音
}
yanshi(40000);
}
}
unsigned char tem=0,tem10=0,tem100=0,tem1000=0;
unsigned char x=0;
SIGNAL(SIG_OVERFLOW0) //TO中斷服務程序
{
TCNT0=255-78; // 10MS
tem+=1;
}
/*
SIGNAL(SIG_OVERFLOW2) //T2中斷服務程序
{
}
SIGNAL(SIG_UART_RECV) //接收中斷
{
}
SIGNAL(SIG_UART_TRANS) //發送完成中斷
{
}
*/
void chushi(void)
{
//CLKPR=128;
//CLKPR=0;
WDTCSR=0B00011000;//KANMENGOU
WDTCSR=0B00101000;//4sKANMENGOU 啟動看門狗 4秒方式
asm("WDR");
DDRB=14+16; //pb =in 無上拉
PORTB=255-6;
DDRD=0; //
PORTD=255; //
DDRC=0; //ADC
PORTC=255-7;
// 初始化PWM //
//==============================================================//
//TCCR1A 7 6 5 4 3 2 1 0//
// 7:6通道A比較輸出模式 快速PWM模式 00普通斷口 01取反 10匹配清零輸出TOP恢復 11。。。
// 5:4通道B比較輸出模式
// 3:2AB通道強制匹配輸出
// 1:0 WGM11 WGM10 控制序列與TCCR1B中的 3:2 組合
//模式 WGM13 WGM12 WGM11 WGM10 定時器/計數器工作模式 計數器上限TOP //
//0 0 0 0 0 普通模式 0XFFFF
//1 0 0 0 1 8位相位修正PWM 0XFF
//2 0 1 0 0 TCT OCR1A
// 0 1 0 1 8位快速PWM 0XFF
// 1 1 1 0 快速PWM ICR1
TCCR1A=226;//242; //AB輸出方式為匹配拉高 非匹配強制方式 快速PWM方式ICR1定義方式
TCCR1B=25; //AB輸出工作于快速PWM方式ICR1定義 時鐘源S/1
ICR1=80; //定義TOP數值 80=100KHZ 效率達到98%
OCR1A=80;//l40 80=0
OCR1B=0;//h38 0=0
//===================//初始化AD轉換器
ADMUX=0B11000000; //AD工作于1.1V基準電壓狀態 同時設定AD0狀態 數據是右對齊方式
//BIT 4-0 決定選擇的AD位 0-7 代表AD0-AD7
ADCSRA=0B11000010; //啟動AD,進入轉換方式 工作于非中斷方式 分頻為S/4
//BIT6為轉換完成標志 通過查詢而進行讀取 寫1開始進行轉換 變成0標志完成轉變
//BIT4為轉換完成標志 通過查詢而進行讀取 變成1表示完成變換 須用軟件寫1來完成清除標志
//初始化定時器T2
//=======================================================//
// TCCR2=7; //T2 1024分頻
// TCNT0=55; // 1/20s
// TIMSK=1<<6; //準許T2中斷bit6
/*
//初始化 UCSRB=216; //允許串口發送和接收,并響應接收完成中斷
UBRRL= 103; //設置串口波特率為4800
UCSRC= ((1<<URSEL)+(1<<UCSZ1)+(1<<UCSZ0)); //幀結構為8位數據+1位stop位
*/
//初始化T0
TCCR0B=5; //TO 1024分頻
TCNT0=78; //
TIMSK0|=1; //準許TO中斷
SREG|=1<<7;
}
unsigned int ADDATA[5];
void pwmjia(void)
{
if(OCR1B<75)
OCR1B+=1;
else
OCR1B=75;
if(OCR1B>10)
OCR1A=OCR1B+2;
else
OCR1A=80;//禁止同步整流
}
void pwmjian(void)
{
if(OCR1B>4)
OCR1B-=1;
else
OCR1B=0;
if(OCR1B>10)
OCR1A=OCR1B+2;
else
OCR1A=80;//禁止同步整流
}
unsigned char shan1=0;
void shan(unsigned char x1,unsigned char x2)//閃爍次數 閃爍間隔總長度
{
shan1+=1;
if(shan1>=x2)
{shan1=0;
}
if(x1==1) //閃爍一次
{
if(shan1==2)
PORTD|=16;
else
PORTD&=255-16;
}
else
{
if(shan1==2||shan1==4)
{
PORTD|=16;
}
else
{
PORTD&=255-16;
}
}
}
int fudian(unsigned int x)
{
return x*37.236;
}
unsigned int setvin=210;//原始電壓點 從EEPROM中來數據
unsigned int dianyain=210;//跟蹤電壓點
unsigned int jiange=0,yuandian1i=0,jianhoui=0,jiahoui=0,yuandian2i=0;
//采樣總時間控制 原點電流 -。5電流 加0。5V電壓后的電流 原點2電流
unsigned char jieduan=0,jieduan1=0,jieduan2=0,jieduan3=0,jieduan4=0;
//先采樣原點電流 然后采樣減電壓后的電流 然后采樣加電壓后的電流 然后再采樣原點電流 處理這些電流數據
//復位函數 功能恢復間隔跟蹤 間隔一定時間后再次啟動跟蹤
void fuwei(void)
{
jiange=0;
jieduan=0;
yuandian1i=0;
yuandian2i=0;
jiahoui=0;
jianhoui=0;
jieduan4=0;
}
//處理跟蹤得到的結果 跟蹤數據得到最終處理
void chuligz(void)
{
if((jiahoui>jianhoui)&&(jiahoui>yuandian1i))
{//加跟蹤成功
dianyain+=8;
fuwei();
jiange=300;//直接等待1S后再次啟動跟蹤
}
else
{
if((jianhoui>jiahoui)&&(jianhoui>yuandian1i))
{//減跟蹤成功
dianyain-=8;
fuwei();
jiange=300;//直接等待1S后再次啟動跟蹤
}
else
{//跟蹤都沒有成功 等待下次跟蹤
fuwei();
}
}
}
//跟蹤主 程序 跟蹤最大功率點功能
void genzong(void)
{
jiange+=1;
if(jiange>600)
{
switch(jieduan)
{
case 0: //階段1 對原來的功率點取樣電流 然后減0。5V電壓 等待1S進入1模式
{PORTB^=16;
jieduan1+=1;
if(jieduan1<=5)//原電流點采樣
{
yuandian1i+=ADDATA[2];
}
if(jieduan1==6)
{
yuandian1i=yuandian1i/5;
if(yuandian1i<10)//如果沒有電流 則說明太陽能板沒有陽光或者是跟蹤點錯誤恢復原始原點
{
dianyain=setvin;
fuwei();
}
else
{
dianyain-=8;//電壓降低越0。5V
}
}
if(jieduan1>200)//進入下個階段
{
jieduan1=0;
jieduan=1;
}
}
break;
case 1://階段2 對-0。5V后的功率點取樣電流然后加1V后等待1S進入模式2
{
//PORTB&=255-16;
jieduan2+=1;
if(jieduan2<=5)//原電流點采樣
{
jianhoui+=ADDATA[2];
}
if(jieduan2==6)
{
jianhoui=jianhoui/5;
dianyain+=16;//提高電壓0。5V
}
if(jieduan2>200)//進入下個階段
{
jieduan2=0;
jieduan=2;
}
}
break;
case 2://階段3 取樣加0。5V后電流 然后恢復電壓到原點 等代2S后進入下個階段
{
jieduan3+=1;
if(jieduan3<=5)//原電流點采樣
{
jiahoui+=ADDATA[2];
}
if(jieduan3==6)
{
jiahoui=jiahoui/5;
dianyain-=8;//恢復電壓到原點
}
if(jieduan3>200)//進入下個階段
{
jieduan3=0;
jieduan=3;
}
}
break;
case 3://階段4 取樣電流然后于階段1取樣電流比較 ,比較基本相同 進行于模式2的取樣比較,處理大小
{
jieduan4+=1;
if(jieduan4<=5)//原電流點采樣
{
yuandian2i+=ADDATA[2];
}
if(jieduan4==6)//原電流點采樣
{
yuandian2i=yuandian2i/5;
jieduan4=0;
if(yuandian1i>yuandian2i)//光線影響處理程序
{
if((yuandian1i-yuandian2i)>580)//如果兩次原點相差20則受到陽光強度影響 啟動再次取樣比較
{
fuwei();
jiange=0;//等待0.5S后從新啟動跟蹤
}
else
{//一切正常處理程序
chuligz();
}
}
else
{
if((yuandian2i-yuandian1i)>580)//如果兩次原點相差30則受到陽光強度影響 啟動再次取樣比較
{
fuwei();
jiange=0;//等待0.5S后從新啟動跟蹤
}
else
{//一切正常處理程序
chuligz();
}
}
}
}
break;
}
}
}
unsigned char aa=0;
int main(void)
{
chushi();
PORTB=255-8;
for(;;) //事實程序在這里面循環
{
if(tem>=1)
{
tem=0;
tem100+=1;
if(tem100>19)
{tem100=0;
//100ms
tem1000+=1;
if(tem1000>=10)
{//節拍1000
tem1000=0;
//1000ks
// asm("WDR");
}//節拍1000END
//100ms
//100msEND
}
//10ms
genzong();//跟蹤功率點程序 完成最大功率點跟蹤
//10msend
}
AD(&ADDATA[0]);
//自動電壓電流調節
aa+=1;
if(aa>20)
{aa=0;
/*
ADMUX=0B11000000;
ADCSRA|=16+64;
for(;!(ADCSRA&16);)
ADDATA[0]=ADC; //讀取AD0
*/
//電壓跟隨 完成最大功率點的電壓限制
if(ADDATA[0]>dianyain)//465 = 1.5v
{
pwmjia();
}
else
{
//if(ADDATA[0]<dianyain-2)
//{
pwmjian();
//OCR1A=80;
//OCR1B=0;
//}
}
}
}
}
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -