I am trying to use PWM6 (fed by the counter PWMB) to generate a simple PWM waveform and output it on P5.4.
- P5.4 looks like it's stuck floating. It doesn't do anything.
- PWMB's internal counter is definitely counting, I can see its values printed over the UART.
Things I've tried:
- If I remove the PWMB_ENO line then P5.4 works like a normal output (strong push/pull that I can control by setting its bit in P5).
- P5.4 works fine as an MCLK0 output (beautiful high-freq square waves)
- Reading someone's HAL for this family and following their exact order & pattern of reg writes (they used a descending counter + different PWM comparison mode, but still P5.4 stayed floating at around 2.7V)
- Checking to make sure EAXFR_MAP & UNMAP are working as expected (I can't read PWMB_CNTR in the UART printing code if they're omitted)
Chip: STC8H1K08
(datasheet link). Pin 7 is "MCLK0/RST/PWM6_2/P5.4".
Any ideas?
void main()
{
// Serial comms: UART1 T2
SCON = 0x50; // 8 bit variable baudrate (no parity)
AUXR |= 0b00000001; // clock UART from T2
AUXR |= 0b00000100; // T2 in 1T mode
AUXR |= 0b00010000; // T2 run
T2L = UART1_TIMER_PRELOAD % 256;
T2H = UART1_TIMER_PRELOAD>>8;
ES = 1; // UART1 interrupt enable
// Clock display brightnessPWM: P5.4 PWMB PWM6
EAXFR_MAP;
RSTCFG = 0b01000000; // P5.4: Make it a normal IO pin (disable chip reset functionality)
P5M1 &= 0b11101111; P5M0 |= 0b00010000; // P5.4: strong push-pull
PWMB_CCER1 = 0; // PWM6: Disable (required before writing to CCMR2)
PWMB_CCMR2 = 0b01101000; // PWM6: PWM mode 1 and enable preload of PWMB_CCR6 (smoother PWM level changes)
PWMB_CCER1 = 0b00010000; // PWM6: Enable
PWMB_ENO = 0b00000100; // PWM6: Enable output
PWMB_PS = 0b00000100; // PWM6: Send to pin P5.4
PWMB_PSCR = 1; // PWMB: Clock at 1/(X+1) of system clock
PWMB_CCR6 = 1000; // PWMB: ratio (out of 65536)
PWMB_CR1 |= 0b00000001; // PWMB: enable
PWMB_BKR = 0x10000000; // PWMB: enable (disable brake) <-- might not be needed as brake not enabled?
EAXFR_UNMAP;
EA = 1; // global interrupt enable
while(1)
{
EAXFR_MAP;
uint16_t curtime = ((uint16_t)PWMB_CNTRH << 8) | PWMB_CNTRL;
EAXFR_UNMAP;
uart1_writeStr("Current PWMB_CNTR value: ");
uart1_writeHex16(curtime);
uart1_write('\r');
uart1_write('\n');
}
}