Hi all, i know it does sound Weird that I am asking a help with this but i surely know that we just don't use AVRs. so here we go.
Anyone to please have a look at the below code conversion and give me a hint as to why it isn't quite working well?
i made the code so simple & is written a C :D
The problem is that i can't get the LCD f(x)s (i wrote about a year ago originally for Atmega32) to work on Cortex M4. (Stm32f407VG)
I made some necessary changes to suit CM4 but it still doesn't Display anything. these changes were somethings like assigning a "char" to a GPIO. for AVR each Port is 8 bits so assigning a character is straightforward But since GPIOs on ARM are 32 i tried to do some masking to still suit D0 to D7 out of D0 to D31 although i think it wasn't much necessarily needed masking anyway.
i virtually spent overnight looking for a bug but i don't seem to find it. i first though it was my LCD which suddenly broke but when plugged to Atmega32, it was displaying quite well.
Below are the code for Both Parties I would very much appreciated if anyone who is familiar with ARM doesn't mind having a look and give me a hint as to where the error might be.
Many Thanks.
AVR CODE
#include"¨ #include "¨ #include #define Enable 5"¨ #define RW 7"¨ #define RS 2 void Init_LCD(void); void Set_LCD_up(void);"¨ void Check_if_LCD_is_Busy(void);"¨ void Command_LCD(unsigned char command);"¨ void Send_a_Character(unsigned char character); "¨void Print_on_LCD(char *string_of_chars);"¨ void Goto_LCD_Pos(uint8_t X , uint16_t Y); "¨void Print_on_LCD_with_Pos(uint8_t X, uint16_t Y, char *String_Of_Chars); int LCD_Line_Pos[2] = {0,64} ; int main(void) { DDRA = 0b11111111; // This is where D0 to D7 are connected"¨ PORTA= 0b00000000;"¨"¨ TCCR1B |= 1<<CS10 | 1<<CS11; // Timer1_B prescaling Init_LCD(); while(1)"¨ { "¨"¨Print_on_LCD_with_Pos(7,1,"Hello World"); // On 1st Line 7th Position "¨ } } void Init_LCD() { "¨"¨DDRD|= (1<<Enable | 1<<RW | 1<<RS); // These are connected to Port D _delay_ms(15);"¨ Command_LCD(0x01); //Clear Screen by 0x01 "¨ _delay_ms(2);"¨ Command_LCD(0x38);"¨ _delay_us(50); "¨ Command_LCD(0x0F);"¨ _delay_us(50);"¨"¨ } void Check_if_LCD_is_Busy() { "¨DDRB = 0x00; "¨PORTD |= 1<<RW; "¨PORTD &= ~1<<RS; while(PORTB >= 0x80)"¨ { "¨Set_LCD_up();"¨ } "¨DDRB = 0xFF;"¨ } "¨ void Set_LCD_up() { "¨ PORTD |= 1<<Enable;"¨ asm volatile ("nop");"¨ asm volatile ("nop");"¨ PORTD &= ~ 1<<Enable;"¨ } "¨ void Command_LCD(unsigned char command) { "¨Check_if_LCD_is_Busy();"¨ PORTB = command;"¨ PORTD &= ~ ((1<<RW) | (1<<RS));"¨ Set_LCD_up();"¨PORTB = 0x00; "¨ } "¨void Send_a_Character(unsigned char character) { "¨Check_if_LCD_is_Busy();"¨ PORTB = character; "¨PORTD &= ~ (1<<RW);"¨PORTD|= 1<<RS;"¨ Set_LCD_up();"¨PORTB = 0x00;"¨ } "¨void Print_on_LCD(char *String_Of_Chars) { "¨while(*String_Of_Chars > 0)"¨ { "¨ Send_a_Character(*String_Of_Chars++);"¨ } "¨} "¨ void Goto_LCD_Pos(uint8_t X , uint16_t Y) "¨"¨{ "¨Command_LCD(0x80 + (X-1) + LCD_Line_Pos[Y-1]); "¨} "¨void Print_on_LCD_with_Pos(uint8_t X, uint16_t Y, char *String_Of_Chars) {"¨ Command_LCD(0x80 + (X-1) + LCD_Line_Pos[Y-1]); "¨"¨ while(*String_Of_Chars > 0)"¨ { "¨ Send_a_Character(*String_Of_Chars++); "¨} }
STM32F407 CODE.
Using Coocox IDE.
#include#include #include #include #include "stm32f4xx.h" #include "stm32f4xx_rcc.h" #include "stm32f4xx_tim.h" #include "stm32f4xx_gpio.h" #include "core_cm4.h"   #define RS GPIO_Pin_0 #define RW GPIO_Pin_1 #define Enable GPIO_Pin_2 // All RS, RW & Enable are @ PortB #define LCD_D0 GPIO_Pin_0 // Lower nibble @ PortA D0 - D3 #define LCD_D1 GPIO_Pin_1 #define LCD_D2 GPIO_Pin_2 #define LCD_D3 GPIO_Pin_3 #define LCD_D4 GPIO_Pin_4 // Higher nibble @ PortA D4 to D7 #define LCD_D5 GPIO_Pin_5 #define LCD_D6 GPIO_Pin_6 #define LCD_D7 GPIO_Pin_7 //Exactly same f(x)s as Atmega32's void Init_LCD(void); void Set_LCD_up(void); void Check_if_LCD_is_Busy(void); void Command_LCD(unsigned char command); void Send_a_Character(unsigned char character); void Print_on_LCD(char *string_of_chars); void Goto_LCD_Pos(uint8_t X , uint16_t Y); void Print_on_LCD_with_Pos(uint8_t X, uint16_t Y, char *String_Of_Chars); void _delay_ms(volatile uint32_t ms); void _delay_us(volatile uint32_t us); int LCD_Line_Pos[2] = {0,64} ;   int main(void) { SystemInit(); // Running @ 84Mhz on Timers 1,2,3... GPIO_InitTypeDef GPIO_InitStructure; // Setting GPIOs & Timers Reset Clocks // All D0 - D7 are made as Output @ 50Mhz RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOA | RCC_AHB1Periph_GPIOB, ENABLE); RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM6, ENABLE); GPIO_InitStructure.GPIO_Pin = (LCD_D0 | LCD_D1 | LCD_D2 | LCD_D3 | LCD_D4 |LCD_D5| LCD_D6 | LCD_D7); GPIO_InitStructure.GPIO_Mode = GPIO_Mode_OUT; GPIO_InitStructure.GPIO_OType = GPIO_OType_PP; GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL; GPIO_Init(GPIOA, &GPIO_InitStructure); GPIO_InitStructure.GPIO_Pin = (RS | RW | Enable); GPIO_InitStructure.GPIO_Mode = GPIO_Mode_OUT; GPIO_InitStructure.GPIO_OType = GPIO_OType_PP; GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL; GPIO_Init(GPIOB, &GPIO_InitStructure);   Init_LCD(); while(1) { Print_on_LCD_with_Pos(7,1,"Hello World"); } } // Both "_delay_us()" and "_delay_ms()" timers tested and work well void _delay_us(volatile uint32_t us) { TIM6->PSC = 83; // PSC-1 TIM6->ARR = (us -1); ARR -1 too TIM6->CNT = 0; // Start from 0 just like TCNT(XY) in CTC mode TIM6->EGR |= TIM_EGR_UG; // Update Event Flag upon a match of CNT with ARR // just like TIFR(XY) with OCR(XY) TIM6->SR &= ~ TIM_SR_UIF; // Clear it since no ISR // or NVIC is needed in this case TIM6->CR1 |= (TIM_CR1_OPM | TIM_CR1_CEN); while(!(TIM6->SR &TIM_SR_UIF)); } void _delay_ms(volatile uint32_t ms) { while(-- ms >0) // Call _Delay_us() 1000 times { _delay_us(1000); } } void Init_LCD() { GPIOB->ODR = (1<<Enable | 1<<RW | 1<<RS); _delay_ms(15); Command_LCD(0x01); //Clear Screen 0x01 = 00000001 _delay_ms(2); Command_LCD(0x38); _delay_us(50); Command_LCD(0x0F); _delay_us(50); }   void Check_if_LCD_is_Busy() { GPIOA->MODER = 0xA8000000; // set up the whole GPIOA as input mode @ 10 Mhz. GPIOA->OSPEEDR = 0xaaaaaaaa; //50Mhz GPIOA->OTYPER = 0x00; GPIOA->PUPDR = 0x00; GPIOB->ODR |= (1<<RW); // Set RW GPIOB->ODR &= ~ (1<<RS); // Clear RS while((GPIOA->IDR & 0xFF) >= 0x80) // only lower 16 bits are read! { Set_LCD_up(); } GPIOA->MODER = 0x55555555; //set the whole GPIOA as output mode Push Pull GPIOA->OSPEEDR = 0xaaaaaaaa; GPIOA->OTYPER = 0x00; GPIOA->PUPDR = 0x00; } void Set_LCD_up() { GPIOB->ODR |= (1<<Enable); asm volatile ("NOP"); asm volatile ("NOP"); GPIOB->ODR &= ~ (1<<Enable); }   void Command_LCD(unsigned char command) { Check_if_LCD_is_Busy(); GPIO_WriteBit(GPIOA, LCD_D0, ((command>>0) & 0x01)); GPIO_WriteBit(GPIOA, LCD_D1, ((command>>1) & 0x01)); GPIO_WriteBit(GPIOA, LCD_D2, ((command>>2) & 0x01)); GPIO_WriteBit(GPIOA, LCD_D3, ((command>>3) & 0x01)); GPIO_WriteBit(GPIOA, LCD_D4, ((command>>4) & 0x01)); GPIO_WriteBit(GPIOA, LCD_D5, ((command>>5) & 0x01)); GPIO_WriteBit(GPIOA, LCD_D6, ((command>>6) & 0x01)); GPIO_WriteBit(GPIOA, LCD_D7, ((command>>7) & 0x01)); GPIOB->ODR &= ~ ((1<<RW) | (1<<RS)); Set_LCD_up(); GPIOA->ODR = 0x0000; }   void Send_a_Character(unsigned char character) { Check_if_LCD_is_Busy(); GPIO_WriteBit(GPIOA, LCD_D0, ((character>>0) & 0x01)); GPIO_WriteBit(GPIOA, LCD_D0, ((character>>1) & 0x01)); GPIO_WriteBit(GPIOA, LCD_D0, ((character>>2) & 0x01)); GPIO_WriteBit(GPIOA, LCD_D0, ((character>>3) & 0x01)); GPIO_WriteBit(GPIOA, LCD_D0, ((character>>4) & 0x01)); GPIO_WriteBit(GPIOA, LCD_D0, ((character>>5) & 0x01)); GPIO_WriteBit(GPIOA, LCD_D0, ((character>>6) & 0x01)); GPIO_WriteBit(GPIOA, LCD_D0, ((character>>7) & 0x01)); GPIOB->ODR &= ~ (1<<RW); GPIOB->ODR |= (1<<RS); Set_LCD_up(); GPIOA->ODR = 0x0000; } void Print_on_LCD(char *String_Of_Chars) { while(*String_Of_Chars > 0) { Send_a_Character(*String_Of_Chars++); } }   void Goto_LCD_Pos(uint8_t X , uint16_t Y) { Command_LCD(0x80 + (X-1) + LCD_Line_Pos[Y-1]); }   void Print_on_LCD_with_Pos(uint8_t X, uint16_t Y, char *String_Of_Chars) { Command_LCD(0x80 + (X-1) + LCD_Line_Pos[Y-1]); while(*String_Of_Chars > 0) { Send_a_Character(*String_Of_Chars++); } }
/* Other than manipulating GPIOs and timer the rest of Syntax are pretty much the same. */
Many Thanks Again
Regards.