📄 vreg.c
字号:
#include <avr/io.h>#include <avr/interrupt.h>#include "vreg.h"#include "stk500protocol.h" /* for stkParam */#define VREG_REF (uint)((2.06 / 2.56) * 1024)#define CHANNEL_VREG 0#define CHANNEL_TARGET 1#define REFERENCE_BITS UTIL_BIN8(1100, 0000)#define PWM_RANGE (1 << 9)#define PWM_CENTER (PWM_RANGE * 7 / 12)#define DIVIDER (uchar)(22 * 1024 / ((33 + 22) * 25.6)) /* is coincidentally == 16 *//* The divider above normalizes the ADC value to 10 * vTarget */UTIL_INTERRUPT(SIG_ADC) /* run with global interrupt enable */{uint value = ADC;uchar muxVal = ADMUX & 0xf; if(muxVal == CHANNEL_VREG){ int x = PWM_CENTER + ((VREG_REF - value) * 32); if(x <= 0){ x = 1; }else if(x > PWM_RANGE - (PWM_RANGE / 5)){ x = PWM_RANGE - (PWM_RANGE / 5); } OCR1A = x; ADMUX = REFERENCE_BITS | CHANNEL_TARGET; }else{ /* must be CHANNEL_TARGET */ /* Since divider is coincidentally a power of 2, do the division here * in the interrupt. Otherwise create an accessor function which is * called when reading the parameter. */ stkParam.s.vTarget = (value + DIVIDER/2) / DIVIDER; ADMUX = REFERENCE_BITS | CHANNEL_VREG; } ADCSRA |= 1 << ADSC; /* start next conversion */ }void vregInit(void){ ADMUX = REFERENCE_BITS | CHANNEL_VREG; ADCSRA = UTIL_BIN8(1000, 1101); /* enable ADC, enable interrupt, prescaler=32 */ ADCSRA |= 1 << ADSC; /* start conversion */}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -