单片机入门

当前位置:首页>文章中心>单片机入门
全部 352 技术分享 332 单片机入门 20

单片机与PC串口通信2

作者:电子开发网   来源:本站   时间:2009-10-18   访问量:1040

1)将采集的电压值显示在数码管上(1通道,0-5V,保留1位小数,比如4.2)
2)通过串口将测量电压值传递给PC。
   传送数据格式:发送16进制数或其他。
3)当电压大于4.5V时,继电器1动作;当电压小于0.5V时,继电器2动作。

所需硬件:   1.单片机实验开发板B
            2.杜邦头插线
            3.DS18B20
            4.STC89C51RC单片机
所需软件:   1. Keil C51 V8.08或Keil_uv3 绿色版本
            2.STC单片机ISP下载编程软件

             TLC0832资料


1664851161725728.jpg

1664851182201410.jpg

/******************************************************************
** 单片机与PC串口通信1
** 晶 振  频 率:11.0592M
** 线路->单片机实验开发板B
******************************************************************/

#include
#include    

/****************************TLC0832端口定义*********************************************/  
sbit ADC_CLK=P1^2;  
sbit ADC_DO=P1^3;  
sbit ADC_DI=P1^4;
sbit ADC_CS=P1^7;


/****************************数码显示 键盘接口定义****************************************/  
sbit PS0=P2^4;//数码管个位    
sbit PS1=P2^5;//数码管十位    
sbit PS2=P2^6;//数码管百位   
sbit PS3=P2^7;//数码管千位
sfr  P_data=0x80;//P0口为显示数据输出口

sbit P_K_L=P2^2;//键盘列  

sbit JDQ1=P2^0;//继电器1控制
sbit JDQ2=P2^1;//继电器2控制

  
unsigned char tab[]={0xfc,0x60,0xda,0xf2,0x66,0xb6,0xbe,0xe0,0xfe,0xf6,0xee,0,0x9c,0x7a,0x9e,0x8e};//字段转换表


unsigned char adc_change(unsigned char a);//操作TLC0832
unsigned int htd(unsigned int a); //进制转换函数
void display(unsigned int a);//显示函数
void delay(unsigned int);//延时函数
    
    
void main(void)
{
    unsigned int a,temp;                                                        
    TMOD=0x20;           //定时器1--方式2
    TL1=0xfa;            
    TH1=0xfa;            //11.0592MHZ晶振,波特率为4800
    SCON=0x50;           //方式1
    TR1=1;               //启动定时
    while(1)
{
    temp=adc_change('0')*10*5/255;
for(a=0;a<20;a++)//显示,兼有延时的作用
    display(htd(temp));
SBUF=(unsigned char)(temp>>8); //将测量结果发送给PC  
        while(TI!=1);
TI=0;
SBUF=(unsigned char)temp;
        while(TI!=1);
TI=0; if(temp>45)
    JDQ1=0;//继电器1动作
else
JDQ1=1;//继电器1复位
if(temp<5)
JDQ2=0;//继电器2动作
else
JDQ2=1;//继电器1复位
}
}


/**************************数码管显示函数**************************/
/*函数原型:void display(void)
/*函数功能:数码管显示
/*输入参数:无
/*输出参数:无
/*调用模块:delay()
/*建立时间:2005/11/14
/*作者:站长
/******************************************************************/
void display(unsigned int a)
{
    bit b=P_K_L;
P_K_L=1;//防止按键干扰显示
    P_data=tab[a&0x0f];//显示小数点后第1位
    PS0=0;
PS1=1;
PS2=1;
PS3=1;
delay(200);
    P_data=tab[(a>>4)&0x0f]|0x01; //显示个位
    PS0=1;
PS1=0;
delay(200);
    P_data=tab[(a>>8)&0x0f];//显示十位
    PS1=1;
    PS2=0;
delay(200);
    //P_data=tab[(a>>12)&0x0f];//显示百位
    PS2=1;
    //PS3=0;
//delay(200);
    //PS3=1;


    P_K_L=b;//恢复按键
P_data=0xff;//恢复数据口
}

