Picproje Elektronik Sitesi

MİKRODENETLEYİCİLER => ARM => Cortex ARM => Konuyu başlatan: mcan - 24 Kasım 2011, 22:58:14

Başlık: Cortex-m3m4 çalışan kütüphane-driver Kodları
Gönderen: mcan - 24 Kasım 2011, 22:58:14
Selam burada ,arm cortex için yazdığım-bulduğum çalıştırıp denediğim kütüphane-driver tarzındaki kodları paylaşmayı planlıyorum.ccs  den alıntısını yapıp keilde cortex m3 için uyarladığım "karakter lcd" kodunu kullanabilirsiniz.
Nette bulabileceğiniz flexy lcd tarzdaki kodlara benziyor tek flexy olmayan yanı data pinlerini kendi içinde ayrı ayrı tanımlanamıyor.Aslında koda bakıp o kısmını değiştirebilirsiniz ancak hızlı deneme yapmak için bu kadarını yazdım...

Lcd_d.c
#ifndef Lcd_Rs_Port
#define Lcd_Rs_Port GPIOB_BASE
#define Lcd_Rs_Pin 9
#define Lcd_Rw_Port GPIOB_BASE
#define Lcd_Rw_Pin 10
#define Lcd_Enable_Port GPIOB_BASE
#define Lcd_Enable_Pin 11
#define Lcd_Data_Port GPIOB_BASE
#define Lcd_Data_Pin1 12
#endif


#define ODR_ 0x0C //GPIO output register
#define IDR_ 0x08 //GPIO input  register
#define CR_ 0x00 //GPIO Mode  register

#define Lcd_Data_InPort (Lcd_Data_Port+IDR_ )
#define Lcd_Data_OutPort (Lcd_Data_Port+ODR_ )

#define BIT_LEVEL_SRAM(a,b) ((SRAM_BB_BASE + (a-SRAM_BASE)*32 + (b*4)))
#define BIT_LEVEL_PERI(a,b) ((PERIPH_BB_BASE + (a-PERIPH_BASE)*32 + (b*4)))

#define Lcd_Rw *((volatile unsigned int *)(BIT_LEVEL_PERI((Lcd_Rw_Port+ODR_),Lcd_Rw_Pin))) //Bitband access rw pin
#define Lcd_Rs *((volatile unsigned int *)(BIT_LEVEL_PERI((Lcd_Rs_Port+ODR_),Lcd_Rs_Pin))) //Bitband access rs pin
#define Lcd_Enable *((volatile unsigned int *)(BIT_LEVEL_PERI((Lcd_Enable_Port+ODR_),Lcd_Enable_Pin))) //Bitband access enable pin

   
typedef struct{
int     : Lcd_Data_Pin1; // on to an I/O port to gain
    int data_pins : 4;          // access to the LCD pins.

} LCD_X ;
 
typedef struct{             
__IO uint32_t : Lcd_Data_Pin1*4; //o
__IO    uint32_t data_pins : 16;          // access to the LCD data pins mode.
} LCD_Data_mode ;

typedef struct{             
__IO uint32_t : Lcd_Rs_Pin*4; // o
__IO    uint32_t mode : 4;          // access to the LCD Rs pins.
} LCD_Rs_ ;

typedef struct{             
__IO uint32_t : Lcd_Rw_Pin*4; // o
__IO    uint32_t mode : 4;          // access to the LCD pins.
} LCD_Rw_ ;

typedef struct{             
__IO uint32_t : Lcd_Enable_Pin*4;         // on to an I/O port to gain
__IO    uint32_t mode : 4;         // access to the LCD pins.
} LCD_Enable_ ;

void delay_us(unsigned int);

#define Lcd_Out ((LCD_X *)(Lcd_Data_OutPort))
#define Lcd_In ((LCD_X *)(Lcd_Data_InPort))
#define Lcd_Mode ((LCD_Data_mode *)(Lcd_Data_Port+CR_))
#define Lcd_Rs_mode ((LCD_Rs_ *)(Lcd_Rs_Port+CR_))
#define Lcd_Rw_mode ((LCD_Rw_ *)(Lcd_Rw_Port+CR_))
#define Lcd_Enable_mode ((LCD_Enable_ *)(Lcd_Enable_Port+CR_))

#define All_input 0x4444 //Data pins input setting
#define All_output 0x3333 //Data pins output 50Mhz setting
#define Pin_output 0x3 //X pins output 50Mhz setting
#define delay_cycles(x) delay_us(x)

#define lcd_type 2           // 0=5x7, 1=5x10, 2=2 lines
#define lcd_line_two 0x40    // LCD RAM address for the second line



char const LCD_INIT_STRING[4] = {0x20 | (lcd_type << 2), 0xc, 1, 6};// These bytes need to be sent to the LCD to start it up.




