Haberler:

Eposta uyarılarını yanıtlamayınız ( ! ) https://bit.ly/2J7yi0d

Ana Menü

stm32 ds1302

Başlatan EMP_Otto, 20 Temmuz 2014, 18:13:10

EMP_Otto

Merhaba arkadaşlar stm32 icin ds1302 kütüphanesi lazım  netten baktımda işe yarar birşey bulamadım.Elinde olan paylaşırsa çok makbule geçer.
Bu işler zordur,özveri ister...

NaMcHo

dsc1302.h
//#include <stm32f4xx.h>
//#include <stm32f4xx_gpio.h>
#include <stm32f10x.h>
#include <stm32f10x_gpio.h>

//Designed by NaMcHo V1000
/*
	Komut byte'nin 0. biti RD/WR'dir bit0 = 0 ise yazma
*/
//Bu birlik komutlari yazmaya gore verilmistir
//Okumak icin bit0 = 1 yapilmali

#define XTAL 72					//MHz
//Pin tanimlamalari

#define SCLK_Set				GPIOC->BSRRL = 0x0001
#define SCLK_Reset			GPIOC->BSRRH = 0x0001
#define DATA_Out_Set		GPIOC->BSRRL = 0x0002
#define DATA_Out_Reset 	GPIOC->BSRRH = 0x0002
#define DATA_Read				(((GPIOC->IDR) >> 1) & 0x0001)
#define CE(x)						(x == SET) ? GPIOC->BSRRL = 0x0004 : GPIOC->BSRRH = 0x0004	//Olmadi bu
#define CE_Set					GPIOC->BSRRL = 0x0004
#define CE_Reset				GPIOC->BSRRH = 0x0004

#define SET 					1
#define RESET 				0

#define IN 						0
#define OUT 					1

#define _24						1
#define _12						0

//Süreler, Biraz fazladan yazdim systick', 1usn'den daha sık araliklarla kesmeye sokmamak icin
#define tcl 		5*XTAL			//usn
#define	tcc			4*XTAL			//usn
#define tdc			1*XTAL			//usn
#define tcdh		1*XTAL			//usn
#define tr			2*XTAL
#define tf			2*XTAL
#define tcwh		4*XTAL			//1 byte data yazdiktan sonra CE'nin sifirda tutulmasi gereken süre
#define tcdd		1*XTAL

typedef enum Ds1302{second=0x80, minute=0x82, hour=0x84, date=0x86, month=0x88, year=0x8C,
										day=0x8A, addressWP=0x8E, DS1302_WR_ADD_TC=0x90, ram}DS1302_WR_ADD;

typedef struct Clock{
	uint8_t sec;
	uint8_t min;
	uint8_t hour;
}Clock_Type;

typedef struct Calendar{
	uint8_t date;
	uint8_t month;
	uint16_t year;
}Calendar_Type;
//Saat ve tarih bilgisinin tutuldugu ekrana baslamak icin kullanilcak
typedef struct Time{
	Clock_Type *clk;
	Calendar_Type *cldr;
}Time_Type;

extern uint8_t GetSeconds(void);
extern uint8_t GetMinutes(void);
extern uint8_t GetHours(void);
extern uint8_t GetDate(void);
extern uint8_t GetMonth(void);
extern uint16_t GetYear(void);

extern void SetSeconds(uint8_t sec);
extern void SetMinutes(uint8_t min);
extern void SetHours(uint8_t hours);
extern void SetDate(uint8_t day);
extern void SetMonth(uint8_t mo);
extern void SetYear(uint16_t yea);
extern void SetDay(uint8_t days);

extern void DS1302Enable(void);
extern void DS1302Disable(void);

extern void WaitForNextByte(void);
extern uint16_t GetBitOfByte(uint8_t byte, uint16_t whichBit);
extern void MakeByteFromBits(uint8_t *byte, uint16_t whichBit, uint16_t valueOfBit);
extern void DataPinConfig(uint16_t direction);
extern void Delay(uint16_t delay);
extern void ConvertBCDToDec(uint8_t *convert);
extern void WriteByte(uint8_t byte);
extern uint8_t GetByte(void);
extern void DS1302Init(uint16_t hourType);
extern void DS1302WriteProtect(FunctionalState func);
extern void DS1302Trickle(FunctionalState func);
extern uint8_t ConvertToBCD(uint16_t decimal);


dsc1302.c
#include "ds1302.h"
#include "main.h"
#include "global.h"

uint16_t GetBitOfByte(uint8_t byte, uint16_t whichBit){
	uint16_t temp;
	temp = byte >> whichBit;
	temp = temp & 0x01;
	return temp;
}

