找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 4265|回复: 1
打印 上一主题 下一主题
收起左侧

1602电压电流表程序

[复制链接]
跳转到指定楼层
楼主
ID:258563 发表于 2017-12-7 11:58 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
#include <stc.h>
#include <intrins.h>
#define RELOAD_COUNT  0xD7                 //12.6 MHz,1T9600bps         

/*----------------------------LCD1602接口定义----------------------------------*/
sbit    LCD_RS= P2^5;        //数据指令
sbit    LCD_RW= P2^7;        //读写控制端
sbit    LCD_EN= P2^4;        //使能端
/********************************显示数据表*********************************/

typedef unsigned char uchar;
uchar tmp;
uchar dis1[] = {"4 -.--V  5 -.--V"};
uchar dis2[] = {"I ----mA P -.--V"};
uchar channel;
uchar result[5];
long  Data=500;   //电压源电压值 v*100                           
void serial_port_initial(void);                //定义串口
void delayms(uchar);                        //延时
void delayus(uchar us);                //延时
void UART_Interrupt_Receive(void);            //接收字符
void send_char(uchar);                         //发送字符
void send_str(uchar stLCD_RS[]);            //发送字符串
uchar get_AD_result(uchar);                    //AD转换
void lcd_en(void);         //输入使能
void lcd_wcmd (uchar cmd) ;
void lcd_wdat (uchar dat) ;
void lcd_printc (uchar x, uchar y, uchar c)    ;
void lcd_prints (uchar x, uchar y, uchar *s)  ;
bit lcd_bz();

/**********************LCD延时子程序********************************/
void delayms(uchar ms)                //LCD延时子程序
{    uchar a,b;                        
    while(ms--)
    {
    for(b=233;b>0;b--)
        for(a=12;a>0;a--);
    }
}

void delayus(uchar us)                //1us相当于
{                           
    uchar a;
    while(us--)
    {
    a++;
    a--;
    }
}

/*****************************************************************************
函数功能:显示相关程序
*****************************************************************************/
void lcd_init()                    //函数功能:LCD初始化子程序
{                           
    lcd_wcmd(0x28);                  //四线显示
    delayms(1);
    lcd_wcmd(0x0c);                //显示打开
    delayms(1);
    lcd_wcmd(0x06);        
    delayms(1);
    lcd_wcmd(0x01);                //显示清屏
    delayms(1);
}
void lcd_en(void)         //输入使能
{
    LCD_EN = 1;
    delayus(10);            //10us
    LCD_EN = 0;
}

bit lcd_bz()
{                           
    bit result;
    LCD_RS = 0;
    LCD_RW = 1;
    LCD_EN = 1;
    delayus(50);   
    result = (bit)(P2 & 0x08);
    LCD_EN = 0;
    return result;   
}
/*****************************************************************************
函数功能:写指令数据到LCD子程序
入口参数:cmd
出口参数:
*****************************************************************************/
void lcd_wcmd(uchar cmd)
{                        
    while(lcd_bz());            //判断LCD是否忙碌


    LCD_RS = 0;
    LCD_RW = 0;
    LCD_EN = 0;
    P2 &= 0xf0;        //清低四位
    P2 |= (cmd&0xf0)>>4;    //写低四位
    lcd_en();
    P2 &= 0xf0;        //清低四位
    P2 |= cmd&0x0f;    //写低四位
    lcd_en();
}

/*****************************************************************************
函数功能:写入显示数据到LCD子程序
入口参数:dat
出口参数:
*****************************************************************************/


void lcd_wdat(uchar dat)   
{                           
    while(lcd_bz());                    //判断LCD是否忙碌


    LCD_RS = 1;
    LCD_RW = 0;
    LCD_EN = 0;
    P2 &= 0xf0;        //清低四位
    P2 |= (dat&0xf0)>>4;    //写低四位
    lcd_en();
    P2 &= 0xf0;        //清低四位
    P2 |= dat&0x0f;    //写低四位
    lcd_en();
}

void lcd_printc (uchar x, uchar y, uchar c)        //字符定位输出
{
    if(y)    lcd_wcmd(x | 0xc0);                //液晶定位
    else    lcd_wcmd(x | 0x80);
    lcd_wdat(c);
}

void lcd_prints (uchar x, uchar y, uchar *s)    //字符串定位输出
{
    if(y)    lcd_wcmd(x | 0xc0);                  //液晶定位
    else    lcd_wcmd(x | 0x80);


    while(*s)
    {
        lcd_wdat(*s);
        s++;
    }
}

