Skocz do zawartości

[STM32F0 Discovery][C/CoCoox] Komunikacja z PCF8583


doles

Pomocna odpowiedź

Witam wszystkich serdecznie,

Chciałbym prosić o pomoc w analizie błędów inicjalizacji i komunikacji z zegarem RTC, który wszyscy znają. Chciałbym przedstawić kod, który nie działa - opisać objawy i spytać o parę rzeczy, które mnie nurtują. A więc do rzeczy. Najpierw Kod:

#define PCF8583_ADDR          ((uint16_t)(0x50))
#define I2C_SCL GPIO_Pin_6
#define I2C_SDA GPIO_Pin_7

// Registers
#define PCF8583_SEC_REG  ((uint8_t)(0x02))
#define PCF8583_MIN_REG  ((uint8_t)(0x03))
#define PCF8583_HOU_REG  ((uint8_t)(0x04))
#define PCF8583_DAY_REG  ((uint8_t)(0x05))
#define PCF8583_MON_REG  ((uint8_t)(0x06))

void PCF8583_Setup(void);
uint8_t PCF8583_RegRead(uint8_t reg);
void PCF8583_RegWrite(uint8_t reg, uint8_t data);

void PCF8583_Setup(void)
{
GPIO_InitTypeDef GPIO_InitStructure;
I2C_InitTypeDef  I2C_InitStructure;

RCC_I2CCLKConfig(RCC_I2C1CLK_HSI);
RCC_APB1PeriphClockCmd(RCC_APB1Periph_I2C1, ENABLE);
RCC_AHBPeriphClockCmd(RCC_AHBPeriph_GPIOB, ENABLE);

GPIO_PinAFConfig(GPIOB, GPIO_PinSource6, GPIO_AF_1); //scl
GPIO_PinAFConfig(GPIOB, GPIO_PinSource7, GPIO_AF_1); //sda

GPIO_StructInit(&GPIO_InitStructure);
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;
GPIO_InitStructure.GPIO_Pin = I2C_SCL | I2C_SDA; //scl - pb6 ; sda - pb7
GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP;
GPIO_InitStructure.GPIO_OType = GPIO_OType_OD;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;

GPIO_Init(GPIOB, &GPIO_InitStructure);

I2C_DeInit(I2C1);

I2C_StructInit(&I2C_InitStructure);
I2C_InitStructure.I2C_Ack = I2C_Ack_Enable;
I2C_InitStructure.I2C_AcknowledgedAddress = I2C_AcknowledgedAddress_7bit;
I2C_InitStructure.I2C_AnalogFilter = I2C_AnalogFilter_Enable;
I2C_InitStructure.I2C_DigitalFilter = 0;
I2C_InitStructure.I2C_Mode = I2C_Mode_I2C;
I2C_InitStructure.I2C_OwnAddress1 = 0;
I2C_InitStructure.I2C_Timing = 0x40B22536;
I2C_Init(I2C1, &I2C_InitStructure);

I2C_Cmd(I2C1, ENABLE);
}


uint8_t PCF8583_RegRead(uint8_t reg)
{
// kopia kodu z AVR
//TWI();

/*
I2C_GenerateSTART(I2C1, ENABLE);
I2C_SendData(I2C1,(uint32_t) 0x50); //address write
I2C_SendData(I2C1, reg); //register to read
I2C_GenerateSTART(I2C1, ENABLE);
I2C_SendData(I2C1,(uint32_t) 0x50); //address read
tmp = I2C_ReceiveData(I2C1);
I2C_GenerateSTOP(I2C1, ENABLE);
*/

uint8_t tmp = 0xFF;

I2C_TransferHandling(I2C1, PCF8583_ADDR, 1, I2C_SoftEnd_Mode, I2C_GenerateF));
I2C1->ICR = I2C_ICR_STOPCF;

return(tmp);
}

void PCF8583_RegWrite(uint8_t reg, uint8_t data)
{
I2C_TransferHandling(I2C1, PCF8583_ADDR, 1, I2C_Reload_Mode, I2C_GenerateF));
I2C1->ICR = I2C_ICR_STOPCF;
}

Adres urządzenia zgodnie z datasheetem - 0b101000 A0 RW. U mnie pin A0 zwarty jest do masy, więc adres wygląda następująco: 0b1010000 - 0x50. STM32 z tego co rozumiem wymaga adresów 7 bitowych a najmłodszy bit R/W ustawia sam np. przy wywołaniu funkcji:

- I2C_TransferHandling

Dobrze rozumiem ?

Po drugie, czy adresowanie 0x50 jest wystarczające, czy mam używać jakiś operacji bitowych ? Nie mogę znaleźć o tym informacji.

Po trzecie, czy jest jakaś różnica, jeśli tak to jaka w inicjalizacji GPIO oraz I2C ? Że najpierw np. zegar RCC peryferiów, potem struktura GPIO, potem funkcje alternatywne, dalej jakiś DeInit, itd.

Po czwarte, o co chodzi w polu struktury I2C_InitStructure.I2C_Timing = 0x40B22536; ? Tzn. rozumiem, że chodzi o częstotliwość zegara I2C, ale jak oblicza się tę wartość ? Zaraz ktoś odeśle mnie do skomplikowanego manuala Cortexa - tak, czytam, analizuje, mam ciągle otwarty, ale nie dla wszystkich jest on łatwy i czytelny.

Teraz do rzeczy: problem jest taki, że gdy wywołuję w main.c funkcję odczytu rejestru z RTC, czyli:

sec =  PCF8583_RegRead(PCF8583_SEC_REG); // rejestr 0x02

gdzie zmienna sec to uint8_t, program zawiesza się i zostaje w pierwszej pętli while tejże funkcji -> while(!(I2C1->ISR & I2C_ISR_TXIS)); z której już nigdy nie wychodzi. Jak mam rozumieć ten błąd ? Czy w tym wypadku w ogóle generowane jest cokolwiek ? Czy ten kod w ogóle jest dobry ? Napisałem go na bazie exampli od ST. Rezystory podciągające 10kΩ, długość lini to ~ 15cm więc nie ma to znaczenia. Układ RTC sprawny, wielokrotnie używany.

Będę wdzięczny za jakiekolwiek wskazówki z I2C do STMów, bo totalnie tego nie ogarniam. Dzięki z góry !

Link do komentarza
Share on other sites

