Ynt: 74HC164 Kullanımı

Başlatan baran123, 21 Nisan 2015, 23:29:37

baran123

Elinde bu entegreden var.4x7 Display sürmek istiyorum fakat internetteki örneklerde ve araştırdığım kadarıyla SPI mantığı ile çalışıyor.2 pin ile 8 çıkış işimi görür diye aldım fakat bunu ccs in hazır fonksiyonu değilde işin mantığıyla yapmak istiyorum.Data ya veriyi gönderip Clock dan bir pals gönderiyoruz okey buraya kadar. Fakat bu 8 bitlik veriyi bitlerine ayırma işlemini unuttum.İnternette bulamıyorum.AND, OR işemiyle yapılıyordu kafam karıştı.Çok kolay bir şey ama çözemedim. Nasıl yapacaz bunu :)

mesaj birleştirme:: 21 Nisan 2015, 23:31:38

CCS olsa direk output_bit ile bitiyordu ama STM de yapacağım. :D

sadogan

#1
8 bitlik i gibi bir değişkenin olsun
i=0B00000001 değerini ata
i ile 8 bitlik verini i ile and le sonuc 1 ise data pini 1 0 ise data pini 0 yap
sonra i yi 1 bit sola kaydır ve işlemi tekrarla taki i=0 olana kadar.


mesaj birleştirme:: 21 Nisan 2015, 23:54:56

stm de ilgili pine 1 yada 0 nasıl yazıyorsunuz?

baran123

Hocam dediklerinize göre bir fonksiyon yazmaya çalışıyorum.

GPIO_SetBits(GPIOA,HC164_CLOCK); //1
GPIO_ResetBits(GPIOA,HC164_CLOCK);//0

sadogan

      for(unsigned char i=0B00000001;i>0;i<<=1) 
      {
         if(data&i)DATAPIN=1;
         else DATAPIN=0;
         CLKPIN=1;
         //burda bikac clk bekleme var
         CLKPIN=0;         
      }

baran123

Hocam fonksiyonu şöyle düzenledim.Fakat 1.displayde abcd segmeneri sönük siğer segmentler yanıyor ve 2,3,4. digitler yanmıyor ve 2.displayin noktası yanıyor.Yani yolladığım veri tam olarak gitmiyor gibi.

Entegrenin a,b uçları birleşip data olarak aldım
/***********************************************************
* Function Name  : HC164_Send
* Description    : HC164 'e 8 bitlik data yollar
* Input          : uint8_t
* Return         : void
***********************************************************/
void HC164_Send(uint8_t Data)
{
    static uint8_t i;
    for(i=0x01; i>0; i<<=1)
    {
        if(Data&i)
            GPIO_SetBits(GPIOA,HC164_DATA);
        else
            GPIO_ResetBits(GPIOA,HC164_DATA);

        GPIO_SetBits(GPIOA,HC164_CLOCK);
        GPIO_ResetBits(GPIOA,HC164_CLOCK);
    }
}


kodlar
/*****************************************************************************

* File Name        : main.c

* Description      : SysTick_Uygulaması

********************************************************************************

* Additional Information : SysTick ile interrupt olusturma.

*******************************************************************************/
#include "stm32f0xx_conf.h"
#include "main.h";

#define RTC_CLOCK_SOURCE_LSI

uint32_t Digit_State;
uint16_t temp = 1997;
uint16_t Display_Buffer[4];

uint16_t Digit_Figures[10]= {0x003F,0x0006,0x005B,0x004F,0x0066,0x006D,0x007C,0x0007,0x007F,0x006F};

static void CPU_Init(void);
static void RTC_Initialize(void);

RTC_TimeTypeDef  RTC_TimeStruct;
RTC_DateTypeDef  RTC_DateStruct;

/***********************************************************
* Function Name  : main
* Description    : Ana program burada döner.
* Input          : void
* Return         : int
***********************************************************/
int main(void)
{
    CPU_Init();
    RTC_Initialize();
    GPIO_Write(GPIOC, 0x000E);
    HC164_Send(0x0F);
    
    while(1)
    {
        /*RTC_GetTime(RTC_Format_BCD,&RTC_TimeStruct);
        RTC_GetDate(RTC_Format_BCD,&RTC_DateStruct);

        Display_Buffer[0] = (RTC_TimeStruct.RTC_Seconds & 0x0F);
        Display_Buffer[1] = (RTC_TimeStruct.RTC_Seconds & 0xF0) >> 4;
        Display_Buffer[2] = (RTC_TimeStruct.RTC_Minutes & 0x0F);
        Display_Buffer[3] = (RTC_TimeStruct.RTC_Minutes & 0xF0) >> 4;*/
    }
}

