miller2 解码状态图手稿


花了一天的时间啊,脑袋都闷闷的,终于有个手稿出来了

对时序协议,写状态图的原则,我总结如下:

1不可再分割

2步数只到当前这一步,不包括前面的一步,也不能包括后面的未知的一步,

3下一个状态,与当前状态之前的状态没有关系,不然的话你还得把之前的状态写出来

4以产生上升沿中断,为状态作图的切入点

5在一个完整的数据处,也还是会截断

6在考虑状态简化的时候,要考虑到,当前的状态是不是得不到数据,如果是得不到数据,其为1个状态,得到数据的还是一个状态

这两个状态就算形状很像,也必须要区分开来,因为状态本身代表着是不是得到数据这一信息在里面,不可忽视。


下面是手稿照片:




写完状态图之后,发现复习了一遍数字逻辑设计,大二学的,不错哈哈哈





可恶的是,每次上升沿,检测出来的值都太大了啊,怎么办呢?没法检测us级别的么,蛋疼啊

同学说是 接触不牢固,导致脉冲的不稳定

这个有可能,但是在我看来,不是最大的问题吧,至少我觉得还不是最大的问题哦 

但是是有可能的,!!

明天干嘛,明天要试试在外部写函数,来解码,而不是在中断里面,可以记录多少数据

在外面使用while循环,进行状态解码,最主要的是定多少个数


2使用定时器隔一段时见采样的方法,虽然有偏移,但是还是不失为一个好方法哦,哈哈

明天可以试试


3可以把两块板子的东西焊接到一起,来试验一下




进行时序检测的时候,来测试最小能够检测多少毫秒的数据

先把板子焊接起来,发送程序里面屏蔽一切中断,进行发送!3.125us的间隔的方波

接收程序里面,打印前100个接收到的数据的情况。看看数据就知道是不是接收正确了

没必要使用数据0,1打印过来看哦

或者在中断程序里面一直打印Uart0_Printf("rTCNTO0\n",)来观察情况。

同学用的接口是,GPB8 ,发送,

EINT7用来接收

已经焊接上

焊上了,还要把它重新弄掉,真是无语啊 ,自私自利的人那,哎重来不考虑别个在干嘛。

跟这样的自私的人合作,会有前途么,哎,这样的人不可以深交,不过这样的人老实,一般的没有触及核心利益的东西,表面的东西,会奉献的很无私

 

下一步的计划!!

1.注意,如果用Uart0_Printf()出来的数据差别太大,跟用示波器打出来的波形对不上,那就有两个问题

你波形发送端产生的波形是不是有?

还有就是你接收端的波形是不是也跟发送端的波形一致,如果不一致,那是肯定不行的,如果一致的话,才进行下一步的计划。

 

2上面的东西弄出来一致了,现在有一个问题打出来的波形,和printf出来的数据,比较相近了,但是现在的问题是,还是有差别

我用自己的主机发送的方波间隔是49us,按说实际检测到的中断在92us,左右,还是要有细微的差别。

 

3可以使用一个定时器,产生一个方波信号,这个方波信号作为我的中断源检测输出,看看打印出来的数据合不合法,如果合法的话,就开始焊接

但是比较局限的是,这个定时器,没法产生miller吗,只能唯一的产生方波信号,利用自动重载不需要系统来搞。

韦东山嵌入式群里面说了,自动重载属于AHB总线,不需要cpu来干涉,也就是不需要cpu指令,

这个说法,也就是说明了可以一边使用定时器产生中断,产生方波波形,然后再使用定时器进行计数,来整


在计算定时器的计算值的时候,不好忘记忽视,Uart0_Printf带来的误差,不然很不对的哦

下午想把在打印函数的延时考虑排除

具体做法如下

1使用定时器1作为PWM输出,定时器0作为捕获 外部中断9作为上升沿捕捉,整个程序只需要一个开发板

2当定时器1翻转的时候,那么其会自动重载,产生稳定的波形

3上升沿来临,外部中断9产生中断,在中断函数里面,使用一个数组记录产生中断时候的rTCNTO 数据

4记录了100次之后,屏蔽中断,尝试在外部主函数中打印出来中断,如果可以的话


现在问题是,在主函数里面打印不了中断,哎苦逼,晚上回来调试一下,先去打会篮球

板子连不上电脑 初步判断是因为串口线接触不良的问题  捣鼓捣鼓就好了哈

