找回密码
 立即注册

QQ登录

只需一步,快速开始

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

求助这个程序和仿真有什么错误,运行一会会后会报错还有显示有问题

[复制链接]
跳转到指定楼层
楼主
1.可控电源设计液晶屏能正常显示功能实现
2.正确显示电压值、 DA能准确输出对应电压
3.能连续可调节0-12V的电压并正常显示
#include"reg52.h"                //包含头文件

//宏定义
#define uchar unsigned char
#define uint unsigned int

//按键定义
sbit KEY1=P2^0;
sbit KEY2=P2^1;
sbit KEY3=P2^2;
sbit KEY4=P2^3;

//液晶控制引脚定义
sbit RS=P2^5;
sbit RW=P2^6;
sbit EN=P2^7;

//DAC定义
sbit CS_5615=P1^5;          //定义选片信号IO口
sbit CLK_5615=P1^6;         //定义时钟信号IO口
sbit DAT_5615=P1^7;         //定义数据输入IO口

//ADC定义
sbit CS=P3^5;  //定义选片信号IO口
sbit CLK=P3^3; //定义时钟信号IO口
sbit DIO=P3^4; //定义数据输入IO口

//报警指示灯定义
sbit led=P3^1;

uint U;
uchar GETU=0;
bit flag=0;
uint a=0;

unsigned char Int,Dec;  //分别储存转换后的整数部分与小数部分
uchar code tab1[]={"Welcome to use  "};  //固定字符
uchar code tab2[]={"adj power supply"};  //固定字符
uchar code tab3[]={"Voltage:     . v"};  //固定字符
uchar code tab4[]={"                "};  //固定字符
uchar code tab5[]={"Short circuit!!!"};  //固定字符
uchar code tab6[]={"Please restart!!"};  //固定字符
//延时函数
void delay(uint xms)  //延时函数,有参函数
{
    uint x,y;
    for(x=xms;x>0;x--)
     for(y=121;y>0;y--);
}

//液晶写入指令函数
void write_1602com(uchar com)
{
    RS=0;  //数据/指令选择置为指令
    RW=0;  //读写选择置为写
    P0=com;  //送入数据
    delay(1);
    EN=1;  //拉高使能端,为制造有效的下降沿做准备
    delay(1);
    EN=0;  //en由高变低,产生下降沿,液品执行命令
}

//液晶写入数据函数
void write_1602dat(uchar dat)
{
    RS=1;  //数据/指令选择置为数据
    RW=0;  //读写选择置为写
    P0=dat;  //送入数据
    delay(1);
    EN=1;  //en置高电平,为制造下降沿做准备
    delay(1);
    EN=0;  //en由高变低,产生下降沿,液晶执行命令
}

//液晶初始化函数
void lcd_init()
{
    uchar p;
    write_1602com(0x38);  //设置液晶工作模式,意思: 16*2行显示,5*7点阵,8位数据
    write_1602com(0x0c);  //开显示不显示光标
    write_1602com(0x06);  //整屏不移动,光标自动右移
    write_1602com(0x01);  //清显示
        write_1602com(0x80);  //日历显示固定符号从第一行第1个位置之后开始显示
    for(p=0;p<16;p++)
    {
            write_1602dat(tab1[p]);  //向液晶屏写日历显示的固定符号部分
    }
        write_1602com(0xc0);  //时间显示固定符号写入位置,从第2个位置后开始显示
    for(p=0;p<16;p++)
        {
            write_1602dat(tab2[p]);  //写显示时间固定符号,两个冒号
    }
    delay(1000);
    write_1602com(0x80);  //日历显示固定符号从第一行第1个位置之后开始显示
    for(p=0;p<16;p++)
    {
        write_1602dat(tab3[p]);  //向液晶屏写日历显示的固定符号部分
    }
        write_1602com(0xc0);  //时间显示固定符号写入位置,从第2个位置后开始显示
    for(p=0;p<16;p++)
    {
        write_1602dat(tab4[p]);  //写显示时间固定符号,两个冒号
    }
}

//液晶显示函数
void shuma(uint buf)
{
    uchar a,b,c,d,p;
    a=buf/1000;        //十位
    b=buf%1000/100; //个位
    c=buf%100/10;  //小数点后一位
        d=buf%10;  //小数点后两位
    if(flag==0)
    {
        write_1602com(0x80+11);
        write_1602dat(a+0x30);
                write_1602dat(b+0x30);
        write_1602dat('.');
        write_1602dat(c+0x30);
    }
        if(flag==1)        //短路提示
        {
                    write_1602com(0x80);         //时间显示固定符号写入位置,从第二个位置后开始显示
                 for(p=0;p<16;p++)
                 {
                    write_1602dat(tab5[p]); //写入时间固定符号,两个冒号
                 }
                    write_1602com(0xc0);         //时间显示固定符号写入位置,从第二个位置后开始显示
                 for(p=0;p<16;p++)
                 {
                    write_1602dat(tab6[p]); //写入时间固定符号,两个冒号
                 }
        }
}

