ĐỌC ADC_ KHÔNG THÀNH CÔNG

phandinhkhanh1995

Thành Viên PIF
Nhóm em đọc 1 kênh ADC ss3 thì có vẻ ổn nhưng khi code cho quá trình lấy 4 mẫu gặp một số trục trặc : khi nó đọc kết quả không chấp nhận nổi :(( nó cứa hàng thì 000 000 000 hàng thì số khác, mặc dù mạch hồng ngoại nhóm em test từng cái chạy khá ổn định. Dưới đây là code nhóm mong mọi người giúp mình tìm ra giải pháp !!! :D:
#include <stdbool.h>
#include <stdint.h>
#include "inc/hw_memmap.h"
#include "inc/hw_types.h"
#include "driverlib/gpio.h"
#include "driverlib/sysctl.h"
#include "driverlib/pin_map.h"
#include "driverlib/adc.h"
#include "driverlib/uart.h"
#include "driverlib/interrupt.h"

////////////////////////////////////////////
uint32_t ui32ADC0Value[4];
//bool ADCFlag;

void ConfigUart(void)
{
SysCtlPeripheralEnable(SYSCTL_PERIPH_UART0);
SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOA);
//
// Set GPIO A0 and A1 as UART pins.
//
GPIOPinConfigure(GPIO_PA0_U0RX);
GPIOPinConfigure(GPIO_PA1_U0TX);
GPIOPinTypeUART(GPIO_PORTA_BASE, GPIO_PIN_0 | GPIO_PIN_1);

//
// Configure the UART for 115,200, 8-N-1 operation.
//
UARTConfigSetExpClk(UART0_BASE, SysCtlClockGet(), 9600,
(UART_CONFIG_WLEN_8 | UART_CONFIG_STOP_ONE |
UART_CONFIG_PAR_NONE));
}
void configADC(void)
{
//mảng chứa giá trị mẫu mỗi lần lấy, ở đây ta cần lấy mỗi lần 4 mẫu
//To do: đổi kích thước của mảng tùy theo số mẫu muốn lấy

//Set system clock


//Enable ADC0
SysCtlPeripheralEnable(SYSCTL_PERIPH_ADC0);

//Enable port E và config cho các chân PE0-PE3 thành chân ADC
//To do: đổi sang chân GPIO theo nhu cầu (cần xem datasheet để biết các chân nào có chức năng ADC)
SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOD);
GPIOPinTypeADC(GPIO_PORTD_BASE, GPIO_PIN_0 | GPIO_PIN_1 | GPIO_PIN_2 | GPIO_PIN_3);

/*Config cho ADC sample sequencer, ở đây ta dùng SS1, chọn kiểu kích hoạt (trigger) bằng
poccesor, và độ ưu tiên là 0 (ưu tiên cao nhất) */
//To do: chỉnh lại SS cần dùng, kiểu trigger hoặc độ ưu tiên (nếu dùng nhiều SS)
ADCSequenceConfigure(ADC0_BASE, 1, ADC_TRIGGER_PROCESSOR, 0);

/* Config cho 4 step của SS1 (tương ứng với 4 mẫu từ 4 kênh). Ở đây giả sử ta cần lấy mẫu từ 4 kênh
(channel) theo thứ tự 0, 1, 2, 3 tương ứng với các chân AIN0-AIN3 hay PE3-PE0, sau khi lấy mẫu kênh
cuối sẽ ngừng lấy mẫu và bật cờ ngắt */
//To do: chỉnh lại kênh (xem datasheet để biết các kênh và chân tương ứng)
ADCSequenceStepConfigure(ADC0_BASE, 1, 0, ADC_CTL_CH0);
ADCSequenceStepConfigure(ADC0_BASE, 1, 1, ADC_CTL_CH1);
ADCSequenceStepConfigure(ADC0_BASE, 1, 2, ADC_CTL_CH2);
ADCSequenceStepConfigure(ADC0_BASE,1,3,ADC_CTL_CH3|ADC_CTL_IE|ADC_CTL_END);

//Enable SS1
ADCSequenceEnable(ADC0_BASE, 1);
}
////////////////////////////////////////////////////////////////////
//void ADCIsr(void)
//{
//ADCIntClear(ADC0_BASE, 3);//Clear Interrupt Flag
//ADCSequenceDataGet(ADC0_BASE, 3, ui32ADC0Value);//Get ADC result
//ADCFlag = true;
//}
///////////////////////////////////////////////////////////////////
void
UARTSend(const uint8_t *pui8Buffer, uint32_t ui32Count)
{
//
// Loop while there are more characters to send.
//
while(ui32Count--)
{
//
// Write the next character to the UART.
//
UARTCharPutNonBlocking(UART0_BASE, *pui8Buffer++);
}
}

//////////////////////////////////////////////////////////////

void ADCSend0(uint32_t val0)
{
uint8_t buf[5];
val0 = val0 * 330 / 4096;
buf[0] = val0 / 100 + 0x30;
buf[1] = (val0 % 100) / 10 + 0x30;
buf[2] = val0 % 10 + 0x30;

buf[3] = ' ';
buf[4] = '\t';
UARTSend(buf, 5);
}
//////////////////////////////////////////////////////////////

