dhw5qq 发表于 2014-6-6 13:43:07

关于vc上位机 的cserialport类的问题(已解决)

本帖最后由 FSL_TICS_ZP 于 2014-7-2 21:57 编辑

// practise4Dlg.cpp : implementation file
//

#include "stdafx.h"
#include "practise4.h"
#include "practise4Dlg.h"

//



#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif

/////////////////////////////////////////////////////////////////////////////
// CAboutDlg dialog used for App About

class CAboutDlg : public CDialog
{
public:
        CAboutDlg();

// Dialog Data
        //{{AFX_DATA(CAboutDlg)
        enum { IDD = IDD_ABOUTBOX };
        //}}AFX_DATA

        // ClassWizard generated virtual function overrides
        //{{AFX_VIRTUAL(CAboutDlg)
        protected:
        virtual void DoDataExchange(CDataExchange* pDX);    // DDX/DDV support
        //}}AFX_VIRTUAL

// Implementation
protected:
        //{{AFX_MSG(CAboutDlg)
        //}}AFX_MSG
        DECLARE_MESSAGE_MAP()
};

CAboutDlg::CAboutDlg() : CDialog(CAboutDlg::IDD)
{
        //{{AFX_DATA_INIT(CAboutDlg)
        //}}AFX_DATA_INIT
}

void CAboutDlg::DoDataExchange(CDataExchange* pDX)
{
        CDialog::DoDataExchange(pDX);
        //{{AFX_DATA_MAP(CAboutDlg)
        //}}AFX_DATA_MAP
}

BEGIN_MESSAGE_MAP(CAboutDlg, CDialog)
        //{{AFX_MSG_MAP(CAboutDlg)
                // No message handlers
        //}}AFX_MSG_MAP
END_MESSAGE_MAP()

/////////////////////////////////////////////////////////////////////////////
// CPractise4Dlg dialog

CPractise4Dlg::CPractise4Dlg(CWnd* pParent /*=NULL*/)
        : CDialog(CPractise4Dlg::IDD, pParent)
{
        //{{AFX_DATA_INIT(CPractise4Dlg)
                // NOTE: the ClassWizard will add member initialization here
        //}}AFX_DATA_INIT
        // Note that LoadIcon does not require a subsequent DestroyIcon in Win32
        m_hIcon = AfxGetApp()->LoadIcon(IDR_MAINFRAME);
}

void CPractise4Dlg::DoDataExchange(CDataExchange* pDX)
{
        CDialog::DoDataExchange(pDX);
        //{{AFX_DATA_MAP(CPractise4Dlg)
        DDX_Control(pDX, IDC_COMBO1, m_combo1);
        //}}AFX_DATA_MAP
}

BEGIN_MESSAGE_MAP(CPractise4Dlg, CDialog)
        //{{AFX_MSG_MAP(CPractise4Dlg)
        ON_WM_SYSCOMMAND()
        ON_WM_PAINT()
        ON_WM_QUERYDRAGICON()
        ON_BN_CLICKED(IDC_BUTTON1, OnButton1)
        ON_BN_CLICKED(IDC_BUTTON2, OnButton2)
        ON_BN_CLICKED(IDC_BUTTON3, OnButton3)
        ON_BN_CLICKED(IDC_BUTTON4, OnButton4)
        ON_BN_CLICKED(IDC_exit, Onexit)
        //}}AFX_MSG_MAP
END_MESSAGE_MAP()

/////////////////////////////////////////////////////////////////////////////
// CPractise4Dlg message handlers

BOOL CPractise4Dlg::OnInitDialog()
{
        CDialog::OnInitDialog();

        // Add "About..." menu item to system menu.

        // IDM_ABOUTBOX must be in the system command range.
        ASSERT((IDM_ABOUTBOX & 0xFFF0) == IDM_ABOUTBOX);
        ASSERT(IDM_ABOUTBOX < 0xF000);

        CMenu* pSysMenu = GetSystemMenu(FALSE);
        if (pSysMenu != NULL)
        {
                CString strAboutMenu;
                strAboutMenu.LoadString(IDS_ABOUTBOX);
                if (!strAboutMenu.IsEmpty())
                {
                        pSysMenu->AppendMenu(MF_SEPARATOR);
                        pSysMenu->AppendMenu(MF_STRING, IDM_ABOUTBOX, strAboutMenu);
                }
        }

        // Set the icon for this dialog.The framework does this automatically
        //when the application's main window is not a dialog
        SetIcon(m_hIcon, TRUE);                        // Set big icon
        SetIcon(m_hIcon, FALSE);                // Set small icon
       
        // TODO: Add extra initialization here

        //自己添加代码
        m_combo1.SetCurSel(1);                //选择第二个串口
        GetDlgItem(IDC_BUTTON3)->EnableWindow(m_openflag);
        GetDlgItem(IDC_BUTTON4)->EnableWindow(m_openflag);

//        port1.InitPort()
       
        return TRUE;// return TRUEunless you set the focus to a control
}

