STM32F429 LCD and PWM

so im trying to make a frequency counter with a nucleoSTM32F429zi and i have a few issuse firstly im using a PWM output through a low pass filter to make a sine wave. that works fine however at the end of the project i have to desplay the frequance on an LCD this is where my problems i have an LCD connected properly. but when the PWM is active there is no output to either putty or the LCD i am also unable to send anymore than a single character at a time and i need a string to show the frequancy. please advise me on what is wrong

#include "mbed.h"
#include "LCD.h"
#include <cstdio>
#include <stm32f4xx.h>

//INCLUDE THE HEADER FILE FOR THIS MCU FAMILY
//Define an instance of SPI - this is a SPI master device
SPI spi(PA_7, PA_6, PA_5); // Ordered as: mosi, miso, sclk could use forth parameter ssel

//We often use a separate signal for the chip select. It is VITAL that for each SPI port, only ONE SPI slave device is enabled.
DigitalOut cs(PC_6); // Chip Select for Basic Outputs to illuminate Onboard FPGA DEO nano LEDs CN7 pin 1

// **************************************************************************
// ******************** NB the following line for F429ZI ********************
// * The following line is essential when using this ribbon connector *
// **************************************************************************
DigitalIn DO_NOT_USE(PB_12); // MAKE PB_12 (D19) an INPUT do NOT make an OUTPUT under any circumstances !!!!! ************* !!!!!!!!!!!
// This Pin is connected to the 5VDC from the FPGA card and an INPUT that is 5V Tolerant
// **********************************************************************************************************


// **************************************** Function prototypes *********************************************
uint16_t read_switches(void); //Read 4 Sliding switches on FPGA (Simulating OPTO-Switches from Motor(s)
uint16_t spi_readwrite(uint16_t data);
// **********************************************************************************************************


// **********************************************************************************************************
// Main function
// **********************************************************************************************************
//this file contains the definitions for register addresses and values etc...


int initPWM(void)
{

SystemCoreClockUpdate();
//ENABLE PORT(S)
RCC->AHB1ENR|=RCC_AHB1ENR_GPIOBEN; //GPIO B clock enable

//CONFIGURE PORT PIN FUNCTIONS
GPIOB->MODER&=~(3u<<(2*0)); //clear pin functions on GPIOB
GPIOB->MODER|=(1u<<(2*0)); //set new pin functions on GPIOB

RCC->APB1ENR|=RCC_APB1ENR_TIM2EN; //timer 2 clock enabled
TIM2->DIER|=TIM_DIER_UIE; //timer uptdate interrupt enabled
//APB clock is Fcy/2 = 180MHz/2 = 90MHz
TIM2->PSC=256-1; //divide APB clock by 256 = 90MHz/256 = 351kHz
TIM2->ARR=3287; //counter reload value, gives a timer period of 100ms when F_APB = 90MHz and PSC = 256
TIM2->CNT=0; //zero timer counter
NVIC->ISER[0]|=(1u<<28); //timer 2 global interrupt enabled
TIM2->CR1|=TIM_CR1_CEN; //start timer counter

while(1) //ENTER 'FOREVER' LOOP - THIS LOOP WILL NEVER EXIT
{
//FOREVER LOOP IS NOW EMPTY (MCU CAN BE PUT TO SLEEP HERE)
}//END OF FOREVER LOOP
}//end main
void TIM2_IRQHandler(void) //TIMER 2 INTERRUPT SERVICE ROUTINE
{
TIM2->SR&=~TIM_SR_UIF; //clear interrupt flag in status register

GPIOB->ODR^=(1u<<0); //XOR GPIOB output data register to invert the selected pin
}


void lcd_delayus(unsigned int us) //blocking delay for LCD, argument is approximate number of micro-seconds to delay
{
unsigned char i;
while(us--)
{
for(i=0; i<SystemCoreClock/4000000; i++);
}
}
void WaitLcdBusy(void)
{
lcd_delayus(1); //3ms blocking delay
}
void set_LCD_data(unsigned char d)
{
LCD_PORT->BSRR=(0xff<<(LCD_D0_pin+16)); //clear data lines
LCD_PORT->BSRR=(d<<LCD_D0_pin); //put data on lines
}

void LCD_strobe(void) //10us high pulse on LCD enable line
{
lcd_delayus(10);
set_LCD_E();
lcd_delayus(10);
clr_LCD_E();
}


void cmdLCD(unsigned char cmd) //sends a byte to the LCD control register
{
WaitLcdBusy(); //wait for LCD to be not busy
clr_LCD_RS(); //control command
clr_LCD_RW(); //write command
set_LCD_data(cmd); //set data on bus
LCD_strobe(); //apply command
}