char lcd_read_byte() {
char low=0,high=0;
Lcd_Mode->data_pins = All_input; //set_tris_lcd(LCD_READ);
    Lcd_Rw = 1;
delay_cycles(1);
    Lcd_Enable = 1;
delay_cycles(1);
    high = Lcd_In->data_pins;
    Lcd_Enable = 0;
delay_cycles(1);
    Lcd_Enable = 1;
    delay_us(1);
    low = Lcd_In->data_pins;
    Lcd_Enable = 0;
Lcd_Mode->data_pins = All_output;
    return( (high<<4) | low);
}


void lcd_send_nibble( char n ) {
Lcd_Out->data_pins = n ;
delay_cycles(1);
    Lcd_Enable = 1;
    delay_us(2);
    Lcd_Enable = 0;
}


void lcd_send_byte( char address, char n ) {

char lcd_timeout = 0;

Lcd_Rs = 0;
    while ( (lcd_read_byte()&0x80) )
    {
if(lcd_timeout>10)
        break;
        else
            lcd_timeout++;
         
    }
    Lcd_Rs = address;
delay_cycles(1);
    Lcd_Rw = 0;
delay_cycles(1);
    Lcd_Enable = 0;
    lcd_send_nibble(n >> 4);
    lcd_send_nibble(n & 0xf);
}


void lcd_init(void) {
char i;
Lcd_Mode->data_pins = All_output;
Lcd_Rs_mode->mode = Pin_output;
Lcd_Rw_mode->mode = Pin_output;
Lcd_Enable_mode->mode = Pin_output;

    Lcd_Rs = 0;
    Lcd_Rw = 0;
    Lcd_Enable = 0;
    delay_us(15000);
    for(i=1;i<=3;++i) {
       lcd_send_nibble(3);
       delay_us(5000);
    }
    lcd_send_nibble(2);
    for(i=0;i<=3;++i)
       lcd_send_byte(0,LCD_INIT_STRING[i]);
}


void lcd_gotoxy( char x, char y) {
   char address;

   if(y!=1)
     address=lcd_line_two;
   else
     address=0;
   address+=x-1;
   lcd_send_byte(0,0x80|address);
}

int lcd_putc( char c) {
   switch (c) {
     case '\f'   : lcd_send_byte(0,1);
                   delay_us(2000);
                                           break;
     case '\n'   : lcd_gotoxy(1,2);        break;
     case '\b'   : lcd_send_byte(0,0x10);  break;
     default     : lcd_send_byte(1,c);     break;
   }
   return(0);
}


char lcd_getc( char x, char y) {
   char value;

lcd_gotoxy(x,y);
    while ( (lcd_read_byte()&0x80) ); // wait until busy flag is low
    Lcd_Rs =1;
    value = lcd_read_byte();
    Lcd_Rs =0;
    return(value);
}


Kodu denemek için örnek program kodu,
#include "STM32F10x.h"
#include <stdio.h>
//#include "Registers.h"
#include "Lcd_d.c"
#include "Retarget.c"


static int ih;
int zg,ipb,ii;


void TIM7_IRQHandler(void)
{
    ih =!ih ;

    while(TIM7->SR)
    {
        TIM7->SR  = 0x0;
    }
   
}

void delay_us(unsigned int i)
{   unsigned int z,y;
    for(z=0;z<i;z++)
{
for(y=0;y<8;)
{
y++;
}
}
}

void delay_zs(unsigned int i)
{   unsigned int z,y;
    for(z=0;z<i;z++)
{
for(y=0;y<5;)
{
y++;
}
}   
}

void SystemInit (void)
{
    delay_zs(88000);
RCC->APB2ENR |= 0x00000018;    // GPIOD donaniminin clock sinyalini uygulayalim
    GPIOC->CRL = 0x37333333;     // GPIOD nin 15, 14, 13, 12 pinleri cikis tanimlandi (Ledler bu pinlerde)
    GPIOC->CRH = 0x33333333;

    RCC->CR |= 0x0010000;     // HSE ON
    RCC->CFGR = 0x001D0000;     // PLL ayarla
    RCC->CR  |= 0x001000000;     // PLL aç
    FLASH->ACR =  0x32; // Flash gecikme ayari
    RCC->CFGR = 0x001D0702;     // SINYAL KAYNAGI PLL APB1 HCLK/16

    RCC->APB1ENR |= 0x00000020;     //Timer7 ye clock verelim
    TIM7->DIER = 0x1;
    TIM7->PSC = 0x1FF;   //182=B6  182*5= H393
    TIM7->ARR = 0xFFFF;
    TIM7->CR1  = 0x85;
NVIC->ISER[1] = 0X00800000;        // NVIC de Timer 7 interrupta izin verelim

}
                                                                                                           



