#include "stm32f10x.h"
void delay (unsigned int psc,unsigned int arr);
void lcd_init (void);
void conversion_numeros_lcd (volatile unsigned int numero);
void lcd_clr (void);
void escribir_lcd (volatile unsigned char letra);
void print_lcd (volatile char abc[]);
void print_num_lcd (volatile unsigned int abc[]);
void ADC1_2_IRQHandler (void);
	
static volatile int dly=0,temp=0;
static volatile float temperatura=0.00;

int main (void)
{
	
	
	RCC->APB2ENR|=RCC_APB2ENR_IOPAEN;			//ver stm3210x.h Habilito reloj del PA
	RCC->APB2ENR|=RCC_APB2ENR_ADC1EN;			//ver stm3210x.h Habilito reloj del ADC1
	RCC->CFGR |= RCC_CFGR_ADCPRE_DIV6; 			//divide el adc del preescaler para asegurar que no pase de 14MHz
	RCC->APB1ENR|=RCC_APB1ENR_TIM3EN;			//ver stm3210x.h Habilito reloj del timer 3
	RCC->APB1ENR|=RCC_APB1ENR_TIM2EN;			//ver stm3210x.h Habilito reloj del timer 2
	
	GPIOA->CRL = 0x42222220;									
	lcd_init ();																													
	lcd_clr ();
	
	/*confuguracion del Timer2*/
	//====================================//
	TIM2->CR1|=0x1;																												
	TIM2->CNT=0;																													
	TIM2->PSC=60000;																												
	TIM2->ARR=2400;																												
	
	//====================================//
	/*confuguracion del ADC1*/
	//====================================//
	ADC1->SMPR2|= ADC_SMPR2_SMP0;
	ADC1->CR2 |= ADC_CR2_ADON | ADC_CR2_CONT;
	for(dly = 0; dly < 6000; dly++);
	ADC1->CR2 |= ADC_CR2_ADON;
	for(dly = 0; dly < 6000; dly++);
	ADC1->CR2 |= ADC_CR2_CAL;
	for(dly = 0; dly < 6000; dly++);
	ADC1->SQR3 = 0x0;
	for(dly = 0; dly < 6000; dly++);
	
	//====================================//
	/*confuguracion interrupcion del TIM2*/
	//====================================//
	TIM2->DIER|=0x01;																											
	NVIC_EnableIRQ(TIM2_IRQn);																						
	
	//====================================//
	/*confuguracion interrupcion del ADC1*/
	//====================================//
	ADC1->CR1 |= ADC_CR1_EOCIE;																					
	NVIC_EnableIRQ(ADC1_2_IRQn);																					
	
	
	/*
		Los bits 1-6 del puerto A es donde se conecta la lcd
			*PA3 D4
			*PA4 D5
			*PA5 D6
			*PA6 D7
			*PA1 RS
			*PA2 ENABLE
		El bit 0 del PA es el ADC ADC12_IN0
		Se asume que el reloj del APB1 esta a 72Mhz
	*/
	while (1)
	{

	}
}

void ADC1_2_IRQHandler (void)
{
	if ((ADC1->SR & ADC_SR_EOC)==0x02)													
	{
	temperatura=((ADC1->DR)/4095.0)*330;									//ecuacion que traduce el valor del adc a un parametro de temp
	}
}

void TIM2_IRQHandler (void)
{
	lcd_clr();
	temp=temperatura*10;																		
	conversion_numeros_lcd (((temp%1000)-(temp%100))/100);	
	conversion_numeros_lcd (((temp%100)-(temp%10))/10);			
	escribir_lcd('.');																			
	conversion_numeros_lcd (temp%10);												
	print_lcd ("'C");
	TIM2->SR &= ~TIM_SR_UIF;															
}

void delay (unsigned int psc,unsigned int arr)
{
TIM3->CR1|=0x08;											
TIM3->PSC=psc;											
TIM3->ARR=arr;
TIM3->CNT=0;
TIM3->CR1|=0x01;
volatile int done=0;
	
	while (done!=1)
	{  	
	if ((TIM3->SR & 0x0001)>0)
		{
			TIM3->SR &= ~TIM3->SR;
			done=1;
		}
	}
}

void lcd_init (void)
{
	/*
		Enable es activo bajo
	*/
	GPIOA->ODR=0b001010<<1; 
	GPIOA->ODR&=0b111101<<1; 
	for(dly = 0; dly < 50000; dly++); 
	GPIOA->ODR=0b001010<<1; 
	GPIOA->ODR&=0b111101<<1;
	for(dly = 0; dly < 50000; dly++); 
	GPIOA->ODR=0b100010<<1;
	GPIOA->ODR&=0b111101<<1;
	for(dly = 0; dly < 50000; dly++); 
	GPIOA->ODR=0b000010<<1;
	GPIOA->ODR&=0b111101<<1;
	for(dly = 0; dly < 50000; dly++); 
	GPIOA->ODR=0b111110<<1;
	GPIOA->ODR&=0b111101<<1;
	for(dly = 0; dly < 50000; dly++); 
}

void lcd_clr (void)
{
	GPIOA->ODR = 0b000010<<1;
	GPIOA->ODR&=0b111101<<1;
	for(dly = 0; dly < 50000; dly++); 
	GPIOA->ODR = 0b000110<<1;
	GPIOA->ODR&=0b111101<<1;
	for(dly = 0; dly < 50000; dly++); 
}

void conversion_numeros_lcd (volatile unsigned int numero)
{
	GPIOA->ODR = 0b001111<<1;											
	GPIOA->ODR&=0b111101<<1;											
	for(dly = 0; dly < 50000; dly++); 														
	numero=numero<<2;
	GPIOA->ODR =(0b000011|numero)<<1;							
	GPIOA->ODR&=0b111101<<1;											
	for(dly = 0; dly < 50000; dly++); 														
}

void print_num_lcd (volatile unsigned int abc[])
{
	unsigned int short j;           							
	for (j=0;abc[j]!=0;j++)												
	{
		conversion_numeros_lcd (abc[j]);						
	}
}

void escribir_lcd (volatile unsigned char letra)
{
	GPIOA->ODR = (letra>>2|0x3)<<1;									
	GPIOA->ODR&=0b111101<<1;														
	for(dly = 0; dly < 50000; dly++);														
	GPIOA->ODR = ((letra<<2)|0x3)<<1;										
	GPIOA->ODR&=0b111101<<1;														
	for(dly = 0; dly < 50000; dly++);														
}

void print_lcd (volatile char abc[])
{
	unsigned int short j;           						
	for (j=0;abc[j]!='\0';j++)									
	{
		escribir_lcd (abc[j]);										
	}
}
