花了一天的时间啊,脑袋都闷闷的,终于有个手稿出来了
对时序协议,写状态图的原则,我总结如下:
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 }
快速中断的作用。能够提高中断的执行速度哈比如上面的重复进入中断的时间是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的时候
屏蔽外部中断四,然后再主函数里面打印这些值,你会发现很有规律吧,哈哈哈哈哈
没有重复,坚决没有,下面是上图。
下面就可以开始解码了哈,不用那么蛋疼了哦