数控步进直流稳压电源(C版本)

[复制链接]
2533|4
手机看帖
扫描二维码
随时随地手机跟帖
njliu|  楼主 | 2007-1-26 19:05 | 显示全部楼层 |阅读模式
#include    <pic.h>
//此程序实现"数控步进直流稳压电源"的功能,调试时为了避免资源冲突,应使实验板上的拔码开关S8拔向高电平
//本程序设定S9键为增加键,当按住S9键不松开时,输出Vout以0.1V连续步进,
//直至键S9松开,当以一定的时间间隔点动S9键时,输出Vout也为点动步进
//递减键S11的功能与S9基本相同时,输出电压的值显示在3个LED上
unsigned     char     R1,R2,R3,TXDATA,LEDF,BJF,COUNTW,data;
unsigned     int        i;
const    char       table[11]={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0XD8,0x80,0x90,0xFF};
//不带小数点的显示段码表
const    char       table0[11]={0X40,0X79,0X24,0X30,0X19,0X12,0X02,0X78,0X00,0X10,0xFF};
//带小数点的的显示段码表
unsigned    char      s[4];            //定义一个显示缓冲数组
//把需要显示的数字装入显示缓冲数组
void        sfz()
{    
    s[0]=R3;
    s[1]=R2;
    s[2]=R1;
    s[3]=0x0A;                    //最后一个LED显示"DARK"
}
//系统各寄存器初始化子程序
void        initial()
{
    R1=0X00;
    R2=0X00;
    R3=0X00;
    sfz();                        //把需要显示的数字装入显示缓冲数组
    TXDATA=0X00;
    LEDF=0X01;
    BJF=0X01;
    TRISB1=0;
    TRISB2=0;
    TRISB4=1;
    TRISB5=1;                    //设置与键盘相关的各口的输入输出方式
    RB1=0;
    RB2=0;                        //设置扫描初始条件    
}
//spi方式显示初始化子程序
void         SPIINIT()
{
    PIR1=0;
    SSPCON=0x30;
    SSPSTAT=0xC0;
//设置SPI的控制方式,允许SSP方式,并且时钟下降沿发送,与"74HC595,当其
//SCLK从低到高跳变时,串行输入寄存器"的特点相对应
    TRISC=0xD7;                //SDO引脚为输出,SCK引脚为输出
    TRISA5=0;                    //RA5引脚设置为输出,以输出显示锁存信号
}
//I2C初始化子程序
void         i2cint()
{
    SSPCON = 0X08;                //初始化SSPCON寄存器
    TRISC3 =1;                    //设置SCL为输入口
    TRISC4 =1;                    //设置SDA为输入口
    TRISA4 = 0;
    SSPSTAT=0X80;                //初始化SSPSTAT寄存器
    SSPADD=0X02;                //设定I2C时钟频率
    SSPCON2=0X00;                //初始化SSPCON2寄存器
    di();                        //关闭总中断
    SSPIF=0;                    //清SSP中断标志
    RA4=0;                        //关掉74HC165的移位时钟使能,以免74HC165
//移位数据输出与I2C总线的数据线发生冲突
    SSPEN=1;                    //SSP模块使能
}
//软件延时子程序
void         DELAY()
{
    for(i = 3553; --i ;) continue;
}
//键服务子程序
void        keyserve()
{
    PORTB=0XFD    ;
    if(RB5==0)    BJF=0X01;        //S9键按下,步进加标志置1
    PORTB=0XFB    ;
    if(RB5==0)    BJF=0X00;        //S11键按下,步进加标志清0
    RB1=0;                        //恢复PORTB的值
    RB2=0;
}
//键扫描子程序
void        KEYSCAN()
{
while(1){    
while(1)    {
            if (RB5==0)    break;
        }
        DELAY();                //若有键按下,则软件延时
        if (RB5==0)    break;        //若还有键按下,则终止循环扫描,返回
      }
}
//SPI传送数据子程序
void  SPILED(data)
{
    SSPBUF=data;                //    启动发送
    do    {
       ;
    }while(SSPIF==0);
    SSPIF=0;
}
//显示子程序
void        display()
{
    SPIINIT();                    //spi方式显示初始化
    RA5=0;                        //准备锁存
    for(COUNTW=0;COUNTW<4;COUNTW++)    {
        data=s[COUNTW];
        if(COUNTW==1)    data=table0[data];//第二位需要显示小数点
        else    data=table[data];
        SPILED(data);            //发送显示段码
    }
    for(COUNTW=0;COUNTW<4;COUNTW++){
        data=0xFF;
        SPILED(data);            //连续发送4个DARK,使显示看起来好看一些
    }
    RA5=1;                        //最后给一个锁存信号,代表显示任务完成
}
//I2C总线输出数据子程序
void        i2cout()
{
    i2cint();                        //因为SPI输出和I2C输出不能同时工作,则需要
//不断在两种方式见切换
    SEN=1;                        //产生I2C启动信号
    for(i=0x02;--i;)    continue;    //给予一定的延时,保证启动
do    {
        RSEN=1;                //产生I2C启动信号
    }while(SSPIF==0);            //如果没能启动,则反复启动,直到启动为止
    SSPIF=0;                    //SSPIF标志清0
    SSPBUF=0X58;                //I2C总线发送地址字节
do    {
        ;
    }while(SSPIF==0);            //等待地址发送完毕
    SSPIF=0;                    //SSPIF标志清0
    SSPBUF=0X01;                //I2C总线发送命令字节
do    {
        ;
    }while(SSPIF==0);            //等待命令发送完毕
    SSPIF=0;                    //SSPIF标志清0
    SSPBUF=TXDATA;            //I2C总线发送数据字节
do    {
        ;
    }while(SSPIF==0);            //等待数据发送完毕
    SSPIF=0;                    //SSPIF标志清0
    PEN=1;                        //产生停止条件
do    {
    ;
    }while(SSPIF==0);            //等待停止条件产生
    SSPIF=0;                    //SSPIF标志清0    
}
//步进加子程序
void        BJADD()
{
    R1++;
    TXDATA=TXDATA+2;
    if(R1>9) {
        R1=0;
        R2++;
        if(R2>9)    {
            R2=0;
            R3++;
        }
    }
    if((R3==1)&&(R2==2)&&(R1==1)){
        R3=0;
        R2=0;
        R1=0;                    //若R3,R2,R1超过120,则又从0计起
        TXDATA=0;
    }
    sfz();                        //把需要显示的数字装入显示缓冲数组
}
//步进减子程序
void        BJSUB()
{
    R1--;
    TXDATA=TXDATA-2;
    if(R1==0XFF) {
        R1=9;
        R2--;
        if(R2==0XFF)    {
    R2=9;
            R3--;
            if(R3==0XFF) {
                R3=1;
                R2=2;
                R1=0;            //若R3,R2,R1小于0,则又从120计起
                TXDATA=0XF0;
            }
        }
    }
    sfz();                        //把需要显示的数字装入显示缓冲数组
}
//主程序
main()
{
    initial();                        //系统各寄存器初始化
    display();                    //调用一次显示子程序
while(1)    {
        i2cout();                    //调用I2C子程序,启动D/A转换    
        KEYSCAN();            //键盘扫描
        keyserve()    ;                //若确实有键按下,则调用键服务程序        
        if(BJF==0X01)     BJADD();//若步进加标志为1,则调用步进加子程序
        else    BJSUB();            //若步进加标志为0,则调用步进减子程序
        display();                //调用一次显示子程序
}
}
w55706| | 2007-2-10 08:38 | 显示全部楼层

顶一下

顶一下

使用特权

评论回复
ocon| | 2007-2-15 19:42 | 显示全部楼层

没电路图,看不懂。

使用特权

评论回复
miky| | 2007-2-24 13:04 | 显示全部楼层

请贴原理图,谢谢!

使用特权

评论回复
njliu|  楼主 | 2007-4-6 21:26 | 显示全部楼层

我先在在混笔记

wind-solar.21ic.org
欢迎到我的新田地里讨论新能源问题.里面我为大家准备很多珍贵的资料.
希望大家支持啊

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

11

主题

29

帖子

1

粉丝