Other Parts Discussed in Thread: AFE4300
Tool/software: Code Composer Studio
I want to use BCM mode and just one channel.
when atemega128 gives AFE4300-EVM board "read ADC"protocol, the AFE4300 replys incorrect result value.
and add an oscilloscope capture photo.
yellow line is MOSI
puple line is MISO
here my code.
please help me
#define F_CPU 16000000UL
#include <avr/io.h>
#include <avr/interrupt.h>
#include <util/delay.h>
#define USART_BAUDRATE 500000
#define BAUD_PRESCALE (((F_CPU/(USART_BAUDRATE*16UL)))-1)
#define sbi(PORTX , BitX) PORTX |= (1 << BitX) // 비트 SET 명령 정의
#define cbi(PORTX , BitX) PORTX &= ~(1 << BitX) // 비트 CLEAR 명령 정의
/***************************
AFE4300 register address definitions
****************************/
volatile unsigned char ADDRESS_ADC_DATA_RESULT=0x00; // (Address 0x00, Default 0x0000)
volatile unsigned char ADDRESS_ADC_CONTROL_REGISTER1=0x01; // (Address 0x01, Default 0x01C3)
volatile unsigned char ADDRESS_MISC_REGISTER1=0x02; // (Address 0x02, Default 0x8000)
volatile unsigned char ADDRESS_MISC_REGISTER2=0x03; // (Address 0x03, Default 0x7FFF)
volatile unsigned char ADDRESS_DEVICE_CONTROL1=0x09; // (Address 0x09, Default 0x0000)
volatile unsigned char ADDRESS_ISW_MUX=0x0A; // (Address 0x0A, Default 0x0000)
volatile unsigned char ADDRESS_VSENSE_MUX=0x0B; // (Address 0x0B, Default 0x0000)
volatile unsigned char ADDRESS_IQ_MODE_ENABLE=0x0C; // (Address 0x0C, Default 0x0000)
volatile unsigned char ADDRESS_WEIGHT_SCALE_CONTROL=0x0D; //(Address 0x0D, Default 0x0000)
volatile unsigned char ADDRESS_BCM_DAC_FREQ=0x0E; // (Address 0x0E, Default 0x0000)
volatile unsigned char ADDRESS_DEVICE_CONTROL2=0x0F; // (Address 0x0F, Default 0x0000)
volatile unsigned char ADDRESS_ADC_CONTROL_REGISTER2=0x10; // (Address 0x10, Default 0x0000)
volatile unsigned char ADDRESS_MISC_REGISTER3=0x1A; //(Address 0x1A, Default 0x0000)
volatile char action=0;
volatile char drdyokay = 0;
volatile char a = 0;
volatile int count=0;
volatile char status=0;
volatile char UART_Ready;
volatile char UART_RxChar;
volatile char UART_Buffer;
volatile char UART_ReceivedChar;
ISR(USART0_RX_vect)
{
UART_ReceivedChar = 1;
UART_RxChar = UDR0;
}
ISR(USART0_TX_vect)
{
UART_Ready = 1;
}
void USART_init()
{
DDRE = 0x02;
UCSR0A |= 0b00000000; // Double the USART1 Transmission Speed
UCSR0B = 0b11011000; // RX complete Interrupt enable(bit7), RX,TX enable(bit 4,3)
UCSR0C = 0b00000110; // no parity bit, 1 stop bit, 8bit data
UBRR0H=0x00;
UBRR0L=0x01;
}
void interrupt_init()
{
SREG=0x80;
EICRA = 0x02; // INT0 = falling edge trigger
EIMSK = 0x01; // enable INT0
EIFR = 0xFF; // clear interrupt flag
//인터럽트 전역 허용!
}
void TIMER_Init(void)
{
TIMSK=0x01;
TCCR0=0x05; // clk/128
//TCCR0=0x01;
TCNT0=0x83;
sei();
}
ISR(TIMER0_OVF_vect)
{
if(status>0)
{
if(count==10)
{
action=1;
count=0;
}
else
{
count++;
}
}
TCNT0=0x83; // (16000000/128)/125 = 1000 -> 0.001 sec
}
ISR(INT0_vect) // INT0 interrupt function
{
if(a==0)
{
sbi(PORTA, 0);
a=1;
}
else if(a==1)
{
cbi(PORTA, 0);
a=0;
}
drdyokay=1;
}
void AFE4300_WRITE(unsigned char address,unsigned char high,unsigned char low)
{
cbi(PORTB, 0); // CS = 0
SPDR = address;
while((SPSR&0x80)!=0x80); // transmit complete ?
SPDR = high;
while((SPSR&0x80)!=0x80); // transmit complete ?
SPDR = low;
while((SPSR&0x80)!=0x80); // transmit complete ?
sbi(PORTB, 0); // CS = 1
}
void set_up()
{
AFE4300_WRITE(ADDRESS_ADC_CONTROL_REGISTER1,0xC1,0x40);
AFE4300_WRITE(ADDRESS_MISC_REGISTER1,0x00,0x00);
AFE4300_WRITE(ADDRESS_MISC_REGISTER2,0xFF,0xFF);
AFE4300_WRITE(ADDRESS_DEVICE_CONTROL1,0x60,0x06);
AFE4300_WRITE(ADDRESS_IQ_MODE_ENABLE,0x00,0x00);
AFE4300_WRITE(ADDRESS_WEIGHT_SCALE_CONTROL,0x00,0x00);
AFE4300_WRITE(ADDRESS_BCM_DAC_FREQ,0x00,0x40); //DAC freq=64KHz
AFE4300_WRITE(ADDRESS_DEVICE_CONTROL2,0x00,0x00);
AFE4300_WRITE(ADDRESS_ADC_CONTROL_REGISTER2,0x00,0x63);
AFE4300_WRITE(ADDRESS_MISC_REGISTER3,0x00,0x30);
}
void measurement(char c_mode)
{
switch (c_mode)
{
case 0: // calibarion off
AFE4300_WRITE(ADDRESS_ISW_MUX, 0x00,0x00);
AFE4300_WRITE(ADDRESS_VSENSE_MUX,0x00,0x00);
break;
case 1: // calibration (R58 99ohm)
AFE4300_WRITE(0x0A,0x01,0x01);
AFE4300_WRITE(0x0B,0x01,0x01);
// AFE4300_WRITE(ADDRESS_ADC_CONTROL_REGISTER1,0xC1,0xC3);
break;
case 2: //calibration (R57 949ohm)
AFE4300_WRITE(0x0A,0x02,0x02);
AFE4300_WRITE(0x0B,0x02,0x02);
// AFE4300_WRITE(ADDRESS_ADC_CONTROL_REGISTER1,0xC1,0xC3);
break;
case 3: //calibration (R56 699ohm)
AFE4300_WRITE(0x0A,0x02,0x01);
AFE4300_WRITE(0x0B,0x02,0x01);
// AFE4300_WRITE(ADDRESS_ADC_CONTROL_REGISTER1,0xC1,0xC3);
break;
}
}
char Datachk(void)
{
if(UART_ReceivedChar!=0)
{
return 1;
}
else
{
return 0;
}
}
char UARTreceive(void)
{
while(!UART_ReceivedChar);
UART_ReceivedChar = 0;
return UART_RxChar;
}
void UARTsend(char TxData)
{
while(!UART_Ready);
UART_Ready = 0;
UDR0=TxData;
}
unsigned char SPI_transfer(unsigned char Data)
{
SPDR = Data; // Data 송신
while(!(SPSR & _BV(SPIF))); // 송신 확인
return SPDR; // 수신 받은 데이터 반환
}
void ADC_READ() // read a byte
{
unsigned char high=0, low=0;
cbi(PORTB, 0); // CS = 1
SPDR = 0x20; //read ADCresister
while((SPSR & 0x80) == 0x00); // transmit complete ?
SPDR=0x00;
while((SPSR & 0x80) == 0x00);
high=SPDR;
SPDR=0x00;
while((SPSR & 0x80) == 0x00);
low = SPDR;
sbi(PORTB, 0);
UARTsend(high);
UARTsend(low);
}
void cailbration() // calibaration
{
measurement(1);
}
void Act(char cmd)
{
switch(cmd)
{
case 0x01: action=1; measurement(3); break; // Start Measurement
case 0x10: action=0; break; // Stop Measurement
case 0x0C: cailbration();break; // setting calibration
}
}
void MAIN_Init(void)
{
cbi(DDRE, 0); // RXD0 핀 입력으로 설정
sbi(DDRE, 1); // TXD0 핀 출력으로 설정
sbi(DDRB, 0); // /SS 출력으로 설정
sbi(DDRB, 1); // SCK 출력으로 설정
sbi(DDRB, 2); // MOSI 출력으로 설정
cbi(DDRB, 3); // MISO 입력으로 설정
//sbi(PORTB, 0); // /SS 1 입력
sbi(DDRA, 0); //test핀 설정
cbi(PORTA, 0);
SPSR = 0;
//SPCR = 85;
SPCR= 0x54;
}
int value = 0;
int main(void){
char command;
USART_init();
MAIN_Init();
TIMER_Init();
interrupt_init();
UART_Ready = 1;
set_up();
status = 1;
for(;;){
if(action==1)
{
action=0;
}
if(Datachk())
{
command = UARTreceive();
Act(command);
ADC_READ();
}
}
}