int main()
{
lcd_init();
lcd_putc('\f');
printf("\fOldu sonunda\nTesekkurler");

    while(1)
   {
     if(ih)
      GPIOC->ODR= 0x00000200; //GPIOC->ODR= 0x20;     // Ledler yansin
     else
        GPIOC->ODR= 0x00000020; //GPIOC->ODR= 0x200;     // Ledler yansin
     delay_us(250000);
     GPIOC->ODR= 0x00000000;     // Ledler sonsun
     delay_us(250000);
   }
}


Delay_us tam olarak çalışmıyordur çünki telefonun kronometresi ile kalibre etmeye çalıştım.
Ayrıca printf için şu koda ihtiyacınız olacak ,yardımından dolayı özellikle @Gerbay a teşekkürler.

Retarget.c
struct __FILE{
char c;
};

FILE __stdout; // linker hatasi vermemesi icin gerekli
FILE __stdin;
FILE __stderr;

int fputc(int ch, FILE *f)
{
  return (lcd_putc((char)ch));
}

int ferror(FILE *f)
{
  // ...
  return EOF;
}

/*void _ttywrch(int ch)
{
  lcd_putc(ch);
}

void _sys_exit(int return_code)
{
  label:  goto label;  // sonsuz döngü
} */


Kütüphanede kullanılan lcd pinlerini değiştirmek için

    #define Lcd_Rs_Port      GPIOB_BASE
    #define Lcd_Rs_Pin      9
    #define Lcd_Rw_Port      GPIOB_BASE
    #define Lcd_Rw_Pin      10
    #define Lcd_Enable_Port   GPIOB_BASE
    #define Lcd_Enable_Pin   11
    #define Lcd_Data_Port   GPIOB_BASE
    #define Lcd_Data_Pin1   12
Kısmını istediğiniz port ve pine göre tanımlayın. LCD data pinlerinin ilki 12. GPIOB pinine denk geliyor, Yani 12-13-14-15 LCD data pinleri ,  lcd rs pini ise 9. pin. Ayrıca eğer lcd 5v ile çalıyorsa portu  ve pinleri tanımlarken pinlerin 5 volt toleranslı olmasına dikkat edin .
Başlık: Cortex-m3m4 çalışan kütüphane-driver Kodları
Gönderen: mcan - 26 Kasım 2011, 02:09:59
Bu gun iki dosyayi daha uyarladim, one wire iletisim ve ds18b20 kodlari...

One wire.c
#define onewire_Port GPIOB_BASE //portu pini burda
#define onewire_Pin 5                   // tanimliyoruz

#define ODR_ 0x0C
#define IDR_ 0x08
#define CR_ 0x00

#define onewire_Data_In (onewire_Port+IDR_)
#define onewire_Data_Out (onewire_Port+ODR_)

#define BIT_LEVEL_SRAM(a,b) ((SRAM_BB_BASE + (a-SRAM_BASE)*32 + (b*4)))
#define BIT_LEVEL_PERI(a,b) ((PERIPH_BB_BASE + (a-PERIPH_BASE)*32 + (b*4)))

typedef struct{             
__IO uint32_t : onewire_Pin*4;
__IO    uint32_t pin : 4;         
} onewire_mode ;

#define ONE_WIRE_INPUT *((volatile unsigned int *)(BIT_LEVEL_PERI(onewire_Data_In,onewire_Pin)))
#define ONE_WIRE_OUTPUT *((volatile unsigned int *)(BIT_LEVEL_PERI(onewire_Data_Out,onewire_Pin)))
#define ONE_WIRE_MODE (*((onewire_mode *)(onewire_Port+CR_))).pin

#define PushPull_out50Mhz  3
#define Float_in  4

/*#define ONE_WIRE_INPUT PortB.Input.Pin5
#define ONE_WIRE_OUTPUT PortB.Output.Pin5
#define ONE_WIRE_MODE PORTB.Mode.Pin5  */
/*******************1-wire communication functions********************/

/************onewire_reset*************************************************/
/*This function initiates the 1wire bus */
/* */
/*PARAMETERS: */
/*RETURNS: */
/*********************************************************************/

void onewire_reset()  // OK if just using a single permanently connected device
{
ONE_WIRE_OUTPUT = 0 ;
ONE_WIRE_MODE = PushPull_out50Mhz;
delay_us( 500 ); // pull 1-wire low for reset pulse 500
ONE_WIRE_MODE = Float_in; // float 1-wire high
delay_us( 500 ); // wait-out remaining initialisation window. 500
ONE_WIRE_MODE = Float_in;
}

/*********************** onewire_write() ********************************/
/*This function writes a byte to the sensor.*/
/* */
/*Parameters: byte - the byte to be written to the 1-wire */
/*Returns: */
/*********************************************************************/



