大家好,
我是 AVR 编程的新手,我被要求开发一个可以读取模拟传感器值并设置 PWM 输出的电路板。该设计包括一个电位器,用作两个 PWM 信号之间的百分比调光器。
由于我的编程经验仅在 Arduino IDE 中进行,因此在迁移到 Atmel Studio 7 时,我使用了 import Arduino Code 选项并使用 Atmel ICE 进行 ISP 编程。
该模型本身由两个模拟信号(传感器和电位器)和 4 个 pwm 输出(两对信号)组成。此外,代码基于基本状态机:
1) 读取传感器和电位器,确定 PWM 输出值。
2)案例1:增加PWM输出值
3)案例2:减小PWM输出值
4)案例3:保持PWM输出值
但是,每当我将传感器放在灯下(由 PWM 控制)时,它就会开始闪烁,我无法达到“稳定状态”。我可能的解决方案是读出传感器的值,并在最高和最低值之间取平均值,稍后将用于设置 PWM 输出电平,第二个将使用中断,但我不知道如何实现它们。
注意:频率设置为10 MHz,因为我使用的是3,3 V,所以根据输入值选择了cristal
/*Begining of Auto generated code by Atmel studio */
#define F_CPU 10000000UL
#include <avr/io.h>
#include <util/delay.h>
#include <Arduino.h>
/*End of auto generated code by Atmel studio */
//Pinout
const int C1 = 9; // Select the pin for Channel 1 PWM Dimming (Sunrise)
const int C2 = 6; // Select the pin for Channel 2 PWM Dimming (Daylight)
const int C3 = 5; // Select the pin for Channel 3 PWM Dimming (Sunrise 2)
const int C4 = 3; // Select the pin for Channel 4 PWM Dimming (Daylight 2)
const int CM = A1; // Select the pin for the color mixer (Potentiometer)
const int ALS = A0; // Select the pin for the ALS signal
//Variables
int ch = 0; // Current PWM level
int count = 0;
float ch1 = 0; // Color mixer factor of the Channel 1 and 3 PWM (0% - 100%)
float ch2 = 0; // Color mixer factor of the Channel 2 and 4 PWM (0% - 100%)
int mixer = 0; // Potentiometer value
int pwm = 0; // PWM counter
int th = 200; // Threshold value (light sensitivity)
int als = 0; // Stores the value of the ALS
int mst = 0; // Maschine state
int sum = 0; // Average ALS value
int sum2 = 0; // Average trimmer value
int wait = 100; // Delay value
int f = 0; //1 Machine State counter
int i = 0; //2 Machine State counter
//Setup
void setup() {
// I/O Pins
pinMode(C1, OUTPUT);
pinMode(C2, OUTPUT);
pinMode(C3, OUTPUT);
pinMode(C4, OUTPUT);
pinMode(ALS, INPUT);
pinMode(CM, INPUT);
// Set PWM outputs to LOW
analogWrite(C1, ch1);
analogWrite(C2, ch2);
analogWrite(C3, ch1);
analogWrite(C4, ch2);
//Serial.begin(9600);
}
void loop() {
//State machine init
switch(mst){
case 0:
// Read the value from the Ambient Light Sensor and the Mixer Pin
for(int i =0; i<wait; i++){
delay(0.00001);
als = analogRead(ALS);
sum = als + sum;
}
// Obtain an average ALS value
sum = sum/wait;
mixer = analogRead(CM);
//Serial.println(sum2);
if(sum > th) {
sum = th;
}
if(mixer >= 1000) {
mixer = 1000;
} else {
}
// Re-map average value to PWM level (0-255 == 0-100%)
pwm = map(sum, 0, th, 255, 0);
//Declare the color mixer percentage
if((mixer>=0)&&(mixer<512)){
ch1 = 100;
ch2 = (100*mixer)/512;
} else if(mixer<1022) {
ch1 = map(mixer, 512, 1000, 100, 0);
ch2 = 100;
} else {
ch1 = 0;
ch2 = 100;
}
//Serial.print(mixer);
ch1 = ch1/100;
ch2 = ch2/100;
//Increase PWM
if(ch<pwm-5){
mst = 1;
}
//Change to the second stage
if(ch>pwm+5){
mst = 2;
}
//Change to third stage
if((ch > pwm-5) && (ch < pwm+5)){
mst = 3;
}
delay(0.000001);
break;
case 1: //Current PWM level less than the actual ALS value
//Compare PWM and ch1 to make a gradual change
count = ch+3;
if (count > 255)
{
count = 255;
}
ch = count;
analogWrite(C1, (ch*ch1));
analogWrite(C2, (ch*ch2));
analogWrite(C3, (ch*ch1));
analogWrite(C4, (ch*ch2));
delay(0.0000001);
//Return to initial state
mst = 0;
break;
case 2: //Current PWM level greater than the actual ALS value
//Compare PWM and ch1 to make a gradual change
count = ch-3;
if (count < 0)
{
count = 0;
}
ch = count;
analogWrite(C1, (ch*ch1));
analogWrite(C2, (ch*ch2));
analogWrite(C3, (ch*ch1));
analogWrite(C4, (ch*ch2));
delay(0.0000001);
//Return to initial state
mst = 0;
break;
case 3: //Current PWM level equal than the actual ALS value
//Keep tha output value
analogWrite(C1, (ch*ch1));
analogWrite(C2, (ch*ch2));
analogWrite(C3, (ch*ch1));
analogWrite(C4, (ch*ch2));
//Return to initial state (Read ALS & Trimmer)
mst = 0;
delay(0.0000001);
break;
default:
//Empty
break;
}
}