/*************************************************************************************************  
;  函数名称:  adc_change  
;  功能描述:  TI公司8位2通adc芯片TLC0832的控制时序  
;  形式参数:  config(无符号整型变量)  
;  返回参数:  a_data  
;  局部变量:  m、n  
;  调用模块:
;  备  注:
**************************************************************************************************/  
unsigned char adc_change(unsigned char config)//操作TLC0832
{
    unsigned char i,a_data=0;
ADC_CLK=0;
_nop_();
ADC_DI=0;
_nop_();
ADC_CS=0;
_nop_();
ADC_DI=1;
_nop_();
ADC_CLK=1;
_nop_();
ADC_CLK=0;
    if(config=='0')
{
ADC_DI=1;
_nop_();
ADC_CLK=1;
    _nop_();
    ADC_DI=0;
    _nop_();
ADC_CLK=0;
}
else if(config=='1')
{
ADC_DI=1;
_nop_();
ADC_CLK=1;
    _nop_();
    ADC_DI=1;
    _nop_();
ADC_CLK=0;
}
ADC_CLK=1;
_nop_();
ADC_CLK=0;
_nop_();
ADC_CLK=1;
_nop_();
ADC_CLK=0;
for(i=0;i<8;i++)
{
    a_data<<=1;
ADC_CLK=0;
a_data+=(unsigned char)ADC_DO;
    ADC_CLK=1;
}
ADC_CS=1;
ADC_DI=1;
    return a_data;
}


/**************************十六进制转十进制函数**************************/
/*函数原型:uint htd(uint a)
/*函数功能:十六进制转十进制
/*输入参数:要转换的数据
/*输出参数:转换后的数据
/*调用模块:无
/*建立时间:2005/11/14
/*作者:站长
/******************************************************************/
unsigned int htd(unsigned int a)
{
    unsigned int b,c;
b=a%10;
c=b;
a=a/10;
b=a%10;
c=c+(b<<4);
a=a/10;
b=a%10;
c=c+(b<<8);
a=a/10;
b=a%10;
c=c+(b<<12);
return c;
}

/*******************************延时函数*********************************/
/*函数原型:delay(unsigned int delay_time)
/*函数功能:延时函数
/*输入参数:delay_time (输入要延时的时间)
/*输出参数:无
/*调用模块:无
/*建立时间:2005/10/21
/*作者:站长
/**********************************************************************/
void delay(unsigned int delay_time)   //延时子程序
{for(;delay_time>0;delay_time--)
{}
  }


keil工程文件打包下载 chuankou2.rar


/******************************************************************
** 单片机与PC串口通信2
** 晶 振  频 率:11.0592M
** 线路->单片机实验开发板B
******************************************************************/

            ;单片机内存分配申明!

            A_BYTE   EQU 20H ;数码管小数点后第1位数存放内存位置
            B_BYTE   EQU 21H ;数码管个位数存放内存位置
            C_BYTE   EQU 22H ;数码管十位数存放内存位置

TEMP_ADC EQU 23H  ;用于保存AD结果(十进制)

            ADC_CLK  BIT P1.2;  
            ADC_DO   BIT P1.3;  
            ADC_DI   BIT P1.4;
            ADC_CS   BIT P1.7;


JDQ1     BIT P2.0 ;继电器1控制
            JDQ2     BIT P2.1 ;继电器2控制

PS0      BIT P2.4 ;数码管小数点后第1位    
            PS1      BIT P2.5 ;数码管个位    
            PS2      BIT P2.6 ;数码管十位   
            PS3      BIT P2.7 ;数码管百位
  

            ;进行温度显示,这里我们考虑用网站提供的两位数码管来显示温度
            ;显示范围00到99度,显示精度为1度
            ;因为12位转化时每一位的精度为0.0625度,我们不要求显示小数,所以可以抛弃TEMPER_L的
;低4位,将TEMPER_H中的低4位移入TEMPER_L中的高4位,这样获得一个新字节,这个字节就是
;实际测量获得的温度这个转化温度的方法非常简洁无需乘于0.0625系数
ORG 0000H
SJMP MAIN
            ORG 0030H
MAIN:       MOV SP,#60H          
            MOV SCON,#50H ;设置成串口1方式
            MOV TMOD,#20H ;波特率发生器T1工作在模式2上
            MOV TH1,#0FAH ;预置初值(按照波特率4800BPS预置初值)
            MOV TL1,#0FAH ;预置初值(按照波特率4800BPS预置初值)
            ;ORL   PCON, #80H;波特率加倍
            SETB TR1 ;启动定时器T1