/***********************************************************
* Function Name  : Digit_Scanner
* Description    : Display taramam metodunu gerçekleştirir.
* Input          : uint32_t
* Return         : void
***********************************************************/
void Digit_Scanner(uint32_t State)
{
    switch(State)
    {
    case 0:
        GPIO_Write(GPIOA, Digit_Figures[Display_Buffer[3]]);
        GPIO_Write(GPIOC, 0x000E);
        break;

    case 1:
        GPIO_Write(GPIOA, Digit_Figures[Display_Buffer[2]] + 0x80);
        GPIO_Write(GPIOC, 0x000D);
        break;

    case 2:
        GPIO_Write(GPIOA, Digit_Figures[Display_Buffer[1]]);
        GPIO_Write(GPIOC, 0x000B);
        break;

    case 3:
        GPIO_Write(GPIOA, Digit_Figures[Display_Buffer[0]]);
        GPIO_Write(GPIOC, 0x0007);
        break;
    }
}

/***********************************************************
* Function Name  : CPU_Init
* Description    : İşlemci ön ayarları ve yapılandırılması.
* Input          : void
* Return         : void
***********************************************************/
static void CPU_Init(void)
{
    GPIO_InitTypeDef  GPIO_InitStructure;

    RCC_AHBPeriphClockCmd(RCC_AHBPeriph_GPIOA,ENABLE);
    RCC_AHBPeriphClockCmd(RCC_AHBPeriph_GPIOC,ENABLE);

    GPIO_InitStructure.GPIO_Pin   = HC164_DATA | HC164_CLOCK;
    GPIO_InitStructure.GPIO_Mode  = GPIO_Mode_OUT;
    GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_Level_1;
    GPIO_InitStructure.GPIO_PuPd  = GPIO_PuPd_NOPULL;

    GPIO_Init(GPIOA,&GPIO_InitStructure);

    GPIO_InitStructure.GPIO_Pin   = GPIO_Pin_0 | GPIO_Pin_1 |GPIO_Pin_2 |GPIO_Pin_3;
    GPIO_InitStructure.GPIO_Mode  = GPIO_Mode_OUT;
    GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_Level_1;
    GPIO_InitStructure.GPIO_PuPd  = GPIO_PuPd_NOPULL;

    GPIO_Init(GPIOC,&GPIO_InitStructure);

    SysTick_Config(SystemCoreClock / 1000); //1 ms
}

/***********************************************************
* Function Name  : RTC_Initialize
* Description    : RTC Clock ve kurulumları burada yapılır.
* Input          : void
* Return         : void
***********************************************************/
static void RTC_Initialize(void)
{
    uint32_t AsynchPrediv = 0, SynchPrediv = 0;

    RTC_InitTypeDef  RTC_InitStructure;

    /* Enable the PWR clock */
    RCC_APB1PeriphClockCmd(RCC_APB1Periph_PWR,ENABLE);

    /* Allow access to RTC */
    PWR_BackupAccessCmd(ENABLE);

#if defined (RTC_CLOCK_SOURCE_LSI)  /* LSI used as RTC source clock*/
    /* The RTC Clock may varies due to LSI frequency dispersion. */
    /* Enable the LSI OSC */
    RCC_LSICmd(ENABLE);

    /* Wait till LSI is ready */
    while(RCC_GetFlagStatus(RCC_FLAG_LSIRDY) == RESET)
    {
    }

    /* Select the RTC Clock Source */
    RCC_RTCCLKConfig(RCC_RTCCLKSource_LSI);

    SynchPrediv = 0x18F;
    AsynchPrediv = 0x63;

#elif defined (RTC_CLOCK_SOURCE_LSE) /* LSE used as RTC source clock */
    /* Enable the LSE OSC */
    RCC_LSEConfig(RCC_LSE_ON);

    /* Wait till LSE is ready */
    while(RCC_GetFlagStatus(RCC_FLAG_LSERDY) == RESET)
    {
    }

    /* Select the RTC Clock Source */
    RCC_RTCCLKConfig(RCC_RTCCLKSource_LSE);

    SynchPrediv = 0xFF;
    AsynchPrediv = 0x7F;

#else
#error Please select the RTC Clock source inside the main.c file
#endif /* RTC_CLOCK_SOURCE_LSI */

    /* Configure the RTC data register and RTC prescaler */
    RTC_InitStructure.RTC_AsynchPrediv = AsynchPrediv;
    RTC_InitStructure.RTC_SynchPrediv = SynchPrediv;
    RTC_InitStructure.RTC_HourFormat = RTC_HourFormat_24;
    // Error flag kontrol edilebilir.
    RTC_Init(&RTC_InitStructure);

    /* Enable the RTC Clock */
    RCC_RTCCLKCmd(ENABLE);

    /* Wait for RTC APB registers synchronisation */
    RTC_WaitForSynchro();

    RTC_TimeStruct.RTC_Hours    = 0x19;
    RTC_TimeStruct.RTC_Minutes  = 0x37;
    RTC_TimeStruct.RTC_Seconds  = 0;

    RTC_DateStruct.RTC_Year     = 0x15;
    RTC_DateStruct.RTC_Month    = 0x04;
    RTC_DateStruct.RTC_Date     = 0x19;

    RTC_SetDate(RTC_Format_BCD,&RTC_DateStruct);
    RTC_SetTime(RTC_Format_BCD,&RTC_TimeStruct);
}