Niestety bez zmian, to samo. Przeczytałem też gdzieś, że I2C w STMach potrafi się zawiesić po skonfigurowaniu taktowania lub po konfiguracji jego pinów. Tzn. w momencie ustawienia wyprowadzeń I2C jako Alternate Function i wybór pola GPIO_InitStructure.GPIO_OType = GPIO_OType_OD; ze struktury powoduje, że piny przełączają się ze stanu OD w stan wysokiej impedancji co I2C wykrywa jako ERROR i pętla While zawsze stoi. Solucją tego problemu jest zresetowanie magistrali I2C i robię to po włączeniu zegara oraz konfiguracji pinów:

I2C_SoftwareResetCmd(I2C1);

Ale to również nic nie daje...

Link do komentarza
Share on other sites

Zarejestruj się lub zaloguj, aby ukryć tę reklamę.
Zarejestruj się lub zaloguj, aby ukryć tę reklamę.

jlcpcb.jpg

jlcpcb.jpg

Produkcja i montaż PCB - wybierz sprawdzone PCBWay!
   • Darmowe płytki dla studentów i projektów non-profit
   • Tylko 5$ za 10 prototypów PCB w 24 godziny
   • Usługa projektowania PCB na zlecenie
   • Montaż PCB od 30$ + bezpłatna dostawa i szablony
   • Darmowe narzędzie do podglądu plików Gerber
Zobacz również » Film z fabryki PCBWay

Dzięki, coś ruszyło. Jest komunikacja po I2C. Odczyt jest nieco dziwny, bo odczytuje mi sekundy np. 0, 1...9, nagle 16, 17, 21, itd. Zlicza w ogóle do 89...a przecież sekund mamy 59 😃 Wiem, że PCFka ma kod BCD, ale to chyba obowiązuje przy zapisie a nie odczycie ? Nie przypominam sobie abym w jakichkolwiek projektach z tym scalakiem coś robił przy odczycie. Po prostu odczytywałem bajt i tyle.

Link do komentarza
Share on other sites

O ile wiem to BCD jest zawsze, czyli przy odczycie tez. Z reszta to ma sens 16 = 0x10h, czyli po 9 jak najbardziej pasuje.

A tak przy okazji - mogłbyś wkleić działający kod? Nie używałem STM32 Cortex-M0, ale może komuś się w przyszłości I2C na tym procku przyda.

  • Pomogłeś! 1
Link do komentarza
Share on other sites

Jasne stary nie ma problemu, mogę wrzucić calutki kod, na którym się uczę. Sam się wkurzam, że do STM32F0 jest słaby support. Wszędzie tylko F1, F3 i F4. Tutaj zrobiłem Timer na zwykłym przerwaniu, przerwanie zewnętrzne, ADC z DMA, uart na przerwaniach, timer z PWM 4 kanałowym, jest zrobiony bardzo fajny i dokładny delay na timerze (us i ms) no i teraz I2C. Wklejam cały kod, na pewno komuś się przyda. Dodatkowo jest obsługa czujnika SHT11 (czujnik wilgotności i temperatury) - wszystko działa pięknie, aa no i napisałem bibliotekę również pod znany i popularny wyświetlacz oparty o sterownik HD44780. Zostawiam tutaj kod, jak ktoś będzie potrzebować plików źródłowych, proszę pisać:

damiandoles@gmail.com

Ze względu na fakt, że naprawdę wkurza mnie brak pomocy do F0 - a to takie fajne małe procki ! Po co do "zegarka" brać potężny kombajn z serii F3 czy F4...api jest to samo. Umiesz F0 umiesz i F3, parę drobnych różnic, ale idea podobna. Zatem może komuś pomogę kodem.

#include "stm32f0xx.h"
#include "stm32f0xx_conf.h"
#include "stm32f0xx_syscfg.h"
#include "stdio.h"
#include "HD44780.h"
#include "Sht.h"

// ----------------------------------------------------------------------------
// Defines
// ----------------------------------------------------------------------------
#define PCF8583_ADDR          ((uint16_t)(0xA0))
#define I2C_SCL GPIO_Pin_6
#define I2C_SDA GPIO_Pin_7

// Registers
#define PCF8583_SEC_REG  ((uint8_t)(0x02))
#define PCF8583_MIN_REG  ((uint8_t)(0x03))
#define PCF8583_HOU_REG  ((uint8_t)(0x04))
#define PCF8583_DAY_REG  ((uint8_t)(0x05))
#define PCF8583_MON_REG  ((uint8_t)(0x06))

void PCF8583_Setup(void);
uint8_t PCF8583_RegRead(uint8_t reg);
void PCF8583_RegWrite(uint8_t reg, uint8_t data);

#define BlueLED GPIO_Pin_8
#define GreenLED GPIO_Pin_9
#define RedLED GPIO_Pin_4
#define UserBTN GPIO_Pin_0
#define ADC1_DR_Address 0x40012440

volatile uint8_t measureFlag = 0;
volatile uint8_t i, j = 0;
volatile char StringLoop[] = "Witaj Dolesie\n\r";
volatile uint16_t ADC_ConvertedData[4];
uint16_t TimerPeriod = 0;
uint16_t Channel1Pulse = 0, Channel2Pulse = 0, Channel3Pulse = 0, Channel4Pulse = 0;
uint8_t sensorsNumbers = 0;
uint8_t subzero, cel, cel_fract_bits;

void ADC1_CH_DMA_Config(void);
void LED_Init(void);
void TIMER2_Init(void);
void BTN_Init(void);
void Handler_Init(void);
void UART1_Init(void);


int main(void)
{
RCC_HSICmd(ENABLE);
SystemInit();
SystemCoreClockUpdate();

Delay_Init();
LCD_Initialize();
LCD_Clear();
   LED_Init();
   BTN_Init();
   TIMER2_Init();
   Handler_Init();
   ADC1_CH_DMA_Config();
   SHT_Init();
   PCF8583_Setup();
   //UART1_Init();

   uint16_t a, b, c, d = 0;
   char str_tab[50];
   uint8_t sec = 0;
   while(1)
{
   	SHT_Reset();
	if(measureFlag == 2)
	{
		SHT_GetResults();
		LCD_Clear();
	}
       /* Test DMA1 TC flag */
       while((DMA_GetFlagStatus(DMA1_FLAG_TC1)) == RESET );
       /* Clear DMA TC flag */
       DMA_ClearFlag(DMA1_FLAG_TC1);
       a = ADC_ConvertedData[0];
       b = ADC_ConvertedData[1];
       c = ADC_ConvertedData[2];
       d = ADC_ConvertedData[3];

       sprintf(str_tab, "%i %.1f %i", realsht_humidity, realsht_temp, sec);
       LCD_GoTo(0,0);
       LCD_WriteText(str_tab);
       /*
   	delay_ms(500);
   	GPIO_SetBits(GPIOC, BlueLED);
   	delay_ms(500);
   	GPIO_ResetBits(GPIOC, BlueLED);
   	*/
   	sec =  PCF8583_RegRead(PCF8583_SEC_REG);
}

   return 0;
}

