Gunakan MimeTex/LaTex untuk menulis simbol dan persamaan matematika.

Welcome to Forum Sains Indonesia. Please login or sign up.

Desember 07, 2024, 05:44:39 AM

Login with username, password and session length

Topik Baru

Artikel Sains

Anggota
Stats
  • Total Tulisan: 139,653
  • Total Topik: 10,405
  • Online today: 51
  • Online ever: 1,582
  • (Desember 22, 2022, 06:39:12 AM)
Pengguna Online
Users: 0
Guests: 28
Total: 28

Aku Cinta ForSa

ForSa on FB ForSa on Twitter

Perhitungan Rumus Pada AT89s51

Dimulai oleh di4914, Juni 22, 2009, 12:49:44 PM

« sebelumnya - berikutnya »

0 Anggota dan 1 Pengunjung sedang melihat topik ini.

di4914

Hi all
gw member baru nih.
butuh pencerahan buat TA.
gw bingung melakukan perhitungan rumus di mikro, nilai-nilai dalam rumus ada bilangan berkomanya,
gimana yach??????
pleaseeeee, help
gw mohon dengan sangat!!!!!!
thanks

Too Payz

Wkkk......
Rumus floating point n desimal dengan MCS51, jangan-jangan bahasa assembler lagi.
Pusing pasti. Mending mulai belajar pake bahasa C dengan Keil C.
Tapi tar deh wa bantu klo bisa sabar

di4914

#2
Yups mumet banget,
makanya gw beralih ke C.
Ditunggu ya mas
tararenk U

oh iya gw dah buat listingnya, tapi bigu di simulasi pake top view hasil perhitungannya kg nongol.
ni listing gw:

#include <at89x51.h>
#define data_adc P1
#define data_lcd P2
#define RS P3_5
#define EN P3_4
#define RD P3_7
#define WR P3_6
#define INT P3_2

void tunda_s();
void tunda();
void clock();
void baca_adc();
void tulis_cmd(unsigned char data_cmd);
void tulis_char(unsigned char data_char);
void Gotoxy(unsigned char baris,unsigned char kolom);
void tulis_str(unsigned char *s);
void tampil_data(unsigned char line,unsigned char colum);
void kon_ascii();
void tampil_data1(unsigned char line,unsigned char colum);
void kon_ascii1();

unsigned char puluhan,satuan,ratusan,koma1,koma2;
unsigned char nilai,sensor;

void main()
{
   unsigned char x=0,y=0,z=0;
   unsigned int tegangan,ppm,nilai;
   //inisialisasi LCD
   data_adc = 0xff;
   P3_3 = 0;
   tulis_cmd(0x38);   //LCD 2x16 character
   tulis_cmd(0x0c);   //Display on, cursor off
   tulis_cmd(0x01);   //hapus layar
   tulis_cmd(0x06);   //Pergeseran tampilan ke kanan
   
   Gotoxy(1,5);
   tulis_str("KADAR CO");
   Gotoxy(2,7);
   tulis_str("V");
   Gotoxy(2,14);
   tulis_str("ppm");
   tunda();
ulang:
   baca_adc();
   tegangan = (sensor * 0.02);
   nilai = tegangan;
   tampil_data(2,1);
   
   ppm = data_adc;
   nilai = ppm;
   tampil_data1(2,10);
   tunda_s();
goto ulang;
}
//Fungsi yang digunakan
void tunda_s()
{
   int c;
   for (c=0; c<500; c++);
   tunda();
}

void tunda()
{
   int i;
   for (i=0; i<210; i++);
}

void clock()
{
   EN = 1;
   EN = 0;
}

void tulis_cmd(unsigned char data_cmd)
{
   RS = 0;
   data_lcd = data_cmd;
   clock();
   tunda();
}

void tulis_char(unsigned char data_char)
{
   RS = 1;
   data_lcd = data_char;
   clock();
   tunda();
}

