下面介绍的开关量消除信号抖动的方法,是我刚开始单片机编程时学到的,下面分享给大家,如有不足之处,请大家指正。
1、定义开关量结构体
typedef struct
{
uint32_t temp_value; //消除抖动前开关量过程值
uint8_t nonjitter_times; //无抖动计数值
uint8_t value; //消除抖动后开关量最终值
}virtualinput;
2、定义并初始化实际开关量变量
virtualinput input[9];//注意此处定于了9个开关量变量,实际工程中读取9个开关量
//数据初始化
void input_init(void)
{
int i;
for (i = 0; i < 9; i++)
{
input[i].nonjitter_times = 0;
input[i].temp_value = 0;
input[i].value = 0;
}
}
这里注意开关量过程值
3、开关量的读取及移位保存图解
4、开关量消抖过程
当读取开关量过程值的最后两位相同时,·证明输入的开关量信号没有改变(即没有抖动),因此需要取过程值input[i].temp_value的最后两位,分两种情况,结果为3(二进制11,即读取到开关量前后两次均为1)结果为0(二进制00,即读取到开关量前后两次均为0),则无抖动计数值加1,即input[i].nonjitter_times++;
当读取开关量过程值的最后两位不同时,无抖动计数值赋值为5,随后input[i].nonjitter_times--;注意无抖动值减小为0后自动赋值为5。
当无抖动计数20次时,此信号有效
5、附录信号读取信号
//开关量读入并消抖函数
void input_cortrol(void)
{
uint8_t i;
//第1部分数据的移位及存储
//对9个开关量结构体变量的过程值进行移位保存
for (i = 0; i < 9; i++)
{
input[i].temp_value <<= 1;
}
//新读到的开关量值存在开关量结构体末位
input[0].temp_value += (((GPIOPinRead(GPIO_PORTE_BASE, GPIO_PIN_0) & 0x01) >> 0) & 0x01);
input[1].temp_value += (((GPIOPinRead(GPIO_PORTE_BASE, GPIO_PIN_1) & 0x02) >> 1) & 0x01);
input[2].temp_value += (((GPIOPinRead(GPIO_PORTE_BASE, GPIO_PIN_2) & 0x04) >> 2) & 0x01);
input[3].temp_value += (((GPIOPinRead(GPIO_PORTE_BASE, GPIO_PIN_3) & 0x08) >> 3) & 0x01);
input[4].temp_value += (((GPIOPinRead(GPIO_PORTC_AHB_BASE, GPIO_PIN_5) & 0x20) >> 5) & 0x01);
input[5].temp_value += (((GPIOPinRead(GPIO_PORTC_AHB_BASE, GPIO_PIN_6) & 0x40) >> 6) & 0x01);
input[6].temp_value += (((GPIOPinRead(GPIO_PORTC_AHB_BASE, GPIO_PIN_7) & 0x80) >> 7) & 0x01);
input[7].temp_value += (((GPIOPinRead(GPIO_PORTA_AHB_BASE, GPIO_PIN_1) & 0x02) >> 1) & 0x01);
input[8].temp_value += (((GPIOPinRead(GPIO_PORTG_AHB_BASE, GPIO_PIN_0) & 0x01) >>0) & 0x01);
//第2部分,数据的消抖
//消除信号抖动
for (i = 0; i < 9; i++)
{
//前后两次数据检测的相同,计数加1
if ((input[i].temp_value & 0x03) == 0x00 || (input[i].temp_value & 0x03) == 0x03)
{
if (input[i].nonjitter_times < 20)
{
input[i].nonjitter_times++;
}
}
else
{
//数据发生变化
if ((input[i].temp_value & 0x06) == 0x00 || (input[i].temp_value & 0x06) == 0x06)
{
input[i].nonjitter_times = 5;
if (input[i].nonjitter_times > 0)
{
input[i].nonjitter_times--;
}
}
}
//计算20次,认为信号有效
if (input[i].nonjitter_times == 20)
{
input[i].value = ~(input[i].temp_value) & 0x01;
}
if (input[i].nonjitter_times == 0)
{
input[i].nonjitter_times = 5;
}
}