2512|0

359

帖子

9

TA的资源

一粒金砂(高级)

楼主
 

实现e-bike monitor的功能 [复制链接]

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实现还需要再研究研究的。



此帖出自NXP MCU论坛
点赞 关注
 

回复
举报
您需要登录后才可以回帖 登录 | 注册

随便看看
查找数据手册?

EEWorld Datasheet 技术支持

相关文章 更多>>
关闭
站长推荐上一条 1/9 下一条

 
EEWorld订阅号

 
EEWorld服务号

 
汽车开发圈

About Us 关于我们 客户服务 联系方式 器件索引 网站地图 最新更新 手机版

站点相关: 国产芯 安防电子 汽车电子 手机便携 工业控制 家用电子 医疗电子 测试测量 网络通信 物联网

北京市海淀区中关村大街18号B座15层1530室 电话:(010)82350740 邮编:100190

电子工程世界版权所有 京B2-20211791 京ICP备10001474号-1 电信业务审批[2006]字第258号函 京公网安备 11010802033920号 Copyright © 2005-2025 EEWORLD.com.cn, Inc. All rights reserved
快速回复 返回顶部 返回列表