void PCF8583_Setup(void)
{
GPIO_InitTypeDef GPIO_InitStructure;
I2C_InitTypeDef  I2C_InitStructure;

RCC_I2CCLKConfig(RCC_I2C1CLK_HSI);
RCC_APB1PeriphClockCmd(RCC_APB1Periph_I2C1, ENABLE);
RCC_AHBPeriphClockCmd(RCC_AHBPeriph_GPIOB, ENABLE);

GPIO_PinAFConfig(GPIOB, GPIO_PinSource6, GPIO_AF_1); //scl
GPIO_PinAFConfig(GPIOB, GPIO_PinSource7, GPIO_AF_1); //sda

GPIO_StructInit(&GPIO_InitStructure);
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;
GPIO_InitStructure.GPIO_Pin = I2C_SCL | I2C_SDA; //scl - pb6 ; sda - pb7
GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP;
GPIO_InitStructure.GPIO_OType = GPIO_OType_OD;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;

GPIO_Init(GPIOB, &GPIO_InitStructure);

I2C_StructInit(&I2C_InitStructure);
I2C_SoftwareResetCmd(I2C1);

I2C_InitStructure.I2C_Ack = I2C_Ack_Enable;
I2C_InitStructure.I2C_AcknowledgedAddress = I2C_AcknowledgedAddress_7bit;
I2C_InitStructure.I2C_AnalogFilter = I2C_AnalogFilter_Enable;
I2C_InitStructure.I2C_DigitalFilter = 0;
I2C_InitStructure.I2C_Mode = I2C_Mode_I2C;
I2C_InitStructure.I2C_OwnAddress1 = 0;
I2C_InitStructure.I2C_Timing = 0x40B22536;
I2C_Init(I2C1, &I2C_InitStructure);

I2C_Cmd(I2C1, ENABLE);
}


uint8_t PCF8583_RegRead(uint8_t reg)
{
uint8_t tmp = 0xFF;

I2C_TransferHandling(I2C1, PCF8583_ADDR, 1, I2C_SoftEnd_Mode, I2C_GenerateF));
I2C1->ICR = I2C_ICR_STOPCF;

return(tmp);
}

void PCF8583_RegWrite(uint8_t reg, uint8_t data)
{
I2C_TransferHandling(I2C1, PCF8583_ADDR, 1, I2C_Reload_Mode, I2C_GenerateF));
I2C1->ICR = I2C_ICR_STOPCF;
}


void EXTI0_1_IRQHandler(void)
{
   if (EXTI_GetITStatus(EXTI_Line0) != RESET)
   {
	j++;
	if(j == 1)
	{
		GPIO_SetBits(GPIOC, GreenLED);
	}
	else if(j == 2)
	{
		GPIO_ResetBits(GPIOC, GreenLED);
		j = 0;
	}

	measureFlag++;

	EXTI_ClearITPendingBit(EXTI_Line0);
   }
}


void LED_Init(void)
{
// configure LED output pin
GPIO_InitTypeDef GPIO_LEDG;
RCC_AHBPeriphClockCmd(RCC_AHBPeriph_GPIOC, ENABLE);
GPIO_LEDG.GPIO_Pin = BlueLED | GreenLED;
GPIO_LEDG.GPIO_Mode = GPIO_Mode_OUT;
GPIO_LEDG.GPIO_OType = GPIO_OType_PP;
GPIO_LEDG.GPIO_PuPd = GPIO_PuPd_UP;
GPIO_LEDG.GPIO_Speed = GPIO_Speed_Level_1; // 2 MHz
GPIO_Init(GPIOC, &GPIO_LEDG);
GPIO_ResetBits(GPIOC, GreenLED);
GPIO_ResetBits(GPIOC, BlueLED);
}

void TIMER2_Init(void)
{

//TimerPeriod = (SystemCoreClock / 10000 ) - 1;
/* Compute CCR2 value to generate a duty cycle at 37.5%  for channel 2 */
//Channel2Pulse = (uint16_t) (((uint32_t) 50 * (TimerPeriod - 1)) / 1000);
/* Compute CCR3 value to generate a duty cycle at 25%  for channel 3 */
//Channel3Pulse = (uint16_t) (((uint32_t) 25 * (TimerPeriod - 1)) / 1000);
/* Compute CCR4 value to generate a duty cycle at 12.5%  for channel 4 */
//Channel4Pulse = (uint16_t) (((uint32_t) 12 * (TimerPeriod- 1)) / 1000);

//ChannelxPulse = DutyCycle * (TIM1_Period - 1) / 100

   TIM_TimeBaseInitTypeDef timerInitStructure;
   RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2, ENABLE);
   timerInitStructure.TIM_Prescaler = 36;
   timerInitStructure.TIM_CounterMode = TIM_CounterMode_Up;
   timerInitStructure.TIM_Period = 20000;
   timerInitStructure.TIM_ClockDivision = TIM_CKD_DIV1;
   timerInitStructure.TIM_RepetitionCounter = 0;
   TIM_TimeBaseInit(TIM2, &timerInitStructure);
   TIM_Cmd(TIM2, ENABLE);

   TIM_OCInitTypeDef TIM_OCStruct;
TIM_OCStruct.TIM_OCMode = TIM_OCMode_PWM1;
TIM_OCStruct.TIM_OutputState = TIM_OutputState_Enable;
TIM_OCStruct.TIM_OCPolarity = TIM_OCPolarity_High;


TIM_OCStruct.TIM_Pulse = 70;
TIM_OC2Init(TIM2, &TIM_OCStruct);
TIM_OC2PreloadConfig(TIM2, TIM_OCPreload_Enable);

TIM_OCStruct.TIM_Pulse = 500;
TIM_OC3Init(TIM2, &TIM_OCStruct);
TIM_OC3PreloadConfig(TIM2, TIM_OCPreload_Enable);

