📄 main.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 + -