Main Menu
Menu

Show posts

This section allows you to view all posts made by this member. Note that you can only see posts made in areas you currently have access to.

Show posts Menu

Messages - secret07

#1
ARM Processors / Re: I2C >> Compass
February 13, 2013, 11:50:12 PM
อ้อขอถามเพิ่มเติมอีก 2 ประเด็นคือ

1. มันต้องต่อ  pull up ด้วยถูกมั๊ยครับ
2. ในฟังชั่น compass นั้นที่มี ค่า x y z ถ้าสมมุติว่ามันอ่านค่าได้แล้ว จะ return ออกมายังไง 3 ค่าครับ
#2
ARM Processors / I2C >> Compass
February 13, 2013, 11:44:57 PM
มารบกวนใหม่อีกครั้งแล้วครับ
งวดนี้ไปยืมเซ็นเซอร์ compass มาเล่นครับ >>> HMC5883L

ตอนนี้มันทำงานไปถึงการส่ง Address แล้ว

printf("Write Address \t"); แสดงมาแล้ว

แต่มันไม่มีการ ACK กลับมาเพื่อที่จะเขียน data ไปอ่ะครับ
ผมดูใน datasheet ของ lpc2138 ที่มันมีตาราง ACK ตรง Master Trans.. กับ Master Reci..เนี้ย
ผมเลือกใช้มาถูกป่าว หรือว่าผมเขียนผิดตรงไหน
ช่วยดูให้หน่อยครับผม

ปล. ตรงช่วงที่คอมเม้นยาววววเลยนั้น  ผมลองเขียนแบบฟังชั่นเดียวอ่ะมันไม่เวิร์ก
      เลยคิดว่าน่าจะเขียนแยกกันจะได้เรียกใช้ง่ายขึ้นหน่อยแต่ก็ติดตรงหลังจากส่ง Address ไปเหมือนกัน
      เอิ๊ก ๆ

