1、按照原定的方案,应该用54100的ADC和传感器在线功能实现电动自行车的行车记录仪功能。主要采集2个模拟量和1个数字量,模拟量是电动自行车电池的实时电压值V和电流值I,P=VI,计算出瞬时功率,通过积分累加功能,计算出消耗的电量,以便达到一定值时报警,提示该去充电了。1个数字量是来自车轮的一个接近开关的脉冲,每次转一圈,触发一次脉冲,记录下来车轮转了几圈,可以记录行驶的距离。主要就是这个功能。
这个功能需要启动芯片的ADC功能,用12位应该可以满足要求了,需要2个通道,54100共12个ADC引脚,ADC0-ADC11。万利这款板子定义了一个ADC通道,ADC7,对应引脚18,这个定义在board_pinmuxing.h中可以找到。模拟量可以用一个GPIO引脚,只是需要定义一个新的channel就可以了。也可以定义一个新的中断,用seq_B的定义来实现。时钟用系统的systick。
2、这次先参照范例adc中的参数设置,展示了简单的UI界面,分3行分别显示行车距离,电池容量,电池电压。见下面的视频。
还是比较粗糙的,但是基本显示了实现功能所需要的参数。随后需要进一步完善。
3、后面简单附上main.c中有关的主要代码,
/* 系统时钟调用
void SysTick_Handler ( void ) {
SYS_ms++;
if (++CntADC == 200) {
FlagADC = TRUE;
CntADC = 0;
}
}
/* 初始化ADC ROM driver,包括中断,标志位,使用内存初始化,如果用DMA还有DMA adc初始化等等,校正也要每次启动都初始化,总之,一个都不能少,参见用户手册UM10850,
/* Initialize the ADC ROM Driver */
static int adcrom_init(void)
{
volatile int size_in_bytes;
Chip_SYSCON_PowerUp(SYSCON_PDRUNCFG_PD_ADC0 | SYSCON_PDRUNCFG_PD_VDDA_ENA | SYSCON_PDRUNCFG_PD_VREFP);
Chip_Clock_EnablePeriphClock(SYSCON_CLOCK_ADC0);
Chip_Clock_SetADCClockSource(SYSCON_ADCCLKSELSRC_MAINCLK);
Chip_Clock_SetADCClockDiv(0x1);
size_in_bytes = ROM_ADC_GetMemSize();
if (RAMBLOCK_H < (size_in_bytes / 4)) {
return 1;
}
hADC = ROM_ADC_Init(start_of_ram_block0, LPC_ADC_BASE, 0);
return 0;
}
... ...
/* Configure the ADC */
ROM_ADC_Configure(hADC, &cfg);
/* Calibrate the ADC */
if (ROM_ADC_Calibrate(hADC, Chip_Clock_GetSystemClockRate()) != LPC_OK) {
//DEBUGSTR ("ERROR: Calibrating ADC\r\n");
while (1) ;
}
//DEBUGSTR ("ADC Initialized and Calibrated successfully!\r\n");
return 0;
}
/* Enable ADC interrupts */
static void adcrom_int_enable(void)
{
NVIC_SetPriority(ADC_SEQA_IRQn, 0x00);
NVIC_ClearPendingIRQ(ADC_SEQA_IRQn);
NVIC_EnableIRQ(ADC_SEQA_IRQn);
}
/* Call-Back function for ADC Start/Stop event */
static void adcrom_startstop(ADC_HANDLE_T hADC, ADC_CBINDEX_T idx, void *arg)
{
switch (idx) {
case ADC_START_SEQ_A:
//DEBUGSTR("Sequence A Started!\r\n");
break;
case ADC_STOP_SEQ_A:
//DEBUGSTR("Sequence A Stopped!\r\n");
break;
default:
break;
}
}
/* Callback function for Buffer Done event */
static void adcrom_bufdone(ADC_HANDLE_T hADC, ADC_CBINDEX_T idx, void *arg)
{
if (idx == ADC_BUFFER_DONE_A) {
/* Buffer A Complete */
pBufA = arg;
ROM_ADC_StartConversion(hADC, ADC_SEQ_A, &buff_A, NUM_SAMPLES_A * NUM_CHANNELS_A);
} else {
;
}
}
/* Register ADC event Callback functions */
static void adcrom_regcb(void)
{
ROM_ADC_RegisterCB(hADC, ADC_BUFFER_DONE_A, adcrom_bufdone); /* Buffer A Done */
ROM_ADC_RegisterCB(hADC, ADC_STOP_SEQ_A, adcrom_startstop); /* SEQ_A Stop */
ROM_ADC_RegisterCB(hADC, ADC_START_SEQ_A, adcrom_startstop); /* SEQ_A Start */
}
... ...
/*****************************************************************************
* 主程序
****************************************************************************/
int main(void)
{
char str[10];
// Setup SystemCoreClock and any needed board code
SystemCoreClockUpdate();
SysTick_Config(SystemCoreClock/1000);
Board_SetupMuxing();
Board_LED_Init ();
// BackGround , TextColor, Text BackColor
SetDisplay(Grey,Black,White);
// Title
DisplayTitle("e-Bike Monitor");
SetColor(Yellow, Grey);
GLCD_DisplayString (20, 160, 2, 1, "Miles = ");
GLCD_DisplayString (20, 180, 2, 1, "Battery Capacity= ");
GLCD_DisplayString (20, 200, 2, 1, "Battery Voltage = ");
/* Initialize the PinMux and setup the memory for ROM driver */
if (adcrom_init())
return 1;
/* Configure the ADC */
if (adcrom_config())
return 1;
adcrom_regcb(); /* Register call-back functions */
adcrom_int_enable(); /* Enable interrupts */
/* Fill the first half of buffer with conversion samples */
if (ROM_ADC_StartConversion(hADC, ADC_SEQ_A, &buff_A, NUM_SAMPLES_A * NUM_CHANNELS_A) != LPC_OK) {
//DEBUGSTR("ERROR: Starting conversion in SEQ_A\r\n");
}
while (1) {
if (FlagADC){
FlagADC = FALSE;
sprintf(str, "%04d", buff_A[0]);
GLCD_DisplayString (180, 160, 2, 1, str);
GLCD_DisplayString (180, 180, 2, 1, "120Ah");
GLCD_DisplayString (180, 200, 2, 1, "3.0V");
}
}
}
这只是实现了简单的用户界面,具体的ADC实现还需要再研究研究的。
|