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

📄 main.c

📁 avr NRF驱动 编程.里面有NRF驱动说明.新手可以参考.
💻 C
字号:

//太阳能帽子 AVR驱动程序  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,fengs=0;
unsigned int changdu=0;

OCR1B=45;
fengs=OCR1A;
OCR1A=50;//关闭风扇

	for(cishu=0;cishu<x;cishu++)
	{
		for(changdu=0;changdu<600;changdu++)
		{
		
		yanshi(31);
		PORTD^=32;	//声音
		
		}
		
		yanshi(40000);
	 
	
	}

OCR1A=fengs;//重新启动风扇

}









unsigned char tem=0,tem10=0,tem100=0,tem1000=0;


unsigned char x=0;

SIGNAL(SIG_OVERFLOW0)		//TO中断服务程序
{

TCNT0=255-10;  		// 10MS
tem=1;


}
/*

SIGNAL(SIG_OVERFLOW2)		//T2中断服务程序
{

}


SIGNAL(SIG_UART_RECV)		//接收中断
{



} 




SIGNAL(SIG_UART_TRANS)		//发送完成中断
{


} 

*/

void chushi(void)
{



	CLKPR=128;
	CLKPR=2;
	
	
	WDTCSR=0B00011000;//KANMENGOU
	WDTCSR=0B00101000;//4sKANMENGOU 启动看门狗 4秒方式
			asm("WDR");

	DDRB=6;	//pb =in 无上拉
	PORTB=255-6;	
	
	DDRD=48;	//5 4 =OUT  3 2 =IN
	PORTD=255-32-16;	//3  2 上拉
	
	DDRC=0;	//ADC
	PORTC=255-3;
	
	
	
	
	
		
	//		初始化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=242; //AB输出方式为匹配拉高  非匹配强制方式  快速PWM方式ICR1定义方式
	TCCR1B=25;	//AB输出工作于快速PWM方式ICR1定义 时钟源S/1
	ICR1=50;			//定义TOP数值
	OCR1A=50;
	OCR1B=45;//启动即可开始进行变换 用来给CPU提供电能
	
	
	
	//===================//初始化AD转换器
	
	ADMUX=0B01000000;	//AD工作于AVCC基准电压状态 同时设定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<=5)
OCR1B=5;
else
OCR1B-=1;

}



void pwmjian(void)
{
	if(OCR1B<50)
	OCR1B+=1;

}


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;
		}
	}

}


unsigned char keyjz=0,keyys=0,dianyad=0,yici=0;

unsigned char ledshan=0,ledkz=0,dianya=0;
//充电闪烁状态  =0充电总 =1充电完成满 
//LED闪烁状态  =0充电指示状态 =1非充电闪烁状态
//dianya =1 低压状态 =2 充满状态
int main(void)
{


	chushi();
	

								  

	for(;;)	//事实程序在这里面循环
	{
		if(tem)
		{
		tem=0;
		
		
		
		
		/*
		ADMUX=0B01000001;
		//ADCSRA=0B11000010;
		ADCSRA|=16+64+128;	//清除完成标志 同时启动转换开始
		for(;(ADCSRA&16)==0;);
		
		ADDATA[1]=ADC;
		
		
		ADMUX=0;
		ADCSRA=0;
		
					ADMUX=0B01000000;
					//ADCSRA=0B11000010;
					ADCSRA|=16+64+128;	//清除完成标志 同时启动转换开始
					for(;(ADCSRA&16)==0;);
					
					ADDATA[0]=ADC;
					
					ADMUX=0;
					ADCSRA=0;
					
					*/
		
			tem100+=1;
			if(tem100>19)
			{tem100=0;
			
			//100ms
									tem1000+=1;
                                  if(tem1000>=10)
                                  {//节拍1000
                                  tem1000=0;
                                  //1000ks
                                 
								if(yici==0)
								{
								yici=1;
								 shengyin(2);	//开机两声
								}
								  
                                  
                                  		asm("WDR");

                                  }//节拍1000END
                                  
				
				//100ms
				
				
			
				if(OCR1B<50)
				{
				ledkz=0;	//指示充电的状态
				}
				else
				{
				ledkz=1;
				}
				
				if(ADDATA[1]>630)	//表示电池电压高
				{
				ledkz=0;//充满电后显示充满
				dianya=1;
				}
				else
				{
					if(ADDATA[1]<620)dianya=0;//3.95v 表示电池电压低
				}
			
			
				if(ledkz)
				{//非充电指示
					if(OCR1A<50)
					shan(2,30);
					else
					shan(1,30);
				
				}
				else
				{//充电指示
					if(dianya)
					{
					shan(2,10);
					}
					else
					{
					shan(1,10);
					}
				}
				
				
				
					//===============================键盘
		
				if(!(PIND&4)&&(keyjz==0))//+
				{
				shengyin(1);
				
				keyjz=1;
				
				OCR1A-=5; 
				if(OCR1A>=40)OCR1A=40;	//最小功率控制
					if(OCR1A<6)
					{
					OCR1A=50;
					shengyin(2);//停机带有两个声音
					}
		
				}
				
				
				if(!(PIND&8)&&(keyjz==0))//-
				{
				shengyin(1);
				keyjz=1;
				OCR1A+=5;
					if(OCR1A==55)
					{
					OCR1A=10;
					}
					
					if(OCR1A>41)
					{
					OCR1A=50;
					shengyin(2);//停机带有两个声音
					}
				}
			
			
			if((PIND&12)==12)keyjz=0;
			


					
				if((ADDATA[1]<540)&&(OCR1A<40))//电池电压低到这里进行将功率处理
				{
				OCR1A=40;
				shengyin(2);
				}
				
				if((ADDATA[1]<530)&&(OCR1A<50))//电池电压低到这里进行将功率处理
				{
					dianyad+=1;
					if(dianyad>10)
					{
					OCR1A=50;
					shengyin(3);
					}
				}
				else
				{
				dianyad=0;
				}
				
			
			
			
			//100msEND
			}
		//10ms
		
		
		

		
		

		//10msend
		
		}
		AD(&ADDATA[0]);
		//自动电压电流调节
		
		
		
		if(ADDATA[1]<630)	//651=2.1v  电池电压检测 电池没有充电满则继续冲 否则禁止功率输出
		{
			if(ADDATA[0]>465)//465 = 1.5v
			{
			pwmjia();
			}
			else
			{
				if(ADDATA[0]<460)
				{
				pwmjian();
				}
			}
		}
		else
		{
		pwmjian();
		
		}
		
		


	}


}


⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -