小学期坑——单片机——铂电阻温度计

我真是给学院的小学期跪了!!! 一周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] = '\0';

            //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] = '\0';
            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);
}

 

posted @ 2015-09-18 22:07  bbbbq  阅读(556)  评论(0编辑  收藏  举报