qq_38514210
笙箫半世
采纳率0%
2018-10-23 08:39

STM32串口通信,串口调试助手中可以实现收发,自己编的串口助手就只能收不能发,有大神知道怎么办吗?

如题,最近做一个这样的调试,用32的开发板向电脑发送数据,用普通的串口调试助手就可以正常收发。
实际如下:32设备收到发来的信号,然后再将另外一组数据发送到调试助手
图片说明
然后在普通的串口调试助手上就是这样的;
我自己根据博客上的代码写了个差不多的串口工具,用的是Communications control ,version6.0这个控件写的。
但是结果上来说,如果32定时自己向这个工具发数据的话是可以发的,工具也能收到并且显示出来,但是用这个工具向32发数据32却收不到。
因此我又用了虚拟串口,用电脑上的串口调试助手和我写的工具互相收发,双方也都是能收到数据,也能互相发送数据,请大神帮我看看到底是那里出了问题!
串口工具收到32的数据:
图片说明
但是这个串口工具向32发送时32却收不到数据。
为了验证串口可以发送,我用了虚拟串口,如下:
图片说明
STM32的程序如下:
void UART1_Send_Array() //
{
unsigned char i=0; //
unsigned char t=0; //
num=8;
for(i=0;i<num;i++)
{

USART_SendData(USART1,send_array[t]); //
while( USART_GetFlagStatus(USART1,USART_FLAG_TC)!= SET);//
t++;

}

}
if(USART_RX_STA&0x8000)
{
UART1_Send_Array();
USART_RX_STA=0;
LED0=!LED0;
}
以及初始化等
#if EN_USART1_RX //Èç¹ûʹÄÜÁ˽ÓÊÕ
//´®¿Ú1ÖжϷþÎñ³ÌÐò
//×¢Òâ,¶ÁÈ¡USARTx->SRÄܱÜÃâĪÃûÆäÃîµÄ´íÎó

u8 USART_RX_BUF[USART_REC_LEN]; //½ÓÊÕ»º³å,×î´óUSART_REC_LEN¸ö×Ö½Ú.
//½ÓÊÕ״̬
//bit15£¬ ½ÓÊÕÍê³É±êÖ¾
//bit14£¬ ½ÓÊÕµ½0x0d
//bit13~0£¬ ½ÓÊÕµ½µÄÓÐЧ×Ö½ÚÊýÄ¿
u16 USART_RX_STA=0; //½ÓÊÕ״̬±ê¼Ç

void uart_init(u32 bound){
//GPIO¶Ë¿ÚÉèÖÃ
GPIO_InitTypeDef GPIO_InitStructure;
USART_InitTypeDef USART_InitStructure;
NVIC_InitTypeDef NVIC_InitStructure;

RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1|RCC_APB2Periph_GPIOA, ENABLE); //ʹÄÜUSART1£¬GPIOAʱÖÓ

//USART1_TX   GPIOA.9

GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9; //PA.9
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP; //¸´ÓÃÍÆÍìÊä³ö
GPIO_Init(GPIOA, &GPIO_InitStructure);//³õʼ»¯GPIOA.9

//USART1_RX GPIOA.10³õʼ»¯
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10;//PA10
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;//¸¡¿ÕÊäÈë
GPIO_Init(GPIOA, &GPIO_InitStructure);//³õʼ»¯GPIOA.10

//Usart1 NVIC ÅäÖÃ
NVIC_InitStructure.NVIC_IRQChannel = USART1_IRQn;
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority=3 ;//ÇÀÕ¼ÓÅÏȼ¶3
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 3; //×ÓÓÅÏȼ¶3
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; //IRQͨµÀʹÄÜ
NVIC_Init(&NVIC_InitStructure); //¸ù¾ÝÖ¸¶¨µÄ²ÎÊý³õʼ»¯VIC¼Ä´æÆ÷

//USART ³õʼ»¯ÉèÖÃ

USART_InitStructure.USART_BaudRate = bound;//´®¿Ú²¨ÌØÂÊ
USART_InitStructure.USART_WordLength = USART_WordLength_8b;//×Ö³¤Îª8λÊý¾Ý¸ñʽ
USART_InitStructure.USART_StopBits = USART_StopBits_1;//Ò»¸öֹͣλ
USART_InitStructure.USART_Parity = USART_Parity_No;//ÎÞÆæżУÑéλ
USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None;//ÎÞÓ²¼þÊý¾ÝÁ÷¿ØÖÆ
USART_InitStructure.USART_Mode = USART_Mode_Rx | USART_Mode_Tx; //ÊÕ·¢Ä£Ê½

USART_Init(USART1, &USART_InitStructure); //³õʼ»¯´®¿Ú1
USART_ITConfig(USART1, USART_IT_RXNE, ENABLE);//¿ªÆô´®¿Ú½ÓÊÜÖжÏ
USART_Cmd(USART1, ENABLE); //ʹÄÜ´®¿Ú1

}

