ผมได้อ่านหนังสือของคุณเรื่อง 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>>
;
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>>
+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 ****************/