LOOP:       ACALL ADC;调用AD转换子程序
            MOV R3,#0
MOV R4,A
MOV R7,#50 ;乘以50再除以255 得到实际电压值的10倍 这样就可以保留小数点后1位
ACALL NMUL21
MOV R7,#255
ACALL NDIV31  
MOV TEMP_ADC,R4
MOV A,R3
MOV R2,A
MOV A,R4
MOV R3,A
ACALL HTD  ;转换成十进制
MOV A,R6
ANL A,#0FH
MOV A_BYTE,A  
MOV A,R6
SWAP A
ANL A,#0FH
MOV B_BYTE,A
MOV A,R5
ANL A,#0FH
MOV C_BYTE,A
            ACALL SEND ;调用串口显示子程序
            ACALL DISPLAY;调用数码管显示子程序
MOV A,R6 ;判断电压>45(4.5V)
CJNE A,#45H,LOOP2
SETB JDQ1
SETB JDQ2
            SJMP LOOP
LOOP2:      JC LOOP3
            CLR JDQ1
SETB JDQ2
SJMP LOOP
LOOP3: SETB JDQ1
            MOV A,R6 ;判断电压<5(0.5V)
CJNE A,#5H,LOOP4
SETB JDQ2
            SJMP LOOP
LOOP4:      JNC LOOP5
            CLR JDQ2
SJMP LOOP
LOOP5:      SETB JDQ2
            SJMP LOOP


/******************************************************************
** 单片机与PC串口通信2
** 晶 振  频 率:11.0592M
** 线路->单片机实验开发板B
******************************************************************/

            ;单片机内存分配申明!

            A_BYTE   EQU 20H ;数码管小数点后第1位数存放内存位置
            B_BYTE   EQU 21H ;数码管个位数存放内存位置
            C_BYTE   EQU 22H ;数码管十位数存放内存位置

TEMP_ADC EQU 23H  ;用于保存AD结果(十进制)

            ADC_CLK  BIT P1.2;  
            ADC_DO   BIT P1.3;  
            ADC_DI   BIT P1.4;
            ADC_CS   BIT P1.7;


JDQ1     BIT P2.0 ;继电器1控制
            JDQ2     BIT P2.1 ;继电器2控制

PS0      BIT P2.4 ;数码管小数点后第1位    
            PS1      BIT P2.5 ;数码管个位    
            PS2      BIT P2.6 ;数码管十位   
            PS3      BIT P2.7 ;数码管百位
  

            ;进行温度显示,这里我们考虑用网站提供的两位数码管来显示温度
            ;显示范围00到99度,显示精度为1度
            ;因为12位转化时每一位的精度为0.0625度,我们不要求显示小数,所以可以抛弃TEMPER_L的
;低4位,将TEMPER_H中的低4位移入TEMPER_L中的高4位,这样获得一个新字节,这个字节就是
;实际测量获得的温度这个转化温度的方法非常简洁无需乘于0.0625系数
ORG 0000H
SJMP MAIN
            ORG 0030H
MAIN:       MOV SP,#60H          
            MOV SCON,#50H ;设置成串口1方式
            MOV TMOD,#20H ;波特率发生器T1工作在模式2上
            MOV TH1,#0FAH ;预置初值(按照波特率4800BPS预置初值)
            MOV TL1,#0FAH ;预置初值(按照波特率4800BPS预置初值)
            ;ORL   PCON, #80H;波特率加倍
            SETB TR1 ;启动定时器T1

LOOP:       ACALL ADC;调用AD转换子程序
            MOV R3,#0
MOV R4,A
MOV R7,#50 ;乘以50再除以255 得到实际电压值的10倍 这样就可以保留小数点后1位
ACALL NMUL21
MOV R7,#255
ACALL NDIV31  
MOV TEMP_ADC,R4
MOV A,R3
MOV R2,A
MOV A,R4
MOV R3,A
ACALL HTD  ;转换成十进制
MOV A,R6
ANL A,#0FH
MOV A_BYTE,A  
MOV A,R6
SWAP A
ANL A,#0FH
MOV B_BYTE,A
MOV A,R5
ANL A,#0FH
MOV C_BYTE,A
            ACALL SEND ;调用串口显示子程序
            ACALL DISPLAY;调用数码管显示子程序