TIM_OCStruct.TIM_Pulse = 5000;
TIM_OC4Init(TIM2, &TIM_OCStruct);
TIM_OC4PreloadConfig(TIM2, TIM_OCPreload_Enable);

   RCC_AHBPeriphClockCmd(RCC_AHBPeriph_GPIOA, ENABLE);

   GPIO_InitTypeDef GPIO_PWM_Output;
   GPIO_PWM_Output.GPIO_Pin = GPIO_Pin_1 | GPIO_Pin_2 | GPIO_Pin_3;
   GPIO_PWM_Output.GPIO_OType = GPIO_OType_PP;
   GPIO_PWM_Output.GPIO_PuPd = GPIO_PuPd_NOPULL;
   GPIO_PWM_Output.GPIO_Mode = GPIO_Mode_AF;
   GPIO_PWM_Output.GPIO_Speed = GPIO_Speed_Level_3;
   GPIO_Init(GPIOA, &GPIO_PWM_Output);

   GPIO_PinAFConfig(GPIOA, GPIO_PinSource1, GPIO_AF_2);
   GPIO_PinAFConfig(GPIOA, GPIO_PinSource2, GPIO_AF_2);
   GPIO_PinAFConfig(GPIOA, GPIO_PinSource3, GPIO_AF_2);
}

void BTN_Init(void)
{
// configure button input pin
GPIO_InitTypeDef GPIO_BTN;
RCC_AHBPeriphClockCmd(RCC_AHBPeriph_GPIOA, ENABLE);
RCC_APB2PeriphClockCmd(RCC_APB2Periph_SYSCFG, ENABLE);
GPIO_BTN.GPIO_Mode = GPIO_Mode_IN;
GPIO_BTN.GPIO_PuPd = GPIO_PuPd_DOWN;
GPIO_BTN.GPIO_Pin = UserBTN;
GPIO_Init(GPIOA, &GPIO_BTN);
}

void Handler_Init(void)
{
// configure external interrupt
RCC_APB2PeriphClockCmd(RCC_APB2Periph_SYSCFG, ENABLE);
EXTI_InitTypeDef EXT_internal0;
EXTI_DeInit();
EXTI_ClearITPendingBit(EXTI_Line0);
EXT_internal0.EXTI_Line = EXTI_Line0 ;
EXT_internal0.EXTI_Mode = EXTI_Mode_Interrupt;
EXT_internal0.EXTI_Trigger = EXTI_Trigger_Rising;
EXT_internal0.EXTI_LineCmd = ENABLE;
EXTI_Init(&EXT_internal0);

// configure NVIC for EXTI0
SYSCFG_EXTILineConfig(EXTI_PortSourceGPIOA, EXTI_PinSource0);
NVIC_SetPriority(EXTI0_1_IRQn, 2);
NVIC_EnableIRQ(EXTI0_1_IRQn); //Enabe EXTI0_1 IRQ
//NVIC_SetPriority(TIM3_IRQn, 1);
//NVIC_EnableIRQ(TIM3_IRQn); //Enabe EXTI0_1 IRQ
}

void ADC1_CH_DMA_Config(void)
{
RCC_AHBPeriphClockCmd(RCC_AHBPeriph_GPIOA, ENABLE);

GPIO_InitTypeDef GPIO_InitStructure;
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_4 | GPIO_Pin_5 | GPIO_Pin_6 | GPIO_Pin_7;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AN;
GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL;
GPIO_Init(GPIOA, &GPIO_InitStructure);
ADC_InitTypeDef ADC_InitStructure;
DMA_InitTypeDef DMA_InitStructure;

/* ADC1 DeInit */
ADC_DeInit(ADC1);

/* ADC1 Periph clock enable */
RCC_APB2PeriphClockCmd(RCC_APB2Periph_ADC1, ENABLE);

/* DMA1 clock enable */
RCC_AHBPeriphClockCmd(RCC_AHBPeriph_DMA1 , ENABLE);

/* DMA1 Channel1 Config */
DMA_DeInit(DMA1_Channel1);
DMA_InitStructure.DMA_PeripheralBaseAddr = (uint32_t)ADC1_DR_Address;
DMA_InitStructure.DMA_MemoryBaseAddr = (uint32_t)ADC_ConvertedData;
DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralSRC;
DMA_InitStructure.DMA_BufferSize = 4;
DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable;
DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable;
DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_HalfWord;
DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_HalfWord;
DMA_InitStructure.DMA_Mode = DMA_Mode_Circular;
DMA_InitStructure.DMA_Priority = DMA_Priority_High;
DMA_InitStructure.DMA_M2M = DMA_M2M_Disable;
DMA_Init(DMA1_Channel1, &DMA_InitStructure);

/* DMA1 Channel1 enable */
DMA_Cmd(DMA1_Channel1, ENABLE);

/* ADC DMA request in circular mode */
ADC_DMARequestModeConfig(ADC1, ADC_DMAMode_Circular);

/* Enable ADC_DMA */
ADC_DMACmd(ADC1, ENABLE);

/* Initialize ADC structure */
ADC_StructInit(&ADC_InitStructure);

/* Configure the ADC1 in continous mode withe a resolutuion equal to 12 bits  */
ADC_InitStructure.ADC_Resolution = ADC_Resolution_12b;
ADC_InitStructure.ADC_ContinuousConvMode = ENABLE;
ADC_InitStructure.ADC_ExternalTrigConvEdge = ADC_ExternalTrigConvEdge_None;
ADC_InitStructure.ADC_DataAlign = ADC_DataAlign_Right;
ADC_InitStructure.ADC_ScanDirection = ADC_ScanDirection_Upward;
ADC_Init(ADC1, &ADC_InitStructure);

/* Convert the ADC1 Vref  with 55.5 Cycles as sampling time */
ADC_ChannelConfig(ADC1, ADC_Channel_4 , ADC_SampleTime_55_5Cycles);
ADC_ChannelConfig(ADC1, ADC_Channel_5 , ADC_SampleTime_55_5Cycles);
ADC_ChannelConfig(ADC1, ADC_Channel_6 , ADC_SampleTime_55_5Cycles);
ADC_ChannelConfig(ADC1, ADC_Channel_7 , ADC_SampleTime_55_5Cycles);

/* ADC Calibration */
ADC_GetCalibrationFactor(ADC1);

/* Enable ADC1 */
ADC_Cmd(ADC1, ENABLE);

/* Wait the ADCEN falg */
while(!ADC_GetFlagStatus(ADC1, ADC_FLAG_ADEN));

/* ADC1 regular Software Start Conv */
ADCBits = USART_StopBits_1;
   USART_InitStructure.USART_Parity = USART_Parity_No;
   USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None;
   USART_InitStructure.USART_Mode = USART_Mode_Rx | USART_Mode_Tx;

   /* Enable GPIO clock */
   RCC_AHBPeriphClockCmd(RCC_AHBPeriph_GPIOA, ENABLE);

   /* Enable USART clock */
   RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1, ENABLE);

   /* Connect PXx to USARTx_Tx */
   GPIO_PinAFConfig(GPIOA, GPIO_PinSource9, GPIO_AF_1);

   /* Connect PXx to USARTx_Rx */
   GPIO_PinAFConfig(GPIOA, GPIO_PinSource10, GPIO_AF_1);

   /* Configure USART Tx, Rx as alternate function push-pull */
   GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9 | GPIO_Pin_10;
   GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;
   GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
   GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
   GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL;
   GPIO_Init(GPIOA, &GPIO_InitStructure);

   /* USART configuration */
   USART_Init(USART1, &USART_InitStructure);

   /* Enable USART */
   USART_Cmd(USART1, ENABLE);