/************************主程序************************************/
void main(void)
{                                            // 初始化串口
    serial_port_initial();  
      lcd_init();                                // 初始化LCD            


    P1ASF=0xff ; // 0110,0011,要设置为 A/D 转换的P1.x 口,先设为高
      channel=4;

while(1){
    get_AD_result(channel);
      dis1[0]=channel+48 ;
     dis1[2]=result[0];
     dis1[4]=result[1];
      dis1[5]=result[2];
    get_AD_result(5);
     dis1[11]= result[0];
     dis1[13]= result[1];
      dis1[14]= result[2];

    get_AD_result(6);

    if(result[3]>=0x7e){result[3]-=0x7e; dis2[1]='+';} else {result[3]=0x7e-result[3]; dis2[1]='-';}                     //127==0x7f
     Data= result[3]*5;
    dis2[2]=Data/1000+48 ;               // 返回 A/D 转换结果
    dis2[3]=(Data%1000)/100+48 ;
     dis2[4]=((Data%100)/10)+48 ;
      dis2[5]=(Data%10)+48 ;

    Data=63750/(get_AD_result(7));                     //Data=255*250/result

     dis2[11]= Data/100+48;
     dis2[13]= (Data%100)/10+48;
      dis2[14]= Data%10+48;

     lcd_prints (0,0,dis1);
    lcd_prints (0,1,dis2);

   if(result[3]=='k')
        {
        while(1)
        {
     send_char(get_AD_result(channel));
       delayms(100);
        }
        }
}
}

/*********************串口相关程序********************************/
void serial_port_initial()                    //定义串口初始值
{
     PCON = 0x00;        //波特率不倍速
    SCON = 0x50;        //8位数据,可变波特率
    AUXR |= 0x40;        //定时器1时钟为Fosc,即1T
    AUXR &= 0xfe;        //串口1选择定时器1为波特率发生器
    TMOD = 0x20;
    TL1 = RELOAD_COUNT;    //设定定时初值
    TH1 = RELOAD_COUNT;        //设定定时器重装值
    ET1 = 0;        //禁止定时器1中断
    TR1 = 1;        //启动定时器1
    EA  = 1;
    ES  = 1;
}   

void send_char(uchar i)                        //发送单字符
{
    SBUF   =   i;
    while(TI ==0); //等待发送完成
    TI     =   0;  //清零串口发送完成中断请求标志
}



void send_str(uchar stLCD_RS[])                    // 发送字符串
{   
    uchar i=0;
    ES     =   0;  //关串口中断
    TI     =   0;  //清零串口发送完成中断请求标志
    while(stLCD_RS != '\0')
    {
        SBUF = stLCD_RS;
        while(!TI);                // 等特数据传送
        TI = 0;                    //清零串口发送完成中断请求标志
        i++;                    // 下一个字符
    }
    ES     =   1;  //允许串口中断
}

void UARTInterrupt(void) interrupt 4        //串口中断接收
{
    if(RI)                             // 是否有数据到来
        {
            RI=0;
            result[3] = SBUF;                // 暂存接收到的数据
     if(result[3]<8)
        {

         channel    =result[3];
         result[3]=get_AD_result(channel);
           send_str("第");
         send_char(channel+48);
          send_str("通道电压是: ");
         send_char(result[0]);
         send_char('.');
          send_char(result[1]);
          send_char(result[2]);
         send_char('V');
         send_char(' ');
         }
    if(result[3]=='p')
        {
        result[3]=get_AD_result(7);
        Data=63750/(result[3]);
          send_str("芯片供电电压是: ");
         send_char(Data/100+48);
         send_char('.');
          send_char((Data%100)/10+48);
          send_char(Data%10+48);
         send_char('V');
         send_char(' ');
        }
        }
}

/**********************AD转换程序********************************/
uchar get_AD_result(uchar channell)            //
{
    uchar AD_finished = 0; // 存储 A/D 转换标志
    ADC_CONTR=0xE0;           //设置速度  0xx00000 打开电源 x0000000
    ADC_RES = 0;
    ADC_CONTR |= channell; // 选择 A/D 当前通道
   delayms(1);              //使输入电压达到稳定
    ADC_CONTR |= 0x08; //0000,1000 令 ADC_START = 1, 启动A/D 转换
    AD_finished = 0;
    while ( AD_finished == 0 ) // 等待A/D 转换结束
    {   
    AD_finished = (ADC_CONTR & 0x10); //0001,0000, ADC_FLAG ==1测试A/D转换结束否

    }
ADC_CONTR &= 0xE0; //1110,0000 令 ADC_START = 0, 关闭A/D 转换,
       result[3]=ADC_RES;
    result[0]=result[3]*Data/25500+48 ;               // 返回 A/D 转换结果
    result[1]=((result[3]*Data/255)%100)/10+48 ;
     result[2]=(result[3]*Data/255)%10+48 ;
return (result[3]);
}
分享到:  QQ好友和群QQ好友和群 QQ空间QQ空间 腾讯微博腾讯微博 腾讯朋友腾讯朋友
收藏收藏2 分享淘帖 顶1 踩
回复

使用道具 举报

沙发
ID:183728 发表于 2018-1-12 13:39 | 只看该作者
原理图有吗
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

手机版|小黑屋|51黑电子论坛 |51黑电子论坛6群 QQ 管理员QQ:125739409;技术交流QQ群281945664

Powered by 单片机教程网

快速回复 返回顶部 返回列表