0
大家好,

我是 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;
}
}
4

0 回答 0