void MakeByteFromBits(uint8_t *byte, uint16_t whichBit, uint16_t valueOfBit){
	(*byte) |= (valueOfBit << whichBit);
}
/*

*/
void DataPinConfig(uint16_t direction){
	GPIO_InitTypeDef gx;

	if(direction == IN){
		gx.GPIO_Pin = GPIO_Pin_1;
		gx.GPIO_Mode = GPIO_Mode_IN;
		gx.GPIO_PuPd = GPIO_PuPd_DOWN;
	}
	else{
		gx.GPIO_Pin = GPIO_Pin_1;
		gx.GPIO_Mode = GPIO_Mode_OUT;
		gx.GPIO_PuPd = GPIO_PuPd_NOPULL;
		gx.GPIO_OType = GPIO_OType_PP;
	}
	GPIO_Init(GPIOC,&gx);
}
/*
  Islev: saniye bilgisi ds1302'den alinir
	Parametreler: yok
	Not:
*/
uint8_t GetSeconds(){
	uint8_t command = second | 0x01;	//okuma
	uint8_t sec=0;

	DS1302Enable();
	//Komutu yolla
	WriteByte(command);
	sec=GetByte();
	DS1302Disable();
	ConvertBCDToDec(&sec);
	return sec;
}
/*

*/
uint8_t GetMinutes(){
	uint8_t command = minute | 0x01;	//okuma
	uint8_t min=0;

	DS1302Enable();
	//Komutu yolla
	WriteByte(command);
	min=GetByte();

	DS1302Disable();
	ConvertBCDToDec(&min);
	return min;
}
/*

*/
uint8_t GetHours(){
	uint8_t command = hour | 0x01;	//okuma
	uint8_t hours=0;

	DS1302Enable();
	//Komutu yolla
	WriteByte(command);
	hours=GetByte();

	DS1302Disable();
	ConvertBCDToDec(&hours);
	return hours;
}
/*

*/
uint8_t GetDate(void){
	uint8_t command = date | 0x01;	//okuma
	uint8_t dates=0;

	DS1302Enable();
	//Komutu yolla
	WriteByte(command);
	dates=GetByte();

	DS1302Disable();
	ConvertBCDToDec(&dates);
	return dates;
}
/*

*/
uint8_t GetMonth(void){
	uint8_t command = month | 0x01;	//okuma
	uint8_t months=0;

	DS1302Enable();
	//Komutu yolla
	WriteByte(command);
	months=GetByte();

	DS1302Disable();
	ConvertBCDToDec(&months);
	return months;
}
/*

*/
uint16_t GetYear(void){
	uint8_t command = year | 0x01;	//okuma
	uint8_t years=0;

	DS1302Enable();
	//Komutu yolla
	WriteByte(command);
	years=GetByte();

	DS1302Disable();
	ConvertBCDToDec(&years);
	return years+2000;
}
/*

*/
void SetSeconds(uint8_t sec){
	uint8_t command = second;		//Yazma komutu
	uint8_t bcdSec;
	sec &= 0x7F;								//CH'yi her ihtimale karsi 0 layalim
	bcdSec = ConvertToBCD(sec);
	DS1302Enable();
	WriteByte(command);
	WriteByte(bcdSec);
	DS1302Disable();
}
/*

*/
void SetMinutes(uint8_t min){
	uint8_t command = minute;		//Yazma komutu
	uint8_t bcdMin;
	bcdMin = ConvertToBCD(min);
	DS1302Enable();
	WriteByte(command);
	WriteByte(bcdMin);
	DS1302Disable();
}
/*

*/
void SetHours(uint8_t hours){
	uint8_t command = hour;		//Yazma komutu
	uint8_t bcdHour;
	bcdHour = ConvertToBCD(hours);
	DS1302Enable();
	WriteByte(command);
	WriteByte(bcdHour);
	DS1302Disable();
}
/*

*/
void SetDate(uint8_t day){
	uint8_t command = date;		//Yazma komutu
	uint8_t bcdDate;
	bcdDate = ConvertToBCD(day);
	DS1302Enable();
	WriteByte(command);
	WriteByte(bcdDate);
	DS1302Disable();
}
/*

*/
void SetMonth(uint8_t mo){
	uint8_t command = month;		//Yazma komutu
	uint8_t bcdMonth;
	bcdMonth = ConvertToBCD(mo);
	DS1302Enable();
	WriteByte(command);
	WriteByte(bcdMonth);
	DS1302Disable();
}
/*

*/
void SetYear(uint16_t yea){
	uint8_t command = year;							//Yazma komutu
	uint8_t yearOnlar;
	uint8_t bcdYear;

	yearOnlar = yea % 100;
	bcdYear = ConvertToBCD(yearOnlar);

	DS1302Enable();
	WriteByte(command);
	WriteByte(bcdYear);
	DS1302Disable();
}
/*

*/
void SetDay(uint8_t days){
	uint8_t command = day;		//Yazma komutu
	uint8_t bcdDay;
	bcdDay = ConvertToBCD(days);
	DS1302Enable();
	WriteByte(command);
	WriteByte(bcdDay);
	DS1302Disable();
}
void DS1302Enable(void){
	GPIO_ResetBits(GPIOC,GPIO_Pin_0);
	//CE_Set;
	GPIO_SetBits(GPIOC,GPIO_Pin_2);
	Delay(tr);
	//Delay(168);

}

void DS1302Disable(void){
	//CE_Reset;
	GPIO_ResetBits(GPIOC,GPIO_Pin_2);
	//Delay(168);
	Delay(tr);
}

