GPIOC->ODR=0x0015; şeklinde bir porta nasıl veri yazılıyor ?

Başlatan DigitalMan, 30 Haziran 2017, 22:12:26

DigitalMan

Arkadaşlar Stm32 serisi mikro denetleyiciler için HAL kütüphaneleri var biliyorsunuz. Bu kütüphanelerin içinde başlıkta verdiğim gibi

GPIOC->ODR=0x0015;


benzer ifadeler var. Anlaşıldığı üzere GPIOC adında yapı (struct) tipinde bir pointer üzerinde IDR , ODR , BSR, BSSR vs. gibi registerlere erişiliyor. ben buna benzer birşeyi pic üzerinde yapmayı istiyorum. aslında yapı ve pointer lerin birlikte kullanımını iyice öğrenmek istiyorum. yukarıda yazdığım kod örneğine benzer şekilde PORTLAR adında bir yapı oluştursak ve bu yapının alt elemanlrı da PORTA, PORTB, PORTC, PORTD olsa, bu yapıdan "port" adında işaretçi tipinde bir referans tanımlasak ve bu referans üzerinden

port->PORTA = 5;


şeklinde PORTA ya veri yazabilsek. ben bir türlü bunu  yapamadım. aslında yapıların pointer ile birlikte kullanımını internetten araştırdım. fakat bu HAL kütüphanelerindeki gibi kullanım şeklinin nasıl yapıldığına dair bir bilgi bulamadım. Bir yapının her bir elemanı üzerinden bir porta veri yazıp okuma ile ilgili yapı tanımlaması nasıl yapılır. bilgisi olan arkadaşlardan yardım bekliyorum. aslında benim problemim yapı alt elemanlarının herbirine tanımlarken port adreslerini atamak. işte bunu yapamıyorum.

atomx

typedef struct foo
{
  unsigned int boo;
} __attribute((packed))__ Foo;


Foo* item = (Foo*)(0x3231);



Yapısını kullanabilirsin. İş tamamen pointer.
Hüseyin TECER

furkanyx

#define FLASH_BASE            ((uint32_t)0x08000000) /*!< FLASH base address in the alias region */
#define SRAM_BASE             ((uint32_t)0x20000000) /*!< SRAM base address in the alias region */
#define PERIPH_BASE           ((uint32_t)0x40000000) /*!< Peripheral base address in the alias region */

#define SRAM_BB_BASE          ((uint32_t)0x22000000) /*!< SRAM base address in the bit-band region */
#define PERIPH_BB_BASE        ((uint32_t)0x42000000) /*!< Peripheral base address in the bit-band region */

#define FSMC_R_BASE           ((uint32_t)0xA0000000) /*!< FSMC registers base address */

/*!< Peripheral memory map */
#define APB1PERIPH_BASE       PERIPH_BASE
#define APB2PERIPH_BASE       (PERIPH_BASE + 0x10000)
#define AHBPERIPH_BASE        (PERIPH_BASE + 0x20000)

#define TIM2_BASE             (APB1PERIPH_BASE + 0x0000)
#define TIM3_BASE             (APB1PERIPH_BASE + 0x0400)
#define TIM4_BASE             (APB1PERIPH_BASE + 0x0800)
#define TIM5_BASE             (APB1PERIPH_BASE + 0x0C00)
#define TIM6_BASE             (APB1PERIPH_BASE + 0x1000)
#define TIM7_BASE             (APB1PERIPH_BASE + 0x1400)
#define TIM12_BASE            (APB1PERIPH_BASE + 0x1800)
#define TIM13_BASE            (APB1PERIPH_BASE + 0x1C00)
#define TIM14_BASE            (APB1PERIPH_BASE + 0x2000)
#define RTC_BASE              (APB1PERIPH_BASE + 0x2800)
#define WWDG_BASE             (APB1PERIPH_BASE + 0x2C00)
#define IWDG_BASE             (APB1PERIPH_BASE + 0x3000)
#define SPI2_BASE             (APB1PERIPH_BASE + 0x3800)
#define SPI3_BASE             (APB1PERIPH_BASE + 0x3C00)
#define USART2_BASE           (APB1PERIPH_BASE + 0x4400)
#define USART3_BASE           (APB1PERIPH_BASE + 0x4800)
#define UART4_BASE            (APB1PERIPH_BASE + 0x4C00)
#define UART5_BASE            (APB1PERIPH_BASE + 0x5000)
#define I2C1_BASE             (APB1PERIPH_BASE + 0x5400)
#define I2C2_BASE             (APB1PERIPH_BASE + 0x5800)
#define CAN1_BASE             (APB1PERIPH_BASE + 0x6400)
#define CAN2_BASE             (APB1PERIPH_BASE + 0x6800)
#define BKP_BASE              (APB1PERIPH_BASE + 0x6C00)
#define PWR_BASE              (APB1PERIPH_BASE + 0x7000)
#define DAC_BASE              (APB1PERIPH_BASE + 0x7400)
#define CEC_BASE              (APB1PERIPH_BASE + 0x7800)