void tulis_str(unsigned char *s)
{
   while(*s)
      tulis_char(*s++);
}

void Gotoxy(unsigned char baris,unsigned char kolom)
{
   if(baris==1)
      tulis_cmd ((0x80 + kolom)-1);
   else
      tulis_cmd ((0xc0 + kolom)-1);
}

void baca_adc()
{
   WR = 1;
   RD = 1;
   tunda();
   WR = 0;
   WR = 1;
   if (INT == 0)
      RD = 0;
      sensor = data_adc;
      RD = 1;
}

void tampil_data(unsigned char line,unsigned char colum)
{
   kon_ascii();
   Gotoxy(line,colum);
   tulis_char(puluhan);
   tulis_char(satuan);
   tulis_str(".");
   tulis_char(koma1);
   tulis_char(koma2);
}

void tampil_data1(unsigned char line,unsigned char colum)
{
   kon_ascii1();
   Gotoxy(line,colum);
   tulis_char(ratusan);
   tulis_char(puluhan);
   tulis_char(satuan);
}

void kon_ascii()
{
   koma2 = (nilai % 10) + 0x30;
   nilai /=10;
   koma1 = (nilai % 10) + 0x30;
   nilai /=10;
   satuan = (nilai % 10) + 0x30;
   nilai /=10;
   puluhan = (nilai % 10) + 0x30;
}

void kon_ascii1()
{
   satuan = (nilai % 10) + 0x30;
   nilai /=10;
   puluhan = (nilai % 10) + 0x30;
   nilai /=10;
   ratusan = (nilai % 10) + 0x30;
}

apa konversi ascii-nya ada yang salah yah, soalnya di listing ini :
tulis_str("KADAR CO");
nongol di LCD "KADAR CO".

pleaseeeeeee help meeeeeee

Too Payz

#3
Haaa.......... ?
Kok bertentangan neh.
Kutipoh iya gw dah buat listingnya, tapi bigu di simulasi pake top view hasil perhitungannya kg nongol.
Kutipapa konversi ascii-nya ada yang salah yah, soalnya di listing ini :
tulis_str("KADAR CO");
nongol di LCD "KADAR CO".
Ini maksudnya :
1. hanya hasil perhitugannya ga nongol tapi untuk karakter ASCII nongol.
2. Karakter " yang seharusnya g nongol ikut nongol.
bener yak? Saya anggap benar aj dah.

Btw ini komunikasi LCD 8 bit dengan mikro kan, jadinya make PORT mikro 2 buah, PORT 2 untuk data LCD dan PORT 3 untuk mode LCD. Klo saya si biasanya hanya 1 PORT untuk LCD, D0 dan D3 LCD tidak digunakan. Jadi komunikasi data 4 bit.
Kalo tertarik mengubah rangkaian LCD bilang, tp tar ubah semua coding program looo..

Sebenarnya basic wa Bahasa C dengan AVR n beda dengan AT89S51.
duluuuu.. banget pake Keil C untuk MCS51. Ya udah, Wa koreksi dulu listingnya :

// -------------- Koreksi 1 -------------------------------------------------------------
Kutip
   P3_3 = 0;
   tulis_cmd(0x38); &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;//LCD 2x16 character
Kok P3_3 tidak di define sekalian, kan nanggung.

Kutipvoid tunda_s()
{
   int c;
   for (c=0; c<500; c++);
   tunda();
}

void tunda()
{
   int i;
   for (i=0; i<210; i++);
}
Wah g jelas neh waktunya coba :

void tunda_ms(unsigned int waktu)
{   unsigned int loop;
   while (waktu--)
   {
      loop=1000;         // tunda 1000 uS
      while (loop--){}      // Xtall 12 MHz
   }
}

void tunda_us(unsigned int waktu)
{
   while (waktu--){}      // tunda 1 uS
}                  // Xtall 12 MHz

Kutipulang:
   baca_adc();
