/*
* ATtiny13A.c
*通过测量外部的0-3V电压控制PWM输出占空比,频率2KHZ
* Created: 2021/12/9 20:57:11
* Author : JIA
*/
#include <avr/io.h>
#define F_CPU 4800000UL //在延时文件前定义
#include <util/delay.h>
//#include <avr/interrupt.h>
#define uchar unsigned char
#define uint unsigned int
#define LED0 PORTB &= ~(1 << PORTB3)
#define LED1 PORTB |= (1 << PORTB3)
void init(void) //初始化函数
{
/******* IO端口配置 ******/
DDRB |= (1 << DDB3) | (1 << DDB0) | (1 << DDB1); //定义输出端口:PB3临时指示灯,PB0-PWM; PB1-STOP(0);
DDRB &= ~((1 << DDB4) | (1 << DDB2)); //定义输入端口:PB4-过载信号监测;PB2-采样信号模拟量输入
PORTB |= (1 << PORTB0); //初始化启动风扇停转
PORTB &= ~((1 << PORTB1) | (1 << PORTB3)); //STOP信号初始化为0;点亮指示灯
/********* ADC 模数转换配置 ***********/
ADMUX |= (1 << MUX0); //VCC作为参考电压,采用右对齐,ADC1(PB2)通道 (REFS0片内1.1V基准)
ADCSRA |= (1 << ADEN) | (1 << ADSC) | (1 << ADPS2) | (1 << ADPS0) |(1 <<ADATE); //(ADATE)连续转换,注意这个值,不允许中断,32分频
ADCSRB = 0X00;
/******** 快速PWM配置 ******/
TCCR0A |= (1 << WGM01) | (1 << WGM00) | (1 << COM0A1) | (1 << COM0A0); //快速PWM,PB4引脚,TCNT0与OCR0A匹配时,输出高电平 (后期改为高电平计数置顶输出高电平
TCCR0B |= (1 << CS01); //时钟8分频,2.4KHZ
OCR0A = 0x38; //15%占空比
TCNT0 = 0x00;
}
/****** 转换结果 调整占空比 *******/
void ADC_Convert(void)
{
unsigned long temp = 0 ;
uint adc_v;
temp =ADC;
_delay_ms(2);
temp += ADC;
_delay_ms(2);
temp+=ADC;
temp = temp/3;
adc_v = (unsigned long)temp*5000/1024; //数据处理得到被测电压值
if ( adc_v <= 3000 )
{
if (adc_v <= 300)
{
OCR0A = 0x19; //10% 0x19
}
if ((300< adc_v) && (adc_v <= 600))
{
OCR0A = 0x33; //20%
}
if ((600< adc_v) && (adc_v <= 900))
{
OCR0A = 0x4C; //30%
}
if ((900 < adc_v) && (adc_v <= 1200))
{
OCR0A = 0x66; //40%
}
if ((1200< adc_v) && (adc_v <= 1500))
{
OCR0A = 0x7F; //50%
}
if ((1500< adc_v) && (adc_v <= 1800))
{
OCR0A = 0x99; //60%
}
if ((1800< adc_v) && (adc_v <= 2100))
{
OCR0A = 0xB2; //70%
}
if ((2100< adc_v) && (adc_v <= 2400))
{
OCR0A = 0xCC; //80%
}
if ((2400< adc_v) && (adc_v <= 2700))
{
OCR0A = 0xE5; //90%
}
if ((2700< adc_v) && (adc_v <= 3000))
{
OCR0A = 0xFF; //100%
}
}
else
{
OCR0A =0xFF;// 0xFF;
}
}
/******* 主函数 ********/
int main(void)
{
init(); //初始化
while (1)
{
ADC_Convert();
if ( !((PINB & 0x10)== 0x10))
{
_delay_ms(200); //排除干扰
if ( !((PINB & 0x10)== 0x10))
{
PORTB |= (1 << PORTB1); //控制继电器吸合,启动保护
OCR0A =0xFF; //风扇全速
LED1; //测试指示灯
_delay_ms(8000); //吸何8sec
PORTB &= ~(1 << PORTB1); //继电器断开
LED0;
_delay_ms(1000);
}
}
}
return 0;
}
附:熔丝位配置图
网上资料比较少,研究调试半天,小冷门,需要的朋友直接用。