#define AFIO_BASE             (APB2PERIPH_BASE + 0x0000)
#define EXTI_BASE             (APB2PERIPH_BASE + 0x0400)
#define GPIOA_BASE            (APB2PERIPH_BASE + 0x0800)
#define GPIOB_BASE            (APB2PERIPH_BASE + 0x0C00)
#define GPIOC_BASE            (APB2PERIPH_BASE + 0x1000)
#define GPIOD_BASE            (APB2PERIPH_BASE + 0x1400)
#define GPIOE_BASE            (APB2PERIPH_BASE + 0x1800)
#define GPIOF_BASE            (APB2PERIPH_BASE + 0x1C00)
#define GPIOG_BASE            (APB2PERIPH_BASE + 0x2000)
#define ADC1_BASE             (APB2PERIPH_BASE + 0x2400)
#define ADC2_BASE             (APB2PERIPH_BASE + 0x2800)
#define TIM1_BASE             (APB2PERIPH_BASE + 0x2C00)
#define SPI1_BASE             (APB2PERIPH_BASE + 0x3000)
#define TIM8_BASE             (APB2PERIPH_BASE + 0x3400)
#define USART1_BASE           (APB2PERIPH_BASE + 0x3800)
#define ADC3_BASE             (APB2PERIPH_BASE + 0x3C00)
#define TIM15_BASE            (APB2PERIPH_BASE + 0x4000)
#define TIM16_BASE            (APB2PERIPH_BASE + 0x4400)
#define TIM17_BASE            (APB2PERIPH_BASE + 0x4800)
#define TIM9_BASE             (APB2PERIPH_BASE + 0x4C00)
#define TIM10_BASE            (APB2PERIPH_BASE + 0x5000)
#define TIM11_BASE            (APB2PERIPH_BASE + 0x5400)


Buradaki tanımları kendine göre değiştirerek iş yapabilirsin. Yani stm32f103 için düşünürsek memory map de zaten bu tanımlar mevcut hangi adreste neye erişebileceğini görebilirsin. Bundan sonra yapman gereken struct oluşturmak.

DigitalMan

cevap veren arkadaşlara çok teşekkür ediyorum. ben kendi çabam ile şöyle birşey yaptım ve sanırım istediğim oldu.

#include <xc.h>

struct Portlar{
    unsigned char A;
    unsigned char B;
    unsigned char C;
    unsigned char D;
};

/*
yada böyle....
struct Portlar{
    unsigned  A: 8;
    unsigned  B: 8;
    unsigned  C: 8;
    unsigned  D: 8;
};
*/

struct Portlar *port = 0xf80; //yapı başlangıç adresi

void main(void){
    
    ADCON1 = 0X07; //tüm portlar digital
    TRISA = TRISB = TRISC = TRISD = 0X00; //tüm portlar çıkış
    PORTA = PORTB = PORTC = PORTD = 0X00; //portlar sıfırlanıyor
    
    port->B = 0x80; //portb ye 0x80 değeri yazılıyor.
    
    for(;;);
}


Bu şekilde tam da istediğim gibi çalışıyor. Fakat bir ayrıntı var. Burada yapının her elemanı üzerinden portlara erişim sağlayacağımız için portların adresleri peş peşe olmalı. pic18f452 için port adresleri 0xf80 den başlıyor ve B,C,D port adresleri de 0xf81,0xf82,0xf83 şeklinde devam ediyor. Peki yapının her alt elemanından birbirini takip etmeyen portlara yada registerlere erişmeyi istesek nasıl olacak. yapının her elemanına nasıl tek tek adres atayabiliriz.

Erhan YILMAZ

Rezerve edersin. Sıraları değişmez.

/** \brief  Structure type to access the Nested Vectored Interrupt Controller (NVIC).
 */
typedef struct
{
  __IO uint32_t ISER[8];                 /*!< Offset: 0x000 (R/W)  Interrupt Set Enable Register           */
       uint32_t RESERVED0[24];
  __IO uint32_t ICER[8];                 /*!< Offset: 0x080 (R/W)  Interrupt Clear Enable Register         */
       uint32_t RSERVED1[24];
  __IO uint32_t ISPR[8];                 /*!< Offset: 0x100 (R/W)  Interrupt Set Pending Register          */
       uint32_t RESERVED2[24];
  __IO uint32_t ICPR[8];                 /*!< Offset: 0x180 (R/W)  Interrupt Clear Pending Register        */
       uint32_t RESERVED3[24];
  __IO uint32_t IABR[8];                 /*!< Offset: 0x200 (R/W)  Interrupt Active bit Register           */
       uint32_t RESERVED4[56];
  __IO uint8_t  IP[240];                 /*!< Offset: 0x300 (R/W)  Interrupt Priority Register (8Bit wide) */
       uint32_t RESERVED5[644];
  __O  uint32_t STIR;                    /*!< Offset: 0xE00 ( /W)  Software Trigger Interrupt Register     */
}  NVIC_Type;