现在问题是打印不出来  恼火中


要产生中断,配置好中断初始化函数之外

外部中断的管脚也要配置好,不然容易出现问题,老是不容易找到

比如外部中断4

void   eint4_init(void)//GPF4
{
      	 rGPFCON &=~(0x3<<8);//GPF4作为miller2接收中断引脚
        rGPFCON |=0x2<<8; //GPG4配置为外部中断
        
        rINTMSK = ~(0x1<<4);//外部中断4_7允许
      // rINTPND |=0x1<<4;//清除外部中断4_7
      // rEINTPEND = (1<<4);//发生了外部中断的标志位,外部中断4清零
       rEINTMASK = ~(1<<4); //允许外部中断4
       rEXTINT0 &= ~(0x7<<16);
       rEXTINT0|=0x5<<16;//上升沿触发
       pISR_EINT4_7=(unsigned int)eint4_test;
   
}

不是rGPFCON |=0x2<<2,不然到死都产生不了中断啊,骚年



截止到0401下午3点钟,有了一些眉目,可以方波脉冲信号进行定时器计数了,方法如下;

1.使用到定时器0和定时器1,定时器0作为pwm输出,要配置好GPB0作为pwm输出管脚,定时器1作为定时计数,两个时钟源的配置是基本一致,相差不大的哦

2使用外部中断4,注意GPFCON的配置啊,如上面的代码,不然进入不了中断的吗

3定义全局变量data[1000]来存放每次进入中断的rTCNTO1的值,数据多了才具有统计意义吗

4在中断函数里面不要停止中断吗,一直计数,也不管它溢出,等计数到了800之后,把全局变量eint4_flag置为1

5在主函数里面,使用while(!eint4_flag)检查状态位,状态位变为1的时候,打印800个data数据出来

6注意,在班子上,现不要把TOUT0输出和EINT4引脚接到一起,等开关拨到NANDFlash之后,一段时间等到PWM输出声音稳定了之后,再使用杜邦线连接两个管脚

下面是主函数

 volatile unsigned int data[1000];
 volatile  unsigned char eint4_flag=0;
 unsigned int j;
int Main()
{
  
	unsigned long a = 1000000;
	unsigned char buf_miller[2]={0x6c,0xc2}; //0110 1100  0000 0010
	
	MMU_Init();


	//timer0_isrinit();
	eint4_init();//开启外部中断并允许外部中断
	
	Uart0_Init(115200) ;
	delay_TR();
	Uart0_Printf("uart init finished\n");
       
       delay_TR();
       Uart0_Printf("eint_init finished\n");
       
       timer0_init();//pwm输出
       delay_TR();
       Uart0_Printf("timer0_Init finished\n");
	//IO_Init(); //管教配置,GPF1外部中断上升沿触发
	//GPB1发送miller码数据
      
        timer1_init();//用来计数
        
         while(!eint4_flag);
          for(j=0;j<800;j++)
          Uart0_Printf("data[%d]=%d eint4_flag=%d\n",j,data[j],eint4_flag);

   while(1);
		
}



下面是中断函数

void __irq  eint4_test(void)
{
        data[data_cnt++]=rTCNTO1;
        rSRCPND = rSRCPND | (0x1<<4);
        rINTPND = rINTPND | (0x1<<4);
       if(rEINTPEND&(1<<4))
              rEINTPEND = rEINTPEND | (0x1<<4); 
        if(data_cnt>800)
               eint4_flag=1;
        
              //以上为清除外部中断4带来的中断标志
}


这样就可以了哈,不要在中断函数里面把定时器关闭,中断屏蔽位置1

相应的文件时《《0401_可以对外部中断脉冲进行定时,但是问题是每个中断重复进入,为何.rar》》

问题又来了,记录的数据,除了在该进入中断的时候进入中断之外,会重复进入一个中断两次,不知道是什么原因,下面是波形



可以解决手拔插这个不好的习惯的方法如下:

一开始屏蔽外部中断9.当一切所需要的配置配置好的时候,延时一段时间,把屏蔽位清零

主函数如下:

