研究生
最后登录1970-1-1
在线时间 小时
注册时间2018-1-4
|
楼主 |
发表于 2018-1-7 09:41:01
|
显示全部楼层
贴代码上来
- /*
- 功能:通过开发板上2个用户按键实现七彩灯光和白色灯光的切换,模拟七彩光球的工作状态。
- 第一个按键是七彩灯效果,开机默认运行七彩灯效果。
- 第二个按键是白光效果,不断按下第二个按键还可以调节白光亮度,从最亮到完全熄灭依次循环,共3档亮度可调。
- 特点:七彩灯光和白光模式都会不断检测按键,所以在不使用定时器和中断的情况下,按键切换基本无延迟。
- */
- #include "stm32f4xx.h"
- //前置函数声明
- void timeout(unsigned int count);
- uint8_t Key_Scan(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin);
- int Bright(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin);
- int Dark(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin);
- int main(void)
- {
- //开启GPIOA、GPIOC和GPIOH的时钟
- RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOA|RCC_AHB1Periph_GPIOC|RCC_AHB1Periph_GPIOH, ENABLE);
-
- //有关LED的初始化
- GPIO_InitTypeDef GPIO_InitStruct;
- GPIO_InitStruct.GPIO_Pin=GPIO_Pin_10|GPIO_Pin_11|GPIO_Pin_12;
- GPIO_InitStruct.GPIO_Mode=GPIO_Mode_OUT;
- GPIO_InitStruct.GPIO_Speed=GPIO_Low_Speed;
- GPIO_InitStruct.GPIO_OType=GPIO_OType_PP;
- GPIO_InitStruct.GPIO_PuPd=GPIO_PuPd_UP;
- GPIO_Init(GPIOH, &GPIO_InitStruct);
-
-
- //有关按键1的初始化
- GPIO_InitStruct.GPIO_Pin=GPIO_Pin_0;
- GPIO_InitStruct.GPIO_Mode=GPIO_Mode_IN;
- GPIO_InitStruct.GPIO_PuPd=GPIO_PuPd_DOWN;
- GPIO_Init(GPIOA, &GPIO_InitStruct);
-
-
- //有关按键2的初始化
- GPIO_InitStruct.GPIO_Pin=GPIO_Pin_13;
- GPIO_Init(GPIOC, &GPIO_InitStruct);
-
- //先将3个LED灯关掉
- GPIO_SetBits(GPIOH, GPIO_Pin_10);
- GPIO_SetBits(GPIOH, GPIO_Pin_11);
- GPIO_SetBits(GPIOH, GPIO_Pin_12);
-
-
-
- /*
- a的值决定了亮灯的颜色和方式。
- a==0,是七彩灯光(红灯、绿灯、蓝灯交替点亮和熄灭,两种不同亮度的灯光可以混合成多种颜色,视觉上看是无缝衔接的七彩变化)。
- a==1,是白光1档,高亮度。
- a==2,是白光2档,中亮度。
- a==3,是白光3档,低亮度。
- a==4,所有灯熄灭。
- a==-1,红灯逐渐亮起,用于七彩灯光程序运行的开头。
- */
- int a=-1;
- while(1)
- {
- switch (a)
- {
- case -1:
- {
- if (Bright(GPIOH,GPIO_Pin_10)==1)//红渐亮,用于七彩灯光程序的开头
- {
- a=1;
- break;
- }
- a=0;
- break;
- }
-
- case 0:
- {
- if (Bright(GPIOH,GPIO_Pin_12)==1)//蓝渐亮
- {
- a=1;
- break;
- }
- if (Dark(GPIOH,GPIO_Pin_10)==1) //红渐灭
- {
- a=1;
- break;
- }
-
- if (Bright(GPIOH,GPIO_Pin_11)==1)//绿渐亮
- {
- a=1;
- break;
- }
- if (Dark(GPIOH,GPIO_Pin_12)==1) //蓝渐灭
- {
- a=1;
- break;
- }
- if (Bright(GPIOH,GPIO_Pin_10)==1)//红渐亮
- {
- a=1;
- break;
- }
- if (Dark(GPIOH,GPIO_Pin_11)==1) //绿渐灭
- {
- a=1;
- break;
- }
-
- break;
- }
-
- case 1: //白光1档
- {
- GPIO_ResetBits(GPIOH, GPIO_Pin_10); //红、绿、蓝全部最大亮度
- GPIO_ResetBits(GPIOH, GPIO_Pin_11);
- GPIO_ResetBits(GPIOH, GPIO_Pin_12);
-
- if ((Key_Scan(GPIOA, GPIO_Pin_0))==1) //如果按下了第一个按键,则切换到七彩灯光模式(下同)
- {
- GPIO_SetBits(GPIOH, GPIO_Pin_10);
- GPIO_SetBits(GPIOH, GPIO_Pin_11);
- GPIO_SetBits(GPIOH, GPIO_Pin_12);
- a=-1;
- }
- if ((Key_Scan(GPIOC, GPIO_Pin_13))==1) //如果按下了第二个按键,则切换到白光2档
- a=2;
-
- break;
- }
-
-
- case 2: //白光2档
- {
- GPIO_ResetBits(GPIOH, GPIO_Pin_10);
- GPIO_ResetBits(GPIOH, GPIO_Pin_11);
- GPIO_ResetBits(GPIOH, GPIO_Pin_12);
- timeout(3000);
- GPIO_SetBits(GPIOH, GPIO_Pin_10);
- GPIO_SetBits(GPIOH, GPIO_Pin_11);
- GPIO_SetBits(GPIOH, GPIO_Pin_12);
- timeout(4000);
-
- if ((Key_Scan(GPIOA, GPIO_Pin_0))==1)
- a=-1;
- if ((Key_Scan(GPIOC, GPIO_Pin_13))==1) //如果按下了第二个按键,则切换到白光3档
- a=3;
-
- break;
- }
-
-
- case 3: //白光3档
- {
- GPIO_ResetBits(GPIOH, GPIO_Pin_10);
- GPIO_ResetBits(GPIOH, GPIO_Pin_11);
- GPIO_ResetBits(GPIOH, GPIO_Pin_12);
- timeout(500);
- GPIO_SetBits(GPIOH, GPIO_Pin_10);
- GPIO_SetBits(GPIOH, GPIO_Pin_11);
- GPIO_SetBits(GPIOH, GPIO_Pin_12);
- timeout(8000);
-
- if ((Key_Scan(GPIOA, GPIO_Pin_0))==1)
- a=-1;
- if ((Key_Scan(GPIOC, GPIO_Pin_13))==1) //如果按下了第二个按键,则切换到全灭模式
- a=4;
-
- break;
- }
-
-
- case 4: //红、绿、蓝全部熄灭
- {
- GPIO_SetBits(GPIOH, GPIO_Pin_10);
- GPIO_SetBits(GPIOH, GPIO_Pin_11);
- GPIO_SetBits(GPIOH, GPIO_Pin_12);
-
- if ((Key_Scan(GPIOA, GPIO_Pin_0))==1)
- a=-1;
- if ((Key_Scan(GPIOC, GPIO_Pin_13))==1)
- a=1;
-
- break;
- }
- }
- }
- }
-
-
- /*
- 简单的延时程序,传进来的数字在for循环里会一直递减,直到变0,则跳出循环。
- */
- void timeout(unsigned int count)
- {
- for (;count!=0;count--);
- }
- /*
- 按键检测程序,此处定义的函数"uint8_t Key_Scan(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin)"
- 和stm32f4xx_GPIO.h第565行的函数"uint8_t GPIO_ReadInputDataBit(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin)"
- 类型一样,只是命名不一样。
- 如果没有按下按键,就会返回0。
- 如果按下了按键,就会不停在while里面循环,直到松开了按键,才会继续往下跑,并返回1。
- 另外请注意:有返回值的函数前面不能用"Void",必须用一种数据类型定义这个函数,如int Key_Scan()。
- */
- uint8_t Key_Scan(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin)
- {
- if(GPIO_ReadInputDataBit(GPIOx, GPIO_Pin) == 1 )
- {
- while(GPIO_ReadInputDataBit(GPIOx, GPIO_Pin) == 1);
- return 1;
- }
- else
- return 0;
- }
- /*
- 七彩灯渐变程序,分为变亮程序和变暗程序。
- 原理:如果LED灯闪烁的频率非常高,人眼就无法辨别闪烁的过程,看到的就是常亮的灯光(参考日光灯)。
- 通过改变一个高频闪烁周期亮灯和灭灯的时间,就能让人眼看到不同亮度的常亮灯光。
- 此处用for循环不断改变一个高频闪烁周期亮灯和灭灯的时间,让人眼看到一个亮度渐变的过程。
- 循环中的timeout(i)是在一次闪烁中亮灯的时间,timeout(10000-(2*i))是在一次闪烁中灭灯的时间。
- j的值是同等亮度循环的次数,j的值越大,则同等亮度循环的次数越多,同等亮度保持的时间越长,总的亮灭过程就越长。
- */
- /*
- 变亮程序
- 在一次高频闪烁周期中,亮灯的时间(i的值)由0增加至5000,灭灯的时间(10000-(2*i)的值)由10000减至0。
- 在一次高频闪烁周期中亮灯时间所占的比例越来越高,所以视觉上看灯是越来越亮的。
- */
- int Bright(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin)
- {
- int i,j;
- for(i=0;i<=5000;i++)
- {
- if ((Key_Scan(GPIOC, GPIO_Pin_13))==1) //如果按下了第二个按键,则返回1(切换到白光模式,下同)
- return 1;
- for(j=0;j<=15;j++)
- {
- GPIO_ResetBits(GPIOx, GPIO_Pin);
- timeout(i);
- GPIO_SetBits(GPIOx, GPIO_Pin);
- timeout(10000-(2*i));
- }
- }
- GPIO_ResetBits(GPIOx, GPIO_Pin);
-
- /*
- 边延时边检测按键的设计,解决了在亮灯保持延时期间按键不灵的问题,效果等同于timeout(120000000)+实时按键检测。
- */
- for(i=1;i<=1200000;i++)
- {
- if ((Key_Scan(GPIOC, GPIO_Pin_13))==1)
- return 1;
- timeout(100);
- }
-
- return 0;
- }
-
- /*
- 变暗程序
- 在一次高频闪烁周期中,亮灯的时间(i的值)由5000减至0,灭灯的时间(10000-(2*i)的值)由0增至10000。
- 在一次高频闪烁周期中亮灯时间所占的比例越来越低,所以视觉上看灯是越来越暗的。
- */
- int Dark(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin)
- {
- int i,j;
- for(i=5000;i>=0;i--)
- {
- if ((Key_Scan(GPIOC, GPIO_Pin_13))==1)
- return 1;
- for(j=15;j>=0;j--)
- {
- GPIO_ResetBits(GPIOx, GPIO_Pin);
- timeout(i);
- GPIO_SetBits(GPIOx, GPIO_Pin);
- timeout(10000-(2*i));
- }
- }
- GPIO_SetBits(GPIOx, GPIO_Pin);
- /*
- 边延时边检测按键的设计,解决了在灭灯保持延时期间按键不灵的问题,效果等同于timeout(120000000)+实时按键检测。
- */
- for(i=1;i<=1200000;i++)
- {
- if ((Key_Scan(GPIOC, GPIO_Pin_13))==1)
- return 1;
- timeout(100);
- }
-
- return 0;
- }
复制代码 |
|