ปล.2  ไม่มีตังซื้อมาเล่นเอง  :'(  :'( ที่จริงอยากได้ Gyro (เขียนรับใช้ ADC ใช่มะครับเพราะพอเขียนเป็น) แต่รุ่นพี่เค้าใช้ทำโปรเจคอยู่
         เลยมาลองเขียน I2C แทน

#include <LPC213X.H>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "uart0.h"

#define Read_Compass 0x3D
#define Write_Compass 0x3C


void Init_PIN(void)
{
PINSEL0 = 0x00000000; // Reset Pinsel 0
PINSEL1 = 0x00000000; // Reset Pinsel 1
PINSEL2 = 0x00000000; // Reset Pinsel 2

PINSEL0 |= (5<<0); // Port0.0 [Uart0 TXD] Bit 1,0 >>> 0,1
// Port0.1 [Uart0 RXD] Bit 3,2 >>> 0,1
PINSEL0 |= (5<<4); // Port0.2 [I2C SCL0] Bit 5,4 >>> 0,1
// Port0.3 [I2C SDA0] Bit 7,6 >>> 0,1
}

void init_i2c0(void)
{
I2C0SCLH = 0x93; // 200k [High 100k]
I2C0SCLL = 0x93; //   [Low  100k] >> I2C = PCLK / 200k = 147 >> 0x93
}

// char read_i2c(void)
// {
// int x_high,x_low,y_high,y_low,z_high,z_low;
// long int x,y,z;
// char data[3];

// I2C0CONCLR = 0x6C; // Clear Register
// I2C0CONSET |= 0x40; // Interface Enable
// I2C0CONSET |= 0x20; // Start

// while((I2C0STAT) != 0x08); // Start Condition
// printf("Start 1 \n");
// I2C0DAT = 0x3C; // write Address
// I2C0CONCLR = 0x28; // [START flag clear bit] and [i2c interrupt clear bit]

// while((I2C0STAT) != 0x18); // ackno
// printf("Write \n");
// I2C0DAT = 0x02; // mode register = Idel mode
// I2C0CONCLR = 0x0C; // Ackno clear and irq clear
//
// while((I2C0STAT) != 0x28); // ackno
// printf("Idel mode \n");
// I2C0DAT = 0x00; // Continuous-Measurement mode
// I2C0CONCLR = 0x0C; // Ackno clear and irq clear

// while((I2C0STAT) != 0x28);
// printf("Write End \n");
// I2C0CONSET |= 0x10;
// I2C0CONCLR = 0x0C; // Ackno clear and irq clear
//
// /**********************************/

// I2C0CONCLR = 0x6C;
// I2C0CONSET |= 0x40;
// I2C0CONSET |= 0x20;

// while((I2C0STAT) != 0x08);
// printf("Start 2 \n");
// I2C0DAT = 0x3D; // Read
// I2C0CONCLR = 0x28;

// while((I2C0STAT) != 0x40); // wait ackno read
// printf("Read \n");
// I2C0CONCLR = 0x0C;

// while((I2C0STAT) != 0x58); // wait ackno data
// printf("Read data x_high \n");
// x_high = I2C0DAT; // x_high byte
// I2C0CONCLR = 0x0C; // Ackno clear and irq clear

// while((I2C0STAT) != 0x58); // wait ackno data
// printf("Read data x_low \n");
// x_low = I2C0DAT; // x_low byte
// I2C0CONCLR = 0x0C; // Ackno clear and irq clear
//
// x = x_low|(x_high<<8);
// /***/
// while((I2C0STAT) != 0x58); // wait ackno data
// printf("Read data y_high \n");
// y_high = I2C0DAT; // y_high byte
// I2C0CONCLR = 0x0C; // Ackno clear and irq clear

// while((I2C0STAT) != 0x58); // wait ackno data
// printf("Read data y_low \n");
// y_low = I2C0DAT; // y_low byte
// I2C0CONCLR = 0x0C; // Ackno clear and irq clear
//
// y = y_low|(y_high<<8);
// /***/
// while((I2C0STAT) != 0x58); // wait ackno data
// printf("Read data z_high \n");
// z_high = I2C0DAT; // z_high byte
// I2C0CONCLR = 0x0C; // Ackno clear and irq clear

// while((I2C0STAT) != 0x58); // wait ackno data
// printf("Read data z_low \n");
// z_low = I2C0DAT; // z_low byte
// I2C0CONCLR = 0x0C; // Ackno clear and irq clear
//
// z = z_low|(z_high<<8);

// I2C0CONSET |= 0x10;
// I2C0CONCLR = 0x0C;
//
// printf("End i2c");

// data[0] = x;
// data[1] = y;
// data[2] = z;
//
// return data[0];
// }

void write_i2c(unsigned char Addr,unsigned char Data)
{
I2C0CONCLR = 0x6C;
I2C0CONSET |= 0x40;
I2C0CONSET |= 0x20;

while((I2C0STAT) != 0x08);
I2C0DAT = Addr;
I2C0CONCLR = 0x28;
printf("Write Address \t");

while((I2C0STAT) != 0x18);
I2C0DAT = Data;
I2C0CONCLR = 0x0C;
printf("Write Data \r\n");

while((I2C0STAT) != 0x28);
I2C0CONSET |= 0x10;
I2C0CONCLR = 0x0C;
}

char read_i2c(unsigned char Addr)
{
long int data;


I2C0CONCLR = 0x6C;
I2C0CONSET |= 0x40;
I2C0CONSET |= 0x20;

while((I2C0STAT) != 0x08);
I2C0DAT = Addr;
I2C0CONCLR = 0x28;
printf("Read Address \t");

while((I2C0STAT) != 0x40);
I2C0CONCLR = 0x0C;
printf("Wait acknowledge \t");

while((I2C0STAT) != 0x58);
data = I2C0DAT;
I2C0CONSET |= 0x10;
I2C0CONCLR = 0x0C;
printf("Read Data \r\n");

return data;
}

void compass_read(void)
{
int x_high,x_low,y_high,y_low,z_high,z_low;
long int x,y,z;

write_i2c(Write_Compass,0x02);
printf("Set Idel Mode Complete\n");
write_i2c(Write_Compass,0x00);
printf("Set Continous-Measurement Complete\n");

x_high = read_i2c(Read_Compass);
printf("Read X_High Complete\n");
x_low  = read_i2c(Read_Compass);
printf("Read X_Low Complete\n");
y_high = read_i2c(Read_Compass);
printf("Read Y_High Complete\n");
y_low  = read_i2c(Read_Compass);
printf("Read Y_Low Complete\n");
z_high = read_i2c(Read_Compass);
printf("Read Z_High Complete\n");
z_low  = read_i2c(Read_Compass);
printf("Read Z_Low Complete\n");

x = x_low|(x_high<<8);
printf("Value X = %d",(int)x);
y = y_low|(y_high<<8);
printf("Value Y = %d",(int)y);
z = z_low|(z_high<<8);
printf("Value Z = %d",(int)z);
}

int main(void)
{
Init_PIN();
init_uart0(38400);
init_i2c0();

while(1)
{
printf("\r\nStart Interface I2C \n\r");
compass_read();
}
}
#3
ขอบคุณคุณ tha อีกครั้ง และคำแนะนำของคุณ crywolf ด้วยครับ

ตอนนี้ก็เวิร์คแล้วครับ สีสันสวยงาม นั่งเล่นสนุกเลย

;D ;D ;D
#4
ผมดูของเว็บนี้เป็นตัวอย่างอ่ะ  http://www.thaimicrotron.com/Referrence/LCD/LCD-Module3.htm
ไม่รู้ว่าเซ็ตแล้วมันผิดตรงไหนป่าวหว่า
ช่วยดูโค๊ดข้างบนนี้ให้หน่อยว่าผิดพลาดตรงไหน
#5
ผมก็มือใหม่ไม่ได้เก่งอะไร

ตอนนี้ผมเขียนแต่ lpc2138 เนี้ยแระมีอยู่อันเดียว ขอยืมเค้ามา

อันอื่นไม่เคยเขียนหรอก แต่แนะนำให้ขยันดู datasheet ประกอบด้วยเยอะอ่ะนะ

เขียนลองผิดลองถูกไปก่อน ไม่เข้าใจก็โพสต์ถามได้ พี่ๆ เค้าให้คำตอบได้

อย่าไปรีบร้อนกับมัน
#6
ไม่ทราบว่าผมเขียนในการสั่งออก LCD ผิดตรงไหนป่าว
คือมันไม่แสดงข้อความตามนั้นเลย

/***************************************/
/*                 LCD                 */
/* LCD Routines for "ET-ARM7 KIT V1.0" */
/* Character 16x2 4-Bit Mode Interface */
/***************************************/

#include <LPC213x.H>
#include <stdio.h>

/*************************/
/* Define LCD PinIO Mask */
/*************************/
#define  LCD_D4     (1<<28)    // P1.28
#define  LCD_D5     (1<<29)    // P1.29
#define  LCD_D6     (1<<30)    // P1.30
#define  LCD_D7     (1<<31)    // P1.31
#define  LCD_EN     (1<<27)    // P1.27
#define  LCD_RS     (1<<25)    // P1.25
#define  LCD_DATA   (LCD_D4|LCD_D5|LCD_D6|LCD_D7)
#define  LCD_IOALL  (LCD_D4|LCD_D5|LCD_D6|LCD_D7|LCD_EN|LCD_RS)

#define  lcd_rs_set() IOSET1 |= LCD_RS // RS = 1 (Select Instruction)
#define  lcd_rs_clr() IOCLR1 |= LCD_RS // RS = 0 (Select Data)
#define  lcd_en_set() IOSET1 |= LCD_EN // EN = 1 (Enable)
#define  lcd_en_clr() IOCLR1 |= LCD_EN // EN = 0 (Disable)

#define  lcd_clear()          lcd_write_control(0x01) // Clear Display
#define  lcd_cursor_home()    lcd_write_control(0x02) // Set Cursor = 0
#define  lcd_display_on()     lcd_write_control(0x0E) // LCD Display Enable
#define  lcd_display_off()    lcd_write_control(0x08) // LCD Display Disable
#define  lcd_cursor_blink()   lcd_write_control(0x0F) // Set Cursor = Blink
#define  lcd_cursor_on()      lcd_write_control(0x0E) // Enable LCD Cursor
#define  lcd_cursor_off()     lcd_write_control(0x0C) // Disable LCD Cursor
#define  lcd_cursor_left()    lcd_write_control(0x10) // Shift Left Cursor
#define  lcd_cursor_right()   lcd_write_control(0x14) // Shift Right Cursor
#define  lcd_display_sleft()  lcd_write_control(0x18) // Shift Left Display
#define  lcd_display_sright() lcd_write_control(0x1C) // Shift Right Display

/********************/
/* Declare Function */
/********************/
void lcd_init(); // Initial LCD
void lcd_wait(); // Wait Busy LCD Complete
void lcd_out_data4(unsigned char); // Strobe 4-Bit Data to LCD
void lcd_write_byte(unsigned char); // Write 1 Byte Data to LCD
void lcd_write_control(unsigned char); // Write Instruction
void lcd_write_ascii(unsigned char); // Write LCD Display(ASCII)
void goto_cursor(unsigned char); // Set Position Cursor LCD
void lcd_print(unsigned char*); // Print Display to LCD
void delay(unsigned long int); // Delay Function

/*****************/
/* Main Function */
/*****************/
int main(void)

PINSEL2 = 0x00000000;

IODIR1 |= 0xFA000000; // P1.25 - P1.31 = Output
lcd_init();

while(1)
{
      goto_cursor(0x00); // ROW 1     
               //0123456789ABCDEF 
      lcd_print("** My Project **"); 

      goto_cursor(0x40);      // ROW 2
               //0123456789ABCDEF 
      lcd_print("**  TEST LCD  **");  }
}