void onewire_write(char data)
{
char count;

for (count=0; count<8; ++count)
{
ONE_WIRE_OUTPUT = 0 ;
ONE_WIRE_MODE = PushPull_out50Mhz; 
  delay_us( 2 ); // pull 1-wire low to initiate write time-slot. 2
ONE_WIRE_OUTPUT = (data&0x01);
data >>= 1;
  delay_us( 60 ); // wait until end of write slot. 60
  ONE_WIRE_MODE = Float_in;
  delay_us( 2 ); // for more than 1us minimum. 2
}
}
/*********************** read1wire() *********************************/
/*This function reads the 8 -bit data via the 1-wire sensor. */
/* */
/*Parameters: */
/*Returns: 8-bit (1-byte) data from sensor */
/*********************************************************************/

char onewire_read()
{
char count, data=0;

for (count=0; count<8; ++count)
{
  ONE_WIRE_OUTPUT = 0 ;
ONE_WIRE_MODE = PushPull_out50Mhz;
  delay_us( 2 ); // pull 1-wire low to initiate read time-slot. 2
  ONE_WIRE_MODE = Float_in;
data>>=1;
  delay_us( 18 ); // let device state stabilise, 8
if ( ONE_WIRE_INPUT==1)
data |= 0x80;
  delay_us( 60 ); // wait until end of read slot. 120
}

return( data );
}



Bu dosya ise basit bicimde sicaklik okumak icin
Ds18b20.c
#define High(v) (*(((unsigned char *) (&v)+ 1)))
#define Low(v) (*((unsigned char *) (&v)))


float ds1820_read(void)
{
signed short temp3;
float result;

onewire_reset();
onewire_write(0xCC);
onewire_write(0x44);

while (temp3 == 0)
  temp3 = onewire_read();

onewire_reset();
onewire_write(0xCC);
onewire_write(0xBE);
Low(temp3) = onewire_read();
High(temp3) = onewire_read();

//result = (float) temp3 / 2.0;   //Calculation for DS18S20 with 0.5 deg C resolution
result = (float) temp3 / 16.0;  //Calculation for DS18B20 with 0.1 deg C resolution
return(result);
}


Ornek ;
main c
#include "STM32F10x.h"
#include <stdio.h>
#include "Registers.h"
#include "Lcd_d.c"
#include "Retarget.c"
#include "one_wire.c"
#include "DS1820_.c"


static int ih;

void TIM7_IRQHandler(void)
{

    ih =!ih ;

    while(TIM7->SR)
    {
        TIM7->SR  = 0x0;
    }
   
}

void delay_us(unsigned int i)
{   unsigned int z,y;
    for(z=0;z<i;z++)
{
for(y=0;y<8;)
{
y++;
}
}
}

void delay_zs(unsigned int i)
{   unsigned int z,y;
    for(z=0;z<i;z++)
{
for(y=0;y<5;)
{
y++;
}
}   
}

void SystemInit (void)
{
    delay_zs(88000);
RCC->APB2ENR |= 0x00000018;    // GPIOD donaniminin clock sinyalini uygulayalim
    GPIOC->CRL = 0x37333333;     // GPIOD nin 15, 14, 13, 12 pinleri cikis tanimlandi (Ledler bu pinlerde)
    GPIOC->CRH = 0x33333333;

    RCC->CR |= 0x0010000;     // HSE ON
    RCC->CFGR = 0x001D0000;     // PLL ayarla
    RCC->CR  |= 0x001000000;     // PLL aç
    FLASH->ACR =  0x32; // Flash gecikme ayari
    RCC->CFGR = 0x001D0702;     // SINYAL KAYNAGI PLL APB1 HCLK/16

    RCC->APB1ENR |= 0x00000020;     //Timer7 ye clock verelim
    TIM7->DIER = 0x1;
    TIM7->PSC = 0x1FF;   //182=B6  182*5= H393
    TIM7->ARR = 0xFFFF;
    TIM7->CR1  = 0x85;
//NVIC->ISER[1] = 0X00800000;        // NVIC de Timer 7 interrupta izin verelim

}
                                                                                                           


int main()
{
char ss=0;
lcd_init();

    while(1)
   {
    ss++;
     if(ih)
      GPIOC->ODR= 0x00000200; //GPIO->ODR= 0x20;     // Ledler yansin
     else
        GPIOC->ODR= 0x00000020; //GPIO->ODR= 0x200;     // Ledler yansin
     delay_us(250000);
     GPIOC->ODR= 0x00000000;     // Ledler sonsun
     delay_us(250000);

if(ss==3)
{
printf("\fTemp:%f3.1",ds1820_read());
ss=0 ;
}
   }
}


CortexM4 icin kitler geldiginde uyarlamaya calisicam.