MOV A,R6 ;判断电压>45(4.5V)
CJNE A,#45H,LOOP2
SETB JDQ1
SETB JDQ2
            SJMP LOOP
LOOP2:      JC LOOP3
            CLR JDQ1
SETB JDQ2
SJMP LOOP
LOOP3: SETB JDQ1
            MOV A,R6 ;判断电压<5(0.5V)
CJNE A,#5H,LOOP4
SETB JDQ2
            SJMP LOOP
LOOP4:      JNC LOOP5
            CLR JDQ2
SJMP LOOP
LOOP5:      SETB JDQ2
            SJMP LOOP


;(8位串行A/D芯片兼容ADC0832)
;=================================
;AD转换子程序
;=================================
ADC:        SETB  ADC_DI
            SETB  ADC_DO
            SETB  ADC_CLK
            CLR   ADC_CS
            NOP
            SETB  ADC_CS                           ;

            CLR   ADC_CLK
            CLR   ADC_CS                            ;开始采集
            CALL  D1MS                           ;延时子程序
            SETB  ADC_DI                            ;首个位为1(起始位)
            SETB  ADC_CLK                          ;时钟上升沿
            NOP

            CLR   ADC_CLK                          ;
            SETB  ADC_DI                           ;又一个时钟上升沿用于极性选择.
            SETB  ADC_CLK                          ;SGL=1  (单极性对地)而不是对VREF

            NOP
            CLR   ADC_CLK            

CLR C                               ;0地址选择位单元

MOV   ADC_DI,C
            SETB  ADC_CLK                       ;又一个时钟上升沿用于选地址

            NOP
            CLR   ADC_CLK
            NOP
            SETB  ADC_CLK                          ;第四个时钟上升沿
            NOP
            CLR   ADC_CLK
            NOP

            SETB  ADC_CLK
            MOV   C,ADC_DO
            CLR   ADC_CLK                          ;时钟下降沿读入数据
            RLC   A                              ;7

            SETB  ADC_CLK
            MOV   C,ADC_DO
            CLR   ADC_CLK
            RLC   A
                                                        ;6
            SETB  ADC_CLK
            MOV   C,ADC_DO
            CLR   ADC_CLK
            RLC   A
                                                        ;5
            SETB  ADC_CLK
            MOV   C,ADC_DO
            CLR   ADC_CLK
            RLC   A
                                                        ;4
            SETB  ADC_CLK
            MOV   C,ADC_DO
            CLR   ADC_CLK
            RLC   A
                                                        ;3
            SETB  ADC_CLK
            MOV   C,ADC_DO
            CLR   ADC_CLK
            RLC   A
                                                        ;2
            SETB  ADC_CLK
            MOV   C,ADC_DO
            CLR   ADC_CLK
            RLC   A
                                                        ;1
            SETB  ADC_CLK
            MOV   C,ADC_DO
            CLR   ADC_CLK
            RLC   A
                                                        ;0
            SETB  ADC_CLK
            NOP
            CLR   ADC_CLK                          ;1
            NOP
            SETB  ADC_CLK
            NOP
            CLR   ADC_CLK                          ;2
            NOP
            SETB  ADC_CLK
            NOP
            CLR   ADC_CLK                          ;3
            NOP
            SETB  ADC_CLK
            NOP
            CLR   ADC_CLK                          ;4
            NOP
            SETB  ADC_CLK
            NOP
            CLR   ADC_CLK                          ;5
            NOP
            SETB  ADC_CLK
            NOP
            CLR   ADC_CLK                          ;6
            NOP
            SETB  ADC_CLK
            NOP
            CLR   ADC_CLK                          ;7
            NOP
            SETB  ADC_CLK
            NOP
            CLR   ADC_CLK                          ;wait for 高阻态
            NOP
            SETB  ADC_CLK
            NOP
            CLR   ADC_CLK                          ;wait for 高阻态
            NOP
            CALL  D1MS
            SETB  ADC_CS
            RET