/***********************************************************
* Function Name  : HC164_Send
* Description    : HC164 'e 8 bitlik data yollar
* Input          : uint8_t
* Return         : void
***********************************************************/
void HC164_Send(uint8_t Data)
{
    static uint8_t i;
    for(i=0x01; i>0; i<<=1)
    {
        if(Data&i)
            GPIO_SetBits(GPIOA,HC164_DATA);
        else
            GPIO_ResetBits(GPIOA,HC164_DATA);

        GPIO_SetBits(GPIOA,HC164_CLOCK);
        GPIO_ResetBits(GPIOA,HC164_CLOCK);
    }
}


systick
void SysTick_Handler(void)
{
    //Digit_Scanner(Digit_State);

    if(Digit_State == 4)
        Digit_State=0;
    else
        Digit_State++;
}

baran123

Hala aynı problem devam ediyor.Clock verme sırasında beklememi yapılmalı ?

JOKERAS

void SpiOut(void) {
    char BitIdx = 8; // Bit counter

    do {
        if (val & 0x01) {
            DATA = 1;
        } else {
            DATA = 0;
        }
        CLOCK = 1; 
        CLOCK = 0; 
        val >>= 1;
      
    } while (--BitIdx);
    LATCH_CLOCK = 1;            //74HC595 için
    LATCH_CLOCK = 0;            //74HC595 için
}


74164 ile 74595, bu entegreler aynı diye biliyorum,74595 serisinde latch özelliği var bu şekilde deneyin.
Bence 595 kullanırsanız daha iyi,fifo buffer gibi bir latch var içinde.
Yani ilk olarak 8 bitlik bir datayı shift ediyorsunuz latc'lara yüklüyorsunuz,datayı yükledikten sonra bir clock pulse gönderdiğinizde
Latch'larda yüklenmiş olan data direk çıkış latchlarına aktarılıyor.
OE(Output Enable) ilede extra çıkış bufferlerını açıp kapata biliyorsunuz. 

baran123

Eski kullandığım HC595 fonksiyonunu düzenledim ve şu şekilde çalıştı.Teşekkürler :)
void HC164_Send(uint8_t Data)
{
    static uint8_t i;

    for(i = 0x80; i > 0; i >>= 1)
    {
        if (i&Data)
            GPIO_SetBits(GPIOA,HC164_DATA);
        else
            GPIO_ResetBits(GPIOA,HC164_DATA);

        GPIO_SetBits(GPIOA,HC164_CLOCK);
        GPIO_ResetBits(GPIOA,HC164_CLOCK);
    }
}


mehmet

Yalnız latch olmadığı için seri veri yollanırken çıkışlarda
bu bilgiler direk görünür.
Olan olmuştur,
olacak olan da olmuştur.
Olacak bir şey yoktur.
---------------------------------------------
http://www.mehmetbilgi.net.tr