void putLCD(unsigned char put) //sends a char to the LCD display
{
WaitLcdBusy(); //wait for LCD to be not busy
set_LCD_RS(); //text command
clr_LCD_RW(); //write command
set_LCD_data(put); //set data on bus
LCD_strobe(); //apply command
}

void initLCD(void)
{
SystemCoreClockUpdate();
RCC->AHB1ENR|=RCC_AHB1ENR_GPIOBEN; //enable LCD port clock


//CONFIG LCD GPIO PINS
LCD_PORT->MODER&=~( //clear pin direction settings
(3u<<(2*LCD_RS_pin))
|(3u<<(2*LCD_RW_pin))
|(3u<<(2*LCD_E_pin))
|(0xffff<<(2*LCD_D0_pin))
);


LCD_PORT->MODER|=( //reset pin direction settings to digital outputs
(1u<<(2*LCD_RS_pin))
|(1u<<(2*LCD_RW_pin))
|(1u<<(2*LCD_E_pin))
|(0x5555<<(2*LCD_D0_pin))
);


//LCD INIT COMMANDS
clr_LCD_RS(); //all lines default low
clr_LCD_RW();
clr_LCD_E();

lcd_delayus(25000); //25ms startup delay
cmdLCD(0x38); //Function set: 2 Line, 8-bit, 5x7 dots
cmdLCD(0x0c); //Display on, Cursor blinking command
cmdLCD(0x01); //Clear LCD
cmdLCD(0x06); //Entry mode, auto increment with no shift
}

void LCDdelay (int time);

int send_to = LCD;

unsigned short SPIout;


void send_LCD(float Q){

cmdLCD(LCD_LINE1);
send_to = LCD;
printf("Volts: %.3fV\n\n", Q);

}

float MISO(PA_6);

int main(){

cs = 1; // Chip must be deselected, Chip Select is active LOW
spi.format(16,0); // Setup the DATA frame SPI for 16 bit wide word, Clock Polarity 0 and Clock Phase 0 (0)
spi.frequency(1000000); // 1MHz clock rate
initLCD();
initPWM();

while(1){ // start infinate loop

float Volts;
SPIout = MISO;
Volts = SPIout*3.3f/4095.0f;
//UART_Display(Volts);
send_LCD(Volts);
int d, c;
for (c = 1; c <= 1000; c++)
for (d = 1; d <= 1000; d++)
{}
LCD_CLR();
}


while(true) //Loop forever Knight Rider Display on FPGA
{
//Read switch state and write to PuTTY
read_switches();

//LED Chaser display KIT lives on!
for (uint32_t i=1;i<=128;i*=2) {
spi_readwrite(i);
wait_ms(20);
}
for (uint32_t i=128;i>=1;i/=2) {
spi_readwrite(i);
wait_ms(20);
}

//Wait for 1 second
wait_ms(1000);

}
}
// **********************************************************************************************************
// Function to read back the state of the switches
//
// uint16_t read_switches(void)
// Return data - the data returned from the FPGA to the MCU over the SPI interface (via MISO)
// **********************************************************************************************************

uint16_t read_switches(void){
uint16_t sw_val = spi_readwrite(0); //Turn off all LEDs + read switches (in one full-duplex transaction)

if (sw_val&(1<<0)){ printf("Switch 0 :"); }
if (sw_val&(1<<1)){ printf("Switch 1 :"); }
if (sw_val&(1<<2)){ printf("Switch 2 :"); }
if (sw_val&(1<<3)){ printf("Switch 3 :"); }
if (sw_val>0) { printf("\r\n"); }
return sw_val;
}


// **********************************************************************************************************
// uint16_t spi_readwrite(uint16_t data)
//
// Function for writing to the SPI with the correct timing
// data - this parameter is the data to be sent from the MCU to the FPGA over the SPI interface (via MOSI)
// return data - the data returned from the FPGA to the MCU over the SPI interface (via MISO)
// **********************************************************************************************************

uint16_t spi_readwrite(uint16_t data) {
cs = 0; //Select the device by seting chip select LOW
uint16_t rx = (uint16_t)spi.write(data); //Send the data - ignore the return data
wait_us(1); //wait for last clock cycle to clear
cs = 1; //De-Select the device by seting chip select HIGH
return rx;
}

  • Isn't there a code formatting tool? How will it leave initPWM()?

    Software delays might need to use volatile variables so they aren't optimized away.

    Might have to debug your own software/hardware, got a unique mix here.

    Get a scope, check the signalling to the display vs expectations.

    Use the debugger, step your code, understand what it is doing, and not doing.

More questions in this forum