/* Enable USART1 IRQ */
   NVIC_InitTypeDef NVIC_InitStructure;
NVIC_InitStructure.NVIC_IRQChannel = USART1_IRQn;
NVIC_InitStructure.NVIC_IRQChannelPriority = 0;
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
NVIC_Init(&NVIC_InitStructure);
USART_ITConfig(USART1, USART_IT_TXE, ENABLE);
USART_ITConfig(USART1, USART_IT_RXNE, ENABLE);
}

void USART1_IRQHandler(void)
{
 static int tx_index = 0;
 static int rx_index = 0;

 if (USART_GetITStatus(USART1, USART_IT_TXE) != RESET) // Transmit the string in a loop
 {
   USART_SendData(USART1, StringLoop[tx_index++]);

   if (tx_index >= (sizeof(StringLoop) - 1))
     tx_index = 0;
 }

 if (USART_GetITStatus(USART1, USART_IT_RXNE) != RESET) // Received characters modify string
 {
   StringLoop[rx_index++] = USART_ReceiveData(USART1);

   if (rx_index >= (sizeof(StringLoop) - 1))
     rx_index = 0;
 }
}

HD44780.c

#include "HD44780.h"

//-------------------------------------
// Write half byte
//-------------------------------------
void _LCD_OutNibble(unsigned char nibbleToWrite)
{
if(nibbleToWrite & 0x01)
	GPIO_SetBits(LCD_GPIO, LCD_D4);
else
	GPIO_ResetBits(LCD_GPIO, LCD_D4);

if(nibbleToWrite & 0x02)
	GPIO_SetBits(LCD_GPIO, LCD_D5);
else
	GPIO_ResetBits(LCD_GPIO, LCD_D5);

if(nibbleToWrite & 0x04)
	GPIO_SetBits(LCD_GPIO, LCD_D6);
else
	GPIO_ResetBits(LCD_GPIO, LCD_D6);

if(nibbleToWrite & 0x08)
	GPIO_SetBits(LCD_GPIO, LCD_D7);
else
	GPIO_ResetBits(LCD_GPIO, LCD_D7);
}

//-------------------------------------
// Write byte
//-------------------------------------
void _LCD_Write(unsigned char dataToWrite)
{
GPIO_SetBits(LCD_GPIO, LCD_EN);
_LCD_OutNibble(dataToWrite >> 4);
GPIO_ResetBits(LCD_GPIO, LCD_EN);
GPIO_SetBits(LCD_GPIO, LCD_EN);
_LCD_OutNibble(dataToWrite);
GPIO_ResetBits(LCD_GPIO, LCD_EN);
delay_us(50);
}

//-------------------------------------
// Write to command register
//-------------------------------------
void LCD_WriteCommand(unsigned char commandToWrite)
{
GPIO_ResetBits(LCD_GPIO, LCD_RS);
_LCD_Write(commandToWrite);
}

//-------------------------------------
// Write to data register
//-------------------------------------
void LCD_WriteData(unsigned char dataToWrite)
{
GPIO_SetBits(LCD_GPIO, LCD_RS);
_LCD_Write(dataToWrite);
}

//-------------------------------------
// Write text
//-------------------------------------
void LCD_WriteText(char * text)
{
while(*text)
	LCD_WriteData(*text++);
}

//-------------------------------------
// Set display coordinates
//-------------------------------------
void LCD_GoTo(unsigned char x, unsigned char y)
{
LCD_WriteCommand(HD44780_DDRAM_SET | (x + (0x40 * y)));
}

//-------------------------------------
// Clear display
//-------------------------------------
void LCD_Clear(void)
{
LCD_WriteCommand(HD44780_CLEAR);
delay_ms(2);
}

//-------------------------------------
// Set home position
//-------------------------------------
void LCD_Home(void)
{
LCD_WriteCommand(HD44780_HOME);
delay_ms(2);
}

//-------------------------------------
// Shift display left
//-------------------------------------
void LCD_ShiftLeft(void)
{
LCD_WriteCommand(HD44780_DISPLAY_CURSOR_SHIFT | HD44780_SHIFT_LEFT | HD44780_SHIFT_DISPLAY);
}

//-------------------------------------
// Shift display right
//-------------------------------------
void LCD_ShiftRight(void)
{
LCD_WriteCommand(HD44780_DISPLAY_CURSOR_SHIFT | HD44780_SHIFT_RIGHT | HD44780_SHIFT_DISPLAY);
}

//-------------------------------------
// Display initialization
//-------------------------------------
void LCD_Initialize(void)
{
unsigned char i;
RCC_AHBPeriphClockCmd(LCD_CLK_LINE, ENABLE);
GPIO_InitTypeDef GPIO_LCD_Struct;
GPIO_LCD_Struct.GPIO_Pin = LCD_D4 | LCD_D5 | LCD_D6 | LCD_D7 | LCD_RS | LCD_EN;
GPIO_LCD_Struct.GPIO_OType = GPIO_OType_PP;
GPIO_LCD_Struct.GPIO_Speed = GPIO_Speed_Level_3;
GPIO_LCD_Struct.GPIO_PuPd = GPIO_PuPd_NOPULL;
GPIO_LCD_Struct.GPIO_Mode = GPIO_Mode_OUT;
GPIO_Init(LCD_GPIO, &GPIO_LCD_Struct);

delay_ms(15);

GPIO_ResetBits(LCD_GPIO, LCD_RS | LCD_EN);

for(i = 0; i < 3; i++)
{
	GPIO_SetBits(LCD_GPIO, LCD_EN);
	_LCD_OutNibble(0x03);
	GPIO_ResetBits(LCD_GPIO, LCD_EN);
	delay_ms(5);
}

GPIO_SetBits(LCD_GPIO, LCD_EN);
_LCD_OutNibble(0x02);
GPIO_ResetBits(LCD_GPIO, LCD_EN);

delay_ms(1);

LCD_WriteCommand(HD44780_FUNCTION_SET | HD44780_FONT5x7 | HD44780_TWO_LINE | HD44780_4_BIT);
LCD_WriteCommand(HD44780_DISPLAY_ONOFF | HD44780_DISPLAY_OFF);
LCD_WriteCommand(HD44780_CLEAR);

delay_ms(2);

LCD_WriteCommand(HD44780_ENTRY_MODE | HD44780_EM_SHIFT_CURSOR | HD44780_EM_INCREMENT);
LCD_WriteCommand(HD44780_DISPLAY_ONOFF | HD44780_DISPLAY_ON | HD44780_CURSOR_OFF | HD44780_CURSOR_NOBLINK);
}