void USART1_IRQHandler(void) //´®¿Ú1ÖжϷþÎñ³ÌÐò
{
u8 Res;
#if SYSTEM_SUPPORT_OS //Èç¹ûSYSTEM_SUPPORT_OSΪÕ棬ÔòÐèÒªÖ§³ÖOS.
OSIntEnter();

#endif
if(USART_GetITStatus(USART1, USART_IT_RXNE) != RESET) //½ÓÊÕÖжÏ(½ÓÊÕµ½µÄÊý¾Ý±ØÐëÊÇ0x0d 0x0a½áβ)
{
Res =USART_ReceiveData(USART1); //¶ÁÈ¡½ÓÊÕµ½µÄÊý¾Ý

    if((USART_RX_STA&0x8000)==0)//½ÓÊÕδÍê³É
        {
        if(USART_RX_STA&0x4000)//½ÓÊÕµ½ÁË0x0d
            {
            if(Res!=0x0a)USART_RX_STA=0;//½ÓÊÕ´íÎó,ÖØпªÊ¼
            else USART_RX_STA|=0x8000;  //½ÓÊÕÍê³ÉÁË 
            }
        else //»¹Ã»ÊÕµ½0X0D
            {   
            if(Res==0x0d)USART_RX_STA|=0x4000;
            else
                {
                USART_RX_BUF[USART_RX_STA&0X3FFF]=Res ;
                USART_RX_STA++;
                if(USART_RX_STA>(USART_REC_LEN-1))USART_RX_STA=0;//½ÓÊÕÊý¾Ý´íÎó,ÖØпªÊ¼½ÓÊÕ      
                }        
            }
        }            
 } 

#if SYSTEM_SUPPORT_OS //Èç¹ûSYSTEM_SUPPORT_OSΪÕ棬ÔòÐèÒªÖ§³ÖOS.
OSIntExit();

#endif
}
#endif

主要就是设置GPIO口,设置波特率等等

VS2010的主要程序如下:
void CSerialTestDlg::OnCbnSelchangeComboCom()
{
// TODO: 在此添加控件通知处理程序代码
int nSel;
nSel = m_comboCom.GetCurSel();//获取组合框控件的列表框中选中项的索引

m_ctrlComm.put_CommPort(nSel+1);//选择串口号(这里因为列表框的索引号是从0开始,所以(nSel+1)对应的才是我们所选的串口号)
m_ctrlComm.put_PortOpen(TRUE);//打开串口
m_ctrlComm.put_RThreshold(2);//收到两个字节引发OnComm事件 
m_ctrlComm.put_InputMode(1);//输入模式选为二进制   
m_ctrlComm.put_Settings(_T("9600,n,8,1"));//设置串口参数,波特率,无奇偶校验,位停止位,位数据位
m_ctrlComm.put_InputMode(1);  // 以二进制方式检取数据 
m_ctrlComm.put_RThreshold(1); //参数1表示每当串口接收缓冲区中有多于或等于1个字符时将引发一个接收数据的OnComm事件 
m_ctrlComm.put_InputLen(0); //设置当前接收区数据长度为0 
m_ctrlComm.get_Input();//先预读缓冲区以清除残留数据  

m_setOk = true;     //标记串口设置OK

}
BEGIN_EVENTSINK_MAP(CSerialTestDlg, CDialogEx)
ON_EVENT(CSerialTestDlg, IDC_MSCOMM1, 1, CSerialTestDlg::OnComm, VTS_NONE)
END_EVENTSINK_MAP()

void CSerialTestDlg::OnComm()
{
// TODO: 在此处添加消息处理程序代码
VARIANT variant_inp; //Variant 是一种特殊的数据类型,除了定长String数据及用户定义类型外,可以包含任何种类的数据。
COleSafeArray safearray_inp;

LONG len,k;

BYTE rxdata[2048]; //设置BYTE数组 An 8-bit integer that is not signed.

CString strtemp;

if(m_ctrlComm.get_CommEvent() == 2) //事件值为2表示接收缓冲区内有字符

{

////////以下你可以根据自己的通信协议加入处理代码
variant_inp=m_ctrlComm.get_Input(); //读缓冲区

safearray_inp=variant_inp; //VARIANT型变量转换为ColeSafeArray型变量
len=safearray_inp.GetOneDimSize(); //得到有效数据长度

for(k=0;k<len;k++)

safearray_inp.GetElement(&k,rxdata+k);//转换为BYTE型数组

for(k=0;k<len;k++) //将数组转换为Cstring型变量

{

BYTE bt=*(char*)(rxdata+k);//字符型

strtemp.Format(_T("%x"),bt); //8位数组显示,就是现在strtemp中是51 00 00 00 0
m_strRXData+=strtemp; //加入接收编辑框对应字符串

}
}

UpdateData(FALSE); //更新编辑框内容
}

void CSerialTestDlg::OnBnClickedButtonSend()
{
// TODO: 在此添加控件通知处理程序代码
if (m_setOk == true) //判断是否打开并初始化串口
{
UpdateData(TRUE); //读取编辑框内容
m_ctrlComm.put_Output(COleVariant(m_strTXData)); //发送数据
}
else
{
MessageBox(_T("请先选择COM口"));
}
}

void CSerialTestDlg::OnBnClickedButtonCleanup()
{
// TODO: 在此添加控件通知处理程序代码
m_strRXData="";
UpdateData(FALSE);//更新编辑框内容
}

请求大神帮我看一下大概是哪里出现了问题!

  • 点赞
  • 写回答
  • 关注问题
  • 收藏
  • 复制链接分享
  • 邀请回答

2条回答

  • m0_37711025 西红柿牛男 3年前

    你debug一下看看上位机发数据进不进32串口中断

    点赞 评论 复制链接分享
  • devmiao devmiao 3年前

为你推荐