⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 main.c

📁 avr NRF驱动 编程.里面有NRF驱动说明.新手可以参考.
💻 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 + -