/**************************/
/* Wait Bysy LCD Complete */
/**************************/
void lcd_wait()
{
int loop=500;  // Busy Delay Time     
while(loop--);  // Busy Loop
}

/****************************/
/* Strobe 4-Bit Data to LCD */
/****************************/
void lcd_out_data4(unsigned char val)
{
IOCLR1 |= (LCD_DATA);   // Reset 4-Bit Pin Data
IOSET1 |= (val<<28);  // DDDD EN,0,RS,0 0000 0000 0000 0000 0000 0000
}

/****************************/
/* Write Data 1 Byte to LCD */
/****************************/
void lcd_write_byte(unsigned char val)

lcd_out_data4((val>>4)&0x0F); // Strobe 4-Bit High-Nibble to LCD
lcd_en_set(); // EN = 1 = Strobe Signal 
lcd_en_clr(); // EN = 0
lcd_wait(); // Wait LCD Execute Complete

lcd_out_data4((val)&0x0F); // Strobe 4-Bit Low-Nibble to LCD
lcd_en_set(); // EN = 1 = Strobe Signal   
lcd_en_clr(); // EN = 0   
lcd_wait(); // Wait LCD Execute Complete
}

/****************************/
/* Write Instruction to LCD */
/****************************/
void lcd_write_control(unsigned char val)
{
lcd_rs_clr(); // RS = 0 = Instruction Select
lcd_write_byte(val); // Strobe Command Byte  
delay(50000);   // Approx. 2mS Delay
}