void CPractise4Dlg::OnSysCommand(UINT nID, LPARAM lParam)
{
        if ((nID & 0xFFF0) == IDM_ABOUTBOX)
        {
                CAboutDlg dlgAbout;
                dlgAbout.DoModal();
        }
        else
        {
                CDialog::OnSysCommand(nID, lParam);
        }
}

// If you add a minimize button to your dialog, you will need the code below
//to draw the icon.For MFC applications using the document/view model,
//this is automatically done for you by the framework.

void CPractise4Dlg::OnPaint()
{
        if (IsIconic())
        {
                CPaintDC dc(this); // device context for painting

                SendMessage(WM_ICONERASEBKGND, (WPARAM) dc.GetSafeHdc(), 0);

                // Center icon in client rectangle
                int cxIcon = GetSystemMetrics(SM_CXICON);
                int cyIcon = GetSystemMetrics(SM_CYICON);
                CRect rect;
                GetClientRect(&rect);
                int x = (rect.Width() - cxIcon + 1) / 2;
                int y = (rect.Height() - cyIcon + 1) / 2;

                // Draw the icon
                dc.DrawIcon(x, y, m_hIcon);
        }
        else
        {
                CDialog::OnPaint();
        }
}

// The system calls this to obtain the cursor to display while the user drags
//the minimized window.
HCURSOR CPractise4Dlg::OnQueryDragIcon()
{
        return (HCURSOR) m_hIcon;
}

void CPractise4Dlg::OnButton1()               
{

        char buf={'a'};
                if(!m_bSerialPortOpened) //检查串口是否打开
        {
                AfxMessageBox("串口没有打开");
                return;
        }
        // TODO: Add your control notification handler code here
        port1.WriteToPort(buf);
}



void CPractise4Dlg::OnButton2()
{
        // TODO: Add your control notification handler code here
                char buf1={'b'};
                if(!m_bSerialPortOpened) //检查串口是否打开
        {
                AfxMessageBox("串口没有打开");
                return;
        }
        // TODO: Add your control notification handler code here
                port1.WriteToPort(buf1);
}

void CPractise4Dlg::OnButton3()
{
        // TODO: Add your control notification handler code here
        int nPort=m_combo1.GetCurSel()+1; //得到串口号,想想为什么要加1
        if(port1.InitPort(this, nPort, 9600,'N',8,1,EV_RXFLAG | EV_RXCHAR,512))
        {
                port1.StartMonitoring();
                m_bSerialPortOpened=TRUE;
                m_unPort=nPort;
        }
        else
        {
                AfxMessageBox("没有发现此串口或被占用");
                m_bSerialPortOpened=FALSE;
        }
        GetDlgItem(IDC_BUTTON3)->EnableWindow(!m_bSerialPortOpened);
        GetDlgItem(IDC_BUTTON4)->EnableWindow(m_bSerialPortOpened);
}


void CPractise4Dlg::OnButton4()
{
        // TODO: Add your control notification handler code here
        port1.ClosePort();//关闭串口
    m_bSerialPortOpened=FALSE;
        GetDlgItem(IDC_BUTTON3)->EnableWindow(!m_bSerialPortOpened);
        GetDlgItem(IDC_BUTTON4)->EnableWindow(m_bSerialPortOpened);
}

void CPractise4Dlg::Onexit()       
{
        // TODO: Add your control notification handler code here
        CDialog::OnCancel();
}

HadesHe 发表于 2014-6-6 13:44:33

不能先说问题再贴代码吗?

dhw5qq 发表于 2014-6-6 13:45:31