//-------------------------------------
// End of file
//-------------------------------------

HD44780.h

#include "stm32f0xx.h"
#include "stm32f0xx_rcc.h"
#include "stm32f0xx_gpio.h"
//#include "delay.h"

#define LCD_GPIO GPIOA
#define LCD_CLK_LINE RCC_AHBPeriph_GPIOA

#define LCD_D4 GPIO_Pin_8
#define LCD_D5 GPIO_Pin_9
#define LCD_D6 GPIO_Pin_10
#define LCD_D7 GPIO_Pin_11
#define LCD_RS GPIO_Pin_12
#define LCD_EN GPIO_Pin_15

//-------------------------------------------------------------------------------------------------
// HD44780 commands
//-------------------------------------------------------------------------------------------------

#define HD44780_CLEAR					0x01

#define HD44780_HOME					0x02

#define HD44780_ENTRY_MODE				0x04
#define HD44780_EM_SHIFT_CURSOR		0
#define HD44780_EM_SHIFT_DISPLAY	1
#define HD44780_EM_DECREMENT		0
#define HD44780_EM_INCREMENT		2

#define HD44780_DISPLAY_ONOFF			0x08
#define HD44780_DISPLAY_OFF			0
#define HD44780_DISPLAY_ON			4
#define HD44780_CURSOR_OFF			0
#define HD44780_CURSOR_ON			2
#define HD44780_CURSOR_NOBLINK		0
#define HD44780_CURSOR_BLINK		1

#define HD44780_DISPLAY_CURSOR_SHIFT	0x10
#define HD44780_SHIFT_CURSOR		0
#define HD44780_SHIFT_DISPLAY		8
#define HD44780_SHIFT_LEFT			0
#define HD44780_SHIFT_RIGHT			4

#define HD44780_FUNCTION_SET			0x20
#define HD44780_FONT5x7				0
#define HD44780_FONT5x10			4
#define HD44780_ONE_LINE			0
#define HD44780_TWO_LINE			8
#define HD44780_4_BIT				0
#define HD44780_8_BIT				16

#define HD44780_CGRAM_SET				0x40

#define HD44780_DDRAM_SET				0x80

//-------------------------------------------------------------------------------------------------
// Functions declarations
//-------------------------------------------------------------------------------------------------
void LCD_WriteCommand(unsigned char);
void LCD_WriteData(unsigned char);
void LCD_WriteText(char *);
void LCD_GoTo(unsigned char, unsigned char);
void LCD_Clear(void);
void LCD_Home(void);
void LCD_ShiftLeft(void);
void LCD_ShiftRight(void);
void LCD_Initialize(void);

//-------------------------------------------------------------------------------------------------
// End of file
//-------------------------------------------------------------------------------------------------

SHTxx.c

//----------------------------------------------------------------------------------
//
// Sensirion SHTxx Humidity Sensor Library
//
// Library for using the SHT1x humidity and temperature
// sensors from Sensirion (http://www.sensirion.com).
// Based on Sensirion application note "Sample Code SHTxx".
//
// To use:
// - supply 5V to SHTxx (constants in calculations assume 5V, see ShtCalculate() and SHTxx datasheet)
// - connect the clock pin of the SHTxx to pin B1 (see Sht.h to change)
// - connect the data pin of the SHTxx to pin B2 (see Sht.h to change)
//
// - call ShtInit() to initialize pins, call when the processor starts
// - call ShtMeasure(MEASURE_TEMP) and ShtMeasure(MEASURE_HUMIDITY) to make the measurements
// - call ShtCalculate() to convert measurements to real-world units
//
// - call ShtReadStatus() and ShtWriteStatus() to modify the status register
//
//
// ToDo:
// - verify checksum digits sent from SHTxx
// - implement soft-reset
// - handle 12/8-bit temp/humidity readings
//
// History:
// 2003-Jul-03	BL	- Created
//
//----------------------------------------------------------------------------------
#include "sht.h"
//#include "delay.h"


void SHT_EnableData(void) 		
{ 
GPIO_InitTypeDef GPIO_SHT_Struct;
GPIO_SHT_Struct.GPIO_Pin = SHT_DATA;
GPIO_SHT_Struct.GPIO_OType = GPIO_OType_PP;
GPIO_SHT_Struct.GPIO_Speed = GPIO_Speed_Level_3;
GPIO_SHT_Struct.GPIO_PuPd = GPIO_PuPd_NOPULL;
GPIO_SHT_Struct.GPIO_Mode = GPIO_Mode_OUT;
GPIO_Init(SHT_GPIO, &GPIO_SHT_Struct);
}

void SHT_DisableData(void)		
{ 
GPIO_InitTypeDef GPIO_SHT_Struct;
GPIO_SHT_Struct.GPIO_Pin = SHT_DATA;
GPIO_SHT_Struct.GPIO_OType = GPIO_OType_PP;
GPIO_SHT_Struct.GPIO_Speed = GPIO_Speed_Level_3;
GPIO_SHT_Struct.GPIO_PuPd = GPIO_PuPd_NOPULL;
GPIO_SHT_Struct.GPIO_Mode = GPIO_Mode_IN;
GPIO_Init(SHT_GPIO, &GPIO_SHT_Struct);

GPIO_SetBits(SHT_GPIO, SHT_DATA);
}

void SHT_DataHigh(void)		
{ 
GPIO_SetBits(SHT_GPIO, SHT_DATA);
}

void SHT_DataLow(void)			
{ 
GPIO_ResetBits(SHT_GPIO, SHT_DATA);
}

void SHT_ClockHigh(void)		
{ 
GPIO_SetBits(SHT_GPIO, SHT_CLOCK);
}

void SHT_ClockLow(void)		
{ 
GPIO_ResetBits(SHT_GPIO, SHT_CLOCK);
}	