//DAC5615驱动函数
void tlc_5615(uint buf)          //DA输出
{
    uint a,c;         //定义变量
    c=buf;                 //要输出的数据赋值
    CS_5615=0;         //引脚拉低
    for(a=16;a>0;a--)         //循环16次
    {
        DAT_5615=c>>15;         //把数据串行口输入da芯片
        c=c<<1; //将数据左移一位,下次循环时就是传输第二位数据了
        CLK_5615=1;                //拉高
        CLK_5615=0;                //拉低
    }
    CLK_5615=1;
    CLK_5615=0;
    CLK_5615=1;
    CLK_5615=0;
    CS_5615=1;
}

//ADC驱动函数
unsigned int A_D()
{
    unsigned char i, dat;
    CS=1;  //一个转换周期开始
    CLK=0;  //为第一个脉冲作准备
    CS=0;  //CS置0,片选有效

        DIO=1;  //DI0置1,规定的起始信号
    CLK=1;  //第一个脉冲
    CLK=0;  //第一个脉冲的下降沿,此前DIO必须是高电平
    DIO=1;  //DI0置1,通道选择信号
    CLK=1;  //第二个脉冲,第2、3个脉冲下沉之前,DI必须跟别输入两位数据用于选择通道,这里选择通道1
    CLK=0;  //第二个脉冲下降沿
    DIO=0;  //DI置0,选择通道0
    CLK=1;  //第三个脉冲
    CLK=0;  //第三个脉冲下降沿
        DIO=1;  //第三个脉冲下沉之后,输入端DIO失去作用,应置1
    CLK=1;        //第四个脉冲
        for(i=0;i<8;i++)  //高位在前
    {
        CLK=1;  //第四个咏冲
        CLK=0;
        dat<<=1;  //将下面储存的低位数据向右移
        dat|=(unsigned char)DIO;  //将输出数据DIO通过或运算储存在dat最低位
    }
    CS=1;  //片选无效
    return dat;  //将读出的数据返回
}

//主函数
void main(void)
{
    U=0;   //电压值显示0
        lcd_init();
        while(1)  //进入循环
        {
            tlc_5615(U);  //输出电压值
                shuma(U/8*10);  //显示电压值
                if(flag==0)           //没有短路
                {
                  if(KEY1==0)        //按键1按下
                 {
                   shuma(U/8*10);
                   shuma(U/8*10);
                   shuma(U/8*10);
                   shuma(U/8*10);
                   shuma(U/8*10);//此处调用显示函数就是延时去抖的作用
                        if(KEY1==0)         //再次判断按键1按下
                        {
                            if(U<960) //1V 对应的是80 10位ad
                                U=U+8;          //电压加0.1V
                        }
                }
                if(KEY2==0)           //按键2按下
                {
                   shuma(U/8*10);
                   shuma(U/8*10);
                   shuma(U/8*10);
                   shuma(U/8*10);
                   shuma(U/8*10);
                        if(KEY2==0)
                        {
                            if(U>=8) //电压减
                                U=U-8;
                        }
                }       
                if(KEY3==0)          //按键3按下
                {
                   shuma(U/8*10);
                   shuma(U/8*10);
                   shuma(U/8*10);
                   shuma(U/8*10);
                   shuma(U/8*10);
                        if(KEY3==0)
                        {
                                U=528;        //输出6.6V电压
                        }
                }
                if(KEY4==0)         //按键4按下
                {
                   shuma(U/8*10);
                   shuma(U/8*10);
                   shuma(U/8*10);
                   shuma(U/8*10);
                   if(KEY4==0)
                   {
                     U=0;           //关闭输出
                         }
                }
        }
                GETU=A_D();                //读取ad数据
                if(GETU>=12)  //0.0196V,采样电阻采集到的电压数据
                {
                   U=0;           //关闭输出
                   led=0;
                   a=0;
                   flag=1; //短路标志位
                 }               
        }
}

1.png (71.83 KB, 下载次数: 72)

1.png

0.png (4.41 KB, 下载次数: 95)

0.png

可控电源.zip

115.61 KB, 下载次数: 4

分享到:  QQ好友和群QQ好友和群 QQ空间QQ空间 腾讯微博腾讯微博 腾讯朋友腾讯朋友
收藏收藏 分享淘帖 顶 踩
回复

使用道具 举报

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

本版积分规则

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

Powered by 单片机教程网

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