Title: ช่วยดู code C-program ให้ด้วยนะครับ เกี่ยวกับ I2C Interface Post by: navakun on October 16, 2010, 04:20:57 PM ผมได้อ่านหนังสือของคุณเรื่อง C Programming for AVR Microcontroller and WinAVR(C Compiler) AVR เล่ม1
เขียนโดย คุณประจิน พลังสันติกุล คือผมต้องการให้มุมที่อ่านได้จาก IC compass(HMC6352) แสดงออกมาทาง Hyperterminal คับ เหมือนผล Run ในเวปนี้ครับ http://wara.com/article-761.html แต่ในเวปนี้เค้าใช้ C++ แต่ของผมใช้ C data sheet ICcompass-HMC6352 in this website http://www.datasheetarchive.com/HMC6352-datasheet.html ผมได้เขียนโปรแกรมเพื่อให้ไมโครคอลโทนเลอร์ AVRmega32 รับค่ามุมจาก IC compass ให้ได้ ตอนนี้ผมสามารถทำให้ AVRmega32 ติดต่อกับ IC compass ได้แล้วครับ แต่ยัง Get data เอาค่ามุมออกมาผ่านทาง HyperTerminal ยังไม่ได้เลยครับ จึงอยากขอความช่วยเหลือ ช่วยดูโปรแกรมให้หน่อยคับ ผลRun ของโปรแกรมนี้มันออกมาเป็น Get data Heading: HMC6352 Heading output Heading = 0 <มุมมันเป็น0ตลอดเลยครับโดย 3 บรรทัดที่ว่านี้จะ delay 500 ms ตลอดครับ> (ผมคิดว่าหน้าจะผิดที่ function HMC6352_Read ) ถ้ายังไงช่วยดูหน่อยนะคับ จักขอบพระคุณยิ่ง /****************************** begin Program **********/ #include<avr/io.h> //AVR IO definitions #include<avr/interrupt.h> //Interrupt Service routine #include<util/twi.h> //AVR TWI interface #include <stdio.h> #define F_CPU 11059200L // MHz #include<util/delay.h> //for delay /*************************begin UART *****************************/ //#include "lib_UART.c" //library UART int uart_putchar(char c, FILE *stream); FILE usart_out = FDEV_SETUP_STREAM(uart_putchar, NULL, _FDEV_SETUP_WRITE); int uart_putchar(char c, FILE *stream){ if(c=='\n'){ uart_putchar('\r', stream); } // Wait for empty transmit buffer while(!(UCSRA & (1<<UDRE)) ); UDR=c; return 0; } void init_usart(unsigned long baud){ unsigned int ubrr; //Set baud rate, baud=Fosc/(16*(UBRR+1)) ubrr=(unsigned int)(F_CPU/16/baud)-1; UBRRH = (unsigned char)(ubrr>>8); UBRRL = (unsigned char)ubrr; UCSRB = (1<<TXEN); //Set frame to 8data, 1stop bit. UCSRC = (1<<URSEL)|(1<<UCSZ1)|(1<<UCSZ0); } /***************************** End UART ********************/ #define TWI_SLA 0x42 //slave address for write #define TWI_SLA2 0x43 //slave address for read #define TWI_SLA3 0x41 //slave for get data command typedef unsigned char byte; //data type typedef unsigned int word; typedef struct{ // Structure word degree; } Heading_TYPE; Heading_TYPE Heading; void delay_ms(uint8_t i) //delay_ms { for (;i > 0; i--) _delay_ms(1); } /****************************************** TWI start*******/ uint8_t TWI_Start() //** uint8_t as same as unsigned char { // Send START condition TWCR = (1<<TWINT)|(1<<TWEN)|(1<<TWSTA); // wait for transmission while (!(TWCR & (1<<TWINT))); switch (TW_STATUS){ // start condition transmitted case TW_START: case TW_REP_START: return 1; // Arbitration lost in SLA+W or data case TW_MT_ARB_LOST: default: return 0; } } /****************************************** TWI Stop *******/ void TWI_Stop() { // Send STOP condition TWCR = (1<<TWINT)|(1<<TWEN)|(1<<TWSTO); } /****************************************** TWI Read *******/ uint8_t TWI_Read(uint8_t ack_bit) { if (ack_bit){ // Start transmission,ACK Received TWCR = (1<<TWINT)|(1<<TWEN)|(1<<TWEA); } else { // Start transmission,NACK Received TWCR = (1<<TWINT)|(1<<TWEN); } // Wait for transmission while (!(TWCR & (1<<TWINT))); switch (TW_STATUS){ // Data received,ACK returned case TW_MR_DATA_ACK: // Data received,NACK returned case TW_MR_DATA_NACK: break; // Arbitration lost in SLA+R or NACK case TW_MR_ARB_LOST: default: return 0; } return(TWDR); // Read TWDR } /************************************* TWI Write ***********/ uint8_t TWI_Write(uint8_t uc_data,uint8_t ack_bit) { TWDR = uc_data; // Load SLA_W to TWDR if (ack_bit){ // Start transmission, ACK Received TWCR = (1<<TWINT)|(1<<TWEN)|(1<<TWEA); } else { // Start transmission, NACK Received TWCR = (1<<TWINT)|(1<<TWEN); } // Wait for transmission while (!(TWCR & (1<<TWINT))); switch (TW_STATUS){ // SLA+W transmitted, ACK received case TW_MT_SLA_ACK: // SLA+W transmitted, NACK received case TW_MT_SLA_NACK: return 1; // SLA+R transmitted, ACK received case TW_MR_SLA_ACK: // SLA+R transmitted, NACK received case TW_MR_SLA_NACK: return 2; // Data transmitted, ACK received case TW_MT_DATA_ACK: // Data transmitted, NACK received case TW_MT_DATA_NACK: return 3; // Arbitration lost in SLA+W or data case TW_MT_ARB_LOST: default: return 0; } } /************************************ HMC6352_Read *******/// uint8_t HMC6352_Read(unsigned char ctl) { unsigned char i=0,m=0; TWI_Start(); // Start condition TWI_Write(TWI_SLA+TW_WRITE,1); // TWI Write mode TWI_Write(TWI_SLA3+TW_WRITE,1); // Control byte TWI_Stop(); _delay_ms(40); TWI_Start(); TWI_Write(TWI_SLA2+TW_READ,1); i = TWI_Read(ctl); m = TWI_Read(ctl); TWI_Stop(); // Stop condition return((m>>8)+i); // return 16 bit } /************************************ HMC6352_Write ******/ void HMC6352_Write(unsigned char ctl,unsigned char h) { TWI_Start(); // Start condition TWI_Write(TWI_SLA+TW_WRITE,1); // TWI Write mode TWI_Write(ctl,1); // Control byte TWI_Write(h,1); // Data byte TWI_Stop(); // Stop condition } /************************************ Heading *****/ // Get Data from Heading(HMC6352) void Read_Heading(void) { Heading.degree = HMC6352_Read(0x00); } // Display Heading(HMC6352) void Display_Heading(void){ printf("HMC6352 Heading output\n"); printf("Heading = %u\n",Heading.degree); } /*********************************** main function *******/ int main(void) { DDRD = 0x00; //Init_Serial(96); // Init Serial port init_usart(115200); stdout = &usart_out; // fclk/64 prescaler TCCR1B = (1<<CS12); while(1){ if(PIND == 0x7F){ printf("Get data Heading:\n"); Read_Heading(); Display_Heading(); _delay_ms(500); } } return 0; } /************************** end program ****************/ |