void SHT_Init(void)
{
RCC_AHBPeriphClockCmd(SHT_GPIO_CLK, ENABLE);
GPIO_InitTypeDef GPIO_SHT_Struct;
GPIO_SHT_Struct.GPIO_Pin = SHT_CLOCK;
GPIO_SHT_Struct.GPIO_OType = GPIO_OType_PP;
GPIO_SHT_Struct.GPIO_Speed = GPIO_Speed_Level_3;
GPIO_SHT_Struct.GPIO_PuPd = GPIO_PuPd_NOPULL;
GPIO_SHT_Struct.GPIO_Mode = GPIO_Mode_OUT;
GPIO_Init(SHT_GPIO, &GPIO_SHT_Struct);

GPIO_ResetBits(SHT_GPIO, SHT_CLOCK);

SHT_DisableData();
}

//----------------------------------------------------------------------------------
// generates a transmission start
//       _____         ________
// DATA:      |_______|
//           ___     ___
// SCK : ___|   |___|   |______
//
//----------------------------------------------------------------------------------
void SHT_TransmissionStart(void)
{
SHT_EnableData();
SHT_DataHigh();
SHT_ClockLow();
delay_us(5);
delay_us(5);
SHT_ClockHigh();	
delay_us(5);
SHT_DataLow();		
delay_us(5);
SHT_ClockLow();	
delay_us(10);
SHT_ClockHigh();	
delay_us(5);
SHT_DataHigh();	
delay_us(5);
SHT_ClockLow();
}

//----------------------------------------------------------------------------------
// communication reset: DATA-line=1 and at least 9 SCK cycles followed by transstart
//       _____________________________________________________         ________
// DATA:                                                      |_______|
//          _    _    _    _    _    _    _    _    _        ___     ___
// SCK : __| |__| |__| |__| |__| |__| |__| |__| |__| |______|   |___|   |______
//----------------------------------------------------------------------------------
void SHT_Reset(void)
{
unsigned char i;
SHT_EnableData();
SHT_DataHigh();
SHT_ClockLow();

for(i = 0; i < 10; i++) //9 SCK cycles
{
	SHT_ClockHigh();
}

SHT_TransmissionStart(); //transmission start
}

//----------------------------------------------------------------------------------
// reads a byte form the Sensibus and gives an acknowledge in case of "ack=1"
//----------------------------------------------------------------------------------
char SHT_ReadByte(void)
{
unsigned char i, val=0;
SHT_DisableData();

// Read in 8 bits, LSB first
for (i = 0x80; i > 0; i /= 2)
{
	SHT_ClockHigh();
	delay_us(5);

	if(GPIO_ReadInputDataBit(SHT_GPIO, SHT_DATA))
		val = (val | i); //read bit

	SHT_ClockLow();
}

// Send ACK
SHT_EnableData();
SHT_DataLow();
SHT_ClockHigh();
delay_us(5);
SHT_ClockLow();
SHT_DisableData();

return val;
}

//----------------------------------------------------------------------------------
// Writes a byte on the Sensibus and checks the acknowledge.
// Returns 0 if the successful
//----------------------------------------------------------------------------------
char SHT_WriteByte(unsigned char value)
{
unsigned char i;
unsigned char error = 0;

// Write each bit one at a time, LSB first
SHT_EnableData();
for (i = 0x80; i  >0; i /= 2)
{
	if (i & value)
		SHT_DataHigh();
	else
		SHT_DataLow();

	SHT_ClockHigh();
	delay_us(5);
	delay_us(5);
	SHT_ClockLow();

}
SHT_DisableData();

// Read ACK
SHT_ClockHigh();
delay_us(5);
error = GPIO_ReadInputDataBit(SHT_GPIO, SHT_DATA);
SHT_ClockLow();

return error; //error=1 in case of no acknowledge
}

//----------------------------------------------------------------------------------
// Read humidity or temperature from the sensor.
// Returns the value in ticks. Use sht_calc() to convert to real world units.
// Returns 0xFFFF if the measurement failed
//----------------------------------------------------------------------------------
int SHT_Measure(unsigned char mode)
{
unsigned int 	temp = 0xFFFF;
unsigned char 	c;

// Signal start of communications
SHT_TransmissionStart();
// Request measurement
SHT_WriteByte(mode);
// Sensor lowers the data line when measurement
// is complete. Wait up to 2 seconds for this.
for (c = 0; c < 20; c++)
{
	if(! GPIO_ReadInputDataBit(SHT_GPIO, SHT_DATA))
		break;
	delay_ms(15);
}

// Read the measurement
if(! GPIO_ReadInputDataBit(SHT_GPIO, SHT_DATA))
{
	temp = SHT_ReadByte();
	temp = temp << 8;
	temp += SHT_ReadByte();
}
return temp;
}

//----------------------------------------------------------------------------------------
// Calculates tempurature in ^C and humidity in %RH (temperature compensated)
// sht_measure() returns temp and humidity in ticks. Use this function to convert
// to compensated values in real world units.
//
// This function returns integers with 2 assumed decimal places. For example 2550
// means 25.50. This is to avoid including the floating point math library.
//
// input :	humi [Ticks] (12 bit)
// 			temp [Ticks] (14 bit)
// output: 	humi [%RH] (2 fixed decimals)
// 			temp [°C]  (2 fixed decimals)
//----------------------------------------------------------------------------------------
void SHT_Calculate(int *p_temperature, int *p_humidity)
{
const long D1x100 = -40 * 100;					// for 5V power
const long D2x100 = 0.01 * 100;					// for 14bit temp
const long C1x100 = -4 * 100;					// for 12bit humidity
const long C2x10000 = 0.0405 * 10000;			// for 12bit humidity
const long C3x10000000 = -0.0000028 * 10000000;	// for 12bit humidity
const long T1x100000 = 0.01 * 100000;			// for 12bit humidity
const long T2x100000 = 0.00008 * 100000;		// for 12bit humidity

long t = *p_temperature;			// temperatere in ticks from sensor
long rh = *p_humidity;				// humidity in ticks from sensor

long t_C;							// temperature in celcius: 2 fixed decimals
long rh_lin;						// relative humidity: 2 fixed decimals
long rh_true;						// temp compensated humidity: 2 fixed decimals

t_C = D1x100 + D2x100*t;			// calculate tempurature in celcius from ticks

rh_lin = (C3x10000000*rh*rh)/100000 + (C2x10000*rh)/100 + C1x100;
rh_true = ((t_C-(25*100)) * (T1x100000 + T2x100000*rh))/100000 + rh_lin;

if(rh_true > 10000)
	rh_true = 10000; 	//cut if the value is outside of
if(rh_true < 10)
rh_true = 10; 			//the physical possible range

*p_temperature = (int)t_C; 			//return temperature [^C]
*p_humidity = (int)rh_true;	 		//return humidity[%RH]
}

