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 !!! :
#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...........
#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...........