用MiniSTM32从一个设备上采集数据,设备使用同步RS232口输出数据,并将数据封装成HDLC帧。我的想法是使用MiniSTM32将同步RS232数据转换成异步RS232的数据,这样就可以发到PC机的串口上由PC机采集数据。
设备输出的时钟为9.6k,下降沿触发,每次发送1位数据。时钟接在MiniSTM32的PC12口上,数据接在PC11口上。在PC12口上设置中断,每遇到一个下降沿就从PC11口上读取1位数据, 每收到一个HDLC帧就把这帧数据从usart1串口上送出去。
使用下面的代码进行采集:
[mw_shl_code=c,true]
u8 RecvData;
u8 BitCount;
u8 FrameBegin;
u8 OneCount;
u8 SyncWord;
u8 FrameBuff[256];
u8 FrameLength;
u8 PacketHead;
u8 PacketTail;
void EXTIX_Init(void)
{
EXTI_InitTypeDef EXTI_InitStructure;
NVIC_InitTypeDef NVIC_InitStructure;
RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO,ENABLE);
//GPIOC.12
GPIO_EXTILineConfig(GPIO_PortSourceGPIOC,GPIO_PinSource12);
EXTI_InitStructure.EXTI_Line=EXTI_Line12;
EXTI_InitStructure.EXTI_Mode = EXTI_Mode_Interrupt;
EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Falling;
EXTI_InitStructure.EXTI_LineCmd = ENABLE;
EXTI_Init(&EXTI_InitStructure);
NVIC_InitStructure.NVIC_IRQChannel = EXTI15_10_IRQn;
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0x00;
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0x00;
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
NVIC_Init(&NVIC_InitStructure);
}
void EXTI15_10_IRQHandler(void)
{
if(EXTI_GetITStatus(EXTI_Line12)!=RESET)
{
delay_us(10);
u8 ReadValue = GPIO_ReadInputDataBit(GPIOC, GPIO_Pin_11);
SyncWord = ((SyncWord>>1)&0x7f)|((ReadValue<<7)&0x80);
if(SyncWord==0x7e)
{
//usart1_send_data(&SyncWord,1);
if(FrameBegin!=0x7e)
{
FrameBegin=0x7e;
EXTI_ClearITPendingBit(EXTI_Line12);
return;
}
else
{
if(FrameLength>5)
{
usart1_send_data(&  acketHead,1);
usart1_send_data(&FrameLength,1);
usart1_send_data(FrameBuff,FrameLength);
usart1_send_data(&  acketTail,1);
}
memset(FrameBuff,0,256);
FrameLength = 0;
EXTI_ClearITPendingBit(EXTI_Line12);
return;
}
}
if(FrameBegin==0x7e)
{
BitCount++;
if(ReadValue==1)
{
OneCount++;
RecvData = ((RecvData>>1)&0x7f)|((ReadValue<<7)&0x80);
}
else
{
if(OneCount==5)
{
BitCount--;
}
else
{
RecvData = ((RecvData>>1)&0x7f)|((ReadValue<<7)&0x80);
}
OneCount = 0;
}
if(BitCount==8)
{
FrameBuff[FrameLength] = RecvData;
FrameLength++;
BitCount = 0;
RecvData = 0;
}
}
EXTI_ClearITPendingBit(EXTI_Line12);
}
}
int main(void)
{
LED_Init();
EXTIX_Init();
delay_init();
usart1_init(115200);
GPIO_InitTypeDef GPIO_InitStructure;
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA|RCC_APB2Periph_GPIOC,ENABLE);
GPIO_PinRemapConfig(GPIO_Remap_SWJ_JTAGDisable, ENABLE);
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_11;//PC11
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU;
GPIO_Init(GPIOC, &GPIO_InitStructure);
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_12;//PC12
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU;
GPIO_Init(GPIOC, &GPIO_InitStructure);
RecvData = 0;
BitCount = 0;
FrameBegin = 0;
OneCount = 0;
SyncWord = 0;
memset(FrameBuff,0,256);
FrameLength = 0;
PacketHead = 0x55;
PacketTail = 0xAA;
u32 i = 0;
while(1)
{
i++;
}
}[/mw_shl_code]
现在的问题是,我采集到的数据大约有1/3是正确的,其他的2/3是错的,请大家帮我看看怎么会出现这样的问题。
P.S.
如果我改成每采集到一个字节就发一个字节的话就完全采集不到正确的数据了,代码如下:
[mw_shl_code=c,true]oid EXTI15_10_IRQHandler(void)
{
if(EXTI_GetITStatus(EXTI_Line12)!=RESET)
{
delay_us(20);
u8 ReadValue = GPIO_ReadInputDataBit(GPIOC, GPIO_Pin_11);
SyncWord = ((SyncWord>>1)&0x7f)|((ReadValue<<7)&0x80);
if(SyncWord==0x7e)
{
FrameBegin = 0x7e;
SyncWord = 0x00;
BitCount = 0;
RecvData = 0;
EXTI_ClearITPendingBit(EXTI_Line12);
return;
}
if(FrameBegin==0x7e)
{
switch(ReadValue)
{
case 1:
BitCount++;
OneCount++;
RecvData = ((RecvData>>1)&0x7f)|((ReadValue<<7)&0x80);
break;
case 0:
if(OneCount<5)
{
BitCount++;
RecvData = ((RecvData>>1)&0x7f)|((ReadValue<<7)&0x80);
}
OneCount=0;
break;
}
if(BitCount==8)
{
usart1_send_data(&RecvData,1);
BitCount=0;
OneCount=0;
RecvData=0;
}
}
EXTI_ClearITPendingBit(EXTI_Line12);
}
}
[/mw_shl_code]
我是初学者,是不是我还有什么地方没有考虑到?请大家帮我看看,谢谢了。
|