;----------------------
;串口发送数据子程序
;----------------------
SEND:       CLR TI
            MOV SBUF,TEMP_ADC
            JNB TI,$
            RET


DISPLAY:    MOV DPTR,#NUMTAB ;指定查表启始地址
            MOV R0,#4
DPL1:       MOV R1,#250 ;显示1000次
DPLOP:      mov a,A_BYTE ;取小数点后第1位数
            MOVC A,@A+DPTR ;查个位数的7段代码
            mov p0,a ;送出个位的7段代码
            CLR PS0
        SETB PS1
    SETB PS2
    SETB PS3
            acall d1ms ;显示1ms
            mov a,B_BYTE ;取个位数
            MOVC A,@A+DPTR ;查十位数的7段代码
ORL A,#01H
            mov p0,a ;送出十位的7段代码
            SETB PS0
        CLR PS1
            acall d1ms ;显示1ms
            mov a,C_BYTE ;取十位数
            MOVC A,@A+DPTR ;查十位数的7段代码
            mov p0,a ;送出十位的7段代码
            SETB PS1
        CLR PS2
            acall d1ms ;显示1ms
            SETB PS2
            djnz r1,dplop ;100次没完循环
            djnz r0,dpl1 ;4个100次没完循环
            ret


;单字节无符号数乘法程序 (R3R4*R7)=(R2R3R4)
;入口: R3,R4,R7
;占用资源: ACC,B
;堆栈需求: 2字节
;出口: R2,R3,R4
NMUL21 :    MOV A,R4
            MOV B,R7
            MUL AB
            MOV R4,A
            MOV A,B
            XCH A,R3
            MOV B,R7
            MUL AB
            ADD A,R3
            MOV R3,A
            CLR A
            ADDC A,B
            MOV R2,A
            CLR OV
            RET

;单字节无符号除法程序 (R2R3R4/R7)=(R2)R3R4 余数R7
;入口: R2,R3,R4,R7
;占用资源: ACC,B,F0
;堆栈需求: 3字节
;出口: (R2),R3,R4,R7,OV
NDIV31 :    MOV A,R2
            MOV B,R7
            DIV AB
            PUSH ACC
            MOV R2,B
            MOV B,#10H
NDV311 :    CLR C
            MOV A,R4
            RLC A
            MOV R4,A
            MOV A,R3
            RLC A
            MOV R3,A
            MOV A,R2
            RLC A
            MOV R2,A
            MOV F0,C
            CLR C
            SUBB A,R7
            JB F0,NDV312
            JC NDV313
NDV312 :    MOV R2,A
            INC R4
NDV313 :    DJNZ B,NDV311
            POP ACC
            CLR OV
            JZ NDV314
            SETB OV
NDV314 :    XCH A,R2
            MOV R7,A
            RET


HTD:        CLR     A ;R2和R3是程序数据入口
            MOV     R4,A           ;转换后的数放在R4,R5,R6
            MOV     R5,A           ;转换完后在分别屏蔽高位和低位取出数据
            MOV     R6,A
            MOV     R7,#10H
ZH:         CLR     C
            MOV     A,R3
            RLC     A
            MOV     R3,A
            MOV     A,R2
            RLC     A
            MOV     R2,A
            MOV     A,R6
            ADDC    A,R6
            DA      A
            MOV     R6,A
            MOV     A,R5
            ADDC    A,R5
            DA      A   
            MOV     R5,A
            MOV     A,R4
            ADDC    A,R4
            DA      A
            MOV     R4,A
            DJNZ    R7,ZH
            RET

D1MS:       MOV R7,#80 ;1MS延时
            DJNZ R7,$
            RET

numtab:     DB 0FCH,60H,0DAH,0F2H,66H,0B6H,0BEH,0E0H,0FEH,0F6H ;实验板上的7段数码管0~9数字的共阴显示代码

            END

keil工程文件打包下载 asm.rar

上一篇:单片机与PC串口通信1

下一篇:单片机与GSM短信模块(TC35i)串口通信1

发表评论:

评论记录:

未查询到任何数据!

在线咨询

点击这里给我发消息 咨询专员

在线咨询

咨询电话

18906103328

电话咨询

微信扫一扫

微信联系
返回顶部