51单片机AD转换、串口蓝牙通讯、labview上位机显示

功能:单片机模拟数字转化,将数字信号通过蓝牙或者串口传输给电脑,电脑上labview显示出一个图表。

我这里实际使用是探测光信号强弱的:

 光信号——>光电探测器——>单片机电压转化为数字信号(AD转化)——>单片机通过串口发送出——>labview接收显示

 

单片机采用非常简单,别人常说它垃圾,可能确实有点垃圾,但是我却很喜欢的stc12c5a60s2,自带AD转化,有2个串口美滋滋,引脚图如下:

我使用P1.1口作为模拟信号输入,P1.3作为串口把数据实时传输出去。

voltagetemp_int=(int)(voltagetemp*1000);
voltagetemp_a = voltagetemp_int /100;
voltagetemp_b = voltagetemp_int %100;
UartSendChar('l');
UartSendChar('m');
UartSendChar(voltagetemp_a);
UartSendChar(voltagetemp_b);
UartSendChar('n');
UartSendChar('o');

根据上面代码,可以知道,传出去的数据,自己为了弄一个校验识别,先发送字符l和m,再发送真实数据,再发送字符n和o表示这一次数据发送结束。模拟信号电压真实值在0-5v之间,这里为了精度高一点显示,先乘以1000,再把高2位和低2位分别取出来,分别发送出去。

 

还是以前本科时候写的主要代码C语言,拿过来改改用,或许不是很规范。问题很大。懒得改了。

完事之后文件夹如下。

 

主函数代码:ceshi.c


#include <12c5a60s2.h>

#include "intrins.h"

#include <stc12delay.h>

#include <ADchange.h>

#include  <math.h>

#include  <uart.h>

int light=0;

uint scan_num=0;

float voltagetemp=0;

int  voltagetemp_int=0;

int  voltagetemp_a=0;

int  voltagetemp_b=0;

int t_int=0;

void main()

{

UartInit();

AD_init();

    while(1)

   {

scan_num++;

 if(scan_num>30)

 {

    scan_num=0;

AD_get(1);

light=initvoltage1;delay(1);

    voltagetemp=light/1024.0*5;

    voltagetemp_int=(int)(voltagetemp*1000);

    voltagetemp_a = voltagetemp_int /100;

voltagetemp_b = voltagetemp_int %100;

// UartSendChar(voltagetemp_int);

    UartSendChar('l');

UartSendChar('m');

UartSendChar(voltagetemp_a);

UartSendChar(voltagetemp_b);

UartSendChar('n');

UartSendChar('o');

 }

}

}

————

ADchange.h内容如下:

idata uint initvoltage1;

void AD_init()

{

P1ASF=0x03;  //P1  0 1 口作为模拟功能AD使用

ADC_RES=0;   //清零转换结果寄存器高8位

ADC_RESL=0; //清零转换结果寄存器低2位

ADC_CONTR=0x80;//开启AD电源  

delay(1);   //等待1ms,让AD电源稳定

}



void AD_get(char channel)  //我这里只能取0 和 1 通道

{  

ADC_CONTR=0x88|channel;    //开启AD转换1000 1000 自定通道 即POWER SPEED1 SPEED0 ADC_FLAG  ADC_START CHS2 CHS1 CHS0

_nop_(); _nop_(); _nop_(); _nop_();//要经过4个CPU时钟的延时,其值才能够保证被设置进ADC_CONTR 寄存器

while(!(ADC_CONTR&0x10));    //等待转换完成

ADC_CONTR&=0xe7;      //关闭AD转换,ADC_FLAG位由软件清0

initvoltage1=ADC_RES*4+ADC_RESL;

//voltagetemp=initvoltage1/1024.0*5;

//FtoS(voltagetemp);

//return str;   //返回AD转换完成的10位数据(16进制)

}

 

————

stc12delay.h内容如下:

 #ifndef __STC12DELAY_H__

#define __STC12DELAY_H__



#define uchar unsigned char

#define uint unsigned int





/*****相关宏定义***/

    /* exact-width signed integer types */

typedef   signed          char int8_t;

typedef   signed short     int int16_t;

typedef   signed           int int32_t;

typedef   signed       long int int64_t;



    /* exact-width unsigned integer types */

typedef unsigned          char uint8_t;

typedef unsigned short     int uint16_t;

typedef unsigned           int uint32_t;

typedef unsigned       long int uint64_t;





////11.0592    1T

void delay01ms() //@11.0592MHz

{

unsigned char i, j;



_nop_();

i = 11;

j = 190;

do

{

while (--j);

} while (--i);

}



 //延时n ms

void delaynms(unsigned int n)

{   unsigned int i;

for(i=0;i<n;i++)

delay01ms();

}

//也是延时 n  ms

void delay(unsigned int n)

{   unsigned int i;

for(i=0;i<n;i++)

delay01ms();

}



////11.0592    1T

void delay1ms12(void)   //误差 -0.018084490741us

{

    unsigned char a,b,c;

    for(c=8;c>0;c--)

        for(b=197;b>0;b--)

            for(a=2;a>0;a--);

}



void delaynms12 (unsigned int n)

{   unsigned int i;

for(i=0;i<n;i++)

delay1ms12();

}



#endif


 

 

————

uart.h内容如下:

  


void UartInit();

void UartSendChar(unsigned char ch); //向外发送字节

void UartSendStr(unsigned char *pStr); //向外发送字符串



void UartInit()

{

//串口2,用于舵机控制器

//串口1,用于接收上位机发出指令

     S2CON = 0x50; // SCON: serail mode 1, 8-bit UART  定时器1作为波特率的发生器

 SCON = 0x50;

 AUXR=0X15;

 BRT=(int)(256-((11059200/9600)/32));

 EA = 1;

 ES = 1;

}



//串口2有关

void UartSendChar(unsigned char ch)   //向外发送字节

{

    S2BUF = ch;

    while(!(S2CON&S2TI));

    S2CON&=~S2TI;

}

void UartSendStr(uchar *pStr)     //向外发送字符串

{

    while(*pStr != 0)

     {

        S2BUF = *pStr++;

        while(!(S2CON&S2TI));

     S2CON&=~S2TI;

     }

}  

把生成的hex文件下载到单片机之后,单片机就不停的向串口发送:l,m,数据1,数据2,n,o,l,m,数据1,数据2,n,o, l,m,数据1,数据2,n,o, ……

 

好,然后是labview做的上位机界面的接收,显示。

 

先看界面情况:

 

然后看前面板程序:

 

先配置串口(和单片机内配置保持一致就行了),电脑上就可以选择串口号,包括蓝牙也可以直接选择电脑蓝牙对应的串口号:

 

再经过一个while循环,循环内进行主要数据的接受和处理。先visa读取数据,这里每次读取10个数据,一边直接显示在缓存区,同时下面接一根线将其转化为图标。

 

 

下面将visa读取的数据实际上是一个字符类型的,转化为字节数组。

下面接for循环,来解析分别把这个10个元素的一维数组内的数据索引出来。

 

 

索引数组就是脚本语言中的a[5],把a数组中第6个元素取出来。

下面就分别把这个数组中,a[i],a[i+1],a[i+2],a[i+3]这4个元素分别拿出来。i是遍历的从0-9。

然后判断,如果满足a[i] =109,a[i+3]=110,(109和110分别是asc的字符mn) 那么 把a[i+1]和a[i+2]这2真实数据拿出来进行一个类型转换,转化为真实的电压数据显示出来即可。

 

完整的labview代码如下:

 

Over~

 

 

Logo

有“AI”的1024 = 2048,欢迎大家加入2048 AI社区

更多推荐