我正在使用 PIC18F47-Q18 Curiosity HPC 开发板和 MPLAB X IDE v6.20。
目标是将模拟输出的 10 位值存储到 8 位 PWM 中。取决于模拟对齐的合理性。 ADRESL 保存数据的前 8 位(2^0 到 2^8),ADRESH 保存位 0 和位 1 中的最后两位(2^9 和 2^10)。通过做
PWM4DCH = ADRESL;
。当我转动电位器时,LED 会变亮。然而,在某个点之后,PWM 周期会重新启动,并且 LED 在再次变亮之前会关闭。如此重复 4 次。我相信这是因为我使用的微控制器是 Fosc/4。最终目标是顺时针旋转电位器时使LED达到最大亮度。
我粘贴了下面的代码,并提供了尽可能多的细节和信息。此外,我目前使用轮询,但当我了解它们如何工作时,我将使用中断标志重新创建它。
// CONFIG1L
#pragma config FEXTOSC = OFF
#pragma config RSTOSC = HFINTOSC_64MHZ
// CONFIG1H
#pragma config CLKOUTEN = OFF
#pragma config CSWEN = OFF
#pragma config FCMEN = OFF
// CONFIG3L
#pragma config WDTCPS = WDTCPS_31
#pragma config WDTE = OFF
#define clock OSCCON1 // define the timer control bits
#define freq OSCFRQ
#define enable_timer T2CONbits.T2ON // define the timer control bits
#define interrupt_enable PIE4bits.TMR2IE
#define PB1 PORTBbits.RB4
#define PB2 PORTCbits.RC5
#define light PORTAbits.RA7
void main(void) {
clock = 0x60; // use High Mhz clock
freq = 0x03; // Use 8Mhz clock
T2CLKCON = 0x01; // Make Timer2 Fosc/4
ANSELA = 0x01; // set up port A,B,C D/A
TRISA = 0x01; // set up port A,B,C I/O
ANSELB = 0x00;
TRISB = 0xFF;
ANSELC = 0x00;
TRISC = 0xFF;
T2PR = 0xC7; // period of the PWM
PWM4DCH = 0x95; // set up duty cycle of PWM
PWM4DCL = 0x10; // set up duty cycle of PWM
RA4PPS = 0x08; // set RA4 to be PWM output
T2CON = 0x20; // set pre scale value of 1:4
PWM4CONbits.PWM4EN = 1; // enable the PWM
PWM4CONbits.POL = 1; // reverse Polarity of PWM
while (1)
{
enable_timer=1; // enable the timer 2
while(PIR4bits.TMR2IF==0); // Monitor that the interrupt flag is zero
enable_timer=0; // disable the timer
PIR4bits.TMR2IF=0; // clear the interrupt flag
ADCON0 = 0x84; // ADC is enabled and ADFM is right justified
ADPCH = 0x00; // Selected channel is RA0
ADCON0bits.GO =1; // start ADC conversion
while (ADCON0bits.GO ==0); // using polling method to wait until GO bit is 0
PWM4DCH = ADRESL; // display ADRESL results on PWM4DCH
ADCON0bits.ADON = 0; // Turn off ADC enable bit
}
return;
}
我尝试将 ADRESL 和 ADRESH 设置为整数 x 和 y,然后再将它们相加并输出到 PWM:
int x;
int y;
int z;
x = ADRESL;
y = ADRESH << 8;
z = (ADRESH << 8 | ADRESL);
PWM4DCH = z;
使用电位器时LED不会做任何事情。
我尝试做上面同样的事情,但是直接进入PWM4DCH:
PWM4DCH = (ADRESH<<8 | ADRESL);
与上面相同的问题。
要将 10 位 ADC 值缩放为 8 位 PWM:
使用公式:
PWM4DCH = (ADRESH << 6) | (ADRESL >> 2);
ADRESH << 6
:将 ADRESH
的 2 个 MSB 与 8 位值的前 2 位对齐。ADRESL >> 2
:保留ADRESL
的高6位,同时丢弃低2位。|
组合形成 8 位缩放结果。您提到的警告是由于从较大的整数类型隐式转换为 8 位无符号类型所致。显式强制转换以避免这种情况:
PWM4DCH = (unsigned char)((ADRESH << 6) | (ADRESL >> 2));