int Main()
{
  
	unsigned long a = 1000000;
	unsigned char buf_miller[2]={0x6c,0xc2}; //0110 1100  0000 0010
	
	MMU_Init();

     int_mask();
	//timer0_isrinit();
	eint9_init();//开启外部中断并允许外部中断
	
	Uart0_Init(115200) ;
	delay_TR();
	Uart0_Printf("uart init finished\n");
       
       delay_TR();
       Uart0_Printf("eint_init finished\n");
       
       timer0_init();//pwm输出
       delay_TR();
       Uart0_Printf("timer0_Init finished\n");
	//IO_Init(); //管教配置,GPF1外部中断上升沿触发
	//GPB1发送miller码数据
      
        timer1_init();//用来计数
        
        
        delay_TR();
        delay_TR();
        delay_TR();
        int_allowed();
        
        
         while(!eint4_flag);
          for(j=0;j<400;j++)
          Uart0_Printf("data[%d]=%d eint4_flag=%d\n",j,data[j],eint4_flag);

   while(1);
		
}





其中 两个函数如下:

void  int_mask(void)
{
       rINTMSK |= 0x1<<5;//外部中断8_23不允许
       rEINTMASK |=1<<9; //允许外部中断9,不允许
}
void int_allowed(void)
{
       rINTMSK = ~(0x1<<5);//外部中断8_23允许
       rEINTMASK = ~(1<<9); //允许外部中断9
}

这个函数屏蔽和开启,只是针对外部中断9而言,其他的可以重新修改,在eint9_init里面就不要开启或者屏蔽外部中断9了


快速中断的作用。能够提高中断的执行速度哈比如上面的重复进入中断的时间是200个定时器计数,即4us,使用快速中断后,重复进入中断的时间降低到了

150,即3us,显然中断执行之间提速了1us。

快速中断的使用方法是,以eint9为例,首先将INTMOD全部清零,然后将eint9对应的位置1,注意,只能有一个快速中断,所有程序只能有一个快速中断

载入中断处理函数的语句是:

 pISR_FIQ=(unsigned int)eint9_test;

整个eint9中断初始化的代码过程如下:

void   eint9_init(void)
{
       rINTMOD &=~(0xffff);//先将int_mod 全部清除为0;
       rINTMOD|=0x1<<5;//外部中断9设置为快速中断
       
       rGPGCON &=~(0x3<<2);//GPG1外部中断9,据说有滤波器的功能
       rGPGCON|=0x2<<2;//GPG1能够作为外部中断9
       
      // rINTMSK = ~(0x1<<5);//外部中断8_23允许
      // rEINTMASK = ~(1<<9); //允许外部中断9
       
       rSRCPND |=(0x1<<5);
       rINTPND |=0x1<<5;//清除外部中断8_23
       rEINTPEND|=0x1<<9;//发生了外部中断的标志位,外部中断9清零
     
       
       rEXTINT1 &= ~(0x7<<4);
       rEXTINT1|=0x5<<4;//上升沿触发 EINT9
       rEXTINT1|=0x1<<7;//外部中断9允许滤波器功能
       
       //pISR_EINT8_23=(unsigned int)eint9_test; //普通中断
        pISR_FIQ=(unsigned int)eint9_test;//快速中断
}

但是中断还是会重新进入,这是什么原因呢,我擦泪

晚上吃饭的时候想了一下,如果是硬件的原因,在下降沿来临的时候,因为是脉冲,会不会因为,由高电平,到低电平来的太快了

如果管脚和电感和电容相连接的话,那么会产生震荡,导致重新产生一个向上的脉冲,产生中断。?

有可能啊,因为这个震荡的时间是一定的,是4us,快速中断的时候是3us。

但是震荡为何会与中断的类型有关呢?这个不解啊


如果考虑焊接一个MSP430来作为PWM输出的话,可能速度跟不上,或者使用IO口模拟那个时序,

速度也不一定能够跟得上,而且程序,代码还得重新设计,考虑不一定能够合的来哦。


偶然间发现数据无重复,这是为什么呢!!这是为什么呢,哈哈哈哈哈哈

我懂了,你定义的数据位1000位的,等到你计数完,之后,又重头开始计数,那么你的值肯定跟上一次有重叠的部分

比如第一个是65535 ,第二个是65335,第三个是55535,第四个是45335

如果当你只重复计数一次的话,那么值就不会重复了,记住,当计数大于800的时候

屏蔽外部中断四,然后再主函数里面打印这些值,你会发现很有规律吧,哈哈哈哈哈

没有重复,坚决没有,下面是上图。


下面就可以开始解码了哈,不用那么蛋疼了哦

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值