.......................
   tunda_s();
goto ulang;
Perintah goto pada bahasa terstruktur sebaiknya tidak digunakan meskipun disediakan, karena akan "lompat" ke baris program yang lain dan bisa menyebabkan kesalahan program (hang).
Pada listing anda tidak akan error karena goto-nya hanya 1 buah, coba jika kompleks dan ada banyak goto-nya. Program anda akan kacau balau.

ganti dengan
while (1)
{
............. // sudah umum untuk looping selamanya
}

Kutipvoid tulis_str(unsigned char *s)
{
   while(*s)
   tulis_char(*s++);
}
Tentu saja tanda " ditampilkan.
Coba ganti

void tulis_str(unsigned char *s)
{
   *s++;   // " (petik) pertama dilewati.
   while(*s!=0x22) tulis_char(*s++);
         // saat *s tidak sama dengan 0x22 = hex-nya karakter " (petik),
         // maka tampilkan ......
}

// -------------- Koreksi 2 -------------------------------------------------------------

Untuk menguji LCD apakah bisa menampilkan bilangan bulat atau pecahan sebaiknya langsung memberikan nilai konstan dulu, jangan dari membaca nilai ADC karena bisa saja proses pembacaan ADC-nya sebenarnya belum berhasil.

Misal :
while(1)
{
   nilai = 195;
   tampil_data1(2,1);
   nilai = 5678;
   tampil_data(2,2);
   tunda_ms(2000);
}

Ok ke koreksi listing
KutipWR = 0;
   WR = 1;
   if (INT == 0)
      RD = 0;
      sensor = data_adc;
      RD = 1;
}
Jika INT sama dengan 0 maka...........
Padahal Pin INT anda belum tentukan nilai defaultnya apa, bisa saja sejak awal berlogika 0.
seharusnya inisialisasi terlebih dahulu yaitu INT = 1; pada main program saat inisialisasi LCD.
INT itu maksudnya dijadikan Interupsi Eksternal (P3.2) untuk membaca apakah ADC selesai konversi (EOC) ?
Tapi kok saya g liat ada proses inisialisasi interupsi eksternal ya ? Coba di cek.
Selain itu saya bingung melihat posisinya yang agak menjorok ke kanan, apakah maksudnya begini :

void baca_adc()
{
   WR = 1;
   RD = 1;
   tunda();
   WR = 0;
   WR = 1;
   if (INT == 0)
   {          // perhatikan posisi kurung kurawal
      RD = 0;
      sensor = data_adc;
      RD = 1;
   }         // perhatikan posisi kurung kurawal
}

Saya koreksi 1 aj yah.
Kutip
unsigned char nilai,sensor;
................
void kon_ascii()
{
   koma2 = (nilai % 10) + 0x30;
   nilai /=10;
   koma1 = (nilai % 10) + 0x30;
   nilai /=10;
..................
}
Saya lihat nilai memiliki data maksimal 4 digit atau maksimal nilai = 9999
tetapi type data yang digunakan unsigned char, coba lihat dulu di link berikut
[pranala luar disembunyikan, sila masuk atau daftar.]
jadi seharusnya unsigned int.

di KeilC ada fungsi Matematika yang namanya math.h pada librarynya.
Lihat helpnya dan cari fungsi ceil atau floor.
atau lihat di [pranala luar disembunyikan, sila masuk atau daftar.]

setelah dibagi dengan 10 harusnya di bulatkan biar tidak menghasilkan pecahan.
jadi menurutku.
void kon_ascii()
{
   koma2 = (nilai % 10) +   0x30;
   nilai = floor (nilai / 10);      // pembulatan ke bawah.
.........................
}

Tolong d koreksi terlebih dahulu sapa tau ad salah.. &nbsp;:-\

di4914

#4
thanks ya kang,
pencerahan 1 lagi yah....hehehe

