Chào mọi người,
Em đang làm giao tiếp SPI giữa con vi điều khiển CC1110 ( nó lập trình thanh ghi giống AVR thôi ạ) với con ADXL345Z (cảm biến gia tốc-chuyển dộng đấy ạ) bằng giao tiếp SPI.
- Đầu tiên, em làm cái project giao tiếp giữa CC1110 và ADXL345 thông qua 4 dây : MOSI, MISO, SCL, CS. Cái project đấy đã chạy rồi ạ, em có thể dùng con CC1110 đọc dữ liệu từ con ADXL345 rồi.
- Thầy giáo em bắt nối chân CS của ADXL345 xuống đất, vì theo nguyên tắc là chỉ có 1 vi điều khiển và một Vi xử lý thì nối chân CS của ADXL345 xuống đất thì nó luôn được chọn là slave của CC1110. Nhưng mà khi em nối chân CS xuống đất thì em không thể nào giao tiếp lại được với con ADXL345 nữa. Mặc dù khi cấu hình SPI cho CC1110 em đã không cấu hình chân CS để điều khiển con Slave (ADXL345) nữa. Em không biết tại sao chân CS chỉ là chân chọn chip, mà sao khi nối xuống đất nó lại không thể hoạt động được nữa.
Mọi người có thể giúp em trả lời thắc mắc, với gợi ý cho em hướng để giải quyết ván đề này không ạ.
Cám ơn mọi người nhiều ạ
Đây là hàm em dùng để giao tiếp với ADXL345:
void SPI_init(void)
{
/************************************************** *************************
* Setup I/O ports
*
* Port and pins used by USART0 operating in SPI-mode are
* MISO (MI): P0_2
* MOSI (MO): P0_3
* SSN (SS) : P0_4
* SCK (C) : P0_5
*/
// Configure USART0 for Alternative 1 => Port P0 (PERCFG.U0CFG = 0)
// To avoid potential I/O conflict with USART1:
// configure USART1 for Alternative 2 => Port P1 (PERCFG.U1CFG = 1)
PERCFG = (PERCFG & ~PERCFG_U0CFG) | PERCFG_U1CFG;
//
// Give priority to USART 0 over USART 1 for port 0 pins
P2DIR = (P2DIR & ~P2DIR_PRIP0) | P2DIR_PRIP0_0;
// Set pins 2, 3 and 5 as peripheral I/O and pin 4 as GPIO output
P0SEL = P0SEL | BIT5 | BIT3 | BIT2;
//P0DIR |= BIT4;// không dùng BIT4 để cấu hình chân CS điều khiển nữa.
// P0_4=0;
// Set clock for SPI protocol,
SLEEP &= ~(0x04); // Power up both oscillator
while( !(SLEEP & 0x40)); // Wait until XOSC is stable
CLKCON = (CLKCON & ~(0x00 | 0x40)) | 0x00;
while (CLKCON & 0x40);
SLEEP |= 0x04; // Oscillator not selected by CLKCON.OSC bit is powered down
// Set USART to SPI mode and Master mode
U0CSR &= ~(0x80 | 0x20);
U0BAUD = SPI_BAUD_M;
U0GCR = (U0GCR & ~(U0GCR_BAUD_E))| SPI_BAUD_E | U0GCR_CPOL | U0GCR_CPHA | U0GCR_ORDER;
}
//---------------------------------------------------------
void ADXL345_Init()
{
//by writing the value 0x01 to the DATA_FORMAT register.
// SPI_Write_byte(POWER_CTL, 0x00);
halWait(50);
SPI_Write_byte(DATA_FORMAT, 0x0B);
halWait(50);
//SPI_Write_byte(INT_ENABLE1, 0x80);
// halWait(50);
SPI_Write_byte(BW_RATE, 0x0A);
halWait(50);
SPI_Write_byte(POWER_CTL, 0x08); //Measurement mode
halWait(50);
}
//----------------------------------------------------------
void halWait(uint8_t wait){
uint32_t largeWait;
if(wait == 0)
{return;}
largeWait = ((uint16_t) (wait << 7));
largeWait += 59*wait;
largeWait = (largeWait >> CLKSPD);
while(largeWait--);
return;
}
//--------------------------------
uint8_t SPI_Write_Read_Byte( uint8_t data)
{
uint32_t timeout = 0x30000;
INT8U received_data=0;
U0DBUF= data;
while(!(U0CSR & U0CSR_TX_BYTE)&& (--timeout!=0))
if(timeout==0) return 2;
U0CSR &= ~U0CSR_TX_BYTE; // Wait for byte to be received from slave
halWait(10);
received_data=U0DBUF;
return received_data;
}
void SPI_Write_byte(uint8_t res_adr, uint8_t data)
{
SPI_Write_Read_Byte(res_adr);
SPI_Write_Read_Byte(data);
}
//----- read a 8-bit data ------------------
uint8_t SPI_Read_byte(uint8_t res_adr)
{
uint8_t data;
uint8_t address=0;
address=res_adr|RD;
SPI_Write_Read_Byte(address);
data=SPI_Write_Read_Byte(0);
return data;
}
void ADXL345_Read_Buf(uint8_t reg, INT8U *pBuf, uint8_t Len)
{
uint8_t i;
uint8_t address;
address = reg|RD;
if (Len>1)//multiple bytes reading
{
address=address|MB;
} // Set CSN low, init SPI tranaction
SPI_Write_Read_Byte(address); // Select register to write to and read status unsigned char
for(i=0;i<Len;i++)
{
pBuf[i] = SPI_Write_Read_Byte(0x00); //cach nay cung dung)
halWait(5);
}
}
Và đây là chương trình chính:
void main( void )
{
INT8U Buffer[1]={0};
uint8_t Bufferx[6]={0,0,0,0,0,0};
SPI_init();
__display(_DBG_Main, "Start \0", EOL );
ADXL345_Init();
//SPI_Write_byte(INT_ENABLE1, 0x27);
Buffer[0]=SPI_Read_byte(DEVID);
halWait(50);
__display(_DBG_Main, "data= \0", x,1,Buffer[0], EOL );
halWait(10);
while(1)
{
ADXL345_Read_Buf(DATAX0, Bufferx, 6);
//The ADXL345 gives 10-bit acceleration values, but they are stored as bytes (8-bits). To get the full value, two bytes must be combined for each axis.
//The X value is stored in values[0] and values[1].
acc_x = ((INT8U)Bufferx[1]<<8)|(INT8U)Bufferx[0];
//The Y value is stored in values[2] and values[3].
acc_y = ((INT8U)Bufferx[3]<<8)|(INT8U)Bufferx[2];
//The Z value is stored in values[4] and values[5].
acc_z = ((INT8U)Bufferx[5]<<8)|(INT8U)Bufferx[4];
__display(_DBG_Main, "X:Y:Z= \0", x , 1, acc_x, c, 1, ':', x ,1, acc_y, c, 1, ':', x ,1, acc_z, EOL);
}
}
Em đang làm giao tiếp SPI giữa con vi điều khiển CC1110 ( nó lập trình thanh ghi giống AVR thôi ạ) với con ADXL345Z (cảm biến gia tốc-chuyển dộng đấy ạ) bằng giao tiếp SPI.
- Đầu tiên, em làm cái project giao tiếp giữa CC1110 và ADXL345 thông qua 4 dây : MOSI, MISO, SCL, CS. Cái project đấy đã chạy rồi ạ, em có thể dùng con CC1110 đọc dữ liệu từ con ADXL345 rồi.
- Thầy giáo em bắt nối chân CS của ADXL345 xuống đất, vì theo nguyên tắc là chỉ có 1 vi điều khiển và một Vi xử lý thì nối chân CS của ADXL345 xuống đất thì nó luôn được chọn là slave của CC1110. Nhưng mà khi em nối chân CS xuống đất thì em không thể nào giao tiếp lại được với con ADXL345 nữa. Mặc dù khi cấu hình SPI cho CC1110 em đã không cấu hình chân CS để điều khiển con Slave (ADXL345) nữa. Em không biết tại sao chân CS chỉ là chân chọn chip, mà sao khi nối xuống đất nó lại không thể hoạt động được nữa.
Mọi người có thể giúp em trả lời thắc mắc, với gợi ý cho em hướng để giải quyết ván đề này không ạ.
Cám ơn mọi người nhiều ạ
Đây là hàm em dùng để giao tiếp với ADXL345:
void SPI_init(void)
{
/************************************************** *************************
* Setup I/O ports
*
* Port and pins used by USART0 operating in SPI-mode are
* MISO (MI): P0_2
* MOSI (MO): P0_3
* SSN (SS) : P0_4
* SCK (C) : P0_5
*/
// Configure USART0 for Alternative 1 => Port P0 (PERCFG.U0CFG = 0)
// To avoid potential I/O conflict with USART1:
// configure USART1 for Alternative 2 => Port P1 (PERCFG.U1CFG = 1)
PERCFG = (PERCFG & ~PERCFG_U0CFG) | PERCFG_U1CFG;
//
// Give priority to USART 0 over USART 1 for port 0 pins
P2DIR = (P2DIR & ~P2DIR_PRIP0) | P2DIR_PRIP0_0;
// Set pins 2, 3 and 5 as peripheral I/O and pin 4 as GPIO output
P0SEL = P0SEL | BIT5 | BIT3 | BIT2;
//P0DIR |= BIT4;// không dùng BIT4 để cấu hình chân CS điều khiển nữa.
// P0_4=0;
// Set clock for SPI protocol,
SLEEP &= ~(0x04); // Power up both oscillator
while( !(SLEEP & 0x40)); // Wait until XOSC is stable
CLKCON = (CLKCON & ~(0x00 | 0x40)) | 0x00;
while (CLKCON & 0x40);
SLEEP |= 0x04; // Oscillator not selected by CLKCON.OSC bit is powered down
// Set USART to SPI mode and Master mode
U0CSR &= ~(0x80 | 0x20);
U0BAUD = SPI_BAUD_M;
U0GCR = (U0GCR & ~(U0GCR_BAUD_E))| SPI_BAUD_E | U0GCR_CPOL | U0GCR_CPHA | U0GCR_ORDER;
}
//---------------------------------------------------------
void ADXL345_Init()
{
//by writing the value 0x01 to the DATA_FORMAT register.
// SPI_Write_byte(POWER_CTL, 0x00);
halWait(50);
SPI_Write_byte(DATA_FORMAT, 0x0B);
halWait(50);
//SPI_Write_byte(INT_ENABLE1, 0x80);
// halWait(50);
SPI_Write_byte(BW_RATE, 0x0A);
halWait(50);
SPI_Write_byte(POWER_CTL, 0x08); //Measurement mode
halWait(50);
}
//----------------------------------------------------------
void halWait(uint8_t wait){
uint32_t largeWait;
if(wait == 0)
{return;}
largeWait = ((uint16_t) (wait << 7));
largeWait += 59*wait;
largeWait = (largeWait >> CLKSPD);
while(largeWait--);
return;
}
//--------------------------------
uint8_t SPI_Write_Read_Byte( uint8_t data)
{
uint32_t timeout = 0x30000;
INT8U received_data=0;
U0DBUF= data;
while(!(U0CSR & U0CSR_TX_BYTE)&& (--timeout!=0))
if(timeout==0) return 2;
U0CSR &= ~U0CSR_TX_BYTE; // Wait for byte to be received from slave
halWait(10);
received_data=U0DBUF;
return received_data;
}
void SPI_Write_byte(uint8_t res_adr, uint8_t data)
{
SPI_Write_Read_Byte(res_adr);
SPI_Write_Read_Byte(data);
}
//----- read a 8-bit data ------------------
uint8_t SPI_Read_byte(uint8_t res_adr)
{
uint8_t data;
uint8_t address=0;
address=res_adr|RD;
SPI_Write_Read_Byte(address);
data=SPI_Write_Read_Byte(0);
return data;
}
void ADXL345_Read_Buf(uint8_t reg, INT8U *pBuf, uint8_t Len)
{
uint8_t i;
uint8_t address;
address = reg|RD;
if (Len>1)//multiple bytes reading
{
address=address|MB;
} // Set CSN low, init SPI tranaction
SPI_Write_Read_Byte(address); // Select register to write to and read status unsigned char
for(i=0;i<Len;i++)
{
pBuf[i] = SPI_Write_Read_Byte(0x00); //cach nay cung dung)
halWait(5);
}
}
Và đây là chương trình chính:
void main( void )
{
INT8U Buffer[1]={0};
uint8_t Bufferx[6]={0,0,0,0,0,0};
SPI_init();
__display(_DBG_Main, "Start \0", EOL );
ADXL345_Init();
//SPI_Write_byte(INT_ENABLE1, 0x27);
Buffer[0]=SPI_Read_byte(DEVID);
halWait(50);
__display(_DBG_Main, "data= \0", x,1,Buffer[0], EOL );
halWait(10);
while(1)
{
ADXL345_Read_Buf(DATAX0, Bufferx, 6);
//The ADXL345 gives 10-bit acceleration values, but they are stored as bytes (8-bits). To get the full value, two bytes must be combined for each axis.
//The X value is stored in values[0] and values[1].
acc_x = ((INT8U)Bufferx[1]<<8)|(INT8U)Bufferx[0];
//The Y value is stored in values[2] and values[3].
acc_y = ((INT8U)Bufferx[3]<<8)|(INT8U)Bufferx[2];
//The Z value is stored in values[4] and values[5].
acc_z = ((INT8U)Bufferx[5]<<8)|(INT8U)Bufferx[4];
__display(_DBG_Main, "X:Y:Z= \0", x , 1, acc_x, c, 1, ':', x ,1, acc_y, c, 1, ':', x ,1, acc_z, EOL);
}
}
Comment