查看: 2466|回复: 2

[原创] 【LPC54114之9 终结篇 双显示屏模拟环境控制系统】

[复制链接]
  • TA的每日心情
    开心
    2019-3-5 08:47
  • 签到天数: 1 天

    [LV.1]初来乍到

    91

    主题

    2927

    帖子

    2

    金牌会员

    Rank: 6Rank: 6

    积分
    7806
    最后登录
    2024-4-25
    发表于 2017-5-14 22:00:10 | 显示全部楼层 |阅读模式
    本帖最后由 jundao721 于 2017-5-16 12:26 编辑

    过这一段时间的努力调试,终于实现了模拟系统,在实际的项目开发中,和单一实现某个功能不一样。单一实现某个功能还是好实现的,把很多个功能结合起来,就会发现,各种坑。虽然这个模拟系统在有限的时间内实现的功能不多,但是基本上集成了CTimer,SCTimer,AD,PWM,Oled,IICDCmotor等等功能。在调试的过程中,你会发现,有时候外设初始化的顺序都会影响整个系统或者影响其他功能。
    这个系统主要是通过双屏显示,采集空气中的气体浓度,光亮情况,温度,气压,定时等,然后通过其他手段来调节空气的数值,比如模拟风扇来调节温度,通过模拟灯光来调节室内亮度,oled显示灯光等级等等。
    下面就详细说明一下调试情况。
    首先是温度和气压的采样,选择BMP180传感器,以前用过,数据还算是精准,如图1所示:

    显示部分都采用的是0.96oled显示屏,一个显示温度,气压,CH4含量,一个显示时间和亮度等级。如图2所示:

    空气成分的采样,使用欧洲的一个品牌,INP20-CH4L-NCVSP,是一款CH4传感器,可以对空气中的CH4含量进行采样,因为是模拟系统,暂时仅使用1套。如图3所示:

    对于温度的反馈,通过风扇改变空气流速,从而起到降压的作用,使用5V小直流作为模拟风扇,L298模块作为驱动模块。如图4所示:

    室内光线控制使用光敏电阻,采样光敏电阻模块的输出电压,通过板载的led灯,改变PWM,从而改变灯光的亮度,来实现调节灯光亮度的目的。如图5所示:

    时间定时,使用按键来完成时间设置定时,模拟系统里默认的是10S,使用震动电机来模拟报警,原来打算用蜂鸣器的,为了不影响群众,改为震动电机,如图6所示:

    接下来聊一聊程序,把主要的部分说明一下,其他的参考附件中的main函数。
    首先应该是引脚复用和GPIO初始化:如图7所示:
    1. /* LED pins */
    2.     IOCON_PinMuxSet(IOCON, 0, 23,IOCON_FUNC0 | IOCON_GPIO_MODE | IOCON_DIGITAL_EN | IOCON_INPFILT_OFF);//BMP180
    3.           IOCON_PinMuxSet(IOCON, 0, 24,IOCON_FUNC0 | IOCON_GPIO_MODE | IOCON_DIGITAL_EN | IOCON_INPFILT_OFF);
    4.         
    5.              /* Switch pins */
    6.     IOCON_PinMuxSet(IOCON, 1, 8,IOCON_FUNC0 | IOCON_GPIO_MODE | IOCON_DIGITAL_EN | IOCON_INPFILT_OFF);//key
    7.         
    8.           IOCON_PinMuxSet(IOCON, 0, 15,IOCON_FUNC0 | IOCON_GPIO_MODE | IOCON_DIGITAL_EN | IOCON_INPFILT_OFF);//oled1
    9.     IOCON_PinMuxSet(IOCON, 1, 9,IOCON_FUNC0 | IOCON_GPIO_MODE | IOCON_DIGITAL_EN | IOCON_INPFILT_OFF);
    10.     IOCON_PinMuxSet(IOCON, 1, 10,IOCON_FUNC0 | IOCON_GPIO_MODE | IOCON_DIGITAL_EN | IOCON_INPFILT_OFF);
    11.     IOCON_PinMuxSet(IOCON, 1, 11,IOCON_FUNC0 | IOCON_GPIO_MODE | IOCON_DIGITAL_EN | IOCON_INPFILT_OFF);
    12.         
    13.           IOCON_PinMuxSet(IOCON, 0, 11,IOCON_FUNC0 | IOCON_GPIO_MODE | IOCON_DIGITAL_EN | IOCON_INPFILT_OFF);//oled2
    14.     IOCON_PinMuxSet(IOCON, 0, 12,IOCON_FUNC0 | IOCON_GPIO_MODE | IOCON_DIGITAL_EN | IOCON_INPFILT_OFF);
    15.     IOCON_PinMuxSet(IOCON, 0, 13,IOCON_FUNC0 | IOCON_GPIO_MODE | IOCON_DIGITAL_EN | IOCON_INPFILT_OFF);
    16.     IOCON_PinMuxSet(IOCON, 0, 14,IOCON_FUNC0 | IOCON_GPIO_MODE | IOCON_DIGITAL_EN | IOCON_INPFILT_OFF);
    17.         
    18.           IOCON_PinMuxSet(IOCON, 1, 1,IOCON_FUNC0 | IOCON_GPIO_MODE | IOCON_DIGITAL_EN | IOCON_INPFILT_OFF);//Õñ¶¯µç»ú
    19.         
    20.         
    21.           IOCON_PinMuxSet(IOCON, 0, 19,IOCON_FUNC0 | IOCON_GPIO_MODE | IOCON_DIGITAL_EN | IOCON_INPFILT_OFF); //motor
    22.           IOCON_PinMuxSet(IOCON, 0, 21,IOCON_FUNC0 | IOCON_GPIO_MODE | IOCON_DIGITAL_EN | IOCON_INPFILT_OFF);
    23.                
    24.                
    25.    IOCON_PinMuxSet(IOCON, 1, 4, IOCON_MODE_INACT | IOCON_FUNC0 | IOCON_ANALOG_EN | IOCON_INPFILT_OFF);//ch4AD
    26.          IOCON_PinMuxSet(IOCON, 1, 3, IOCON_MODE_INACT | IOCON_FUNC0 | IOCON_ANALOG_EN | IOCON_INPFILT_OFF);//lightAD
    27.          
    28.          
    29.          IOCON_PinMuxSet(IOCON, 0, 29, IOCON_MODE_INACT | IOCON_FUNC7 | IOCON_DIGITAL_EN | IOCON_INPFILT_OFF);//lightpwm
    30.          IOCON_PinMuxSet(IOCON, 1, 2, IOCON_MODE_INACT | IOCON_FUNC3 | IOCON_DIGITAL_EN | IOCON_INPFILT_OFF); //motorpwm
    复制代码
    1. /*oled2 pins blue*/
    2.                         GPIO_PinInit(GPIO,0,11,&led_config);//´Ë´¦GPIOµÄÅäÖÃÈç¹û·Å´óMotorÅäÖúóÃ棬motor²»ÄÜÔËÐÐ
    3.                   GPIO_PinInit(GPIO,0,12,&led_config);
    4.                         GPIO_PinInit(GPIO,0,13,&led_config);
    5.                         GPIO_PinInit(GPIO,0,14,&led_config);
    6.                  GPIO_SetPinsOutput(GPIO,0,1u<<11);
    7.                  GPIO_SetPinsOutput(GPIO,0,1u<<12);
    8.                  GPIO_SetPinsOutput(GPIO,0,1u<<13);
    9.                  GPIO_SetPinsOutput(GPIO,0,1u<<14);
    10. //               
    11.                  GPIO_SetPortMask(GPIO,0,1u<<11);
    12.                  GPIO_SetPortMask(GPIO,0,1u<<12);
    13.                  GPIO_SetPortMask(GPIO,0,1u<<13);
    14.                  GPIO_SetPortMask(GPIO,0,1u<<14);
    15.                  GPIO_WriteMPort(GPIO,0,1u<<11);
    16.                  GPIO_WriteMPort(GPIO,0,1u<<12);
    17.                  GPIO_WriteMPort(GPIO,0,1u<<13);
    18.                  GPIO_WriteMPort(GPIO,0,1u<<14);        
    复制代码

    然后是按键初始化和按键处理,如图8和图9所示所示:
    1. INPUTMUX_Init(INPUTMUX);
    2.                 INPUTMUX_AttachSignal(INPUTMUX,kPINT_PinInt0,kINPUTMUX_GpioPort1Pin8ToPintsel);
    3.                 /* Turnoff clock to inputmux to save power. Clock is only needed to make changes */
    4.     INPUTMUX_Deinit(INPUTMUX);
    5.                  /* Initialize PINT */
    6.     PINT_Init(PINT);

    7.                 /* Setup Pin Interrupt 0 for rising edge */
    8.     PINT_PinInterruptConfig(PINT, kPINT_PinInt0, kPINT_PinIntEnableFallEdge, pint_intr_callback);
    9.                
    10.                 /* Enable callbacks for PINT */
    11.     PINT_EnableCallback(PINT);
    复制代码
    1. void Key_process(void)
    2. {
    3.         uint8_t i;
    4.         if(keyflag==1)
    5.         {
    6.                 CTIMER_StartTimer(CTIMER1);
    7.                 keyflag=0;
    8.         }        
    9.         if(Tfinishflag ==1)
    10.         {
    11.                 CTIMER_StopTimer(CTIMER1);
    12.                 GPIO_SetPinsOutput(GPIO,1,1u<<1);//Õñ¶¯µç»ú
    13.                 for(i=0;i<5;i++)
    14.                 Delay_nms(0xAFFFF);
    15.                 GPIO_ClearPinsOutput(GPIO,1,1u<<1);
    16.                 Tfinishflag=0;
    17.         }
    18. }
    复制代码

    然后是定时器1计数中断初始化,如图10所示:
    1. void Key_TimConfig(void)//¶¨Ê±Æ÷1ÓÃÓÚ¼ÆÊý
    2. {
    3.                 ctimer_config_t config;
    4.          static ctimer_match_config_t matchConfig0;
    5.         SYSCON->ASYNCAPBCTRL  = 1;
    6.         CLOCK_AttachClk(kFRO12M_to_ASYNC_APB);
    7.         CTIMER_GetDefaultConfig(&config);
    8.         CTIMER_Init(CTIMER1,&config);
    9.                  
    10.                  //match channel 0 configuration
    11.                  matchConfig0.enableCounterReset = true;
    12.                  matchConfig0.enableCounterStop = false;
    13.                  matchConfig0.matchValue = CLOCK_GetFreq(kCLOCK_BusClk);//1S
    14.                  matchConfig0.outControl = kCTIMER_Output_Toggle;
    15.                  matchConfig0.outPinInitState = false;
    16.                  matchConfig0.enableInterrupt = true;
    17.                  
    18.                  CTIMER_RegisterCallBack(CTIMER1,&ctimer_callback_table[0],kCTIMER_MultipleCallback);
    19.                  CTIMER_SetupMatch(CTIMER1,kCTIMER_Match_0,&matchConfig0);
    20. //                 CTIMER_StartTimer(CTIMER1);
    21.            CTIMER_StopTimer(CTIMER1);
    22. }
    复制代码

    然后就是BMP180的显示程序:
    1. BMP085Convert();
    2.                         for(t=0;t<10;t++)
    3.                         Delay_nms(0xAFFFF);
    4.                         lcdshow[0] =(u8) (temper/100);
    5.                         lcdshow[1] =(u8) ((temper-(temper/100)*100)/10);
    6.                         lcdshow[2] =(u8) (temper%10);
    7.                         sprintf(lcdtest,"%d",lcdshow[0]);
    8.                         sprintf(lcdtest2,"%d",lcdshow[1]);
    9.                         sprintf(lcdtest3,"%d",lcdshow[2]);
    10.                         LCD_Print(40,0,lcdtest,TYPE16X16,TYPE8X16);
    11.                         LCD_Print(48,0,lcdtest2,TYPE16X16,TYPE8X16);
    12.                         LCD_Print(56,0,lcdpoint,TYPE16X16,TYPE8X16);
    13.                         LCD_Print(64,0,lcdtest3,TYPE16X16,TYPE8X16);
    14.                         LCD_Print(72,0,lcdword4,TYPE16X16,TYPE8X16);
    复制代码

    其实oled显示都一样,都不多说了,下面是多路采样AD的初始化:
    1. /* Configure the converter. */
    2.     adcConfigStruct.clockMode = kADC_ClockSynchronousMode; /* Using sync clock source. */
    3.     adcConfigStruct.clockDividerNumber = 1;                /* The divider for sync clock is 2. */
    4.     adcConfigStruct.resolution = kADC_Resolution12bit;
    5.     adcConfigStruct.enableBypassCalibration = false;
    6.     adcConfigStruct.sampleTimeNumber = 0U;
    7.     ADC_Init(ADC0, &adcConfigStruct);

    8.     /* Use the temperature sensor input to channel 0. */
    9. //    ADC_EnableTemperatureSensor(ADC0, false);

    10.     /* Enable channel 7's conversion in Sequence A. */
    11.     adcConvSeqConfigStruct.channelMask = (1U << 7)|(1U << 6); /* Includes channel 0. */
    12.     adcConvSeqConfigStruct.triggerMask = 0U;
    13.     adcConvSeqConfigStruct.triggerPolarity = kADC_TriggerPolarityNegativeEdge;
    14.     adcConvSeqConfigStruct.enableSingleStep = false;
    15.     adcConvSeqConfigStruct.enableSyncBypass = false;
    16.     adcConvSeqConfigStruct.interruptMode = kADC_InterruptForEachSequence;
    17.     ADC_SetConvSeqAConfig(ADC0, &adcConvSeqConfigStruct);
    18.     ADC_EnableConvSeqA(ADC0, true); /* Enable the conversion sequence A. */
    复制代码

    然后是光敏电阻改变led的亮度处理:
    1. ctimer_config_t config;
    2. //    uint32_t LightsrcClock_Hz;
    3.          SYSCON->ASYNCAPBCTRL = 1;
    4.           /* CTimer0 counter uses the AHB clock, some CTimer1 modules use the Aysnc clock */
    5.     LightsrcClock_Hz = CLOCK_GetFreq(kCLOCK_BusClk);
    6.     CTIMER_GetDefaultConfig(&config);

    7.     CTIMER_Init(CTIMER0, &config);
    8. //    CTIMER_SetupPwm(CTIMER0, kCTIMER_Match_1, 90, 1000, srcClock_Hz, false);
    9.     CTIMER_StartTimer(CTIMER0);        
    复制代码
    1. if(ADLightResult <=0x100)//Êý¾Ý´¦Àí²¿·Ö±ØÐëÔÚADת»»Ç°Ãæ
    2.                         {
    3.                         CTIMER_SetupPwm(CTIMER0, kCTIMER_Match_1, 100, 1000, LightsrcClock_Hz, false);
    4. //                        Delay_nms(1000);
    5.                         DLight =1;
    6.                         }
    7.                         else if((ADLightResult>0x100) && (ADLightResult<=0x300))
    8.                         {
    9.                         CTIMER_SetupPwm(CTIMER0, kCTIMER_Match_1,96, 1000, LightsrcClock_Hz, false);
    10. //                        Delay_nms(1000);
    11.                         DLight =2;
    12.                         }
    13.                         else if((ADLightResult>0x300)&&(ADLightResult<=0x500))
    14.                         {
    15.                         CTIMER_SetupPwm(CTIMER0, kCTIMER_Match_1, 90, 1000, LightsrcClock_Hz, false);
    16. //                        Delay_nms(1000);
    17.                         DLight =3;
    18.                         }
    复制代码

    模拟风扇电机定时器初始化:
    1. sctimer_config_t sconfig;
    2.           sctimer_pwm_signal_param_t pwmParam;
    3.     uint32_t srctClock_Hz;
    4.          
    5.           srctClock_Hz = CLOCK_GetFreq(kCLOCK_BusClk);
    6.     SCTIMER_GetDefaultConfig(&sconfig);

    7.     SCTIMER_Init(SCT0, &sconfig);
    8.     /* Configure PWM params with frequency 24kHZ from output 4 */
    9.     pwmParam.output = kSCTIMER_Out_5;
    10.     pwmParam.level = kSCTIMER_HighTrue;
    11.     pwmParam.dutyCyclePercent = 18u;//updatedDutycycle;
    12.                 SCTIMER_SetupPwm(SCT0, &pwmParam, kSCTIMER_CenterAlignedPwm, 1000U, srctClock_Hz, &eventNumberOutput5);
    复制代码

    以上都是部分重要的程序,其他的可参考附件。
    最后是整个系统的操作视频,优酷正在审查:
    按动按键观察定时时间变化,10S震动电机报警;改变灯光亮度,观察led5(绿灯)亮度变化和oled中光线等级的变化;用手摸温度传感器,改变温度,设置为大于31.5度风扇转动,观察温度数值变化和风扇的反馈情况。

    图1

    图1

    图2

    图2

    图3

    图3

    图4

    图4

    图5

    图5

    图6

    图6

    main.rar

    5.43 KB, 下载次数: 30, 下载积分: 威望 1

    重要文件

    加油哦
    回复

    使用道具 举报

  • TA的每日心情
    奋斗
    10 小时前
  • 签到天数: 1735 天

    [LV.Master]伴坛终老

    4

    主题

    7036

    帖子

    0

    金牌会员

    Rank: 6Rank: 6

    积分
    11428
    最后登录
    2024-4-25
    发表于 2017-11-15 09:10:50 | 显示全部楼层
    干的好不错
    哎...今天够累的,签到来了~
    回复 支持 反对

    使用道具 举报

  • TA的每日心情
    擦汗
    2021-7-5 15:45
  • 签到天数: 664 天

    [LV.9]以坛为家II

    42

    主题

    1594

    帖子

    19

    金牌会员

    Rank: 6Rank: 6

    积分
    5382
    最后登录
    2021-12-22
    发表于 2017-11-15 10:29:36 | 显示全部楼层
    环境控制系统!  好啊!
    该会员没有填写今日想说内容.
    回复 支持 反对

    使用道具 举报

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

    本版积分规则

    关闭

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

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

    GMT+8, 2024-4-25 21:22 , Processed in 0.121278 second(s), 22 queries , MemCache On.

    Powered by Discuz! X3.4

    Copyright © 2001-2024, Tencent Cloud.

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