ShadowWares Forum

Microcontroller => ARM => ข้อความที่เริ่มโดย: anon1206 ที่ พฤษภาคม 22, 2013, 04:42:54 pm



หัวข้อ: ตอนนี้ผมมี EEPROM 24LC512 ต่ออยู่กับ ARM LPC1756 ไม่ทราบว่าจะเขียนโปรแกรม เขียนอ่าน ยังไงครับ
เริ่มหัวข้อโดย: anon1206 ที่ พฤษภาคม 22, 2013, 04:42:54 pm
ตอนนี้ผมมี EEPROM 24LC512 ต่ออยู่กับ ARM LPC1756 ไม่ทราบว่าจะเขียนโปรแกรม เขียนอ่าน ยังไงครับ มี Library ให้ใช้ไหมครับ (ใช้  Keil ครับ)

วงจรตามรูปครับ
SCL ต่อขา P0.1
SCD ต่อขา P0.0

(http://image.ohozaa.com/i/5b0/VbpfeV.png) (http://image.ohozaa.com/view2/wQBDIAYNoWlUNqN9)


หัวข้อ: Re: ตอนนี้ผมมี EEPROM 24LC512 ต่ออยู่กับ ARM LPC1756 ไม่ทราบว่าจะเขียนโปรแกรม เขียนอ่าน ยังไงครับ
เริ่มหัวข้อโดย: ShadowMan ที่ พฤษภาคม 23, 2013, 08:40:58 am
อ้างถึง
ตอนนี้ผมมี EEPROM 24LC512 ต่ออยู่กับ ARM LPC1756 ไม่ทราบว่าจะเขียนโปรแกรม เขียนอ่าน ยังไงครับ
ส่วนนี้ตอบลำบากครับ แต่มีสองสิ่งที่คุณในฐานะคนเขียนโปรแกรมต้องรู้คือ I2C Protocol ว่าด้วย 24LC512 และการเขียนโปรแกรมใช้งาน I2C Module ของ ARM LPC1756 (หากไม่ใช้ Module สามารถเขียนโปรแกรมสร้างลอจิกของ SDA และ SCL เองได้)

อ้างถึง
มี Library ให้ใช้ไหมครับ (ใช้  Keil ครับ)
คิดว่ามี ลองเข้าไปหา Application Note ใน NXP ดูครับ แต่คิดว่าคงไม่ใช่ Library ที่สร้างมาสำหรับ LPC1756 และ 24LC512 โดยตรง อย่างไรก็ตามสามารนำมาใช้เป็นแนวทางได้


หัวข้อ: Re: ตอนนี้ผมมี EEPROM 24LC512 ต่ออยู่กับ ARM LPC1756 ไม่ทราบว่าจะเขียนโปรแกรม เขียนอ่าน ยังไงครับ
เริ่มหัวข้อโดย: anon1206 ที่ มิถุนายน 05, 2013, 11:23:39 am
ตอนนี้ผม เขียนโปรแกรมสร้างลอจิกของ SDA และ SCL เอง
แต่ทำไมตรงที่เป็นตัวแปรแบบบิต ERROR ทุกตัวเลยครับ

เช่นในฟังก์ชันเขียนข้อมูล
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
bit I2C_write(unsigned char dat)
{
   bit data_bit;      
   unsigned char i;   

   for(i=0;i<8;i++)            /* For loop 8 time(send data 1 byte) */
   {
      data_bit = dat & 0x80;      /* Filter MSB bit keep to data_bit */
      SDA = data_bit;            /* Send data_bit to SDA */
      I2C_clock();               /* Call for send data to i2c bus */
      dat = dat<<1;  
   }

   LPC_GPIO0->FIOSET = SDA ; //SDA = 1;         /* Set SDA */
   I2C_delay();      
   LPC_GPIO0->FIOSET = SCL ; //SCL = 1;         /* Set SCL */
   I2C_delay();

   data_bit = SDA;      /* Check acknowledge */
   LPC_GPIO0->FIOCLR  = SCL; //SCL = 0;         /* Clear SCL */
   I2C_delay();
   return data_bit;   /* If send_bit = 0 i2c is valid */          
}
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
จุดที่เป็นสีแดงจะขึ้น error
error:  #20: identifier "bit" is undefined
ทุกตัวเลยครับ เกิดจากอะไรครับจะประกาศตัวแปรแบบบิตต้องประกาศอะไรก่อนหรือป่าว


หัวข้อ: Re: ตอนนี้ผมมี EEPROM 24LC512 ต่ออยู่กับ ARM LPC1756 ไม่ทราบว่าจะเขียนโปรแกรม เขียนอ่าน ยังไงครับ
เริ่มหัวข้อโดย: ShadowMan ที่ มิถุนายน 05, 2013, 01:11:36 pm
"bit" ไม่ได้รองรับกับ compiler ทุกตัว
ตรวจสอบดูให้ดีว่า code ที่คุณลอกเขามา เขาใช้เครื่องมือตัวเดียวกันกับคุณจริงหรือไม่
ในเบื้องต้น ให้เปลี่ยน "bit" เป็นชนิดอื่นได้ (และอาจจะต้องปรับปุง code เล็กน้อย)


หัวข้อ: Re: ตอนนี้ผมมี EEPROM 24LC512 ต่ออยู่กับ ARM LPC1756 ไม่ทราบว่าจะเขียนโปรแกรม เขียนอ่าน ยังไงครับ
เริ่มหัวข้อโดย: anon1206 ที่ มิถุนายน 06, 2013, 08:55:14 pm
สอบถามในส่วนของ A0 A1 A2 หน่อยครับ ว่า บางวงจรต่อ GND หมด บางวงจรต่อ VCC ที่ A1 ต่างกันยังไงครับ
อย่างเช่นวงจรของผมต่อที่ A1 หมายถึงอะไรครับ

(http://image.ohozaa.com/i/5b0/VbpfeV.png) (http://image.ohozaa.com/view2/wQBDIAYNoWlUNqN9)


หัวข้อ: Re: ตอนนี้ผมมี EEPROM 24LC512 ต่ออยู่กับ ARM LPC1756 ไม่ทราบว่าจะเขียนโปรแกรม เขียนอ่าน ยังไงครับ
เริ่มหัวข้อโดย: วิสิทธิ์ แผ้วกระโทก ที่ มิถุนายน 06, 2013, 09:42:55 pm
เป็นการกำหนด Chip select bit ของตัว 24LC512 ในกรณีที่คุณต่อมากกว่า 1 ตัว ในวงจรเดียวกัน และอยู่บนเส้นทางเดินสัญญาณ (Bus) เดียวกัน
จะต้องมีตัวบอกให้รู้ ว่าแต่ละตัว ต่างกันอย่างไร นั่นก็คือ กำหนดผ่าน A0,A1,A2 

การต่อเข้ากับ VCC เราจะได้ Logic 1
ต่อเข้า GND เราจะได้ Logic 0

เพราะฉะนั้น ถ้าเราต่อลง GND หมด เราจะได้ Chip select bit = 000

นั่นก็แปลว่า ตอนเราส่ง Control Byte เราต้องส่ง S 1 0 1 0 A2 A1 A0 1 เท่ากับ S 1 0 1 0 0 0 0 1

ลองอ่านดูในดาต้าชีท แล้วเทียบก้ับโค๊ดที่เราเขียนอยู่ครับ


หัวข้อ: Re: ตอนนี้ผมมี EEPROM 24LC512 ต่ออยู่กับ ARM LPC1756 ไม่ทราบว่าจะเขียนโปรแกรม เขียนอ่าน ยังไงครับ
เริ่มหัวข้อโดย: anon1206 ที่ มิถุนายน 07, 2013, 12:30:39 am
อยู่บนเส้นทางเดินสัญญาณ (Bus) เดียวกัน
อยู่บนเส้นทางเดินสัญญาณ (Bus) เดียวกัน หมายรวมถึงอุปกรณ์ที่ใช้การสื่อสารแบบ I2C ทั้งหมดใช่ไหมครับ

เพราะวงจรผมมี 24LC512 อยู่เพียงตัวเดียว แต่มีอุปกรณ์ที่สื่อสารแบบ I2C อีกตัวคือ DS1307 ซึ่งใช้สาย SCL SDA ตัวเดียวกัน

ผมเข้าใจถูกต้องไหมครับ  [emo=shy]


หัวข้อ: Re: ตอนนี้ผมมี EEPROM 24LC512 ต่ออยู่กับ ARM LPC1756 ไม่ทราบว่าจะเขียนโปรแกรม เขียนอ่าน ยังไงครับ
เริ่มหัวข้อโดย: วิสิทธิ์ แผ้วกระโทก ที่ มิถุนายน 07, 2013, 08:41:43 am
เข้าใจถูกต้องแล้วครับ

(http://upic.me/i/mm/kwi2c.png) (http://upic.me/show/45279940)


หัวข้อ: Re: ตอนนี้ผมมี EEPROM 24LC512 ต่ออยู่กับ ARM LPC1756 ไม่ทราบว่าจะเขียนโปรแกรม เขียนอ่าน ยังไงครับ
เริ่มหัวข้อโดย: anon1206 ที่ มิถุนายน 07, 2013, 01:40:48 pm
ตอนนี้ผมใช้ Keil เป็น Compiler ซึ่งไม่สามารถใช้ตัวแปรบบิต(bit) ได้
ผมจึงทำการเป็นจากตัวแปร bit เป็น  char ตามโค้ดครับ
eeprom ใช้ 24LC512 Address But อยู่ที่ 010 คือ S 1 0 1 0 A2 A1 A0 0 = 0xA4


ฟังก์ชัน I2C_write แบบเดิมที่ใช้ตัวแปรบิตไม่ได้
Code:
bit I2C_write(unsigned char dat)
{
   bit data_bit;      
   unsigned char i;  

   for(i=0;i<8;i++)          
   {
      data_bit = dat & 0x80;    
      SDA = data_bit;          
      I2C_clock();              
      dat = dat<<1;  
   }

   LPC_GPIO0->FIOSET = SDA ; //SDA = 1;        
   I2C_delay();      
   LPC_GPIO0->FIOSET = SCL ; //SCL = 1;        
   I2C_delay();

   data_bit = SDA;      /* Check acknowledge */
   LPC_GPIO0->FIOCLR  = SCL; //SCL = 0;         /* Clear SCL */
   I2C_delay();
   return data_bit;   /* If send_bit = 0 i2c is valid */          
}

ฟังก์ชัน I2C_write ที่แก้โดยเปลี่ยน bit เป็น  char
Code:
char I2C_write(unsigned char dat)
{
char data_bit;
unsigned char i;

for(i=0;i<8;i++)
{
data_bit = dat & 0x80;
if(data_bit== 0x80)                                  //  if(data_bit == 1) SDA = 1;
LPC_GPIO0->FIOSET = SDA ; //  
else                                                  //   else  SDA = 0;
LPC_GPIO0->FIOCLR = SDA ;        //
I2C_clock();  
dat = dat<<1;  
}
LPC_GPIO0->FIOSET = SDA ; //SDA = 1;
I2C_delay();
LPC_GPIO0->FIOSET = SCL ; //SCL = 1;
I2C_delay();

data_bit = SDA;   /* Check acknowledge */
LPC_GPIO0->FIOCLR  = SCL; //SCL = 0;
I2C_delay();
if(data_bit == 1)
      UART0_SENT_DATA("ERROR..TT ",10);  // ถ้า data_bit = 1 แสดงว่าเกิดการผิดพลาด
else
check_wr = 1;
}

ผมอยากถามว่าฟังก์ชันที่ผมแก้จะสามารถใช้งานได้ไหมครับ
เพราะผมลองให้โปรแกรมเช็คค่า data_bit ถ้าเป็น 1 จะ ERROR
โดยการส่ง ออกทาง serial port uart0 ไปแสดงบน HyperTerminal จะแสดงค่า ERROR ตลอดเลยครับ


โค้ดในส่วน I2C_clock,i2c_start,i2c_stop และ I2C_write
Code:
void I2C_clock(void)
{
I2C_delay();
LPC_GPIO0->FIOSET = SCL ; //SCL = 1;
I2C_delay();  
LPC_GPIO0->FIOCLR  = SCL; //  SCL = 0;
}
void I2C_start(void)
{
if(SCL)
LPC_GPIO0->FIOCLR  = SCL; //   SCL = 0;
LPC_GPIO0->FIOSET = SDA ; //SDA = 1;        
LPC_GPIO0->FIOSET = SCL ; //SCL = 1;
I2C_delay();
LPC_GPIO0->FIOCLR = SDA ; //SDA = 0;
I2C_delay();
LPC_GPIO0->FIOCLR  = SCL; // SCL = 0;        
}

void I2C_stop(void)
{
if(SCL)
LPC_GPIO0->FIOCLR  = SCL; //SCL = 0;
LPC_GPIO0->FIOCLR = SDA ; //SDA = 0;
I2C_delay();
LPC_GPIO0->FIOSET = SCL ; //SCL = 1;
I2C_delay();
LPC_GPIO0->FIOSET = SDA ; //SDA = 1;
}

char I2C_write(unsigned char dat)
{
char data_bit;
unsigned char i;

for(i=0;i<8;i++) /* For loop 8 time(send data 1 byte) */
{
data_bit = dat & 0x80;
//SDA = data_bit; /* Filter MSB bit keep to data_bit */
if(data_bit== 0x80)
LPC_GPIO0->FIOSET = SDA ; /* Send data_bit to SDA */
else
LPC_GPIO0->FIOCLR = SDA ;
I2C_clock();
dat = dat<<1;  
}

LPC_GPIO0->FIOSET = SDA ; //SDA = 1;
I2C_delay();
LPC_GPIO0->FIOSET = SCL ; //SCL = 1;
I2C_delay();
data_bit = SDA;   /* Check acknowledge */
LPC_GPIO0->FIOCLR  = SCL; //SCL = 0; /* Clear SCL */

I2C_delay();
if(data_bit == 1)
UART0_SENT_DATA("ERROR..TT ",10);
else
check_wr = 1;
//return data_bit; /* If send_bit = 0 i2c is valid */
}


โค้ด Main ในส่วน I2C
Code:
int main(void)
{
    I2C_start();
   I2C_write(0xA4);
   I2C_write(0x00);
   for (i=1;i<=16;i++)
   {
   I2C_write(i);
   }
   I2C_stop();    
   if(check_wr == 1)
   {
   UART0_SENT_DATA("OK..",3);
   }else UART0_SENT_DATA("ERROR",5);

}


หัวข้อ: Re: ตอนนี้ผมมี EEPROM 24LC512 ต่ออยู่กับ ARM LPC1756 ไม่ทราบว่าจะเขียนโปรแกรม เขียนอ่าน ยังไงครับ
เริ่มหัวข้อโดย: ShadowMan ที่ มิถุนายน 07, 2013, 02:30:48 pm
ดู code ผ่านๆ มาสะดุดตาที่:
Code: (c)
data_bit = dat & 0x80;   
if(data_bit==1)

ขอถาม 1 คำถามว่า:
มีค่าอะไร ที่ AND ด้วย 0x80 แล้วได้เท่ากับ 1 ?

หรือจาก:
Code: (c)
data_bit = dat & 0x80;   

data_bit จะมีค่าเท่ากับ 1 เมื่อ dat มีค่าเท่าไร่?


หัวข้อ: Re: ตอนนี้ผมมี EEPROM 24LC512 ต่ออยู่กับ ARM LPC1756 ไม่ทราบว่าจะเขียนโปรแกรม เขียนอ่าน ยังไงครับ
เริ่มหัวข้อโดย: anon1206 ที่ มิถุนายน 07, 2013, 02:56:58 pm
ต้องขออภัยครับ พอดีเขียนผิดนะครับ ผมแก้แล้วเป็น if(data_bit== 0x80) แต่ก็ยัง ERROR เหมือนเดิมครับจะมีทางเช็คหรือแก้จากตรงไหนดีครับ


หัวข้อ: Re: ตอนนี้ผมมี EEPROM 24LC512 ต่ออยู่กับ ARM LPC1756 ไม่ทราบว่าจะเขียนโปรแกรม เขียนอ่าน ยังไงครับ
เริ่มหัวข้อโดย: ShadowMan ที่ มิถุนายน 07, 2013, 04:45:00 pm
ok งั้นมาว่ากันต่อ
จาก
Code: (c)
SDA = data_bit;

หมายความว่า ค่าของ SDA ที่เป็นไปได้มีสองค่าคือ 0x80 และ 0x00 ใช่หรือไม่?

ไม่ว่าตำตอบที่ได้จะใช่หรือไม่ใช่ ไม่ใช่ประด็นหลัก ประเด็นหลักคือ SDA มันเปลี่ยนค่าตอนไหน และ มันส่งผลอะไรกับ:
Code: (c)
LPC_GPIO0->FIOSET = SDA;

และ
Code: (c)
LPC_GPIO0->FIOCLR = SDA ;


ผมดู code ของคุณแล้วไมเข้าใจว่าตกลง SDA ของคุณคืออะไร?
ที่มัน print "ERROR" ออกมาก็มาจากสาเหตุเดียวคือ
data_bit = SDA; ซึ่ง SDA จะต้องเท่ากับ 1
แล้วมันเป็น 1 ได้อย่างไร? SDA มันเชื่อมโยงไปไหน?


หัวข้อ: Re: ตอนนี้ผมมี EEPROM 24LC512 ต่ออยู่กับ ARM LPC1756 ไม่ทราบว่าจะเขียนโปรแกรม เขียนอ่าน ยังไงครับ
เริ่มหัวข้อโดย: anon1206 ที่ มิถุนายน 07, 2013, 06:01:14 pm
คือผมนำตัวอย่างมาจากเว็บนี้นะครับ http://www.geocities.ws/aon_micro/24cxx.html แล้วนำมาแปลงให้ใช้กับ ARM LPC1756 ที่เขียนด้วย Keil
 ซึ่งของเค้าเช่น SCL = 1;  SDA = 1; หรือ  SCL = 1; SCL = 0;

ผมเลยนำมาแปลงเป็น  LPC_GPIO0->FIOSET = SDA;  ซึ่งคือการเซ็ตให้ logic = 1 และ  LPC_GPIO0->FIOCLR = SDA; คือ logic = 0
ไม่ทราบว่าผมเข้าใจถูกหรือป่าวครับถ้าผิดต้องขอคำแนะนำด้วยครับ

ซึ่ง SDA และ SCL คือขา GPIO ที่ผมนำมาใช้งานคือ

#define SDA 0x00000001  //P0.0
#define SDA 0x00000002  //P0.1

โค้ดตัวอย่างที่นำมาแปลง
Code:
#include <reg51.h>
#include <intrins.h>
#include <stdio.h>
// Define Port
sbit SDA = P1^0;
sbit SCL = P1^2;
sbit LED_R = P2^0; //LED red

// Define Register
unsigned char dat_buff[8];
bit check_wr = 0;

// Function
void init (void)
{
SCON = 0x52;
TMOD = 0x20;
TH1 = 0xfd;
TR1 = 1;

P2 = 0xff;
RST = 0;
SCL = 0;
SDA = 1;
}

void delay (void)
{
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
}

void c_high (void)
{
SCL = 1;
delay();
}

void c_low (void)
{
SCL = 0;
delay();
}

void start_i2c (void)
{
SDA = 1;
c_high();
SDA = 0;
delay();
c_low();
}

void stop_i2c (void)
{
SDA = 0;
c_high();
SDA = 1;
}

bit wr_byte (unsigned char x) // Write 1 Byte
{ unsigned char i;
bit outport;
for (i=1;i<=8;i++)
{
outport = x & 0x80; //0x80 = 10000000B
SDA = outport;
x = x<<1;
c_high();
c_low();
}
SDA = 1;
c_high();
outport = SDA; // Check ACK
c_low();
if (outport == 1)
LED_R = 0;// LED red
else
check_wr = 1;
}

unsigned char rd_byte () // Read 1 Byte
{
unsigned char i,dat ;
bit inport;
dat = 0;
SDA = 1; // Important if SDA not set can read 1 byte only !!!
for (i=1;i<=8;i++)
{
c_high();
inport = SDA;
dat = dat<<1;
dat = dat|inport;
c_low();
}
return(dat);
}

// Send ACK
void ack (void)
{
SDA = 0;
_nop_();
c_high();
c_low();


}

// Clear Buffer
void clr_buff (void)
{
unsigned char i;
for (i=1;i<=8;i++)
dat_buff[i] = 0;
}

void delay_s (unsigned int count)
{
unsigned char i;
while (count)
{ for (i=0;i<=255;i++);
count--;}
}

//**************MAIN******************//
void main (void)
{
unsigned char i,j,k;
init();

printf("\nTest 24LCXX Write\n");
start_i2c();
wr_byte(0xa0); //Send write
wr_byte(0x00); //Send address

for (i=1;i<=16;i++)
{
wr_byte(i);
}
stop_i2c();
if (check_wr == 1)
printf("Write OK\n\n");
else
{printf("Write error!!!\n");}

init();
printf("\nTest 24LCXX Read");
start_i2c();
wr_byte(0xa0); //Send write
wr_byte(0x00); //Send address
start_i2c(); //Start again
wr_byte(0xa1); //Send read

for (j=1;j<=8;j++)
{
printf("\n");
for (k=1;k<=8;k++)
{
printf("%02bX ",rd_byte());
ack();
}
}
stop_i2c();

while(1);

}


หัวข้อ: Re: ตอนนี้ผมมี EEPROM 24LC512 ต่ออยู่กับ ARM LPC1756 ไม่ทราบว่าจะเขียนโปรแกรม เขียนอ่าน ยังไงครับ
เริ่มหัวข้อโดย: anon1206 ที่ มิถุนายน 08, 2013, 08:00:15 am
 [emo=cry] มีจะแนะนำหรือบอกวิธีการแปลงอย่างโค้ด i2c มาใช้กับ ARM LPC1756 ให้ได้ไหมครับ ว่าต้องเขียนแบบไหน
หรือต้องแก้ตรงจุดไหนบ้าง
เหมือนตัวอย่างเค้าจะเข้าถึงระดับบิตอย่างเดียวเลย
โค้ดตัวอย่าง http://www.geocities.ws/aon_micro/24cxx.html
ตั้งแต่ประกาศ port

// Define Port
sbit SDA = P1^0;
sbit SCL = P1^2;
sbit LED_R = P2^0; //LED red

แล้วผมจะเขียนเปลี่ยนจากบิตมาเป็นแบบไหนแนะนำหน่อยครับ  [emo=azn]


หัวข้อ: Re: ตอนนี้ผมมี EEPROM 24LC512 ต่ออยู่กับ ARM LPC1756 ไม่ทราบว่าจะเขียนโปรแกรม เขียนอ่าน ยังไงครับ
เริ่มหัวข้อโดย: ShadowMan ที่ มิถุนายน 08, 2013, 09:23:48 am
ในเมื่อคุณ define:
Code: (c)
#define SDA 0x00000001  //P0.0

นั่นหมายความว่า SDA เป็นค่าคงที่มีค่าเท่ากับ 1 ตลอดไป แล้วคุณเขียนโปรแกรมแบบนี้:
Code: (c)
   data_bit = SDA;      /* Check acknowledge */
   LPC_GPIO0->FIOCLR  = SCL; //SCL = 0;
   I2C_delay();
   if(data_bit == 1)
          UART0_SENT_DATA("ERROR..TT ",10);  // ถ้า data_bit = 1 แสดงว่าเกิดการผิดพลาด

data_bit ก็ย่อมเป็น 1 ผลก็ต้องได้ ERROR... ออกมาตลอดไป นั่นเป็นสิ่งที่ถูกต้องแล้ว (แต่คุณไม่อยากได้สิ่งที่ถูกต้องนั้น)

การจรวจสอบการ Acknowledge จาก I2C Devices ไม่ใช่การจับค่าคงที่ใส่ตัวแปร แต่คือการอ่านสถานะลอจิกที่ขา SDA บรรทัดไหนที่ทำสิ่งนี้?

ลอก code เขามาใช้ ไม่ใช่เรื่องเสียหาย แต่ถ้าคุณยังใช้ IO Port ของ MCU ไม่เป็นอันนี้เรื่องใหญ่ครับ
ลองกลับไปเขียนโปรแกรม อ่านค่าจาก Switch แล้วสั่ง LED ให้ติดดับก่อน จากนั้นค่อยมาแก้โจทย์ข้อนี้ต่อน่าจะดีกว่าหรือเปล่า
งานแบบนี้ ยิ่งใจร้อน มันจะยิ่งช้า


หัวข้อ: Re: ตอนนี้ผมมี EEPROM 24LC512 ต่ออยู่กับ ARM LPC1756 ไม่ทราบว่าจะเขียนโปรแกรม เขียนอ่าน ยังไงครับ
เริ่มหัวข้อโดย: anon1206 ที่ มิถุนายน 19, 2013, 03:27:17 pm
ตอนนี้ผมได้ศึกษา Port I/O ตามที่พี่บอกมาแล้วครับอยากให้ช่วยดู code ให้หน่อยเพราะตอนนี้ยังไม่ออกเลยครับไม่รู้ตรงไหนมีปัญหา

ส่วนการกำหนดขาและ define ต่าง ๆ
Code: (c)

#define   SDA (1<<0)  //กำหนดขา P0.0 ชื่อ SDA
#define SCL (1<<1) //กำหนดขา  P0.1 ชื่อ SCL

#define MEMDIR LPC_GPIO0->FIODIR          // รีจีสเตอร์  FIODIR    ตั้งชื่อเป็น MEMDIR
#define MEMSEL LPC_PINCON->PINSEL0    // รีจีสเตอร์   PINSEL0  ตั้งชื่อเป็น   MEMSEL
#define MEMSET LPC_GPIO0->FIOSET       // รีจีสเตอร์   FIOSET   ตั้งชื่อเป็น MEMSET
#define MEMCLR LPC_GPIO0->FIOCLR      // รีจีสเตอร์   FIOCLR   ตั้งชื่อเป็น MEMCLR
#define MEMIN  LPC_GPIO0->FIOPIN           // รีจีสเตอร์   FIOPIN     ตั้งชื่อเป็น  MEMIN 

#define SDA0  MEMCLR  =  SDA     //กำหนดให้ขา  SDA  มีลอจิกเป็น 0 ชื่อว่า SDA0
#define SDA1  MEMSET  =  SDA     //กำหนดให้ขา  SDA  มีลอจิกเป็น 1 ชื่อว่า SDA1
#define SCL0  MEMCLR  =  SDA     //กำหนดให้ขา  SCL  มีลอจิกเป็น 0 ชื่อว่า SCL0
#define SCL1  MEMSET  =  SDA      //กำหนดให้ขา  SCL  มีลอจิกเป็น 1 ชื่อว่า SCL1


ฟังก์ชัน I2C_start
Code: (c)

void I2C_start(void)
{
   
   MEMDIR |= SDA;  //กำหนดให้ขา SDA ทำหน้าที่เป็นพอร์ต Output
   SDA1 ; //SDA = 1;       
   SCL1 ; //SCL = 1;
   _delay_ms(10);
   SDA0 ; //SDA = 0;
   _delay_ms(10);
   SCL0 ; // SCL = 0;       
}


ฟังก์ชัน I2C_stop
Code: (c)

void I2C_stop(void)
{
          MEMDIR |= SDA;  //กำหนดให้ขา SDA ทำหน้าที่เป็นพอร์ต Output
   SCL0 ; //SCL = 0;
   _delay_ms(10);
   SDA0 ; //SDA = 0;
   _delay_ms(10);
   SCL1 ; //SCL = 1;
   _delay_ms(10);
   SDA1 ; //SDA = 1;
   _delay_ms(10);         
}


ฟังก์ชันตรวจสอบค่า ack
Code: (c)

int ack_(void)
{
   int bit=0;
          MEMDIR  &= ~SDA;  //กำหนดขา SDA ทำหน้าที่เป็น input
        // กำหนดให้ SCL =0 และ SCL =1 รอการส่งค่า ack จากตัว 24LC512
   SCL0;                // SCL = 0;
   SCL1;                // SCL = 1 ;
          bit = (MEMIN & SDA);  //รับค่า ack ที่ส่งจากจากตัว 24LC512 เก็บไว่ที่ตัวแปร bit

   MEMDIR |= SDA;   //กำหนดให้ขา SDA ทำหน้าที่กลับเป็น output
   return (bit); 
}


ฟังก์ชัน write8bit
Code: (c)

unsigned char write8bit(unsigned char input)
{
   unsigned char temp,q0;      
   MEMDIR |= SDA;    // กำหนดขา SDA เป็น output
   for(temp=8;temp>0;temp--)            
   {
      q0 = input & 0x80;    //นำค่า input ที่รับมาแอนกับ 0x80   
      if(q0 == 0x80) SDA1;   
      else  SDA0;

               _delay_ms(10);                         
      SCL1;
      _delay_ms(10);
      SCL0;       
      input = input<<1;   
   }
   ack_();  //ตรวจสอบค่า ack          
}


ฟังก์ชัน read8bit
Code: (c)

unsigned char read8bit()
{
 unsigned char temp,q0,rbyte=0 ;
        MEMDIR &= ~SDA;   //กำหนดขา SDA เป็น input
 for(temp=8;temp>0;temp--)
 {
    SCL1;     //SCL = 1
   _delay_ms(10);
   rbyte = rbyte<<1;
          MEMDIR &= ~SDA;  //กำหนดขา SDA เป็น input
   q0 = (MEMIN & SDA);
   if(q0 == SDA)
   rbyte = rbyte|0x01;
   _delay_ms(10);
       SCL0;    //SCL = 0
       _delay_ms(10);
  }
 return(rbyte);   
}


ฟังก์ชัน main
Code: (c)

int main(void)
{
unsigned char Whole_Temp[ ];
unsigned char temp;

   SystemInit();
    MEMDIR |=SCL;  //กำหนดให้ขา SCL ทำหน้าที่เป็น output
   
        //เริ่มต้อนการเขียนข้อมูล
        I2C_start();
          write8bit(0xA4);  //ตำแหน่ง address Hardware ที่ต่อคือ 010 จึงได้เป็น 10100100 = 0xA4
          write8bit(0x00);   //ตำแหน่ง address ที่จะทำการเขียนข้อมูล
          write8bit(0x41);   //ข้อมูลที่จะทำการเขียนลง
   I2C_stop();
   //============================================================
        //เริ่มต้นการอ่านข้อมูล
   I2C_start();
   write8bit(0xA4);
   write8bit(0x00);
   I2C_start();
          write8bit(0xA5);  // 10100101 = A5 ทำการเขียนข้อมูล
         temp = read8bit(0x00); //นำข้อมูลที่อ่านไปเก็บที่ temp
   I2C_stop();
   Whole_Temp[0] = temp; 
         UART0_SENT_DATA(Whole_Temp,1);  //ส่งข้อมูลออกไปตรวจสอบผ่าน Serial port
}


หัวข้อ: Re: ตอนนี้ผมมี EEPROM 24LC512 ต่ออยู่กับ ARM LPC1756 ไม่ทราบว่าจะเขียนโปรแกรม เขียนอ่าน ยังไงครับ
เริ่มหัวข้อโดย: ShadowMan ที่ มิถุนายน 19, 2013, 06:04:38 pm
อ้างถึง
ตอนนี้ผมได้ศึกษา Port I/O ตามที่พี่บอกมาแล้วครับอยากให้ช่วยดู code ให้หน่อยเพราะตอนนี้ยังไม่ออกเลยครับไม่รู้ตรงไหนมีปัญหา
"ตอนนี้ยังไม่ออกเลยครับ"
อะไรไม่ออก? สัญญาญไม่ออกตามที่ควรจะเป็น หรือ เขียน/อ่านค่าไม่ได้? ค่าที่อ่านมาได้มีค่าเท่าไร?


หัวข้อ: Re: ตอนนี้ผมมี EEPROM 24LC512 ต่ออยู่กับ ARM LPC1756 ไม่ทราบว่าจะเขียนโปรแกรม เขียนอ่าน ยังไงครับ
เริ่มหัวข้อโดย: anon1206 ที่ มิถุนายน 19, 2013, 06:27:28 pm

อะไรไม่ออก? สัญญาญไม่ออกตามที่ควรจะเป็น หรือ เขียน/อ่านค่าไม่ได้? ค่าที่อ่านมาได้มีค่าเท่าไร?

ผมลองเขียน 0x41ลงไปที่ตำแหน่ง 0x00 และค่าที่อ่านได้จะเป็น 0xFF ตลอดเลยครับ ผมจะทดสอบยังไงครับว่าค่านั้นเขียนลงไปได้แล้ว
หรือโค้ดตรงไหนที่ผมน่าจะเขียนผิดครับ


หัวข้อ: Re: ตอนนี้ผมมี EEPROM 24LC512 ต่ออยู่กับ ARM LPC1756 ไม่ทราบว่าจะเขียนโปรแกรม เขียนอ่าน ยังไงครับ
เริ่มหัวข้อโดย: ShadowMan ที่ มิถุนายน 20, 2013, 09:35:46 am
อ่านค่ามาได้เป็น 0xFF นั่นเป็นสัญญาณบอกว่า I2C Device ยังไม่ตอบสนองใดๆ ครับ
จะต้องตรวจสอบว่าสัญญาณต่างๆ ที่ถูกสร้างขึ้นมานั้นถูกต้องตามรูปแบบของ I2C รวมไปถึงค่าต่างๆ ที่ส่งออกไปเพื่อร้องของการเขียน/อ่านกับ I2C Device ด้วย และที่ขาดไม่ได้คือ Hardware จะต้องถูกต้อง


หัวข้อ: Re: ตอนนี้ผมมี EEPROM 24LC512 ต่ออยู่กับ ARM LPC1756 ไม่ทราบว่าจะเขียนโปรแกรม เขียนอ่าน ยังไงครับ
เริ่มหัวข้อโดย: anon1206 ที่ มิถุนายน 20, 2013, 10:31:27 am
สอบถามหน่อยครับไลบารี่ของ 24LCxx สามารถนำมาใช้กับ 24LCxxx ได้เลยไหมครับเช่น 24LC16 กับ 24LC512
สามารถนำมาใช้ได้เลยไหมครับ หรือมีส่วนไหนที่ต่างกันที่เราต้องแก้ครับ


หัวข้อ: Re: ตอนนี้ผมมี EEPROM 24LC512 ต่ออยู่กับ ARM LPC1756 ไม่ทราบว่าจะเขียนโปรแกรม เขียนอ่าน ยังไงครับ
เริ่มหัวข้อโดย: ShadowMan ที่ มิถุนายน 20, 2013, 01:52:36 pm
ผมไม่รู้จักไลบารี่ 24LCxx ดังกล่าวครับ ไม่สามารถยืนยันให้ได้ ว่าได้ ไม่ได้ อย่างไร
ในกรณีทั่วไป เมื่อลงท้ายด้วย xx นั้นหมายความว่า อะไรก็ได้ แต่ไม่ได้หมายความว่าได้ในทุกกรณี
รายละเอียดที่จำเป็นน่าจะอยู่ในไฟล์ที่คุณใช้อยู่


หัวข้อ: Re: ตอนนี้ผมมี EEPROM 24LC512 ต่ออยู่กับ ARM LPC1756 ไม่ทราบว่าจะเขียนโปรแกรม เขียนอ่าน ยังไงครับ
เริ่มหัวข้อโดย: Hildareth ที่ กุมภาพันธ์ 25, 2019, 05:54:27 pm
กำลังหาโค็ดอยู่พอดี