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

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~

 

 

  • 17
    点赞
  • 223
    收藏
    觉得还不错? 一键收藏
  • 6
    评论
好的,下面是一个简单的示例代码,用于实现51单片机ADC0808模块进行AD转换并通过串口发送给LabVIEW上位机。请注意,以下代码仅供参考,具体实现可能需要根据您的具体情况进行调整和修改。 ``` #include <reg51.h> #define FOSC 11059200L #define BAUD 9600 #define TIMER_1_RELOAD (65536UL - (FOSC/12UL/32UL/BAUD)) sbit CS = P1^0; // ADC0808芯片选择端 sbit OE = P1^1; // ADC0808输出使能端 sbit CLK = P1^2; // ADC0808时钟端 sbit DIN = P1^3; // ADC0808数字输入端 sbit DOUT = P1^4; // ADC0808数字输出端 void InitUart() { TMOD &= 0x0F; TMOD |= 0x20; TH1 = TIMER_1_RELOAD/256; TL1 = TIMER_1_RELOAD%256; TR1 = 1; SM0 = 0; SM1 = 1; REN = 1; EA = 1; ES = 1; } void SendByte(unsigned char dat) { SBUF = dat; while(TI == 0); TI = 0; } void SendString(unsigned char *s) { while(*s) { SendByte(*s++); } } unsigned char GetAdcValue(unsigned char ch) { unsigned char dat; CS = 0; OE = 1; CLK = 0; DIN = 1; CLK = 1; DIN = 0; CLK = 0; DIN = 1; CLK = 1; DIN = ch & 0x01; CLK = 0; DIN = (ch >> 1) & 0x01; CLK = 1; DIN = (ch >> 2) & 0x01; CLK = 0; OE = 0; CLK = 1; dat = DOUT; CLK = 0; dat <<= 1; dat |= DOUT; CLK = 1; dat <<= 1; dat |= DOUT; CLK = 0; dat <<= 1; dat |= DOUT; CLK = 1; dat <<= 1; dat |= DOUT; CLK = 0; dat <<= 1; dat |= DOUT; CLK = 1; dat <<= 1; dat |= DOUT; CLK = 0; dat <<= 1; dat |= DOUT; OE = 1; CS = 1; return dat; } void main() { unsigned char adc_value; InitUart(); // 初始化串口 while(1) { adc_value = GetAdcValue(0); // 获取ADC0808的通道0的转换值 SendByte(adc_value); // 将ADC转换值通过串口发送给LabVIEW上位机 } } void UartIsr() interrupt 4 using 1 { // 处理串口中断 } ``` 上述代码中,我们使用P1口控制ADC0808芯片的选择、输出使能和时钟,并通过P1.3口向ADC0808芯片输入数字信号。我们通过GetAdcValue函数获取ADC0808转换通道0的值,并通过串口将值发送给LabVIEW上位机。您需要根据您的具体情况修改代码中的端口和通信参数。同时,您还需要在LabVIEW中编写相应的串口接收程序来接收单片机发送的数据。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 6
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值