//168MHz calismada 168 yazinca yaklasik 1usn delay
void Delay(uint16_t delay){
	while(delay--);
}

//BCD dönusturucu
void ConvertBCDToDec(uint8_t *convert){
	uint16_t temp = (*convert),temp1,temp2;
	temp1 = temp >> 4;
	switch(temp1){
		case 0:
			temp1 = 0;
			break;
		case 1:
			temp1 = 10;
			break;
		case 2:
			temp1 = 20;
			break;
		case 3:
			temp1 = 30;
			break;
		case 4:
			temp1 = 40;
			break;
		case 5:
			temp1 = 50;
			break;
		default:
			temp1 = 0;
			break;
	}

	temp2 = temp & 0x0F;
	(*convert) = temp1 + temp2;		//Güncellendi
}
/*

*/


void WriteByte(uint8_t byte){
	uint16_t bitofByte,cnt;

	DataPinConfig(OUT);
	//GPIO_ResetBits(GPIOC,GPIO_Pin_0);
	for(cnt = 0; cnt < 8; cnt++){
		bitofByte = GetBitOfByte(byte,cnt);
		if(bitofByte == 1){
			//DATA_Out_Set;
			GPIO_SetBits(GPIOC,GPIO_Pin_1);	//IO pin
		}
		else{
			//DATA_Out_Reset;
			GPIO_ResetBits(GPIOC,GPIO_Pin_1);
		}

		Delay(tdc);
		GPIO_SetBits(GPIOC,GPIO_Pin_0);		//SCLK enable
		//SCLK_Set;
		Delay(tcdh);
		GPIO_ResetBits(GPIOC,GPIO_Pin_0);
		//SCLK_Reset;

	}
	Delay(tf);
}

uint8_t GetByte(void){
	uint8_t byte=0;
	uint16_t cnt,readBit;

	DataPinConfig(IN);

	for(cnt = 0; cnt < 8; cnt++){
		Delay(tf);
		readBit = GPIO_ReadInputDataBit(GPIOC,GPIO_Pin_1);
		MakeByteFromBits(&byte,cnt,readBit);

		if(cnt < 7){
			GPIO_SetBits(GPIOC,GPIO_Pin_0);
			//SCLK_Set;
			Delay(tr);
			GPIO_ResetBits(GPIOC,GPIO_Pin_0);	//SCLK
			//SCLK_Reset;
		}
	}
	return byte;
}

void DS1302Init(uint16_t hourType){
	uint8_t temp,readCommand;
	readCommand = second | 0x01;

	if(hourType == _24){
		DS1302Enable();
		WriteByte((hour |0x01));		//saat reg.. oku
		temp = GetByte();
		DS1302Disable();
		temp &= 0x7F;

		DS1302Enable();
		WriteByte(hour);
		WriteByte(temp);
		DS1302Disable();
	}
	else if(hourType == _12){
		DS1302Enable();
		WriteByte((hour |0x01));		//saat reg.. oku
		temp = GetByte();
		DS1302Disable();
		temp |= 0x80;

		DS1302Enable();
		WriteByte(hour);
		WriteByte(temp);
		DS1302Disable();
	}

	DS1302Enable();
	WriteByte(readCommand);
	temp = GetByte();
	DS1302Disable();
	if((temp & 0x80) == 0x80){
		temp = (temp & 0x7F);
		DS1302WriteProtect(DISABLE);

		DS1302Enable();
		WriteByte(second);			//CH biti sifirlaniyor
		WriteByte(temp);
		DS1302Disable();
	}

}

void DS1302Trickle(FunctionalState func){

	if(func == ENABLE){
			DS1302Enable();
			WriteByte(DS1302_WR_ADD_TC);
			WriteByte(0xA6);									//Trickle aktif, üstteki diyot aktif, 4kOhm aktif
			DS1302Disable();
		}
		else{
			DS1302Enable();
			WriteByte(DS1302_WR_ADD_TC);
			WriteByte(0xA4);									//direncler devreye alinmadi
			DS1302Disable();
		}
}

void DS1302WriteProtect(FunctionalState func){
	if(func == DISABLE){
		DS1302Enable();
		WriteByte(addressWP);
		WriteByte(0x00);				//Registerlara yazim serbest
		DS1302Disable();
	}
	else{
		DS1302Enable();
		WriteByte(addressWP);
		WriteByte(0x80);				//Yazma korumasi aktif edildi
		DS1302Disable();
	}
}
uint8_t ConvertToBCD(uint16_t decimal){
	uint16_t temp;
	uint8_t bcd = 0;
	temp = decimal % 10;		//Birler basamagi aliniyor 0-9 arasi sayi
	bcd |= temp;
	temp = decimal / 10;
	bcd |= temp << 4;

	return bcd;
}


Stm32f407 ile bir uygulama yapmıştım gayet guzel calisiyordu.
Yalnız şöyle bir bakınca kutuphaneyi daha kullanışlı hale getirmek için biraz modifeye yapmak gerekicek.

EMP_Otto

Teşekkürler hocam çok makbule gecti ;D ;D
Bu işler zordur,özveri ister...