void ADCSend1(uint32_t val1)
{
uint8_t buf[5];
val1 = val1 * 330 / 4096;
buf[0] = val1 / 100 + 0x30;
buf[1] = (val1 % 100) / 10 + 0x30;
buf[2] = val1 % 10 + 0x30;

buf[3] = ' ';
buf[4] = '\t';
UARTSend(buf, 5);
}
////////////////////////////////////////////////////////////////

void ADCSend2(uint32_t val2)
{
uint8_t buf[5];
val2 = val2 * 330 / 4096;
buf[0] = val2 / 100 + 0x30;
buf[1] = (val2 % 100) / 10 + 0x30;
buf[2] = val2 % 10 + 0x30;

buf[3] = ' ';
buf[4] = '\t';
UARTSend(buf, 5);
}
///////////////////////////////////////////////////////////////////

void ADCSend3(uint32_t val3)
{
uint8_t buf[5];
val3 = val3 * 330 / 4096;
buf[0] = val3 / 100 + 0x30;
buf[1] = (val3 % 100) / 10 + 0x30;
buf[2] = val3 % 10 + 0x30;
buf[3] = ' ';
buf[4] = '\n';
UARTSend(buf, 5);
}
///////////////////////////////////////////////////////////////////////
void main(void)
{
configADC();
ConfigUart();
SysCtlClockSet(SYSCTL_SYSDIV_5|SYSCTL_USE_PLL|SYSCTL_OSC_MAIN|SYSCTL_XTAL_16MHZ);
while(1)
{
//Xóa cờ ngắt và kích hoạt lấy mẫu
ADCIntClear(ADC0_BASE, 1);
ADCProcessorTrigger(ADC0_BASE, 1);

//Chờ đến khi lấy mẫu xong
// while(!ADCFlag);
while(!ADCIntStatus(ADC0_BASE, 1, false));
SysCtlDelay(SysCtlClockGet()/3);
/*Đọc data (giá trị mẫu) lưu vào mảng, thứ tự mẫu trong mảng cũng chính là thứ tự các step (hay
channel) như đã config. Cụ thể là ui32ADC0Value[0] sẽ chứa mẫu của CH0, ui32ADC0Value[1] chứa mẫu
của CH1,... */
ADCSequenceDataGet(ADC0_BASE, 1, ui32ADC0Value);
// SysCtlDelay(SysCtlClockGet()/3);
ADCSend0(ui32ADC0Value[0]);
// SysCtlDelay(SysCtlClockGet()/3);
ADCSend1(ui32ADC0Value[1]);
// SysCtlDelay(SysCtlClockGet()/3);
ADCSend2(ui32ADC0Value[2]);
// SysCtlDelay(SysCtlClockGet()/3);
ADCSend3(ui32ADC0Value[3]);
SysCtlDelay(SysCtlClockGet()/3);
}
}
Và kết quả đọc được :
000 000 000 00000 000 000 00038 037 037 03013 006 003 00000 000 000 00015 019 021 02029 033 032 03024 019 018 01000 000 000 00017 021 022 02034 031 030 03000 000 000 00016 020 022 02029 026 024 02000 000 000 00031 032 032 03003 000 000 00001 001 000 00035 033 031 03000 000 000 00036 036 035 03...........
 

Sang Trần

Gà con
Staff member
Code:
ADCProcessorTrigger(ADC0_BASE, 1);
Bạn cho dòng này vào trước khi lấy mẫu nhá khi có trigger ADC mới get value. Thân !
 

phandinhkhanh1995

Thành Viên PIF
mình có cho ADCProcessorTrigger(ADC0_BASE, 1) rồi bên dưới vòng lặp while rồi, nhưng kết quả đo thì nó lung tung quá!@@ không biết tại sao ?
 

phandinhkhanh1995

Thành Viên PIF
cho mình hỏi ? mình dã chỉnh lại nhưng khi đọc nó có giá trị rất bé so với khi mà đo tưng module hồng ngoại ví (trong chế độ ss3 )
 

honghiep

Cố Vấn CLB
Staff member
Chào bạn.
- đầu tiên là khi insert code vô bài viết bạn vui lòng cho vào thẻ code cho dễ nhìn.
- Thứ 2 là bạn nên lưu ý trình tự khi viết code: Phần config clock cho MCU nên để đầu chương trình, không nên để sau các hàm config peripheral, có thể dẫn đến các lỗi không mong muốn do system clock thay đổi sau khi khởi tạo các peripheral
- Bạn nói là giá trị AdC đọc về khi ghép các module lại khác so với khi test từng cái: bạn lưu ý là với các led phát, khi phát đồng thời thì các led thu đều nhận được tín hiệu từ led phát đó nếu không có phương pháp che chắn, sắp xếp vị trí hợp lý. Vì vậy để giảm tình trạng các led ảnh hưởng đến nhau thì mỗi lần chỉ nên cho 1 led phát và 1 led thu - hoặc tất cả các led cùng thu nhưng chỉ lấy giá trị bạn cần, việc này có thể làm quá trình đọc bị chậm nhưng kết quả phép đo sẽ có độ chính xác cao hơn.
- Việc giá trị AdC đọc về lung tung thì bạn nên kiểm tra lại kết nối phần cứng, mux chân vào module adc đã chính xác chưa, các chân đã config đúng chức năng adc chưa.
 
Top