目前我想实现上位机去控制我的LED灯,我按钮1点亮   按钮2熄灭
现在出现的问题是我打开串口后,然后点亮led是可以的,但是再点熄灭就不行了,
必须关闭串口以后再重新打开串口点按钮2才可以熄灭,请问是我的上位机的问题还是我下位机的问题,还是cserialport这个类的问题,请教各位了!

dhw5qq 发表于 2014-6-6 13:46:22

下位机我是用stm8ss208的单片机,

下位机我贴下我的代码

dhw5qq 发表于 2014-6-6 13:47:03

#include <iostm8s208rb.h>
#include "main.h"

uint buf,m;
_Bool flag_led1,flag_led2;

#define adc_enable()                        ADC_CR1|=0x01
#define adc_disable()                        ADC_CR1&=~0x01

voidadc_init(void)       //adc初始化
{
    adc_disable();       
    ADC_CSR=0x00;
    ADC_CR2=0x18;
    ADC_CR1=0x03;
    asm("nop");        asm("nop");asm("nop");        asm("nop");        asm("nop");        asm("nop");                                       
    adc_enable();       
}

unsigned longadc_get(uchar mux)                //得到adc转换后的
{
    uchardataH, dataL;
    uintvalue = 0;   
   // adc_init();
    ADC_CSR|=(mux&0x0f);//选择通道               
    while(!((ADC_CSR&0x80)==0x80));                //等待转换完成
    ADC_CSR&=~0x80;                                //软件清零
    asm("nop");        asm("nop");asm("nop");        asm("nop");        asm("nop");        asm("nop");       
    dataL = ADC_DRL;            //读取寄存器数据
    dataH = ADC_DRH;            //右对齐数据   
    value = dataH*256+dataL;          
    returnvalue;
}



ulongSort_detection(uchar mux)            //中值滤波
{
    uchar   i,j,k;
    ulong   tmp,adc_buf;   
    for(i=0;i<5;i++)
    {
      adc_buf = adc_get(mux);
      asm("nop");        asm("nop");asm("nop");        asm("nop");        asm("nop");        asm("nop");       
    }
    for(j=4;j>0;j--)            //冒泡排序
    {
      for(k=0;k<j;k++)
      {
            if(adc_buf>adc_buf)
            {
                tmp = adc_buf;
                adc_buf = adc_buf;
                adc_buf = tmp;
            }
      }
    }
    returnadc_buf;         //函数返回值为数组中间值
}


void Key_init()
{
    PF_DDR_DDR3=0;
    PD_DDR_DDR0=0;
    PD_DDR_DDR2=0;
    PD_DDR_DDR3=0;
   
    PF_CR1_C13=1;
    PD_CR1_C10=1;
    PD_CR1_C12=1;
    PD_CR1_C13=1;
}

void Led_init()
{
    PC_DDR_DDR1=1;
    PF_DDR_DDR6=1;
    PF_DDR_DDR5=1;
    PF_DDR_DDR4=1;
   
    PC_CR1_C11=1;
    PF_CR1_C16=1;
    PF_CR1_C15=1;
    PF_CR1_C14=1;
}

void Uart_init()
{
    UART1_BRR2 = 0x00; //9600bps @2M
    UART1_BRR1 = 0x0D; //9600bps @2M
    UART1_CR3 = 0x00;//1位停止位,不开启同步模式
    UART1_CR2 = 0x2C;// 使能发送和接收功能,并开启接收中断
    UART1_CR1 = 0x00;//8位数据,不使用奇偶效验,并且使能UART1
}

void send_char(char buf)
{
    UART1_DR = buf;//发送TxBuffer1数组的字符
    while((UART1_SR & 0x80) == 0x00);//查询发送缓冲区的字节是否已经发送出去
}
uchar Get_char()
{
    uchar b;
    b=UART1_DR;
    while((UART1_SR & 0x80) == 0x00);//查询发送缓冲区的字节是否已经发送出去
    return b;
}

void send_string(char *buf)
{
    while(*buf)
    {
      send_char(*(buf++));
    }
}

void Timer4_init()
{
    TIM4_ARR=255;//计数到255后产生溢出
    TIM4_PSCR=0x07;//128分频,即2M/128=15.625KHz(相当于计数器周期为64uS)
    TIM4_IER=0X01;//禁止中断
    TIM4_EGR=0x01;//允许产生更新事件
    TIM4_CR1=0X01;//启动定时器
}

