查看: 3656|回复: 0

[原创] [学习LPC54114] 实验3 1路ADC,2路PWM,1路定时器

[复制链接]
  • TA的每日心情
    开心
    2019-2-14 16:49
  • 签到天数: 296 天

    连续签到: 1 天

    [LV.8]以坛为家I

    241

    主题

    2239

    帖子

    6

    金牌会员

    Rank: 6Rank: 6

    积分
    4473
    最后登录
    2020-4-14
    发表于 2017-4-16 17:22:18 | 显示全部楼层 |阅读模式
    在实验过程发现这块开发板给用户的资源实在是少的可怜,在进行ADC、PWM、时钟等实验时多次造成增加每个功能模块,其他的就不正常了。最后到目前为止实现了1路ADC、1路定时器、2路PWM。下边按照拷贝网友 何昌新 的工程代码来进行我们的实验。
    首先是LCD,代码省略的,与前述的一样:一个lcd.h的文档,存放与LCD设置和模块相关的代码;主程序直接将显示区域设定好后写入,就像实验2一样的显示界面,只是将A0,A1改成ADC0了——就是只实现1路ADC,够用了。最后给完整的代码。
    1. ADC0实现
    参考 何昌新 的设置,做了一些试验修改,原来的程序是中断的,在我这里都不正常,只好参考adc_5411x.h文档修改,将ADC的初始化改成//ADC Initial
    void
    adcInit(void){
    Chip_ADC_Init(LPC_ADC, ADC_CR_RESOL(2) | ADC_CR_CLKDIV(0));
    Chip_ADC_SetSequencerBits(LPC_ADC, ADC_SEQA_IDX, ADC_SEQ_CTRL_SEQ_ENA | ADC_SEQ_CTRL_CHANNEL_EN(3) | ADC_SEQ_CTRL_START);
    Chip_IOCON_PinMuxSet(LPC_IOCON, 1, 0, (IOCON_FUNC7 | IOCON_MODE_INACT |IOCON_ANALOG_EN));
    Chip_ADC_Calibration(LPC_ADC);
    }
    上述代码只能完成ADC0的初始化,测试需要由主程序代码触发完成。
    需要说明的是IOCON_FUNCx,这个函数可以查到由0~7组成,很有意思的事只有IOCON_FUNC3,测试ADC时微调感觉是对数变化的,其他的,1,2,4,5,6,7的变化都是线性的,并且数值越大约满幅度输出,入上述设的IOCON_FUNC7,可以测得0~4090——接近4095的12位了。
    参考adc_5411x.h文档ADC_CR_RESOL(2)可以改变ADC采样位数,0=6位,1=8位,2=10位,3=12位,发现改动后没有什么大变。喜欢的网友可以试试。
    2. 2路PWM实现
    因为要用到ADC0,可能以后还要用到ADC1,或ADC2,因此将2路PWM从Arduino的6个ADC的A3,A4输出,参考文档stc_pwm_5411x.h。初始化代码:
    //PWM Initial
    void pwmInit(void){
    Chip_SCTPWM_Init(LPC_SCT);
    Chip_SCTPWM_SetRate(LPC_SCT,10000);
    Chip_IOCON_PinMuxSet(LPC_IOCON,1,3,IOCON_FUNC3|IOCON_MODE_INACT|IOCON_DIGITAL_EN|IOCON_INPFILT_OFF);
    Chip_SCTPWM_SetOutPin(LPC_SCT,3,6);
    Chip_IOCON_PinMuxSet(LPC_IOCON,1,4,IOCON_FUNC3|IOCON_MODE_INACT|IOCON_DIGITAL_EN|IOCON_INPFILT_OFF);
    Chip_SCTPWM_SetOutPin(LPC_SCT,4,7);
    Chip_SCTPWM_Start(LPC_SCT);
    }
    上述代码直接启动频率为100KHz,2路PWM,但PWM周期没有,因此需要在主程序中设定WPM周期,后边给出代码。
    分析代码LPC_IOCON,1,3——PIO1的3,和LPC_SCT,3,6,的3是控制输出PWM为PIO1的3输出,但测试将对应的改成0或者5——想采用A0或A5作为PWM输出就是不可以,一时没有看明白,为什么依葫芦画瓢的0,1不能输出PWM信号!1~4都可以。这是实验PWM的一个问题。
    其次在stc_pwm_5411x.h文档中有设置周期函数如下:
    __STATIC_INLINE uint32_t Chip_SCTPWM_PercentageToTicks(LPC_SCT_T *pSCT, uint8_t percent))
    {
    return (Chip_SCTPWM_GetTicksPerCycle(pSCT) * percent) / 100;
    }
    其中说明percent位周期代入值为百分比0~100。我想设成0~1000,那么先将uint8_t percent改成uint16_t percent这样可以带入超过100的数值,而后将第二行改成:return (Chip_SCTPWM_GetTicksPerCycle(pSCT) * percent) / 1000;
    在主函数中改变周期值为0~999,结果实现的还是0~100的,无法实现0~1000的细分变化。关心去的网友可以做这个实验。
    3. 定时器Tick
    直接拿来主义,代码如下:
    //TimeTick Interrupt
    void SysTick_Handler(void){js++;}
    只有程序计数器增加,结果由主函数处理。主函数main.cpp代码:
    #include "board.h"
    #include "6903.h"

    //Definitions
    #define tickRate (100)//Biger is Fast

    void dispBase(void);
    void dispMes(void);

    //Variables/
    uint8_t testTime=0;
    uint16_t val0,val1,dut0=1,dut1=1,ddt0=1,ddt1=2;
    uint32_t js;

    //TimeTick Interrupt
    void SysTick_Handler(void){js++;}
    //Delayer
    void delay(int counter){
    volatile uint32_t i,j;
    for(i=0;i<counter;++i){
    for(j=0;j<i;j++){;}}
    }
    //GPIO Initial
    void ioInit(void){
    //Define LED Pins
    Chip_GPIO_SetPinDIR(LPC_GPIO,  LEDGpio,LED4,true);
    Chip_GPIO_SetPinState(LPC_GPIO,LEDGpio,LED4,true);
    Chip_GPIO_SetPinDIR(LPC_GPIO,  LEDGpio,LED5,true);
    Chip_GPIO_SetPinState(LPC_GPIO,LEDGpio,LED5,true);
    Chip_GPIO_SetPinDIR(LPC_GPIO,  LEDGpio,LED6,true);
    Chip_GPIO_SetPinState(LPC_GPIO,LEDGpio,LED6,true);
    Chip_GPIO_SetPinDIR(LPC_GPIO,  LEDGpio,LED7,true);
    Chip_GPIO_SetPinState(LPC_GPIO,LEDGpio,LED7,true);
    //Define LCD CTRL Pins
    Chip_GPIO_SetPinDIR(LPC_GPIO,  lcdGpio,sdat,true);
    Chip_GPIO_SetPinState(LPC_GPIO,lcdGpio,sdat,true);
    Chip_GPIO_SetPinDIR(LPC_GPIO,  lcdGpio,sclk,true);
    Chip_GPIO_SetPinState(LPC_GPIO,lcdGpio,sclk,true);
    Chip_GPIO_SetPinDIR(LPC_GPIO,  lcdGpio,sreg,true);
    Chip_GPIO_SetPinState(LPC_GPIO,lcdGpio,sreg,true);
    Chip_GPIO_SetPinDIR(LPC_GPIO,  lcdGpio,sres,true);
    Chip_GPIO_SetPinState(LPC_GPIO,lcdGpio,sres,false);
    }
    //ADC Initial
    void adcInit(void){...}//代码省略了
    //PWM Initial
    void pwmInit(void){...}//代码省略了
    //ADC Sample one
    void adcTest(void){
    Chip_ADC_StartSequencer(LPC_ADC,ADC_SEQA_IDX);
    if(Chip_ADC_GetFlags(LPC_ADC)){
      val0=(Chip_ADC_GetGlobalDataReg(LPC_ADC,ADC_SEQA_IDX)&ADC_SEQ_GDAT_RESULT_MASK)>>ADC_SEQ_GDAT_RESULT_BITPOS;
    }
    }
    //LED Flash Test Pragram
    void led(void){Chip_GPIO_SetPinToggle(LPC_GPIO,LEDGpio,LED4);}

    int main(void){
    SystemCoreClockUpdate();
    Chip_GPIO_Init(LPC_GPIO);
    SysTick_Config(SystemCoreClock/tickRate);//Tick Rate more faster
    ioInit();
    adcInit();
    pwmInit();
    lcdInit();
    lcdClear();
    dispBase();
    while(true){
      testTime++;
      if(dut0<96){ddt0++;}else{ddt0=3;}dut0+=ddt0;
      if(dut1<88){ddt1++;}else{ddt1=2;}dut1+=ddt1;
      Chip_SCTPWM_SetDutyCycle(LPC_SCT,3,Chip_SCTPWM_PercentageToTicks(LPC_SCT,dut0));
      Chip_SCTPWM_SetDutyCycle(LPC_SCT,4,Chip_SCTPWM_PercentageToTicks(LPC_SCT,dut1));
      if(testTime>49){
       adcTest();
       testTime=0;
       led();
      }else{testTime=js;}
      dispMes();
      //printf("PWM0:%d PWM1:%d ADC0:%d \r\n",dut0,dut1,val0);
    }
    }
    //Display Based 6903
    void dispBase(void){//LPC54110 Test
    c2l(0,0,21);c2l(1,0,25);c2l(2,0,12);c2l(3,0,5);c2l(4,0,4);c2l(5,0,1);c2l(6,0,1);
    c2l(7,0,0);c2l(9,0,29);c2l(10,0,14);c2l(11,0,28);c2l(12,0,29);
    c2l(0,1,19);c2l(1,1,28);//JS
    c2l(0,2,10);c2l(1,2,13);c2l(2,2,12);c2l(3,2,0);//ADC0
    c2l(0,3,25);c2l(1,3,32);c2l(2,3,1);//PW0
    c2l(8,3,25);c2l(9,3,32);c2l(10,3,2);//PW1
    }
    //Display Test Data 6903
    void dispMes(void){
    c2l(3,1,(js/100000)%10);c2l(4,1,(js/10000)%10);c2l(5,1,(js/1000)%10);c2l(6,1,(js/100)%10);c2l(7,1,(js/10)%10);c2l(8,1,(js)%10);
    c2l(5,2,(val0/1000)%10);c2l(6,2,(val0/100)%10);c2l(7,2,(val0/10)%10);c2l(8,2,(val0)%10);
    c2l(4,3,(dut0/100)%10);c2l(5,3,(dut0/10)%10);c2l(6,3,(dut0)%10);
    c2l(12,3,(dut1/100)%10);c2l(13,3,(dut1/10)%10);c2l(14,3,(dut1)%10);
    }
    程序说明:
    SysTick_Config(SystemCoreClock/tickRate);tickRate的数值代表timeTick的时间间隔小,例如tickRate=100,表示1秒100次中断。
    testTime为ADC测试周期,此次定为0.5秒采样一次,如果将if(testTime>49)更改,则可以改变ADC采样周期,由adcTest();触发完成。
    最后一个说明//printf("PWM0:%d PWM1:%d ADC0:%d \r\n",dut0,dut1,val0);注释掉了,因为一旦加入这条,程序就死了,实际上的输出是在USB虚拟串口完成的,不知道开发板的内部如何设置的,没有时间深入研究了。
    PWM见照片32。结果见照片31。

    2路PWM,变化太快拖影

    2路PWM,变化太快拖影

    LCD屏显结果

    LCD屏显结果
    回复

    使用道具 举报

    您需要登录后才可以回帖 注册/登录

    本版积分规则

    关闭

    站长推荐上一条 /3 下一条

    Archiver|手机版|小黑屋|恩智浦技术社区

    GMT+8, 2025-7-24 00:46 , Processed in 0.079374 second(s), 20 queries , MemCache On.

    Powered by Discuz! X3.4

    Copyright © 2001-2024, Tencent Cloud.

    快速回复 返回顶部 返回列表