#include "stm32f103xb.h"
#include <stdint.h>
void delay_us(uint16_t us);
void delay_ms(uint16_t ms);
void GPIO_Config(void);
void LCD_Init(void);
void LCD_Send(uint8_t value, uint8_t rs);
void LCD_Print(char *str);
void LCD_Clear(void);
void LCD_SetCursor(uint8_t row, uint8_t col);
void mostrar_menu(uint8_t cursor, uint8_t motor_status, uint8_t motor_dir);
void actualizar_salidas(uint8_t motor_status, uint8_t motor_dir);
int main(void)
{
uint8_t cursor = 0;
uint8_t motor_status = 0;
uint8_t motor_dir = 0;
GPIO_Config();
LCD_Init();
mostrar_menu(cursor, motor_status, motor_dir);
actualizar_salidas(motor_status, motor_dir);
while(1)
{
if((GPIOB->IDR & (1 << 0)) == 0)
{
delay_ms(10);
while((GPIOB->IDR & (1 << 0)) == 0);
delay_ms(10);
cursor++;
if(cursor > 1)
cursor = 0;
mostrar_menu(cursor, motor_status, motor_dir);
}
if((GPIOB->IDR & (1 << 1)) == 0)
{
delay_ms(10);
while((GPIOB->IDR & (1 << 1)) == 0);
delay_ms(10);
if(cursor == 0)
{
motor_status = !motor_status;
}
else
{
motor_dir = !motor_dir;
}
actualizar_salidas(motor_status, motor_dir);
mostrar_menu(cursor, motor_status, motor_dir);
}
}
}
void GPIO_Config(void)
{
RCC->APB2ENR |= RCC_APB2ENR_IOPAEN;
RCC->APB2ENR |= RCC_APB2ENR_IOPBEN;
RCC->APB2ENR |= RCC_APB2ENR_AFIOEN;
GPIOA->CRL = 0x22222222;
GPIOA->CRH &= ~(0xFFF);
GPIOA->CRH |= (0x222);
GPIOB->CRL &= ~(0xFF);
GPIOB->CRL |= (0x88);
GPIOB->ODR |= (1 << 0);
GPIOB->ODR |= (1 << 1);
GPIOB->CRH &= ~((0xF << 8) | (0xF << 12));
GPIOB->CRH |= ((0x2 << 8) | (0x2 << 12));
}
void LCD_Init(void)
{
delay_ms(20);
LCD_Send(0x38, 0);
delay_ms(5);
LCD_Send(0x38, 0);
delay_us(150);
LCD_Send(0x38, 0);
delay_us(150);
LCD_Send(0x38, 0);
LCD_Send(0x0C, 0);
LCD_Send(0x06, 0);
LCD_Send(0x01, 0);
delay_ms(2);
}
void LCD_Send(uint8_t value, uint8_t rs)
{
if(rs)
GPIOA->BSRR = (1 << 8);
else
GPIOA->BRR = (1 << 8);
GPIOA->BRR = (1 << 9);
GPIOA->ODR &= ~(0x00FF);
GPIOA->ODR |= value;
GPIOA->BSRR = (1 << 10);
delay_us(2);
GPIOA->BRR = (1 << 10);
delay_us(100);
}
void LCD_Print(char *str)
{
while(*str)
{
LCD_Send(*str, 1);
str++;
}
}
void LCD_Clear(void)
{
LCD_Send(0x01, 0);
delay_ms(2);
}
void LCD_SetCursor(uint8_t row, uint8_t col)
{
uint8_t address;
if(row == 0)
address = 0x80 + col;
else
address = 0xC0 + col;
LCD_Send(address, 0);
}
void mostrar_menu(uint8_t cursor, uint8_t motor_status, uint8_t motor_dir)
{
LCD_Clear();
LCD_SetCursor(0, 0);
if(cursor == 0)
LCD_Print(">");
else
LCD_Print(" ");
LCD_Print("Status:");
if(motor_status)
LCD_Print("Run ");
else
LCD_Print("Stop");
LCD_SetCursor(1, 0);
if(cursor == 1)
LCD_Print(">");
else
LCD_Print(" ");
LCD_Print("Dir:");
if(motor_dir)
LCD_Print("Right");
else
LCD_Print("Left ");
}
void actualizar_salidas(uint8_t motor_status, uint8_t motor_dir)
{
if(motor_status)
GPIOB->BSRR = (1 << 10);
else
GPIOB->BRR = (1 << 10);
if(motor_dir)
GPIOB->BSRR = (1 << 11);
else
GPIOB->BRR = (1 << 11);
}
void delay_us(uint16_t us)
{
volatile uint32_t i;
while(us--)
{
for(i = 0; i < 8; i++);
}
}
void delay_ms(uint16_t ms)
{
volatile uint32_t i;
while(ms--)
{
for(i = 0; i < 2000; i++);
}
}