2017-10-14 21 views
0

나는 내 코드에서 꽤 바보 같은 실수라고 생각하는 것을 찾기가 어렵다. ATmega328을 사용하고 있습니다.PWM 듀티 사이클 값의 범위를 제한하는 방법은 무엇입니까?

내가 필요한 것은 듀티 사이클이 0 %에서 100 % 사이가 아니라 다른 두 값 사이에서 변화하는 PWM 신호를 생성하는 것입니다. 이는 매크로를 duty_maxduty_min으로 설정하여 고려됩니다. 내가 내 코드에서 일을하고있어 1024 개 값의 해상도를 가진 ADC를, 읽기, 허용되는 값의 범위에 읽은 값에 매핑된다

#define duty_max 239 
#define duty_min 50 

[...] 

//Reading the ADC 
ADMUX = 0b01000101; 
ADCSRA |= (1<<ADSC); 
while(!(ADCSRA & (1<<ADIF))); 
ADCSRA |= (1<<ADIF); 
//Setting the variable 'duty' to the value read by the ADC 
cli(); 
duty = ADC; 
sei(); 
//Mapping to the range of accepted values 
duty = round((duty*(duty_max-duty_min))/1023 + duty_min); 

//Generating the PWM signal 
OCR0B = duty; 
//Timer 0 
TCCR0A = 0b00100011; 
TCCR0B = 0b00000001; 

나는 데 문제은 신호이다 그것이해야대로 작동하지 않습니다. 0에서 1023 사이의 ADC 판독 값을 스윕하고 오실로스코프로 출력 신호를 측정 할 때, 신호는 최소 듀티 사이클에서 최대 값으로 상승하고 싶습니다. 그러나 0에서 40 % (대략) 4 시간이 소요됩니다. 즉, ADC 값이 증가하면 일정 시간에 듀티 사이클이 증가하는 것을 멈추고 0으로 돌아가고 0으로 돌아갈 때까지 계속 증가합니다. 전체 ADC 범위 내에서 4 번.

매핑 공식을 duty = round(duty/4);으로 바꾸면 문제가 없지만 듀티 사이클은 0 %에서 100 %까지이므로 허용 범위를 벗어납니다.

왜 이런 일이 발생합니까? 실수는 매핑 공식에 나와 있어야하지만 찾을 수는 없으며 이미 잠시 동안 이미 처리해 왔습니다.

+0

'의무'유형은 무엇입니까? – flaviodesousa

+0

@flaviodesousa 그것은'unsigned int'입니다. – Tendero

+0

"광범위한 토론"의견은 귀하의 이전 질문과 관련이 있습니다. 실제로 도움이되지 않는 질문에 대해서는 어떤 대답도 수락하지 마십시오. 더 많은 의견을 얻으려면 질문에 현상금을 사용하십시오. –

답변

0

거의 16 비트

(duty*(duty_max-duty_min))/1023 

결과 듀티가 347 일 때, 출력 값 (최대 값의 약 47 % 임) (114)로부터 방울을 절단함으로써 증상을 복제 수 있었다 최소 듀티 사이클 인 50으로 설정하십시오. 이 경우 이 세 번 발생하고 입력 범위 (네 가지가 아님)에 대해 비트이 발생합니다.

, 당신이 경우에, 시도하고 있습니다이를 방지 공약수로 두 숫자를 분할하려면 듀티 차이, 189, 3으로 나누어, 그래서 1023

duty = round((duty*63)/341) + duty_min; 
로 작성하는 시도이다

이 변경되는지 확인하십시오.