本帖最后由 Junsea 于 2016-4-11 23:29 编辑
在论坛吸收养分多年,鲜有做贡献,分享一个自己使用多年的基于概率统计的输入电平检测,以及上升沿下降沿判断的算法!一同探讨!
typedef struct //输入数字量结构体
{
uint8_t p; //记录IO前一刻的状态
uint16_t buf; //采集缓存
uint8_t sta; //采集开始标志
uint8_t end; //采集结束
uint8_t cnt; //采集计数
}_input;
_input input01_struct; //定义输入结构体变量
#define i_input01 (*(__IO uint32_t *)(0x42000000+((0x10000+0x0800+0x8)<<5) + (2<<2))) //输入IO位带
while(1)
{
if(acq_16bit(&input01_struct,(uint16_t)(i_input01))==1) //16bit数据采集结束
{
edge_input01(&input01_struct); //判断上升沿下降沿
}
}
/*采集16次输入状态,根据输入信号特性确定调用周期,可以是1ms,也可以是10ms*/
uint8_t acq_16bit(_input *ptr,uint16_t idr)
{
if((ptr->sta==0)&&(ptr->p!=idr)) //IO状态发生翻转,开始进行16次采样
{
ptr->sta = 1;
}
if((ptr->sta==1)&&(ptr->cnt<16))
{
ptr->buf = ptr->buf<<1;
ptr->buf &= 0xFFFE;
ptr->buf |= idr;
ptr->cnt++;
if(ptr->cnt==16) //采集完成
{
ptr->cnt = 0;
ptr->sta = 0;
ptr->end = 1;
}
}
return(ptr->end);
}
/*判断上升沿还是下降沿*/
void edge_input01(_input *ptr) //输入IO高低电平以及上升沿下降沿
{
if(ptr->p==0) //上升沿ptr->p = 0
{
if(get_int_1no(ptr->buf)>=12) //这里的12可以根据需求灵活调整
{
/*信号的上升沿要干的事情放到这里*/
ptr->p = 1;
}
}
else //下降沿ptr->p = 1
{
if(get_int_1no(ptr->buf)<=4) //这里的4也可以根据需求灵活调整
{
/*信号下降沿要干的事情放到这里*/
ptr->p = 0;
}
}
ptr->end = 0;
}
/*获取16位整数中含1的个数*/
uint8_t get_int_1no(uint16_t x)
{
uint8_t num = 0;
while(x)
{
x &= (x-1);
num++;
}
return(num);
}