//----------------------------------------------------------------------------------
// Reads the status register 
//----------------------------------------------------------------------------------
char SHT_ReadStatusReg(unsigned char *p_value)
{
unsigned char error = 0;
SHT_TransmissionStart(); 					//transmission start
error = SHT_WriteByte(STATUS_REG_R); 		//send command to sensor
*p_value = SHT_ReadByte(); 					//read status register (8-bit)
return error; 								//error=1 in case of no response form the sensor
}

//----------------------------------------------------------------------------------
// Writes the status register . Note this library only supports the default
// 14 bit temp and 12 bit humidity readings.
//----------------------------------------------------------------------------------
char SHT_WriteStatusReg(unsigned char value)
{
unsigned char error = 0;
SHT_TransmissionStart(); 					//transmission start
error += SHT_WriteByte(STATUS_REG_W);		//send command to sensor
error += SHT_WriteByte(value); 				//send value of status register
return error; 								//error>=1 in case of no response form the sensor
}

void SHT_GetResults(void)
{
temp_ticks = SHT_Measure(SHT_TEMPERATURE);
humidity_ticks = SHT_Measure(SHT_HUMIDITY);

temp_sht = (int)temp_ticks;
humidity_sht = (int)humidity_ticks;
SHT_Calculate(&temp_sht, &humidity_sht);		//konwersja z binarki na odpowiednią wartość liczb rzeczywistych
realsht_temp = (float)temp_sht/100;				//przeliczenie temperatury na wartość z przecinkiem
realsht_humidity = (int)humidity_sht/100;		//przeliczenie wilgotności na wartość z przecinkiem
}

char SHT_SoftReset(void)
{
unsigned char error = 0;
SHT_TransmissionStart();			//reset communication
error += SHT_WriteByte(RESET);		//send RESET-command to sensor
return error;						//error=1 in case of no response form the sensor
}

SHTxx.h

//----------------------------------------------------------------------------------
//
// Sensirion SHT1x Humidity Sensor Library
//
//----------------------------------------------------------------------------------
#include "stm32f0xx.h"
#include "stm32f0xx_rcc.h"
#include "stm32f0xx_gpio.h"
#include "stdbool.h"

#ifndef __sht_h
#define __sht_h

#define SHT_TEMPERATURE 	0x03		// Measure temp - for ShtMeasure
#define SHT_HUMIDITY 		0x05		// Measure humidity - for ShtMeasure

#define SHT_GPIO 			GPIOB
#define SHT_DATA 			GPIO_Pin_13
#define SHT_CLOCK 			GPIO_Pin_14

#define SHT_GPIO_CLK 		RCC_AHBPeriph_GPIOB

#define STATUS_REG_W 		0x06 		// Command to read status register
#define STATUS_REG_R 		0x07 		// Command to write status register
#define RESET 				0x1E 		// Command for soft reset (not currently used)

int humidity_sht;
int temp_sht;
unsigned int temp_ticks;
unsigned int humidity_ticks;
int realsht_humidity;
float realsht_temp;

void SHT_Init(void);
void SHT_Reset(void);
int  SHT_Measure(unsigned char mode);
void SHT_Calculate(int *p_temperature, int *p_humidity);
char SHT_ReadStatusReg(unsigned char *p_value);
char SHT_WriteStatusReg(unsigned char value);
void SHT_GetResults(void);
char SHT_SoftReset(void);
#endif

Faktycznie - przyznaję się, że PCFka również zwraca kod BCD...szybko napisałem dwie funkcje do konwersji kodu bcd i decymalnego. Może też komuś się przyda:

//-------------------------------------
// Convert int decimal value to BCD value
//-------------------------------------
int DecToBcd(int data)
{
return ((data/10) << 4) + (data % 10);
}

//-------------------------------------
// Convert BCD value to int decimal value
//-------------------------------------
int BcdToDec(int data) 
{ 
return (10*(data>>4) + (data & 0x0F)); 
}

Najmocniej dziękuję za pomoc !!

[ Dodano: 15-02-2015, 20:47 ]

Mam jeszcze jedno ciekawe pytanie, otóż zacząłem robić sobie obsługę pamięci EEPROM 24C64, i co ciekawe komunikacja jest, ale...problem jest taki, że, gdy na magistrali mam oba urządzenia, tzn. pamięć eeprom i pcfke, to w pętli głównej while(1) wykonuje się najpierw odczyt sekund z pcfki, następnie odczyt jakiejś strony pamięci i gdy pętla "wraca" od nowa i dochodzi do odczytu sekund z pcfki, to zostaje w nieszczęsnej pętli while. W takim razie pojawia się pytanie - jaka jest "procedura" obsługi wielu urządzeń na i2c w stm32 ? Czy muszę np. włączać i wyłączać magistralę ? Coś resetować ?

sec = PCF8583_RegRead(PCF8583_SEC_REG);

delay_ms(10);

page_value = EEPROM_ReadByte(0);

Link do komentarza
Share on other sites

Urządzenia muszą mieć różne adresy. Jak ustalilićmy PCF8583 jest widoczny pod adresem 0xa0. Natomiast 24C64 musi mieć przypisany inny adres. Szybko patrząc na datasheet układu eeprom widzę, że adresy są typy 0xA_ gdzie _ można ustawić odpowiednimi pinami. Jeśli podłączyłeś wszystko do masy, to masz oba układy pod adresem 0xa0, czyli niepoprawnie skonfigurowane I2C. Trzeba któryś z nich przestawić i będzie działało poprawnie, nic nie trzeba resetować/

Link do komentarza
Share on other sites

Hm, dziwne bo fakt, dla PCFki pin konfiguracyjny adresu urządzenia mam zwarty do masy stąd adres 0xA0. Z kolei pin E2 pamięci eeprom mam zwarty do Vcc, czyli jest tam "1" logiczne - adresy już są inne i z tego wynika, że adres pamięci eeprom to 0xA8. Poza tym kod dla AVR z tymi adresami działał, w dodatku były jeszcze 2 inne urządzenia na magistrali.

Link do komentarza
Share on other sites

Bądź aktywny - zaloguj się lub utwórz konto!

Tylko zarejestrowani użytkownicy mogą komentować zawartość tej strony

Utwórz konto w ~20 sekund!

Zarejestruj nowe konto, to proste!

Zarejestruj się »

Zaloguj się

Posiadasz własne konto? Użyj go!

Zaloguj się »
×
×
  • Utwórz nowe...

Ważne informacje

Ta strona używa ciasteczek (cookies), dzięki którym może działać lepiej. Więcej na ten temat znajdziesz w Polityce Prywatności.