void Device_inti()
{
    Key_init();
    adc_init();
    Led_init();
    Uart_init();
    Timer4_init();
    LED1=1;
    LED2=1;
    LED3=1;
    LED4=1;
    asm("rim");// 开全局中断
}

void Ad_handle()
{
      if(m>=50)
      {
          m=0;
          send_char(buf%10000/1000+48);
          send_char(buf%1000/100+48);
          send_char(buf%100/10+48);
          send_char(buf%10/1+48);
          send_char(0x0a);
      }
}


void main()
{
Device_inti();

    while(1)
    {
            
      
       buf=adc_get(9)*3.22;   
       // Ad_handle();   
       if(KEY1==0)
       {
         if(m>=10)
         {
            m=0;
            send_string("hello STM8");
         }
            while(KEY1==0);
       }
      
    }
}

#pragma vector=20
__interrupt void Uart1_IRQHandler(void)
{
    ucharuartbuf;
    uartbuf=Get_char();
    send_string("iget it \n");
   
    switch(uartbuf)
    {
          case 'a':
         //flag_led1=1;
             LED1=0;
            break;
            
          case 'b':
      //    flag_led2=1;
            LED1=1;
            break;
          default :break;
    }
   
   
    return;
}

#pragma vector=25
__interrupt void Timer1_IRQHandler(void)
{

TIM4_SR = 0x00; // 清除更新标志
m++;
return;
}

wangpengcheng 发表于 2014-6-6 13:50:44

没有人能帮你编程的,别人只能帮你理一下思路,根本不会有人去看你的那么长的代码!

68336016 发表于 2014-6-6 14:06:25

发送的2个按钮函数,将 char类型改为 static char看看,
因为是异步传输,很可能WriteToPort的时候,数组生命周期已经结束。

dhw5qq 发表于 2014-6-6 15:30:25

wangpengcheng 发表于 2014-6-6 13:50
没有人能帮你编程的,别人只能帮你理一下思路,根本不会有人去看你的那么长的代码! ...

这话说的,我只是不知道问题在哪?

这代码是我昨天就敲完,今天验证的时候出现这个问题了!

wangpengcheng 发表于 2014-6-6 15:45:47

dhw5qq 发表于 2014-6-6 15:30
这话说的,我只是不知道问题在哪?

这代码是我昨天就敲完,今天验证的时候出现这个问题了! ...

单步调试,设断点,printf等好多种调试方法,先把问题点确认!

dhw5qq 发表于 2014-6-6 20:05:19

68336016 发表于 2014-6-6 14:06
发送的2个按钮函数,将 char类型改为 static char看看,
因为是异步传输,很可能WriteToPort的时候,数组生 ...

查了vc的书,好像一个控件在处理消息以后需要返回,可能是没有返回,导致程序无法响应按钮2

68336016 发表于 2014-6-6 20:18:53

dhw5qq 发表于 2014-6-6 20:05
查了vc的书,好像一个控件在处理消息以后需要返回,可能是没有返回,导致程序无法响应按钮2 ...

别管书上怎么说,有没有按我说的试试,只需要敲 12个字母而已。

dhw5qq 发表于 2014-6-7 20:37:13

试过了,还是不行,我问了我们老师,他说你需要清空缓冲区数据!

ispex13 发表于 2014-6-8 01:14:24

在上位机程序中设置一个数组变量,如char m_cSendbuf, 然后每次发送都是先 m_cSendbuf = 'a'或'b',然后WriteToPort(m_cSendbuf,1),试试看。还不行就把按钮消息中只设置m_cSendbuf,然后设一个BOOL值作为标志,将WriteToPort的执行放到一个定时器中,多执行WriteToPort几次,不信还收不到!

68336016 发表于 2014-6-8 02:31:01

这个类我使用很久了,特地又试一次,毫无问题。

dhw5qq 发表于 2014-6-9 13:30:09

68336016 发表于 2014-6-8 02:31
这个类我使用很久了,特地又试一次,毫无问题。

我知道跟这个串口类没有关系,可能我的思路出问题了,我再试试吧!按照楼上的
页: [1]
查看完整版本: 关于vc上位机 的cserialport类的问题(已解决)