/****************************/
/* Write Data(ASCII) to LCD */
/****************************/
void lcd_write_ascii(unsigned char c)
{
lcd_rs_set(); // RS = 1 = Data Select
lcd_write_byte(c);     // Strobe 1 Byte to LCD   
}

/*******************************/
/* Initial 4-Bit LCD Interface */
/*******************************/
void lcd_init()
{
lcd_rs_clr(); // RS = 0 = Instruction Select
lcd_en_clr(); // EN = 0 
delay(50000); // wait VDD raise > 4.5V

lcd_write_control(0x33); // Initial (Set DL=1 3 Time, Reset DL=0 1 Time)
lcd_write_control(0x32);
lcd_write_control(0x28);  // Function Set (DL=0 4-Bit,N=1 2 Line,F=0 5X7)
lcd_write_control(0x0C);  // Display on/off Control (Entry Display,Cursor off,Cursor not Blink)
lcd_write_control(0x06);  // Entry Mode Set (I/D=1 Increment,S=0 Cursor Shift)
lcd_write_control(0x01);  // Clear Display  (Clear Display,Set DD RAM Address=0)
}

/***************************/
/* Set LCD Position Cursor */
/***************************/
void goto_cursor(unsigned char i)
{
i |= 0x80; // Set DD-RAM Address Command
lcd_write_control(i); 
}

/************************************/
/* Print Display Data(ASCII) to LCD */
/************************************/
void lcd_print(unsigned char* str)
{
int i;

for (i=0;i<16 && str[i]!=0;i++)  // 16 Character Print
{
lcd_write_ascii(str[i]); // Print Byte to LCD
}
}

/***********************/
/* Delay Time Function */
/*    1-4294967296     */
/***********************/
void delay(unsigned long int count1)
{
while(count1 > 0) {count1--;} // Loop Decrease Counter
}
#7
ขอบคุณท่าน tha และ firmware.c มากครับที่มาแนะนำ

ในที่สุดก็ได้แล้วครับหลังจากดันทุลังไม่อยากเสียตัง ผมลองปรับ TIMER จาก Interrupt ทุก 1ms เป็น 100 ms
และเปลี่ยน ไม่ใช้ float ตามที่ท่านบอก ก็เห็นผลเลยครับ

ตอนนี้อยากให้มันแสดงผ่าน LCD แทนเลยไปซื้อ LCD 16x2 มาต่อตรงช่อง P1.25 - P1.31 ที่ทาง ETT ทำมาต่อแบบ 4 bit ไรเนี้ยแระ
ตอนนี้หน้าจอไฟสีฟ้าสว่างสวยงามมาก แถวแรกขึ้นเป็นสี่เหลี่ยมขาว ๆ



** ปัญหาคือสั่งออก LCD ยังไงอ่ะครับ **

:'( :'( :'(
#8
ขอบคุณสำหรับคำตอบครับผม