最近在弄一个东西,用stm32进行调制解调。在解调端,通过一些基本处理后送入到AD口时,一个码元周期是244us,如果是码元1,那么在最开始会有大概25us的幅度冲击(3.5V);如果是0,整个码元周期内都不会有幅度的冲击。于是我的想法就是利用AD和DMA ,利用幅度进行判决。但是现在从结果来看,会存在一定的误码,所有的误码都是发送1时有可能会被判决成0。一般情况下这都是由于幅度判决时门限的问题,可是我无论怎么更改门限和调整位同步算法,1判决成0这种误码一直存在。所以我就有了以下一些问题,希望各位大神能够解答。
1、因为送入AD口的数据是连续的,所以AD我现在是一直开着,利用DMA把AD值存储到内存buf1中,500个点进一次中断。DMA中断函数中,先关闭DMA,再切换DMA存储的内存地址到buf2,开启DMA,如此循环进行乒乓操作。所以每次中断函数执行的时候会漏掉一些AD采样的值,我想请问各位中断函数的时间是多少呢?利用JTAG仿真的时候,算出大概中断函数的执行时间是9us不到10us,我想知道是不是中断函数就是这个时间。下面是我的DMA中断函数
[mw_shl_code=c,true]void DMA1_Channel1_IRQHandler(void)
{
static u8 BufFlg=0;
if((DMA1->ISR) & (1<<1))
{
DMA1_Channel1->CCR&=~(1<<0);
DMA1->IFCR |= 1<<1;
if(BufFlg==0)
{
DMA1_Channel1->CMAR = (u32)(AD_Value2+30);
BufFlg=1;
flag1 = 1;
//memcpy(AD_Value1, AD_Value2+500, 30*sizeof(short));
}
else
{
DMA1_Channel1->CMAR = (u32)(AD_Value1+30);
BufFlg=0;
flag2 = 1;
//memcpy(AD_Value2, AD_Value1+500, 30*sizeof(short));
}
DMA1_Channel1->CCR|=1<<0;
}
//DMA_ClearITPendingBit(DMA1_IT_TC1);
}[/mw_shl_code]
2、其实根据波形,可以知道关键是对1的判决,检测是否有幅度的冲击。目前我的算法是,遍历buf,如果找到连续的3个点大于预设的门限值(假设此时为第10个点),就进行位同步调整,并判决为1。因为一个码元周期是54个点,所以理论上下一个位同步的点应该是当前点加上54(即10+54=64),考虑实际的情况,我现在进行遍历的点是这个理论点(64)左边15个点开始,一直持续到理论点(64)右边4个。如果这其中找到了幅度的冲击,继续之前的;如果没有就判决为0,更改下一个位同步时刻的理论点(64+54=118)。因为我不管怎么更改门限,都会存在1判决为0的情况,所以有可能是某个码元周期点数小于40并且大于58,如果是这样,就说明AD的稳定度很低。stm32的AD的稳定度会有这么低吗?
3、1判决成0就是在扫描区间内没有找到幅度冲起来的点,因为冲起来的电压大概是3.5V,大于stm32AD的参考电压3.3V,会不会是因为是这个原因导致的AD采样不稳定,导致有些时候采样值不稳定,所以冲击起来的高度完全没有采到呢?
最后,我还做过这种测试,就是一次性采样5000个点,将这5000个点分割存储在10个buf中,每个buf500个点,利用算法进行判决,试了几组数据都没有误码。这两种方法唯一的区别就是一次性采样5000个点就不会发生DMA中断函数中,切换buf时导致的部分采样点丢失,所以个人感觉第一个原因是主要原因。请问各位大神,利用JTAG仿真时得出来的大概9us的中断函数执行时间到底是否准确?
写了一大堆,希望有大神能够耐心解答,非常感谢。
|