gimana kalo gw mo nampilan hasil perhitungannya berkoma, misalnya
hasil perhitungan dari data ADC jadi tegangan. kan rumus umumnya Vout = (Vin/2^n)*Vref

jadi gw pengen yang tampil di LCD ntu, satuan dan dua dibelakang koma, kyk 2.25
hehehehe......
tolongnya kaaaaang...
tararenk U ;D

oh iya kang kalo gw masukin 2 perhitungan
Vout = (Vin/2^n)*Vref sama
ppm = (Vout - 0.8848)/0.0018
memorinya ndak cukup
hehehehe.......
solusinya gimana yah kang???????
sekali lagi tararenk U ya kang ;D

Too Payz

#5
Kutip
gimana kalo gw mo nampilan hasil perhitungannya berkoma, misalnya
hasil perhitungan dari data ADC jadi tegangan. kan rumus umumnya Vout = (Vin/2^n)*Vref

jadi gw pengen yang tampil di LCD ntu, satuan dan dua dibelakang koma, kyk 2.25
Anggap hasil perhitunganmu 45,6789 volt dan pengennya ketelitian 2 angka dibelakang koma.
caranya cukup dengan mengalikan 100 terlebih dahulu baru d bulatkan dan di proses.
Codingnya gini :

void DECIMAL2LCD (unsigned char sensor)   // data nilai ADC ada di sensor (listingmu)
{
   float nilai_V;
.......................               // rumus konversi ADC ke nilai tegangan.
.......................               // anggap hasilnya nilai_V = 45,6789 volt
   nilai_V = ceil (nilai_V * 100);      // kalikan 100 dulu
   koma2 = (nilai_V% 10) +   0x30;
   nilai_V= floor (nilai_V/ 10);         // pembulatan ke bawah.
   koma1 = (nilai_V% 10) +   0x30;
   nilai_V= floor (nilai_V/ 10);         // pembulatan ke bawah.
...................dst
   tampil_data(x,y);
}

Kutip
Vout = (Vin/2^n)*Vref sama
ppm = (Vout - 0.8848)/0.0018
memorinya ndak cukup
Iya kalo saya liat programnya g sederhana neh, makanya makan memori banyak.

ada 2 cara dari kasusmu:
1. mengubah program hingga sederhana mungkin.
Coba sederhanakan dulu.
Beberapa cara hemat memori :
- Minimalkan penggunaan global variabel.
- Menggunakan fungsi dengan lokal variabel.
- Inisialisasi Variabel gunakan tipe data yang sesuai dan tidak berlebihan.
- Minimalkan penggunaan tipe floating point.
- Penggunaan banyak n array sesuai kebutuhan.
- Gunakan RAM internal AT89S5x terlebih dahulu secara maksimal baru registernya
   (berkaitan dengan global variabel dan lokal variabel).
- dll.
Untuk rumus usahakan menggunakan prosedur dengan nilai return jadi hemat memori.

2. Ganti mikro AT89S51 dengan AT89S52
Mudah-mudahan cukup.  ;D
G cukup lagi, ganti dengan AT89S53.  :)  memori mayan neh  :kribo:

di4914


Too Payz


mekanik_gagal

Kutip dari: Too Payz pada Juni 23, 2009, 03:48:11 PM
Wkkk......
Rumus floating point n desimal dengan MCS51, jangan-jangan bahasa assembler lagi.
Pusing pasti. Mending mulai belajar pake bahasa C dengan Keil C.
Tapi tar deh wa bantu klo bisa sabar

maap cuman mw numpang nnya...
yg di maksud bahasa asembler
yang ada port nya bukan??...truz ada setb n clr...
tolong kasih tw gw yg masih ijo ini...
menuntut ilmu hukumnya wajib

tAZZZ

@mekanik gagal: yup ada sbr gituh trus ada mov....intinya lebih panjaaaaaaaang dibanding bahasa C, tapi lebih hemat memori dibanding C