zoukankan      html  css  js  c++  java
  • 小学期坑——单片机——铂电阻温度计

    我真是给学院的小学期跪了!!! 一周6天扔在实验室!大四了还让不让人好好考研啊!!!这些玩意儿大二大三去搞就行了啊!!!

    吐槽完毕.活还是要干的,砖还是要搬的。比起奇葩的电气传动电子的东西真是友好。

    队友并没有黄金右手,抽到的题目好魔性。

    铂电阻测温度大概是搞个电桥出来当温度传感器通过测电压来搞吧,然而并不会电桥就扔给擅长模电的机智的队友了。

    默默揽下码代码的工作。然而我讨厌单片机编程 凸 凸 说得好像会一样== 

    上位机要求可设置温度上下界,可采集温度并画出波形。

    下位机要求能测温,(AD转换),超过上位机设定的上下界时LED屏显示高了还是低了,能与上位机通讯。

     ==========================

    因为懒成一坨了所以完全没更新所以除了安装可以不用管以下的了

    拉倒最下面就好了= =

    =================================

    2015.9.18上位机通讯摸索中

    不想编硬件就先从软件下手=w=

    VS没有MFC今天才发现= = 重新搞了一遍。大二学的,已经忘光= = 不过并没有什么关系因为重点是搞出和串口的通讯。

    step1: MSCOMM安装

      因为MSCOMM控件老师直接给了资料所以就用MSCOMM控件了,其实API应该也可以搞,考完研再看吧。

      首先VS2015应该是不带MSCOMM的,所以要自己下一个。

      http://download.csdn.net/download/flydream0/4583699

      把下载的文件解压,搞到一个mscomm32.ocx 

      一开始企图把他放在windows/sysWOW64下,然后企图注册失败。又复制了一份到windows/system32下。再搞就行了。

      把Regsvr32  mscomm32.ocx搞到记事本里,改成.bat,管理员身份运行。 不然各种跪,不信你试试。

      (老师的资料是XP的已经过时了,所以照着做各种跪,不知道有没有学弟学妹能搜到我的博客,趴)

    step2:先搞个对话框 T T

      一路选选选,基于对话框。然后没啥了 = = 

      在对话框上右键插入ActiveX控件,选Microsoft Communication Control. Version 6.0。就出现了一个长得很丑的= = 电话向的东西。

      不要在意这些细节。

    Step3.各种乱搞

      右击该图标,在快捷菜单中选择“添加变量”,如m_mscomm1。然后在该控件的属性里添加OnComm函数(右侧属性栏上方有一个闪电图标,就是添加消息响应的地方)。

      以上是偷懒复制的= =

      找出TOOLBOX(VIEW-TOOLBOX),往里面扔两个文本(Static Text)写Upper和Lower免得我忘记= =扔俩编辑框(Edit Control),改一下ID免得忘记 = = 

      分别给他们添加变量m_send_upper, m_send_lower

      留下确定按钮删掉取消(因为懒)

      听说老师希望我们把它做得好看一点然而我并没有什么审美,所以还是保持原状吧= =

      

      

      PS:如果忘了以上的怎么搞,请看这个拯救了我大二小学期的网站(我就不吐槽学校的教材上有多少错了)http://www.jizhuomi.com/software/257.html

    Step4:对话框初始化码码码

      感觉我马上就要写出一个无脑教程了,不如更无脑一点,丰富一下老师的教程= =

      我的解决方案叫poi,所以编辑poiDlg.cpp里的BOOL CpoiDlg::OnInitDialog() 函数

      在里面添加代码,具体作用看注释

        m_mscomm1.put_CommPort(5);    //设置端口COM5
        m_mscomm1.put_InBufferSize(1024);    //设置输入缓冲区的大小,Bytes
        m_mscomm1.put_OutBufferSize(512);  //设置输出缓冲区的大小,Bytes
        if (!m_mscomm1.get_PortOpen())      //打开串口
        {
            m_mscomm1.put_PortOpen(true);
        }
        m_mscomm1.put_InputMode(1);  //设置输入方式为二进制方式 
        m_mscomm1.put_Settings(L"9600,n,8,1"); //设置波特率等参数 
        m_mscomm1.put_RThreshold(1);  //为1表示有一个字符即引发事件 
        m_mscomm1.put_InputLen(0);

    Step5:加串口接收代码

      找到void CpoiDlg::OnCommMscomm1(),在里面添加

      待修改版(因为并不知道下位机怎么往上传的,望天)

      里面加了一个新的Edit,变量为m_rev,显示接受的值。。。。因为懒所以懒得截图了。

      设置了两个全局变量tot,num计算平均值

      

    void CpoiDlg::OnCommMscomm1()
    {
        // TODO: 在此处添加消息处理程序代码
        VARIANT variant_inp;
        COleSafeArray safearray_inp;
    
        long i = 0;
        int len;
        char rxdata[1000];
        switch (m_mscomm1.get_CommEvent())
        {
            case 2:
                //表示接缓冲区内有字符
                variant_inp = m_mscomm1.get_Input();//接收数据
                safearray_inp = variant_inp;
                len = safearray_inp.GetOneDimSize();
                m_rev = 0;
                for (i = 0; i < len; i++)
                {
                    int tmp;
                    safearray_inp.GetElement(&i, &rxdata[i]);
                    tmp = rxdata[i];
                    m_rev = m_rev * 10 + tmp;
                }
                rxdata[i] = '';
    
                //m_rev = rxdata;
                tot += m_rev;
                num += 1;
                m_ave = m_rev / num;
    
                if (m_rev > m_send_upper) m_stat = "High"
                else if (m_rev < m_send_lower) m_stat = "Low"
                else m_stat = "OK";
                UpdateData(false);            // 将接收数据进行显示
                break;
    
            default:
                break;
        }
    
    }

    Step6:串口输出(设置)代码

    只用往外传两个数。这个到时候写下位机的时候得订个协议?

    为何我作死用double存又换int?只因怕老师输入奇怪的东西= =

    void CpoiDlg::OnBnClickedOk()
    {
        // TODO: 在此添加控件通知处理程序代码
        CDialogEx::OnOK();
    
        byte inst[8];
        CByteArray sendArr;
        sendArr.SetSize(8);
        //发送上界数据
        int nowval = (int)m_send_upper;
        for (int j = 8; j > 0 ; j--)
        {
            inst[j] = (nowval & 1);
            nowval >>= 1;
            sendArr.SetAt(j, inst[j]);
        }
        m_mscomm1.put_Output(COleVariant(sendArr));
        //发送下界数据
        nowval = (int)m_send_lower;
        for (int j = 8; j > 0; j--)
        {
            inst[j] = (nowval & 1);
            nowval >>= 1;
            sendArr.SetAt(j, inst[j]);
        }
        m_mscomm1.put_Output(COleVariant(sendArr));
    
    }

    Step7:teechart完成绘图

    炸裂了为什么这么多要求,摔!

    下载teechart,其他操作同S1(记得把名字里的(CN)删一下或者把批处理的文件名改成一样的)

    http://download.csdn.net/download/dzh_syh110/4810001

    要吐了背背单词睡觉去

    ================================

    UPDATE

    下位机部分

    #include <reg51.h>    
    
    #define uchar unsigned char  
    #define uint unsigned int 
    #define Disdata P0    //液晶数据端口
    
    sbit CS  =  P0^0;
    sbit SO  =  P0^1; 
    sbit SI  =  P0^2; 
    sbit LED_H = P2^0;
    sbit LED_L = P2^1;
    
    uchar upper = 5;
    uchar lower = 0;
    uchar cnt = 0;
    sbit lcden=P1^2;
    sbit lcdrs=P1^0;
    sbit rw=P1^1; //液晶
    sbit led=P0^3;
    sbit ALE=P2^3; //锁存控制位
    sbit  TLC1549_CLK =P2^5;
    sbit  TLC1549_CS =P2^7;
    sbit  TLC1549_DO =P2^6; //DEF TLC
          
    uint s;
    uchar num,num1,num2,num3,num4,num5;
    uint senddata;
    
    
    void InitUART  (void)  //串口初始化
    {
    
        SCON  = 0x50;           
        TMOD |= 0x20;    //定时器1工作方式2         
        TH1   = 0xFD;   //寄存器装入初值
        //TL1   = 0xFD;   //寄存器装入初值  
        TR1   = 1;      // 定时器1打开                      
        EA    = 1;      //总中断打开
        ES    = 1;      //串口中断打开
    
        LED_H = 1;
        LED_L = 1;
    }                           
    
    
    void SendByte(unsigned char dat)  //发送一个字节
    {
         SBUF = dat;
         while(!TI);
        TI = 0;
    }
    
    
    
    
    void delay30(void)   //延时30us
    {   unsigned char a;
        for(a=13;a>0;a--);
    }
    void delay(uint z) //延时zms
    {
       uint x,y;
        for(x=z;x>0;x--)
        for(y=110;y>0;y--);
    }
    
    
       
    void write_com(uchar com)          //写液晶屏命令
    {
          lcdrs=0;
          P0=com;
          delay(5);
          lcden=1;
          delay(5);
          lcden=0;
     }
     void write_data(uchar date)       //写液晶屏数据
     {
       lcdrs=1;
       P0=date;
       delay(5);
       lcden=1;
       delay(5);
       lcden=0;
     }
    
    void init()   //初始化液晶屏                                  
    {
         rw=0;                                                   
         lcden=0;
         write_com(0x38);     
        write_com(0x0c);
         write_com(0x06);
         write_com(0x01);
        write_com(0x80);   
        delay(1000); 
    }
    
    
    
    uint ReadTLC1549()   //AD 读
    {
        uint temp=0,delay=20;
        uchar i;
        TLC1549_CS = 0;
        for(i=0;i<10;i++)   
        {
            TLC1549_CLK = 0; 
            temp <<=1;
            temp |= TLC1549_DO; 
            TLC1549_CLK = 1; //上升沿
        }
        TLC1549_CS = 1;
        while(delay--); 
        return temp;
    }
    
           
    
    void Display(void)    //显示数据
    {          
               
        uint calD, calV;
        uchar v1,v2,v3; 
        float Tar;
    
        calD=ReadTLC1549();
                             
        calV=(uint)(4.88*calD); //5V 1024个刻度 每个4.88mV
        Tar= calV*0.001*13.5+13.75;
        
        senddata = (uint)(Tar*3);
        v1 = (uchar)Tar;
        v2 = v1 % 10;
        v1 /= 10;
        
        v3 = (uchar)(Tar * 10 - v1 * 100 - v2 * 10);
    
           write_com(0x80);
        write_data(0x30+v1);   
        write_com(0x81);
        write_data(0x30+v2);
        write_com(0x82);
        write_data(0x2e);
        write_com(0x83);
        write_data(0x30+v3);
    
            
        if(upper<Tar) // to mv
        {
             write_com(0x84);
             write_data('H');  
             write_com(0x85);
             write_data('I'); 
             write_com(0x86);
             write_data('G'); 
             write_com(0x87);
             write_data('H');  
               write_com(0x88);
             write_data(' '); 
             LED_H = 0;  
            LED_L = 1;
        }else if(lower > Tar){
            write_com(0x84);
             write_data('L');  
             write_com(0x85);
             write_data('O'); 
             write_com(0x86);
            write_data('W'); 
             write_com(0x87);
             write_data(' ');  
               write_com(0x88);
            write_data(' '); 
               LED_H = 1;
            LED_L = 0;
        } else {
             write_com(0x84);
             write_data(' ');  
             write_com(0x85);
             write_data(' '); 
             write_com(0x86);
            write_data(' '); 
             write_com(0x87);
             write_data(' ');  
               write_com(0x88);
            write_data(' '); 
            LED_L = 1;
            LED_H = 1;
        }
    
            
        SendByte(senddata);
    
    }
    
    void main()   {
        TLC1549_CS=1;
        TLC1549_CS=0;
        init();
        InitUART();
        while(1)
           { 
    
               led=0;
               Display();
               delay(1000);                     
                  
          }
    }
    
    
    void UART_SER (void) interrupt 4 //串口中断
    {
        unsigned char Temp;        
        //通讯 起始位为1 设置upper else lower   
       if(RI)                        //接收中断?
         {
              RI=0;                   
              Temp=SBUF;             //读入缓冲区的值
    
            if(Temp & 128)       {
                  upper = Temp ^ 128;                              
            }
             else lower = Temp;
         }
    }

    上位机部分= =

    略微有些复杂。这里只给出dlg.cpp的代码,有心情了再来加注释填坑吧= =

    // poiDlg.cpp : 实现文件
    //
    
    #include "stdafx.h"
    #include "poi.h"
    #include "poiDlg.h"
    #include "afxdialogex.h"
    #include "CTChart.h"
    #include "CAxis.h"
    #include "CAxes.h"
    #include "CScroll.h"
    #include "CSeries.h"
    #include "tchart1.h"
    
    #ifdef _DEBUG
    #define new DEBUG_NEW
    #endif
    const int N = 100005;
    double tot = 0;
    int num = 0;
    double rec[N];
    
    // CpoiDlg 对话框
    
    
    CpoiDlg::CpoiDlg(CWnd* pParent /*=NULL*/)
        : CDialogEx(IDD_POI_DIALOG, pParent)
        , m_rev(0)
        , m_ave(0)
        , m_stat(_T(""))
        ,m_send_upper(5)
        , m_comnum(0)
        , m_boderate(0)
    {
        m_hIcon = AfxGetApp()->LoadIcon(IDR_MAINFRAME);
    }
    
    void CpoiDlg::DoDataExchange(CDataExchange* pDX)
    {
        CDialogEx::DoDataExchange(pDX);
        DDX_Control(pDX, IDC_MSCOMM1, m_mscomm1);
        DDX_Text(pDX, IDC_EDIT3, m_rev);
        DDX_Text(pDX, IDC_EDIT_AVER, m_ave);
        DDX_Text(pDX, IDC_EDIT7, m_stat);
        DDX_Text(pDX, IDC_EDIT_UPPER, m_send_upper);
        DDX_Text(pDX, IDC_EDIT_LOWER, m_send_lower);
        DDX_Control(pDX, IDC_Chart1, m_chart);
        DDX_CBIndex(pDX, IDC_COMBO1, m_comnum);
        DDX_CBIndex(pDX, IDC_COMBO2, m_boderate);
        DDX_Control(pDX, IDC_BUTTON2, m_open);
    }
    
    BEGIN_MESSAGE_MAP(CpoiDlg, CDialogEx)
        ON_WM_PAINT()
        ON_WM_QUERYDRAGICON()
        ON_BN_CLICKED(IDOK, &CpoiDlg::OnBnClickedOk)
        ON_BN_CLICKED(IDC_BUTTON1, &CpoiDlg::OnBnClickedButton1)
        ON_BN_CLICKED(IDC_BUTTON2, &CpoiDlg::OnBnClickedButton2)
        ON_EN_CHANGE(IDC_EDIT_UPPER, &CpoiDlg::OnEnChangeEditUpper)
        ON_EN_CHANGE(IDC_EDIT_LOWER, &CpoiDlg::OnEnChangeEditLower)
        ON_CBN_SELCHANGE(IDC_COMBO1, &CpoiDlg::OnCbnSelchangeCombo1)
        ON_CBN_SELCHANGE(IDC_COMBO2, &CpoiDlg::OnCbnSelchangeCombo2)
    END_MESSAGE_MAP()
    
    
    // CpoiDlg 消息处理程序
    
    BOOL CpoiDlg::OnInitDialog()
    {
        CDialogEx::OnInitDialog();
    
        // 设置此对话框的图标。  当应用程序主窗口不是对话框时,框架将自动
        //  执行此操作
        SetIcon(m_hIcon, TRUE);            // 设置大图标
        SetIcon(m_hIcon, FALSE);        // 设置小图标
    
        // TODO: 在此添加额外的初始化代码
    
        m_mscomm1.put_CommPort(6);          //端口号为6
        m_mscomm1.put_InBufferSize(1024);  //设置输入缓冲区的大小,Bytes
        m_mscomm1.put_OutBufferSize(512);  //设置输出缓冲区的大小,Bytes 
        if (!m_mscomm1.get_PortOpen())      //打开串口
        {
            m_mscomm1.put_PortOpen(true);
        }
        m_mscomm1.put_InputMode(1);  //设置输入方式为二进制方式 
        m_mscomm1.put_Settings(L"9600,n,8,1"); //设置波特率等参数 
        m_mscomm1.put_RThreshold(1);  //为1表示有一个字符即引发事件 
        m_mscomm1.put_InputLen(0);
    
        return TRUE;  // 除非将焦点设置到控件,否则返回 TRUE
    }
    
    // 如果向对话框添加最小化按钮,则需要下面的代码
    //  来绘制该图标。  对于使用文档/视图模型的 MFC 应用程序,
    //  这将由框架自动完成。
    
    void CpoiDlg::OnPaint()
    {
        if (IsIconic())
        {
            CPaintDC dc(this); // 用于绘制的设备上下文
    
            SendMessage(WM_ICONERASEBKGND, reinterpret_cast<WPARAM>(dc.GetSafeHdc()), 0);
    
            // 使图标在工作区矩形中居中
            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;
    
            // 绘制图标
            dc.DrawIcon(x, y, m_hIcon);
        }
        else
        {
            CDialogEx::OnPaint();
        }
    }
    
    //当用户拖动最小化窗口时系统调用此函数取得光标
    //显示。
    HCURSOR CpoiDlg::OnQueryDragIcon()
    {
        return static_cast<HCURSOR>(m_hIcon);
    }
    
    BEGIN_EVENTSINK_MAP(CpoiDlg, CDialogEx)
        ON_EVENT(CpoiDlg, IDC_MSCOMM1, 1, CpoiDlg::OnCommMscomm1, VTS_NONE)
    END_EVENTSINK_MAP()
    
    
    void CpoiDlg::OnCommMscomm1()
    {
        // TODO: 在此处添加消息处理程序代码
        VARIANT variant_inp;
        COleSafeArray safearray_inp;
    
        long i = 0;
        int len;
        char rxdata[1000];
        switch (m_mscomm1.get_CommEvent())
        {
            case 2:
                //表示接缓冲区内有字符
                variant_inp = m_mscomm1.get_Input();//接收数据
                
                safearray_inp = variant_inp;
                len = safearray_inp.GetOneDimSize();
                m_rev = 0;
                for (i = 0; i < len; i++)
                {
                    int tmp;
                    safearray_inp.GetElement(&i, &rxdata[i]);
                    tmp = rxdata[i];
                    
                    m_rev = m_rev * 16 + tmp;
                }
                
                rxdata[i] = '';
                m_rev =( (int)(m_rev / 3.0 * 10)) / 10.0;
                //m_rev = rxdata;
                tot += m_rev;
                num += 1;
                rec[(int)num%N] = m_rev;
                m_ave = tot / num;
    
                if (m_rev > m_send_upper) m_stat = "High";
                else if (m_rev < m_send_lower) m_stat = "Low";
                else m_stat = "OK";
                
                
    
                for (int i = 1; i <= num; i++)
                {
                    CSeries serDemo1 = (CSeries)m_chart.Series(0);
                    serDemo1.AddNullXY(i, rec[i], NULL);
                }
                UpdateData(false);            // 将接收数据进行显示
                
                break;
    
            default:
                break;
        }
    
    }
    
    
    void CpoiDlg::OnBnClickedOk()
    {
        // TODO: 在此添加控件通知处理程序代码
        CDialogEx::OnOK();
    
    }
    
    
    void CpoiDlg::OnEnChangeEdit8()
    {
        // TODO:  如果该控件是 RICHEDIT 控件,它将不
        // 发送此通知,除非重写 CDialogEx::OnInitDialog()
        // 函数并调用 CRichEditCtrl().SetEventMask(),
        // 同时将 ENM_CHANGE 标志“或”运算到掩码中。
    
        // TODO:  在此添加控件通知处理程序代码
    }
    
    
    void CpoiDlg::OnBnClickedButton1()
    {
        // TODO: 在此添加控件通知处理程序代码
        
        CByteArray sendArr;
        sendArr.SetSize(1);
        //发送上界数据
        m_mscomm1.put_OutBufferCount(0);
        int nowval = (int)m_send_upper;
        nowval |= 128;
        sendArr.SetAt(0, nowval);
    
        m_mscomm1.put_Output(COleVariant(sendArr));
        //发送下界数据
        m_mscomm1.put_OutBufferCount(0);
        nowval = (int)m_send_lower;
        
        sendArr.SetAt(0, nowval);
        m_mscomm1.put_Output(COleVariant(sendArr));
    }
    
    
    void CpoiDlg::OnBnClickedButton2()
    {
        // TODO: 在此添加控件通知处理程序代码
        UpdateData(true);
    
        m_mscomm1.put_CommPort(m_comnum + 1);    //设置端口
        m_mscomm1.put_InBufferSize(1024);    //设置输入缓冲区的大小,Bytes
        m_mscomm1.put_OutBufferSize(512);  //设置输出缓冲区的大小,Bytes
    
        if (!m_mscomm1.get_PortOpen())      //打开串口
        {
            m_mscomm1.put_PortOpen(true);
        }
        m_mscomm1.put_InputMode(1);  //设置输入方式为二进制方式 
        
         
        int boderate = (2 << m_boderate) * 4800;
        CString str;
        str.Format(_T("%d"), boderate);
        str += ",n,8,1";
        m_mscomm1.put_Settings(str); //设置波特率等参数
    
        m_mscomm1.put_RThreshold(1);  //为1表示有一个字符即引发事件 
        m_mscomm1.put_InputLen(0);
    }
    
    
    void CpoiDlg::OnEnChangeEditUpper()
    {
        // TODO:  如果该控件是 RICHEDIT 控件,它将不
        // 发送此通知,除非重写 CDialogEx::OnInitDialog()
        // 函数并调用 CRichEditCtrl().SetEventMask(),
        // 同时将 ENM_CHANGE 标志“或”运算到掩码中。
    
        // TODO:  在此添加控件通知处理程序代码
        UpdateData(true);
    }
    
    
    void CpoiDlg::OnEnChangeEditLower()
    {
        // TODO:  如果该控件是 RICHEDIT 控件,它将不
        // 发送此通知,除非重写 CDialogEx::OnInitDialog()
        // 函数并调用 CRichEditCtrl().SetEventMask(),
        // 同时将 ENM_CHANGE 标志“或”运算到掩码中。
    
        // TODO:  在此添加控件通知处理程序代码
        UpdateData(true);
    }
    
    
    void CpoiDlg::OnCbnSelchangeCombo1()
    {
        // TODO: 在此添加控件通知处理程序代码
        UpdateData(true);
    }
    
    
    void CpoiDlg::OnCbnSelchangeCombo2()
    {
        // TODO: 在此添加控件通知处理程序代码
        UpdateData(true);
    }
  • 相关阅读:
    Git .gitignore文件简介及使用
    JMeter 报告监听器导入.jtl结果文件报错解决方案
    JMeter 中实现发送Java请求
    JMeter 正则表达式提取器结合ForEach控制器遍历提取变量值
    Tomcat_记一次tomcatwar包应用简单部署过程
    Python_基于Python同Linux进行交互式操作实现通过堡垒机访问目标机
    Python_关于多线程下变量赋值取值的一点研究
    JMeter 后置处理器之正则表达式提取器详解
    性能测试 CentOS下结合InfluxDB及Grafana图表实时展示JMeter相关性能数据
    Python 标准类库-数据类型之copy-深拷贝浅拷贝操作
  • 原文地址:https://www.cnblogs.com/bbbbbq/p/4820401.html
Copyright © 2011-2022 走看看