Suwmiarka/Soft/Suwmiarka/caliper.c

228 lines
5.6 KiB
C

#include "caliper.h"
#include "systick.h"
#include "hardware.h"
#include "stm32f10x.h"
#include <stdint.h>
//------------------------zmienne prywatne-------------------------//
uint32_t Caliper_Timestamp;
int32_t Caliper_AbsValue,Caliper_RelValue;
uint8_t Caliper_State,Caliper_ISR_State;
EXTI_TypeDef *EXTI_Regs=EXTI_BASE;
//------------------------zmienne zewnętrzne-------------------------//
extern __IO uint32_t Tick;
//-----------------------------Funkcje------------------------------//
void Caliper_Initialize(void)
{
GPIO_InitTypeDef GPIO_Conf;
EXTI_InitTypeDef EXTI_Conf;
NVIC_InitTypeDef NVIC_Conf;
//włącz zegar GPIOA,EXTI
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA|RCC_APB2Periph_AFIO, ENABLE);
//CLK,DATA - wejście
GPIO_Conf.GPIO_Pin=CLK|DATA;
GPIO_Conf.GPIO_Mode=GPIO_Mode_IN_FLOATING;
GPIO_Conf.GPIO_Speed=GPIO_Speed_50MHz;
GPIO_Init(GPIOA,&GPIO_Conf);
//przerwanie na narastającym zboczu CLK
GPIO_EXTILineConfig(GPIO_PortSourceGPIOA,5);
EXTI_ClearITPendingBit(CLK);
EXTI_Conf.EXTI_Line = CLK;
EXTI_Conf.EXTI_Mode = EXTI_Mode_Interrupt;
EXTI_Conf.EXTI_Trigger = EXTI_Trigger_Falling;
EXTI_Conf.EXTI_LineCmd = ENABLE;
EXTI_Init(&EXTI_Conf);
NVIC_Conf.NVIC_IRQChannel = EXTI9_5_IRQn;
NVIC_Conf.NVIC_IRQChannelPreemptionPriority = 10; //priorytet 10 , wyżej niż USB (tam jest 11 i 12)
NVIC_Conf.NVIC_IRQChannelSubPriority = 0;
NVIC_Conf.NVIC_IRQChannelCmd = ENABLE;
NVIC_Init(&NVIC_Conf);
// Inicjalizuj zmienne
Caliper_State=0;
Caliper_ISR_State=0;
Caliper_AbsValue=0;
Caliper_RelValue=0;
Caliper_Timestamp=0;
}
uint32_t Caliper_GetAbsVal (void)
{
return Caliper_AbsValue;
}
uint32_t Caliper_GetRelVal (void)
{
return Caliper_RelValue;
}
uint8_t Caliper_GetState (void)
{
//jezeli suwmiarka nie nadawała przez 500ms - jest odłączona
if(Tick-Caliper_Timestamp>CALIPER_MEAS_TIMEOUT)
Caliper_State &= !CALIPER_CONNECTED;
//zwróć stan suwmiarki
return Caliper_State;
}
int8_t Caliper_ISRWait(uint32_t Pin,uint8_t Value)
{
uint32_t tmp,timestamp;
timestamp=Tick;
while(1)
{
tmp=PIO_Read(GPIOA)&Pin;
if(tmp && Value)
return NO_ERROR;
if ( !tmp && !Value)
return NO_ERROR;
if(Tick-timestamp>CALIPER_ISR_TIMEOUT)
return TIMEOUT;
}
}
void EXTI9_5_IRQHandler(void)
{
uint8_t BitCntr,Caliper_ISRState;
int32_t Caliper_AbsValueTmp,Caliper_RelValueTmp;
GPIO_SetBits(GPIOA,LED2);
Caliper_ISRState=CALIPER_START;
Caliper_AbsValueTmp=0;
Caliper_RelValueTmp=0;
while(1)
{
switch(Caliper_ISRState)
{
//bit startu
case CALIPER_START:
//czekaj na narastające zbocze CLK
if(Caliper_ISRWait(CLK,1)==TIMEOUT)
{
Caliper_ISRState=CALIPER_TIMEOUT;
break;
}
GPIO_ResetBits(GPIOA,LED2);
//przejdź do odczytu bezwzględnego położenia swumiarki
BitCntr=0;
Caliper_ISRState=CALIPER_ABS_DATA;
break;
//bezwzględne położenie swumiarki
case CALIPER_ABS_DATA:
//czekaj na narastające zbocze CLK
if(Caliper_ISRWait(CLK,0)==TIMEOUT)
{
Caliper_ISRState=CALIPER_TIMEOUT;
break;
}
if(Caliper_ISRWait(CLK,1)==TIMEOUT)
{
Caliper_ISRState=CALIPER_TIMEOUT;
break;
}
//zapisz kolejny bit
GPIO_SetBits(GPIOA,LED2);
if(PIO_Read(GPIOA)&DATA)
Caliper_AbsValueTmp |= (1<<BitCntr);
GPIO_ResetBits(GPIOA,LED2);
//zwiększ licznik bitów
BitCntr++;
if(BitCntr>=23)
Caliper_ISRState=CALIPER_MIDDLE;
break;
//bit środkowy
case CALIPER_MIDDLE:
//czekaj na narastające zbocze CLK
if(Caliper_ISRWait(CLK,0)==TIMEOUT)
{
Caliper_ISRState=CALIPER_TIMEOUT;
break;
}
if(Caliper_ISRWait(CLK,1)==TIMEOUT)
{
Caliper_ISRState=CALIPER_TIMEOUT;
break;
}
//przejdź do odczytu względnego położenia swumiarki
BitCntr=0;
Caliper_ISRState=CALIPER_REL_DATA;
break;
case CALIPER_REL_DATA:
//czekaj na narastające zbocze CLK
if(Caliper_ISRWait(CLK,0)==TIMEOUT)
{
Caliper_ISRState=CALIPER_TIMEOUT;
break;
}
if(Caliper_ISRWait(CLK,1)==TIMEOUT)
{
Caliper_ISRState=CALIPER_TIMEOUT;
break;
}
//zapisz kolejny bit
if(PIO_Read(GPIOA)&DATA)
Caliper_RelValueTmp |= (1<<BitCntr);
//zwiększ licznik bitów
BitCntr++;
if(BitCntr>=23)
Caliper_ISRState=CALIPER_END;
break;
case CALIPER_END:
//czekaj na opadające zbocze CLK
if(Caliper_ISRWait(CLK,0)==TIMEOUT)
{
Caliper_ISRState=CALIPER_TIMEOUT;
break;
}
if(Caliper_ISRWait(CLK,1)==TIMEOUT)
{
Caliper_ISRState=CALIPER_TIMEOUT;
break;
}
//dane odebrane
//konwertuj na liczby ze znakiem (uzupełnij najstarsze bity znakiem) i zapisz
Caliper_AbsValue=(Caliper_AbsValueTmp<<9)>>9;
Caliper_RelValue=(Caliper_RelValueTmp<<9)>>9;
//oznacz żę suwmiarka jets podłączona, zapisz moment odebrania danych
Caliper_Timestamp=Tick;
Caliper_State |= CALIPER_CONNECTED;
//wyczyść flagę przerwania i kończ
EXTI_ClearITPendingBit(CLK);
return;
case CALIPER_TIMEOUT:
//wyczyść flagę przerwania i kończ
EXTI_ClearITPendingBit(CLK);
return;
default:
break;
}
}
}